I have a problem with my script.
In my table, every row has a url link which open modal window with email input to change this email without refresh page.
Script is ok if you change only one row. If I change second, third, etc row, every values changed by last one.
If I refresh page (F5) - script works perfectly.
Any helps ? Thanks a lot.
$(document).ready(function() {
var table = $('#example').DataTable();
$('#example tbody').on('click', 'a', function () {
var row = $(this).closest('tr[role="row"]');
var data = table.row(row).data();
$("#myModal").modal("show");
$("#email").val(data[0]);
$("#ulozit").click(function(){
var novy_email = $("#email").val();
$.ajax
({
method: "POST",
url: "action_admin.php?action=uprava_emailu",
data: { novy_email:novy_email, id:data[3] },
success: function(data)
{
table.ajax.reload();
$("#myModal").modal("hide");
}
})
});
});
});
You have nested onClick handlers.
The second handler is added every time the first handler is called. The jQuery event model allows multiple handlers on one element, therefore a later handler does not override an older handler. The handlers will execute in the order in which they were bound.
In short: Do not nest your handlers.
Related
I have a page where I return users posts, these posts can be commented on the fly using some jquery code, after a new comment is posted I insert the new comment under the post along with a Delete button. The problem is the Delete button doesn't work on the newly inserted element unless I reload the page. I read that the solution is using the .on() method however I am a little confused re how to implement this.
I have one function that updates the post part with the newly inserted comment and this is the function that deletes the comment:
$(document).ready(function () {
$("button[id*='deletecmnt_']").click(function () {
var id = this.id.replace('deletecmnt_', '');
var comment_card_id = ('#comment_' + id);
var token = $(this).data('token');
$.ajax({
url: '../comment/' + id,
type: 'post',
data: {_method: 'delete', _token: token},
success: function () {
// Checks for display of comment card and removes it
if ($(comment_card_id).is(":visible")) {
$(comment_card_id).fadeOut("fast");
}
}
})
})
});
I don't understand what needs to be changed here and how.
You need to use event delegation for elements added dynamically. In your .on() method, you need to add the selector that you want the handler attached to after it's created.
$(document).ready(function(){
$("body").on("click", "button[id*='deletecmnt_']", function () {
// codes
}
});
This will listen for clicks on elements not yet created that match your selector. Here's the JQuery API doc page for more info: http://api.jquery.com/on/
I'm working on a script to check if a file exists every 5s on onclick event. When it exists, I notify the client and reset the counter. First file check everything works fine, but when I check another file (click on another link with other data-file), it checks again both files and first file check is looping forever until I refresh the page. I tried everything I could think of, nothing worked. Please help!
var intervalCheck;
function isFileExists(file) {
$.ajax({
type: 'HEAD',
url: '/apps/'+file,
success: function() {
alert('found '+file);
clearInterval(intervalCheck);
},
error: function() {
}
});
}
$('#dialog').on('show.bs.modal', function(e) {
var file = $(e.relatedTarget).data('file');
$("a#checkfile").click(function() { intervalCheck = setInterval(function() { isFileExists(file); },5000); });
});
You must bind click event to only a#checkfile in clicked #dialog. Otherwise it will bind event to all a#checkfile elements. So when you open dialog for second time there will be 2 events on the a#checkfile link.
$(this).find('a#checkfile')
UPDATE
If there is one dialog contains multiple links, you can use jquery's one function for one-time events.
$('a#checkfile').one('click', function(){});
I am using datatables and fetching the data from an ajax URL. Each row of my returned table data includes a field that renders a button that looks like this:
<button type="button" data-catid="8" data-catname="Programming:JavaScript"></button>
The values assigned data-catid and data-catname come from the datatables retrieved data.
In certain cases, when the table finishes loading, I want to trigger a click on one of these buttons. My code for that is this:
$('#mydatatable').find('button[data-catid="9"]').trigger('click');
However, I cannot find a way to do this so that it occurs after the table has rendered and the button exists in the dom so I can find it and trigger the click.
I have tried drawCallback and initComplete but neither of those is triggered after the button has actually been added to the dom, allowing me to find it with jquery.
Is there a way I can do this? i.e. trigger my click after the mytable has finished retrieving its data via ajax and rendered it?
I am using datatables v 1.10
EDIT:
Here is how my click event handler is attached to the summary table.
var selectedCat = 0;
$('#mydatatable :button').click(function () {
selectedCat = this.getAttribute("data-catId");
console.log("selecteCat is " + selectedCat);
qDetailTable.ajax.url('/datatables/question-data/' + selectedCat).load();
var selectedCatName = this.getAttribute("data-catName");
$('#questDetailCat').text('Questions about: ' + selectedCatName);
$('#questSummary').hide();
$('#questDetail').show();
});
Move the click handler into a separate function, for example:
var selectedCat = 0;
function OnCategoryClick(btn){
selectedCat = btn.getAttribute("data-catId");
console.log("selecteCat is " + selectedCat);
qDetailTable.ajax.url('/datatables/question-data/' + selectedCat).load();
var selectedCatName = btn.getAttribute("data-catName");
$('#questDetailCat').text('Questions about: ' + selectedCatName);
$('#questSummary').hide();
$('#questDetail').show();
});
Event handler needs to be in a named function because you will not be able to trigger click event for elements that are not in DOM as with jQuery DataTables.
Change how you attach your click handler.
$('#mydatatable').on('click', 'button', function () {
OnCategoryClick(this);
});
Remember to always use delegated event handlers with elements inside jQuery DataTables because elements for pages other than first will not be available in DOM. See jQuery DataTables – Why click event handler does not work for more details.
Use $() API method to locate required button and call your handler function OnCategoryClick().
var btn = $('#datatable-summary').DataTable().$('button[data-catid="9"]').get(0);
OnCategoryClick(btn);
Replace datatable-summary with your actual ID of the summary table.
If you need to update details as soon as the summary table is initialized and drawn, use initComplete option to define a callback and do it there.
So I have a page that loads the data into the page through the following ajax function.
$(document).ready(function(){
function loadData(page){
$.ajax
({
type: "POST",
url: "inc/load_data.php",
data: "p="+page+"XXXXXXXXXXX",
success: function(msg)
{
//alert(msg);
$("#container").ajaxComplete(function(event, request, settings)
{
$("#container").html(msg);
//**MODIFIED CODE
$(document).delegate('a.vote_up','click', f_vote_up);
});
}
});
}
});
//Loaded Message
$msg.='<span class="vote_buttons" id="vote_buttons'.$row['id'].'">
</span>';
The message that is loaded has some links that need to work with a another Ajax function(given below), which is apparently not working. The second function(below) is loaded before the data is loaded into the page. I suspect, may be since this function is loaded way before the data is loaded, the second function is not recognizing the click on vote_up. Is there any way to fix it??? I'm not too familiar with AJAX, I would really appreciate some help.. Thank you
$(function(){
$("a.vote_up").click(function(){
//get the id
alert("Hi");
//REST OF THE CODE
}
//***NEW FUNCTION
function f_vote_up(){
//get the id
the_id = $(this).attr('id');
//REST OF THE CODE
$("span#vote_buttons"+the_id).html("Hello, Testing Response!");
alert("End of Func!"); // <
}
When you call that second function, it's only grabbing all the a.vote_up elements that currently exist on the page. When you add more links to the page later on, they don't know to listen for the click.
You can do one of two things to fix this:
Add the click listener to each new link when you add it to the DOM. But this is a bit of work, because you'd have to change how your AJAX function builds the links, and you'd have to turn that click-listener-assigning function into something standalone that you could use at any time.
Instead of doing using the click method, use the delegate method instead:
$(document).delegate('a.vote_up', 'click', function () { ... });
More info on event delegation with jQuery.
you should bind your click event after you load the html
$.ajax
({
type: "POST",
url: "inc/load_data.php",
data: "p="+page+"XXXXXXXXXXX",
success: function(msg)
{
//alert(msg);
$("#container").ajaxComplete(function(event, request, settings)
{
$("#container").html(msg);
$("a.vote_up").click(function(){
//get the id
alert("Hi");
//REST OF THE CODE
});
});
}
});
You can use the live function to bind an event to dynamically created elements, i.e.:
$("a.vote_up").live('click', function(){
//get the id
alert("Hi");
});
http://api.jquery.com/live/
This will effectively bind this click event to all elements which match the a.vote_up selector, now and in the future.
I am using JQuery to add a row to a table. Within the row is an element who's click event I am capturing:
$(document).ready(function() {
var newRow = "<tr> ... </tr>";
$('tableName > tbody:last').append(newRow);
$(...).click( function() { // click event on newly inserted elem in the row
alert("click");
});
}
This works great and the alert comes up as expected. BUT when I now add the new row dynamically via an ajax call and parsing the xml, it stops working:
$(document).ready(function() {
getData();
$(...).click( function() { // click event on newly inserted elem in the row
alert("click");
});
function getData() {
$.ajax({
...
success: function(data) {
//parse the xml
$('tableName > tbody:last').append(parsedXml);
}
});
}
The html is correctly added to the DOM, but the click event is no longer captured. Is there some issue with scope or closures going on here?
use
$(...).live('click', function() { // click event on newly inserted elem in the row
alert("click");
});
This keeps the click event running after it has been used
more info
When working with a table, I like to use .delegate() for this. It's very similar to .live(), but lets you set up an event listener on a single parent element, rather than individual handlers on every child element. So whether you have a table of one row or 1000, you still need only one handler.
$('#yourtable').delegate('your_descendant_element','click', function(){
alert("click");
});
You should look into using the live() event handler. It allows you to create an event that matches elements created in the future dynamically, which is what is not happening right now. Another way to fix it would be to move the all to bind down below where you append the new table row, but live() is a much better answer.