jQuery function doesn't work after after loading dynamic content - javascript

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.

Related

How to lock / set / block variable inside .on jquery

So, I have a jQuery AJAX call that gets data from the server (some text, some links).
Inside AJAX success callback function I got a .on that is bind to <a> that load for me next page and get me the text of the clicked link (let's say stackoverflow.com).
The problem starts here because in the newly loaded page I got anchors...
After every click on anchor links I got new .text() value.
$.ajax({
url: url,
type: type,
dataType: dataType,
success: function(data){
$('.container').append(data);
$('.container').on('click', 'a', function(e){
e.preventDefault();
var clickLinkName = $(this).text();
console.log(clickLinkName);
$('.container').load($(this).attr('href'));
});
}
});
I would like to know how to lock clickLinkName variable. OR any other way to save only first hit.
I think this would do the trick:
$.ajax({
url: url,
type: type,
dataType: dataType,
success: function(data) {
$(".container").append(data);
var clickLinkName; // Declared here.
$(".container").on("click", "a", function(e) {
e.preventDefault();
// If not initialized, initialize.
if(!clickLinkName) {
clickLinkName = $(this).text();
}
console.log(clickLinkName);
$(".container").load($(this).attr("href"));
});
}
});
That would save only the first value in the variable clickLinkName. This answers your question, but I'm sure there are better ways of doing this.

Query function not being fired when called

I have a Jquery function to delete a row in an HTML table, it looks like this;
$(document).ready(function(){
$("#thisNet td a.delete").click(function() {
if (confirm("Are you sure you want to delete this row?")) {
var id = $(this).parent().parent().attr('id');
var data = 'id=' + id ;
var parent = $(this).parent().parent();
$.ajax({
type: "POST",
url: "delete-row.php",
data: data,
cache: false,
success: function()
{
parent.fadeOut('slow', function() {$(this).remove();});
}
});
}
});
});
I don't know if it works or not because when I click the button I never get into the function. The delete item to click is in a table created by PHP/MySQL. I followed the tutorial here; https://sarfraznawaz.wordpress.com/2009/09/14/deleting-table-rows-using-jquery-and-php/ to create the delete function. I'm guessing the reason it doesn't fire has to do with timing. The $(document).ready(function() already thinks the page is done loading before the table is created..but I don't know how to overcome this problem.
The page is here; http://kcmecc.org/RaspPi/ once you access it use the drop down to select Net #1. The delete column is the last one with the red x.
Your delete button doesn't exist on document ready. You need to use .on to delegate the event to an ancestor element when dynamically adding elements...
$(document).on('click', '#thisNet td a.delete', function() {

Onclick works only after second click

I have a list in HTML which looks like
<a onclick="open_file()" id="3.txt">3.txt</a>
My open_file() function is looking this
function open_file() {
$("a").click(function (event) {
var file_name = event.target.id;
$("#f_name").val(file_name);
$.ajax({
url: "docs/" + file_name,
dataType: "text",
success: function (data) {
$("#text_form").val(data);
$('#text_form').removeAttr('readonly');
$('#delete_button').removeAttr('disabled');
$('#save_button').removeAttr('disabled');
}
})
});
}
The problem is function finally loads data into all fields(text_form and f_name) only after two clicks on such link. It works even if I at first click on one file, then click on another and it loads. Is there any way to fix this?
What you're currently doing is adding an onclick event to a link that calls a function that adds another onclick event via jQuery.
Remove the onclick property and the open_file() function wrapper so that jQuery adds the event as you intended.
You do not need onclick="open_file()" this:
<div id='linkstofiles'>
<a id="3.txt">3.txt</a>
//other links go here
</div>
$("#linkstofiles a").click(function (event) {
var file_name = event.target.id;
$("#f_name").val(file_name);
$.ajax({
url: "docs/" + file_name,
dataType: "text",
success: function (data) {
$("#text_form").val(data);
$('#text_form').removeAttr('readonly');
$('#delete_button').removeAttr('disabled');
$('#save_button').removeAttr('disabled');
}
})
});
You don't need to bind a click event again in the function when you have onclick in your html.
Also for $ is not defined, you need to put jquery library in the head.

Event delegation not working jquery

So I'm just getting started with event delegation and I'm still fairly confused by it but here goes:
I have a button which adds a rating in ajax, once clicked again I'd like it to remove the rating, here's the code with annotations (and some parts removed to make it look more clear).
$(document).on("click", '.add_rating', function() {
l.start();
var input = $(this).prev().children('.my_rating');
var score = input.val();
var what_do = input.attr('action_type');
var cur_average = $('.current_average').val();
var data = {};
data.score = score;
data.media_id = <?php echo $title_data->media_id; ?>;
data.what_do = what_do;
$.ajax({
dataType: "json",
type: 'post',
url: 'jquery/actions/add_remove_rating',
data: data,
success: function(data) {
if (data.comm === 'success') {
//do some other stuff there, irrelevant
$('.ladda-button').removeClass('btn-primary');
$('.ladda-button').removeClass('btn-sm');
$('.ladda-button').addClass('btn-danger btn-xs');
$('.ladda-label').html('Remove');
$('.ladda-button').addClass('remove_rating'); <-- add the remove rating class I want to call if the button is clicked again
input.attr('action_type', 'remove_rating');
l.stop();
}
}
});
$('.remove_rating').on('click', function() { <-- this doesn't work, why?
alert('remove was clicked');
});
});
I can't seem to trigger this:
$('.remove_rating').on('click', function() { <-- this doesn't work, why?
alert('remove was clicked');
});
Any help appreciated!
Edit: on a side note, I don't actually need this to work as php figures out if we're removing or adding a score based on the action_type attribute. I just wanted to find out why it's not triggering.
change your code to:
$(document).on("click", '.add_rating', function() {
l.start();
var input = $(this).prev().children('.my_rating');
var score = input.val();
var what_do = input.attr('action_type');
var cur_average = $('.current_average').val();
var data = {};
data.score = score;
data.media_id = <?php echo $title_data->media_id; ?>;
data.what_do = what_do;
$.ajax({
dataType: "json",
type: 'post',
url: 'jquery/actions/add_remove_rating',
data: data,
success: function(data) {
if (data.comm === 'success') {
//do some other stuff there, irrelevant
$('.ladda-button').removeClass('btn-primary');
$('.ladda-button').removeClass('btn-sm');
$('.ladda-button').addClass('btn-danger btn-xs');
$('.ladda-label').html('Remove');
$('.ladda-button').addClass('remove_rating'); <-- add the remove rating class I want to call if the button is clicked again
input.attr('action_type', 'remove_rating');
l.stop();
$('.remove_rating').on('click', function() { <-- this doesn't work, why?
alert('remove was clicked');
});
}
}
});
});
EXPLANATION:
first have a look here: Understanding Event Delegation.
event delegation is used when you need to create event handlers for elements that do not exist yet. you add a .remove_rating class to elements dynamically, however you are trying to attach a handler to elements with the above mentioned class before you even attach it.
you are attaching the class when the asynchronous ajax call returns, in the success function, however your event handler block is being processed right after you send the ajax, and not after the ajax returns (ajax is async rememeber?). therefore, you need to wait until the ajax returns and the elements are created, and only then attach the handler to them.
alternatively, using event delegation, you can attach the handler to the document, like you did in the following line:
$(document).on("click", '.add_rating', function() {
it means, that you attach the handler to the document, and whenever any element ON the document is clicked, if that element has the class '.add_rating' then execute the handler.
therefore, you may attach another handler to the document to monitor for clicks on elements with the .remove_rating class as follows:
$(document).on("click", '.remove_rating', function() {
this is called event delegation, because you delegate the event to a parent element.
Because class was added after click event initialised. You need to use live event handlers, like this:
$( document ).on('click', '.remove_rating', function() {
In this case .remove_rating click handler will work on dynamically created elements and on class name changes.

jquery click event

I have some jquery that looks like this,
$('.career_select .selectitems').click(function(){
var selectedCareer = $(this).attr('title');
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
}
});
});
My problem is that if the user keeps clicking then the .hfeed keeps getting data appended to it. How can I limit it so that it can only be clicked once?
Use the one function:
Attach a handler to an event for the elements. The handler is executed at most once per element
If you wanted the element to only be clicked once and then be re-enabled once the request finishes, you could:
A) Keep a state variable that updates if a request is currently in progress and exits at the top of the event if it is.
B) Use one, put your code inside a function, and rebind upon completion of request.
The second option would look like this:
function myClickEvent() {
var selectedCareer = $(this).attr('title');
var that = this;
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
},
complete: function() {
$(that).one('click', myClickEvent);
}
});
}
$('.career_select .selectitems').one('click', myClickEvent);
You can either use a global variable like
var added = false;
$('.career_select .selectitems').click(function(){
if(!added) {
// previous code here
added = true;
}
});
or use .one("click", function () { ... }) instead of the previous click function to execute the handler at most once per element. See http://api.jquery.com/one/ for more details.

Categories

Resources