Remove clicked <li> onclick - javascript

I have this JavaScript code:
window.onload = init;
function init () {
var button = document.getElementById("submitButton");
button.onclick = addItem;
var listItems = document.querySelectorAll("li"); //assigning the remove click event to all list items
for (var i = 0; i < listItems.length; i++) {
listItems[i].onclick = li.parentNode.removeChild(li);
}
}
function addItem() {
var textInput = document.getElementById("item"); //getting text input
var text = textInput.value; //getting value of text input element
var ul = document.getElementById("ul"); //getting element <ul> to add element to
var li = document.createElement("li"); //creating li element to add
li.innerHTML = text; //inserting text into newly created <li> element
if (ul.childElementCount == 0) { //using if/else statement to add items to top of list
ul.appendChild(li); // will add if count of ul children is 0 otherwise add before first item
}
else {
ul.insertBefore(li, ul.firstChild);
}
}
function remove(e) {
var li = e.target;
var listItems = document.querySelectorAll("li");
var ul = document.getElementById("ul");
li.parentNode.removeChild(li);
}
and this HTML:
<body>
<form>
<label for="item">Add an item: </label>
<input id="item" type="text" size="20"><br>
<input id="submitButton" type="button" value="Add!">
</form>
<ul id="ul">
</ul>
<p>
Click an item to remove it from the list.
</p>
</body>
What I want to do is remove the whichever <li> element the user clicks, but this doesn't seem to be working and I am unable to find an answer anywhere else online for this specific scenario. Hoping someone can help me out here and show me what i am missing.

UPDATE
Plain JS delegation
Add the eventListener to the UL to delegate the click even on dynamically inserted LIs:
document.getElementById("ul").addEventListener("click",function(e) {
var tgt = e.target;
if (tgt.tagName.toUpperCase() == "LI") {
tgt.parentNode.removeChild(tgt); // or tgt.remove();
}
});
jQuery delegation
$(function() {
$("#submitButton").on("click",function() {
var text = $("#item").val(); //getting value of text input element
var li = $('<li/>').text(text)
$("#ul").prepend(li);
});
$("#ul").on("click","li",function() {
$(this).remove();
});
});
Original answer
Since you did not mention jQuery
var listItems = document.getElementsByTagName("li"); // or document.querySelectorAll("li");
for (var i = 0; i < listItems.length; i++) {
listItems[i].onclick = function() {this.parentNode.removeChild(this);}
}
you may want to wrap that in
window.onload=function() { // or addEventListener
// do stuff to the DOM here
}
Re-reading the question I think you also want to add that to the dynamic LIs
li.innerHTML = text; //inserting text into newly created <li> element
li.onclick = function() {
this.parentNode.removeChild(this);
// or this.remove(); if supported
}
Here is the complete code as I expect you meant to code it
Live Demo
window.onload=function() {
var button = document.getElementById("submitButton");
button.onclick = addItem;
}
function addItem() {
var textInput = document.getElementById("item"); //getting text input
var text = textInput.value; //getting value of text input element
var ul = document.getElementById("ul"); //getting element <ul> to add element to
var li = document.createElement("li"); //creating li element to add
li.innerHTML = text; //inserting text into newly created <li> element
li.onclick = function() {
this.parentNode.removeChild(this);
// or this.remove(); if supported
}
if (ul.childElementCount == 0) { //using if/else statement to add items to top of list
ul.appendChild(li); // will add if count of ul children is 0 otherwise add before first item
}
else {
ul.insertBefore(li, ul.firstChild);
}
}
In case you want to use jQuery, the whole thing gets somewhat simpler
Live Demo
$(function() {
$("#submitButton").on("click",function() {
var text = $("#item").val(); //getting value of text input element
var li = $('<li/>')
.text(text)
.on("click",function() { $(this).remove()});
$("#ul").prepend(li);
});
});

I know you already received an answer, but back to your original remove function. You have the following:
function remove(e) {
var li = e.target;
var listItems = document.querySelectorAll("li");
var ul = document.getElementById("ul");
li.parentNode.removeChild(li);
}
Change it to this and you should get what you were trying to achieve:
function remove(e)
{
var li = e.target;
var ol = li.parentElement;
ol.removeChild( li);
return false;
}

I'd suggest simplifying things a little:
Object.prototype.remove = function(){
this.parentNode.removeChild(this);
};
var lis = document.querySelectorAll('li');
for (var i = 0, len = lis.length; i < len; i++) {
lis[i].addEventListener('click', remove, false);
}
JS Fiddle demo.
Of course, having done the above, I'd then have to go further (possibly because I like jQuery too much) and also:
Object.prototype.on = function (evt, fn) {
var self = this.length ? this : [this];
for (var i = 0, len = self.length; i < len; i++){
self[i].addEventListener(evt, fn, false);
}
};
Object.prototype.remove = function(){
var self = this.length ? this : [this];
for (var i = 0, len = self.length; i < len; i++){
self[i].parentNode.removeChild(self[i]);
}
};
document.querySelectorAll('li').on('click', remove);
JS Fiddle demo.

If you don't want to write function in javascript, you can use immediately invoked anonymous function like below...
<elem onclick="(function(_this){_this.parentNode.removeChild(_this);})(this);"

If I understood you correctly:
$("li").on("click", function() {
$(this).remove()
});

The answer is more obvious than it could seem, you forgot to add init() in your script, is normal that the click event aren't triggered, they're not set on the element!
EDIT:
Your code has some logical errors. If you don't add an onclick function for all those created elements you will not be able to remove the clicked element. This is because the function init() is called one time at the load of the page!
function init() {
var button = document.getElementById("submitButton");
button.onclick = function() {addItem()};
}
function addItem() {
var textInput = document.getElementById("item"); //getting text input
var text = textInput.value; //getting value of text input element
var ul = document.getElementById("ul"); //getting element <ul> to add element to
var li = document.createElement("li"); //creating li element to add
li.innerHTML = text; //inserting text into newly created <li> element
li.onclick = function() {this.parentNode.removeChild(this);}
if (ul.childElementCount == 0) { //using if/else statement to add items to top of list
ul.appendChild(li); // will add if count of ul children is 0 otherwise add before first item
} else {
ul.insertBefore(li, ul.firstChild);
}
}
init();

Related

after adding elements through button why clicking on list items will not change the heading?

I have a simple application. There is a list, clicking on an item in the list will update the header to match the text of the list item. There is also a button to add new items to the list.
Here is my code
var counter = 1;
var MyList = document.querySelector("#mylist"); // mylist is id of ul
var heading = document.querySelector("#heading"); // heading is id of header
var btn = document.querySelector(".btn");
var list = document.querySelectorAll("#mylist li");
for (i = 0; i < list.length; i++) {
list[i].addEventListener("click", changeHead);
}
function changeHead() {
heading.innerHTML = this.innerHTML;
}
btn.addEventListener("click", addRecord);
function addRecord() {
MyList.innerHTML += "<li>something New " + counter + "</li>";
counter++;
}
<h1 id="heading">Hii,Bhushan</h1> <button class="btn">Add New</button>
<ul id="mylist">
<li>bhushan dhage</li>
<li>vishal Ambhore</li>
<li>Ravi kauthale</li>
<li>manik jadhav</li>
</ul>
Clicking on list items seems to work correctly but when I add a new list item and click on it the header does not update. Do you know why this is the case?
Thank you.
This happens because you only add your eventListener once, you have to add it to the new item each time you add one.
If I were you rather than using innerHTML I would use createElement and then append your new element to the list. This has the added advantage of being able to add your eventListener to the new li while you're making it.
In an HTML document, the document.createElement() method creates the HTML element specified by tagName, or an HTMLUnknownElement if tagName isn't recognized.
Here is the code, the only changes are in the addRecord function
var counter = 1;
var MyList = document.querySelector("#mylist"); // mylist is id of ul
var heading = document.querySelector("#heading"); // heading is id of header
var btn = document.querySelector(".btn");
var list = document.querySelectorAll("#mylist li");
for (i = 0; i < list.length; i++) {
list[i].addEventListener("click", changeHead);
}
function changeHead() {
heading.innerHTML = this.innerHTML;
}
btn.addEventListener("click", addRecord);
function addRecord() {
var listItem = document.createElement('li');
var text = document.createTextNode("something New " + counter);
listItem.appendChild(text)
listItem.addEventListener("click", changeHead);
MyList.appendChild(listItem);
counter++;
}
<h1 id="heading">Hii,Bhushan</h1> <button class="btn">Add New</button>
<ul id="mylist">
<li>bhushan dhage</li>
<li>vishal Ambhore</li>
<li>Ravi kauthale</li>
<li>manik jadhav</li>
</ul>
I hope you find this helpful if anything is confusing feel free to ask.
i did a simple change in your code, might help you
var counter = 1;
var MyList = document.querySelector("#mylist"); // mylist is id of ul
var heading = document.querySelector("#heading"); // heading is id of header
var btn = document.querySelector(".btn");
var list = document.querySelectorAll("#mylist li");
MyList.onclick = function(e) {
heading.innerHTML = e.target.innerHTML;
}
btn.addEventListener("click", addRecord);
function addRecord() {
MyList.innerHTML += "<li>something New " + counter + "</li>";
counter++;
}
<h1 id="heading">Hii,Bhushan</h1> <button class="btn">Add New</button>
<ul id="mylist">
<li>bhushan dhage</li>
<li>vishal Ambhore</li>
<li>Ravi kauthale</li>
<li>manik jadhav</li>
</ul>
This might work for you i removed unnecesary functions created an li element rather than changing myList innerHtml. also when new li created a event listener is added to it.
let counter = 1;
myList.forEach(function(element) {
addListener(element);
});
function addListener(element) {
element.addEventListener("click", function() {
heading.innerHTML = element.innerHTML;
});
}
btn.addEventListener("click", function() {
let newLi = document.createElement("LI");
newLi.innerHTML= "Something New" + counter;
addListener(newLi);
counter ++;
MyList.appendChild(newLi);
});

Appending a link to a li element

I am trying to append an a link to the list items but I am struggling figuring out how to get the a link with the textnode.
So basically I want something along the lines of
<li>Bumble</li>
I have managed to get the li's outputting correctly, I just don't understand how I have the a element as part of the output too.
Here is all the code
//Process the JSON data
function processResponse (){
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText);
console.log(response[1])
//Grab suggestions div from DOM
var suggestions = document.getElementById('suggestions');
//Create new element UL
var list = document.createElement('UL');
//Create new elements for li's
var newLi, newText ;
//For all the text nodes
var textNodes = [];
//For all the li's
var liList = [];
//For all the links
var links = [];
//For loop to add and append all suggestions
for (var i = 0; i < response[1].length; i++) {
links[i] = document.createElement('a');
var setHTML = response[1][i].replace(/\s/g, '_');
var link = 'http://en.wikipedia.org/wiki/'+setHTML;
links[i].href = link;
//Create new text node with the response from api
textNodes[i] = document.createTextNode(response[1][i]);
//Create a new element 'li' into array
liList[i] = document.createElement('li')
//Append the response(textnode) to the li in the array
liList[i].appendChild(textNodes[i]);
//Append the li to the UL
list.appendChild(liList[i]);
}
console.log(links);
//Append the UL to the suggestions DIV
suggestions.appendChild(list);
} else {
alert('There was a problem with the request');
}
}
}
You create the a elements, but you never put them in the li elements. Currently, your code does
//Append the response(textnode) to the li in the array
liList[i].appendChild(textNodes[i]);
Maybe you wanted
//Append the response(textnode) to the a in the array
links[i].appendChild(textNodes[i]);
//Append the a to the li in the array
liList[i].appendChild(links[i]);
for (var i = 0; i < response[1].length; i++) {
links[i] = document.createElement('a');
var setHTML = response[1][i].replace(/\s/g, '_');
var link = 'http://en.wikipedia.org/wiki/'+setHTML;
links[i].href = link;
links[i].text = response[1][i];
//Create new text node with the response from api
//textNodes[i] = document.createTextNode(response[1][i]);
//Create a new element 'li' into array
liList[i] = document.createElement('li')
//Append the response(textnode) to the li in the array
liList[i].appendChild(links[i]);
//Append the li to the UL
list.appendChild(liList[i]);
}
You're close. Append the text node to the link, and append that to the li:
textNodes[i] = document.createTextNode(response[1][i]);
links[i].appendChild(textNodes[i]);
liList[i] = document.createElement('li')
liList[i].appendChild(links[i]);
list.appendChild(liList[i]);

How can i create a submenu using the DOM in javascript

I'm trying to create a submenu, so that when the item on the menu line is clicked then a submenu will appear along with all its values.
I've created a label along with a div to illustate it.
Once the label is clicked, another div needs to produce another list of items, i haven't got a clue how to do this. Please help !!
<script>
var div = document.createElement("div");
var lbl = document.createElement("label");
lbl.innerHTML = "Menu";
div.appendChild(lbl)
btn.onlclick = function() {
var alert = prompt("This button works");
};
The list works but i need to show up when i click on the label
(function() {
var outerUL, li, innerUL, thirdLI, index;
outerUL = document.createElement('ul');
for (index = 0; index < 5; ++index) {
li = document.createElement('li');
li.innerHTML = "SubMenu" + index;
if (index === 2) {
thirdLI = li;
}
outerUL.appendChild(li);
}
innerUL = document.createElement('ul');
for (index = 0; index < 3; ++index) {
li = document.createElement('li');
li.innerHTML = "Subsubmenu #" + index;
innerUL.appendChild(li);
}
thirdLI.appendChild(innerUL);
document.body.appendChild(outerUL);
})();
document.body.appendChild(div);
Any Suggestions ??
Thank you

How do i remove the submenu using a mouseout/mouseleave event handler

I'm trying to create a submenu for a menu item, i have got as far as creating a list of items and using a mouseover event handler but the submenu just remains there. i need it to be removed once the mouse clears away from the submenu div, not the label div. The mouseover function works but the mouseout im having a problem with. I am new to using javascript and DOM
This is the code (DOM):
var creatbtndiv = document.createElement("div");
var creatbtn = document.createElement("button");
creatbtn.innerHTML = "Click Me";
var creatlbl = document.createElement("label");
creatlbl.innerHTML = "Hover Over Me ";
creatbtndiv.appendChild(creatlbl);
creatbtndiv.appendChild(creatbtn);
document.body.appendChild(creatbtndiv);
var list = function () {
var creatDiv = document.createElement("div");
creatDiv.id = "submenudiv";
creatDiv.className = "submenudiv";
var creatul = document.createElement("ul");
for(index = 0; index < 5; ++index){
li = document.createElement("li");
li.className = "list";
li.innerHTML = "Submenu" + index;
creatul.appendChild(li);
}
creatDiv.appendChild(creatul);
document.body.appendChild(creatDiv);
};
//If the cursor hovers over the label, activate this function//
creatlbl.onmouseover = function () {
var alert = confirm("yes master");
list();
};
creatDiv.onmouseout = function(){
var confirm = confirm("the mouse is out");
list.removeChild(creatDiv);
};
creatDiv its outside its scope, so this function does nothing:
creatDiv.onmouseout = function(){
//var confirm = confirm("the mouse is out");
list.removeChild(creatDiv);
};
You could put this function, after:
document.body.appendChild(creatDiv);
creatDiv.onmouseout = function(){
//var confirm = confirm("the mouse is out");
this.parentNode.removeChild(this);
};
The issue is that 'creatDiv' doesn't exist until the mouseover event occurs, and thus triggers the list() function.
You cannot attach the onmouseout event to the nonexistent creatDiv.
Suggested change:
var list = function () {
var creatDiv = document.createElement("div");
creatDiv.id = "submenudiv";
creatDiv.className = "submenudiv";
var creatul = document.createElement("ul");
for(index = 0; index < 5; ++index){
li = document.createElement("li");
li.className = "list";
li.innerHTML = "Submenu" + index;
creatul.appendChild(li);
}
creatDiv.appendChild(creatul);
document.body.appendChild(creatDiv);
creatDiv.onmouseout = function(){
document.body.removeChild( this )
};
};
This will still be not quite right, though, because the div will go away when you mouse between text, but that's another issue.

How the heck do I do string comparison from a list item to the items in an array

I am attempting to take the contents of an individual list items in one UL and when one is clicked add the value of that individual LI to an array and append the text string of the list item to an ordered list item somewhere else on the page.
I am having trouble comparing the string of the clicked LI,iterating through the array to make sure the string of the LI listed once, and then adding the text to the OL. Help appreciated.
var list = $('.list'),
listItem = $('.list li'),
container = $('.list-content ul'),
containerItem = $('.list-items li');
itemArray = [];
listItem.on({
'click' : function(){
var current = $(this),
currentText = $(this).text();
if( itemArray.length <= 0 ) {
itemArray.push(currentText);
$('<li>'+ currentText + '</li>').appendTo(container); //add text to new area
}else{
for( var count = 0; count < itemArray.length; count++){
if( currentText === itemArray[count] ){
return false;
break;
} else {
itemArray.push(currentText);
$('<li>'+ currentText + '</li>').appendTo(container); //add text to new area
break;
}
}
}
}//end of click function
});
You can use $.inArray() to check whether an object is present in an array
this should do
var list = $('.list'),
listItem = $('.list li'),
container = $('.list-content ul'),
containerItem = $('.list-items li'),
itemArray = [];
listItem.on({
'click' : function(){
var current = $(this),
currentText = $(this).text();
if($.inArray(currentText, itemArray) == -1){
itemArray.push(currentText);
$('<li>'+ currentText + '</li>').appendTo(container); //add text to new area
}
}//end of click function
});
Demo: Fiddle

Categories

Resources