Multiple buttons with the same ID [closed] - javascript

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
SOLVED: Not enough coffee - the event listener was being added before the buttons were created.
Im creating a table from HTML LocalStorage like so:
for (i = 1; i <= localStorage['count']; i++) {
tableHtml = tableHtml + "<tr><td><button class='delete' id=" + i + ">Delete</button></td><td>" + localStorage['fullName' + i] + "</td><td>" + localStorage['email' + i] + "</td><td>" + localStorage['phoneNum' + i] + "</td></tr>";
}
This works great, however the delete button is proving troublesome.
I saw this:
jQuery find ID of clicked button by class
So I assumed i could do this:
$(".delete").click(function () {
alert('delete clicked for id: ' + $(this).id);
});
However, it doesn't work. Suggestions?

you can get the id of element by using javascript without using jquery wrapper like this:
$(".delete").click(function () {
alert('delete clicked for id: ' + this.id); // get id via javascript
});
or:
$(".delete").click(function () {
alert('delete clicked for id: ' + $(this)[0].id); // via javascript object
});
If you see the link reffered in question it is also getting id using javascript (this.id)
if you want to get via jquery then:
$(".delete").click(function () {
alert('delete clicked for id: ' + $(this).attr("id")); // via jquery object
});

When are you binding the click event? If it's before the element exists, you'll want to use .on.
$('body').on('click','.delete', function(){
alert('delete clicked for id: ' + $(this).attr('id'));
});
Check out a working jsFiddle.

use pure javascript:
this.id
or jquery
$(this).attr('id');
as $(this) is jquery object. and you are trying to get javascript property id. You need to first convert the object to javascript.
$(this)[0].id;

DOM elements shouldn't have numbers as the first character of id.
Change your code to something like this:
for (i = 1; i <= localStorage['count']; i++) {
tableHtml = tableHtml + "<tr><td><button class='delete' id=del-id" + i + ">Delete</button> </td><td>" + localStorage['fullName' + i] + "</td><td>" + localStorage['email' + i] + "</td><td>" + localStorage['phoneNum' + i] + "</td></tr>";
}
And
$(".delete").click(function () {
alert('delete clicked for id: ' + $(this).prop('id');
});
This should take you on the right track.
REMEMBER that .prop() function is jQuery 1.10+ specific.
If you are using an older version use .attr()
As some people here mentioned - id's can be numeric as of HTML5
still using them in a numeric form might generate rather unpleasant problems.
Link in the comments below from one of the users.

Related

JQuery / Javascript Click Event not detected in Dynamic table

I have looked through several answered questions, and tried to implement the solutions for my issue. I have a table being generated dynamically in javascript, that I then need a click event on in one column for each row.
I have tried the following:
$("#iFaceTbl tr").on('click', 'td.delInt', function(event) {
console.log("Clicked.");
let intId = event.target.id;
console.log("ID was: " + intId);
});
Wehre delInt is a class on the cell in each row.
When I run it, and watch the console, no click event is detected at all.
I'm sure I've done something wrong. For reference, here is the html, and javascript forming the table.
<table id="iFaceTbl"></table>
and
for (i=0; i < iFaces_count; i++) {
let html_to_insert = '<tr><td>' + intArray[i] + '</td><td id="' + intArray[i] +'" class="delInt"><i class="fa fa-trash delInt" aria-hidden="true"></span></td></tr>';
Currenthtml = Currenthtml + html_to_insert;
if (i == iFaces_count-1) {
iFaceTbl.innerHTML = Currenthtml;
}
}
Any help is greatly appreciated.
Was able to solve my issue with the change shown here to my event trigger. I had to remove the icon portion in favor of a 'X'. Code now looks like this:
$(document).on('click', '#iFaceTbl td', function(event) {
console.log("Clicked.");
let intId = event.target.id;
console.log("ID was: " + intId);
});

Bind function to dynamically created element [duplicate]

This question already has answers here:
Event handler not working on dynamic content [duplicate]
(2 answers)
Event binding on dynamically created elements?
(23 answers)
Closed 7 years ago.
I have some javascript which generates some html elements, like below:
for (var i = 0; i < suggestions.length; i++) {
var suggestion = suggestions[i];
var $li = $('<li data-profile-id="'+ suggestion.id + '" data-profile-name="'+suggestion.first_name + ' ' + suggestion.last_name + ' " class="search-name-result" ></li>');
$suggestionsUl.append($li);
var $img = $('<img src="/img/profile/' + suggestion.picture_url + '" class="search-suggest-img pull-left" />');
$li.append($img);
var $link = $('' + suggestion.first_name + ' ' + suggestion.last_name + '');
$li.append($link);
}
What I need to be able to do is also assign a function to each dynamically created li element, something like the below code:
$('.search-name-result').on('click', function(e){
$input.val($('.search-name-result').data('profile-name'));
});
But im not sure how to assign this to each li when they are created.
Thanks
Almost there, but actually delegate it using a parent container like document
$(document).on('click','.search-name-result', function(e){
$input.val($(this).data('profile-name'));
});
Also, you can change
$('.search-name-result').data('profile-name'))
to use $(this) like
$(this).data('profile-name'))
since it will be the clicked .search-name-result
You should use event delegation for dynamically added elements.
$(document).on('click','.search-name-result', function(e){
$input.val($('.search-name-result').data('profile-name'));
});

Stop additional click events on specific element ID - JQuery

I have a snippet of my jQuery code;
$('#elements').on('click', '.items', function () {
var content, id, tag;
tag = this.tagName;
id = $('#' + this.id);
content = id.html();
switch (tag.substr(0, 1)) {
case "P":
id.html("<textarea id='" + this.id + "In' class='" + tag + "In' type='text'>" + content + "</textarea>");
break;
case "H":
id.html("<input id='" + this.id + "In' class='" + tag + "In' value='" + content + "' >");
break;
}
});
The purpose of this is when I click on a paragraph tag, it will add a text area inside of the paragraph tag (with the content inside it ready for editing). When I click a heading tag, it will create an 'input' tag with the content inside it for editing.
Unfortunately, when i click twice on the paragraph, it adds a text area with the content inside it as it should but on the second click it adds another text area inside of that, now the 'content' of the textarea is: <textarea id="2In" class="PIn" type="text">Paragraph one. and with every click it adds: <textarea id="2In" class="PIn" type="text">
I understand this is happening as it should given the code but I want to stop the click event on that specific ID (this.id) but keep the click event active on the other elements with the class '.items'.
**Additionally: **
I'm sure this is bad practice to approach this by creating the editiable tags inside of the old ones so if anyone has a better approach be sure to let me know.
Many thanks,
Mike
I'd probably solve it by adding a :not(.clicked) to the selector, and adding that class when you add the input. E.g.:
$('#elements').on('click', '.items:not(.clicked)', function () {
$(this).addClass("clicked");
// ...your current handling...
});
But you could solve it by checking for the existence of the field, provided the input or textarea you're adding is the only one the paragraph will have:
$('#elements').on('click', '.items', function () {
if (!$(this).find("input, textarea")[0]) {
// ...your current handling...
}
});
Or actually jQuery extends CSS to provide :has and to allow :not to have more complex contents, so in theory this would work:
$('#elements').on('click', '.items:not(:has(input)):not(:has(textarea))', function () {
// ...your current handling...
});
...but that selector is getting a bit unwieldy...
What about using .one?
By using one, the click event can only be triggered once. Here's an example.
$('#elements > *').one('click', function () {
var content, id, tag;
tag = this.tagName;
id = $('#' + this.id);
content = id.html();
switch (tag.substr(0, 1)) {
case "P":
id.html("<textarea id='" + this.id + "In' class='" + tag + "In' type='text'>" + content + "</textarea>");
break;
case "H":
id.html("<input id='" + this.id + "In' class='" + tag + "In' value='" + content + "' >");
break;
}
});
But it seems you are trying to do something like allowing a user to edit text and saving the new input. I'd advise using a combination of contenteditable and localStorage.

Change link attribute after calling function

In a Jquery Mobile application I have a listview that calls a function wen clicked:
Go home
When a row link as above is clicked it calls this function:
function OnSaveOrDelete(acID){
if (localStorage.Favourites.indexOf("/" + acID + "/") >= 0)
{
alert('Ac Removed #' + acID);
$(this).prop('data-icon','delete');
var tmp = localStorage.Favourites;
localStorage.Favourites = tmp.replace("/" + acID + "/", "");
}
else{
alert('New Ac Saved #' + acID);
localStorage.Favourites += "/" + acID + "/";
}
}
When the existing item isnt in localStorage I add it, and then need to change the icon / data-icon attribute. As is shown in my code above, Im trying to do this via:
$(this).prop('data-icon','delete');
Ive also tried:
$(this).attr('data-icon','delete');
But neither of these work. Im assuming this is because '$(this)' isnt defined.
How can I updated my code to do what I need?
You can pass this in:
onclick="OnSaveOrDelete(' + item.ID + ', this)"
function OnSaveOrDelete(acID, obj) {
//$(obj) refers to the clicked element
$(obj).prop('data-icon','delete');
}

How to create selector, that link to dynamically created element? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I would like to know, how to create selector, that links to dynamically created element, without using event on the dynamically created element?
NOTE: dynamically created element I mean element, that is not in HTML at the beginning
I know that I can use $(this), when I have event (for example .click) on the element, but when I don't have event and I need selector on the dynamically created element?
Thanks to all.
update: Here is my situation:
$(".product div a").click(function() {
var nameOfProduct = $(this).parent().find("h3").text();
var dataPrice = parseInt($(this).parent().find("div b").text());
var isProductIn = false;
var itemsInDay = $(/*HERE I NEED THE SELECTOR*/).find("div.item").nextUntil("div.center");
itemsInDay.each(function () {
if (nameOfProduct == ($(this).find("span ins span").text())) {isProductIn = true;};
});
if (isProductIn) {
//add only +1, not new product again;
} else {
var imgOfProduct = $(this).parent().parent().find("img").attr('src').replace('med', 'min');
var product = ('<div class="item" data-price="' + dataPrice + '"><img src="' + imgOfProduct + '"><span><ins><b>1x</b> ' + nameOfProduct + '</ins><img src="images/delete.png"></span></div>');
$(product).appendTo(".dayOrder:last").delay(800).hide().slideDown();
}
return false;
});
Try something lihe this http://jsfiddle.net/pEb7D/5/
HTML:
<div class="test"></div>
Javascript:
dynamicSelector = $('.test').append('<div class="newElement">Hello!</div>');
setTimeout(function () {
dynamicSelector.text('Goodbye!');
}, 3000);
UPDATE:
OK, so you're putting the items into the .orderDay:last element. There you could loop through it's contents and see if you already have an existing element of one or other type.
However I would recommend making an array according to the product ID and then reacting to that.
For example http://jsfiddle.net/8byQp/
Javascript:
daysOrderArray = [];
$(".product div a").click(function() {
var nameOfProduct = $(this).parent().find("h3").text();
var imgOfProduct = $(this).parent().parent().find("img").attr('src').replace('med', 'min');
var dataId = $(this).parent().parent().data("id");
var dataPrice = parseInt($(this).parent().find("div b").text());
priceSum += dataPrice;
updatePrice(priceSum);
if(dataId in daysOrderArray){
// Now add number rather than new product.
daysOrderArray[dataId]++;
$('.item[data-id="' + dataId + '"] .quantity').text(daysOrderArray[dataId]);
} else {
daysOrderArray[dataId] = 1;
var product = ('<div class="item" data-id="' + dataId + '" data-price="' + dataPrice + '"><img src="' + imgOfProduct + '"><span><ins><b><span class="quantity">1</span>x</b> ' + nameOfProduct + '</ins><img src="images/delete.png"></span></div>');
$(product).appendTo(".dayOrder:last").delay(800).hide().slideDown();
return false;
}
});

Categories