Can't append Button element to li parent - javascript

I'm trying to append a button into a li item with the .appendChild method, but it doesn't work. I also tried altering the parent's inner HTML.
let inputElement = document.querySelector('#input');
let listItem = document.createElement('li');
listItem.className = 'todo-item'
let checkButton = document.createElement('button');
checkButton.className = 'checkButton'
//? When adding the child element, it is only added after the text content is defined.
listItem.appendChild(checkButton);
listItem.textContent = inputElement.value;
<div class="app">
<div class="list">
<h1> My Todo List </h1>
<ul class="todo-list" id="list">
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
</ul>
<input id="input" class="list-input" type="text" placeholder="Next I need to...">
</div>
</div>
Here's the current result
If I modify the order in which the child is appended, the button DOES show up but it's not the best result
//? When adding the child element, it is only added after the text content is defined.
listItem.textContent = inputElement.value;
listItem.appendChild(checkButton);

Setting the textContent property will reset the whole li element, thus removes the previously added button, try with insertAdjacentHTML().
The insertAdjacentHTML() method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position. It does not reparse the element it is being used on, and thus it does not corrupt the existing elements inside that element.
let inputElement = document.querySelector('#input');
let listItem = document.createElement('li');
listItem.className = 'todo-item'
let checkButton = document.createElement('button');
checkButton.className = 'checkButton'
listItem.appendChild(checkButton);
listItem.insertAdjacentHTML('beforeend',inputElement.value);
document.querySelector('#list').appendChild(listItem);
<div class="app">
<div class="list">
<h1> My Todo List </h1>
<ul class="todo-list" id="list">
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
</ul>
<input id="input" class="list-input" type="text" placeholder="Next I need to...">
</div>
</div>

First do not be so greedy with the ";" signs ;)
This happens cause the whole thing is wrong :)
Look, This would and will work perfectly in plain html:
<ul>
<li><input type="radio" name="gender" value="male"> Male</li>
<li><input type="radio" name="gender" value="female"> Female</li>
<li><input type="radio" name="gender" value="other"> Other </li>
....
</ul>
And now we do exactly the same in Javascript.
var ipb=document.createElement("INPUT") //Not button ! Forget that this
// button tag
// even exists
ipb.setAttribute("id","ibp_0"); //always a good idea
ipb.setAttribute("name","gender"); //if its inside a form you want to use
//and a must have for radio buttons *)'
ipb.setAttribute("type","radio");// or checkbutton or input - what you
// want for a input type
ipb.setAttribute("value","male");
var txt = document.createTextNode("Male");
ipb.appendChild(txt);
// and now you can
LIST.appendChild(ipb); //the formaly created <UL> Node for sure
As you can see its the same thing like writing the html version just in a different syntax. There is no magic thing in behind which will do something for you.
The text node is not a perfect idea. I would use a label for that. Or a additional Label.
A label has a "FOR" attribute which i really suggest to use if you go that way.
But this typing i let up to ou :) Have fun !
*) radio buttons. They know that they belong together by the name.

You've created the element, for listItem but you've never actually added it to the DOM.
You need to append or insert the listItem before you try to add the checkbox.

Related

Hw do I clck the add btn and it display the info in the input field and display it n a <p> created with JS. (no inline JS)

Im trying to take the user input and add it to the page with the click of the button and add it to the page in a new paragraph element created thru javascript, I didn't want to use any inline javascript and I wanted to use as little html as possible and do it mainly thru javascript.
<body>
<div class="input">
<form>
<input id="input" type="text" placeholder="Enter task to do..." />
<button id="add_btn">Add</button>
</form>
</div>
<div class="task_list">
<ul id="todo">
<li></li>
</ul>
</div>
<script>
//take user input and add it to the page as a task to do
let div = document.querySelector('.task_list');
let input = document.querySelector('#input')
let pElement = document.createElement('p');
let add = document.getElementById('add_btn');
div.appendChild(pElement);
add.addEventListener(onclick, function (){
input.value;
pElement.innerHTML = input;
console.log(add);
});
</script>
You've got some problems with your code:
You're wrongly binding the event listener. You should use 'click' instead of onclick (which isn't defined anyway).
You didn't define any button type, so the button is treated as submit button, by default. Add type="button" attribute so that the page doesn't refresh on clicking on it.
In the event listener, you should create a fresh p element always, and assign its textContent with input.value (unless you're dealing with HTML content, in which case, innerHTML would be appropriate).
The following snippet makes the code work. Not sure what end result should be like (e.g. you may want to append the list items in ul), but this can get you on track.
//take user input and add it to the page as a task to do
let div = document.querySelector('.task_list');
let input = document.querySelector('#input')
let add = document.getElementById('add_btn');
add.addEventListener('click', function() {
let pElement = document.createElement('p');
pElement.textContent = input.value;
div.appendChild(pElement);
});
<div class="input">
<form>
<input id="input" type="text" placeholder="Enter task to do...">
<button type="button" id="add_btn">Add</button>
</form>
</div>
<div class="task_list">
<ul id="todo">
<li></li>
</ul>
</div>

Getting text content of a div element excluding its children

I have the following HTML code and I need to console.log only Shipping.
I tried a few methods but can't seem to get it to work.
I tried selecting first its children and printing out the textContent of its parent - no go. I could delete its children and print out what's left but I can't do that.
Any suggestions?
<div class="accordion shadowed-box shipping collapsed summary">
<fieldset>
<legend>
Shipping
<div id="shippingTooltip" class="form-field-tooltip cvnship-tip" role="tooltip">
<span class="tooltip">
<div class="tooltip-content" data-layout="small tooltip-cvn">
<div id="cart-checkout-shipping-tooltip" class="html-slot-container">
<p>We ship UPS, FedEx and/or USPS Priority Mail.<br>
<a class="dialogify" data-dlg-options="{"height":200}" href="https://www.payless.com/customer-service/ordering-and-shipping/cs-ordering-shipping-schedule.html" title="shipping information">Learn more about our shipping methods and prices.</a>
</p>
</div>
</div>
</span>
</div>
Edit
</legend>
</fieldset>
</div>
I tried this:
var accordionChildren = document.querySelector('.accordion.shadowed-box.shipping>fieldset>legend *');//selects the first child
var accordionTitle = accordionChildren.parentElement;
var text = accordionTitle.textContent;
console.log(text);
I want to get Shipping but instead I get still all the text contents of the legend element.
you can access Text nodes by iterating over the child nodes (or access the intended node directly) of the accordionTitle variable.
let textNode = accordionTitle.childNodes[0],
text = textNode.textContent;
console.log(text);
See https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes and https://developer.mozilla.org/en-US/docs/Web/API/Text
You just need to find the TextNode child from all of the elements children, you do this by iterating over all of the childNodes and when the node type matches TextNode, return its textContext.
For a jQuery based solution on how to pick the TextNode child of an element see this question - but my example shows how to do it in vanilla ES (with a for loop over childNodes):
Object.defineProperty(HTMLElement.prototype, 'onlyTextContent', {
enumerable: false,
configurable: false,
get: function() {
for(let i = 0; i < this.childNodes.length; i++) {
if(this.childNodes[i].nodeType === Node.TEXT_NODE) {
return this.childNodes[i].textContent.trim();
}
}
return null;
}
});
document.addEventListener('DOMContentLoaded', function() {
console.log(
document.getElementById('legend1').onlyTextContent
);
});
<div class="accordion shadowed-box shipping collapsed summary">
<fieldset>
<legend id="legend1">
Shipping
<div id="shippingTooltip" class="form-field-tooltip cvnship-tip" role="tooltip">
<span class="tooltip">
<div class="tooltip-content" data-layout="small tooltip-cvn">
<div id="cart-checkout-shipping-tooltip" class="html-slot-container">
<p>We ship UPS, FedEx and/or USPS Priority Mail.<br>
<a class="dialogify" data-dlg-options="{"height":200}" href="https://www.payless.com/customer-service/ordering-and-shipping/cs-ordering-shipping-schedule.html" title="shipping information">Learn more about our shipping methods and prices.</a>
</p>
</div>
</div>
</span>
</div>
Edit
</legend>
</fieldset>
</div>
You can get the contents of the <legend> tag as a string and then use a regular expression to remove the HTML tags and their content inside. Like this:
let legends = document.querySelector('.accordion.shadowed-box.shipping>fieldset>legend');
let title = legends.innerHTML.replace(/<.*/s, '');
// title = "Shipping"
The regular expression matches the first < character and everything that follows. So we replace that match with an empty string ''.

How to remove an attribute from an HTML element

<ol>
<li id="ItsMyKitchen">It's My Kitchen</li>
<div id="mykitchen" hidden>
<img src="images/image1.jpg" height="200px" width="200px"/>
<ul>
<li>Pizza</li>
<li>Camorised Oinon rice</li>
<li>Jollof</li>
<li>Banku with Okor</li>
<li>Fufu</li>
<li>Spanish Omellet</li>
<li>Fried Rice with Beef</li>
<li>Steamed Rice with Curry Chicken</li>
<li>Yong Chow Fried Rice </li>
</ul>
</div>
i want to remove the "hidden" attribute from the div element that has "mykitchen" as the id. Am using this javascript code
var ItsMyKitchen1 = document.getElementById("ItsMyKitchen");
ItsMyKitchen1.onclick = function(){
document.getElementById("myKitchen").removeAttribute("hidden");
}
but it seems not to be working. any help
You've created your div with id mykitchen, but when you try to get the element by id, you're trying to select a div with id myKitchen. Try making those two match, and then your code should work as expected.
Your use of element.removeAttribute is correct, but capitalization matters for element ids!
You can try this way.
document.getElementById("mykitchen").addEventListener("load", myFunction);
function myFunction() {
document.getElementById("mykitchen").removeAttribute("hidden");
}

Why is eventListener not being added?

I have code here in a todo list that can add and delete tasks. I'm trying to implement code to edit tasks after they are added by double clicking. Right now the code should just log to the console after double clicking the LI element but it's not doing anything.
newTodoInput.addEventListener('keyup', function addTodoController(event){
if ( event.keyCode === 13){
if ( newTodoInput.value !== '' ){
var newTask = todos.addTaskToList(newTodoInput.value.trim(), todos.taskList);
var clone = templateContent.cloneNode(true);
clone.querySelector("label").appendChild(document.createTextNode(newTodoInput.value.trim()));
todoList.appendChild(clone);
newTodoInput.value = '';
deletingTasks();
editingTasks();
}
}
}); // END addEventListener(addTodoController)
function deletingTasks() {
var deleteTaskButtons = document.querySelectorAll('button.destroy');
_.last(deleteTaskButtons).addEventListener('click', function removeLi(){
//console.log(event.target.parentNode.parentNode.parentNode);
event.target.parentNode.parentNode.parentNode.removeChild(event.target.parentNode.parentNode);
todos.deleteTask(_.indexOf(deleteTaskButtons, event.target), todos.taskList);
});
}
function editingTasks(){
var editTask = document.querySelectorAll('li');
_.last(editTask).addEventListener('dblclick', function taskEdit(){
console.log("Edit this task!");
});
}
I'm invoking the editingTasks function every time a task is added just like I did with the deleting tasks function so that the event listeners will be added to each li element as it's added but I'm not getting anything. Any pointers to why this code doesn't work? Here's the HTML if needed:
<ul class="todo-list">
<!-- These are here just to show the structure of the list items -->
<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
<template id='newtasktemplate'>
<li>
<div class="view">
<input class="toggle" type="checkbox">
<label class="tasking"></label>
<button class="destroy"></button>
</div>
<input class="edit" value="Rule the web">
</li>
</template>
</ul>
It seems likely that your code that does:
var editTask = document.querySelectorAll('li');
_.last(deleteTaskButtons).addEventListener(...)
may not be selecting the right <li> tag. My suggestion is to change your template to add a unique class name to the <li> tag as in:
<li class="myListItem">
And, then change your code to this:
var editTask = document.querySelectorAll('.myListItem');
_.last(deleteTaskButtons).addEventListener(...)

Am using Push() array was used am trying to use for select a list from drop down menu and post that list into a span?

HTML section
div to show the values
<div class="lef rightCol n">
<span class="para"> add-on Services(Optional)</span>
<div class="new">
<ul>
</ul>
</div>
</div
div that contain drop down
<div class="rightCol n mar ">
<span id="at1" class="spn">Click here to add add-on Services</span>
<ul id="ad1" class="drpdwn">
<li><input type="checkbox" id="ck1" value="1"><a id="a1">Drop Shadows</a></
li>
<li><input type="checkbox" id="ck2" value="2"><a id="a2">Reflections</a> <
li>
<li><input type="checkbox" id="ck3" value="6">General Spotting</a></li>
</ul>
I have tried this slide down while click
jQuery
slide down while click at1(Span)
this is the try for show on span on new div
here where should i use Push() most of them force me to use i don't know how and for what
var ots = [];
$('#at1,#at2,#at3,#at4,#at5,#at6').click(function(){
$(this).next('.drpdwn').stop().slideToggle();
}),
$('#ck1').click(function()
{
option=$('#a1').text();
$('.new ul').append('<li><span id="span1" alt="1" ></span></li>');
$('#span1').html(option).addClass('surr');
ots.push({id: 1});
}),
$('#ck2').click(function()
{
option=$('#a2').text();
$('.new ul').append('<li><span id="span2" alt="1" ></span></li>');
$('#span1').html(option).addClass('surr');
ots.push({id: 2});
}),
now i moved some value to array ots while append now the question is how to retrieve the newly created span's alt atrribute using array..?am using like these its not working clearly
some function
var f = $('.new span').length;
ad=o;
cs=o;
for(i=1;i<=f;i++)
{
$.each(this.opt, function() {
$.each(this, function(name, value) {
cs=eval($( "#span"+value).attr("alt"));
console.log(name + '=' + value);
ad+=cs;
console.log("ad: "+ad);
})
})
}
it shows ad as Nan and every time i click those id's it created like 1 then 1,2 then 1,2,3 like this help me out every time select check box it plays like this.!
push method is used to add new item in an array...so in your code push() was obivously used to push items to array(though i cannot find push methods in your question...so wouldn't be able to explain in your case)
docs
ex:
var sports = ["soccer", "baseball"];
sports.push("football", "swimming");

Categories