Reputation: 11107
I have three div boxes on my pageIn each div box there is a delete button I press that removes the div box from the code. An ajax request in that same event sends an unique number based on which div box was pressed to the server. In order to prevent multiple click events to be called on the delete button, I used the one() event. But in rare events where I click the button quickly it will fire the event twice and I see that the database received duplicate numbers. I thought one() prevents that from happening. What could be wrong with my jquery code to cause it to fire twice? My code is below.
Sample button from HTML
<input id="delete_post_3" type="button" value="X">
jQuery Code
$('#delete_post_1').one('click', function() {
var session_user_id = <? php echo $session_user_id; ?> ;
var number = 1;
$.post('ajax_delete_post.php', {
user_id: session_user_id,
number: number
}, function() {
$('#post_1').remove();
});
});
$('#delete_post_2').one('click', function() {
var session_user_id = <? php echo $session_user_id; ?> ;
var number = 2;
$.post('ajax_delete_post.php', {
user_id: session_user_id,
number: number
}, function() {
$('#post_2').remove();
});
});
$('#delete_post_3').one('click', function() {
var session_user_id = <? php echo $session_user_id; ?> ;
var number = 3;
$.post('ajax_delete_post.php', {
user_id: session_user_id,
number: number
}, function() {
$('#post_3').remove();
});
});
Update: Per request, I'm going to give a brief explanation on my code for the entire page.
<script>
//when document is ready, loads jquery code that allows any div boxes that currently
//exist on the page to have a click event that will delete the box. this is the same
//code seen above in my example.
</script>
<form>
//form to fill out info
</form>
<script>
//ajax post sent when form button clicked
$.post('ajax_file.php', {data: data}, function(data){
//in here div box is created
<script>
//duplicated jquery code from top of page. without it the div box delete button does
//not work
</script>
});
</script>
Upvotes: 9
Views: 1341
Reputation: 1240
I know your question was about finding out why your one() wasn't working. But it looks like, over the course of discussion, we've all determined that you've ended up creating multiple one() declarations. We also now know that you'll get one execute for each one() you declare and that is undesired for your situation. While that finding technically answers your question, I believe your problem isn't solved. I was thinking that maybe your approach to your problem could be modified and ended up making this JS fiddle:
The gist of my suggestion:
That's pretty much it. This is my first attempt ever to answer a question on stackoverflow, so I hope you'll find this helpful!
Upvotes: 0
Reputation: 95018
Stop binding the events every time you add more buttons and instead bind them only once using event delegation.
var session_user_id = <? php echo $session_user_id; ?> ;
$("#someparentelement").on( "click", "button[id^=delete_post]:not(.handled)", function(){
var theid = this.id.replace(/delete_post_/i,"");
$(this).addClass("handled");
$.post('ajax_delete_post.php', {
user_id: session_user_id,
number: theid
}, function() {
$('#post_' + theid).remove();
});
});
Small note though, I suspect you don't need to pass user_id
, php should be able to pull that out of the session.
Edit: Oops, .one
delegeated still only fires one event overall, not one per child. Updated to similar .on
functionality.
Important
Do not put this code in a location where it will execute more than once.
Upvotes: 0
Reputation: 499
You should lock your post and maybe get everything into one function like that:
var locker = 0;
$('.delete_post').on('click', function() {
if (locker == 0)
{
locker = 1;
var session_user_id = <? php echo $session_user_id; ?> ;
var number = $(this).attr('id');
$.post('ajax_delete_post.php', {
user_id: session_user_id,
number: number
}, function() {
$('#'+number).remove();
locker = 0
});
}
});
Your input thing should of course look like that then:
<input id="3" class="delete_post" type="button" value="X">
<input id="2" class="delete_post" type="button" value="X">
<input id="1" class="delete_post" type="button" value="X">
Upvotes: 0
Reputation: 2889
It seems like you are using synchronous call issue. remove all the code from click function to a new function. call that function on click. also use asynchronous ajax request.
Upvotes: 0
Reputation: 51870
From what I understand in your document :
<script>
//if #delete_post_1 exists in the page, it receives a "once" event handler to delete #post_1
</script>
<form>
</form>
<script>
$.post('ajax_file.php', {data: data}, function(data){
//if the request succeeds, this html code is loaded into the DOM
<script>
//are you sure that you do not bind a *second* "once" event handler to #delete_post_1 ?
</script>
});
</script>
Upvotes: 0
Reputation: 22339
I can't tell if this issue is sorted or not, but given all the feedback in the comments it seems you are binding one
twice and it also seems based on the comments you left in user23875
's answer that you are aware of that.
If you bind the event twice it executes twice, simple as that.
If you are fully aware of the fact that you are binding the event twice, why not try unbinding any previous attached event first.
$('#delete_post_1').off('click').one('click', function() {
...
$('#delete_post_2').off('click').one('click', function() {
...
$('#delete_post_3').off('click').one('click', function() {
Unless you are also re-rendering your complete HTML twice the above will make sure you are only ever having attached a single click event.
As user23875
had pointed out, you are certainly doing something funky in your scripts.
You should be separating your code as much as possible to ensure code you only intent to run ones only gets called ones and so on.
Hopefully the above will fix this issue.
Upvotes: 3
Reputation: 16436
How about you add a '.disabled'
class to the button on click, and have the click event have a :not(.disabled)
on the event selector?
EXAMPLE:
$('#delete_post_1:not(.disabled)').one('click', function() {
$(this).addClass('disabled');
var session_user_id = <? php echo $session_user_id; ?> ;
var number = 1;
$.post('ajax_delete_post.php', {
user_id: session_user_id,
number: number
}, function() {
$('#post_1').remove();
});
});
Upvotes: 0
Reputation: 6232
could you try this code and check the console if it fires twice?
$('#delete_post_3').on('click', function(event) {
var session_user_id = <?php echo $session_user_id;?> ;
var number = 3;
$.post('ajax_delete_post.php', {
user_id: session_user_id,
number: number
}, function() {
$('#post_3').remove();
})
$(this).off(event);
})
try one last thing: quotes
"user_id": session_user_id,
"number": number
Upvotes: 0
Reputation: 640
Well, first check that you do not have a space between <
and php
where you echo the session_user_id
... This might be an possible solution, the rest seams to be right.
Upvotes: 0