Reference appened HTML code via id with jquery - javascript

I have a problem concerning the use of .append("..."). I am coding a simple To-Do List and want to delete a list element when I click on the appended "REMOVE" button by reference to the buttons class.
I think it is not working because .append() isn't changing the html code of the website. At least I can't spot a difference after clicking the "ADD ITEM" button.
Do you have any ideas?
Thanks in advance!
var inputText;
var itemList = [];
$("#addButton").click(function(){
inputText = $("#textInput").val();
itemList.push(inputText);
$("#textInput").val("");
showItems();
});
//not working
$(".deleteButton").click(function(e){
console.log("test");
var className = e.attr("id");
console.log("ID:" + className);
});
function showItems(){
$("#list").html('');
for(var i=0; i<=itemList.length-1; i++){
$("#list").append('<div class="listelement"><p type="text" class="listItem" id="listItem '+ i +'">'+ itemList[i] +'</p> <button type="button" class="deleteButton" id="'+ i +'">REMOVE</button><div>');
}
}
<body>
<div class="container">
<div class="headline">
<h1 id="headline">TO DO LIST</h1>
</div>
<div class="userInput">
<input type="text" id="textInput">
<button type="button" id="addButton">ADD ITEM</button>
</div>
<div class="list" id="list">
<div class="listelement" id="listelement">
</div>
</div>
</div>
<script src="jquery-3.4.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>

You need to use event delegation.
$(document).on("click",".deleteButton",function(e) {
$(this).closest(".listelement").remove()
});
$(".deleteButton").click(function(e){ will only work on those elements that exist on the page, but not on newly added elements.
var inputText;
var itemList = [];
$("#addButton").click(function() {
inputText = $("#textInput").val();
itemList.push(inputText);
$("#textInput").val("");
showItems();
});
//not working
$(document).on("click",".deleteButton",function(e) {
$(this).closest(".listelement").remove()
});
function showItems() {
$("#list").html('');
for (var i = 0; i <= itemList.length - 1; i++) {
$("#list").append('<div class="listelement"><p type="text" class="listItem" id="listItem ' + i + '">' + itemList[i] + '</p> <button type="button" class="deleteButton" id="' + i + '">REMOVE</button><div>');
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="headline">
<h1 id="headline">TO DO LIST</h1>
</div>
<div class="userInput">
<input type="text" id="textInput">
<button type="button" id="addButton">ADD ITEM</button>
</div>
<div class="list" id="list">
<div class="listelement" id="listelement">
</div>
</div>
</div>

If you just want to remove that specific div where you are clicking you can use following code. You dont need to match id here.
$(document).on("click",".deleteButton",function(e){
let parent = $(this).closest(".listelement");
parent.remove();
});
But according to your code after delete if you add something, all the data of the array will show.Because you are not deleting data from array. I think you need to delete that data from the array too.
$(document).on("click",".deleteButton",function(e){
let parent = $(this).closest(".listelement");
let id = $(this).attr("id");
console.log(id);
itemList.splice(id, 1);
parent.remove();
});

The issue here is that the element appended doesn't have an event listener attached to it, when you're calling $(...).click it will attach an event listener only to the currently existing elements. Since you're calling it when the document loads and there are no elements with the class deleteButton at that time it won't do anything.
You can solve this by moving the deletion code to it's own function and attaching a click event listener for each new element you create.
In order to do so efficiently, you'll need to get the element you're creating, you can do this like so:
$(HTML Code).appendTo('#list').click(...);
This will create an element from the html you pass it, append it to the element with the id list and attach a click event listener to it, so in the end this will the result:
var inputText;
var itemList = [];
$("#addButton").click(function() {
inputText = $("#textInput").val();
itemList.push(inputText);
$("#textInput").val("");
showItems();
});
function deleteItem(e) {
console.log(e.target.id);
}
function showItems() {
$("#list").html('');
for (var i = 0; i <= itemList.length - 1; i++) {
var html = '<div class="listelement"><p type="text" class="listItem" id="listItem ' + i + '">' + itemList[i] + '</p> <button type="button" class="deleteButton" id="' + i + '">REMOVE</button><div>';
$(html).appendTo('#list').click(deleteItem);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="headline">
<h1 id="headline">TO DO LIST</h1>
</div>
<div class="userInput">
<input type="text" id="textInput">
<button type="button" id="addButton">ADD ITEM</button>
</div>
<div class="list" id="list">
<div class="listelement" id="listelement">
</div>
</div>
</div>

If you try to do something with the elements that are dynamically added to DOM using the jQuery click() method it will not work, because it bind the click event only to the elements that exist at the time of binding
you can use
$(document).on("click", "button.deleteButton" , function() {
$(this).parent().remove();
});
https://jsfiddle.net/82d0e5at/3/

Related

Javascript - Retrieving values of a div when a button inside that div is clicked

I'm writing the code to edit a database table.
I have the following HTML:
<div id="1">
<div contenteditable>aaa</div>
<div contenteditable>bbb</div>
<div contenteditable>ccc</div>
<button onClick="a('save')">SAVE</button>
<button onClick="a('delete')">DELETE</button>
</div>
<div id="2">
<div contenteditable>ddd</div>
<div contenteditable>eee</div>
<div contenteditable>fff</div>
<button onClick="a('save')">SAVE</button>
<button onClick="a('delete')">DELETE</button>
</div>
<div id="3">
<div contenteditable>ggg</div>
<div contenteditable>hhh</div>
<div contenteditable>iii</div>
<button onClick="a('save')">SAVE</button>
<button onClick="a('delete')">DELETE</button>
</div>
And so on.
Using the following function, I can get the clicked button:
function a(value) {
console.log(value);
}
When a button (SAVE or DELETE) is clicked, I need to retrieve:
the id of the "parent" div;
the content of each of the three contenteditable divs inside the same "parent" div.
Is it possible using pure Javascript?
Any suggestion will be very appreciated.
Thanks in advance.
What I would do is implement click listeners in JS, that way I can query elements easily.
Here is the example:
// Query all div.div-editable elements
document.querySelectorAll('div.div-editable')
.forEach((div) => {
// The id of the parent
const divId = div.id;
// Each of content editable divs inside the parent div
const editables = div.querySelectorAll('div[contenteditable]');
// The buttons Save and Delete
const saveBtn = div.querySelector('button.button-save');
const deleteBtn = div.querySelector('button.button-delete');
// Add click listeners to buttons
saveBtn.addEventListener('click', function() {
console.log('Saved: ' + divId);
const contentOfEditableDivs = Array.from(editables).map((div) => div.innerText);
console.log('Values of divs:', contentOfEditableDivs);
});
deleteBtn.addEventListener('click', function() {
console.log('Deleted: ' + divId);
const contentOfEditableDivs = Array.from(editables).map((div) => div.innerText);
console.log('Values of divs:', contentOfEditableDivs);
});
});
<div id="1" class="div-editable">
<div contenteditable>aaa</div>
<div contenteditable>bbb</div>
<div contenteditable>ccc</div>
<button class="button-save">SAVE</button>
<button class="button-delete">DELETE</button>
</div>
<div id="2" class="div-editable">
<div contenteditable>ddd</div>
<div contenteditable>eee</div>
<div contenteditable>fff</div>
<button class="button-save">SAVE</button>
<button class="button-delete">DELETE</button>
</div>
<div id="3" class="div-editable">
<div contenteditable>ggg</div>
<div contenteditable>hhh</div>
<div contenteditable>iii</div>
<button class="button-save">SAVE</button>
<button class="button-delete">DELETE</button>
</div>
EDIT 1: Added code snippet
EDIT 2: Simplified explanation
You can send this keyword in the argument of click's event handler and then access the parent div's id.
So your HTML would look something like:
// rest of the code here
<button onClick="a(this, 'save')">SAVE</button>
<button onClick="a(this, 'delete')">DELETE</button>
// rest of the code here
And your JS code would change to:
function a(elem, value) {
console.log(elem.parentNode.id);
}
More details on the following link:
how i get parent id by onclick Child in js

Unable to find the specific items value jQuery

I am facing an easy problem but unable to find a solution the problem is
i am creating a dynamic div with some elements also with some data
$("#divSearchedIssue").append(`
<div class="statistic d-flex align-items-center bg-white has-shadow">
<div class="icon bg-red">
<i class="fa fa-tasks"></i>
</div>
<div class="text">
***//want to get this below id value//**
Mobile Code :
<small id="mbCode">
${ data[0].MobileCode }
</small>
***/want to find/**
<br>
Failed From:
<small>
${ data[0].FailedStation }
</small>
<br>
Issues :
<small>
${ data[0].Issues }
</small>
</div>
<div class="text"><strong> </strong></div>
<div class="text">
<button type="button" id="btn" class="btn btn-warning pull-right">Start</button>
</div>
<div class="text"><br></div>
</div>`);
Here I have a button .On this button click i want to fetch the value of
small text which id is #mbCode as mentioned above inside the code
I am trying this by using the following button click code
$(document).on('click', '#btn', function () {
var data = $(this).closest('small').find('#mbCode').val();
alert(data);
});
but its not working.I mean I cant fetch the value of #mbCode on this button click .So help needed
Thanks for helping
Based on .closest()
Description: For each element in the set, get the first element that
matches the selector by testing the element itself and traversing up
through its ancestors in the DOM tree.
As <small> is not an ancestors to button in hierarchy(while traversing-up),
So You need to first go the parent of <small> through .closest() and then try to find <small> html using .find() and .html()
$(document).on('click', '#btn', function () {
var data = $(this).closest('.statistic').find('small').html();
alert(data);
});
Working snippet:-
data = [{'MobileCode':20,'FailedStation':'WATERLOO','Issues':'broken'}];
$("#divSearchedIssue").append('<div class="statistic d-flex align-items- center bg-white has-shadow"><div class="icon bg-red"><i class="fa fa-tasks"></i></div><div class="text">Mobile Code :<small id="mbCode">' + data[0].MobileCode + '</small><br>Failed From: <small> ' + data[0].FailedStation + '</small><br>Issues :<small> '+ data[0].Issues + '</small></div><div class="text"><strong> </strong></div><div class="text"><button type="button" id="btn" class="btn btn-warning pull-right">Start</button></div><div class="text"><br></div></div>');
$(document).on('click', '#btn', function () {
var data = $(this).closest('.statistic').find('small').each(function(){
alert($(this).html());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divSearchedIssue"></div>
Note:- .text() will work too
https://jsfiddle.net/tyz4ox50/
As identifiers must be unique, Directly use ID Selector with .text()/.html() method
var data = $('#mbCode').text()
However if you are appending multiple elements I would recommend an alternative to persist Mobile code arbitrary data using custom data-* attribute along with <button> which can be fetched using .data(key) and attach event handler using Class Selector
$("#divSearchedIssue").append('<button type="button" id="btn" class="btn btn-warning pull-right" data-mobilecode="' + data[0].MobileCode + '" >Start</button>');
var counter = 0;
function append() {
$("#divSearchedIssue").append('<button type="button" id="btn" class="btn btn-warning pull-right" data-mobilecode="' + ++counter + '" >Start</button>');
}
append();
append();
append();
$(document).on('click', '.btn', function() {
var data = $(this).data('mobilecode');
console.log(data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divSearchedIssue"></div>
Try the following code snippet
var value = $('#mbCode').val();
Make sure the id is unique
Ids shouldn't be duplicate in an web-page.
Also, small is not one of the parent nodes of btns, and use html instead of val.
You need to go two-level higher to statistic Make it
$(document).on('click', '.text #btn', function () {
var data = $(this).closest('.statistic').find('#mbCode');
console.log(data.html());
});
Demo
var counter = 0;
function append() {
$("#divSearchedIssue").append(
`<div class="statistic d-flex align-items-
center bg-white has-shadow">
<div class="icon bg-red"><i class="fa fa-tasks">
</i></div>
<div class="text">
Mobile Code :<small id="mbCode">` +
(counter++) +
`</small><br>Failed From: <small> ' +
data[0].FailedStation + '</small><br>Issues :<small> ' + data[0].Issues +
'</small></div>
<div class="text"><strong> </strong>
</div>
<div class="text"><button type="button" id="btn" class="btn btn-
warning pull-right">Start</button></div>
<div class="text"><br></div>
</div>`
);
}
append();
append();
append();
$(document).on('click', '.text #btn', function () {
var data = $(this).closest('.statistic').find('#mbCode');
console.log(data.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divSearchedIssue"></div>
If your element already has an ID attribute you should be able to find the element by the ID. $("#mbCode")
Your js code
$(this).closest('small').find('#mbCode').val(); // "$(this)", in your code, represents the "button" that was clicked.
is looking for "small" tag inside "button" element, but it's not there. It would work if your button was like
<button type="button" id="btn" class="btn btn-warning pull-right"><small id="mbCode"></small></button>
This should work:
$(document).on('click', '#btn', function () {
var $mbCode = $('#mbCode');
console.log($mbCode);
});

Jquery: How to add an image to a remove button

I'm working on a class project to create a shopping list in jquery. I'm struggling with two similar issues.
As you can see from the image, I have an "Add" button and a remove "X" which both function a they should.
I'm trying to replace both of these objects with images I have created in Adobe Illustrator, the first a "plus +" icon and the second a "minus -" icon.
Any advice is much appreciated.
Shopping List
$(document).ready(function() {
$("#input-form").submit(function() {
var newItem = $("#input-item").val();
if (newItem.length > 0) {
var listItem = "<li>";
listItem += "<input type='checkbox'>";
listItem += "<span>" + newItem + "</span>";
listItem += "<span class='remove'>X</span>";
listItem += "</li>";
$("#items").append(listItem);
}
return false;
})
})
$(document).on("click", ".remove", function() {
$(this).parent().remove();
})
<body>
<div id="main">
<header>
<h1>Shopping List</h1>
</header>
<div id="input">
<form id="input-form">
<input id="input-item" type ="text">
<button type="submit">add</button>
</form>
</div>
<div id="list">
<ul id="items">
<!-- Items will go here -->
</ul>
</div>
</div>
</body>
I see you are using <button> tag for add and <span> for remove.
In any case, you can add image by:
<button type="submit"><img src="your/image/url"/></button>
<span class="remove"><img src="your/image/url"/></span>

Jquery function is needed

Following code add div on click button. But I want to add classes to all divs in code with id(1), id(2) etc without clicking position. Is this possible.
JS:
$(function() {
$('button').on('click', function() {
var $sparkLines = $('.sparkLines');
$("#sparkLineContainer").append('<div id="id' + ($sparkLines.length + 1) + '" class="sparkLines">Some Stuff Here</div>');
});
});
HTML:
<div id="sparkLineContainer">
<div class="sparkLines" id="id1">Some stuff here</div>
<div class="sparkLines" id="id2">Some stuff here</div>
<div class="sparkLines" id="id3">Some stuff here</div>
</div>
<button>Add Spark Line</button>
Actually I want to add class to all divs but with id1, id2, id3.
For example:
<div class="addclass" id="id1"></div>
<div class="addclass" id="id2"></div>
Hi you can do that using a counter on your function, Let me use Jquery on this.
function addDiv(){
var counter =0;
$('id').append('div id="' + counter +'"');
counter = counter + 1;
}
This should work.

Jquery clone and rename input fields

I have the following:
<!-- group clone //-->
<div class="section">
<div class="parent row infoOn">
<div class="validGroup">
<a title="remove" class="iconClose" href="#">remove</a>
<div class="grouping">
<div class="clearfix valid">
<label>Name<span class="iconReq"> </span>:</label>
<input type="password" class="text inpButton" name="items[0].first">
</div>
<div class="clearfix">
<label>Email<span class="iconReq"> </span>:</label>
<input type="text" class="text inpButton" name="items[0].first">
</div>
</div>
</div>
</div>
<div class="row addControl">
Add
</div>
</div>
<!-- group clone //-->
and jQuery:
$(function(){
// Control clone
$('div.addControl a.button').click(function (e){
e.preventDefault();
var parent = $(this).closest('.section').find('.parent:last');
var parentInput = parent.clone();
parentInput.find("input").val("");
parent.after(parentInput);
});
$('div.validGroup a.iconClose').live('click', function (e){
e.preventDefault();
if ($(this).closest('.section').find('.parent').length > 1){
$(this).closest('div.parent').remove();
}
});
reflesh();
});
clicking the "Add" button removes
values from input fields and clones
the group (2 input fields).
clicking "remove" link removes
group
Question: how would I change it so that when adding OR removing a new group, input fields would be renamed to name="items[INDEX].first" and name="items[INDEX].last"
For example. when there's only one "group", input fields would have names:
name="items[0].first"
name="items[0].last"
if I add another one, the new one would have
name="items[1].first"
name="items[1].first"
and so on.
When I remove the first one (one with items[0].first), the second one's input names would be modified from "items[1].first" to items[0].first.
here is what it looks like:
I figured it out:
var size = parseInt($('.form .section .parent').size());
$('.form .section .parent').each(function(index){
$(this).find('input.text').each(function(){
$(this).attr("name", $(this).attr("name").replace($(this).attr("name").match(/\[[0-9]+\]/), "["+index+"]"));
});
if (size > 1) { $(this).find('a.iconClose').show(); }else{ $(this).find('a.iconClose').hide(); }
});
$('.add-more').on('click',function(){
var newelement= $(".form-content").eq(0).clone();
var num = $('.form-content').length;
var newNum = num + 1;
newelement.find('input').each(function(i){
$(this).attr('name',$(this).attr('name')+newNum);
$(this).attr('id',$(this).attr('id')+newNum);
});
$('.form-content').last().after(newelement);
});

Categories