What to do when users outrun ajax - ajax

My program does an ajax call when the user clicks on a radio button. Upon success, the background color of the table cell containing the radio button is changed to let the user know their selection has been posted to the database.
The problem is sometimes the background doesn't change. I'm trapping for errors, so I don't think it's because of an error. I'm wondering if the user is outpacing the success callback.
var setup = {};
setup.url = 'Gateway.cfc';
setup.type= 'POST'
setup.dataType='json';
$.ajaxSetup(setup);
var settings = {};
settings.data = {};
settings.data.method = 'Save';
settings.data.AssignmentID = $('input[name=AssignmentID]').val();
settings.error = function(xhr, ajaxOptions, thrownError) {
$('#msgErr').text(thrownError);
};
settings.success = function(result) {
$('#msg').empty();
$('#msgErr').empty();
if (result.RTN) { // uppercase RTN
$('#' + settings.data.AnswerID).addClass('answer');
} else {
$('#' + settings.data.AnswerID).next().append('<span class="err"> ' + result.MSG + '</span>');
}
}
$('input').filter(':radio').change(function() {
var myName = $(this).attr('name');
$('input[name=' + myName + ']').closest('td').removeClass('answer');
settings.data.AnswerID = $(this).val();
$.ajax(settings);
});

There is a delay between your Ajax post to the server and the ui element update on your screen. I do not know which Ajax library you are using, but you could plug into the Ajax framework and display a floating div element that covers the whole screen. This div could have other elements like an image or other divs, spans, p tags, etc. This is also called a dialog in some libraries.
I would recommend trying to find the before_Ajax_send and after_Ajax_receive functions in your Ajax library and attaching your functions to these events. The before_send function should display the floating div and the after_receive should close the div.
Hope this helps.

Gonna post this as an answer, on the off-chance that it does the trick :)
$('input').filter(':radio').change(function() {
$(this).closest('td').removeClass('answer');
var mySettings = $.extend(true, {data:{AnswerID: $(this).val()}}, settings);
$.ajax(mySettings);
});
This will make sure there are no race conditions with your settings if calls are made in quick succession.

Related

jqgrid setting page of grid

When a user selects a cell, I have the following code which goes to a window.location
beforeSelectRow: function (rowid, e) {
var $td = $(e.target).closest("td"),
iCol = $.jgrid.getCellIndex($td[0]);
if (this.p.colModel[iCol].name === 'FlSaved') {
var pagenum = $('#reportList').getGridParam('page');
var rownum = 200;
alert(pagenum);
alert(rownum);
window.location = "/Plt/FileUpload/" + '?id=' + encodeURIComponent(rowid) + '&pagenum=' + pagenum;
}
Note how I am passing the pagenum. The reason why I am passing the page number is because when the user finishes with what they need
to do at window.location, I need the user to go back to the grid page that they were at.
To do this, I am doing the loadComplete where I set the value of the page but does not seem to be working.
loadComplete: function (data) {
if ('#TempData["pageNum"]') {
$("#rpList").trigger("reloadGrid",[{page:pagenum}]);
}
Where is the best place of do the trigger reloadGrid at?
It's unclear for me when '#TempData["pageNum"]' will be set, when it will be cleared and whether the code will be hold in the cache of the web browser. If we forget about the questions I have one important remark to your code: if you use .trigger("reloadGrid", ...) inside of loadComplete you should place the call of trigger inside of setTimeout. It will allows to process till the end the current loadiong of the grid before starting the next loading initialized by .trigger("reloadGrid", ...). So the code could be about the following:
loadComplete: function (data) {
...
if (/*some condition*/) {
setTimeout(function () {
$(this).trigger("reloadGrid",[{page: pagenum}]);
}, 50);
}
...
}
Event the usage of 0 instead of 50 is not the same as the usage of .trigger("reloadGrid",...) without setTimeout.

JqGrid BeforeShow event of add dialog variables reset

I call the following function before the add dialog is shown; after clicking [+] on the JqGrid.
MVC Controller grid configuration
ordersGrid.ClientSideEvents.BeforeAddDialogShown = "initAddDialog";
The function makes an Ajax call to create a new order record either with or without a linking id, dependent on whether an existing order was selected when the [+] button was clicked.
The purpose is to make available the id necessary to make another Ajax call to retrieve additional linked information from another service, and to pre-populate the new record with date/time information and (where applicable) common information from an existing record.
function initAddDialog() {
var newOrderId = 0;
var newOrderLinkId = 0;
var selRow = jQuery('#clientOrderGrid').jqGrid('getGridParam', 'selrow');
var selRowData = jQuery('#clientOrderGrid').jqGrid('getRowData', selRow);
Get linking ID from selected row (if any)
var curOrderLinkId = (selRowData.OrderLinkId == null) ? 0 : selRowData.OrderLinkId;
Ajax call to create new 'Holding' Order
$.ajax({
url: '/Order/ajaxNewOrder?OrderLinkId=' + curOrderLinkId,
success: function (newOrderResponse) {
arr = newOrderResponse.split("|");
newOrderId = arr[0];
newOrderLinkId = arr[1];
},
error: function () { alert("There was an error creating an Order record"); }
});
If I break the code here using Firebug in Firefox, I can see that the variables newOrderId and newOrderLinkId have been set correctly with the id's from the newly created record, and if I hit F8 the (already displayed) dialog is populated with these //values.
If I don't break the code the dialog is displayed, but displays the values with which the variables were initialised i.e. newOrderId = 0, newOrderLinkId = 0.
$('#' + 'OrderId').val(newOrderId);
$('#' + 'OrderLinkId').val(newOrderLinkId);
$('#' + 'Stock').val(stock);
$('#' + 'SettlesTs').val(settlesTs);
$('#' + 'ReceivedTs').val(dtThis);
$('#' + 'ReceivedHHmm').val(dtTime);
I've tried calling the same function after the add dialog is shown, but get the same results.
Any thoughts as to why this is, or is there a better way of achieving the same result?
Thanks
I have taken the native add/edit dialog out of the equation and am using my own 'add' form along with the native inline editing of JqGrid. I'm sure with more research it would have been possible to find a solution, but with deadlines looming I had to find a workaround.

ajax call not responding with $.post

What i am trying to do is to get the value of the selected elements by jquery selection. After that, those value are post to php script via ajax and then retrieve the data from the database and display it on the same page (something called autocompete).
var marvalue=$("input[name=m_status]:checked").val();
var fromhvalue=$("#fromheight").val();
var tohvalue=$("#toheight").val();
var value = $("#edu_det1").val();
alert (value);
var regvalue = $("#religion").val();
alert (regvalue);
var occvalue = $("#occupation").val();
alert (occvalue);
var convalue = $("#country").val();
alert (convalue);
Alert is there to check the correct values. As you see the code above this will get the values from the different input elements.
Below is the code i used to post to php
/*
$.post("regsearch.php", {queryString: ""+value+"",queryString1: ""+marvalue+"",queryStringfage: ""+fage+"",queryStringtage: ""+tage+""+queryStringfromh: ""+fromhvalue+""+queryStringtoh: ""+tohvalue+""+}, function(data) { // Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
});
*/
The problem :
when the comment is removed nor the alert popup and neither the result displayed. Ok about the result as no query is posted.
Major part is that when i use the below code which hold only m_status and edu_det1 it works.
marvalue=$("input[name=m_status]:checked").val();
alert (marvalue);
var value = $("#edu_det1").val();
alert (value);
The post code for above is
$.post("regsearch.php", {
queryString: ""+value+"",
queryString1: ""+marvalue+"",
queryStringfage: ""+fage+"",queryStringtage: ""+tage+""
}, function(data) {
// Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
});
The code for age and it verification is not added here. What is the problem and how to sort this out?
It will be better if you use jquery serialize() function. This will make your life easier to work with forms.
var querstring = $(form).serialize();
above will help
I guess using ajax post jQuery.ajax() will do the same thing and you can even serialize the fields in your page.
http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
I have done similar type of code
UserName is the field Which I am passing
var data = $('#Username').serialize();
$('#usernameCheck').empty();
if (!$("form").validate().element("#Username"))
return;
$.ajax({
url: '/SignUp/CheckUsername',
type: 'POST',
data: data,
async: true,
success: function (result) {
if (result == 1) {
$('#usernameCheck').html('<font color=green>Username available</font>');
usernameOK = true;
}
else if (result == 2) {
$('#usernameCheck').html('<font color=red>Username not available</font>');
usernameOK = false;
}
else {
$('#usernameCheck').empty();
usernameOK = false;
}
}
});
First of all you should use your console to see Javascript errors, as I'm sure this will generate some. For example that querystring is undefined.
I'd also console.log instead of alert, it is less annoying and more informative.
Then: you dont need to use f.e. ""+marvalue+"" - just use marvalue. On the other hand f.e. queryString should be quoted...
$.post("regsearch.php", {'queryString':value,'queryString1': marvalue,'queryStringfage':fage,'queryStringtage':tage,'queryStringfromh': fromhvalue,'queryStringtoh':tohvalue}, function(data) {
$('#suggestions').fadeIn();
$('#suggestions').html(data);
});

jquery: bind click event to ajax-loaded elmente? live() won't work?

hey guys,
I have an input field that looks for matched characters on a page. This page simply lists anchor links. So when typing I constantly load() (using the jquery load() method) this page with all the links and I check for a matched set of characters. If a matched link is found it's displayed to the user. However all those links should have e.preventDefault() on them.
It simply won't work. #found is the container that shows the matched elements. All links that are clicked should have preventDefault() on them.
edit:
/*Animated scroll for anchorlinks*/
var anchor = '',
pageOffset = '',
viewOffset = 30,
scrollPos = '';
$(function() {
$("a[href*='#']").each(function() {
$(this).addClass('anchorLink');
$(this).bind('click', function(e) {
e.preventDefault();
//console.log('test');
anchor = $(this).attr('href').split('#')[1];
pageOffset = $("#"+anchor).offset();
scrollPos = pageOffset.top - viewOffset;
$('html, body').animate({scrollTop:scrollPos}, '500');
})
});
});
Well, I'm looking for all href's that contain a #. So I know those elements are anchors that jump to other elements. I don't want my page to jump, but rather scroll smoothly to this element with this specific #id.
This works fine when I use bind('click', ... for normal page-elements that have been loaded when the page is opened. It doesn't work for anchors that have been loaded via ajax! If I change the bind to live nothing does change for the ajax loaded elements - they still don't work. However normal anchors that have always been on the page are not triggering the function as well. So nothing works with live()!
When you say "it won't work" do you mean that your function is not been called or that you can not cancel out of the function? As far as I know you can not cancel out live events. With jQuery 1.4 you can use return false to cancel out live event propagation. Calling e.preventDefault() won't work.
Edit: right so this code should in principal work. What it still won't do is, it won't add the 'anchorLink' class to your new anchors. However if the clicks work then let me know and I will give you the right code to add the class too!
var anchor = '',
pageOffset = '',
viewOffset = 30,
scrollPos = '';
$(function() {
$("a[href*='#']").each(function() {
$(this).addClass('anchorLink');
});
$("a").live('click', function(e) {
if ($(this).attr("href").indexOf("#") > -1) {
e.preventDefault();
//console.log('test');
anchor = $(this).attr('href').split('#')[1];
pageOffset = $("#" + anchor).offset();
scrollPos = pageOffset.top - viewOffset;
$('html, body').animate({ scrollTop: scrollPos }, '500');
//nikhil: e.preventDefault() might not work, try return false here
}
});
});

jQuery monitoring form field created by AJAX query

Preface: I am sure this is incredibly simple, but I have searched this site & the jQuery site and can't figure out the right search term to get an answer - please excuse my ignorance!
I am adding additional form fields using jQuery's ajax function and need to then apply additional ajax functions to those fields but can't seem to get jQuery to monitor these on the fly form fields.
How can I get jQuery to use these new fields?
$(document).ready(function() {
$('#formField').hide();
$('.lnk').click(function() {
var t = this.id;
$('#formField').show(400);
$('#form').load('loader.php?val=' + t);
});
//This works fine if the field is already present
var name = $('#name');
var email = $('#email');
$('#uid').keyup(function () {
var t = this;
if (this.value != this.lastValue) {
if (this.timer) clearTimeout(this.timer);
this.timer = setTimeout(function () {
$.ajax({
url: 'loader.php',
data: 'action=getUser&uid=' + t.value,
type: 'get',
success: function (j) {
va = j.split("|");
displayname = va[1];
mail = va[2];
name.val(displayname);
email.val(mail);
}
});
}, 200);
this.lastValue = this.value;
}
});
});
So if the is present in the basic html page the function works, but if it arrives by the $.load function it doesn't - presumably because $(document).ready has already started.
I did try:
$(document).ready(function() {
$('#formField').hide();
$('.lnk').click(function() {
var t = this.id;
$('#formField').show(400);
$('#form').load('loader.php?val=' + t);
prepUid();
});
});
function prepUid(){
var name = $('#name');
var email = $('#email');
$('#uid').keyup(function () {
snip...........
But it didn't seem to work...
I think you are close. You need to add your keyup handler once the .load call is complete. Try changing this...
$('#form').load('loader.php?val=' + t);
prepUid();
To this...
$('#form').load('loader.php?val=' + t, null, prepUid);
What you are looking for is the jquery live function.
Attach a handler to the event for all elements which match the current selector, now or in the future
You can do something like this:
$('.clickme').live('click', function() {// Live handler called.});
and then add something using the DOM
$('body').append('<div class="clickme">Another target</div>');
When you click the div added above it will trigger the click handler as you expect with statically loaded dom nodes.
You can read more here: http://api.jquery.com/live/

Resources