javascript PeriodicalExecuter crashing into user's submit (POST)? - javascript

When I look at logs with the Charles proxy, I see that the user's submit (POST) doesn't always contain all the form data. Sometimes it is missing the bottom third of the form data, apparently when the AJAX call in the PeriodicalExecuter fires. I'm not absolutely sure about this. Here's roughly how the page script looks:
document.observe("dom:loaded", function() {
...
new PeriodicalExecuter(function(pe) {msgEntryRqst(host_URL, web_sid, pageType, recordNbr);}, delaySecs);
...
}
function msgEntryRqst(host_URL, web_sid, pageType, recordNbr) {
...
new Ajax.Request('/'+host_URL, {
method: 'get',
parameters: {c: 'AJAX_request', ajtype: 'instantMessage', sid: web_sid, pagetype: pageType, record: recordNbr, rnd: Math.random()},
onSuccess: function(response) {
if(response.responseText.length>0) {
...
}
}
}
}
Is there a way to do, for example, DOCUMENT.observe('click', 'myHandler'), perhaps within the "dom:loaded" section, to set a flag when the user has clicked on a save button or navigation tab, to skip one cycle of the AJAX command and thereby not truncate the user's POST?

Related

How to stop/pause async call of ajax

I am stuck on this since yesterday, now I need help. I don't know how to properly 'question' this, but I think this is around the concern of ajax is asynchronous.
I am unable to complete the ajax call from my view when I call an ajax function inside an ajax postback.
$.ajax({
url: '#Url.Action("GetValidateAssignAccountName", "AccountsAssignment")?companyID=' + companyid,
type: request_method,
data: form_data
}).done(function (data) {
if (data == '') {
PromptAssign(data, post_url, request_method, form_data);
}
else {
Assign(post_url, request_method, form_data);
}
});
Assign function doesn't work/complete. I don't know how to call it, but it goes through the controller and calls the stored procedure, returns a success msg, but for some reason, the procedure did not work/save.
My problem is that, when I call PromptAssign - in which case I call a messageDialog and then call the Assign inside, right there the Assign does the job. Here is the PromptAssign function:
$("#messagedialog").dialog({
open: function () {
$(".ui-widget-overlay").css({ background: "#000000", opacity: 0.5 });
$(".ui-dialog-title").css("color", "#228B22");
//$(".message-img").attr("src", "../Content/images/success.png");
$(".message-wrapper").html(msg);
},
modal: true, height: 250, width: 500,
buttons: {
//'Ok': function () { $(this).dialog('close'); },
'Assign': function () {
Assign(post_url, request_method, form_data);
$(this).dialog('close');
},
'Close': function () { $(this).dialog('close'); }
},
create: function () {
$(this).closest(".ui-dialog")
.find(".ui-button").eq(2)
.addClass("btn btn-default");
},
title: "Confirmation",
dialogClass: "noclose"
});
Initially, the code was just the assign function which calls an sp to save a data. But we added the PromptAssign (first code block, then call a msgbox/PromptAssign, then assign) which is a validation if its existing or not, then the user can still Assign after if he still chooses to.
So when the validation returns nothing, I don't need to PromptAssign, so I just call the Assign straight away. This is not working. Anything I am missing on how to use ajax?
Just to answer the comments, there was an earlier problem like this that goes to the ajax, and then to the controller executing the stored procedure but for some reason the data isn't updated. We fixed the issue by making those ajax calls in a separate function.
For this one, I was trying to apply the same thing to no avail, I know there is nothing wrong in my way of using ajax, turns out, it was a data issue. The specific record in which I was testing is not working properly due to database validations. Still, thank you for looking at it.

How to add preloader to website without manually show/hide it

On my website (MVC and web API) I have added a preloader for a better user experience purpose.
I have added the preloader at two points:
After Login, between the user is authenticated and the redirection to the homepage.
In every page that loads data from the server.
I did it with an image that I show when the page/data loads and I hide when the data is fully loaded.
<div id="dvReqSpinner" style="display: none;">
<br />
<center><img src="~/images/loading_spinner.gif" /></center>
<br />
</div>
And with jquery I show and hide it:
$("#dvReqSpinner").show();
$("#dvReqSpinner").hide();
It's a little bit anoying to keep showing and hiding an image every time I need to load data (using an AJAX call to web API, authenticating the user etc.. - Every action that takes time and I want to show the user that something is "happening"), isn't there any "automatic" option to have a preloader on a website?
I don't know if its the case, but if you use jquery ajax to handle your requests, you can do something like this:
$(document).ajaxStart(function() {
// every time a request starts
$("#dvReqSpinner").show();
}).ajaxStop(function() {
// every time a request ends
$("#dvReqSpinner").hide();
});
EDIT:
If you want to avoid showing the spinner for fast requests, i think this can make it work:
var delayms = 3000; // 3 seconds
var spinnerTimeOut = null;
$(document).ajaxStart(function() {
// for every request, wait for {delayms}, then show spinner
if(spinnerTimeOut!=null){
clearTimeout(spinnerTimeOut);
}
spinnerTimeOut = setTimeout(function(){
$("#dvReqSpinner").show();
}, delayms);
}).ajaxStop(function() {
// every time a request ends
clearTimeout(spinnerTimeOut); // cancel timeout execution
$("#dvReqSpinner").hide();
});
Give it a try. i couldn't test it -.-'
To show or hide a loading indicator in a single page app, I would add and remove a CSS class from the body:
#dvReqSpinner {
display: none;
}
body.loading #dvReqSpinner {
display: block;
}
and
$("body").addClass("loading");
$("body").removeClass("loading");
Primarily this would make the JS code independent on the actual page layout, so it's "nicer" but not really "less work".
To do it "automatically", I recommend abstracting your Ajax layer into a helper object:
var API = {
runningCalls: 0,
// basic function that is responsible for all Ajax calls and housekeeping
ajax: function (options) {
var self = this;
self.runningCalls++;
$("body").addClass("loading");
return $.ajax(options).always(function () {
self.runningCalls--;
if (self.runningCalls === 0) $("body").removeClass("loading");
}).fail(function (jqXhr, status, error) {
console.log(error);
});
},
// generic GET to be used by more specialized functions
get: function (url, params) {
return this.ajax({
method: 'GET',
url: url,
data: params
});
},
// generic POST to be used by more specialized functions
post: function (url, params) {
return this.ajax({
method: 'POST',
url: url,
data: params
});
},
// generic POST JSON to be used by more specialized functions
postJson: function (url, params) {
return this.ajax({
method: 'POST',
url: url,
data: JSON.stringify(params),
dataType: 'json'
});
},
// specialized function to return That Thing with a certain ID
getThatThing: function (id) {
return this.get("/api/thatThing", {id: id});
}
// and so on ...
};
so that later, in your application code, you can call it very simply like this:
API.getThatThing(5).done(function (result) {
// show result on your page
});
and be sure that the low-level stuff like showing the spinner has been taken care of.
You can use global ajax handlers for this.
This code will execute whenever you make an ajax request. all you have to do here is enable your spinner.
$( document ).ajaxSend(function() {
$("#dvReqSpinner").show();
});
This code will execute once your ajax request succeeded. all you have to do here is enable your spinner.
$( document ).ajaxSuccess(function( event, request, settings ) {
$("#dvReqSpinner").hide();
});
You can also use other global ajax function to handle things like showing a popup when a ajax request fails using ".ajaxError()"
Below link will have details of all the other functions
https://api.jquery.com/category/ajax/global-ajax-event-handlers/

Independent jquery functions execute consecutively when one is called

My problems seems basic, yet I have tried a lot of different ways of putting these functions on one html file to no avail. The problem is that, when the 1st function is called, the second also runs, leaving me with the results of the second function all the time. I have no idea what I am doing wrong, please help. Here is the code in question.
<script>
$(document).ready(function () { // Make sure the elements are loaded on the page
// Listen for a click event on the button
$('#buttonON').click(funct);
$('#buttonOFF').click(funct2);
});
// Now define the function
function favfunct(e) {
// Stop the page from "following" the button (ie. submitting the form)
e.preventDefault();
e.stopPropagation();
// Insert AJAX call here...
$.ajax("carstatusupd.php", {
// Pass our data to the server
data: { "username" : "sibusiso", "caron" : "1", "caroff" : "0"},
// Pass using the appropriate method
method: "POST",
// When the request is completed and successful, run this code.
success: function (response) {
// Successfully added to favorites. JS code goes here for this condition.
}
});
function funct2(e) {
// Stop the page from "following" the button (ie. submitting the form)
e.preventDefault();
e.stopPropagation();
// Insert AJAX call here...
$.ajax("carstatusupd.php", {
// Pass our data to the server
data: { "username" : "sibusiso", "caron" : "0", "caroff" : "1"},
// Pass using the appropriate method
method: "POST",
// When the request is completed and successful, run this code.
success: function (response) {
// Successfully added to favorites. JS code goes here for this condition.
}
});
}
</script>
You have omitted the closing brace from the function favfunct().
Please use this,
<script>
$(document).ready(function () {
function funOne(){
};
function funTwo(){
};
$('#buttonON').live('click',function(){
funOne();
});
$('#buttonOFF').live('click',function(){
funTwo();
});
});
NOte: initialize function before use and initialize them into document ready.

PHP cannot unset session variable

I cannot unset a session variable used on a search filter. When clicking domain.com/index.php?filter=clear nothing happens and the filter is not cleared.
I am using a mixture of php and JS to update the table using AJAX
PHP:
/**
* Clears the current filter
*/
function clear()
{
unset($_SESSION['filter']);
// Clear current page
unset($_SESSION['arctic_page']);
}
}
JS:
clear: function()
{
// Show loading image
new Element('img', { src: '/images/loading.gif' }).setStyle('float', 'right').injectTop(Issues.container.getElement('h2'));
// Create AJAX request
new Ajax('index.php',
{
method: 'get',
data: 'ajax=true&filter=clear',
update: 'issue_list',
onComplete: Issues.initialise
}).request();
}
It looks like prototype JS, correct? It's been a while for me, but I thought this was the correct syntax:
new Ajax.Request('index.php',
{
method: 'get',
data: 'ajax=true&filter=clear',
update: 'issue_list',
onComplete: Issues.initialise
});

jQuery: Can't retrieve an attribute of a dynamically created DOM element

Here's the situation: I'm writing a simple AJAX application that performs CRUD functions. When the user double clicks on a particular element, the element changes into a text box so that they can edit inline. When the text box loses focus (code for which is below), the value of the textbox gets POSTed to a PHP script that updates the database.
All is groovy except for one thing. When I create a new record, which gets popped onto the top of the list with AJAX, I can't edit that record without refreshing the page. I mean, the edit looks like it's been committed, but when you refresh, it reverts back to the original. After refreshing, there are no issues.
To boil it down: When I try to run the following code on newly created rows in my table (both in the database and on the page), the edit appears to be made on the page, but never makes it to the database.
//Make changes on FOCUSOUT
$('#editable').live('focusout', function(){
var parentListItem = $(this).parents('li');
var theText = $(this).val();
var parentListItemID = parentListItem.parents('ul').attr('id');
$(this).remove();
parentListItem.html(theText);
parentListItem.removeClass('beingEdited');
$.post("databasefuncs.php?func=edit", { postedMessage: parentListItemID, fullTextContent: theText },
function(result){
if(result == 1) {
parentListItem.parents('ul').animate({ backgroundColor: 'blue' }, 500).animate({ backgroundColor: '#eeeeee' }, 500);
} else {
alert(result);
}
});
});
I suppose you are not binding the event to the new DOM Element loaded via AJAX.
Your problem is that the post executes but the function you target (func=edit) never fires, the params you are sending after the question mark are never read by your php, you are sending a post request and wanting it to behave like a get by attaching parameters to the URL, change your request to:
$.ajax({
type: "POST",
url: "databasefuncs.php",
data: {func: "edit", postedMessage: parentListItemID, fullTextContent: theText},
success: function(data, textStatus, jqXHR) {
if(textStatus === "success") {
parentListItem.parents('ul').animate({ backgroundColor: 'blue' }, 500).animate({ backgroundColor: '#eeeeee' }, 500);
}
else {
alert(textStatus);
}
}
});
Now in your PHP you have $_POST["func"] = "edit";
Hope this is clear and it helps. Cheers.

Categories