jQuery - ignore double AJAX calls? - javascript

I have AJAX calls attached in multiple places (unfortunately not only buttons, but also links, forms and other stuff), I know how to handle this manually (find every place I do an AJAX call and then block / overlay the button during first call), I'm wondering if there's a way to do it more automagically?
If we're talking jQuery - maybe a plugin? Something that will just work? :)
It'd be perfect to have something like:
if clicked element has .ajax class
block all ajax requests if the current one is still live
I'd then add .ajax class to every button/link/whatever triggering the request and voila. Does anything like this exist?

You can to create a global variable:
loadingAjax = false;
whenever an event triggers, you turn this variable to TRUE by using:
$("selector").click(function(){
if(!loadingAjax){
loadingAjax = true;
$.ajax(options)..
}
});
And you should turn loadingAjax back into false when the ajax stops:
$( document ).ajaxStop(function() {
loadingAjax = false
});

Related

Bind Clicked Object to Callback

I'm using the Modaal library and want to dynamically load the content of the modal via Ajax, which requires sending the ID for each clicked item through to the callback.
I think I need to bind the clicked element to the modaal function, but am not sure how. I think that jQuery's on method.
Without binding, the popup works (but data is not updated for each item):
var info_popup = $('.info-popup');
info_popup.modaal({
after_open: function(ev){
console.log(info_popup.data('unique_id'));
}
});
When I bind the function, it returns the data, but a second click is required to launch the modal:
$('.info-popup').on('click', function() {
var unique_id = $(this).data('unique_id');
return $(this).modaal({
after_open: function(ev){
console.log(unique_id);
}
});
});
So I'm thinking I need to somehow forward the clicked status to Modaal, but not sure how.
Update
I can achieve this by setting the start_open parameter in Modaal to true, but not sure if this is an elegant approach, and would like to see how it would be done from outside of Modaal.

Prevent $element.on('click') before ajax is loaded

I am making and ajax call and storing the results in an array. After the first set of data is loaded, I am using next and previous buttons to navigate through the array.
I want to prevent any $(element).on('click') events from happening until I have the first set of data loaded.
Is there any way to do this?
I have already tried to use
$(element).unbind('click');
for when the document loads and then
$(element).bind('click');
when the ajax call is successful, but still clicking on either the next or previous links will still trigger my
$('#next #prev').on('click', function () {
//my code to navigate through the array here.
});
Anyone have any ideas on how I can complete stop this event from firing until the ajax has loaded?
You can disable them by default and in the ajax success callback you can turn them on with something like this:
$(element).prop("disabled", false); // Element will get enabled for clicking
I will update the answer now as it is not working for the concerned person, to disable the button do this:
$(element).attr(“disabled”, true);
In success callback of the ajax call you need to do this:
$(element).removeAttr('disabled');
$.ajax({
....
success:function(){
$('#next #prev').on('click', function(){
// only ajax event complete the #prev can run this function
}).off('click'); // no more clickable now
}
});
or you can just
$('#next #prev').hide();
// done?
$('#next #prev').show();

Javascript: event duplication

I can not figure out what is wrong with my code.
I have a couple of global variables which I change every time some certain button is pressed,there is also a couple of custom functions that perform ajax calls that returns a chunk of html code with a pagination below, that works like this:
$('#foot #pagination a.page').live('click', function(){
window.mode = 'partial';
window.key = $('input#search').val();
window.page = $(this).parent().find('input').val();
setTimeout('getData();', 0);
});
sometimes when moving to another page event doubles and I got the doubled html.
when caling getData(); from a browser console - everything works fine, like it has to work.
What can cause this?
You should execute this function only once after document.ready.
Or do something like this:
$('#foot').off('click', '#pagination a.page', navigation) // remove event
.on('click', '#pagination a.page', navigation); // add event
function navigation(e) {
window.mode = 'partial';
window.key = $('input#search').val();
window.page = $(e.currentTarget).parent().find('input').val();
setTimeout('getData();', 0);
});
The problem was that jQuery .live() pushes some data to jQuery stack on document ready, but after ajax response comes from the server and document ready event is called again - in this case .live() pushes the same data again to a jQuery stack, which then causes multiple event body calls.
I used .die() before .live() and everything now works fine.

How can I call a Jquery method on DOM elements that don't exist yet?

I'd like to use this lightbox plugin for some autocomplete links, that don't yet exist on my page.
You normally activate it using:
$(document).ready(function($) {
$('a[rel*=facebox]').facebox()
})
Since the a links aren't all on the page upon page load, I would normally look to the .live or .delegate methods to bind to an event, but in this case, what 'event' would I bind to to say "once this element is on the page, then call this method on it".
Or am I going about this totally the wrong way?
There is no such event.
You need to invoke the plugin when you add the elements to the page.
// create a new <a>, append it, and call the plugin against it.
$('<a>',{rel:"facebox"}).appendTo('body').facebox();
This example creates a new <a> element. If you're getting some elements from an AJAX response, call it against those:
var elems = $( response );
elems.filter( 'a[rel="facebox"]' ).facebox(); // if the <a> is at the top level
elems.find( 'a[rel="facebox"]' ).facebox(); // if the <a> is nested
elems.appendTo('body');
Not yet tested :
$(document).ready(function($) {
$(document).bind('change', docChanged) ;
})
function docChanged()
{
if ($('a[rel*=facebox][class!="faceboxed"]').length > 0)
{
$('a[rel*=facebox][class!="faceboxed"]').addClass("faceboxed").facebox();
}
}
This is entirely possible using the .live function. You just need to use the DOMNodeInserted event.
$(document).ready(function() {
$("a[rel*=facebox]").live("DOMNodeInserted", function() {
$(this).facebox();
});
});
You'll need to just add this call to the ajax that loads in the links.

jQuery click() not working on replaced html

I am trying to create a go-moku game using jquery,php, and mysql database.
I have a ajax function that updates the a board every second if needed.
var turnCount = -1;
setInterval(function(){
$.get('includes/boardControl.php',{turn: turnCount }, function(data){
if(data != "")
{ $("#board").html(data);
turnCount = $("#turnCount").text();
$("#turnCount").text("")
}
});
}, 1000);
This works just fine, it checks the database to see if turn has been incremented and replaces the board if it has. Now what I want to ultimately do is create a click function that use Ajax to update the board and turn count in the database. I am hoping to somehow use the N'th selector do determine what square I'm clicking on.
I have several questions.
1) My click function right now is
$(document).ready(function() {
$("td > img").click(function(){
alert("clicked");
});
});
as of right now it works on a extra test table I wrote into the html, but not on the table created with the previous function. What am I doing wrong?
2) The tutorials I've looked at so far dictate that I should write code in the following way.
$(document).ready(function() {
//code here
});
When i asked a question last night, I was told that I was over complicating things with my functions. So when should i use a document.ready function and when not? And is it fine to put all of my scripts into one document.ready function or should I have multiple?
3)
Once I get the click image to work I am hoping to send a X,Y coordinate to the server and change that corresponding spot on the board. How would I determine what cell in the table is clicked in order to know what coordinates to use? (or is there a much easier way?)
sounds like you need to change
$("td > img").click(function(){
alert("clicked");
});
to
$("td > img").live('click',function(){
alert("clicked");
});
Edit: For jQuery 1.9 and later you can do:
$("#board").on('click', 'td > img', function(){
// handle click
});
The $(document).ready() function only fires when the page first loads - in order to make this work try something like this:
function bindClicks() {
$("td > img").click(function(){
alert("clicked");
});
}
$(document).ready(bindClicks);
This will allow you to call bindClicks() later on if need be to bind the click events of a new table.
1) Are you re-wiring the click event after the ajax content loads?
The $(document).ready function will fire as soon as the page is fully loaded, but won't fire after ajax calls. So you will need to re-wire the click event after every ajax call:
2) KISS. Keep it as simple as possible. If you have 50+ lines inside a document.ready statement you might want to create some functions.
3) The best way to accomplish this might be to assign a specific ID to each cell and capture that in the click event. You can then pass that to the server and update the specific cell on the return.
Are you sure JQuery is matching you query:
$("td > img")
I would load firefox with firebug and check that your actually getting match first. The second table your creating may have a slightly different structure then you expected and firebug can show you the exact structure also.
Goodluck.

Categories

Resources