views:

180

answers:

2

Full calendar have no included options to work-time feature (selecting first and last rows in agenda view for any day - where in example company is not working). I managed something like that:

viewDisplay: function(view){
                    $.ajax({
                        url: 'index.php?r=calendar/Default/worktime',
                        dataType: 'json',
                        success: function(data){
                            if(view.name=='agendaWeek')
                                selectWorkTime(data, 30, 0, 24, false);
                            else if(view.name=='agendaDay')
                                selectDayWorkTime(data, 30, 0, 24, view, false);
                        }
                    });
                }

Where index.php?r=calendar/Default/worktime is php file returning json. It looks like that:

$arr = array(
        'mon' => array('8:00', '17:00'),
        'tue' => array('9:00', '15:00'),
        'wed' => array('9:30', '19:00'),
        'thu' => array('6:00', '14:00'),
        'fri' => array('0:00', '24:00'),
        'sat' => array('9:00', '14:00'),
        'sun' => array()
    );

    foreach ($arr as &$day){
        foreach($day as &$hour){
            $tmp = explode(':', $hour);
            $hour = $tmp[0] * 3600 + $tmp[1] * 60;
        }
    }

    print json_encode($arr);

and at the end, some functions using for counting and selecting work-time:

function selectDayWorkTime(timeArray, slotMinutes, minTime, maxTime, viewObject, showAtHolidays){
    var dayname;
    $('.fc-content').find('.fc-view-agendaWeek').find('.fc-agenda-body')
    .children('.fc-work-time').remove();
    $('.fc-content').find('.fc-view-agendaDay')
    .find('.fc-work-time-day').removeClass('fc-work-time-day');
    switch(viewObject.start.getDay()){
        case 1: dayname='mon'; break;
        case 2: dayname='tue'; break;
        case 3: dayname='wed'; break;
        case 4: dayname='thu'; break;
        case 5: dayname='fri'; break;
        case 6: dayname='sat'; break;
        case 0: dayname='sun'; break;
    }
    for(var day in timeArray){
        if(day == dayname){
            if($('.fc-content').find('.fc-view-agendaDay').find('.fc-'+day).attr('class').search('fc-holiday') == -1 || showAtHolidays){
                var startBefore = 0;
                var endBefore = timeArray[day][0] / (60 * slotMinutes) - (minTime * 60) / slotMinutes;
                var startAfter = timeArray[day][1] / (60 * slotMinutes) - (minTime * 60) / slotMinutes;
                var endAfter = (maxTime - minTime) * 60 / slotMinutes - 1;
                for(startBefore; startBefore < endBefore; startBefore++){
                    $('.fc-view-agendaDay').find('.fc-slot'+startBefore).find('div').addClass('fc-work-time-day');
                }
                for(startAfter; startAfter <= endAfter; startAfter++){
                    $('.fc-view-agendaDay').find('.fc-slot'+startAfter).find('div').addClass('fc-work-time-day');
                }
            }
        }
    }
}

function selectWorkTime(timeArray, slotMinutes, minTime, maxTime, showAtHolidays){
    for(var day in timeArray){
        var startBefore = 0;
        var endBefore = timeArray[day][0] / (60 * slotMinutes) - (minTime * 60) / slotMinutes;
        var startAfter = timeArray[day][1] / (60 * slotMinutes) - (minTime * 60) / slotMinutes;
        var endAfter = (maxTime - minTime) * 60 / slotMinutes - 1;
        if(startBefore > endBefore) endBefore = startBefore;
        if(startAfter > endAfter) startAfter = endAfter;
        try{
            selectCell(startBefore, endBefore, 'fc-'+day, 'fc-work-time', false, showAtHolidays);
            selectCell(startAfter, endAfter, 'fc-'+day, 'fc-work-time', true, showAtHolidays);
        }
        catch(e){
            continue;
        }
    }
}

function selectCell(startRowNo, endRowNo, collClass, cellClass, closeGap, showAtHolidays){
    $('.fc-content').find('.fc-view-agendaWeek').find('.fc-agenda-body')
    .children('.'+cellClass+''+startRowNo+''+collClass).remove();
    $('.fc-content').find('.fc-view-agendaDay')
    .find('.fc-work-time-day').removeClass('fc-work-time-day');
    if($('.fc-content').find('.fc-view-agendaWeek').find('.'+collClass).attr('class').search('fc-holiday') == -1 || showAtHolidays){
        var width = $('.fc-content').find('.fc-view-agendaWeek')
        .find('.'+collClass+':last').width();
        var height = 0;
        if(closeGap && (startRowNo != endRowNo)){
            height = $('.fc-content').find('.fc-view-agendaWeek')
            .find('.fc-slot'+ startRowNo).height();
        }
        $('.fc-view-agendaWeek').find('.fc-agenda-body').prepend('<div class="'+cellClass+' '
            + ''+cellClass+''+startRowNo+''+collClass+'"></div>');
        $('.'+cellClass).width(width - 2);
        height += $('.fc-content').find('.fc-view-agendaWeek')
        .find('.fc-slot'+ endRowNo).position().top
        - $('.fc-content').find('.fc-view-agendaWeek')
        .find('.fc-slot'+ startRowNo).position().top;
        $('.'+cellClass+''+startRowNo+''+collClass).height(height);
        $('.'+cellClass+''+startRowNo+''+collClass)
        .css('margin-top',
            $('.fc-content').find('.fc-view-agendaWeek')
            .find('.fc-slot'+ startRowNo).position().top);
        $('.'+cellClass+''+startRowNo+''+collClass)
        .css('margin-left',
            $('.fc-content').find('.fc-view-agendaWeek')
            .find('.'+collClass+':last').offset().left - width / 2);
    }
}

Don't forget about CSS:

.fc-work-time-day{
        background-color: yellow;
        opacity: 0.3;
        filter: alpha(opacity=30); /* for IE */
    }

    .fc-work-time{
        position: absolute;
        background-color: yellow;
        z-index:10;
        margin: 0;
        padding: 0;
        text-align: left;
        z-index: 0;
        opacity: 0.3;
        filter: alpha(opacity=30); /* for IE */
    }

So, I've got some questions about - is the other way to make the same, but no using absolute div's in agendaWeek? And... How can I get in viewDisplay function actual slotMinutes, minTime and maxTime

A: 

Marty thanks for your post: I am sorry, i have no answer for your question, but a new question (but i don't see any comment button at this post, i am sorry if this is the wrong way).

Now my question: I have tested your great solution (becaus i need nearly the same function), but your i think your javaScript knowledge is better than mine, and i have anonther strange effect. In my calendar all worktimes are moved (shifted) to the right side, so the entry of monday is on tuesday and so on. did you not have this effect. what do you think about time ranges with some breaks in it. for example working times are 08:00 - 12:00 and 15:00 - 20:00 so the gap between 12:00 and 15:00 should not be marked.

I am looking forward a post of you.

chichi
you guys are using StackOverflow the wrong way .. questions should be posted as questions, and asnwers should be posted as answers .. this is not forum ..
Lukman
A: 

Cure for shifting - replace function into this:

function selectCell(startRowNo, endRowNo, collClass, cellClass, closeGap, showAtHolidays){
$('.fc-content').find('.fc-view-agendaWeek').find('.fc-agenda-body')
.children('.'+cellClass+''+startRowNo+''+collClass).remove();
$('.fc-content').find('.fc-view-agendaDay')
.find('.fc-work-time-day').removeClass('fc-work-time-day');

if($('.fc-content').find('.fc-view-agendaWeek').find('.'+collClass).attr('class').search('fc-holiday') == -1 || showAtHolidays){
    var width = $('.fc-content').find('.fc-view-agendaWeek')
    .find('.'+collClass+':last').width();
    var height = 0;
    if(closeGap && (startRowNo != endRowNo)){
        height = $('.fc-content').find('.fc-view-agendaWeek')
        .find('.fc-slot'+ startRowNo).height();
    }
    $('.fc-view-agendaWeek').find('.fc-agenda-body').prepend('<div class="'+cellClass+' '
        + ''+cellClass+''+startRowNo+''+collClass+'"></div>');
    $('.'+cellClass).width(width);
    height += $('.fc-content').find('.fc-view-agendaWeek')
    .find('.fc-slot'+ endRowNo).position().top
    - $('.fc-content').find('.fc-view-agendaWeek')
    .find('.fc-slot'+ startRowNo).position().top;
    $('.'+cellClass+''+startRowNo+''+collClass).height(height);
    $('.'+cellClass+''+startRowNo+''+collClass)
    .css('margin-top',
        $('.fc-content').find('.fc-view-agendaWeek')
        .find('.fc-slot'+ startRowNo).position().top);
    var dayname = collClass.slice(3);
    var dayNo;
    switch(dayname){
        case 'mon': dayNo=0; break;
        case 'tue': dayNo=1; break;
        case 'wed': dayNo=2; break;
        case 'thu': dayNo=3; break;
        case 'fri': dayNo=4; break;
        case 'sat': dayNo=5; break;
        case 'sun': dayNo=6; break;
    }
    $('.'+cellClass+''+startRowNo+''+collClass)
    .css('margin-left',
        $('.fc-content').find('.fc-view-agendaWeek')
        .find('.fc-slot'+ startRowNo).position().left + (width + 1) * dayNo);
}

}

Not-continuous daily work time is not supported yet. You must use only one period of work time per day.

Zozo