event.preventDefault() not working if link added by js - javascript

i have a problem with event.preventDefault() because the event not stop.
i have two different functions. the first function is a xhrCall and show all posts and append the result to a table. in this function, i create a link with class="del" and href="#".
$.each(data, function(i, data){
$('#listMsg').append('<tr><td>' + data.id + '</td><td>' + data.msg + '</td><td><a class="del" rel="'+ data.id + '" href="#"> delete</a></td></tr>');
});
my next function is to handle the delete.
$(". del").click(function(e) {
e.preventDefault();
var id = $(this).attr('rel')
alert('delete + ' + id);
});
If i copy a link directly into my index.php file with the same class, the code work!
unfortunately, i don't know what i missed or how to talk to links that are insert with js.
thanks a lot for help!

Did you say you were adding the link with ajax? If so you need to do it this way:
$("#listMsg").on("click", ".del", function(e) {
e.preventDefault();
var id = $(this).attr('rel')
alert('delete + ' + id);
});
if Jquery is version 1.7 or older do it this way
$("#listMsg").delegate( ".del", "click", function(e) {
e.preventDefault();
var id = $(this).attr('rel')
alert('delete + ' + id);
});

Related

How to on click an element added to the html from the same javascript?

I have retrieved some rows from the database by ajax request and added to my HTML page. I want to delete a record using ajax but it doesn't work.
$(document).ready(() => {
$.getJSON("/admin/getMakes", data => {
$.each(data, (i, makes) => {
$("ul#makes").append(
'<li class="list-group-item">' +
makes.makeName +
' <a href="#",id="deleteMake",data-id=' +
makes._id +
'><i class="fa fa-trash" ></i></a>' +
"</li>"
);
});
});
$("#deleteMake").on("click", function(e) {
alert("clicked");
// var id = $(this).attr("data-id");
// $.ajax({
// type: "DELETE",
// url: "/admin/deletemake" + id,
// success: function(response) {
// $(this).hide();
// //window.location.href = "/admin/deletemake";
// },
// error: function(err) {
// console.log(err);
// }
// });
});
});
I have added an alert to check if it works but it doesn't work so the mistake isn't in the request.
The first mistake - id must be unique.
The second is incorrect event delegation.
The third - typo in href="#",id="deleteMake",data-id
Lets fix them all :)
Fix typos and use class
$("ul#makes").append(
'<li class="list-group-item">'
+ makes.makeName +
'<a href="#" class="deleteMake" data-id=' + makes._id + '>' +
'<i class="fa fa-trash" ></i>' +
'</a>' +
'</li>'
);
Fix delegation issue
$("#makes").on('click' '.deleteMake', function(e) {
alert("clicked");
})
1) <a href="#",id="deleteMake", - there should be no commas in a HTML tag. Replace commas with spaces.
2) To set the handler in-place, instead of in a subsequent block:
.append(
$('<li class="list-group-item"></li>')
.append(
$('')
.on('click',function(e){
alert(makes._id);
// You don't actually want the browser scrolling to #
e.preventDefault();
})
.append('<i class="fa fa-trash" ></i>')
)
)
If you leave the code your style, then you can attach the event like this:
$("ul#makes")
.append(
$(
'<li class="list-group-item">' +
makes.makeName +
' d' +
"</li>"
)
.on('click','#deleteMake',function(
alert(makes._id);
// You don't actually want the browser scrolling to #
e.preventDefault();
)
);
In your code, the events are also attached before content is generated, because the XHR result callback is certain to occur after the main thread finishes execution. That problem doesn't happen with any of the above code. If you MUST set handlers before content is generated, use .on() delegation:
$("ul#makes").on("click", "#deleteMake", function(e){
alert($(this).data('id'));
// You don't actually want the browser scrolling to #
e.preventDefault();
});

jQuery click event is not working in first click

I using a code on my page. Like this:
$('#language_id').change(function () {
var urli = 'https://example.com/php/get_arch.php?language_id=' + language_id;
$.ajax({
type: "GET",
url: urli,
dataType: 'json',
success: function(response){
var options = '';
$.each(response.archs, function() {
options += '<option value="' + this.arch_id + '">' + this.name + '</option>';
});
$('#arch_id').html('<option value="0">- ' + selachitecture + ' -</option>'+options);
$('#arch_id').attr('disabled', false);
}
});
});
$('#arch_id').change(function(){
var version_id = $('#version_id :selected').val();
$('#selectBoxInfo').load('https://example.com/dl.php?fileName=' + arch_id + "&lang=" + lang);
return(false);
});
$('body').on('click', '.buttond a', function() {
alert("new link clicked!");
$("a").removeAttr("onclick");
});
I explain my code: when selecting an optional, it will create a button "Download". This button load by Ajax. I don't want feature pop-up of this button.
So, I tried to prevent this button turn on the pop-up.
The problem is: at first click in button, my Javascript is not working. It only works from the second click.
I don't know problem at here. I using 'on' to listen to all event.
replace your code with this code ..
$('#selectBoxInfo')
.load('https://example.com/dl.php?fileName=' + arch_id+"&lang="+lang
,function(){
$("a").removeAttr("onclick");
}
);

Ajax request called multiple times though I need only once?

I have been working on a e-commerce web application. There is a wishlist module which I'm trying to implement. I'm adding the products into wishlist using ajax calls and also removing it with ajax. The adding part works fine but I have a problem in removing part . What I'm trying to do is, making an ajax call to fetch the wishlist items from the database and adding a remove button dynamically using jquery. Although I know that I have to use a .live function to attach an event to it which I did but when i click on the button all the items which are present in the wishlist are removed . I see multiple ajax request was made in console under network tab and I don't get it why , although I clicked it only once. The following is a snippet of my code
$.ajax({
type: "POST",
url: "fetchdata1",
data: "cat=" + cat,
success: function(data) {
productContainer.innerHTML = "";
var $productContainer = $('#productContainer');
$.each(data, function(key, value) {
if (value['newVar'] === 1) {
$productContainer.append("<div id='productBox' class='grid_3'>\n\
<a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\n\
<a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\n\
<span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span>\n\
<br/><br/><a id='remove' href='#'>REMOVE</a></div>");
foo(value['id']);
} else {
$productContainer.append("<div id='productBox' class='grid_3'>\n\
<a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\n\
<a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\n\
<span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span></div>");
}
});
}
});
function foo(value) {
var pid = value;
$('#remove').live("click", function() {
$.ajax({
type: "POST",
url: "removeFromWishlist",
data: "pid=" + pid,
success: function(response) {
}
});
});
In the first ajax request I'm fetching products from the database then adding remove button to it dynamically then calling function foo which attach the click event using .live function and then make call to database to remove it.
Hey guys I'm not pro at web, so go easy on me if I made some silly mistake.
Thanks!
Problem:
You have same id for multiple hyperlink and you are using .live function on "id based" selector. It is applying click function again & again on first element.
Solution:
Update your hyperlink
<a href='#' onclick="foo(this)" pid=value['id']>REMOVE</a>
Then in foo() function
function foo(obj) {
var pid = $(obj).attr("pid");
$(obj).bind("click", function() {
$.ajax({
type: "POST",
url: "removeFromWishlist",
data: "pid=" + pid,
success: function(response) {
}
});
});
i don't get why you using same id multiple times.
and afaik, jQuery.live already deprecated.
you can use this if you want to get live behavior:
$(document).on('click', 'element-selector', function(){
...
});
with your code, it can rewriten to:
$(document).on('click', '[id=remove]', function(){
...ajax call...
});
now the problem with your fetch data function is this:
$.each(data, function(key, value) {
if (value['newVar'] === 1) {
...append element...
**foo(value['id']);**
} else {
...append element...
}
});
as we know foo() are your function that bind remove behavior.
based on your code, whenever that fetch data has newVar = 1, it will directly call foo. which mean binding remove behavior multiple times, as many as newVar = 1 was.
solution:
you can put pid as a attribute on your a element
maybe something like remove
and within remove click function, you can use $(this).attr('pid') to get that value.
and remove that foo() content to outside the function, since $(element).live(...) or $(document).on(event, element, ...) will listen the element, even the element dynamicly added to the page.
The issue happened because you register listener multiple times in each loop. So to resolve, you need to register once after all button has been populated. I also change selector to class ".remove" because you going to have multiple remove button so using id is will be duplicated, and using jquery .on() instead of .live() (deprecated)
$.ajax({
type: "POST",
url: "fetchdata1",
data: "cat=" + cat,
success: function(data) {
productContainer.innerHTML = "";
var $productContainer = $('#productContainer');
$.each(data, function(key, value) {
if (value['newVar'] === 1) {
$productContainer.append("<div id='productBox' class='grid_3'>\n\
<a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\n\
<a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\n\
<span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span>\n\
<br/><br/><a class='remove' id='remove' data-pid='" + value['id'] + "' href='#'>REMOVE</a></div>");
} else {
$productContainer.append("<div id='productBox' class='grid_3'>\n\
<a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\n\
<a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\n\
<span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span></div>");
}
});
foo();
}
});
function foo() {
$('.remove').on("click", function() {
var pid = $(this).data("pid");
$.ajax({
type: "POST",
url: "removeFromWishlist",
data: "pid=" + pid,
success: function(response) {
}
});
});

String Not Appended to Dynamically Created Div

I've researched this in depth on stackexchange and I don't think I am making a 'common' mistake, and the other answers have not solved this.
The problem is I am trying to append data to a DEFINITELY existing div of a certain ID. What I DO know is that the div is dynamically generated, and that is probably why it is hidden.
Despite using jquery on I cannot seem to get jquery to find the particular div.
Here is the code:
$(document).ready(function() {
function example_append_terms(data) {
var sender_id = data['sender_id'];
$.each(data, function(k, v) {
if (k != 'sender_id') {
html = '<span data-lemma="' + v['key'] + '" class="lemma">' + v['name'] + '</span>';
$('#' + sender_id + ' .lemmas').append(html);
}
});
}
function example_get_options(data) {
$.ajax({
url: '/example/',
type: 'post',
data: data,
success: function(data) {
//alert(JSON.stringify(data))
example_append_terms(data)
},
failure: function(data) {
alert('Got an error dude');
}
});
return false;
}
$(document).on('click', ".example-synset-option", function() {
var synset = $(this).data('name');
var sender_id = $(this).attr('id')
example_get_options({
'synset': synset,
'sender_id': sender_id,
});
});
});
On clicking a certain div, an action is fired to "get options" which in turn runs an ajax function. The ajax function runs the "replacer" function example_append_terms.
Having tested up to example_append_terms the .each iteration is definitely working. But when I did tested $('#' + sender_id + ' .lemmas').length I continue to get 0.
Where is this jquery newb going wrong?
I fixed it by changing stuff...
For some inexplicable reason fetching the data attribute worked better than the id..
function intellitag_append_terms(data) {
var sender_id = $('*[data-location="'+data['sender_id']+'"] .lemmas');
$.each(data, function(k, v) {
if (k != 'sender_id') {
html = $('<span data-lemma="' + v['key'] + '" class="label label-primary lemma">' + v['name'] + '</span>');
html.appendTo(sender_id)
//$('#' + sender_id).append(html);
}
});
}

How to load JSON data associated with each link onclick?

I have created a dynamic link based on JSON data, The problem I am having, when I click on the links is its not loading the information associated for each of the link.
for example when i click on Algebra it should load the id and author info. But currently it work for only the last link.
How can I make it work for every link so that it loads for each one?
here is my code below:
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script>
var url= 'sample.json';
$.ajax({
url: url,
dataType: "jsonp",
jsonpCallback: 'jsoncback',
success: function(data) {
console.log(data);
//$('.bookname').empty();
var html ='';
$.each(data.class, function(key, value) {
console.log(value.name+ " value name");
console.log(value.desc + " val desc");
$('.bookname').empty();
html+= '<div class="books" id="authorInfo-'+key+'">';
html+= '<a href="#" >'+value.name+ key+'</a>';
html+= '</div>';
$(".bookname").append(html);
var astuff = "#authorInfo-"+key+" a";
console.log(value.desc + " val desc");
$(astuff).click(function() {
var text = $(this).text();
console.log(text+ " text");
var bookdetails =''
$("#contentbox").empty();
$.each(value.desc, function(k,v) {
console.log(v.id +"-");
console.log(v.author +"<br>");
bookdetails+= v.id +' <br> '
bookdetails+= v.author + '<br>';
});
$("#contentbox").append(bookdetails);
});
});
},
error: function(e) {
console.log("error " +e.message);
}
});
</script>
</head>
<body>
<div id="container">
<div class="bookname">
</div>
<div id="contentbox">
</div>
<div class="clear"></div>
</div>
</body>
</html>
The problem is you are updating the inner html of the element bookname in the loop, which will result the previously added handlers being removed from the child elements.
The calls $('.bookname').empty(); and $(".bookname").append(html); within the loop is the culprits here. You can rewrite the procedure as something like this
jQuery(function ($) {
var url = 'sample.json';
$.ajax({
url: url,
dataType: "jsonp",
jsonpCallback: 'jsoncback',
success: function (data) {
var $bookname = $('.bookname').empty();
$.each(data.class, function (key, value) {
var html = '<div class="books author-info" id="authorInfo-' + key + '">';
html += '' + value.name + key + '';
html += '</div>';
$(html).appendTo($bookname).data('book', value);
});
},
error: function (e) {
console.log("error " + e.message);
}
});
var $contentbox = $("#contentbox");
$('.bookname').on('click', '.author-info .title', function (e) {
e.preventDefault();
var value = $(this).closest('.books').data('book');
var text = $(this).text();
console.log(text + " text");
var bookdetails = '';
$.each(value.desc, function (k, v) {
console.log(v.id + "-");
console.log(v.author + "<br>");
bookdetails += v.id + ' <br> ';
bookdetails += v.author + '<br>';
});
$contentbox.html(bookdetails);
});
});
Change
$(astuff).click(function()
to
$(document).on("click", "#astuff", function()
I assume "astuff" is a ID and you forgot the number sign and quotes in your original selector. The jQuery "click" listener only listens for events on elements that were rendered during the initial page load. You want to use the "on" listener, it'll look for events on elements currently in the DOM.

Categories