Button that creates a <li> and adds user input on it - javascript

The exercise says that my button (like a submit) must use the information set by user in input tag and create an li tag with the text as content. It was my first JavaScript class, so I'm still not familiarised with the syntax.
This is my actual code. I used a querySelector with the id of my existing ul tag, and addEventListener to create an event for the click action. I can't remember how to properly create the new li tag, and don't know how to use the content as info for it.
let myElement = document.querySelector('#add-book');
myElement.addEventListener("click", (e) => {
if (e.target.classList == 'button-add') {
let liElement = document.createElement('li');
let content = document.appendChild(liElement);
content.textContent();
}
});
I hope the button works properly, and show the element in the page by clicking the button (with the typed information).

Oversimplified, but hey, it works:
function AddLi(str)
{
var li = document.createElement('li');
li.appendChild(document.createTextNode(str))
li.innerHTML += ' <button onclick="this.parentNode.remove()">-</button>';
document.getElementById("out").appendChild(li);
}
<form>
<input type="text" name="userinput">
<input type="button" value="Add LI" onclick="AddLi(userinput.value)">
</form>
<span id="out"/>

I guess this is what you want:
(function () {
document.querySelector('#add').addEventListener('click', function () {
let input = document.querySelector('#text');
let list = document.querySelector('#list');
let item = document.createElement('li'); // create li node
let itemText = document.createTextNode(input.value); // create text node
item.appendChild(itemText); // append text node to li node
list.appendChild(item); // append li node to list
input.value = ""; // clear input
});
})();
<div>
<input id="text" type="text" />
<button id="add">Add</button>
</div>
<ul id="list">
<li>example item</li>
</ul>
But please, in the future, ask more specific questions. I don't even know what your problem is, because you don't provide all your code. Also the last sentence of your question is telling me nothing useful at all (.. "I hope the button works properly, and show the element in the page by clicking the button (with the typed information) " ..).

Try
function addBook(book) {
list.innerHTML +=
`<li>${esc(book.value)} <button onclick="del(this)">Del</button></li>`;
book.value = '';
}
function del(item) {
item.parentNode.remove();
}
function esc(s) {
return s.replace(/[&"<>]/g,c =>
({'&':"&",'"':""",'<': "<",'>':">"}[c]));
}
<ul id="list"></ul>
<input id="data" type="text" />
<button onclick="addBook(data)">Add</button>

Related

adding a date to the items in the list and displaying them on a webpage

I am completely lost on a task where I have to add a date to the items when they are created, store them in a list and then present on my webpage.
my javascript code
var counter=4;
var completelist = document.getElementById("thelist");
var currentTime = new Date();
todo=[todo1,todo2,todo3];
todoButton.onclick=function addelement() {
var userTodoInput = document.getElementById("todoInput");
if(userTodoInput.value!=="" ){
let node = document.createElement("LI");
node.innerHTML = userTodoInput.value;
completelist.appendChild(node);
todo.push(userTodoInput);
document.getElementById("mydiv").innerHTML += "<div class='todo' ><p id='t-list'> You have added this to the list of actions: " + userTodoInput.value + "</p></br></div>";
} else {
alert("Enter something in textarea")
}
counter++;
}
My dom
<div class="todo-container" >
<h1 class="about-heading">The todo list </h1>
<p id="todo-paragraph">On this page you are able to add new items to your to-do list </p>
<div class="todo-items">
<ul id="thelist">
<li class="todo"id="todo1">Item 1</li>
<li class="todo" id="todo2">Item 2</li>
<li class="todo" id="todo3"> Item 3</li>
</ul>
<input id="todoInput" type="text" name="todoInput" placehoder="Type your to-do here">
<button id="todo-button" >Add Item </button>
<div id="mydiv">
</div>
</div>
what would you suggest on this?
The problem is, your todoButton is not defined anywhere in your code.
If you add var todoButton = document.getElementById("todo-button");, your script should be working.
EDIT:
If you want to append date to user input, check edited code below. I stored userTodoInput and currentTime to single variable, named newItem and then place the variable on places you need it. I hope this help.
var counter = 4;
var completelist = document.getElementById("thelist");
var currentTime = new Date();
todo = [todo1, todo2, todo3];
todoButton.onclick = function addelement() {
var userTodoInput = document.getElementById("todoInput");
if (userTodoInput.value !== "") {
let node = document.createElement("LI");
let newItem = `${userTodoInput.value} ${currentTime}`;
node.innerHTML = newItem;
completelist.appendChild(node);
todo.push(newItem);
document.getElementById("mydiv").innerHTML += "<div class='todo' ><p id='t-list'> You have added this to the list of actions: " + newItem + "</p></br></div>";
} else {
alert("Enter something in textarea")
}
counter++;
Take a look to the following commented code. Obviously it is a basic implementation, but I think that main concepts are clear:
// GET ELEMENTS.
const list = document.getElementById('list');
const input = document.getElementById('input');
const button = document.getElementById('button');
const onClickHandler = () => {
// CHECK FOR TO-DO NAME.
if (input.value) {
// USE ELEMENT CHILDREN COUNT AS INDEX.
const index = list.children.length;
// CREATE li ELEMENT PROGRAMMATICALLY.
const li = document.createElement('LI');
// INSTANTIATE A NEW DATE OBJECT.
const date = new Date();
// ADD ATTRIBUTES.
li.id = `todo${index}`;
li.class = 'todo';
li.innerText = `${input.value} - ${date.toString()}`;
// ADD ELEMENT TO DOM.
list.appendChild(li);
} else {
alert('Please type your to-do.')
}
};
// ADD EVENT LISTENER.
button.addEventListener('click', onClickHandler);
<div>
<h1>The todo list</h1>
<p>On this page you are able to add new items to your to-do list</p>
<div>
<ul id="list"></ul>
</div>
<input id="input" type="text" name="todo" placeholder="Type your to-do here">
<button id="button" type="button">Add Item</button>
</div>

remove each li item todo list using on click

I intended to make a todo list but I'm getting a problem that i wanna make a button that come inline in list item like so <li>my task</li><button>Delete</button>
but my delete button isn't deleting items correctly it only deletes one items and then start giving error
this is my code, please look here and also tell me what kind of mistakes I'm doing I'm very beginner in web development
<!DOCTYPE html>
<html>
<body>
<input type="text" placeholder="Enter Task" onfocus="this.value=''" id="myTask">
<button onclick="myFunction()">Try it</button>
<button onclick="deleteTask()">del it</button>
<ol id="myList">
</ol>
<script>
function myFunction() {
var node = document.createElement("LI");
var myTask = document.getElementById("myTask").value;
var textnode = document.createTextNode(myTask);
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);
var btn = document.createElement("input");
var abcElements = document.querySelectorAll('LI');
for (var i = 0; i < abcElements.length; i++){
abcElements[i].id = 'abc-' + i;
}
// node.setAttribute("id", "li1");
btn.setAttribute("type", "submit");
btn.setAttribute("value", "delete");
btn.setAttribute("id", "delete");
node.appendChild(btn);
btn.addEventListener('click', ()=>{
// console.log("OK");
document.getElementById("abc-0").parentNode.removeChild(document.getElementById("abc-0"))
})
}
function deleteTask() {
var i = 0;
var item = document.getElementsByTagName("LI")[i];
i++;
item.parentNode.removeChild(item);
}
</script>
</body>
</html>
So I just want to make a delete button with every list item as I click on Try it button
Some points to address:
Don't call a function myFuntion. Give it a descriptive name, like addTask
Don't create id-attributes with sequential numbers. That is almost never needed.
The initial HTML should not have a delete button, since it should associate with a list item.
Don't make the type of the delete button "submit". That only makes sense when you have a form element, and need to submit the form.
Don't give the created button the same id over and over again: that is invalid in HTML. id-attributes should have unique values. But again, it is rarely needed to assign an id to dynamically generated elements.
In an event listener you can use the event object to get the element on which the event was fired. Or you can use the this object in a function. But you can also reference the node variable that exists in the so-called closure.
function addTask() {
var node = document.createElement("LI");
node.textContent = document.getElementById("myTask").value;
var btn = document.createElement("button");
btn.textContent = "delete";
btn.addEventListener('click', () => node.remove());
node.appendChild(btn);
document.getElementById("myList").appendChild(node);
}
li > button { margin-left: 5px }
<input type="text" placeholder="Enter Task" onfocus="this.value=''" id="myTask">
<button onclick="addTask()">Add task</button>
<ol id="myList"></ol>
try something like this:
function myFunction() {
const li = document.createElement("li");
li.innerHTML = document.getElementById("myTask").value;
const button = document.createElement("button");
button.innerHTML = "delete";
li.appendChild(button);
button.addEventListener("click", () => li.parentNode.removeChild(li));
document.getElementById("myList").appendChild(li);
}

How would I assign each list item a sequential ID in Javascript? (in an html document by the way)

Here is the section which is confusing me:
<script type="text/javascript">
//declaring veriables
var inputField = document.getElementById("input");
var addBtn = document.getElementById("addBtn");
var html = "";
var x = 0;
addBtn.addEventListener('click', function(){
var text = inputField.value;
addToList(text);
})
//adds items to list
function addToList(text){
html += "<li id=(x+=1)><h4><input type='checkbox' id=(x+=1) onclick= 'clearspecifieditems()'>"+text+"</h4></li>";
document.getElementById("myList").innerHTML = html;
inputField.value = "";
}
//clears items
function clearspecifieditems(itemid)
{
//delete selected item
};
So the goal here is to create a to-do list (I'm new to coding). The addToList(text) function is supposed to create a new list item and assign a sequential ID to it. However, I cannot seem to figure out how to have it generate the ID. In addition, clearspecifieditems(itemid) is supposed to get the IDs of all the list items that are checked, and clear all of them.
For the first part of your question either use string concatenation similar to how you added the text variable...
function addToList(text) {
const id = x + 1;
html += '<li id="' + id + '"><h4><input type="checkbox" id="' + id + '">' + text + '</h4></li>';
// ..
}
...or use a template literal:
function addToList(text) {
const id = x + 1;
html += `<li id="${id}"><h4><input type="checkbox" id="${id}" />${text}</h4></li>`;
// ..
}
HOWEVER, for the second part, how to clear checked boxes:
I purposely left the onclick out of the above code because it sounds as if you need a separate button to clear the checkboxes:
// Grab the button and add an click listener to it
// to call `clearSpecifiedItems`
const button = document.querySelector('.clear');
button.addEventListener('click', clearSpecifiedItems, false);
function clearSpecifiedItems() {
// Select all the checked checkboxes using their class
const selected = document.querySelectorAll('.test:checked');
// Set their checked property to false (or null)
selected.forEach(input => input.checked = false);
}
<input class="test" type="checkbox" />
<input class="test" type="checkbox" />
<input class="test" type="checkbox" />
<input class="test" type="checkbox" />
<button class="clear">Clear</button>
Notice that none of these inputs have IDs. I've used a class to pick up the elements instead. So unless you're using the ids for anything else it makes the first part of your code redundant. Just use a CSS selector to grab the elements you need and then process them. No IDs required!
I can see what you're going for. You are almost there. Just a little bit of syntactical error, and a bit of a logical one.
You see, when you increment x two times, You will have a different id for the <li> and the <input>. What I suggest is you increment the x beforehand and then use it.
You can do it like this:
function addToList(text){
x++;
html += "<li id="+ x +"><h4><input type='checkbox' id="+ x +" onclick= 'clearspecifieditems()'>"+text+"</h4></li>";
document.getElementById("myList").innerHTML = html;
inputField.value = "";
}
or this (ES6)
function addToList(text){
x++;
html += `<li id=${x}><h4><input type='checkbox' id=${x} onclick= 'clearspecifieditems()'>${text}</h4></li>`;
document.getElementById("myList").innerHTML = html;
inputField.value = "";
}
Is it absolutely necessary that you must only increment? Can the ID's be truly unique? I suggest you use UUID in that case
Your second question is how to make clearspecifieditems work. Here's what you can do. You can pass the context, or simply the checkbox that was clicked and then get it's ID easily..
So you would define your function something like this:
function clearspecifieditems(element){
//delete selected item
console.log(element.id); // this would give you the ID of the selected checkbox and then you can do whatever with it
};
and slightly modify your function call on the click event
html += "<li id="+ x +"><h4><input type='checkbox' id="+ x +" onclick= 'clearspecifieditems(this)'>"+text+"</h4></li>";
Note this this part.
More more information, See this
Just use string interpolation to reference the x variable and increment it by one every time you add a new item as follows:
/* JavaScript */
var inputField = document.getElementById("input");
var addBtn = document.getElementById("addBtn");
var output = document.getElementById("output");
var html = "";
var x = 0;
function addToList(text) {
output.innerHTML += `<li id=id${x}><h4><input type='checkbox' id=${x}>This list item has an id: id${x}"</h4></li>`;
inputField.value = "";
x++;
}
addBtn.addEventListener('click', function(){
var text = inputField.value;
addToList(text);
})
<!-- HTML -->
<input type="text" id="input" />
<button id="addBtn">Add Items</button>
<div id="output"></div>
And for removing checked elements, simply add another button, say removeBtn and then add a click listener to the button that invokes the clearspecifieditems().
Inside the function, assign a variable to a list of all the checkboxes, loop through the variable using forEach and remove any checkbox that is not checked like this:
function clearspecifieditems() {
var check = document.querySelectorAll('[id^="id"]');
check.forEach(checkBox => {
if(checkBox.children[0].children[0].checked){
checkBox.remove();
}
});
}
removeBtn.addEventListener('click', clearspecifieditems);
#output {list-style: none;}
/* <input type="text" id="input" />
<button id="addBtn">Add Items</button> */
<ul id="output">
<li id="id0"><h4><input type="checkbox" id="input0">This list item has an id: id0"</h4></li>
<li id="id1"><h4><input type="checkbox" id="input1">This list item has an id: id1"</h4></li>
<li id="id2"><h4><input type="checkbox" id="input2">This list item has an id: id2"</h4></li>
<li id="id3"><h4><input type="checkbox" id="input3">This list item has an id: id3"</h4></li>
</ul>
<hr>
<button id="removeBtn">Remove</button>
You're sending X as 1. You should do like this :
var input = document.getElementById("input");
var div = document.getElementById("div");
var button = document.getElementById("addbutton");
var id = 0;
button.onclick = function() {
text = input.value;
addtask(text)
}
function addtask(text) {
var element = document.createElement("li");
element.setAttribute("id", id)
var deleteE = document.createElement("input");
deleteE.setAttribute("type", "checkbox");
deleteE.setAttribute("onclick", "deleteX(" + id + ")");
var node = document.createTextNode(text);
element.appendChild(deleteE);
element.appendChild(node);
div.appendChild(element);
id += 1;
}
function deleteX(id) {
document.getElementById(id).style.visibility = "hidden";
}
<input id="input"> <button id="addbutton"> add </button>
<div id="div"></br> </div>

Adding onclick event on dynamic checkbox

I'm trying to make a 'CRUD' in pure Javascript, it's almost done, the only thing that I need is preparing the inputs with the value of <li>, to do it, I'd like to add an onclick event in a checkbox that is created dynamically in the function insert(), but everytime I click the checkbox nothing happens.
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function(){
btnInsert = document.getElementById("btnInsert");
btnEdit = document.getElementById("btnEdit");
btnDelete = document.getElementById("btnDelete");
vname = document.getElementById("tbName");
ul = document.getElementsByTagName("ul")[0];
btnInsert.onclick = insert;
btnDelete.onclick = remove;
}
function insert(){
li = document.createElement("li");
li.innerHTML = vname.value;
li.innerHTML += " <input type='checkbox' onclick='select()' value='Select' /> Update";
ul.appendChild(li);
vname.value = "";
}
function select(){
alert("Checked");
}
function remove(){
var lis = document.getElementsByTagName("li");
for(i = 0; i<lis.length; i++){
lis[i].onclick = function(){
this.remove();
}
}
}
</script>
</head>
<body>
<label for="tbName">Name: </label>
<input name="tbName" id="tbName"/><br /><br />
<button id="btnInsert">Insert</button>
<button id="btnEdit">Edit</button>
<button id="btnDelete">Delete</button>
<br /><br />
<ul>
</ul>
</body>
</html>
It seems the name select is causing conflict since I could get your code working with the following changes:
HTML
li.innerHTML += " <input type='checkbox' onclick='sel()' value='Select' />Update";
Javascript
function sel(){
alert("Checked");
}
Further tests show that if we log the contents of the function with:
li.innerHTML += " <input type='checkbox' onclick='console.log(select.toString)' value='Select' />Update";
the console shows the following
function select() { [native code] }
So my guess is that select is the name of a function already defined by the browser, hence why you can't use it as a name for your functions.
In short, your code triggers another select function, not the one you defined in your source code.
The OP doesn't want it to fire on the LI, he wants it to fire on the checkbox!
Give your dynamic checkbox an ID value like chkBox1.
Now after you have appended it to the document, you can call it with:
var thechkBox=document.getElementById("chkBox1");
Now you can hit thechkBox with:
thechkBox.addEventListener("click", itfired); //itfired is the script that captures the click event.
That is one of many Events you would then have access to (https://www.w3schools.com/js/js_htmldom_events.asp)!
If you needed the dynamic checkbox to perform a function "on"click!

Transferring iframe value to textarea

I'm making an app that submits posts, but I originally designed it with a textarea in mind, I've since put in an iframe to create a rich text field, set the display style to hidden for the textarea and wanted to know how I could modify it to use the iframe value.
HTML
<div id="textWrap">
<div class="border">
<h1>Start Writing</h1><br />
<input id="title" placeholder="Title (Optional)">
<div id="editBtns">
<button onClick="iBold()">B</button>
<button onClick="iUnderline()">U</button>
<button onClick="iItalic()">I</button>
<button onClick="iHorizontalRule()">HR</button>
<button onClick="iLink()">Link</button>
<button onClick="iUnLink()">Unlink</button>
<button onClick="iImage()">Image</button>
</div>
<textarea id="entry" name="entry" rows="4" cols="50" type="text" maxlength="500" placeholder="Add stuff..."></textarea>
<iframe name="richTextField" id="richTextField"></iframe><br />
<button id="add">Submit</button>
<button id="removeAll" onclick="checkRemoval()">Delete All Entries</button>
<ul id="list"></ul>
<ul id="titleHead"></ul>
</div><!--end of border div-->
</div><!--end of textWrap-->
Here is the JS to submit the posts.
//target all necessary HTML elements
var ul = document.getElementById('list'),
removeAll = document.getElementById('removeAll'),
add = document.getElementById('add');
//richText = document.getElementById('richTextField').value;
//make something happen when clicking on 'submit'
add.onclick = function(){
addLi(ul)
};
//function for adding items
function addLi(targetUl){
var inputText = document.getElementById('entry').value, //grab input text (the new entry)
header = document.getElementById('title').value, //grab title text
li = document.createElement('li'), //create new entry/li inside ul
content = document.createElement('div'),
title = document.createElement('div'),
//textNode = document.createTextNode(inputText + ''), //create new text node and give it the 'entry' text
removeButton = document.createElement('button'); //create button to remove entries
content.setAttribute('class','content')
title.setAttribute('class','title')
content.innerHTML = inputText;
title.innerHTML = header;
if (inputText.split(' ').join(' ').length === 0) {
//check for empty inputs
alert ('No input');
return false;
}
removeButton.className = 'removeMe'; //add class to button for CSS
removeButton.innerHTML = 'Delete'; //add text to the remove button
removeButton.setAttribute('onclick', 'removeMe(this);'); //creates onclick event that triggers when entry is clicked
li.appendChild(title); //add title textnode to created li
li.appendChild(content); //add content textnode to created li
li.appendChild(removeButton); //add Remove button to created li
targetUl.appendChild(li); //add constructed li to the ul
}
//function to remove entries
function removeMe(item){
var deleteConfirm = confirm('Are you sure you want to delete this entry?');
if (deleteConfirm){var parent = item.parentElement;
parent.parentElement.removeChild(parent)}
};
function checkRemoval(){
var entryConfirm = confirm('Are you sure you want to delete all entries?');
if (entryConfirm){
ul.innerHTML = '';
}
};
demo I'm working on for reference.. http://codepen.io/Zancrash/pen/VemMxz
you can use either local storage for passing iframe values to the parent DOM.
or ( use this to pass value from iframe to parent container )
var iFrameValue = $('#iframe').get(0).contentWindow.myLocalFunction();
var iFrameValue = $('#iframe').get(0).contentWindow.myLocalVariable;
From IFrame html
<script type="text/javascript">
var myLocalVariable = "text";
function myLocalFunction () {
return "text";
}
</script>

Categories

Resources