在我的项目中,用户可以预订房间。我的房间有几个小时(例如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;
...
}
答案 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"