How can I get add__deal__btn and do something with it?
When page loads, it does't exist and i can't get it, but after adding it how can i get it?
let addTitle = document.querySelector('.add__title');
let addBtn = document.querySelector('.add__btn');
let tasks = document.querySelector('.tasks');
let addDealBtn = [];
addBtn.onclick = function() {
let task = document.createElement('div');
task.className = 'task__card';
let taskTitle = document.createElement("h4");
taskTitle.innerHTML = addTitle.value
task.appendChild(taskTitle)
addDealBtn = document.createElement("button");
addDealBtn.className = "add__deal__btn";
addDealBtn.innerHTML = "Add deal";
task.appendChild(addDealBtn);
tasks.append(task);
}
<div class="add">
<input type="text" class="add__title">
<br>
<button class="add__btn">Add</button>
</div>
<div class="tasks"></div>
Thanks
After you have clicked on .add__btn:
let addBtn = document.querySelector('.add__btn');
addBtn.click(); // <= A computational click standing in for a user click
you can grab add__deal__btn using:
const addDealBtn = document.getElementsByClassName('add__deal__btn')[0];
Use document.getElementsByClassName to select elements on the page that have a given class applied to them. This returns an array. Then get the first item in the array (or, whichever one you want) using brackets:
document.getElementsByClassName("add__btn")[0]
Related
I am trying to add delete button to each item in a list. Adding them works as long as I do not have the delete button.
const newcontainer = document.getElementById("toDoContainers");
//gets number of list items in todolist
//adds list item to list
function deleteitem(paramitem){
var element = document.getElementById(paramitem);
element.remove(paramitem);
}
function addnew(){
let numb = document.getElementById("todolistitems").childElementCount;
var listitem = document.createElement("li");
var reallist = document.getElementById("todolistitems");
var inputvar = document.getElementById("inputfield").value;
var node = document.createTextNode(inputvar);
let numbvar = numb +1;
listitem.appendChild(node);
listitem.setAttribute('id', numbvar);
listitem.addEventListener('onClick', deleteitem(listitem));
reallist.appendChild(listitem);
var inputvar = document.getElementById("inputfield").value="";
// node.appendChild(document.createTextNode(inputvar));
/// document.getElementById("toDoContainers").innerHTML=inputvar;
}
<h1>To Do List</h1>
<div class="container">
<input id="inputfield" type="text"><button id="addToDo" onclick="addnew()">Add</button>
<div class="tO" id="toDoContainers">
<ul id="todolistitems">
</ul>
</div>
</div>
I tried a thing where on each list item created, you can 'onclick'=deleteitem(item). I have tried using queryselector, getelementbyId, and queryselectorall in the delete function.
Adding list items works as long as I do not try adding the delete functionality.
There's a few errors in your code.
You've used 'onClick' instead of 'click' for the click event
Your click event assignment is actually running or interpreting the remove function and attempting to use the return value of the function as the click function.
You've also passed in the list item HTML element as opposed to the ID, which the function requires. This function then tries to use the element itself to find the element and then remove a child element with the same parameter - this will always return undefined.
You need to wrap this in another function that returns the function to be performed on click, and fix that error, as below:
const newcontainer = document.getElementById("toDoContainers");
//gets number of list items in todolist
//adds list item to list
function deleteitem(paramitem) {
var element = document.getElementById("list" + paramitem);
element.remove();
}
function addnew() {
let numb = document.getElementById("todolistitems").childElementCount;
var listitem = document.createElement("li");
var reallist = document.getElementById("todolistitems");
var inputvar = document.getElementById("inputfield").value;
var node = document.createTextNode(inputvar);
let numbvar = numb + 1;
listitem.appendChild(node);
listitem.setAttribute("id", "list" + numbvar);
listitem.addEventListener("click", function () {
deleteitem(numbvar);
});
reallist.appendChild(listitem);
var inputvar = (document.getElementById("inputfield").value = "");
// node.appendChild(document.createTextNode(inputvar));
/// document.getElementById("toDoContainers").innerHTML=inputvar;
}
<h1>To Do List</h1>
<div class="container">
<input id="inputfield" type="text"><button id="addToDo" onclick="addnew()">Add</button>
<div class="tO" id="toDoContainers">
<ul id="todolistitems">
</ul>
</div>
</div>
I'm trying to capture the input of a textarea and converting it to an array but it is reading the whole input as one element and making array of length 1.
<html>
<textarea id="area"></textarea>
<input type="submit" onclick="won()">
<p id="one" style="display: none;"></p>
</html>
The js part displays a message of the length of the array.
var area = document.getElementById("area");
var lines = area.value.split("\n");
var pa = document.getElementById("one");
function won() {
pa.style.display = "block";
pa.innerHTML = lines.length;
}
What I'm trying to achieve with the whole thing is that. The multi line input is to be converted into an array with each new line being a new element. Then I loop through the array and if even one element doesn't pass a validation function, an exception message is displayed under the texarea.
Can someone kindly help me with this?
With your snippet, you're grabbing the value onload so it would be empty, it should be in the event where you grab the value. Also avoid inline event triggering, add the event via js.
var area = document.getElementById("area");
var button = document.getElementById("btn-submit");
var one = document.getElementById("one");
button.addEventListener('click', () => {
// get value
var lines = area.value.split("\n");
one.style.display = "block";
one.innerHTML = lines.length;
})
<textarea id="area"></textarea>
<button type="button" id="btn-submit">Submit</button>
<p id="one" style="display: none;"></p>
What I'm trying to achieve with the whole thing is that. The multi
line input is to be converted into an array with each new line being a
new element. Then I loop through the array and if even one element
doesn't pass a validation function, an exception message is displayed
under the texarea.
const area = document.getElementById("area");
const button = document.getElementById("btn-submit");
const error = document.getElementById("error");
const items = document.getElementById("items");
button.addEventListener('click', () => {
// get textarea value, remove emptys
const lines = area.value.split("\n").filter(Boolean);
// reset error and items dom
error.innerHTML = items.innerHTML = ''
// do your validation, could loop or use .some(), .includes()
if (!lines.length) {
error.innerHTML = 'Enter at least one item'
} else if (!lines.includes('cat')) {
error.innerHTML = 'Entered lines should include at least one cat'
} else {
// no errors
items.innerHTML = `${lines.length} items<br><ul><li>${lines.join('</li><li>')}</li></ul>`
}
})
<textarea id="area"></textarea>
<button type="button" id="btn-submit">Submit</button>
<div id="error"></div>
<div id="items"></div>
Simply put your line var lines = area.value.split("\n"); under the won function like below and you will get your total lines.
Example
var area = document.getElementById("area");
var pa = document.getElementById("one");
function won() {
var lines = area.value.split("\n");
pa.style.display = "block";
pa.innerHTML = lines.length;
}
You can check it here too, https://codepen.io/vadera-abhijeet/pen/yLPxLRY
I have a problem in Javascript.I am adding new list items to the 'ul' elements and this list is empty at first and I do not want to add same values twice. When I write the if statement I get the exception because my list is empty so the result return null.
How can I fix this this problem?
Thank you in advance...
Html Codes
<input type="text" id="the-filter" placeholder="Search For..." />
<div class="list-container">
<ul id="myList"></ul>
<button id="button">Click</button>
Javascript Codes
let newlist = document.querySelector("#myList");
const li = document.getElementsByClassName('list-group-item');
const button = document.getElementById("button");
const button.addEventListener('click' , listName);
const input = document.getElementById("the-filter");
function listName()
const inputVal = input.value;
for (i = 0; i < li.length; i++) {
if ((li[i].innerHTML.toLocaleLowerCase().includes(inputVal) && inputVal!="") ||
(li[i].innerHTML.toUpperCase().includes(inputVal) && inputVal!="")) {
let newItem = document.createElement("li");
li[i].classList.add("list-group-item");
let textnode = document.createTextNode(li[i].innerHTML.toLocaleLowerCase());
newItem.appendChild(textnode);
if((newlist.children[0].innerHTML.toLocaleLowerCase().includes(inputVal))){
newlist.insertBefore(newItem, newlist.childNodes[0]);
}
}
}
}
If I understood the task correct, you need to add items to the list by button click.
If same item exists (case insensitive), then nothing happens.
const list = document.querySelector("#myList");
const button = document.getElementById("button");
button.addEventListener("click", listName);
const input = document.getElementById("the-filter");
function listName() {
const inputVal = input.value;
const [...lis] = document.getElementsByClassName("list-group-item");
const same = lis.find((el) => el.textContent.toLowerCase() === inputVal.toLowerCase());
if (same) {
return;
}
let newItem = document.createElement("li");
newItem.classList.add("list-group-item");
newItem.textContent = inputVal;
list.appendChild(newItem)
}
<input type="text" id="the-filter" placeholder="Search For..." />
<div class="list-container">
<ul id="myList"></ul>
<button id="button">Click</button>
</div>
You're on the right track with event listeners and element creation, but your original code didn't quite seem to match your stated goal.
Here's a solution you might find useful, with some explanatory comments:
// Identifies some DOM elements
const
input = document.getElementById("my-input"),
newList = document.getElementById("my-list"),
items = document.getElementsByClassName('list-group-item'),
button = document.getElementById("my-button");
// Focuses input, and calls addItem on button-click
input.focus();
button.addEventListener('click', addItem);
// Defines the listener function
function addItem(){
// Trims whitespace and sets string to lowerCase
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
// Clears and refocuses input
input.value = "";
input.focus();
// Ignores empty input
if (!inputTrimmedLower) { return; }
// Ignores value if a list item matches it
for (const li of items) {
const liTrimmedLower = li.textContent.trim().toLocaleLowerCase();
if (liTrimmedLower === inputTrimmedLower) {
console.log(`${inputTrimmedLower} is already listed`);
return;
}
}
// If we got this far, we want to add the new item
let newItem = document.createElement("li");
newItem.classList.add("list-group-item");
newItem.append(inputTrimmedLower); // Keeps lowerCase, as your original code
newList.prepend(newItem); // More modern method than `insertBefore()`
}
<input id="my-input" />
<ul id="my-list"></ul>
<button id="my-button">Click</button>
I'm building a todo app and I use a function to create a list item entered by the user.
There is an event listener added to the output section to listen for a delete button click for each item displayed. My problem is that the delete button is only working for one item and then it stops working.
In the console, it appears that the function is actually called every time I press the button, but the functionality only works for one click. Do I need to add all the list items into an array perhaps?
const todo = document.getElementById('todo');
const enter = document.getElementById('enter');
const output = document.getElementById('output');
enter.addEventListener('click', () => {
listItem(todo);
});
let createListItem;
var deleteBtn;
let checkBtn;
function listItem(todo) {
createListItem = document.createElement('li');
createListItem.innerText = todo.value;
todo.value = '';
output.appendChild(createListItem);
checkBtn = document.createElement('button');
deleteBtn = document.createElement('button');
checkBtn.innerText = 'check';
deleteBtn.innerText = 'delete';
createListItem.append(checkBtn);
createListItem.append(deleteBtn);
checkBtn.classList.add('checkBtn');
deleteBtn.classList.add('deleteBtn');
}
output.addEventListener('click', deleteFunc);
function deleteFunc() {
console.log('function called');
createListItem.remove();
}
<section class="controls">
<div>
<label for="todo">Enter a to-do</label>
<input type="text" name="todo" id="todo">
</div>
<span>
<button id="enter" class = "enter"><i class="fas fa-paper-plane"></i></button>
</span>
</section>
<section>
<ul id="output" class="output">
</ul>
</section>
You need to delegate and use relative addressing because your code only removes the LAST added LI
The variable createListItem pollutes the global scope. Add the keyword var or let in the listItem function too
function deleteFunc(e) {
console.log('function called');
const tgt = e.target;
if (e.target.innerText==="delete") tgt.closest("li").remove()
}
Added benefit from this delegation is that adding the functionality to the "check" button is just
if (e.target.innerText==="check") ...
I would recommend to use a class and testing
if (e.target.classList.contains("delete")
instead of the innerText - especially if you want to change language of the button
const todo = document.getElementById('todo');
const enter = document.getElementById('enter');
const output = document.getElementById('output');
enter.addEventListener('click', () => {
listItem(todo);
});
let createListItem;
var deleteBtn;
let checkBtn;
function listItem(todo) {
let createListItem = document.createElement('li'); // use let or var here
createListItem.innerText = todo.value;
todo.value = '';
output.appendChild(createListItem);
checkBtn = document.createElement('button');
deleteBtn = document.createElement('button');
checkBtn.innerText = 'check';
deleteBtn.innerText = 'delete';
createListItem.append(checkBtn);
createListItem.append(deleteBtn);
checkBtn.classList.add('checkBtn');
deleteBtn.classList.add('deleteBtn');
}
output.addEventListener('click', deleteFunc);
function deleteFunc(e) {
console.log('function called');
const tgt = e.target;
if (e.target.innerText==="delete") tgt.closest("li").remove()
}
<section class="controls">
<div>
<label for="todo">Enter a to-do</label>
<input type="text" name="todo" id="todo">
</div>
<span>
<button id="enter" class = "enter"><i class="fas fa-paper-plane"></i></button>
</span>
</section>
<section>
<ul id="output" class="output">
</ul>
</section>
Your createListItem variable is a global that gets set to the most-recently appended item, so the delete function will always delete the most-recent item. Once an element el has already been removed from the DOM tree, el.remove() is a no-op, so it only works once.
To fix, you can either use event delegation as in #mplungjan's answer or assign a unique id to each list item and pass that as a parameter to the function to determine what to delete.
Example of the second approach:
<ul>
<li id="item-0"></li>
<li id="item-1"></li>
<li id="item-2"></li>
</ul>
const deleteById = id => document.querySelector(`#item-${id}`).remove()
First though:
I think os because you are targeting the "ul" instead the "li" elements. Try adding the event listeners to each "li" element with a querySelectorAll() instead of targeting "output" directly.
When you add another item, you call listItem() which sets a new value to createListItem. This means, when you call deleteFunc(), createListItem.remove(); is only executed on the last element you have added. If this item was already removed, your out of luck as well.
function deleteFunc(e) {
console.log('function called');
const { target } = e; // get target
target.closest("li").remove()
}
Remove the listener on output. (This line: output.addEventListener('click', deleteFunc);)
And add the listener to each deleteBtn:
checkBtn.classList.add('checkBtn');
deleteBtn.classList.add('deleteBtn');
deleteBtn.addEventListener('click', deleteFunc);
This might help you:
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
Find the solution.
const todo = document.getElementById('todo');
const enter = document.getElementById('enter');
const output = document.getElementById('output');
enter.addEventListener('click', () => {
listItem(todo);
});
let createListItem;
var deleteBtn;
let checkBtn;
var index = 0;
function listItem(todo) {
createListItem = document.createElement('li');
createListItem.innerText = todo.value;
createListItem.id= 'li' + index;
todo.value = '';
output.appendChild(createListItem);
checkBtn = document.createElement('button');
deleteBtn = document.createElement('button');
checkBtn.innerText = 'check';
deleteBtn.innerText = 'delete';
deleteBtn.id = 'btn' + index;
createListItem.append(checkBtn);
createListItem.append(deleteBtn);
checkBtn.classList.add('checkBtn');
deleteBtn.classList.add('deleteBtn');
deleteBtn.onclick = function() { deleteFunc(this); };
index += 1;
}
//output.addEventListener('click', deleteFunc);
function deleteFunc(e) {
var rowId = e.id.replace('btn','');
var row = document.getElementById('li'+rowId);
console.log('function called' + rowId);
//alert(rowId);
if (row != null) {
row.remove();
}
//console.log('function called');
//createListItem.remove();
}
<section class="controls">
<div>
<label for="todo">Enter a to-do</label>
<input type="text" name="todo" id="todo">
</div>
<span>
<button id="enter" class = "enter"><i class="fas fa-paper-plane"></i></button>
</span>
</section>
<section>
<ul id="output" class="output">
</ul>
</section>
I'm building a small to do list and everything worked fine so far until I included a checkbox. now when I click on the button, nothing happens and neither do I see a checkbox. There must be something wrong with the order of code-does someone know how I need to rearrange the code and WHY?
Html code:
<body>
<h1>To Do List</h1>
<p><input type="text" id="textItem"/><button id="add">Add</button></p>
<ul id="todoList">
</ul>
</body>
Javascript code:
function addItem() {
var entry = document.createElement("li");
var checkBox = document.getElementById("input");
checkBox.type = "checkbox";
var span = document.createElement("span");
span.innerText = entry;
var textItem = document.getElementById("textItem");
entry.innerText = textItem.value;
var location = document.getElementById("todoList");
entry.appendChild(checkBox);
entry.appendChild(span);
location.appendChild(entry);
}
var item = document.getElementById("add");
item.onclick = addItem;
UPDATED - I've spotted 4 issues . Follow Below :
1st : When you create the check box you should be using setAttribute method to specify input type : checkbox.setAttribute("type" , "checkbox")
2nd : Your checkbox variable should be creating an input element : var checkBox = document.createElement("input");
3rd : You should be using innerHtml instead of innerText as you are referencing a list ELEMENT stored in your entry variable : span.innerHtml = entry;
4th: Really minor but you should grab your item and attach an event to the item before your function :
var item = document.getElementById("add");
item.addEventListener("click" , addItem)
Just change your javascript to the following :
var item = document.getElementById("add");
item.addEventListener("click" , addItem)
function addItem() {
var entry = document.createElement("li");
var checkBox = document.createElement("input");
checkBox.setAttribute("type" , "checkbox");
var span = document.createElement("span");
span.innerHtml = entry;
var textItem = document.getElementById("textItem");
entry.innerText = textItem.value;
var location = document.getElementById("todoList");
entry.appendChild(checkBox);
entry.appendChild(span);
location.appendChild(entry);
}
Example Here : http://codepen.io/theConstructor/pen/pyPdgg
Good Luck!