How to delete elements from to do list? - javascript

I apologize if this is a bit confusing to read, this is my first post.
Please consider the following code:
HTML:
...
<form>
<input type="text" id="to-do-input" placeholder="Add new task..">
<button id="add-to-do" type="button">Add ToDo</button>
</form>
<div id="to-do-container">
</div>
...
JAVASCRIPT:
var addButton = document.getElementById("add-to-do");
toDoArray = [];
addButton.addEventListener("click", function() {
let nHTML = '';
let todoValue = document.getElementById("to-do-input").value;
toDoArray.push(todoValue);
toDoArray.forEach( function(item) {
//READ BELOW
//<!--set each array item's id to it's own string value minus white spaces
var itemId = item.replace(' ','');
item.setAttribute("id", itemId); //console: "item.setAttribute is not a function"
//-->
nHTML += '<li>' + item + ' <button id="delete">Remove</button> </li>';
});
document.getElementById("to-do-container").innerHTML = '<ul>' + nHTML + '</ul>';
document.getElementById("to-do-input").value = '';
});
PROBLEM:
The plan is to set each array item's id value to its own string value minus all spaces via .replace(), but the console is saying:
app.js:17 Uncaught TypeError: item.setAttribute is not a function
at app.js:17:26
at Array.forEach (<anonymous>)
at HTMLButtonElement.<anonymous> (app.js:14:27
I tried to also type item.setAttribute("id", ${itemId}), but that hasn't worked either.

Javascript code:
var addButton = document.getElementById("add-to-do");
toDoArray = [];
addButton.addEventListener("click", function () {
let nHTML = '';
let todoValue = document.getElementById("to-do-input").value;
toDoArray.push(todoValue);
toDoArray.forEach(function (item, index) {
//READ BELOW
//<!--set each array item's id to it's own string value minus white spaces
var itemId = item.replace(' ', '');
// item.setAttribute("id", itemId); //console: "item.setAttribute is not a function"
//--> //This line has been replaced
nHTML += `<li id='${itemId}'>` + item + ` <button id="delete" onclick="dltFun(${index},${itemId})">Remove</button> </li>`; //This line has been replaced
});
document.getElementById("to-do-container").innerHTML = '<ul>' + nHTML + '</ul>';
document.getElementById("to-do-input").value = '';
});
function dltFun(index, itemId) {
let element = document.getElementById(itemId)
element.remove()
toDoArray.splice(index, 1)
}

Fixed JavaScript code:
const addButton = document.getElementById('add-to-do');
const input = document.getElementById('to-do-input');
const toDoContainer = document.getElementById('to-do-container');
const toDoArray = [];
addButton.addEventListener('click', () => {
toDoArray.push(input.value);
toDoContainer.innerHTML = `<ul>${toDoArray
.map(
(todo) =>
`<li id='${todo.replace(
' ',
'',
)}'>${todo}<button id="delete">Remove</button> </li>`,
)
.join('')}</ul>`;
input.value = '';
});
Hope this helps.

Related

How to dyncamically set the value of a dropdownlist from an array

I am trying to get a value from a dropdown list. I have the dropdown list and I have the value that I want but I don't know how to link them to each other. So the value of the category should go in the dropdown list and then the image value from that string should be the outcome.
This is the JSON file array called ill.json
...
[{"id":"7","category":"Lente collectie 2021","image":"Teddy_bears_10.png"},{"id":"11","category":"Lente collectie 2021","image":"Individual_floral_elements_01.png"}
...
The category value goes into the dropdown list and then the outcome should be the image value:
This is my dropdown
...
const req = new XMLHttpRequest();
req.open('GET', 'ill.json', true);
req.send();
req.onload = function() {
const json = JSON.parse(req.responseText);
let dropdown = "";
let html = "";
//FILLING DROPDOWN WITH CATEGORYs
var result = json.reduce(function (r, a) {
r[a.category] = r[a.category] || [];
r[a.category].push(a);
return r;
}, Object.create(null));
let keys = Object.keys(result)
keys.forEach((key) => {
dropdown += "<select id='select'>"
dropdown += "<option value='" + key + "'>"
dropdown += key
dropdown += "</option>"
dropdown += "</select"
})
document.getElementsByClassName('dropdown')[0].innerHTML = dropdown;
...
And this is how I got the images
...
//get all images
json.forEach(function(val) {
html += "<div class='illustratie-item'>";
html += "<img class='dt-filelist-image' src='" + val.image + "'/>"
html += "</div><br>";
});
document.getElementsByClassName('illustratie-wrapper')[0].innerHTML = html;
...
If I get that right, it should be as easy as this:
var categorySelect = document.querySelector('.dropdown');
categorySelect.addEventListener('change', function(evt) {
var item = json.find(function(item) {
return item.id === evt.target.value;
});
console.log(item.image); // there's your image
});
Check the below snippet.
var images = [{"id":"7","category":"Lente collectie 2020","image":"Teddy_bears_10.png"},{"id":"11","category":"Lente collectie 2021","image":"Individual_floral_elements_01.png"}];
var dropdown = '';
dropdown += '<select id="select">';
Object.keys(images).forEach(function(key) {
dropdown += '<option value="' + images[key].id + '">';
dropdown += images[key].category;
dropdown += '</option>';
});
dropdown += '</select>';
document.getElementsByClassName('dropdown')[0].innerHTML = dropdown;
var categorySelect = document.querySelector('#select');
categorySelect.addEventListener('change', function(evt) {
var item = images.find(function(item) {
return item.id === evt.target.value;
});
console.log( item.image );
});
<div class="dropdown"></div>

Display names under profile pics Firebase Web Realtime-Database

User specific infoProfile pic displayI fixed a ton of bugs I had before.
Goal: Dynamically display all signed up users with their names displayed under their profile pic.
What it does now: Dynamically displays all users(when you click it shows specific user info) and profile pics in seperate divs.
Image:Dynamic images displayed
Snippet:
const dbRef = firebase.database().ref();
const usersRef = dbRef.child('userInfo');
const userListUI = document.getElementById("userList");
usersRef.on("child_added", snap => {
let user = snap.val();
let $h3 = document.createElement("h3");
$h3.innerHTML = user.name;
$h3.setAttribute("child-key", snap.key);
$h3.addEventListener("click", userClicked)
userListUI.append($h3);
});
function userClicked(e) {
var userID = e.target.getAttribute("child-key");
const userRef = dbRef.child('userInfo/' + userID);
const userDetailUI = document.getElementById("userDetail");
userDetailUI.innerHTML = ""
userRef.on("child_added", snap => {
var $p = document.createElement("p");
$p.innerHTML = snap.key + " - " + snap.val()
userDetailUI.append($p);
});
}
var storage = firebase.storage();
var storageRef = storage.ref();
$('#List').find('tbody').html('');
var i = 0;
storageRef.child('users').listAll().then(function(result) {
result.items.forEach(function(imageRef) {
i++;
displayImage(i, imageRef);
});
});
function displayImage(row, images) {
images.getDownloadURL().then(function(url) {
// console.log(url);
let new_html = '';
// new_html += '<tr>';
new_html += '<td>';
// new_html += '</td>';
// new_html += '<td>';
new_html += '<img src= "' + url + '">';
new_html += '</td>';
// new_html += '</tr>';
new_html += row;
$('#List').find('tbody').append(new_html);
});
}
<table id="List">
<tbody>
</tbody>
</table>
<br><br>
<ul id="userList"></ul>
<div id="userDetail">
<p>
<strong class="detailName"></strong>
</p>
</div>
What I've done to try to fix:Googling, playing around with the display image function (tried moving the $('#List').find('tbody').append(new_html); below the 2nd to last });) add something to the new_html to display names but the images.getDownloadURL messes the other stuff I tried because if I add another function after or before it, I'll get an error because the images are stored in storage and the user info is in realtime database. Any pointers?
var userData = docRef.collection("userInfo");
usersRef.on("child_added", snap => {
let user = snap.val();
let $ul = document.createElement("ul");
$ul.innerHTML = user.name;
$ul.setAttribute("child-key", snap.key);
$ul.addEventListener("click", userClicked)
userListUI.append($ul);
});
function userClicked(e) {
var userID = e.target.getAttribute("child-key");
const imageRef = storageRef.child('users/' + userID);
const userRef = dbRef.child('userInfo/' + userID);
// window.location = 'profileview.html';
const userDetailUI = document.getElementById("userDetail");
userDetailUI.innerHTML = "";
userRef.on("child_added", snap => {
var $ul = document.createElement("ul");
$ul.innerHTML = snap.key + " - " + snap.val()
userDetailUI.append($ul);
});
}

saving background color on localstorage

I got the data stored on my localStorage and display them in table format with each row having a button. What I want to do now is, when the button is clicked I want it to change the background color to another color and when the page refreshes the button persists its color state.
Here is my code
// here i will be the data in form of table
// my algorithm comes here
// this function will get data from the localstorage
const get_todos = ()=>{
  let todos = new Array();
  let todos_str = localStorage.getItem("todo");
  if(todos_str !== null){
    todos = JSON.parse(todos_str);
  }
  return todos;
}
//this function will show the data in the localstorage in table format
const show = ()=>{
  let todos = get_todos();
  let text = "";
  for(let i = 0; i < todos.length; i++){
      let allData = todos[i];
      let eventName = allData.Eventname;
      let location = allData.Location;
      let date = allData.Date;
      text += "<tr>";
      text += "<td>" + eventName + "</td>";
      text += "<td>" + location + "</td>";
      text += "<td>" + date + "</td>";
      text += "<td>" + "<button class='buttons' type='button'>Pending</button>" + "</td>";
      text += "<td>" + "<i id='remove' class='fas fa-trash-alt btndelete'></i>" + "</td></tr>";
  }
  //the data gotten from the localstorage will be here
  let table = document.querySelector("#table > tbody");
  table.innerHTML = text;
  //this is where the button background color will change
window.addEventListener("load", ()=>{
    let thead = document.querySelector("#thead");
    let buttons = Array.from(document.querySelectorAll(".buttons"));
    thead.addEventListener("click", (e)=>{
      if(e.target.className === "buttons"){
        let index = buttons.indexOf(e.target);
        changeBackground(e, index);
      }
    });
    buttons.forEach(btn, index =>{
      btn.className = sessionStorage.getItem('background${index}') || 'buttons';
      
    });
  });
  const changeBackground = (e, index)=>{
    e.target.className += "change";
    sessionStorage.setItem(background${index}, e.target.className);
  }
  
}
window.addEventListener("DOMContentLoaded", ()=>{
  show();
});
There is few errors in your code:
First:
btn.className = sessionStorage.getItem('background${index}') || 'buttons';
Should be:
btn.className = sessionStorage.getItem(`background${index}`) || 'buttons';
because you are create a string using Template literals (Template strings)
Second:
e.target.className += "change";
Should be:
e.target.className += " change";
You have to add space when concatenate strings, or else in your case it will not provide the intended behavior, since your code will add change class name to the previous class as one word.
Third:
sessionStorage.setItem(background${index}, e.target.className);
Should be:
sessionStorage.setItem(`background${index}`, e.target.className);
In your question you are talking about localStorage but you are
using sessionStorage, Still not sure if this what you want, so if you want it to be localStorage just replace sessionStorage with localStorage
// here i will be the data in form of table
// my algorithm comes here
// this function will get data from the localstorage
const get_todos = ()=>{
let todos = new Array();
let todos_str = localStorage.getItem("todo");
if(todos_str !== null){
todos = JSON.parse(todos_str);
}
return todos;
}
//this function will show the data in the localstorage in table format
const show = ()=>{
let todos = get_todos();
let text = "";
for(let i = 0; i < todos.length; i++){
let allData = todos[i];
let eventName = allData.Eventname;
let location = allData.Location;
let date = allData.Date;
text += "<tr>";
text += "<td>" + eventName + "</td>";
text += "<td>" + location + "</td>";
text += "<td>" + date + "</td>";
text += "<td>" + "<button class='buttons' type='button'>Pending</button>" + "</td>";
text += "<td>" + "<i id='remove' class='fas fa-trash-alt btndelete'></i>" + "</td></tr>";
}
//the data gotten from the localstorage will be here
let table = document.querySelector("#table > tbody");
table.innerHTML = text;
//this is where the button background color will change
window.addEventListener("load", ()=>{
let thead = document.querySelector("#thead");
let buttons = Array.from(document.querySelectorAll(".buttons"));
thead.addEventListener("click", (e)=>{
if(e.target.className === "buttons"){
let index = buttons.indexOf(e.target);
changeBackground(e, index);
}
});
buttons.forEach(btn, index =>{
btn.className = localStorage.getItem(`background${index}`) || 'buttons';
});
});
const changeBackground = (e, index)=>{
e.target.className += " change";
localStorage.setItem(`background${index}`, e.target.className);
}
}
window.addEventListener("DOMContentLoaded", ()=>{
show();
});

Javascript wrong variable type

Hello I'm preparing little guessing word game.
Somehow the type of my variable get changed from string to obj type what causes an Uncaught TypeError.
Here is a fragment of code:
let passwordArray = ["Java Script Developer", "FrontEnd"];
let sample = passwordArray[Math.floor((Math.random() *
passwordArray.length))];
let password = sample.toUpperCase();
let new_password = "";
for(let x =0; x<password.length;x++){
if(password[x]===" "){new_password += " "}
else{new_password += "-"}
}
$("#password span").text(new_password);
This part works correclty problem appears when I want to repalce a letter
String.prototype.replaceAt = function(index, replacement){
return this.substr(0,index) + replacement + this.substr(index + replacement.length)
};
function check(num) {
let test = false;
let temp = $(event.target).val();
if(password.indexOf(temp)>-1){test=true; /*alert(test +"/"+temp+"/"+password)*/}
$("#"+num).attr("disabled", true);
if(test === true) {
$("#"+num).removeClass("letter").addClass("hitletter");
let indeksy =[];
for(let i =0; i<password.length;i++ ){
if(password.charAt(i) === temp){indeksy.push(i)}
}
for(let x=0; x<indeksy.length;x++) {
let indx = indeksy[x];
new_password = new_password.replaceAt(indx, temp);
}
$("#password").html(new_password);
}};
My HTML basically is just:
<nav>
<input type="button" value="o mnie" id="me">
<input type="button" value="kalkulator" id="cal">
<input type="button" value="Wisielec" id="wis">
<input type="button" value="Memory" id="mem">
</nav>
<div id="content"></div>
Rest is dynamically added in JS:
$(function() {
$("#wis").click(function () {
$("#content").empty().append("" +
"<div id='container'>\n" +
"<div id='password'><span>Sample text</span></span></div>\n" +
"<div id='counter'>Counter: <span id='result'></span></div>\n" +
"<div id='gibbet' class='image'></div>\n" +
"<div id='alphabet'></div>\n" +
"<div id='new'>\n" +
"<input type='text' id='new_password'/>\n" +
"<button id='add' onclick='newPass()'>Submit</button>\n" +
"</div>\n" +
"</div>"
);
start();
});
});
function start(){
let new_password = "";
$("#contetn").empty();
let letters = "";
for(let i=0; i<32; i++){
letters += "<input class='letter' type='button' value='"+litery[i]+"' onclick='check("+i+")' id='"+i+"'/>"
}
$("#alphabet").html(letters);
$("#result").text(mistakeCounter);
for(let x =0; x<password.length;x++){
if(password[x]===" "){new_password += " "}
else{new_password += "-"}
}
$("#password span").text(new_password);
}
The problem is that variable new_password is somehow changing from type string to type object when i want to use function replaceAt()
looking at your code, with the new String.prototype.replaceAt this error can happen on 2 situations:
when the variable that uses replaceAt is not a string, example:
null.replaceAt(someIndex,'someText');
{}.replaceAt(someIndex,'someText');
[].replaceAt(someIndex,'someText');
the other situation is when you pass null or undefined as replacement:
"".replaceAt(someIndex,undefined);
"".replaceAt(someIndex,null);
just add some verification code and should be working good

Make a html unordered list from javascript array

I'm having a bit of a problem. I'm trying to create a unordered list from a javascript array, here is my code:
var names = [];
var nameList = "";
function submit()
{
var name = document.getElementById("enter");
var theName = name.value;
names.push(theName);
nameList += "<li>" + names + "</li>";
document.getElementById("name").innerHTML = nameList;
}
<input id="enter" type="text">
<input type="button" value="Enter name" onclick="submit()">
<br>
<br>
<div id="name"></div>
For example, if I post 2 names, Name1 and Name2 my list looks like this:
•Name1
•Name1,Name2
I want it to look like this:
•Name1
•Name2
If you look at your code, you are only creating one li with all your names as the content. What you want to do is loop over your names and create a separate li for each, right?
Change:
nameList += "<li>" + names + "</li>";
to:
nameList = "";
for (var i = 0, name; name = names[i]; i++) {
nameList += "<li>" + name + "</li>";
}
If you are interested in some better practices, you can check out a rewrite of your logic here: http://jsfiddle.net/rgthree/ccyo77ep/
function submit()
{
var name = document.getElementById("enter");
var theName = name.value;
names.push(theName);
document.getElementById("name").innerHTML = "";
for (var I = 0; I < names.length; I++)
{
nameList = "<li>" + names[I] + "</li>";
document.getElementById("name").innerHTML += nameList;
}
}
You are using an array, when you print an array JavaScript will show all the entries of the array separated by commas. You need to iterate over the array to make it work. However you can optimize this:
var names = [];
function displayUserName()
{
var theName = document.getElementById("enter").value;
if (theName == "" || theName.length == 0)
{
return false; //stop the function since the value is empty.
}
names.push(theName);
document.getElementById("name").children[0].innerHTML += "<li>"+names[names.length-1]+"</li>";
}
<input id="enter" type="text">
<input type="button" value="Enter name" onclick="displayUserName()">
<br>
<br>
<div id="name"><ul></ul></div>
In this example the HTML is syntactically correct by using the UL (or unordered list) container to which the lis (list items) are added.
document.getElementById("name").children[0].innerHTML += "<li>"+names[names.length-1]+"</li>";
This line selects the div with the name: name and its first child (the ul). It then appends the LI to the list.
As #FelixKling said: avoid using reserved or ambiguous names.
<div>
<label for="new-product">Add Product</label><br /><br /><input id="new-product" type="text"><br /><br /><button>Add</button>
</div>
<div>
<ul id="products">
</ul>
<p id="count"></p>
</div>
var products = [];
var productInput = document.getElementById("new-product");
var addButton = document.getElementsByTagName("button")[0];
var productListHtml = "";
var abc = 0;
addButton.addEventListener("click", addProduct);
function addProduct() {
products.push(productInput.value);
productList();
}
function productList() {
productListHtml += "<li>" + products[abc] + "</li>";
document.getElementById("products").innerHTML = productListHtml;
abc++;
}

Categories

Resources