FullCalendar does not unselect previous selection - javascript

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.

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.

How can I set up rule for selectable FullCalendar

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

Jquery fullcalendar eventClick function not working

I am using the FullCalendar plugin for my calendar.
I am trying to loop through some ajax data I have acquired and populate my calendar with the relevant fields I want to use.
This is what i'm doing:
for (var i = 0; i < $requests.length; i++)
{
var currEvent = {
title: $requests[i].staff_name,
start: new Date($requests[i].start_date),
end: new Date($requests[i].end_date),
backgroundColor: $requests[i].color,
borderColor: $requests[i].color,
textColor: "white",
}
$module.fullCalendar(
'renderEvent',
currEvent,
true
);
}
This will populate my calendar but i've been trying to add the eventClick callback so i can alert out the event's title or something. But everything I do results in either not outputting to the calendar or outputting with the click function doing nothing. How can I render my events and then assign a click function to each one?
This code will do it, I was also accidentally calling the plugin twice which screwed it up completely.
$module.fullCalendar({
weekends: false,
eventLimit: 3,
editable: false,
disableResizing: false,
events: allEvents,
eventClick: function(event, element) {
alert(event.title);
}
});

Affecting Fullcalendar today button .fc-today-button

I'm having trouble getting custom controls to work when clicking the 'today' button that is part of Fullcalendar.
All the documentation I can find tells me that Fullcalendar's built-in controls can be affected using two methods:
So, this one works for me when it's applied to previous, next, month, agendaWeek and agendaDay, but not for 'today' (button.fc-today-button):
$('body').on('click', 'button.fc-next-button', function() {
console.log('I Clicked Next');
});
Some documentation also say that this works, although I can't make it do so on any button:
$('.fc-next-button span').click(function(){
console.log('I Clicked Next');
});
Does anyone know why this is and what I'm doing wrong?
Well, you want to affect the "today" button, yet you are adding code for the "next" button. You want to do something like:
$(".fc-today-button").click(function() {
alert('Clicked Today!');
});
This applies a click event to anything with the class "fc-today-button" (that is the class that the Today button will have).
Working example:
$('#fullCal').fullCalendar({
events: [{
title: 'Event 1',
start: moment().add(1, 'h'),
end: moment().add(2, 'h'),
allDay: false
}],
header: {
left: '',
center: 'prev title next today',
right: ''
},
timezone:'local',
defaultDate: '2014-11-15',
editable: false,
eventLimit: false,
firstDay: 6,
defaultView: 'agendaWeek',
});
$(".fc-today-button").click(function() {
alert('Clicked Today!');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.1.1/fullcalendar.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.1.1/fullcalendar.min.js"></script>
<div id="fullCal"></div>
After investigation and the help of MikeSmithDev (thanks Mike - your help was invaluable), it appears as though the 'today' event only gets triggered if it physically positioned below/after the calendar, the rest of the header controls (button.fc-next-button etc) don't seem to mind where they are physically positioned.
Likely the first function executes before the calendar is finished loading... so it works, there is just no button to bind it to.
I was able to more or less achieve this with a native workaround of sorts. You may utilize the "customButtons" and "headerToolbar" in combination to effectively remove the original today button and replace it with your own which can trigger custom function code upon being clicked.
I'm actually using this with VueJS, but should be equally feasible with Vanilla JS.
// these are the options you can pass when initializing a fullcalendar
customButtons: {
focusButton: {
text: "focus",
click: this.scrollToCurrentDay // this is a vue component function, but you could just as well pass a vanilla JS function
}
},
headerToolbar: { // this effectively removes the original today button and adds our custom button to the header of the calendar
left: '',
center: 'title',
right: 'prev focusButton next'
}
I wanted to do this because I wanted to not only focus the month when today was clicked, but also to scroll the calendar to the day (useful when using small screens like phones).
My custom today button click handler:
scrollToCurrentDay: function(arg) {
let CalendarAPI = this.$refs.calendar.getApi();
CalendarAPI.today();
var todayElement = document.getElementsByClassName('fc-day-today')[0];
var calendarElement = document.getElementsByClassName('fc')[0];
if (todayElement) {
todayElement.scrollIntoView();
} else {
calendarElement.scrollIntoView();
}
},

Binding an event to an add dialog select input in jqgrid

I have a jqgrid with the add dialog enabled for adding new rows. The way I would like it to work is that the user will select from a list of drop down items and the item chosen will cause a second drop-down to be populated with data based on the first item.
For example, if my grid had two columns, one for country and one for state, when the user clicked the add button, the country input would be a drop-down, dynamically populated with countries by an ajax call. Then, when the user selects a country, the state drop-down is populated based on the country selected.
Currently I am doing something like the following:
beforeProcessing: function () {
var allcountries = ajaxcall();
$('#clientReportsGrid').setColProp('Countries', { editoptions: { value: allcountries, class: 'edit-select' }, editrules: { required: true, edithidden: true} });
},
loadComplete: function () {
$('#Countries').change(function () {
// States will be populated here
alert("changed");
});
}
The first part in beforeProcessing works fine and the countries drop-down is populated as expected. However, the event in loadComplete does not get attached to the select input with id the 'Countries' and the alert never occurs. It seems that the select object has not yet been created with loadComplete fires, but if that is the case I'm not sure where to place the logic where the states will be populated.
Any ideas?
jqGrid has no direct support of depended selects, but in the answer you will find the implementation of the scenario. The most problem is that the code is not small, but it's quickly to analyse a working code as to write your own one.
I ended up doing something like the following, its a bit redundant but it works and isn't too code heavy:
First, in the beforeProcessing callback, I populate both the countries and states drop-downs with their initial values:
beforeProcessing: function () {
var allcountries = ajaxCallToFetchCounties();
$('#clientReportsGrid').setColProp('Countries', { editoptions: { value: allcountries, class: 'edit-select' }, editrules: { required: true, edithidden: true} });
var states = ajaxCallToFetchStates();
$('#clientReportsGrid').setColProp('States', { editoptions: { value: states , class: 'edit-select' }, editrules: { required: true, edithidden: true} });
}
Then in the pager's add option, I used the beforeShowForm callback to attach a method to the change event of the countries select input, and within that method I fetch the states based on the current country and repopulate the select control:
beforeShowForm: function (form) {
$("#Countries").unbind("change").bind("change", function () {
var states = ajaxCallToFetchStates();
//Manually clear and re-populate the states select box here with the new list of states.
});
$('#tr_AccountCode', form).show();
}

Categories