jQuery preventDefault() doesn't work with .on()
Yes, I've read many other articles with the same problem, but I don't understand how to fix this. I have created a bookmark button that needs to change the icon when clicked.
my jQuery:
jQuery(document).ready( function() {
var bm = jQuery(".user_bookmark");
bm.on("click", ".user_bookmark", function (e) {
e.preventDefault();
post_id = jQuery(this).attr("data-post_id")
nonce = jQuery(this).attr("data-nonce")
jQuery.ajax({
type : "post",
dataType : "json",
url : bookmarkAjax.ajaxurl,
data : {action: "eri_user_bookmark", post_id : post_id, nonce: nonce},
success: function(response) {
if(response.type == "success") {
var add = 'Add Bookmark';
var remove = 'Remove Bookmark';
var display = bm.attr('display');
var bookmarked = bm.attr('bookmarked');
if (display == 'icon') {
add = '<i class="x-icon" data-x-icon-o="" aria-hidden="true"></i>';
remove = '<i class="x-icon" data-x-icon-s="" aria-hidden="true"></i>';
}
if (bookmarked) {
bm.html(remove);
bm.attr('bookmarked', 'false');
} else {
bm.html(add);
bm.attr('bookmarked', 'true');
}
}
else {
alert("Your bookmark could not be added")
}
}
})
});
})
First, I had it bm.click()
, but it only took one click to use, then read to switch to the .on()
feature, now refreshing the page.
I tried switching out function (e)
with function ()
and replacing e.preventDefault();
with return false;
, e.stopImmediatePropagation();
and e.stopPropagation();
.
Also tried switch bm.on()
with jQuery(document).on()
all these changes. That still runs my code and doesn't refresh, but doesn't change the element in the jQuery code.
HTML example:
<a class="user_bookmark" data-nonce="2b92b05de9" data-post_id="1" href="https://example.com/wp-admin/admin-ajax.php?action=eri_user_bookmark&post_id=1&nonce=2b92b05de9" display="icon" bookmarked="true" style="outline: none;">
<i class="x-icon" data-x-icon-s="" aria-hidden="true"></i>
</a>
Complete PHP Gist : https://gist.github.com/mrgandy/91361fca86e769235eec684a4647b875
The problem is because you accidentally nested event handlers. You will attach a delegated event handler to .user_bookmark
listen for click events on child .user_bookmark
elements . Your HTML shows that these elements are not nested, so the event handler never fires, so no preventDefault()
call or AJAX request.
Assuming the element <a />
you're targeting is not dynamically created, then remove the second parameter you used in the on()
call .
jQuery($ => {
var $bm = $('.user_bookmark');
$bm.on('click', function(e) {
e.preventDefault();
let post_id = $(this).data('post_id');
let nonce = $(this).data('nonce');
console.log(post_id, nonce);
console.log('ajax request here...');
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="user_bookmark" data-nonce="2b92b05de9" data-post_id="1" href="https://example.com/wp-admin/admin-ajax.php?action=eri_user_bookmark&post_id=1&nonce=2b92b05de9" display="icon" bookmarked="true" style="outline: none;">
<i class="x-icon" data-x-icon-s="" aria-hidden="true"></i>
Lorem ipsum
</a>
If you were actually adding elements dynamically to the DOM after the page loaded, you would need to assign the delegated event handlers to a static parent, which would look like this:
jQuery($ => {
$(document).on('click', '.user_bookmark', function(e) {
e.preventDefault();
let post_id = $(this).data("post_id");
let nonce = $(this).data("nonce");
console.log(post_id, nonce);
console.log('ajax request here...');
});
})