This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 3 years ago.
I suppose my function isn't correctly defined since when I replace table html code, table rows don't trigger anymore the function they are bound with.
Here is my HTML table:
<tr class="open-row-modal" href="/dashboard_staff/settings/ajax_update_period/1" data-toggle="modal" data-target="#form-modal">
<td>bla bla</td>
<td>30,00</td>
</tr>
And my javascript code:
var formAjaxSubmit = function(form, modal, obj_to_replace = false) {
$(form).submit(function (e) {
e.preventDefault();
$.ajax({
type: $(this).attr('method'),
url: $(this).attr('action'),
data: $(this).serialize(),
success: function (xhr, ajaxOptions, thrownError) {
if ( $(xhr).find('.has-error').length > 0 ) {
$(modal).find('.modal-body').html(xhr);
formAjaxSubmit(form, modal);
} else {
$(modal).modal('toggle');
if (obj_to_replace !== false) {
$(modal).modal('toggle');
obj_to_replace.parentNode.innerHTML = xhr;
}
}},
error: function (xhr, ajaxOptions, thrownError) {
// handle response errors here
}
});
});
};
$('.open-row-modal').click(function() {
var url = $(this)[0].attributes.href;
var parent_card = findAncestor($(this)[0], 'card-default');
let load = $('#form-modal-body').load(url.value, function () {
$('#form-modal').modal('toggle');
formAjaxSubmit('#form-modal-body form', '#form-modal', parent_card);
});
});
function findAncestor (el, cls) {
while ((el = el.parentElement) && !el.classList.contains(cls));
return el;
}
When the table is replaced, the click function is not triggered anymore.
I think it's because the elements are dynamically updated. Try using event delegation to handle the event. In jquery, try using .on() to attach the click event to the document selectors
$(document).on('click','.open-row-modal',function() {
See https://api.jquery.com/on/ for documentation about the .on() event handler.
Related
i have this code with out the (doc on) it work in tell the div is reloaded after the reload the buttons do not work. With (doc on) the event fires but drops the variables any ideas?
$(document).on(".status").click(function (event) {
event.preventDefault();
var ids = $(this).attr("data-id-status");
var status = $(this).attr("data-status");
var record = this;
$(record).attr('class', 'btn btn-danger big-bnt prams');
$(record).prop('disabled', true);
$(record).html('Precessing');
$.ajax({
url: 'ajax.php',
type: 'post',
data: {action: 'status', id: ids, status: status},
success: function (data, status) {
alert(data);
if (data == '0') {
$('#flag-view').fadeOut(800, function () {
$("#r" + ids).remove();
$('#flag-view').fadeIn().delay(2000);
});
}
else if (data == '2') {
}
else if (data == '3') {
}
},
error: function (xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}
}); // end ajax call
})
Your declaration is incorrect change
From
$(document).on(".status").click(function (event) {
To
$(document).on("click", ".status", function(event){
});
That is not how .on() works.
.on() is a helper function that is used for adding event handlers to an element (with an optional selector), like so:
$(document).on("click", ".status", function (event) {
// Do your stuff here
});
Doing it like this (providing a selector) makes it into a delegated handler. Only one event handler is added to the document and any events that bubble up will be caught and given to the callback function.
You can also add the event handler directly to an element (or a collection of elements), like so:
$(document).find(".status").on("click", function (event) {
// ...
});
If the .status elements the handler was added to are removed then the handler will also be removed.
Event handling in jQuery can be a little confusing at first but it is quite logical. I would suggest that you read up on it to get a better sense of how it works.
I know about event.preventDefault() and event.stopImmediatePropagation(). But it doesn't work for me. In my case I have such ajax call:
$('#templateConfirmDialog').on('show.bs.modal', function (event) {
$(this).find('.modal-yes').click(function(){
var form = form2js('search_form', '.', true, function (node) {}, false);
var requestData = JSON.stringify(form, replacer);
var $formErrors = $('.search_form').find('.alert-danger');
event.preventDefault();
event.stopImmediatePropagation();
$.ajax({
type: 'POST',
contentType : "application/json",
url: '/fraud/template/testCreate',
data: requestData,
dataType: 'json',
success: function (data) {
$formErrors.text('');
//if no errors just reload
if (data === undefined || data.length === 0) {
location.reload();
}
else {
//else bind error messages
data.forEach(function(error) {
$('#new-' + error.field + '-error').text(error.defaultMessage);
})
}
}
});
});
My problem is that the ajax call is prevented as much times as I made attempts to input data. If I entered invalid data once - ajax is called twice. If twice - 3 times. What may be a reason of such behavior?
Every time this event happens:
$('#templateConfirmDialog').on('show.bs.modal', function (event) {
You bind a new click event handler:
$(this).find('.modal-yes').click(function(){
So if you show.bs.modal twice, then you have two click event handlers both submitting the AJAX request. Instead, just bind the click event handler once to the target clickable element, instead of binding it every time the modal is displayed.
Replace this:
$('#templateConfirmDialog').on('show.bs.modal', function (event) {
$(this).find('.modal-yes').click(function(){
//...
});
});
With this:
$('#templateConfirmDialog').find('.modal-yes').click(function(){
//...
});
Or, if that element is dynamically added to the DOM, this:
$(document).on('click', '#templateConfirmDialog .modal-yes', function(){
//...
});
That way there's just a single click event handler created when the page loads, rather than adding a new handler every time you display the modal.
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 7 years ago.
My purpose is to define ajax method callback with jquery.
all DOM of parent div are loaded dynamically
i have define delete button foreach comments
and i want to get confirmation from twitter bootrap modal befor throw the ajax request : https://jsfiddle.net/r4sLt016/5/
this.deleteComment = function () {
self = this;
$("button[name='deleteComment']").each(function (index, el) {
$(this).unbind().bind('click', function (event) {
event.preventDefault();
var ref = $(this).attr('data-ref');
var callback = function () {
/*$.ajax({
url: '/path/to/file',
type: 'DELETE',
data: {param1: 'value1'},
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
});*/
alert("multiple");
}
self.confirm("Delete Comment ", "Are you sure you want \
to delete this Comment ?", callback);
});
});
}
this.confirm = function(head, question, callback) {
$(".modal-title").html(head);
var body = $("<p/>").text(question);
$(".modal-body").html(body);
$("#deleteModal").click(function(event) {
callback();
$('.customModal').modal('hide');
});
$('.customModal').modal('show');
}
You are binding the click event deleteModal element everytime you call the confirm() method!
So you have to unbind() and bind() again like you did at the deleteComment buttons.
Like this:
this.confirm = function(head, question, callback) {
$(".modal-title").html(head);
var body = $("<p/>").text(question);
$(".modal-body").html(body);
$("#deleteModal").unbind().bind('click', function(event) {
callback();
$('.customModal').modal('hide');
});
$('.customModal').modal('show');
}
>> Updated JSfiddle!
This question already has answers here:
Event handler not working on dynamic content [duplicate]
(2 answers)
Closed 9 years ago.
I wrote a script, which get data (in Json type) from a method and show it in div tag with a close button, when i click on close button it is not work! my script is:
$(document).ready(function () {
$("#go").click(function () {
setInterval(function () {
$.ajax({
type: "POST",
url: "WebForm2.aspx/GetMyBooks",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
for (var i = 0; i < response.d.length; i++) {
$("#pejiGrid").append("<div class='modal'><div style='float:left;'><span class='close'>X</span></div>" + response.d[i].BOOK_NAME + "<br/>" + response.d[i].BOOK_DESC + "</div><br/>");
};
},
});
$('.modal').hover(
function () {
$(this).find('.close').delay(0).fadeIn(300);
},
function () {
$(this).find('.close').delay(0).fadeOut(500);
});
}, 5000);
});
$('span.close').click(
$(this).closest('div.modal').fadeOut(0)
);
});
What is the problem?
EDIT : about my hover script i should say it shows the close button by delay but i gave zero to delay value :
$('.modal').hover(
function () {
$(this).find('.close').delay(0).fadeIn(300);
},
function () {
$(this).find('.close').delay(0).fadeOut(500);
});
some body can help me what is the problem?
You need to use event delegation here to bind the click event to your dynamically created div and span element inside #pejiGrid:
$('#pejiGrid').on('click', 'span.close', function() {
$(this).closest('div.modal').fadeOut(0);
});
I had a question regarding Ajax loading of html into a DIV. Ideally what I want is this:
A toggle div with close button, which I have the code for here: http://jsfiddle.net/tymeJV/uhEgG/28/
$(document).ready(function () {
$('#country').click(function () {
$("#country_slide").slideToggle(function() {
if ($(this).is(":visible")) {
alert("im visible!");
}
});
});
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
});
Then I want some AJAX code to load a html file into the div when the div is expanded. The trick is that if the HTML is loaded successfully, I want it to avoid reloading the HTML file again if the div is closed and repoened, since I have already loaded it, and just simply toggle the content in and out with the button. The code I have for this (which I got help on from here is this):
http://jsfiddle.net/spadez/uhEgG/55/
$(function () {
$('#country_link').on('click', function (e) {
// Prevent from following the link, if there is some sort of error in
// the code before 'return false' it would still follow the link.
e.preventDefault();
// Get $link because 'this' is something else in the ajax request.
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true)
return false;
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend: function () {
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
$("#country_slide").html('Error');
},
complete: function () {
},
});
});
});
I haven't been able to get this working yet though. So my question is, is it actually possible to do this, and if it is, can anyone with more experience with jquery please help me integrate the div toggle with the ajax loading script.
This is one of my first jquery scripts and I am having a bit of a hard time with it, perhaps it is not for beginners. Thank you.
I edited the fiddle you posted adding the call to slideToogle() where appropriate. Also added a div element to hold the loaded html code.
<div id="country_slide">
Close
<div class=".content"></div> <!-- This is the div I added -->
</div>
You can check the log messages in the console to verify that the code is doing what you expect. The URL for the Ajax call you were doing always returned an error so I changed to the URL that jsfiddle provides for testing: /echo/html/.
Here's the modified JS code:
$(function () {
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
$('#country_link').on('click', function (e) {
e.preventDefault();
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true) {
console.log('Not using Ajax.');
$("#country_slide").slideToggle();
return false;
}
$.ajax({
type: 'GET',
dataType: 'html',
url: '/echo/html/',
timeout: 5000,
beforeSend: function () {
$("#country_slide .content").html('<p>Loading</p>')
},
success: function (data, textStatus) {
console.log('Fecthed with Ajax.');
$("#country_slide .content").html(data);
$("#country_slide").slideToggle();
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
},
complete: function () {
},
});
});
});