Sorry to ask such a basic question. I would like to add an Ajax feature to my input page which does:
use the blockUI plugin to add a popup window which tells users to wait
in the meanwhile ajax detects the existence of output page
if calculations are finished, ajax redirects the browser to the output page (batchoutput.html)
If everything goes well, the popup message will appear for around 1-2 mins until the calculations are done, then the browser will be redirected to the batchoutput.html page.
However, the situation is: the popup message window appears only for a second, then after a min or two the browser goes to the batchoutput.html. My guess is something is wrong with my ajax function. It seems like the ajaxstart and ajaxstop are misfired. Can I have some suggestions?
Here is the code:
$('.input1_button').click(function () {
$(document).ajaxStart(function(){
$.blockUI({ css: {
border: 'none',
padding: '15px',
backgroundColor: '#000',
'-webkit-border-radius': '10px',
'-moz-border-radius': '10px',
opacity: .5,
color: '#fff'
} });
});
$(document).ajaxStop(function(){
$.unblockUI();
});
$.ajax({
type: "post",
url: "/batchoutput.html",
data: $(".articles").serialize(),
dataType: "html",
success: function() {
window.location = '/batchoutput.html';
}
});
});
ajaxStop is fired right after the ajax request is complete, and complete means error or success.
Therefore, what happens after you click a button is:
ajaxStart is fired, causing UI to block
ajax request to /batchoutput.html is performed
if request fails, ajaxStop is fired, causing UI to unblock
My suggestion is to:
block UI on button click (i.e. move $.blockUI directly into click function)
after that, send ajax request repeatedly until it finishes with success (you can use Javascript's native function setInterval or trigger next request on ajaxError)
when request succeds, unblock UI and redirect (this can be done either directly in success callback or in ajaxSuccess method)
Related
I have a single page mark-up with popup divs that contain forms that the user can use to update his/her account information. After form submission the popup closes and the page refreshes showing the updated information that is located within a li (this seems to be working). The problem is, if the user goes back and tries to update again the button within the popup is not submitting.
Thanks in advance for any suggestions!!!
Javascript
$('#updateadmin').click(function() {
var admin = $('#adminform').serializeArray();
/*alert(admin);*/
$.ajax({
type: "POST",
url: 'adminupdate.php',
data: admin,
success: function(data) {
if(data=="success") {
$('#admindiv').popup('close');
$.mobile.changePage('companyinfo.php', {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true,
changeHash: false
});
} else {
$('#adminupdatestatus').html(data).css({color: "red"}).fadeIn(1000);
}
}
});
return false;
});
It sounds like the #updateadmin link/button is located on the page that gets reloaded, if this is the case then you should delegate your event handler so it affects matching elements in the DOM for all time, not just when the code runs.
You would change this:
$('#updateadmin').click(function() {
to this:
$(document).on("click", "#updateadmin", function() {
This works because you're now attaching the event handler to the document element which always exists. When events reach the document element they are checked to see if the element on which they originally fired matches the selector we put as the second argument for .on().
Documentation for .on(): http://api.jquery.com/on
Trying to find out why this jQuery JS isn't making ajax call though it is being called for execution.
I have this button to make an ajax GET request to a method in the controller, the method will partial render. When I click on the button I don't see any request coming on the console but I see the alert "test" on the browser.
I have the same exact JS with other parameters working for other tupes of ajax calls, so I just copied one of them and changed all required parameters, expecting it shall work right away. Neither I get any errors on the console. My routes and id names are good and verified. What is it that I am missing here?
view - Note: this button is rendered via a different ajax, that part works.
<%= button_tag "Add / Remove", :id => "add_remove_button", :onclick => "javascript:add_remove();" %> #note: this is buried under div tags in a html table
JS-
function add_remove(){
$('#add_remove_button').click(function() {
$.ajax({
type: 'GET',
url: "/item/add_remove",
success:$('#view_item').html(data)
/*function(){ },
data:$('#test').serialize(),
error: function(){ },
success: function(data){ },
complete: function (){ }*/
}); #No ajax call made
/*return false;*/
});
alert('test'); #I get this alert
}
You'll always see that alert() because click() is asynchronous: the code inside the function() passed to click does not get executed until you click, but the rest of add_remove() will get called.
Here's what is actually happening in your code, which explains why the AJAX call doesn't get made:
Using :onclick => ... attaches add_remove() to your button.
You click the button, add_remove() gets called and attaches another click callback to your button. Then add_remove() calls alert(). There is no AJAX call happening here, just adding a new click handler, and sending an alert.
You click the button a second time, and you will attach a third click callback to the button. However since you also attached a click handler the first time you clicked the button, you should see an AJAX request here.
Click it a third time and you'll see two AJAX requests this time, for a total of 3 AJAX requests.
Here's what you actually want to do. Remove the :onclick => ... from the button:
<%= button_tag "Add / Remove", :id => "add_remove_button" %>
Attach a click event to the button when the page first loads:
$(function(){
$('#add_remove_button').click(function() {
$.ajax({
type: 'GET',
url: "/item/add_remove",
success: function(data) { $('#view_item').html(data); },
data: $('#test').serialize(),
error: function(){ },
success: function(data){ },
complete: function (){ }
});
return false;
});
});
You are mixing up the jquery-registering-callbacks style and the old event-handler attributes. So you triggered the registering when calling the add_remove function.
Simply remove the :onclick stuff and function add_remove(){ ... }
I have a really annoying issue with jQuery and/or the jQuery UI Dialog Box.
After clicking on a special link a modal dialog will pop up with some loaded content (ajax) and inside this loaded content are new links/buttons that load their url inside the same div Box, so the dialog still is loaded, but with new content then. The Problem is, that if you link on that link (inside a fresh loaded dialog box and on a recently reloaded website) it works as it should, but with the second click it loads the url twice, with the third it loads 4 times ... It growing exponentially with every new link loaded inside the dialog. I testet this with a counter stored inside $_SESSION.
This is the Javascript Code:
var somedialog = $('<div></div>').dialog({
autoOpen: false,
resizable: false,
modal: true,
/*show: 'fade',
hide: 'puff',*/
closeOnEscape: true,
close: function(){
}
});
function openInDialog(url, title, width, height)
{
somedialog.empty();
somedialog.dialog("option", "width", width);
somedialog.dialog("option", "height", height);
somedialog.dialog("option", "title", title);
somedialog.load(url,{},function (responseText, textStatus, XMLHttpRequest)
{
somedialog.dialog('open');
}
);
//somedialog.load(url,{},function (responseText, textStatus, XMLHttpRequest){
// dialogdiv.somedialog('open');
//});
}
$('a.ajaxBuyItemDialog').on('click',function(){
openInDialog(this.href, this.title, 400, 300);
//prevent the browser to follow the link
return false;
});
There seemed to bee other people with this issue, but that was not a very effective discussion: https://stackoverflow.com/questions/6471360/jquery-load-after-load-repeated-results-problem
Thanks for your help!
EDIT:
This is part of the code which is located in the loaded script:
$("#_BUYITEM_FORM").live('submit', function(){
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response){ // on success..
$("#_BUYITEM_CONTENT").html('<p class="AjaxLoaderImg"><span>Einen Moment bitte...</span></p>');
$("#_BUYITEM_CONTENT").html(response); // update the DIV
}
});
return false; // cancel original event to prevent form submitting
});
Without it I can't get it to refresh the dialog box with new content.
It seems that your javascript code is replicated in every $('a.ajaxBuyItemDialog') destination page clicked. Adding that script to the dialog again at every click causes event to be triggered more than once.
If you reload the script numerous times it will add a new submit handler to form each time since you are using live().
live() will delegate the handler to the document and thus should either only be called once or you need to call die() before script loads each time.
if you were to get rid of using live() you could move the submit handler to the success callback of load() and use submit() rather than live(). If the original form is replaced...the original submit() event handler will also be gone
"Dirty" solution
function watchBuyItemForm(){
$("#_BUYITEM_FORM").submit(function(){
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response){ // on success..
somedialog.html(ajaxLoader);
somedialog.html(response); // update the DIV
watchBuyItemForm();
}
});
return false; // cancel original event to prevent form submitting
});
}
I have a jquery sortable with an ajax callback tied to the update event. The ajax callback sends the updated sort order back to the server and then does a refresh of the sortable to guarantee that the client and server are both in sync.
The problem I am having is that the user can start a new sortable event before the ajax call has completed - I'd like to prevent that.
What I did try doing was disabling the sortable on the update event, and then re-enabling it when the ajax call returned. However unless I messed up the sequence, this didn't seem to work - I can still start a new sortable drag while the ajax call is still active.
Is there any other way to prevent this? I can certainly set a global javascript variable that says, "hey not right now, I'm ajaxing..." and reference it, but I'm not sure what sortable event would check for this, or how it would kill the sortable click request.
Thoughts?
For a better user experience...
Instead of disabling the interface, you should cancel the previous ajax request so that it doesn't overwrite any new requests.
This keeps the interface responsive, fluid and flexible.
It allows the user to 'change their mind' and reorder the list while waiting for it to save.
Any old requests are cancelled and therefore don't overwrite new requests...
//keep track of ajax request to allow cancellation of requests:
var ajaxRequest = null;
$('ul.sortable').sortable({
containment: 'parent',
update: function (event, ui) {
//display your loading anim gif
//get list of ids in correct order:
var ids = $(this).sortable('toArray').toString();
//cancel any previous ajax requests:
if (ajaxRequest) {
ajaxRequest.abort();
}
//post order to web service:
ajaxRequest = $.ajax({
type: 'POST',
url: 'somewebservice.blah',
data: ids,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (response) {
//saved ok:
ajaxRequest = null;
//hide your loading anim gif
}
});
}
});
You can simply overlay a transparent absolutely-positioned div over the whole list, which will prevent any clicks/drags on the list.
Set it in your CSS to display: none. Then, when you initiate an AJAX call, set it to display: block, and when your AJAX call completes, switch it back to display: none.
Did you try to set the disabled property ?
$('#sortable').sortable('option', 'disabled', true )
And then after the ajax request
$('#sortable').sortable('option', 'disabled', false )
I'm using some jQuery tabs that load their content via ajax. I'm using $(document).ready() in conjunction with the following code:
// Hide loading animation, show content container
$("#content").show();
$("#loading").hide();
The purpose is to wait until the page is fully loaded, then show the content and hide the loading animation.
However, $(document).ready() only waits for the main page to load, not the external ajax content.
Is there something I can do wait until the ajax is loaded too?
Thanks in advance.
Depending on your ajax library, there is usually an option for supplying a callback which is called when the underlying ajax (get post..) operation is complete. You could use that callback to do your initialization rather than within .ready()....
First, if you wish to show animation while you're loading, use ajaxStart and ajaxStop. It does it auto-painlessly. Here's an example:
// Note! This uses jquery-ui to do the dialog...
jQuery(document).ready(function() {
var body = jQuery("body");
body.append('<div id="ajaxBusy"><div style="text-align:center" ><p>Communicating with server...<br \/>Please wait for this operation to finish.<br \/><img src="\/js\/jquery.smallhbar.indicator.gif" \/><\/p><\/div><\/div>');
jQuery('#ajaxBusy').css({
display:"none",
margin:"0px",
width:"260px",
height:"170px",
padding:"5px",
textAlign:'center'
});
jQuery("#ajaxBusy").dialog({
autoOpen: false,
bgiframe: true,
closeOnEscape: false,
//modal: true,
title: 'Shipping Department'});
jQuery(document).ajaxStart(function() {
jQuery('#ajaxBusy').dialog('open');
});
jQuery(document).ajaxStop(function() {
jQuery('#ajaxBusy').dialog('close');
});
});
With this code in my jQuery.ready section, a pretty dialog automatically flashes when ajax operations are occurring.
Finally, if you need to show content afterwards, you need to put your show() method within the success function of your ajax call. If you have multiple ajax calls happening, you'll need to use some variables as flags to signal when everything is done (clunky).
Do you have one or more than one ajax call happening?