I am learning jquery and i am stuck with a problem. Here is the code
$(function(){
var gotProducts=new Array();
var productsWithDelete=new Array();
$('.addProducts').on('keyup',function(event) {
var searchVal=$(this).val().trim();
if(searchVal.length > 0) {
$.ajax({
url: 'http://localhost/url',
data: { products: $(this).val(), },
type: 'POST',
dataType: 'html',
success: function(msg) {
$('#printTheProducts').html(msg);
}
});
}
});
$('.productsButton').click(function() {
alert('yes');
});
});
The response I am getting from the ajax call is a button having class productsButton.
Now when i try to click that button I got through ajax then it does not alert yes. I mean it does nothing.
Question:-
What might be the problem?
Try event delegation using .on() for generated button, As they are generated dynamically
$('#printTheProducts').on('click','.productsButton',function(){
alert('yes');
});
Where #printTheProducts is the closest parent element, you can use document or document.body also as a selector!
Syntax:
$(closestparentelement).on('event','targetselector',function(){
});
Related
Can anyone point out what I'm doing wrong here? I'm trying to interact with data (appended using ajax)
The alerts fire if the element is already in DOM, but not when It's appended.
Am I using the ".on" wrong?
$(function() {
$('.card').on('click','.add-exercise', function() {
alert('clicked');
});
// Detect 'enter' key up
$('#search').on('keyup', function(e){
if(e.keyCode == 13)
{
console.log('hit enter key');
$(this).trigger("enterKey");
}
});
$('#search').on("enterKey",function(e){
$.ajax({
url: '{{ url("exercises/load") }}',
method: "POST",
data: {
_token: "{{csrf_token()}}",
search: $('#search').val(),
},
dataType: "text",
success: function(data) {
console.log(data);
$('.exercise-result').remove();
$('.card-deck').append(data);
}
});
});
});
I guess you have other .card elements in data.
You have to assign the event click again for them. The event is currently only assigned to your first .card elements. This is why it doesn't fire on your new .card elements.
I believe you need to add the event again each time the append is done. Try this and let me know if it works:
function addEvent() {
$('.card').on('click','.add-exercise', function() {
alert('clicked');
});
}
$(function() {
addEvent();
// Detect 'enter' key up
$('#search').on('keyup', function(e){
if(e.keyCode == 13)
{
console.log('hit enter key');
$(this).trigger("enterKey");
}
});
$('#search').on("enterKey",function(e){
$.ajax({
url: '{{ url("exercises/load") }}',
method: "POST",
data: {
_token: "{{csrf_token()}}",
search: $('#search').val(),
},
dataType: "text",
success: function(data) {
console.log(data);
$('.exercise-result').remove();
$('.card-deck').append(data);
addEvent();
}
});
});
});
I think the .card element is also loading dynamically, in order to make event delegation works properly you need to bind it to an element which is present at the time of page load.
So either you can attach it to the document object.
$(document).on('click','.card .add-exercise', function(){
// rest of your code
});
or better approach would be, attach to an element which is present at the time of page load(I guess .card-deck is present at the time of page load since you are appending data to that or attach to body tag).
$('.card-deck').on('click','.card .add-exercise', function(){
// rest of your code
});
I'm using below code. This is bootstrap 3 delete conformation message.
$(document).ready(function(){
$('a.btnDelete').on('click', function (e) {
e.preventDefault();
var id = $(this).closest('div').data('id');
$('#myModal').data('id', id).modal('show');
});
$('#btnDelteYes').click(function () {
var id = $('#myModal').data('id');
var dataString = 'id='+ id ;
$('[data-id=' + id + ']').parent().remove();
$('#myModal').modal('hide');
//ajax
$.ajax({
type: "POST",
url: "delete.php",
data: dataString,
cache: false,
success: function(html)
{
//$(".fav-count").html(html);
$("#output").html(html);
}
});
//ajax ends
});
});
This is the trigger element that I'm using
<div data-id="MYID"><a class="btnDelete" href="#">Delete</a></div>
And I'm using the same HTML element dynamically to trigger delete and it doesn't work.
Can someone point me the correct way to do it?
You have to use event delegation
$(document).on("click" , '#btnDelteYes' ,function () {
Pretty much: bind the click higher up to something that exists when the script is run, and when that something is clicked, tell it to pass the click event to the #btnDelteYes element instead
I cant understand what exactly you are doing on your code due to missing information, but the answer is: you should use event delegation on the dynamically inserted content
you can try
$('[data-id=MYID]').on('click','.btnDelteYes',function({
e.preventDefault();
var id = $(this).closest('div').data('id');
$('#myModal').data('id', id).modal('show');
});
here <div data-id="MYID"> should be a hard coded html content and The idea is to delegate the events to that wrapper, instead of binding handlers directly on the dynamic elements.
Simple ajax query, but being triggered for every item of a class using the .click() event. When it gets to the .done() I cannot figure out how to look up the element which was clicked so I can properly remove the m_action class.
Below is the code. I'm sure I'm missing something simple, but I've been searching with Chrome and Firefox web tools without luck, and can't find a duplicate question here on Stack.
In short: using the code below, how do I properly remove the m_action class of the clicked element on a successful jQuery ajax return?
<script type="text/javascript">
jQuery("div#normal .m_action").click(function() {
jQuery.ajax({
url: "./action.php",
type: "POST",
data: { action: this.id }
}).done(function(result) {
jQuery(this).removeClass("m_action");
jQuery(this).html(result);
}).fail(function(result) {
alert("There was an error.")
});
})
</script>
You can just store a reference to it so that it is available anywhere in that scope:
jQuery("div#normal .m_action").click(function() {
var elem = this; // <-- right here
jQuery.ajax({
url: "./action.php",
type: "POST",
data: { action: this.id }
}).done(function(result) {
jQuery(elem).removeClass("m_action"); // <-- elem is still available
jQuery(elem).html(result); // <--
}).fail(function(result) {
alert("There was an error.")
});
});
Just a note for the future, your problem doesn't have to do with jQuery. This is just a simple use of variables within a scope. The this pointer changes within the done function, so you just needed to cache the reference.
This code should work:
$(document).ready(function()
{
jQuery(".m_action").click(function() {
var self = $(this);
jQuery.ajax({
url: "./action.php",
type: "POST",
data: { action: this.id }
}).done(function(result) {
self.removeClass("m_action");
self.html(result);
}).fail(function(result) {
alert("There was an error.")
});
})
});
</script>
This code works fine for first click as it changes class along with image which is referenced from CSS. But when I click second time it acts like clicked in previous class which I assume removed already.
if(Model.SeenItWantToSeeIt.Status==1)
{
<div class="movie_data">
<div class="usermovie_option"> </div>
</div>
<div class="clear"></div>
}
else{
<div class="movie_data">
<div class="usermovie_option"> </div>
</div>
<div class="clear"></div>
}
And Javascript for toggling class is
$(".want_to_see_it").click(function () {
var wantToSeeIt = $(this);
alert('clicked on want to see it.');
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: 1, MovieID: movieID },
dataType: 'json',
type: "POST",
success: function (data) {
wantToSeeIt.removeClass();
wantToSeeIt.addClass("dont_want_to_see_it");
$("dont_want_to_see_it").show();
},
error: function (data) {
alert('Error occurred.');
}
});
});
$(".dont_want_to_see_it").click(function () {
alert('clicked on donot want to see it');
var wantToSeeIt = $(this);
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: 0, MovieID: movieID },
dataType: 'json',
type: "POST",
success: function (data) {
wantToSeeIt.removeClass();
wantToSeeIt.addClass("want_to_see_it");
$("want_to_see_it").show();
},
error: function (data) {
alert('Error occurred.');
}
});
});
And problem is it shows "clicked on donot want to see it" or "clicked on want to see it" as alert every time I click . What I have to do is this message should alternate every time I Click on their respective image.
Problem here is that you want to change the handlers dynamically on click of each element. But events are bound to the element directly using click event.
One option is to hide and show respective items.
Another option is to bind and unbind events.
Third option is to use event delegation. Your requirement will work with this since with event delegation events are not directly attached to the elements, they are instead delegated. So the moment you swap the class name event subscribed for that class name will automatically get delegated. SO next click on the same element will go to the other event handler attached its new class name. See if this is what you were looking for.
$(document).on('click',".want_to_see_it" ,function (e) {
var wantToSeeIt = $(this);
alert('clicked on want to see it.');
///Your ajax
wantToSeeIt.removeClass();
wantToSeeIt.addClass("dont_want_to_see_it");
$(".dont_want_to_see_it").show();
});
$(document).on('click',".dont_want_to_see_it" ,function (e) {
alert('clicked on donot want to see it');
var wantToSeeIt = $(this);
///Your ajax
wantToSeeIt.removeClass();
wantToSeeIt.addClass("want_to_see_it");
$(".want_to_see_it").show();
});
Note:- In the example i have attached to the document, You should n't attach it to the document, instead attach it to any containing element that is present in DOM at any time.
Demo
There was another issue, you missed . before the classname in your ajax success.
The problem is you need to unbind("click") to clear the previous handler then bind a new event handler for its new class.
Instead of unbinding and rebinding, do in one handler:
$(".usermovie_option a").on("click", function () {
var status = 0;
if ($(this).hasClass("want_to_see_it")) {
status = 1;
}
$.ajax({
url: '#Url.Action("SeenIt", "MovieProfile")',
data: { Status: status, MovieID: movieID,
dataType: 'json',
type: "POST",
success: function (data) {
$(this).toggleClass("want_to_see_it");
$(this).toggleClass("dont_want_to_see_it");
},
error: function (data) {
alert('Error occurred.');
}
});
});
Doing following in jQuery:
$('#signupbox1').on('click', '#signup1', function() {
var str = $('#signupform').serialize();
// make it look like a waiting button
$('#signup1').addClass("btn_wait");
var btn_val = $('#signup1').val();
$('#signup1').val('');
$.ajax({
type: "POST",
url: "signup_step1.php",
data: str,
success: function(msg) {
//doing stuff here
$('#signup1').removeClass("btn_wait");
$('#signup1').val(btn_val);
}
});
});
How could you disable the click event as well till you receive an answer from the ajax call? So, when you click on the button it not only "transforms" to a waiting button because of the added class, but also the click event will be "paused"... is this possible?
Thank you very much in advance!
$('#signupbox1').on('click', '#signup1', function() {
var str = $('#signupform').serialize();
// make it look like a waiting button
var btn_val = $('#signup1').val();
$('#signup1').addClass("btn_wait").val('').unbind('click');
$.ajax({
type: "POST",
url: "signup_step1.php",
data: str,
success: function(msg) {
$('#signup1').removeClass("btn_wait").val(btn_val);
},
complete: function() {
$('#signup1').bind('click'); // will fire either on success or error
}
});
});
You can add a flag to denote "currently loading". You can use anything like a variable, property or attribute. In this example, I use jQuery .data()
Also, it's advisable that you use submit event instead of adding a click handler to the submit button when you submit a form.
$('#signupform').on('submit', function() {
var form = $(this),
loading = form.data('loading'), //check loading status
str, button, val;
//if not loading
if(!loading){
//set loading to true
form.data('loading',true);
str = form.serialize();
button = $('#signup1', form);
val = button.val();
// make it look like a waiting button
button
.addClass("btn_wait");
.val('');
$.ajax({
type: "POST",
url: "signup_step1.php",
data: str,
success: function(msg) {
//remove loading state
form.data('loading',false);
//return button to normal
button
.removeClass("btn_wait");
.val(val);
}
});
}
});