How can I set up rule for selectable FullCalendar - javascript

I am trying to set up a rule for selectable attribute. The rule should be like this:
selectable attribute is true for future weeks, otherwise false
However, I could not find how can I check dates in calendar option. I tried some ways but javascript does not accept these ways. Here is my current option. Any helps ?
$(document).ready(function () {
$('#calendar').fullCalendar({
//some options
//some options
selectable: true,
selectHelper: true,
select: function (start, end) {
var title = loadRequired("ff8081815c776701015c7788151d06b4",
"activity",
"#Session["token"].ToString()");
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
}
$('#calendar').fullCalendar('unselect');
},
});
});

I could be mistaken but because selectable is just a bool and doesn't accept a callback I don't think there is a nice way of doing this. I would probably set it to true and then catch it in the select callback.
In the select callback you could check if the selected date is in the future and if it is just call unselect and return from the function.

You can do either/both of these:
1) In the "select" callback, check the start/end dates. If they're before the date that you want to allow, then don't continue to process the code, just return false.
2) You could also set the validRange property so that events can't even be dragged onto the areas you choose to exclude: https://fullcalendar.io/docs/current_date/validRange/

I checked situation on select atrr.
select: function (start, end) {
var check = end.unix()*1000;
var today = #weekdays[6]*1;
if(today > check)
{
$('#calendar').fullCalendar('unselect');
}else
{
$('#calendar').fullCalendar('select');
var title = loadRequired("ff8081815c776701015c7788151d06b4",
"activity",
"#Session["token"].ToString()");
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
}
}
},
now I can do what I want on functionality. However, I can still select the area on calendar, the area's color changed to blue, then it goes my check point, and if situation is false: unselect atrr is activated.
Is there any way to do this ? Actually selectable attribute should not be true when the area is in the past and should be true on future weeks

Related

renderEvent after selecting dates not working in Fullcalendar

I would like to add and render event by selection of dates range. select() is correctly fired, but there is error calendar.fullCalendar is not a function on the last line. I googled a lot but did not find any working solution.
I use FullCalendar v4 in timeline-view.
var calendar = null;
document.addEventListener('DOMContentLoaded', function() {
calendar = new FullCalendar.Calendar(document.getElementById('preview'), {
editable: true,
eventResizableFromStart: true,
eventResourceEditable: true,
selectable: true,
...
select: function(selectionInfo) {
var event = new Object();
event.title = 'title';
event.start = selectionInfo.start;
event.end = selectionInfo.end;
event.resourceId = selectionInfo.resource.id;
calendar.fullCalendar('renderEvent', event); // console says 'calendar.fullCalendar is not a function'
//$('#preview').fullCalendar('renderEvent', event); // I also tried this, but the same error as above
}
});
});
calendar.fullCalendar('renderEvent', event);
...I guess you copied this from somewhere? Because this is fullCalendar version 3 syntax. for version 4 you would write
calendar.addEvent(event);
See https://fullcalendar.io/docs/Calendar-addEvent for documentation. Always check that the examples you find apply to the correct version of the software.

Change date range to show events in FullCalendar

I need to be able to set a "date range" with FullCalendar, using the "List" view. By date range, I mean being able to enter using 2 text fields, 2 different dates, for example :
Text field 1 : 2018-05-05
to
Text field 2 : 2018-05-06
And to filter the content of the calendar, using the List view to display the result, and show events that matches that date range.
Here's my code for the FullCalendar part:
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'listMonth, month,agendaWeek,agendaDay'
},
defaultView: 'listMonth',
locale: 'fr',
contentHeight: 600,
navLinks: true, // can click day/week names to navigate views
selectable: false,
eventRender: function(event, element, view) {
element.find('.fc-widget-header').append("<div style='color:#fff'>Conférencier choisi</div>");
element.find('.fc-title').append("<br/>" + event.lieu);
element.find('.fc-list-item-title').append("<br/>" + event.lieu);
element.find('.fc-list-item-title').append("<a href='" + event.lienconferencier + "'><div class='conferencier-calendrier-container'><div style='float:left;background-image:url(" + event.photoconferencier + ");width:40px;height:40px;background-size:cover;border-radius:100px;'></div><div style='float:left;padding-left:5px;font-weight:normal;'><strong>Conférencier</strong><br>" + event.conferencier + "</div></a>");
return ['all', event.status].indexOf($('#filter-status').val()) >= 0 &&
['all', event.client].indexOf($('#filter-contact').val()) >= 0 &&
['all', event.conferencier].indexOf($('#filter-conferencier').val()) >= 0 &&
['', event.numero].indexOf($('#numero').val()) >= 0;
},
selectHelper: true,
editable: false,
eventLimit: true, // allow "more" link when too many events
events: [
{
title: 'Example',
start: '2018-05-05',
end: '2018-05-06',
color: '#ff0000',
lieu: 'Montreal',
numero: '300445',
conferencier: 'John Doe',
photoconferencier: 'http://www.example.com/img/profile.jpg',
lienconferencier: 'http://www.example.com/profile/link.html',
url: 'http://www.google.com'
},
{
title: 'Example2',
start: '2018-05-08',
end: '2018-05-010',
color: '#ff0000',
lieu: 'New York',
numero: '300446',
conferencier: 'Steve Jobs',
photoconferencier: 'http://www.example.com/img/profile2.jpg',
lienconferencier: 'http://www.example.com/profile/link2.html',
url: 'http://www.apple.com'
},
],
});
And here's my text fields code:
<input type="text" placeholder="Date : From" id="start_date">
<input type="text" placeholder="Date : To" id="end_date">
I think I would have to add something like this:
$('#start_date').on('change', function () {
$('#calendar').fullCalendar('rerenderEvents');
});
$('#end_date').on('change', function () {
$('#calendar').fullCalendar('rerenderEvents');
});
But I am not sure. Also, please keep in mind that there's other filters too. Hence the "eventRender" part in the code with a bunch of stuff. So I need to make sure that "dateRange" filter won't break the other filters.
I read about "visibleRange" on FullCalendar's website, but I do not understand how I can make it work based on what is entered in the 2 "date range" text fields. I think also disabling the other views that I have set (to show the result in the List view only), would be a good idea.
Any idea how I can make it work? I'm kind of lost here.
Thanks a lot
EDIT :
I have tried this code:
$('#start_date').on('change', function () {
$('#calendar').fullCalendar('changeView', 'list', {
start: 2018-05-10,
end: 2018-05-30
});
});
Which is working. Basically, what it does is that I enter a new date in a text field with the ID of "start_date" (which uses a datepicker script, to that's why I went with "on change"), it changes the view to the list view, which is great, and displays only the events between the date I have entered. So to make it dynamic, I did this :
$('#start_date').on('change', function () {
var start_date = $('#start_date').val();
var end_date = $('#end_date').val();
$('#calendar').fullCalendar('changeView', 'list', {
start: start_date,
end: end_date
});
});
I have 2 fields, "start_date", and "end_date".
I thought that setting the "start" and "end" option in the changeView code for FullCalendar would update automatically everytime I select a new date, but it doesn't work. In fact, it works partially. If I enter the "end_date" first, then the "start_date", it will filter and work perfectly, showing the right date range. But after that, I cannot change it for another dateRange by changing the dates in the fields.
It acts like this probably because my function is "on change", based on the "#start_date" element. So I have to select the end_date first, to make sure it filters and change the view with something in the "end" option.
Any idea what I am doing wrong?
Thanks
EDIT 2 :
I tried changing the function from a "change" event to "click", and adding a "search" button. There's 2 issues here.
1 - It works only once. If I make a search, then change the date, and click again on the "#search-range" button, it won't do anything.
2 - When it works (first time after page load), if I select from May 1rst to May 5th for example, it will show the range from May 1rst to May 4th, for some reasons. Here's my code again :
$('#search-range').on('click', function () {
var start_date = $('#start_date').val();
var end_date = $('#end_date').val();
$('#calendar').fullCalendar('changeView', 'list', {
start: start_date,
end: end_date
});
});
Any ideas what's going on?
Thanks again
You're probably looking for the validRange option.
$('#start_date').on('change', function(){
$('#calendar').fullCalendar('option', 'validRange', {
// Don't worry if user didn't provide *any* inputs.
start: this.value,
end: $('#end_date').val()
});
});
$('#end_date').on('change', function(){
$('#calendar').fullCalendar('option', 'validRange', {
// Don't worry if user didn't provide *any* inputs.
start: $('#start_date').val(),
end: this.value
});
});
Demo: https://jsfiddle.net/8wd7sxyv/
UPDATE
The end date is now inclusive. So if end date is 2018-05-31, events on that day are included — the default behavior only includes up to 2018-05-30.
If the start and end dates are in same month, view is listMonth; otherwise, it is listYear.
function filterByDateRange(start_date, end_date, format) {
var s = $.fullCalendar.moment(start_date),
e = $.fullCalendar.moment(end_date),
v = $('#calendar').fullCalendar('getView'),
a, b;
// Start date is invalid; set it to the start of the month.
if (! s.isValid()) {
b = e.isValid();
s = b ? e.clone() : $.fullCalendar.moment();
s.date(1);
$('#start_date').val(s.format(format));
a = true;
}
// End date is invalid; set it to the end of the month.
if (! e.isValid()) {
b = s.isValid();
e = b ? s.clone() : $.fullCalendar.moment();
e.date(e.daysInMonth());
$('#end_date').val(e.format(format));
a = true;
}
// Start date is after end date; set it to a day before the end date.
if (s.isAfter(e)) {
s = e.clone().add('-1', 'day');
$('#start_date').val(s.format(format));
// End date is before start date; set it to a day after the start date.
} else if (e.isBefore(s)) {
e = s.clone().add('1', 'day');
$('#end_date').val(e.format(format));
}
// Add 1 day so that `end_date` is inclusive.
e = e.isValid() ? e.add('1', 'day') : e;
$('#calendar').fullCalendar('option', 'validRange', {
start: s.isValid() ? s : null,
end: e.isValid() ? e : null
});
a = a || s.isSame(e, 'month');
// If months are different, switch to the year list.
if ('listYear' !== v.name && ! a) {
$('#calendar').fullCalendar('changeView', 'listYear');
// Otherwise, switch back to month list, if needed.
} else if ('listMonth' !== v.name) {
$('#calendar').fullCalendar('changeView', 'listMonth');
}
}
$('#start_date').on('change', function(){
filterByDateRange(this.value, $('#end_date').val(), 'YYYY-MM-DD');
});
$('#end_date').on('change', function(){
filterByDateRange($('#start_date').val(), this.value, 'YYYY-MM-DD');
});
Demo: https://jsfiddle.net/8wd7sxyv/6/

fullcalendar: display all events of a specific day when hovering his daycell

I'm developing a Calendar application via fullcalendar.
I'm currently working on a mini sized calendar. The mini calendar will not display the events.
I'm trying to use tooltip instead. so when the user will mouseover a specific daycell - all the events of the specific daycell will be displayed via tooltip. (this is my issue)
I been working on this issue for almost two days now.
unfortunately, full calendar only offers "eventMouseover". (no dayMouseover available).
Also, using $(".fc-day").hover is not really the best way to go because it is working only when hovering the bottom of the cell.
there is no documentation for this on the web so far.
Anybody knows which is the best way to Tackle an issue?
here is my code so far:
$("#miniCalendar").fullCalendar({
defaultDate: currentDate,
viewRender: function (view, element)
{
monthStart = view.intervalStart.format("YYYY-MM-DD");
monthEnd = view.intervalEnd.subtract(1, "days");
monthEnd = view.intervalEnd.format("YYYY-MM-DD");
mStart = view.intervalStart.format("M");
yStart = view.intervalStart.format("YYYY");
},
events: function (start, end, timezone, callback) { //custom events function to be called every time the view changes
$.ajax({
url: getMonthDataUrl,
type: "post",
data: {
startDate: monthStart,
endDate: monthEnd,
custom_config: Config
},
error: function () {
//alert("there was an error while fetching events!");
},
success: function (data) {
calendarData = data;
console.log(calendarData);
thingsToDoAfterWeLoadCalendarData(calendarData);
callback(eventsJsonArray); //pass the event data to fullCalendar via the supplied callback function
}
});
},
fixedWeekCount: false,
dayRender:
function (date, cell) {
//the events are loaded vie eventAfterAllRender function
//eventAfterAllRender takes time to load. so we need dayRender function in order to give the calendar default colors until the real colors are loaded
// the default colors spouse to look like the correct colors. this is needed for a better looking calendar while loading new events
if (!cell.hasClass("fc-other-month")) {
//that means this is a cell of this current month (becuase only cells that belong to other month have the "fc-other-month" class
var weekDay = date.format("dddd");
if (weekDay == "Saturday" || weekDay == "Friday") {
cell.css("background-color", "#edf5f9");
} else{
//regular days
cell.css("background-color", "#f7fafc");
}
} else{
//cells that belong to the other months
$(".fc-other-month").css("background-color", "#ffffff");
}
},
eventAfterAllRender:
(function(view, event, element) {
let viewDisplay = $("#miniCalendar").fullCalendar("getView");
if (viewDisplay.name == "month") { //checking if this the month view. this is needed for better display of the week\day view (if we ever want to use it)
$(".fc-day:not(.fc-other-month)").each(function(index, element) {
//loop through each current month day cell
$(this).empty(); //removing old icons in case they are displayed
let cellDate = moment($(this).data("date")).format("YYYY-M-D"); // "YYYY-M-D" date format is the key in the json_backgrundColorBigCalendar array
$(this).css("background-color", json_backgrundColorBigCalendar[cellDate]); //set the background colour of the cell from the json_backgrundColorBigCalendar array.
});
}
$(".fc-other-month").css("background-color", "#ffffff"); //days that belong to other month gets a color background that will show this days are irrelevant
}),
dayClick: function(date, jsEvent, view) {
window.location = fullCalendarUrl;
},
});
I dont really know if there is a "fullcalendar-way" doing this, but why can't you use your hover event listener and just also let it listen on fc-day-top hover?
$(".fc-day, .fc-day-top").hover(function(e) {
console.log($(e.currentTarget).data("date"));
});
This will also work if you hover the top of a day cell.
Update:
To get the events on hover use this:
var $calendar = $("#calendar");
$(".fc-day, .fc-day-top").hover(function(e) {
var date = moment.utc($(e.currentTarget).data("date"));
var events = $calendar.fullCalendar("clientEvents", function(event) { return event.start.startOf("day").isSame(date); });
console.log(events);
});
(Tested on the calendar on the fullcalendar main site).
Of course you have to change the jQuery selector of the calendar (#calendar) as it is in your code.
I've never seen full calendar before, but if I understand correctly you want to bind a hover function to custom days of the calendar. Is that correct?
If so you can simply select days of the calendar with their "data-date" attribute. So something like the code below would let you specify a hover function for a desired day:
$("[data-date='2017-10-10']").hover(function(e) {
console.log("You moused over 10/10/2017!");
});

FullCalendar does not unselect previous selection

I've been working with FullCalendar lately for a reservation system.
The problem is that whenever I select a time range it all adds to the eventData object. What I am trying to do is select one time range only.
When I click the $('#btn-reserve') button it should render the event on the calendar.
What's happening is that even my previous selections are getting rendered on the calendar. I only want to render the last selection I made.
here is my code
$('.calendar').fullCalendar({
selectable: true,
select: function(start, end) {
$('#end_time').val(end);
$('#start_time').val(start);
$('#newScheduleModal').modal({
show : true,
backdrop: 'static',
keyboard: false
});
$('#btn-reserve').click(function(){
eventData = {
title: 'Lesson Schedule',
start: start,
end: end
};
$('.calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
$('#newScheduleModal').modal('hide');
});
$('#btn-cancel-reserve').click(function(){
$('.calendar').fullCalendar('unselect');
eventData = {};
})
},
})
You are adding a new click event every time the calendar is selected. You need to unbind the click before adding it like so:
$('#btn-reserve').off('click').click(function
You might want to do the same for your "#btn-cancel-reserve" element.

fullcalendar add events dynamically

I'm trying to create events in my full calendar dynamically.
I have:
$('#calendar').fullCalendar({
viewRender: function (view) {
var h;
if (view.name == "month") {
h = NaN;
}
else {
h = 2500; // high enough to avoid scrollbars
}
$('#calendar').fullCalendar('option', 'contentHeight', h);
},
lang: 'fr',
events: [
{
title: '8 présents',
start: data[0]
},
{
title: '8 excusés',
start: data[1]
},
{
title: '8 excusés',
start: '2015-01-08'
},
{
title: '8 présents',
start: '2015-01-08'
},
],
dayClick: function (date, jsEvent, view) {
window.location.replace(Routing.generate('dateChoisie', {date: date.format()}));
}
})
I have a var data, which is an array that contains all the dates of the events. I want to insert this in the events in the same way I inserted data[0], data[1], etc, but dynamically for all the dates.
I have tried to do a for:
events: [
for (var i = 0, max = data.Lenght; i < max; i++) {
{
title: '8 présents',
start: data[i]
},
}
{
title: '8 excusés',
start: data[1]
},
{
title: '8 excusés',
start: '2015-01-08'
},
{
title: '8 présents',
start: '2015-01-08'
},
],
But it doesn't work inside the list.
Anybody know how I can do this?
after rendering the full calendar you can add events dynamically.
var event={id:1 , title: 'New event', start: new Date()};
$('#calendar').fullCalendar( 'renderEvent', event, true);
I was searching for a while and I have found an possibility.
It was very easy at the end...
I let this here, maybe anybody is interested in.
for (var i in data)
var monthSource = new Object();
monthSource.title = data[i]+' présents';
monthSource.start = i; // this should be date object
monthSource.end = new Date(y, m, d); //to now
month[a] = monthSource;
a++;
}
$('#calendar').fullCalendar({
viewRender: function (view) {
$('#calendar').fullCalendar( 'removeEvents');
$('#calendar').fullCalendar('addEventSource', month);
}
Source: http://fullcalendar.io/docs/event_data/addEventSource/
You can dynamically add an event source. An Event Source is an url which can for example return json data.
Maybe it might be sufficient for you to fire the refetch event after you changed the event data.
.fullCalendar( 'refetchEvents' )
Source: http://fullcalendar.io/docs/event_data/refetchEvents/
(The accepted solution will lose the event if you do anything complicated; the event added is ephemeral and will spontaneously disappear if you blink too hard. This solution is robust and will work if you do more complicated things.)
Support for persistent events is a bit inelegant. You may have to dump, reload, AND render the entire calendar state...:
var CAL, EVENTS;
$(document).ready(function() {
// set up calendar with an EventSource (in this case an array)
EVENTS = [...];
$('#calendar').fullCalendar({...});
// calendar object
CAL = $('#calendar').fullCalendar('getCalendar');
// extend object (could be its own function, etc.)
CAL.refresh = function() {
CAL.removeEvents();
CAL.addEventSource(EVENTS);
}
// finish setting up calendar
CAL.refresh();
});
Demo:
EVENTS.pop(); // remove last event
refresh(); // refresh calendar; last event no longer there
see https://stackoverflow.com/a/18498338
How about doing as it says on the website example:
https://fullcalendar.io/docs/renderEvent-demo
So add the event, and then use whatever you want to add that to the backend.
Or you can add the event to backend, then return the database's new id and then add it to the timeline, so you'll have the ids right.
Or update the id with return message, whatever rocks your boat.
although it is not specified on the fullcalender site, it is necessary to assign a value to the "allday" parameter to be able to add new events dynamically. If you set this value to "false", it will not add the event to the AllDay row. If you do "true" it will add to the AllDay row.
var event = {
title: 'New Event',
start: Date(Date.now()),
backgroundColor: App.getLayoutColorCode('purple'),
allDay: false
}
jQuery('#calendar').fullCalendar('renderEvent',event,true);
or
var originalEventObject = jQuery(this).data('eventObject');
var copiedEventObject = jQuery.extend({}, originalEventObject);
copiedEventObject.title = "New Event";
copiedEventObject.start = date;
copiedEventObject.className = jQuery(this).attr("data-class");
copiedEventObject.backgroundColor = App.getLayoutColorCode('purple');
copiedEventObject.allDay = false;
jQuery('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
Simple examples of adding events can be found in the example-projects repo. There's currently examples for angular, vue, react, and bootstrap.
Wanted to mention this for anyone not using jquery who stumbles upon this

Categories