FullCalendar,营业时间和日期范围

时间:2017-10-24 10:10:45

标签: javascript fullcalendar

在我的项目中,用户可以预订房间。我的房间有几个小时(例如08:00-17:00)。我尝试使用营业时间,但在夏季和冬季会有不同的变化。

我还尝试使用日期范围为this post的反向背景事件,但如果我使用selectConstraint,则不考虑范围。

最好的办法是将日期范围添加到营业时间,但似乎尚未实施。

有没有人能满足我的需求?

由于

编辑:这是我的fullcalendar选项

function FCInit(){
        var formatColumn, formatColumnWeek;

        // Entete des colonnes
        if ($(window).width() < 600) {
            formatColumn = 'ddd';
            formatColumnWeek = 'ddd\nDD/MM';
        }
        else {
            formatColumn = 'dddd';
            formatColumnWeek = 'dddd\nDD/MM';
        }

        var fcOpts = {

            header: {                               
                left: 'today,datePickerButton',
                center: 'prev,title,next',
                right: 'month,agendaWeek,agendaDay'
            },

            contentHeight: 'auto',                  
            eventLimit: false,                      
            allDaySlot: true,                       
            slotEventOverlap: false,                    
            nowIndicator: true,                     
            timeFormat: 'H:mm',                     
            columnFormat: formatColumn,             // Format des jours dans l'entete     ddd: Mon  /  ddd M/D : Mon 09/07  /  dddd : MOnday /
            navLinks: true,                         

            eventOverlap: false,                        
            selectable: true,
            selectHelper: true,
            selectOverlap: true,
            selectConstraint:999,
            unselectCancel: '#reservation',
            views: {                                
                week: {
                    columnFormat: formatColumnWeek
                }
            },

            events:[{
                     id:3,
                     title:"R\u00e9serv\u00e9",
                     start:"2017-11-02 08:00",
                     end:"2017-11-02 10:00",
                     overlap:false,
                     color:"#C41305"
            },{
                     id:999,
                     className:"fc-nonbusiness",
                     title:"",
                     start:"08:00",
                     end:"17:00",
                     dow:[4],
                     ranges:[
                        {
                          start:"2017-11-01",
                          end:"2017-11-30"
                        }
                     ],
                     rendering:"inverse-background",
            }],

            /* Ajout de datepicker (nécessite Jquery UI css et js) */
            customButtons: {
                datePickerButton: {
                    text: '',
                    click: function () {

                        var $btnCustom = $('.fc-datePickerButton-button'); // name of custom  button in the generated code
                        $btnCustom.after('<input type="hidden" id="hiddenDate" class="datepicker"/>');

                        $("#hiddenDate").datepicker({
                            flat: true,
                            showOn: "button",
                            dateFormat: "yy-mm-dd",
                            onSelect: function (dateText, inst) {
                                $('#full-calendar').fullCalendar('changeView', 'agendaDay', dateText);
                            }
                        });

                        var $btnDatepicker = $(".ui-datepicker-trigger"); // name of the generated datepicker UI
                        //Below are required for manipulating dynamically created datepicker on custom button click
                        $("#hiddenDate").show().focus().hide();
                        $btnDatepicker.trigger("click"); //dynamically generated button for datepicker when clicked on input textbox
                        $btnDatepicker.hide();
                        $btnDatepicker.remove();
                        $("input.datepicker").not(":first").remove();//dynamically appended every time on custom button click

                    }
                }
            },
            dayRender: function(date, cell){
                if(date.isBefore(new Date())){
                    cell.css('cursor','no-allowed');
                }
            },

            eventRender: function (event, element) {

                if(event.ranges) {
                    return (event.ranges.filter(function (range) { // test event against all the ranges

                        return (event.start.isBefore(range.end) &&
                            event.end.isAfter(range.start));

                    }).length) > 0;
                }

                if(event.rendering === "background"){
                    // Just add some text or html to the event element.
                    element.append("<div class='fc-title'>"+event.title+"</div>");
                }

            },
            dayClick: function(date, jsEvent, view){
                if(date.isSameOrAfter(new Date()) && view.name === 'month'){
                    $('#full-calendar').fullCalendar('changeView', 'agendaWeek', date);
                }
            },
            select: function(start, end, jsEvent, view){
                if(start.isSameOrAfter(new Date()) && view.name !== 'month'){
                    $('#reservation_dateFrom').val(start.format('DD/MM/YYYY HH:mm'));
                    $('#reservation_dateTo').val(end.format('DD/MM/YYYY HH:mm'));
                    $('#reservation').modal('show');
                }else if(start.isBefore(new Date())){
                    alert('Il n\'est pas possible de réserver dans le passé');
                    $('#full-calendar').fullCalendar('unselect');
                }

            }

        };
        $('#full-calendar').fullCalendar(fcOpts);

    };

以及用于存储数据的symfony实体(Horaire是营业时间的集合):

/*src/AppBundle/Entity/HoraireSalle.php*/

class HoraireSalle
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dateFrom", type="datetime")
     */
    private $dateFrom;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dateTo", type="datetime")
     */
    private $dateTo;

    /**
     * @ORM\ManyToOne(targetEntity="Horaire", inversedBy="salles")
     */
    private $horaire;

    /**
     * @ORM\ManyToOne(targetEntity="Salle", inversedBy="horaires")
     */
    private $salle;
    ...
}

2 个答案:

答案 0 :(得分:1)

感谢@ADyson,我或多或少地做了我想要的事情。这是我的解决方案。

function isAllowed(start, end) {

        var events = $('#full-calendar').fullCalendar('clientEvents', function (event) {
            return event.rendering === 'inverse-background' && event.start && event.end;
        });

        var allow = events.filter(function (event) {
            return (start.isBetween(moment(new Date(event.ranges[0].start)), moment(new Date(event.ranges[0].end)))
                && end.isBetween(moment(new Date(event.ranges[0].start)), moment(new Date(event.ranges[0].end)))
                && start.format("HH:mm") >= event.start.format("HH:mm") && end.format("HH:mm") <= event.end.format("HH:mm")
                && event.dow.indexOf(start.day()) > -1
                && event.dow.indexOf(end.day()) > -1)
        });

        events = $('#full-calendar').fullCalendar('clientEvents', function (event) {
            return event.rendering !== 'inverse-background' && event.start && event.end;
        });


        var overlap = events.filter(function (event) {
            return event.start.isBefore(end) && event.end.isAfter(start);
        });

        if (allow.length && overlap.length == 0) {
            return true;
        }
        return false;
    }

    function FCInit() {
        var formatColumn, formatColumnWeek;

        if ($(window).width() < 600) {
            formatColumn = 'ddd';
            formatColumnWeek = 'ddd\nDD/MM';
        }
        else {
            formatColumn = 'dddd';
            formatColumnWeek = 'dddd\nDD/MM';
        }

        var fcOpts = {
            header: {                               // Ordre des boutons de l'entete
                left: 'today,datePickerButton',
                center: 'prev,title,next',
                right: 'month,agendaWeek,agendaDay'
            },

            contentHeight: 'auto',                  
            eventLimit: false,                      
            allDaySlot: true,                   
            slotEventOverlap: false,            
            nowIndicator: true,                                     
            timeFormat: 'H:mm',                     
            columnFormat: formatColumn,             
            navLinks: true,                                             
            eventOverlap: false,
            selectable: true,
            selectHelper: true,
            {% if businessHours is defined and businessHours is not empty %}
            selectAllow: function (eventInfo) {
                return isAllowed(eventInfo.start, eventInfo.end);
            },
            {% else %}
            selectOverlap: false,
            {% endif %}
            unselectCancel: '#reservation',
            views: {                                
                week: {
                    columnFormat: formatColumnWeek
                }
            },

            events: [{
                 id:3,
                 title:"R\u00e9serv\u00e9",
                 start:"2017-11-02 08:00",
                 end:"2017-11-02 10:00",
                 overlap:false,
                 color:"#C41305"
        },{
                 id:999,
                 className:"fc-nonbusiness",
                 title:"",
                 start:"08:00",
                 end:"17:00",
                 dow:[4],
                 ranges:[
                    {
                      start:"2017-11-01",
                      end:"2017-11-30"
                    }
                 ],
                 rendering:"inverse-background",
                 }],

            /* Ajout de datepicker (nécessite Jquery UI css et js) */
            customButtons: {
                datePickerButton: {
                    text: '',
                    click: function () {

                        var $btnCustom = $('.fc-datePickerButton-button'); // name of custom  button in the generated code
                        $btnCustom.after('<input type="hidden" id="hiddenDate" class="datepicker"/>');

                        $("#hiddenDate").datepicker({
                            flat: true,
                            showOn: "button",
                            dateFormat: "yy-mm-dd",
                            onSelect: function (dateText, inst) {
                                $('#full-calendar').fullCalendar('changeView', 'agendaDay', dateText);
                            }
                        });

                        var $btnDatepicker = $(".ui-datepicker-trigger"); // name of the generated datepicker UI
                        //Below are required for manipulating dynamically created datepicker on custom button click
                        $("#hiddenDate").show().focus().hide();
                        $btnDatepicker.trigger("click"); //dynamically generated button for datepicker when clicked on input textbox
                        $btnDatepicker.hide();
                        $btnDatepicker.remove();
                        $("input.datepicker").not(":first").remove();//dynamically appended every time on custom button click

                    }
                }
            },
            dayRender: function (date, cell) {
                if (date.isBefore(new Date())) {
                    cell.css('cursor', 'no-allowed');
                }
            },

            eventRender: function (event, element, view) {

                if (event.rendering === 'inverse-background' && event.ranges) {
                    return (event.ranges.filter(function (range) { // test event against all the ranges

                        var start = moment(new Date(range.start));
                        var end = moment(new Date(range.end));
                        return (view.start.isSameOrBefore(end) &&
                            view.end.isSameOrAfter(start)) &&
                            view.start.day(event.dow[0]).isBetween(start, end);

                    }).length > 0);
                }

                if (event.rendering === "background") {
                    // Just add some text or html to the event element.
                    $(element).data("title",event.title);
                }

            },
            dayClick: function (date, jsEvent, view) {
                if (date.isSameOrAfter(new Date()) && view.name === 'month') {
                    $('#full-calendar').fullCalendar('changeView', 'agendaWeek', date);
                }
            },
            select: function (start, end, jsEvent, view) {
                if (start.isSameOrAfter(new Date()) && view.name !== 'month') {
                    $('#reservation_dateFrom').val(start.format('DD/MM/YYYY HH:mm'));
                    $('#reservation_dateTo').val(end.format('DD/MM/YYYY HH:mm'));
                    $('#reservation').modal('show');
                } else if (start.isBefore(new Date())) {
                    alert('Il n\'est pas possible de réserver dans le passé');
                    $('#full-calendar').fullCalendar('unselect');
                }

            }

        };
        $('#full-calendar').fullCalendar(fcOpts);

答案 1 :(得分:0)

工作示例fullcalendar动态范围

假设您需要在以下日期范围之间要求事件

start: "2018-06-01",

end: "2018-08-01"

http://jsfiddle.net/521wucLq/