Monah
Monah

Reputation: 6784

place a div in the correct position over table

I am trying to build a scheduler, and here are the requirements

  1. show the working hours for each resource
  2. show the interviews and allow to change the interview duration by using the resizing option and to move the interviews using the draggable and droppable

kindly I need help in the following:

  1. after building the schedule, how can draw each interview to be placed on top of the schedule at the right position
  2. if there is many schedules drawn beside each others, is it possible to drag an interview from schedule i to schedule j?

$.fn.scheduler = function(options) {
  var context = $(this)
  var resources = {
      start: null,
      end: null,
      ownerId: null,
      ownerName: null,
      duration: 15, // 15 minutes,
      interviews: []
    }
    // build the scheduler

  function build() {
    if (options !== null && options !== undefined)
      $.extend(resources, options)
    var start = resources.start
    var end = resources.end
    var table = $('<table>')
    var temp = start
    console.log(start)
    while (temp < end) {
      console.log(temp)
      var tr = $('<tr>')
      var time = $('<td>')
      time.addClass('time')
      time.html(temp.getHours() + ':' + temp.getMinutes())
      tr.append(time)
      var event = $('<td>')
      event.addClass('event')
      tr.append(event)
      tr.appendTo(table)
      temp.setMinutes(temp.getMinutes() + resources.duration)
    }
    context.append(table)
  }
  build()
}
$(document).ready(function() {
  $('.scheduler').scheduler({
    start: new Date(2015, 11, 21, 9, 0, 0),
    end: new Date(2015, 11, 21, 17, 0, 0),
    ownerId: 1196,
    interviews: [{
      id: 111,
      start: new Date(2015, 11, 21, 11, 35, 0),
      duration: 45
    }]
  })
})
.scheduler {
  height: 200px;
  overflow-y: scroll;
}
.scheduler table {
  border: 1px solid #ddd;
  border-collapse: collapse;
  ;
}
table {
  font-size: 1.0em;
}
table td {
  height: 20px;
  border-bottom: 1px solid #ddd;
}
table td.time {
  border-right: 1px solid #ddd;
}
.time {
  width: 70px;
  font-weight: bold;
  color: #c1c1c1;
}
.event {
  width: 160px;
}
.interview {
  position: absolute;
  width: 160px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='scheduler'>

</div>

JSFIDDLE

Upvotes: 1

Views: 112

Answers (1)

Monah
Monah

Reputation: 6784

for the first part of your question, try the following:

1- Update your css as follows

.scheduler{
    font-family: Calibri;
    position: relative;
    height: 400px;
    overflow-y: scroll;
}
.interview {
    position: absolute;
    background-color: aqua;
    opacity: 0.5;
    width: 160px;
    border:1px solid #808080;
}

2- Add the following JS function to your scheduler

function showInterviews() {
        for (var interview in resources.interviews) {
            var iw = resources.interviews[interview]
            var timeStart = iw.start.getHours() * 60 + iw.start.getMinutes()
            var timeEnd = timeStart + iw.duration
            var result = context.find('.time').filter(function () {
                return $(this).data('start') <= timeEnd && $(this).data('end') >= timeStart;
            })
            if (result.length > 0) {
                var first = result.first().next()
                var position = first.position()
                console.log(first.css('font-size'))
                var div = $('<div>')
                div.addClass('interview')
                div.attr('start', timeStart)
                div.attr('end', timeEnd)
                div.attr('duration', iw.duration);
                div.css('top', position.top + 1)
                div.css('width', first.width()+1)
                div.css('height', (result.length - 1) * 24  - result.length)
                div.css('left', position.left + 1)
                div.appendTo(context)
            }
        }
    }

3- Update your build function to store the start and end time in the data attributes

var timeStart = temp.getHours() * 60 + temp.getMinutes()
var timeEnd = timeStart + resources.duration
time.attr('data-start', timeStart)
time.attr('data-end', timeEnd)

Explanation:

I- How to find the intersection between the interview div and the schedule table especially we are working on time segments

  1. Convert each time slot to minutes by ( Hour * 60 + minutes) as start and calculate the end of slot by start + duration
  2. Find the common tds that intersects with the interview start and end by ( td.start <= interview.end and td.End>=interview.start
  3. exclude the last in the result since your time slot start = the previous slot end time

II- Get the first element in the result and update your interview top and left by the first td element position.

III - I am not able to tell why the value 24 is there, I tried (first.height() + result.length) instead of 24 but it didn't give the expected result, maybe someone can help to clear this point.

here a working demo

hope it will help you

Upvotes: 1

Related Questions