Removing elements by id using event Javascript dynamically - javascript

I have list of phones thats displaying as ul li. When user clicking button "buy" it creates new li with in another div "ordersDiv" user can delete his purchase from cart by clicking "Remove" And this must remove li with matching id.
Code that creates purchase:
$("#list").delegate("button",'click',function(){
var purchase = {id: null,name: null,price: null };
var purchases = [];
for(var i = 0; i < phones.length; i++){
if(this.id === phones[i].id){
purchase.id = phones[i].id;
purchase.name = phones[i].name;
purchase.price = phones[i].price;
//break;
purchases.push(purchase);
console.log(purchases);
$.each( purchases, function(i, purchase){
purchases.push("<li id='"+ purchase.id +"'>" + purchase.id +
"<br>" + purchase.name + "<br>" + "Price:" +purchase.price + "<br><button id='"+purchase.id+"' type='button' class='btn-default'>remove</button>" +"</li>" );
});
$('#ordersUl').append(purchases);
}
}
});
Code that supposed to remove li:
$("#ordersCartDiv #ordersUl").delegate("button","click", function() {
var buttonId = $(this).attr('id');
console.log(buttonId);
//$("li[id=buttonId]").remove();
$("#ordersUl").remove(buttonId);
console.log("test"); // code indentation
});
Problem is that this code doesn't removes anything.

you must pass a selector in remove function, like this:
$("#ordersUl").remove('#'+buttonId);

Use remove on button id.
$("# " + buttonId).remove();
No need to use ordersUl since id is unique(?).
If you don't have id unique:
$("#ordersUl #" + buttonId).remove(); // Will remove button inside #ordersUl
Remove the set of matched elements from the DOM.
Docs: http://api.jquery.com/remove/

$("#ordersUl").remove("#"+buttonId);

You should call remove function on element
$("li#"+buttonId).remove();
But ID is supposed to be unique, so it is bad idea to use it in this way. Use data- attributes or classes.

Related

Unable to get property 'nodeValue' of undefined or null reference in simple jQuery loop

I am inserting li values into a ul element on a form.
Just as testing, I am entering 2 values into the ul. Now, once the user clicks submit, I am checking if any of those li values are duplicates in another list... if not, then submit the values. But, I am working on a scenario where if the user enters a few duplicates and non-duplicates in the ul.. then I would want the non-duplicates to be taken away from the ul element once they are submitted, but keep the duplicates in the list so that the user can see the duplicates.
Here is my code:
console.log("Serial Length - " + $("#SerialUL li").length);
var serialUlLength = $("#SerialUL li").length;
// remove serial numbers that have been submitted from the list on the form.
for(i = 0; i < serialUlLength; i++){
var serialNumber = $("#SerialUL li:eq(" + i + ")").contents().get(0).nodeValue;
var isInSubmitArray = $.inArray(serialNumber, submitArray);
if(isInSubmitArray > -1){
console.log(serialNumber);
$("#SerialUL li:eq(" + i + ")").remove();
}
}
As I stated above, as of now, I am only entering 2 li values into the ul for simple testing. The list that I am comparing against has 0 values in it.. so there shouldn't be any duplicates at this point. The problem I am experiencing happens for the second li element. I am receiving this console error:
Unable to get property 'nodeValue' of undefined or null reference
I have debugged in the console, but I guess I am staring at this for too long. Can someone assist in explaining why I am getting this error?
Any help is appreciated.
UPDATE
The values I am entering as li are 10 and 11. Here is what I see in the console based off of the code above in my question:
UPDATE 2
Code to show li being appended to ul element
// Append TextBox Value to '<ul>' element for user to see once they click button
$("#SerialUL").append("<li class='bullet-serial'>" + serialTxtBoxValue + "<button type='button' class='remove-button'>x</button></li>");
How about this vastly simpler and easier to debug - assuming a leading serial number and something not a number after
var submitArray=[123,567];
$("#SerialUL li").each(function(_,li) {
var ser = parseInt(li.textContent.trim()); // add .replace(/[^0-9]/g,"") if needed
console.log(ser)
if (submitArray.indexOf(ser) !== -1) {
console.log("removing",ser)
li.remove();
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="SerialUL">
<li>123 <button>X</button></li>
<li>456 <button>X</button></li>
<li>123 <button>X</button></li>
<li>567 <button>X</button></li>
<li>789 <button>X</button></li>
</ul>
More complex version with some useful extras such as delegation
var submitArray = [];
$("#serialTxtBox").on("input", function(e) {
var val = this.value;
$("#err").toggle(val && submitArray.indexOf(val)!==-1);
if (String(val).length == 3 && submitArray.indexOf(val)==-1) {
submitArray.push(val);
$("#SerialUL").append("<li class='bullet-serial'>" + val + "<button type='button' class='remove-button'>x</button></li>");
$(this).val("");
}
if ($("#err").is(":visible")) $(this).val("");
})
$("#SerialUL").on("click",".remove-button", function(e) { // delegation
e.preventDefault();
$(this).closest("li").remove();
submitArray = [];
$("#SerialUL li").each(function(_, li) {
var ser = parseInt(li.textContent.trim()); // add .replace(/[^0-9]/g,"") if needed
submitArray.push(ser);
});
})
#err { color:red; display:none }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="serialTxtBox" /><span id="err">Already there</span>
<ul id="SerialUL">
</ul>
You are returning element node with .contenets().get(0). "nodeValue" always returns null on element node.
Try filtering for text nodes only on contents() function:
var serialNumber = $("#SerialUL li:eq(" + i + ")").contents().filter(function() {
return this.nodeType === 3;
}).get(0).nodeValue;
Or use .textContent instead .nodeValue:
var serialNumber = $("#SerialUL li:eq(" + i + ")").contents().get(0).textContent;

Getting Index of Item in List coming from Array

I have this array:
var names = [
"Name1",
"Name2",
"Name3"
];
I converted this to Unorder List for HTML:
for(i = 0; i < names.Length; i++){
text += "<li>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
Now, I got this:
Name1
Name2
Name3
And I am happy with the result. But now I want if someone click on Name2 so it alert me the index of the value. What I want is it should in Mobile App (Cordova) so that when user click on List Item it will show details on other activity (Some other page).
PS:
I checked:
var index = $( "li" ).index( this );
and
var index = $("ul li.active").index();
But seems like these are not made for me.
May be I should Dynamically assign ID's to each <li> item? What should I do now?
You can directly get index using index method.
$("li").click(function () {
alert($(this).index());
});
If you have multiple ul elements on page and you want to bind click event to some specific element you can do this.
To bind click on element by id
$("#YourUlId li").click(function () {
alert($(this).index());
});
To bind click event by class
$(".YourUlClass li").click(function () {
alert($(this).index());
});
$( "li" ).index will return elements index with respect to all li elements in DOM.
You need to use .index() with jquery object of clicked element. It will return the elements index in its parent container:
var index = $(this).index();
Pass the id dynamically in for loop
for(i = 0; i < names.Length; i++){
text += "<li id="+i+">" + names[i] + "</li>";
}
assign the click event, u will get the id by below code
$(li).click(function(){
alert($(this).attr("id"));
});
use this for getting the current element
<ul>
<li>Male</li>
<li>Female</li>
</ul>
<script>
$("li").click(function(){
alert($(this).index())
})
</script>
See below working snippet
var names = [
"Name1",
"Name2",
"Name3"
];
var text='<ul>';
for(i = 0; i < names.length; i++){
text += "<li>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
$('li').on('click',function(){
alert($(this).index())
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="choices"></div>
Using native javascript, you can just create a function that will alert the index of the array value corresponding the li element value/id
First you attach the function on the choices
document.getElementById('Name2').setAttribute('onclick','checkIndex(this)');
then loop through the array and hunt for the matching array value
function checkIndex(item){
for(i=0;i<names.length;i++){
if(names[i] == item.innerHTML){ //or item.id
alert(names.indexOf(names[i]));
}
}
}
I would handle it in a declarative way, using html data-attributes, handled by jquery. see here
Here's an example.
var names = ["jack", "mary", "lou", "andrew"];
var text = "<ul>";
for (var i = 0; i < names.length; i++) {
text += "<li data-id='" + i + "'>" + names[i] + "</li>";
}
text += "</ul>";
document.getElementById("choices").innerHTML = text;
$("li").click(function(e){
alert($(this).data("id"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
My Choice
<div id="choices"></div>
</body>
</html>
Of course you can change data-id with whatever you want, or either add other attributes (data-page ? data-txt ? ) and handle all this in a proper way.
Also, dynamically assign ids to your list is a possibility, but I prefer this because I find it more flexible.

Setting and using attribute of dynamically created variable in JQuery/Javascript

I have some javascript/JQuery which allows me to create a new entry in an HTML ordered list. This works fine. But now I am trying to set each entry to have an id equal to a variable 'id''s value, so that I can identify an entry and remove its id from a javascript array.
I am being told that I can't use setAttribute OR defineProperty, so I don't know what to do! I am including both my attempts to demonstrate what I am trying to achieve:
var idList = []; //array of entry ids
$(function (){
$("#click-me").click(function (e){
e.preventDefault();
i++;
var list = $("#list"); //works fine
var name = $("#colleague-select option:selected").text(); //works fine
var id = $("#colleague-select").val(); //works fine
var remove = "<button type='button' class='remove-me'> X </button>"; //works fine
var entry = "<li>" + name + remove+ "</li>"; //works fine
//entry.setAttribute("id", id); //doesn't work
//or
Object.defineProperty(entry, 'id', {
get: function(){return id;},
set: function(value) {id = value;}
});
list.append(entry); //adds entry to HTML element 'list'
idList.push(id); //adds id to array which should be the same as entry's id
return false;
});
});
$(document).on('click', ".remove-me", function(){
var entry = $(this).parent();
entry.remove();
var id = entry.attr("id"); //gets value of attribute "id". How will this need to be changed?
var index = idList.indexOf(id); //finds the index number of id within array
idList.splice(index,1); //removes id from array
});
Help on how to do this will be much appreciated, thanks
Entry is a string of html not an dom node, you can create an jQuery object out of it and then add the attribute or just add the id in the string
var entry = $("<li>" + name + remove+ "</li>").attr('id', id); //works fine
or
var entry = "<li id=\""+id+"\">" + name + remove+ "</li>"; //works fine
The click event on .remove-me doesn't work because you're calling entry.remove() and afterwards entry.attr("id"). At that point the entry element has been removed and thus you can't the get the id.
Move entry.remove() below entry.attr("id").

Get values and ids of all span elements inside form

I am trying to get all span elements inside the form. The span elements are turning into input text fields and become editable. When you click away they are turning back into span elements. I will attached fiddle live example.
I gave it a go but the problem is that I am getting both ids but only value of the first span element.
Here is my html:
<span name="inputEditableTest" class="pztest" id="inputEditableTest" data-editable="">First Element</span>
<span name="inputEditableTest2" class="pztest" id="inputEditableTest2" data-editable="">Second Element</span>
<input id="test" type="submit" class="btn btn-primary" value="Submit">
And here is JavaScript with jQuery:
$('body').on('click', '[data-editable]', function () {
var $el = $(this);
var name = $($el).attr('name');
var value = $($el).text();
console.log(name);
var $input = $('<input name="' + name + '" id="' + name + '" value="' + value + '"/>').val($el.text());
$el.replaceWith($input);
var save = function () {
var $p = $('<span data-editable class="pztest" name="' + name + '" id="' + name + '" />').text($input.val());
$input.replaceWith($p);
};
$input.one('blur', save).focus();
});
$("#test").on('click', function(){
var ok = $("span")
.map(function () {
return this.id;
})
.get()
.join();
var ok2 = $("#" + ok).text();
alert(ok);
alert(ok2);
//return [ok, ok2];
});
Here is the fiddle https://jsfiddle.net/v427zbo1/3/
I would like to return the results as an array example:
{element id : element value}
How can I read ids and values only inside specific form so something like:
<form id = "editableForm">
<span id="test1">Need these details</span>
<span id="test2">Need these details</span>
<input type="submit">
</form>
<span id="test3">Don't need details of this span</span>
Lets say I have got more than 1 form on the page and I want JavaScript to detect which form has been submitted and grab values of these span elements inside the form
I will be grateful for any help
$("#test").on('click', function(){
var result = {};
$("span").each(function (k, v) {
result[v.id] = v.innerHTML;
});
alert(JSON.stringify(result));
//return [ok, ok2];
});
Here is an example: https://jsfiddle.net/v427zbo1/4/
Container issue:
You should use this selector: #editableForm span if you want to get all the divs inside this container.
$("#editableForm span").each(function (k, v) {
result[v.id] = v.innerHTML;
});
But if you want to get only first-level children elements then you should use this selector: #editableForm > span
Example with getting all the spans inside #editableForm container: https://jsfiddle.net/v427zbo1/9/
If you want to have several forms, then you can do like this:
$('form').on('submit', function(e){
e.preventDefault();
var result = {};
$(this).find('span').each(function (k, v) {
result[v.id] = v.innerHTML;
});
alert(JSON.stringify(result));
//return [ok, ok2];
});
Example with two forms: https://jsfiddle.net/v427zbo1/10/
You can't use .text to return the value of multiple elements. It doesn't matter how many elements are selected, .text will only return the value of the first one.
Virtually all jQuery methods that return a value behave this way.
If you want to get an array of values for an array of matched elements, you need another map. You also need to join the strings with , # as you're producing something along the lines of #id1id2id3 instead of #id1, #id2, #id3:
var ok = $("span").map(function () {
return this.id;
}).join(', #')
var ok2 = $("#" + ok).map(function () {
return $(this).text();
});
That said, you're already selecting the right set of elements in your first map. You pass over each element to get its ID, you already have the element. There is no reason to throw it away and reselect the same thing by its ID.
If I got you right following code will do the job
var ok = $("span")
.map(function () {
return {id: $(this).attr('id') , value: $(this).text()};
}).get();
Check this fiddle.

Javascript to get the div info

I have 4 <div> tag and <a> tag for each <div> tags.
In each and every div tag i have inserted 2 span tag and a a tag.
When the a tag is clicked i need to get the product name and the price of that div
Here is the demo http://jsfiddle.net/8VCWU/
I get the below warning message when i use the codes in the answer ...
Try this:
$(".get").click(function(e) {
e.preventDefault();
var $parent = $(this).closest(".item");
var itemName = $(".postname", $parent).text();
var itemPrice = $(".price", $parent).text();
alert(itemName + " / " + itemPrice);
});
Example fiddle
Note that you had a lot of repeated id attributes which is invalid code and will cause you problems. I've converted the #item elements and their children to use classes instead.
jQuery
$(".get").click(function(event){
event.preventDefault(); /*To Prevent the anchors to take the browser to a new URL */
var item = $(this).parent().find('#postname').text();
var price = $(this).parent().find('#price').text();
var result = item + " " + price;
alert(result)
});
DEMO
A Quick Note about id:
The id attribute specifies a unique id for an HTML element (the value must be unique within the HTML document).
A unique identifier so that you can identify the element with. You can use this as a parameter to getElementById() and other DOM functions and to reference the element in style sheets.
solution is below
use the blow code and try it
<a data-role="link" href="javascript:linkHandler('<%= obj.productname %>', '<%= obj.price %>')" class="get" >Add <a>
function linkHandler(name, price)
{
alert(name);
alert(price);
var name = name;
var price = price;
var cartItem = new item(name, parseFloat(price));
// check duplicate
var match = ko.utils.arrayFirst(viewModel.cartItems(), function(item){ return item.name == name; });
if(match){
match.qty(match.qty() + 1);
} else {
viewModel.cartItems.push(cartItem);
var rowCount = document.getElementById("cartcontent1").getElementsByTagName("TR").length;
document.getElementById("Totala").innerHTML = rowCount;
}
}
with jQuery
​$('a.get').on('click',function(){
var parent = $(this).parent();
var name = $(parent+' #postname').text();
var price = $(parent+' #price').text();
});​​​​​​​​
Or again:
$('a').click(function(e){
e.preventDefault();
var $price = $(this).siblings('#price').text();
var $postname = $(this).siblings('#postname').text();
alert($price);
alert($postname);
});
Try
function getPrice(currentClickObject)
{
var priceSpan = $(currentClickObject).parent("div:first").children("#price");
alert($(priceSpan).html());
}
and add to your a tag:
...
I'd suggest to use classed instead of id if you have more than one in your code.
The function you're looking for is siblings() http://api.jquery.com/siblings/
Here's your updated fiddle:
http://jsfiddle.net/8VCWU/14/
Hi I cleaned up the HTML as mentioned using the same Id more than once is a problem.
Using jQuery and the markup I provided the solution is trivial.
Make a note of the CSS on the below fiddle
http://jsfiddle.net/8VCWU/27/
$(document).ready(function(){
$("#itmLst a.get").click(function(){
var $lstItm = $(this).parents("li:first");
var pName = $lstItm.find("span.postname").html();
var price = $lstItm.find("span.price").html();
alert("Product Name: " + pName + " ; Price: " + price);
});
});
I have made some changes in your html tags and replace all repeated Ids with class, because you have repeated many ids in your html and it causes trouble so it is wrong structure. In HTML, you have to give unique id to each and every tag. it will not be conflicted with any other tag.
Here i have done complete bins demo. i have also specified all alternative ways to find tag content using proper jQuery selector. the demo link is as below:
Demo: http://codebins.com/bin/4ldqp8v
jQuery
$(function() {
$("a.get").click(function() {
var itemName = $(this).parent().find(".postname").text().trim();
var itemPrice = $(this).parent().find(".price").text().trim();
//OR another Alternate
// var itemName=$(this).parents(".item").find(".postname").text().trim();
// var itemPrice=$(this).parents(".item").find(".price").text().trim();
//OR another Alternate
//var itemName=$(this).closest(".item").find(".postname").text().trim();
// var itemPrice=$(this).closest(".item").find(".price").text().trim();
//OR another Alternate
//var itemName=$(this).siblings(".postname").text().trim();
//var itemPrice=$(this).siblings(".price").text().trim();
alert(itemName + " / " + itemPrice);
});
});
Demo: http://codebins.com/bin/4ldqp8v
You can check above all alternatives by un-commenting one by one. all are working fine.

Categories

Resources