FullCalendar event duplicate after the first even - javascript

when I select an event it's ok, after I get duplicated, quadrupled, etc.
Why? I don't undertastand why it's
This is my code in javascript
$('#calendar').fullCalendar({
snapDuration: '00:30:00',
selectable: true,
aspectRatio: 1.8,
scrollTime: '08:00', // undo default 6am scrollTime
resources: '{!! route('fullcalendar.roomall') !!}',
events: '{!! route('fullcalendar.bookingall') !!}',
select: function( start, end, jsEvent, view, resourceId) {
$('#event-modal').find('input[name=title]').val('');
// set values in inputs
$('#event-modal').find('input[name=evtStart]').val(
start.format('YYYY-MM-DD HH:mm:ss')
);
$('#event-modal').find('input[name=evtEnd]').val(
end.format('YYYY-MM-DD HH:mm:ss')
);
// show modal dialog
$('#event-modal').modal('show');
/*
bind event submit. Will perform a ajax call in order to save the event to the database.
When save is successful, close modal dialog and refresh fullcalendar.
*/
$("#event-modal").on('click','.save', function(event) {
event.preventDefault();
var id = resourceId['id'];
var roomName = resourceId['title'];
var title = $('#title').val();
var start = $('#evtStart').val();
var end = $('#evtEnd').val();
$('#event-modal').modal('hide');
$.ajax({
url: '{{ route('events.save') }}',
data: $("#event-modal").serialize(),
type: 'post',
dataType: 'json',
data: {
'_token': $('input[name=_token]').val(),
'title': title,
'start': start,
'end': end,
'roomId': id,
'roomName': roomName
},
success: function(response) {
callback(response);
$("#calendar").fullCalendar( 'refetchEvents');
}
});
});
},
});
when I select an event it's ok, after I get duplicated, quadrupled, etc.
Why? I don't undertastand why it's

The problem is because you keep on adding more and more "click" event handlers to the "save" button every time the "select" callback runs.
$("#event-modal").off("click", ".save").on('click','.save', function(event) {
should fix your issue (.off() removes the specified event handlers from the element).
Questions of this nature get asked all the time. You need to understand that adding an event handler to an element doesn't remove the previous ones, they can all exist together, and they all will continue to respond to events until you remove them.

Related

How do you Get and Add events to a specific source?

I was successfully able to specify multiple sources: My SQL server source, and an empty array to hold any user-generated events userAddedEvents = []. The idea was that I could use this array later to "save" new events to my server.
var userAddedEvents = []; //container for event objects that will hold user-generated content
var calendar = new FullCalendar.Calendar(calendarEl, {
eventSources: [
{
events: function (fetchInfo, successCallback, failureCallback) {
$.ajax({
url: url,
type: 'post',
contentType: "application/json; charset=utf-8", //include fetchInfo in request body instead of form-data
dataType: "json",
data: JSON.stringify(fetchInfo), //the fetchInfo object must be stringified
success: function (data) {
events = $.merge([], data.events);
successCallback(events);
}
});
}
}, //end server source
{
id: 'userAddedEvents',
events: userAddedEvents
} //end local array source
]
});
So, here's me trying to add an event to my userAddedEvents source...
select: function (info) {
// https://fullcalendar.io/docs/select-callback
console.log(info)
console.log('selected ' + info.startStr + ' to ' + info.endStr)
calendar.addEvent({
start: info.startStr,
end: info.endStr,
rendering: 'background', //v4 and v5 use different terminology
color: '#ff9f89',
selected: true, //custom, extended property
}, userAddedEvents);
calendar.unselect(); //clear the current selection
},
Anyway, long story short... when I try to dump out the results of userAddedEvents, it's empty, although, I do see new content on my calendar.
==UPDATED== with example included... I added a custom button where I attempt to get content from the userAddedEvents array.
Alternatively (also shown in the example), I've had success getting ALL events with calendar.getEvents(), then using $.grep to filter some specific property or extended property. Ultimately though, I suppose I'm trying to use a "temporary event source" for the sake of convenience -- I can act upon the userAddedEvents array, stringify it, empty it, etc. I do not know how to getEvents for a specific source object.
customButtons: {
getUserCreatedEvents: {
text: 'Get User Events',
click: function () {
console.log(calendar.getEventSources()); //both event sources are listed
console.log(calendar.getEventSourceById(userAddedEvents)); //missing the id in output {calendar, id, internalEventSource, url}
console.log(calendar.getEventSourceById('userAddedEvents')); //has the the id in output {calendar, id, internalEventSource, url}
console.log(userAddedEvents) //the array is empty
/*
events = calendar.getEvents();
// console.log(events)
var filteredResultsGREP = $.grep(events, function (event) {
return event.rendering === 'background';
});
*/
/*
https://fullcalendar.io/docs/Event-toPlainObject (version 5 only)
*/
// this WILL show any events added based on the property specified
// console.log(filteredResultsGREP);
}
}
}
How do I get the events that are new? I want to hold all user-created events before I send them to SQL for processing.
Firstly, apologies for totally forgetting about this question, having started to help with it.
After some digging it looks like you can't get the raw events for an individual event source, which is a bit annoying.
So I think actually your simplest approach is just to add the events to your separate array, without worrying about the structure in fullCalendar. Then you can just send that list to the server when you want to save them.
select: function (info) {
var evt = {
start: info.startStr,
end: info.endStr,
rendering: "background", //v4 and v5 use different terminology
color: "#ff9f89",
selected: true //custom, extended property
};
calendar.addEvent(evt);
userAddedEvents.push(evt);
calendar.unselect(); //clear the current selection
},
Demo: https://codepen.io/ADyson82/pen/abdVVNM
The only extra complication you might have is if you allow events to be dragged or resized (or otherwise edited) after they've been added, you'll have to sync that with the separate array, which is a bit of extra work.

Add another event source FullCalendar?

I try to add another event source on my FullCalendar. First, I get all events from manual function that I create own and I render all events using renderEvent function. But, I got error when I try to add another event source. So, I want to add holidays feature. I create another event source to get holidays date. That event was success to showed in my FullCalendar. But there is weird thing.
Example : If I have range of my holiday date, such as start : 2019/02/26 - end : 2019/02/28. The event content length doesn't 26 until 28, but start from 26 until 27.
What it's wrong? This is my code for to get all events.
// Get Agenda Data
function getEvents(datas) {
$("input[name=unitAgenda]").attr("value",
$("select[name=unit]").val());
var reUnit = datas.replace("- ","");
$('.calendar').fullCalendar('removeEvents');
$('.calendar').fullCalendar('refetchEvents');
$.ajax({
url: 'agendakerja/kalender/get_events',
dataType: 'JSON',
data: { unit: reUnit },
success: function(data) {
$.each(data["events"], function (index, event) {
$('.calendar').fullCalendar('renderEvent', event, true);
});
}
});
//passing unit name to function
global = reUnit;
}
And this is my code for get holidays date.
eventSources: [
{ url: 'agendakerja/kalender/get_holidays' }
]
Please help me!

FullCalendar: refetchEvents call causes to all meetings to blink during re-rendering

I play with fullCalendar and I use refetchEvents:
$('#calendar').fullCalendar('refetchEvents');
It works properly and this command calls events method with callback
events: function (start, end, timezone, callback) { /* ... */ }
however it first remove all meetings from calendar and after - renders new ones. This approach causes to all table to blink (different from google behaviour).
Is there any other way to render meetings without clear-add?
Seems like I need to add only deltas that makes work too hard, messy and not stable
Thanks,
My suggestion is to do the ajax request first (where you initially put .fullCalendar('refetchEvents')), and if it succeeds, then call refetchevents. The code will look something like this:
var events = [];
$.get('/events/get', function(result){
events = result;
});
$('#calendar').fullCalendar({
events: function (start, end, timezone, callback) {
callback(events);
}
});
Add this in your ajax parameter :
async:false,
$.ajax({
url: calendar_url + '&start'+start.unix()+'&end='+end.unix(),
dataType: 'JSON',
async:false,
success: function(response) {
}
})
Use below approach instead of refetchEvents so it's not blinking.
var events = {
url: '/getEVents',
type: 'GET',
}
$('#calendar').fullCalendar('removeEventSource', events);
$('#calendar').fullCalendar('addEventSource', events);

jquery mobile - pageinit event no triggered when using mobile.changePage

I have the following code for handling on click event of a button:
$(document).on("click", '.submit_review_button', function(event, ui) {
var place = $.data(this, "object");
var ttext = $("#review_text").val();
var review = new Object();
review.business_place_id = place._id;
review.review = ttext;
review.user_id = user._id;
// var review = {business_place_id:place.id, review: ttext, user_id: user.id}
$.ajax({
url: site_url + '/reviews/',
type:'POST',
data: review,
success: function(data) {
$.mobile.changePage("show_reviews_page", {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true
});
// initShowReviewsPage();
},
error:function(data) {
alert(1);
}
});
});
I also have this code in document-ready:
$("#show_reviews_page").on('pageinit', function() {
initShowReviewsPage();
});
I know that the pageInit binding works, because if I go to #show_reviews_page using it works.
But when clicking on the .submit_review_button button, the on click event fires, the page changes but the init doent fire and the page is not valid.
Any idea why it doesnt work?
"pageinit" event is fired only once when the page loads in the DOM for the first time.
If you want fire a function everytime you go to a page, use "pageshow" or "pagebeforeshow" events.

toggling class on click by javascript on ajax post success

This code works fine for first click as it changes class along with image which is referenced from CSS. But when I click second time it acts like clicked in previous class which I assume removed already.
if(Model.SeenItWantToSeeIt.Status==1)
{
<div class="movie_data">
<div class="usermovie_option"> </div>
</div>
<div class="clear"></div>
}
else{
<div class="movie_data">
<div class="usermovie_option"> </div>
</div>
<div class="clear"></div>
}
And Javascript for toggling class is
$(".want_to_see_it").click(function () {
var wantToSeeIt = $(this);
alert('clicked on want to see it.');
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: 1, MovieID: movieID },
dataType: 'json',
type: "POST",
success: function (data) {
wantToSeeIt.removeClass();
wantToSeeIt.addClass("dont_want_to_see_it");
$("dont_want_to_see_it").show();
},
error: function (data) {
alert('Error occurred.');
}
});
});
$(".dont_want_to_see_it").click(function () {
alert('clicked on donot want to see it');
var wantToSeeIt = $(this);
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: 0, MovieID: movieID },
dataType: 'json',
type: "POST",
success: function (data) {
wantToSeeIt.removeClass();
wantToSeeIt.addClass("want_to_see_it");
$("want_to_see_it").show();
},
error: function (data) {
alert('Error occurred.');
}
});
});
And problem is it shows "clicked on donot want to see it" or "clicked on want to see it" as alert every time I click . What I have to do is this message should alternate every time I Click on their respective image.
Problem here is that you want to change the handlers dynamically on click of each element. But events are bound to the element directly using click event.
One option is to hide and show respective items.
Another option is to bind and unbind events.
Third option is to use event delegation. Your requirement will work with this since with event delegation events are not directly attached to the elements, they are instead delegated. So the moment you swap the class name event subscribed for that class name will automatically get delegated. SO next click on the same element will go to the other event handler attached its new class name. See if this is what you were looking for.
$(document).on('click',".want_to_see_it" ,function (e) {
var wantToSeeIt = $(this);
alert('clicked on want to see it.');
///Your ajax
wantToSeeIt.removeClass();
wantToSeeIt.addClass("dont_want_to_see_it");
$(".dont_want_to_see_it").show();
});
$(document).on('click',".dont_want_to_see_it" ,function (e) {
alert('clicked on donot want to see it');
var wantToSeeIt = $(this);
///Your ajax
wantToSeeIt.removeClass();
wantToSeeIt.addClass("want_to_see_it");
$(".want_to_see_it").show();
});
Note:- In the example i have attached to the document, You should n't attach it to the document, instead attach it to any containing element that is present in DOM at any time.
Demo
There was another issue, you missed . before the classname in your ajax success.
The problem is you need to unbind("click") to clear the previous handler then bind a new event handler for its new class.
Instead of unbinding and rebinding, do in one handler:
$(".usermovie_option a").on("click", function () {
var status = 0;
if ($(this).hasClass("want_to_see_it")) {
status = 1;
}
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: status, MovieID: movieID,
dataType: 'json',
type: "POST",
success: function (data) {
$(this).toggleClass("want_to_see_it");
$(this).toggleClass("dont_want_to_see_it");
},
error: function (data) {
alert('Error occurred.');
}
});
});

Categories

Resources