How do i prevent my .done handler from being called multiple times? - javascript

I have this JQuery expression where i push a button, get some HTML from the server and then append it to a DOM node in my document:
<script type="text/javascript">
$(document).ready(function () {
$(".addbutton").click(function () {
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' })
.done(function (data) {
$(addbuttonNode).next().next().append(data); //find better way of doing this
});
});
});
</script>
I have multiple ".addButton" buttons on my web site. The problem im experiencing is that after multiple clicks on the buttons my .done handler is being called multiple times.
My guess is that i have a list of event handlers that are being executed, I cant understand where / why this is done or how I prevent it from happening.

The problem is not taht you do the request is done more then once rathern then it calls done after its done.. you can keep the state in data object::
$(document).ready(function () {
var posting = false;
$(".addbutton").data("done", false).click(function () {
var addbuttonNode = $(this);
if (!addbuttonNode.data("done")) {
addbuttonNode.data("done", true);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' })
.done(function (data) {
$(addbuttonNode).next().next().append(data);
});
}
});
});

I would do the following:
$(".addbutton").click(function () {
var addbuttonNode = $(this);
addbuttonNode.attr('disabled',true);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' })
.done(function (data) {
$(addbuttonNode).next().next().append(data); //find better way of doing this
addbuttonNode.attr('disabled',false);
});
});

You could check it for any request pending:
$(document).ready(function () {
$(".addbutton").click(function () {
// if any request pending, return {undefined}
if ($.active) return;
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", {
id: '#guid'
}).done(function (data) {
// instead of .next().next()
$(addbuttonNode).nextAll('selector').first().append(data); //find better way of doing this
// or .parent().find('selector')
});
});
});
If you wish instead each button to be clickable only once, then use jQuery .one() method:
$(document).ready(function () {
$(".addbutton").one('click', function () {
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", {
id: '#guid'
}).done(function (data) {
// instead of .next().next()
$(addbuttonNode).nextAll('selector').first().append(data); //find better way of doing this
// or .parent().find('selector')
});
});
});

Try to use bind, and unbind functions for the event handling. Then You can unbind the click function after it was executed once.
<script type="text/javascript">
$(document).ready(function () {
$(".addbutton").bind('click',function () {
var addbuttonNode = $(this);
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' }).done(function (data) {
addbuttonNode.next().next().append(data);
});
addbuttonNode.unbind('click');
});
});
</script>
Another way of doing nearly the same, I think this should be better:
<script type="text/javascript">
$(document).ready(function () {
$(".addbutton").each(function(){
$(this).bind('click',function () {
$.post("/InteractiveApplications/GetQuizAnswer", { id: '#guid' }).done(function (data) {
addbuttonNode.next().next().append(data);
});
$(this).unbind('click');
});
});
});
</script>
I haven't tried it yet, but it should work, try it! :)
You can also set up a class or data attribute to check if the button was already clicked. You can then exit from the script like if($(this).hasClass('clicked')) { return; } or something...

Related

how to bind event to element after generateing

I have this script :
$(window).load(function () {
$(document).on('click', '.btn-delete-confirm', function () {...});
});
and I have this element :
<div id="attachments"></div>
and I have this script to load some html :
$(document).on('click', '.nav-tabs li a[href="#attach"]', function () {
$.ajax({
url: loadAttachmentsURL,
data: { equipmentId: equipmentId },
success: function (data) {
$("#attachments").html(data);
}
});
});
in my result from ajax I have some button that have .btn-delete-confirm class but when clicked on them nothing happen .
the sample of result like this :
<td><a data-id="73b2db39-199c-845c-8807-6c6164d2d97d" data-url="/Admin/EquipmentAttachment/Delete" class="btn-delete-confirm btn">Delete</a></td>
how can I resolve this ?
one way will be by attaching click event after html is set:
$(document).on('click', '.nav-tabs li a[href="#attach"]', function() {
var equipmentId = "?";
var loadAttachmentsURL = "/url";
$.ajax({
url: loadAttachmentsURL,
data: {
equipmentId: equipmentId
},
success: function(data) {
$("#attachments").html(data);
$(".btn-delete-confirm").click(function() {
alert("click!");
});
}
});
});
another will be attaching the click event to the document context:
$(document).on('click', ".btn-delete-confirm", function() {
alert("click!");
});
$(document).on('click', '.nav-tabs li a[href="#attach"]', function() {
var equipmentId = "?";
var loadAttachmentsURL = "/url";
$.ajax({
url: loadAttachmentsURL,
data: {
equipmentId: equipmentId
},
success: function(data) {
$("#attachments").html(data);
}
});
});
You are trying to add an eventlistener to something that isnt there yet.
This will result in an error, and the event wont fire again.
So try to add the listener AFTER the ajax import.
$(document).on('click', '.nav-tabs li a[href="#attach"]', function () {
$.ajax({
url: loadAttachmentsURL,
data: { equipmentId: equipmentId },
success: function (data) {
$('#attachments').html(data);
$('.btn-delete-confirm').on('click', function () {...});
}
});
});
Though .delegate() method is deprecated in jquery-3.0, its description is still worth to have a look:
Attach a handler to one or more events for all elements that match the
selector, now or in the future, based on a specific set of root
elements.
Exmaple:
// jQuery 1.4.3+
$( elements ).delegate( selector, events, data, handler );
// jQuery 1.7+
$( elements ).on( events, selector, data, handler );
Using document as a root element is not a big problem, but have you tried #attachments ?
$(window).load(function () {
$("#attachments").on('click', '.btn-delete-confirm', function () {...});
});

JavaScript setInterval inside bind

I am trying to make an infinite periodic get loop:
<script type=text/javascript>
$(function() {
$('a#log').bind('click', setInterval(function() {
$.get(
$LOG + '/json_test',
{},
function(data) {
document.getElementById("logs").innerHTML = data.replace('\n', '<br/>');
}
);
}, 2000));
});
</script>
If I do this
<script type=text/javascript>
$(function() {
$('a#log').bind('click', function() {
$.get(
$LOG + '/json_test',
{},
function(data) {
document.getElementById("logs").innerHTML = data.replace('\n', '<br/>');
}
);
});
});
</script>
All works well, but without infinite loop.
As #sacho say, setInterval() returns a Number. You are binding that number as your click handler instead a function. That's why is not working, but...
You can do something like this is just want to call the ajax function every time is finished, you can't be sure that your response will be every 2000ms.
$('a#log').click(function (e) {
e.preventDefault();
infiniteLoop();
})
function infiniteLoop() {
$.get(
$LOG + '/json_test',
{},
function(data) {
$("#logs").html(data.replace('\n', '<br/>'));
infiniteLoop();
}
);
}
Note: Use jQuery (specially to manage the DOM) every time you can if you already loaded the library
You need wrap your setInterval function in a intermediate function to prevent it from executed before your click. In other word, a function inside a function.
$(function () {
$('a#log').bind('click', function () {
setInterval(function () {
$.get('example.json',{}, function (data) {
$('#logs').html(JSON.stringify(data).replace('\n', '</br>'));
});
}, 2000);
});
});
JSfiddle Working Demo: http://jsfiddle.net/x13sruaf/
$('a#log').on('click', infiniteLoop);
function infiniteLoop() {
setInterval(function() {
}, 2000);
}
You can try this :
<script type=text/javascript>
$(function() {
var refreshIntervalId;
$('a#log').bind('click', function (){
clearInterval(refreshIntervalId);
refreshIntervalId = setInterval(function() {
$.get(
$LOG + '/json_test',
{},
function(data) {
document.getElementById("logs").innerHTML = data.replace('\n', '<br/>');
}
);
}, 2000);
});
});
</script>

Div not displaying correctly on show

<script type='text/javascript'>
$(document).ready(function () {
var fenster = $(location).attr('href');
if (fenster == 'http://www.cyrill-kuhlmann.de/index.php/') {
$('#intro-page').show(function () {
$(this).click(function () {
$(this).fadeOut(250);
});
});
}
});
</script>
I have a div that needs to be displayed in full-screen as an intro. The problem is that it doesn't display correctly; it just displays itself in the top left corner and grows until its full-screen. Why is it doing this?
show() takes the duration of the animation as a first parameter. You have given it a function, which is incorrect. Either you meant to chain your methods:
$('#intro-page').show().click(function () {
$(this).fadeOut(250);
});
Or, you did mean to put a callback function in there, but you missed out the first parameter; the duration:
$('#intro-page').show(250, function(){
$(this).click(function(){
$(this).fadeOut(250);
});
});
Documentation
show()
<script type='text/javascript'>
$(document).ready(function () {
var fenster = $(location).attr('href');
if (fenster == 'http://www.cyrill-kuhlmann.de/index.php/') {
$('#intro-page').show(function () {
$(this).click(function () {
$(this).fadeOut(250);
});
});
}
});
</script>
try the following:
<script type='text/javascript'>
$(document).ready(function () {
var fenster = $(location).attr('href');
if (fenster == 'http://www.cyrill-kuhlmann.de/index.php/') {
$('#intro-page').show();
$('#intro-page').click(function(){
// seperate it from show function call so you can have more access to object
// and do logic on it.
$(this).fadeOut(250);
});
}
});
</script>

JQuery Ajax + Dropdown Menu function only runs once

This function only runs once. How can I get it to run multiple times?
I have tried using live() as was suggested in another SO question, but that made no difference to the program.
$(function() {
$('#chooseTeam').live('change', (function() {
$.getJSON($SCRIPT_ROOT + '/_get_info', {
selectedDeck: $('#chooseTeam').val()
}, function(data) {
/* Do something */
});
}
return false;
}));
});
Did you tried with document ready instead of $function()
$(document).ready(function() {
$('#chooseTeam').live('change', (function() {
$.getJSON($SCRIPT_ROOT + '/_get_info', {
selectedDeck: $('#chooseTeam').val()
}, function(data) {
/* Do something */
});
}
return false;
}));
});
Regards

jquery ajaxStart/ajaxStop not working

i have very simple code that i making partial postback by jquery and i use ajaxStart/ajaxStop for doing some work. but it is not working. i just could not understand why it is not working.
here is my code
$("#imgHolder").ajaxStart(function () {
$('div#content').block({
message: '<table><tr><td><img src="../images/ajax-loader.gif" border="0"/></td><td><h3>Processing...</h3></td></tr><table>',
css: { border: '1px solid #a00' }
});
$('#imgHolder').empty();
$("#btnPrint").hide();
});
$("#imgHolder").ajaxStop(function () {
$("#btnPrint").show();
$('div#content').unblock();
});
$(document).ready(function () {
$.ajax({
type: "POST",
url: "UPSLabelFormUK.aspx/ProcessInfo",
data: JSON.stringify(DTO),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data.d[0].Message == "SUCCESS") {
//alert(data.d[0].TrackNumber);
///alert(data.d[0].LabelImagePath);
var _images = [data.d[0].LabelImagePath];
$.each(_images, function (e) {
$(new Image()).load(function () {
$('#imgHolder').html("<img src='" + data.d[0].LabelImagePath + "' width='310' height='402' border=0/>");
}).attr('src', this);
});
}
} ,
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
});
i just dont not understand why my above ajaxstart/ajaxstop did not work. please help me to understand why was wrong in my code.
but my ajaxstart/ajaxstop started working when i change the code a bit like
$(document).ajaxStart(function () {
$('div#content').block({
message: '<table><tr><td><img src="../images/ajax-loader.gif" border="0"/></td><td><h3>Processing...</h3></td></tr><table>',
css: { border: '1px solid #a00' }
});
$('#imgHolder').empty();
$("#btnPrint").hide();
});
$(document).ajaxStop(function () {
$("#btnPrint").show();
$('div#content').unblock();
});
the only change is $(document).ajaxStop(function () { instaed of
$("#imgHolder").ajaxStart(function () {
so please explain why my above ajaxStart/ajaxStop code did not work. thanks
Given the fact that ajaxStart is only called if there are no other
ajax requests in progress, it makes is useless if you want to use it
as an AJAX loader indicator.
have u tried with ( tell me is it working or not)
jQuery(document).ajaxStart(function(){
alert("it begins");
})
As of jQuery 1.8, the .ajaxStop() method should only be attached to document.
from jquery api web page of "ajaxStop". You can check it here.
Try this:
$("#loading").bind({
ajaxStart: function() { $(this).show(); },
ajaxStop: function() { $(this).hide(); }
});
Essentially binding your loadingAnimationElement to the globally fired ajaxStart and ajaxStop events. Only shows up when you intend it to.
When jQuery is not performing any Ajax requests and a new request is initiated, it fires an ajaxStart event. If other requests begin before this first one ends, those new requests do not cause a new ajaxStart event. The ajaxStop event is triggered when the last pending Ajax request is completed and jQuery is no longer performing any network activity.
This combination works fine. Thanks to user #brroshan
JS of Master page
<script language="JavaScript" type="text/javascript">
$(document).ajaxStart(function () {
$("#loading").show();
});
$(function () {
// Some other code
// The end of this code block
$("#loading").hide();
$("#loading").bind({
ajaxStart: function () { $(this).show(); },
ajaxStop: function () { $(this).hide(); }
});
});
</script>
html of Master page
<div id="loading" class="display: none;">
<h2>Loading...</h2>
</div>
Try this sample code:-
var $loading = $('#div_Loader').hide();
$(document).ajaxStart(function () {
$loading.show();
})
.ajaxStop(function () {
setTimeout(function () {
$loading.hide();
}, 1000);
});

Categories

Resources