I am dynamically creating li with javascript, I want to add a close button to each li element created dynamically to delete the li element on click of the close button.This is my code so far:
function addNew(){
// get value from input field
var taskName = document.getElementById('task-name').value;
// innerHTML to be inserted inside li
var fullText = taskName + '<span class = "close" onclick =
"addListener(this)">×</span>';
// calling create function from Element object
Element.createNew('li','className','tasks',0,fullText);
}
// remove function
function addListener(e){
e.parentNode.parentNode.removeChild(e.parentNode);
}
The problem is the remove function removes the last li instead of li being clicked.
Here is the JSFiddle of the problem.
store all the list items in an array.
//suppose your list items have a class name 'lists'
//create a global var
var lis = document.getElementsByClassName('lists');
initially it'll be empty,
so in your add method(in which you're appending the new list item to ul,
push the new list item in the lists array.
and in the addEvent(e) method , loop around every element in the lists array
function addEvent(e){
for(var i=0; i<lists.length; i++){
if(lists[i] === e){
//remove the lists element by using lists[i] instead of e
// and remember to pop the lists[i] and resize the lists array
}
}
Related
I'm making a to-do list application. I want to delete items by clicking a button attached to the list element, but it only deletes the button and not the entire element. Currently, <li> elements in a <ul> by the following:
function newElement() {
event.preventDefault(); // stop default redirect
var li = document.createElement("li"); // create an <li> element
/* make a text node from the input and put it in the <li> */
var inputValue = document.getElementById("task").value; // retrieve value of text box
var t = document.createTextNode(inputValue); // create a text node of the box value
li.appendChild(t); // put the text node in the single <li>
/* attach a button to the <li> element that deletes it */
var btn = document.createElement("BUTTON"); // Create a <button> element
btn.innerHTML = "X"; // Insert text
btn.className = "button" // add class name for CSS targeting
btn.addEventListener('click', removeItem); // add event listener for item deletion
li.appendChild(btn); // Append <button> to <li>
li.addEventListener('click', checkToggle); // add event listener for a click to toggle a strikethrough
appendItem("list", li); //append the li item to the ul
}
and the function called by the button's listener appears as:
function removeItem() {
this.parentNode.removeChild(this);
}
I want the button to delete the entire <li> node, but it only deletes the button portion of it.
Just looking at this, I think you need to add another parentNode. It seems you are only removing the button right now.
Just move this one step further up the hierarchy
function removeItem() {
this.parentNode.parentNode.removeChild(this.parentNode);
}
Use remove() so you are not dealing withe child element references
function removeItem() {
this.parentNode.remove()
// this.closest('li').remove()
}
or since you have a reference, just delete it
btn.addEventListener('click', function () { li.remove() })
Trying to create a function that console.logs the data-attribute associated with an .active class each time the .active class changes elements.
So far I can only get the initial data attribute value of the first element's .active class. Calling the function after the .active class has changed elements produces the same results as initially calling the function.
// Variables
var activeItem = document.querySelectorAll('.active');
// Get the Data-Targ value from the .active_class
var active_href = function() {
for (i = 0; i < activeItem.length; ++i) {
var reports = activeItem[i].dataset.targ;
console.log('data-targ of .active is: ' + reports);
}
};
In reply to comments, this is how I am initially attaching the .active class.
It is being attached to the first child of the parent container.
(essentially, the first li of the ul it is contained in)
var first_child = ul.children[0];
var active = first_child.classList.add('active');
So, the active_href isn't calling the dynamically updated .active class placement along the ul > li chain that happens through Next and Previous buttons containing the event handlers that add and remove the active class.
I am attempting to build a simple narrow by filter using given key word buttons on an otherwise static list of items.
The buttons are in an unordered list and when selected get the class ".selected-tag-button" added to them.
The items are divs with class ".item" and get class ".included-item" when they are active. Inside the div is another UL with list items that contain key words that match the text node on the buttons.
Right now it is working, except, instead of using "buttonName" which contains only the key word for the clicked button, I would like to use "buttonArray" which contains an array of all the selected key words.
I assume I will need some kind of function, but I am not sure where to start. If more than one are selected I want the result to be limited to only items that contain ALL of the selected key words. All of the solutions I have been able to figure out will return the divs that contain ANY of the key words in the array.
$(document).ready(function() {
$("li.tag-button").on("click", function() {
// Toggle button
$(this).toggleClass("selected-tag-button");
// Remove included-item class from all items
$(".item" ).removeClass("included-item");
// Pass the button text into variable
var buttonName = $(this).text().slice(2);
// Create array with button text for all active buttons
var buttonArray = $(".selected-tag-button").map(function() {
return $(this).text().slice(2);
}).get();
console.log(buttonArray);
// Add included-item class to divs containing the button text
$('li:contains("' + buttonName + '")').parents().parents().addClass("included-item");
// If all buttons are inactive, add included-item class to all items
if ($(".selected-tag-button").length == 0 ) {
$(".item" ).addClass("included-item");
}
});
});
Consider this fiddle:
http://jsfiddle.net/6qavvth8/
for(i=0; i<buttonArray.length;i++){
contains += ':contains("' + buttonArray[i] + '")';
}
$('ul' + contains).parents().addClass("included-item");
Loop through your button array to build your jquery selector and keep adding :contains()
Slight modification of #bingo's solution. Works perfectly, thanks.
$(document).ready(function() {
$("li.tag-button").on("click", function() {
// Toggle button
$(this).toggleClass("selected-tag-button");
// Remove included-item class from all items
$(".item" ).removeClass("included-item");
// Create array with button text for all active buttons
var buttonArray = $(".selected-tag-button").map(function() {
return $(this).text().slice(2);
}).get();
// Add included-item class to divs containing the button text
var contains = "";
for(i = 0; i < buttonArray.length; i++){
contains += ':contains("' + buttonArray[i] + '")';
}
$('ul' + contains).parents().addClass("included-item");
// If all buttons are inactive, add included-item class to all items
if ($(".selected-tag-button").length == 0 ) {
$(".item" ).addClass("included-item");
}
});
});
I'm making a to-do list to help me understand Javascript. I've managed to create a series of <li> elements with text inside. I'd like to delete the <li> elements, when they are clicked. However, at the moment they are unresponsive.
JSFIDDLE: http://jsfiddle.net/tmyie/aYLFL/
HTML:
<input id="input" placeholder="Write here">
<button>Add</button>
<hr>
<ul></ul>
Javascript:
var doc = document, // creates a variable, changing 'document' to the variable 'doc'
list = doc.getElementsByTagName('ul')[0],
li = doc.getElementsByTagName('li')[0],
input = doc.getElementById('input'),
button = doc.getElementsByTagName('button')[0]; // creates a variable called 'button', that gets the first array of all the <button> elements
button.onclick = function () {
var mySubmission = doc.getElementById('input').value; // Get values of the input box and call it 'mySubmission'
var item = doc.createElement('li'); // Creates a <li> element in a variable called 'item'
item.innerHTML = mySubmission; // Inside the created 'item', the inner HTML becomes mySubmission + the class 'remove'
list.appendChild(item); // get <ul>, and add the variable 'item'.
doc.getElementById('input').value = ""; // resets input after submission
};
The remove function:
li.onclick = function () {
li.parentNode.removeChild(li);
};
Excuse the excessive comments, I'm try get a better understanding of Javascript.
You define li to be:
li = doc.getElementsByTagName('li')[0]
But there are no li elements to begin with, so doc.getElementsByTagName('li')[0] returns undefined.
You'll need to move that event handler into the other callback:
list.appendChild(item); // get <ul>, and add the variable 'item'.
item.onclick = function () {
list.removeChild(item);
};
I've got a function that creates an unordered list in a form. I have another function that is supposed to add items to the list according to the selected value of a select box. The second function adds items to the list and they have the appropriate id's and whatnot, but no text. I cannot get the items to have text in them no matter what I try. Here is the current contents of the JavaScript function.
function anotherItem()
{
var textValue = document.forms['newForm'].selectBox1.value;
var ul = document.getElementById("newList");
var new_item = document.createElement("li");
new_item.id = textValue;
new_item.innerHtml = textValue; // I've also tried new_item.value = textValue among variations.
ul.insertBefore(new_item, ul.firstChild);
}
5| new_item.innerHtml = textValue;
| └┬─┘
| └───Should be "HTML"
JavaScript is case-sensitive. Now textValue should be written in the create li.
(It should had created an error if you put innerHtml, if you look in the console.)
Test it out: http://jsfiddle.net/DerekL/svUqG/