Delete div by /{id} json-server - javascript

I've written a Todo task app, using JSON-Server, to manage the REST routing.
I've uploaded my code here:
https://codesandbox.io/s/json-server-i5hv5
Problem I'm having, is that when I click on a todo task, I want to delete only that DIV by {id}, from the database.
However, the delete function only works, if you click on the last div added. And even then, it deletes all {id}'s in the DB and divs on the page, rather than the single div, I've clicked on.
Struggling to make this work.
I want to only delete the div I click on. And I only want that div to be removed in the DB, by it's allocated id={id}.
This is the click function in question:
document.getElementById('id').addEventListener('click', function(event)
{
event.preventDefault();
console.log('clicked');
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
var id = divs[i].getAttribute('id');
divs[i].parentElement.removeChild(divs[i]);
fetchService.deleteTodoTask(id);
}
});
Any approaches/tips, would be grateful!

I got this working, by changing the way I'm accessing the DOM element on click. And the below code seems to work well.
I'm them passing the grabbed ID on click, into fetchService.deleteTodoTask(id).
Which is where the delete REST route is being handled:
const list = document.querySelector('.js-todo-list');
list.addEventListener('click', event => {
if (event.target.classList.contains('js-delete-todo')) {
const itemKey = event.target.parentElement.dataset.key;
const id = itemKey;
var elem = document.getElementById(id);
elem.parentNode.removeChild(elem);
fetchService.deleteTodoTask(id);
}
});
function deleteTodoTask(id) {
const options = {
method: 'DELETE'
};
return fetch(`${url}/${id}`, options);
}

Related

I cant seem to fetch the localstorage string. it shows up in the " localstorage tab " but i just cant retrieve the data, after refresh

`use strict`;
//assigned all btns to a variable
const addbtn = document.querySelector('.addbtn');
const deletebtn = document.querySelector('.deletebtn');
const clearbtn = document.querySelector('.clearbtn');
const saveList = document.querySelector(`.save`);
var addList = document.createElement('LI');
let listCount = [];
//LOCAL STORAGE
JSON.parse(localStorage.getItem(`saved`));
// alert(localStorage.getItem(`saved`));
localStorage.getItem(`saved`);
//FUNCTIONS
//SAVE
saveList.addEventListener(`click`, function() {
localStorage.setItem('saved', JSON.stringify(listCount));
alert(localStorage.getItem(`saved`));
location.reload();
});
//DELETEALL BUTTON
const deleteAll = function() {
var ulList = document.getElementById('list');
var deleteList = document.getElementsByTagName('li');
while (deleteList.length > 0) {
console.log(ulList.removeChild(deleteList[0]));
}
};
//EVENTLISTENER
clearbtn.addEventListener('click', deleteAll);
// /// ADDING FUNCTION
addbtn.addEventListener('click', function() {
const textBoxValue = document.querySelector('.text-box');
let value = textBoxValue.value;
if (value === '') {
alert(`Please add a chore`);
} else {
var ulList = document.getElementById('list');
var addList = document.createElement('LI');
addList.textContent = value;
listCount.push(value);
addList.className = 'list-text';
ulList.appendChild(addList);
textBoxValue.value = '';
//create delete button on list//
var deleteSingle = document.createElement('button');
deleteSingle.setAttribute('class', 'btn button');
//delete clicked list//
deleteSingle.appendChild(document.createTextNode('Delete'));
addList.appendChild(deleteSingle).addEventListener('click', function() {
this.parentNode.remove();
});
}
});
im new here so im slowly learning how to properly post questions on here. sorry for the sloppiness.
i have spent my last 4 hours trying to find the easiest way to just save my todo list so when page is refresh my todos are still there. i tried adding it on the addbtn function but i couldnt get it to work. i thought adding it there so once the add buttong is clicked automatically would save it to the local storage, but i didnt manage to make that work. so then i created an empty global array and when the addbtn is clicked the input gets added to the array and made a "save" button to save the array into the localstorage and then retrieve it once the page is refresh but i cant get it to work. i see my array list in the localstorage tab but when i refresh the page the list on the actual page is empty. what am i missing? and what do you think is the easiest way to add this into my code?
once again sorry for messy code and thank you soo much in advance.

Onclick event for "li" in a for loop when using createElement

I'm trying to add an event listener (onclick) onto every li element that gets created in a specific for loop - using JavaScript.
First I tried using tempLi.onclick (see code below for context), but it wouldn't run the function. After that I searched for the issue here on Stackoverflow, and I read that this method I'm using below should work - but it doesn't (not in my case at least).
if (users.length !== 0) {
for (let i = 0; i < users.length; i++) {
let tempLi = d.createElement('li');
tempLi.className = 'btn btn-primary knappur'
tempLi.innerHTML = users[i];
getId('usersUl').appendChild(tempLi);
(function(value) {
tempLi.addEventListener("click", function() {
alert(value);
}, false);
})(users[i]);
getId('usersUl').innerHTML += '<br>';
}
}
The code is in a function called loginPrepare:
let loginPrepare = () => { ... }
How can I execute code when I click on the generated li (tempLi)?
EDIT: The code that I'd like to run when clicked on the "li" is login(users[i])
I would put the event handler on your ul and rely on event bubbling instead of attaching an event handler to each. It would look something like this.
document.getElementById('usersUl')
.addEventListener('click', function(e) {
if (e.target.hasClass('knappur') {
// Do your work
}
});
You are creating a function inside a loop, referencing the ever-changing index i, which, when the loop is done might be a completely different value than what you think it is.
Also, I think this way you are attaching the event-listener before the tempLi has had time to be properly integrated into the dom.
Third: you don't need to create a new event-listener for each list item. One is enough.//
Try this instead:
if (users.length !== 0) {
const list = getId('usersUl')
for (let i = 0; i < users.length; i++) {
let tempLi = d.createElement('li');
tempLi.className = 'btn btn-primary knappur';
tempLi.innerHTML = users[i];
tempLi.setAttribute('data-user', users[i])
list.appendChild(tempLi);
//list.innerHTML += '<br>'; don't do this btw, <br />s aren't valid children of lists!
}
list.addEventListener("click", event => {
const user = event.target.getAttribute('data-user');
alert(user);
});
}
We can achieve event binding to HTML in very simple way using JQuery like below:
$("#usersUl").on('click',function(e){
//what we do
});

pass click event between two page by localStorage

I want to take a click event from 2nd page . 1st page have a link for 2nd page, there have a button when click the button it add a HTML row on 1st page. I am trying to use localStorage for passing data. My code don't work, take a look below:
1st Page.html
HTML
<div id="content">
</div>
JS
var output = document.getElementById('content');
addEvent(window, 'storage', function (event) {
if (event.key == 'StorageName') {
output.innerHTML = event.newValue;
}
});
2nd Page.html
HTML
<input id="data" type="button" value="+" onclick="addRow()">
JS
addEvent(dataInput, 'keyup', function () {
localStorage.setItem('StorageName', this.value);
});
var dataInput = dataInput = document.getElementById('data');
object.onclick = function(){
addRow() {
var div = document.createElement('div');
div.className = 'row';
div.innerHTML = '<button>GO</button>';
document.getElementById('content').appendChild(div);
}
};
You haven't defined your addRow() function properly. A function's name is defined with the keyword function, not inside of the function body. Your code:
object.onclick = function(){
addRow() {
var div = document.createElement('div');
div.className = 'row';
div.innerHTML = '<button>GO</button>';
document.getElementById('content').appendChild(div);
}
};
Should be changed to:
function addRow() {
var div = document.createElement('div');
div.className = 'row';
div.innerHTML = '<button>GO</button>';
document.getElementById('content').appendChild(div);
}
object.onclick = addRow;
I agree with skyline3000's answer the addRow() should be defined. Also there are a few other things that could/should change:
define dataInput before attaching an event to it
object.onclick should be dataInput.onclick since thats the element being clicked. (is click event what you really want? maybe onkeyup?)
when you set the localStorage you want to set the function definition being passed to Page 1 which appears to be addRow(). Simply remove the parenthesis to pass just the definition.(Should also be defined before using)
If you want to just pass the function you shouldn't set the onclick event on Page 2. What you should probably do is record how many times you want it to run when you go to Page 1.
You dont need to pass the function everytime if it isnt changing; Just set it once and record the number of times it was clicked.
page 1 can catch the load event and the check localStorage for the function definition and number of times it was run. Then it can loop and perform the function.
the code you have doesn't add a link back to page 2 if thats what you are looking for but you can add that into the addrow function when you know the file name and path.
Page 1
var output = document.getElementById('content');
addEvent(window, 'load', function (event) {
if (localStorage.getItem('StorageName') && localStorage.getItem('rowsToAdd')) {
for(var i = 0; i > rowsToAdd;i++){
var addNewRow = localStorage.getItem('StorageName');
addNewRow();
}
}
});
Page 2
var dataInput = document.getElementById('data');
function addRow() {
var div = document.createElement('div');
div.className = 'row';
div.innerHTML = '<button>GO</button>';
document.getElementById('content').appendChild(div);
};
localStorage.setItem('StorageName', addRow);
dataInput.onclick = function() {
if(localStorage.getItem('rowsToAdd')){
localStorage.setItem('rowsToAdd', localStorage.getItem('rowsToAdd') + 1);
}else{
localStorage.setItem('rowsToAdd',1);
}
}
I didn't test this code so it may not work copy+pasted but something pretty close hopefully.
I also answered this with the best understanding of what you wanted that I could manage but I dont fully see the desired result of what you seemed to be doing.

Change value of first iteration input with next iteration input value

Structure Concept:-
Basically, i am trying to create the modal window containing input and that modal window currently fires when the input on index page get focused for that I have used data attribute to make a link between them by assigning them same attribute value.
Javascript Concept:-
for the modal window, I have created the modal object. and model object contains a bindModal method which takes one argument and that argument is data attribute value. after taking that value bindModal method will search dom elements containing that particular value and after the search, I iterate over them using each loop.
Problem
So basically I want whenever user starts typing on the model input it should get written automatically in input on the index page.
I will appreciate you all if guys help me out to make my code more optimized and well structured and most important thing is that let me know what mistake I have done in overall work Thanks
JavaScript Code
var modal = function () {
this.toggleModal = function () {
$('#modal').toggleClass('content--inActive').promise().done(function () {
$('#modal__close').on('click',function(){
$('#modal').addClass('content--inActive');
});
});
}
this.bindModal = function (bindVal) {
var bindValue = $(document).find('[data-modal-bind = ' + bindVal + ']');
$.each(bindValue, function (index) {
var bind1 = $(this);
if(index === 1) {
var bind2 = $(this);
$(bind1).change(function (){
$(bind2).val(bind1.val());
});
}
});
}
}
var open = new modal();
$('#input_search').on('click',function(){
open.toggleModal();
open.bindModal('input');
});
Here is one way to do what you want:
var modal = function() {
this.bindModal = function(bindVal) {
var bindValue = $('[data-modal-bind = ' + bindVal + ']');
bindValue.each(function(index) {
$(this).keyup(function() {
var value = $(this).val();
bindValue.each(function(i, e) {
$(this).val(value);
});
});
});
}
}
$('#input_search').on('click', function() {
var open = new modal();
open.bindModal('input');
});
Changes done:
I cached the inputs with same binding values in bindValue variable, and then bound the the keyup event for each of them. On keyup, the value of the current input is get in value, which is then assigned to each input using the inner loop.
This makes the inputs to be in sync while typing. Hope that solves your issue.

Trying to make a to do list

Im new to javascript and coding in general, I'm trying to make a simple to do list but cant get the delete button to delete all the checkboxes, it will only delete the last checkbox made. Thanks guys
http://jsfiddle.net/2L8y73ac/
var task = document.getElementById('textinput');
function ObjectTask() {
self = this;
self.init = function() {
self.itemText=document.createTextNode(task.value);
self.checkbox = document.createElement("input");
self.checkbox.type = "checkbox";
self.checkbox.name = task.value;
self.checkbox.id = "checkbox";
self.checkbox.value = "0";
self.checkbox.onclick = self.clickMe;
self.listItem=document.createElement("li");
self.listItem.id = task.value;
self.listItem.appendChild(self.itemText);
self.listItem.appendChild(self.checkbox);
self.deleteCheckBox = document.getElementById('deleteBtn');
self.deleteCheckBox.onclick = self.deleteMe;
document.getElementById('place').appendChild(self.listItem);
}
self.clickMe = function() {
if (self.checkbox.value === "0") {
self.checkbox.value = "1";
console.log("1");
}else {
self.checkbox.value = "0";
console.log("0");
}
}
self.deleteMe = function(){
if (self.checkbox.value == "1"){
var parent = self.listItem.parentNode;
parent.removeChild(self.listItem);
}
}
}
function taskadd() {
var taskNew = new ObjectTask();
taskNew.init();
}
I can't seem to get the adding to work either, but that doesn't matter. :)
The problem is that you assign a new click handler to the single delete button everytime when you add an item. When you click the delete button, the event handler of the last item is called, everytime (even when the item itself is already deleted).
The problem is in this piece of code:
self.deleteCheckBox = document.getElementById('deleteBtn');
self.deleteCheckBox.onclick = self.deleteMe;
deleteCheckBox is assigned the (global) delete button. After that, you assign a new onclick handler to it, overwriting the previous one.
A better approach would be to write one generic handler for the delete button, which looks up all selected checkboxes and finds the other elements belonging to it to delete them. So just like your global taskadd(), you should also have a global taskdelete() that deletes all selected tasks.

Categories

Resources