JQuery FullCalendar trouble with invoking rerenderEvents from ajax success - javascript

For some reason, I cannot get the calendar to rerender after a POST. All goes well up to that point:
$('#calendar').fullCalendar({
...
select: function (startDate, endDate) {
$.ajax({
url: 'data.php',
type: "POST",
data: {
'start':startDate,
'end':endDate,
}
success: $('#calendar').fullCalendar('rerenderEvents')
}
...
});
The data posts successfully, my php script adds the new event to the database just fine. The only problem is that the calendar is not being rerendered with the new data in the database.
If I refresh the page (F5 in Firefox) the new event is rendered. Obviously, I need the event to show up as soon as it has been committed to the database. I can't expect my user to refresh the page.
I have done many permutations of this success statment, eg:
function () {
$('#calendar').fullCalendar('rerenderEvents');
}
and (with my php returning 'success'),
function (data) {
if (data === 'success') $('#calendar').fullCalendar('renderEvents');
}
However, no matter what, the new event added to the database only shows up if I refresh the screen. Can anyone suggest what I might be doing wrong?

Try:
$('#calendar').fullCalendar("refetchEvents");
Update 2013-01-31.
That works because you are forcing FC to reread the event source and render the calendar again.
However, if that is sometimes a brute force solution, another way to achieve the same (when possible) is to do this, say in dayClick when creating a new event:
update event-DB using $.ajax
create the corresponding new event:
yourcal.fullCalendar('renderEvent', {id:x,start:timest,end:timend,title:txt}, true);

Related

window.history.pushState the pages do not update

I am using window.history.pushState() to change the url of the page and put it in the history list, everything works but I have a problem, if for example in a page I execute an operation (ajax), which changes the values ​​in the db and textually update a part of the page, if I browse elsewhere and return to this page, I find what was originally there and not the changes made, to see them correctly I have to refresh the page.
I don't currently use any caching systems
Some contents are loaded with ajax others are directly on the page
window.history.pushState() is used only in the home page in the others I don't need it even if it happens on all
in the example page I have this code
function init() {
$('#weekDays').on('show.bs.modal', function(event) {
var modal = $(this);
$.ajax({
type: 'post',
cache: false,
url: '/my_account/get_giorni_chiusura_sett',
dataType: 'html'
}).done(function(data) {
modal.find('.modal-content').html(data);
});
});
$('body').on('click', '#save-closing-days', function() {
var dataString = $('#form-weekdays-close').serialize();
$.ajax({
type: 'post',
cache: false,
url: '/my_account/set_giorni_chiusura_sett',
data: dataString,
dataType: 'json'
}).done(function(data) {
if (data.update === 'ok') {
var daysClose = $.map(data.giorni, function(v) {
return '<strong>' + v + '</strong>';
}).join(' - ');
$('#list-days-close').html(daysClose);
$('#weekDays').modal('hide');
}
});
});
}
when I arrive in the page the content is loaded without ajax and generated by php, the first function loads the content in the modal upon opening, the second one saves / updates the data on the database and updates the text on the DOM
Closing days: Saturday - Sunday
Update and become
Closing days: Sunday
Now I move to other pages from the menu and back, but I find it again:
Saturday - Sunday
If I reload the page, the data is updated
The History API doesn't maintain the state of the DOM for you. You need to do that yourself. MDN has a good guide but the short version is:
When the user clicks a link then your JS should prevent the default behaviour and call pushState to change the URL and use DOM methods to update the page to match what the server would send for that URL.
When the user presses the back button in their browser and a popstate event fires then your JS should read the URL (and state data if applicable) from the event and using DOM methods to update the page to match what the server would send for that URL (i.e. undoing the changes from the previous paragraph).

JS recreate eventlistener

I'm working with JQuery and ajax.
SCENARIO:
The scenario is the following.
I have a table with different features and each row has it's own button to call "show data " function. With the first call I check some microservices that manipulated the origin data. If data is available ,I show a button for every manipulated data to show in a chart. Every Button gets a listener created in de success method of an ajax call. So there can be three scenarios:
First: show data is called the first time. So there is no
Eventlistener created yet. In that case I create I new one for each
button.
Second: Imagine I clicked a button to show the data in a chart. After
that, the chart gets closed. Now I want to show the same data again.
So my Eventlistener should stay the same and there should not be
another one added.
Third: I click another feature in the table which might have data the
is manipulated differently or will be shown in another chart (e.g. pie
chart insted of flow chart.) So the scenario is pretty much like in
case one but now there is an old Listener to delete.
As a summary: I have to save the Eventlistener Object persistend when it gets createt because when case 3 turns up, I want to call removeEventlistener but I get an error that this object is not defined:
I'm a total noob in js.
This scenario results in the problem, that the eventarguments are not updated and you can see that the data output of listeners pops up for a second and gets overlayed by newer.
And when you do a few attemps, it ends in chaos where nothing fits. By this I mean the wrong data is shown in a wrong chart (one of an older event.).
So I wanted to delete the old listener and recreate it.
Is this a possible solution or is there a better way to do it?
The whole funtion looks like this:
function showData(id,category,feature,date,caller,already_called){
document.getElementById("originButtonDiv").style.visibility='visible';
document.getElementById("squareButtonDiv").style.visibility='hidden';
try{
//show data again -> maintain listener
if(old_already_called == 0 && already_called == 1){
old_already_called = already_called;
}
//New feature choosen -> Delete old listener and create new one
if(old_already_called == 1 && already_called == 0){
$.ajax({
type:'GET',
url:"${path}/user/...
dataType:'text',
async: false,
success:function genTable(data){
var originDataButton = document.getElementById("originDataButton");
//originDataButton.removeEventListener("click",_listener,true);
originDataButton.addEventListener("click", function _listener(){
originDataButtonClicked(id,category,feature,date);
}, true);
if(data.localeCompare("true")==1){
document.getElementById("squareButtonDiv").style.visibility='visible';
var squaredDataButton = document.getElementById("squaredDataButton");
//squaredDataButton.removeEventListener("new_click",_squared_listener,true);
squaredDataButton.addEventListener("click",function _squared_listener(){
squaredDataButtonClicked(id,category,feature,date);
}, true);
}
}
});
old_already_called = 0;
}
}
catch{
//first call --> create new Eventlistener
$.ajax({
type:'GET',
url:"${path}/user/...
dataType:'text',
async: false,
success:function genTable(data){
var originDataButton = document.getElementById("originDataButton");
originlistener = originDataButton.addEventListener("click", function _listener(){
originDataButtonClicked(id,category,feature,date);
}, true);
if(data.localeCompare("true")==1){
document.getElementById("squareButtonDiv").style.visibility='visible';
var squaredDataButton = document.getElementById("squaredDataButton");
squaredDataButton.addEventListener("click",function _squared_listener(){
squaredDataButtonClicked(id,category,feature,date);
}, true);
}
}
});
old_already_called = 1;
}
}
Update:
I'm pretty sure now that the problem is the usage of ajax. I defined a logic tree for my use case because I have to detect whether an Eventlistener should be created, persist unchanged or deleted and recreated. I guess I can differentiate these circumstances in my code but the problem is, that I define the listener in the ajax success method. Between two calls the listener is undefined. So is there a possibility to save a listener object peristent on the client between to ajax calls so that I can delete it within future calls? I guess this would be the solution for my problem.

Retain javascript data while Forward and Backward browser button click

I have following dropdown which calls javascript showTable method.
<select name="any_name" id="any_id" onChange="showTable()">
I have following showTable method which calls a php method via post to populate data in my showData div.
function showTable()
{
$.ajax({
type: "POST",
url: "sample.php",
data: {"Id" : myId},
success: function (data)
{
document.getElementById("showData").innerHTML= data;
}
});
}
It works fine. Now the problem arises when I hit FORWARD and then BACKWARD browser button. On hitting BACKWARD button, I get my previous page but my showData div is empty. How can I retain data in this div which I got from my PHP script? I think I have made it clear what I want to ask.
Look for local storage w3schools.com/html/html5_webstorage.asp and manage to save and retreive values between your back/forward behavior.
;)

how to run an onchange function when page is loaded if the selected box is already selected

Im running into a problem where i have an ajax driven page that is drawn when a user selects something from a simple drop down:
<select id = "selectdepartment">
<option id = "default">Select an option...</option>
....
</select>
and the remainder of the page is drawn using the jquery .change() :
$('#selectdepartment').change(function(){
});
Which then runs some ajax to php script. everything works great, the problem is when i submit a form that was drawn with ajax (using $_SERVER['PHP_SELF'];), the data gets submited, the page reloads, and the page is cleared but the select box is still left where it was. The user has to move to a different option then back to the one the selected originally to re-fire the .change(). that sucks.
I could fix this by passing a php variable in all of my forms, then checking to see the variable set on every page load and if it is draw the page parts then, but this would lead to pretty messy code and it's less than desirable.
There has to be a way to do this with the jquery library, though my knowledge of the javascript language in general is not what i would like it to be. If anyone has any helpful hints please share, dont do it for me though, i wont learn that way :)
edit: code with .trigger
$('#selectdepartment').change(function(){
var department = $('#selectdepartment').val();
var day = $('#data').data('day');
var month = $('#data').data('month');
var year = $('#data').data('year');
//alert (department);
if(department === "Select an option..."){
$('.hiddenuntildepartmentisselected').css({"display":"none"});
}
else{
$('.hiddenuntildepartmentisselected').css({"display":"block"});
}
showpoints(department);
drawpointstable(department, day, month, year);
displaytheuseresforselecteddepartment(department, '');
$('#sendthedepartment').val(''+department+'');
$('#hiddendepartmentidforaddinganewpoint').val(''+department+'');
}).trigger('change');//end run functions
You can use the .trigger() function to immediately trigger the change event handler when the page has loaded:
$('#selectdepartment').change(function() {
// code here
}).trigger('change');
Or if you need to call it elsewhere via JavaScript/jQuery:
$('#selectdepartment').trigger('change'); // or just .change() as a shorthand
Updated
Your button for the form could make use of the onClick attribute, which would invoke a method to parse the form fields and post the data to your php script via .ajax().
In the success event method you then check any flags you need to and modify the element as you desire if needed.
Basic example:
Inside of .ajax():
...
url: 'xxx.xxx.xxx',
async: true,
type: 'POST',
dataType: 'html',
data: JSON.stringify( form_fields ),
beforeSend: function()
{
// Pre send stuff, like starting a loading gif
},
success: function( data, textStatus, xhr )
{
// Be sure you load the page with the content first
$( '#containing-div' ).html( data );
// Do your check here, and modify your element if needed here
if( flagtocheck === 'xxx' )
{
// Modify the element in question...
}
// I call a custom method termed `.ctrls()` here that makes any
// adjustments to the DOM once its loaded/updated.
},
error: function( xhr, textStatus, errorThrown )
{
}
Of course, you'll want to set flagtocheck appropriately in your case.
Hope that helps!
Note regarding edit
This post was edited to be a little more descriptive and more easily understood. Since the person asking the question is already using the .ajax() method, the success event method is the ideal place for doing what the person asking the question is requesting. It is 1 less method invocation to directly modify the element there than using it to call .trigger() or .change() which then also directly modifies the element.

Will reinitializing a JavaScript object at global scope cause a memory leak?

I have links in a JQuery DataTable that use JQuery UI's tooltip feature. Each link has a tooltip that is populated by an Ajax call. I would like to limit the number of Ajax calls to as few as possible. The DataTable uses server-side processing, and the results are paginated, so there will never be more than ten links on the page at any one time.
The data that is returned by the Ajax call will never change and thus can be safely cached. In my testing, I have seen that the browser does cache the result of each Ajax call, so that it only makes one call per link, and then uses the cache thereafter. My concern is that some user might have their browser configured in such a way that it doesn't use the cache for some reason, and they will be firing off one Ajax call after another, every time they mouse over a link.
Here is the JavaScript for the tooltip:
$('.jobId').tooltip({
content: function(callback) {
var jobId = $(this).text();
$.ajax({
url: 'myUrl',
data: {jobId: jobId},
dataType: 'json',
success: function(data) {
var html = formatResults(data);
callback(html);
},
error: function() {
callback('An error has occurred.');
}
});
}
});
I considered storing the result of each Ajax call in a JavaScript object declared at global scope, and then checking that before making the Ajax call, but I have the vague sense that this might cause a memory leak somehow.
var gJobs = new Object();
$('.jobId').tooltip({
content: function(callback) {
var jobId = $(this).text();
if (gJobs[jobId]) {
callback(gJobs[jobId]);
} else {
$.ajax({
url: 'myUrl',
data: {jobId: jobId},
dataType: 'json',
success: function(data) {
var html = formatResults(data);
gJobs[jobId] = html;
callback(html);
},
error: function() {
callback('An error has occurred.');
}
});
}
}
});
I am also concerned that if the table has a large number of rows, the gJobs object could end up using a lot of memory. To prevent the gJobs object from growing indefinitely, every time the user goes to the next or previous page of results in the DataTable, I use the fnDrawCallback function to reinitialize gJobs:
$('#jobsTable').dataTable({
...
"fnDrawCallback": function() {
gJobs = new Object();
}
});
I should mention that since the data returned by each Ajax call doesn't change, I could also just store the data in the JSP as static text, and populate the tooltips that way instead of using Ajax. However, I have to make a separate web service call to get the data for each link, and rather than make ten web service calls every time the user pages forward or back, I would rather load the data on demand via Ajax.
Is there anything wrong with this approach? Is there any way this can cause a memory leak? Should I explicitly delete all the properties of gJobs before reinitializing it? Thanks for your help.

Categories

Resources