Array for li element - javascript

I just finished learning Javascript. Now i am doing some practical test to further sharpen my knowledge. I look for some random practical projects online and i found this site (https://skillcrush.com/2018/06/18/projects-you-can-do-with-javascript/) 9. Build a JavaScript To-Do List.
As i scan the codes, i understand how the flow works but got confused in this particular section:
*Everytime the createListElement() function is triggered, does it create an array of li element?
*How does the delete button created for every 'li' is only associated to work with that specific li element?

The createListElement() function creates a single list element. Here is what it does.
Creates the element.
Adds it to the list.
Adds the strike-through.
Adds the delete button.
The delete button is a child element of the list item. In it's onclick listener, it stores the specific li element that it belongs to. Perhaps more ideal code in that area would look something like this:
function deleteListItem(e) {
e.path[0].parentElement.classList.add("delete")
}
dBtn.addEventListener("click", deleteListItem)
In all onclick events, e.path[0] is the element that was clicked. Since the delete button has no children within it that will also trigger that function, it will always be the delete button. Then, by getting the parent element, it will always be the right list item.

Here is related code:
function createListElement() {
var li = document.createElement("li"); // creates an element "li"
li.appendChild(document.createTextNode(input.value)); //makes text from input field the li text
ul.appendChild(li); //adds li to ul
input.value = ""; //Reset text input
//START STRIKETHROUGH
// because it's in the function, it only adds it for new items
function crossOut() {
li.classList.toggle("done");
}
li.addEventListener("click",crossOut);
//END STRIKETHROUGH
// START ADD DELETE BUTTON
var dBtn = document.createElement("button");
dBtn.appendChild(document.createTextNode("X"));
li.appendChild(dBtn);
dBtn.addEventListener("click", deleteListItem);
// END ADD DELETE BUTTON
//ADD CLASS DELETE (DISPLAY: NONE)
function deleteListItem(){
li.classList.add("delete")
}
//END ADD CLASS DELETE
}
A1: While createListElement triggered, var li = document.createElement("li") would create a single li element, and append to DOM by ul.appendChild(li)
A2: var dBtn = document.createElement("button"); create a button element and append to li element by li.appendChild(dBtn).
dBtn.addEventListener("click", deleteListItem); add a click event to the corresponding button, if button clicked, it would trigger defined deleteListItem function. And in deleteListItem function:
function deleteListItem(){
li.classList.add("delete")
}
li refers to the 'li' element you just created. Thus it would add a delete class to associated li element and hide li.

*Everytime the createListElement() function is triggered, does it create an array of li element?
Close! Think of ul as the parent container of all the li items. In this specific example there is ul already defined globally:
var ul = document.querySelector("ul");
Everytime createListElemet() is triggered it creates a new li element and appends to the existing ul container.
How does the delete button created for every 'li' is only associated
to work with that specific li element?
If you follow the code line at a time -
var dBtn = document.createElement("button"); //create button element
dBtn.appendChild(document.createTextNode("X")); //create text node with text "X" and append to the button element
li.appendChild(dBtn); //append the deleteBtn + text node to the li element. Here is why that specific delete element is associated to that *li* element.

Related

How to append li and div tags to html using javascript dynamically

I am creating a horizontal timeline where the new element needs to be appended as per requirement.
I need to add new li ,div tags to ol dynamically using javascript in below code
This is my html code
<section class="timeline">
<ol>
<li>
<div>
<time>1934</time> mycode
</div>
</li>
</ol>
</section>
I am new to technology.
Could you please help.
What you need can be achieved using those methods from the document object.
1- let container = document.getElementById("YourContainerDiv"); which returns the container div element to append list items (li) to.
2- let listItem = document.createElement("li"); which returns a new element of list item.
3?- listItem.innerText = 'bla bla'; an optional step to populate your list item with data.
4- container.appendChild(listItem); which will add the newly created list item to the parent container element.
In order to dynamically create and append elements we have to use below methods to achieve what we need.
document.createElement()- This method creates the HTML element with the tag name passed as parameter.
example :create a li element:-
var dynamicLi = document.createElement("li");
element.setAttribute()- This method is use to set attribute.
example - add id in the newly create li tag":-
dynamicLI.setAttribute("id","li1");
node.appendChild()- This method append a node to the end of the list of children of a specified parent node.
example - add newly created li tag to its parent ul tag:-
let ul = document.getElementById("dynamic-list"); // we get the parent node
ul.appendChild(li); // we append the li in the ul tag .
So, below is the working code snippet, using step defined above:
let ul = document.getElementById("Ul");
let li = document.createElement("li");
li.setAttribute('id','li1');
ul.appendChild(li);
Use this code.
var ul = document.getElementById("list");
var li = document.createElement("li");
li.appendChild(document.createTextNode("timeline"));
ul.appendChild(li);
for jQuery see this reference :
Javascript to create an li and append to an ol

Getting String Value Of JavaScript Button

I have a list of buttons that is created by the DOM which references an array. When a button in the list is clicked, I want to retrieve the String that is displayed on the Button.
I have tried the following code to reference the string value, but get undefined:
this.String; inside the function when the button is clicked to retreive the string.
How can I properly retrieve the string.
The click handling function is:
$('.timeButtons').click(function() {
confirmation.push(this.textContent);
})
This is how the list of buttons is created:
var populateList=function(array){
var list = document.createElement('ul');
list.className="delete";
for(var i = 0; i < array.length;- i++) {
var item = document.createElement('li');
var itemButton=document.createElement('button');
itemButton.style.cssText='background:#f85a5a; border:none; width:200px; height:50px; margin-bottom:50px; align:center; border-radius:25px; color:#ffffff;'
itemButton.appendChild(document.createTextNode(array[i]));
item.appendChild(itemButton);
list.appendChild(item);
}
return list;
}
Assuming that this is a reference to the button element in question, you can use this.textContent to get the button's text. (Or .innerHTML.)
Demo: http://jsfiddle.net/w0ntsrLx/
Or since in your edited question you seem to be using jQuery, use the .text() method. In a comment you say that the containing div has the "timeButtons" class, so bind a delegated handler to that div as follows:
$(".timeButtons").on("click", "button", function(e) {
confirmation.push($(this).text());
});
Demo: http://jsfiddle.net/w0ntsrLx/1/
That way the function will only be called if the click is on a button element within the .timeButtons div, and this will be the clicked button. The click handler that you show in your question with $(".timeButtons").click(...) is bound to the div and doesn't in any way test for the buttons, so within the handler this will be the div, not the clicked button.
Check this out
Assuming you want pure javascript code,
Whenever an event is triggered, an object is passed back in callback (generally being named as 'event'). this object has many properties including source element, position of click and many more.
get the element using event.srcElement
You can use element.innerHTML or element.innerText to find out the content of the Button.
There is a difference between using innerText and innerHTML, but in your case, both can be used.
Also, you can use jquery too to easily append child, create elements and binding events.

AFUI list dynamically created list element doesn't let me have click events

I am trying to attach a click handler to an element that I create dynamically and add to an li element. When I try to attach it to the li element it doesn't work. But when I try to add it to a higher level div or even the ul element then the click handler works.
This doesn't give me my click event:
var ul = document.createElement('ul');
ul.setAttribute('class','list');
main_div.appendChild(ul);
var li = document.createElement('li');
ul.appendChild(li);
var checkbox = document.createElement('div');
checkbox.setAttribute('class','checkBtn-unselected');
checkbox.onclick = function(){alert('foo');};
li.appendChild(checkbox);
This does give me my click event:
var ul = document.createElement('ul');
ul.setAttribute('class','list');
main_div.appendChild(ul);
var li = document.createElement('li');
ul.appendChild(li);
var checkbox = document.createElement('div');
checkbox.setAttribute('class','checkBtn-unselected');
checkbox.onclick = function(){alert('foo');};
ul.appendChild(checkbox);
I am using intel's App framework/UI as well. I don't know if that may have anything to do with it. Also, in other places I have been able to just write HTML and place my checkbox in it and it seems to work. This is only when I try to create it dynamically does the event handler not run.
your code is good, but the height of checkbox DIV is 0 so your click is not fired, the li has a padding of 20px. I added this and click works:
checkbox.style.height = "40px";
Here is full code: http://jsbin.com/moqoge/7/edit
The problem was that next to my checkbox I had a label. The padding of the label (which had some relative positioning fuzziness) overlapped my button and was intercepting the touch/click events. I changed the css of the label so it didn't overlap my button and now it's working.

addEventListener will not attach a listener to the element

/***************************************************** *
* Function: renderTodos
* Builds a list of todo items from an array
* rebuilds list each time new item is added to array
****************************************************** */
function renderTodos(arr) {
// erases all previous content
uList.innerHTML = '';
for ( var i = 0; i < tdArray.length; i++ ) {
// create a link element
var remex = document.createElement('span');
//link element didn't work so try a button
//var remex = document.createElement('input');
//remex.setAttribute('type','button');
remex.setAttribute('class', 'deletex');
remex.innerHTML="X";
// set attribute index and value
remex.setAttribute('index', i);
remex.addEventListener('click',removeTodo);
console.dir(remex);
// create <li> element
var li_element = document.createElement('li');
li_element.style.lineHeight = "20pt";
li_element.appendChild(remex);
li_element.innerHTML += tdArray[i];
// add item to list
uList.appendChild(li_element);
inField.value = '';
}
} // /renderTodos
This function builds a list based on text field inputs. Each time the the "add item" button is clicked, the event calls this function to add the item to the list. Everything works beautifully UNTIL I try to add the eventListener to the "x" that is appended to the li element prior to the list item text. The idea is that the "x" is clickable, and onClick it removes the list item entry from the list. But I have tried 6 ways to Sunday to attach an eventListener to the "x" object and nothing works. I have tried attaching the event listener to a span object, and a button object; I have moved "remex.addEventListener..." all around in the function, after it has been rendered, before it gets rendered, etc.; I have eliminated the CSS; I have tried changing the addEventListener to onClick; I have tried this code on our own Apache server, I have moved it to jsbin.com in hopes that some server setting was getting in my way; and probably a few more things I can't remember in the long list of things I have tried. As you see, I have tried it as a button and as a span, hence the commented code.
In short, no matter what I try, the eventListener will NOT attach to the "x". Any ideas? Do you need to see more of the code?
This line overrides the attached eventlistener:
li_element.innerHTML += tdArray[i];
Setting innerHTML replaces all the original elements within li_element. += is just a shortcut to li_element.innerHTML = li_element.innerHTML + tdArray[i];
If tdArray[i] contains just some text, you can add its content like this:
li_element.appendChild(document.createTextNode(tdArray[i]));
If tdArray[i] contains elements, you could append a wrapper element, and then set the innerHTML of the wrapper.

jQuery adding elements to parent

I'm having some trouble figuring out how to add elements to a parent object on a click event.
The result that i'm hoping to achieve is this:
<ul>
<li><button>B1</button>
<ul class="newul">
<li><button>B1.1</button>
<ul class="newul">
<li><button>1.1.1</button></li>
<li><button>1.1.2</button></li>
</ul>
</li>
<li><button>B1.1</button></li>
</ul>
</li>
<li><button>B2</button></li>
<li><button>B3</button></li>
</ul>
Let's say I click button B2. I want a new UL added to the parent LI of that button and then be able to add new LI elements to the newly created UL. I hope that makes sense!
So basically, click button, add new UL with class "newul" to the LI you're currently in -> add new LI's to that newly created UL.
The jquery I'm currently using is as follows:
$('button').click(function(){
//Get parent..
var parent = $(this).parent();
//Add a new UL to the parent and save it as newul
var newul = parent.add("ul");
//Add the class to the new UL
newul.addClass('newul');
//Add a new li to the new UL
newli = newul.add('li');
//Add a button to the new LI
newli.append('<button></button>');
});
Unfortunately, this is having completely undesired effects and sticks buttons everywhere all over the place. I'd appreciate any help you can offer.
Here's a visible example of what i'm after. The top part is the effect id like to achieve.
Example of desired result
Even though #am not i am has the correct code. There is no explanation of why your code fails, and I think that's the answer you are asking for.
There are several problems in your code:
First
//Add a new UL to the parent and save it as newul
var newul = parent.add("ul");
The 'ul' is a selector and so is going to search the DOM for other <ul> elements, rather than create a new one. Also, parent.add() method is returning the parent object, not the ul's that you selected.
Correct code:
//Add a new UL to the parent and save it as newul
var newul = $("<ul>").appendTo(parent);
Second:
//Add a new li to the new UL
newli = newul.add('li');
Same problem again, and since newul is actually still the parent you're getting all types of craziness. Also, you're missing a var, but maybe I just don't get your closure.
Correct code:
//Add a new li to the new UL
var newli = $("<li>").appendTo(newul);
That's all. If you fix that in your code, it'll work.
However, unless you really need those references to persist, better performance is usually achieved if you pass the whole thing as a string:
$('button').click( function() {
$(this).parent()
.append(
$('<ul class="newul"><li><button></li></ul>')
);
});
Edit
And if you wanted all the new buttons to have the same functionality, use the on() method and a class for your buttons:
$('body').on('click', 'button.ul-appending', function() {
$(this).parent()
.append(
$('<ul class="newul"><li><button class="ul-appending"></li></ul>')
);
});
You could change the 'body' selector to something much more specific so this doesn't get queried on every click on your page. Just make sure to add the class ul-appending to all the existing buttons that aren't generated by this handler.
JSFiddle
One issue I see here is that the new buttons created will not have the click event bound to them. I fix this by using on and setting the event as a delegate. In doing so I give the outer ul an id of container. I also check to make sure you haven't already added a ul element and append one if it isn't inside the li. Here is a working example.
$('#container').on("click", "button.newbtn", function(){
var parent = $(this).closest('li');
var childUl = parent.children('ul');
if(childUl.length === 0) {
parent.append("<ul class='newul'></ul>");
childUl = parent.children('ul');
}
childUl.append($("<li><button class='newbtn'>" + $(this).html() + "." + (childUl.children().length + 1) + "</button></li>"));
});​
$('button').click(function(){
//Get parent..
var parent = $(this).parent();
//Add a new UL to the parent and save it as newul
var newul = $("<ul/>");
//Add the class to the new UL
newul.addClass('newul');
//Add a new li to the new UL
var newli = $('<li/>');
//Add a button to the new LI
newli.append('<button></button>');
// add ul to parent li
parent.append( newul.append( newli ) );
});
The issue here is that you're using .add() instead of .after().
.add() adds the passed element to the current selection. .after() adds the passed elements after the current selection.
Using .after(), we can simplify your script into a nice little one-liner:
$('button').click(function(){
$(this).after('<ul class="newul"><li><button></button></li></ul>');
});​
Since .after() inserts content next to the current element, there's no need to get the .parent(). .after() can take a complete string of HTML, so there's no need to use jQuery to manipulate the class and add the child elements.
Example.
Use .on function for dynamically added elements.
You can use something like this.
$(document).ready(function(){
i = 1;
$('body').on("click","button",function(event){
$(this).after('<ul class="newul"><li><button>TestButton'+i+'</button></li></ul>');
i++;
});
});
Here is the DEMO. Adjust button with your css and button values accordingly.
​

Categories

Resources