Is it possible to limit FullCalendar so when creating an event dragging, the event doesn't go across other days?
I mean: If I start selecting on March 20, at 09:00, I want that the user can't choose the event to finish on March 21, at 13:00.
You can add a eventConstraint to your calendar settings.
eventConstraint:{
start: '00:00', // a start time (start of the day in this example)
end: '24:00', // an end time (end of the day in this example)
},
You can reproduce it in this plunker.
If you want to constraint it only during dragging I think you only can do it using eventDrop callback. There you can use revertFunc to revert the drag&drop movement to the previous state, if moment.startOf('day) are different.
Something like:
$('#calendar').fullCalendar({
events: [
// events here
],
editable: true,
eventDrop: function(event, delta, revertFunc) {
if (!event.start.startOf('day').isSame(event.end.startOf('day'))) {
revertFunc();
}
}
});
$('#calendar').fullCalendar({
events: [
{
title : 'event1',
start : '2010-01-01'
},
{
title : 'event2',
start : '2010-01-09T09:30:00',
end : '2010-01-09T15:30:00',
},
{
title : 'event3',
start : '2010-01-09T12:30:00',
allDay : false // will make the time show
}
]
});
Related
I am working on a drag-drop app for managing employees' shifts, it basically consists of two parts:
1- employees cards on the top (these contain all unassigned employees who have not any shifts)
2- calendar (HTML table element) for the assigned employees and their shifts on weekdays the app
each employee has availability for all weekdays something like this
const DEFAULT_MEMBER_AVAILABILITY = {
friday: { start: '10:00', end: '23:00', all_day: false }, // part-time availability in friday
monday: { start: 'null', end: 'null', all_day: false }, // not available in monday
saturday: { start: '00:00', end: '00:00', all_day: true },// full-time availability in saturday
sunday: { start: '00:00', end: '00:00', all_day: true },
thursday: { start: '00:00', end: '00:00', all_day: true },
tuesday: { start: '00:00', end: '00:00', all_day: true },
wednesday: { start: '00:00', end: '00:00', all_day: true },
};
to show a member's availability just hover on his card and the first row will be colored based on his availability like this:
1- not available on the day: red
2- full-time: green
3- part-time: yellow
hover on a card
and the slots will be reset again when the mouse leaves the card.
the user can assign a shift to an employee by dragging his card and dropping it on the first row.
while dragging the first row will be colored based on his availability like the previous rules.
dragging an employee card
once dropping the employee card will be removed from top and a new row inserted in calender with a new shift in the day dropped on.
the problem is when I drop a card the card is removed and the card which is next to it and will be in the removed card position behave as I hover on it (shows the related member availabilty) even the mouse on the calender.
note*
I am using event delegtion since the dom cahnges alot with 'removing cards' and 'adding cards' with something like this:
this.#employeesCardsContainer.addEventListener(
'mouseenter',
this.#handleEmployeesCardsMouseEnter.bind(this),
true
);
I am not sure if this is helpful or not
"the card which is next to it and will be in the removed card position"
I think the problem happen because of this,I think the mouse position is not being updated while dragging and when dropping the browser behave as the mouse still in his position before dragging.
I need to display all the events of the year starting by the current date, so essentially from March to December, I tried setting up the property visibleRange as follows:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'list' ],
header: {
left: 'prev,next today',
center: 'title',
right: 'listDay'
},
views: {
listDay: { buttonText: 'list day' },
listWeek: { buttonText: 'list week' }
},
defaultView: 'listWeek',
navLinks: true,
editable: true,
eventLimit: true,
events: <?= json_encode($events) ?>,
visibleRange: {
start: '2020-03-01',
end: '2020-12-31'
}
});
calendar.render();
});
the problem's that I get only the month of March is there a way to achieve this?
I get only the month of March
Actually, according to your code, what you will get is only a single week, or a single day. You cannot even show a whole month based on what you have written.
The issue with your attempt though is a simple logical one. You are defined views as listWeek and listDay. The names in these fix a period of time - "week" and "day" which the views will cover. This fixed period takes priority over any visibleRange setting.
If you want your view to take account of the visibleRange, then you must just specify the view name, without a fixed time period in its name:
header: {
left: 'prev,next today',
center: 'title',
right: 'list'
},
defaultView: 'list',
The above however will restrict you to only the exact time period specified. You cannot move to another year. To make this dynamic, you can use a function to calculate the visible range every time the view needs changing:
visibleRange: function(currentDate) {
var yr = currentDate.getFullYear();
return {
start: yr + '-03-01',
end: yr + '-12-31'
}
},
dateIncrement: { "years": 1}
Demo: https://codepen.io/ADyson82/pen/XWbgyGZ
P.S. Specifying a view name without a time period is demonstrated in the visibleRange documentation already.
I'm using FullCalendar.js to show tasks entered by users. For this I have created a pop up to take Event basic details and details about recurrence. An event can recur daily, weekly, 28 day, 31 day , 30 day cycles. I have been able to render events for daily and weekly cases but I cant think about how to render events occurrences with 28/30/31 days between them.
My code for calendar is as follows:
$('#calendar').fullCalendar({
//height: 420,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: moment(),
defaultView: 'month',
eventRender: function (event, element, view) {
console.log(event.start.format());
if (event.ranges == undefined)
return true;
else {
return (event.ranges.filter(function (range) {
if (range.end == undefined)//Check if only start is given
return (event.end.isAfter(range.start))
else
return (event.start.isBefore(range.end) &&//If both start and end date is given
event.end.isAfter(range.start));
}).length) > 0;
}
},
events: function (start, end, timezone, callback) {
var events = getEvents(start, end); //This should be a JSON request
callback(events);
},
eventClick: function (calEvent, jsEvent, view) {
alert('Event: ' + calEvent.title);
//$('#btnOpenPopUp').click();
}
});
and json for events is like so:
{
title: "My repeating event",
id: 1,
start: '10:00', // a start time (10am in this example)
end: '14:00', // an end time (6pm in this example)
dow: [1, 2, 3, 4, 5], // Repeat monday and thursday
ranges: [{
start: moment().startOf('month').subtract(1, 'month'),
end: moment().startOf('month').subtract(1, 'month').add(7, 'd'),
}, {
start: moment('2016-12-15', 'YYYY-MM-DD'), //all of february
//end: moment('2016-11-01', 'YYYY-MM-DD').endOf('month'),
}
I need help to render tasks that occur after every 28 days. Any suggestions?
Maybe you could use later.js project (http://bunkat.github.io/later/index.html) to calculate the occurrences of the tasks. This code sample will produce the all occurrences between 2 dates for every 28 days:
<html>
<head>
<script src="moment.js" type="text/javascript"></script>
<script src="moment-recur-min.js" type="text/javascript"></script>
<script type="text/javascript">
var recurrence = moment().recur("2016-12-06", "2017-12-06").every(28).days();
var allDates = recurrence.all("L");
console.log(allDates);
</script>
</head>
<body>
test
</body>
</html>
I am currently doing some repeating event of fullCalendar in my code. However when switching to next/prev month, my event getting bug or disappear. I know that stick is needed but where should I put it when my code is like this?
var repeatingEvents = [{
title: sub[x],
start: tmefrm[x],
end: tmeto[x],
dow: [har[x]],
ranges: [{
start: moment(dtefrm[x]),
end: moment(dteto[x]),
}],
color: 'green',
}];
var getEvents = function( start, end ){
return repeatingEvents;
}
$('#calendar').fullCalendar({
defaultDate: moment(),
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay',
},
defaultView: 'month',
eventRender: function(event, element, view){
//console.log(event.start.format());
return (event.ranges.filter(function(range){
return (event.start.isBefore(range.end) &&
event.end.isAfter(range.start));
}).length)>0;
},
events: function( start, end, timezone, callback ){
var events = getEvents(start,end); //this should be a JSON request
callback(events);
},
});
I read the docs which it says that event must be an Event Object with a title and start at the very least.
Unless my code is like this it will be easy.
var myCalendar = $('#calendar');
myCalendar.fullCalendar();
var myEvent = {
title: sub[x],
color: 'green',
start: tmefrm[x],
end: tmeto[x],
dow: [har[x]],
ranges: [{
start: new Date(dtefrm[x]),
end: new Date(dteto[x]),
}],
}
myCalendar.fullCalendar('renderEvent', myEvent, [ stick= true]);
What I do ? Is I want to use repeating event, and so far this code make me go far from previous progress but I'm not sure where to put this stick.
Any help would be great :)
It's simple!
myCalendar.fullCalendar('renderEvent', myEvent, true);
I'm using FullCalendar to display events entered by users. As such, I can't control when they are scheduled for.
Strangely, someone has scheduled an event for 11:59pm, and it is basically invisible on FullCalendar's agenda view.
Here is a JSFiddle for the scenario I'm describing. The JS is copied below:
$(function () {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar({
header: false,
contentHeight: 300,
defaultView: 'agendaDay',
scrollTime: '24:00:00',
allDaySlot: false,
slotDuration: '00:15:00',
slotEventOverlap: false,
forceEventDuration: true,
defaultTimedEventDuration: '00:30:00',
displayEventEnd: false,
editable: false,
events: [{
title: 'Earlier (visible) Event',
start: new Date(y, m, d, 22, 00)
}, {
title: 'Late (hard to see) Event',
start: new Date(y, m, d, 23, 59)
}]
});
});
As you'll see on JSFiddle, the "Late (hard to see) Event" renders just two pixels tall at the bottom of the calendar, which is unusable. Is there a solution for this? Maybe some way to view the day through 1am the next morning, for instance?
Add maxTime: "24:59:59". That will extend the agenda view beyond midnight making your event visible.
Here's the jsFiddle: http://jsfiddle.net/0tm5cgjb/2/