Sorting an unordered list with JavaScript - javascript

I have an unordered list.
This list has elements with checkboxes in it. If you check in a checkbox, the list element goes to the bottom of the list. when you check out one of the checkboxes, it has to go back to its original place. so far, I managed.
BUT. Take the following situation: You checked in all the checkboxes, and they seem to align according to their original place. Now, when you check out a list element, it will stuck between to other elements, which are on their place, but they are checked in. I want that in that case, the checked off box will be the first in the list. Then, when you check off the next box, that one will now be on the right place, aligning with thee unchecked boxes only.
TL;DR:
I have to make a To Do list, the 'done' elements go to the bottom, the undone elements sorted above, according to their timestamp.
http://codepen.io/balazsorban44/pen/mAvqmk
<!DOCTYPE html>
<html>
<head>
<title>A Todo List</title>
<style media="screen">
*{
margin:0;
padding: 0;
font-family: sans-serif;
color: gold;
font-weight: bolder;
font-size: 1em;
border: none;
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
width: 100vw;
background: #333;
}
#content{
border: 1px solid #333;
padding: 20px;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
background-color: gold;
box-shadow: 0px 0px 4px 4px rgba(0,0,0,.2);
}
h1,h2{
display: block;
color: #444;
font-size: 1.3em;
padding: 10px;
align-self: flex-start;
}
h2{
font-size: 1.1em
}
input{
color: #333;
padding: 5px;
border-radius: 5px;
border: 1px solid #333;
box-shadow: inset 0px 0px 3px rgba(0,0,0,.3)
}
input:focus{
outline: none
}
button{
background: #333;
border-radius: 5px;
padding: 5px 10px;
max-width: 50%;
margin-top:15px;
cursor: pointer
}
ul li{
list-style-type: none;
color:#333;
min-width: 100px;
padding: 5px;
align-self: flex-start;
}
ul li input{
margin: 0 5px
}
</style>
</head>
<body onload="loaded()">
<div id=content>
<h1>A very nice To Do list</h1>
<div>
<input id="todo-input" type="text" name="todo-input" value="" placeholder="Click + or press Enter." onkeydown="enter()">
<button type="button" name="button" onclick="addTask()">+</button>
</div>
<h2>Your todo list (done/all): <output>/</output></h2>
<ul id="tasks">
</ul>
</div>
<script type="text/javascript">
const inputArea= document.getElementById('todo-input')
const list = document.getElementById("tasks");
tasks = [];
function loaded(){
inputArea.focus();
}
function addTask(){
const newTask = document.createElement("li")
const text = document.createTextNode(inputArea.value)
const checkBox = document.createElement("input");
newTask.appendChild(text);
list.insertBefore(newTask, list.childNodes[0]);
checkBox.setAttribute("type", "checkbox");
checkBox.setAttribute("onclick", "toggleCheckBox()");
list.childNodes[0].insertBefore(checkBox, list.childNodes[0].childNodes[0]);
tasks.push({timestamp: new Date(), task: inputArea.value});
list.childNodes[0].id=tasks[tasks.length-1].timestamp.getTime();
inputArea.value ="";
inputArea.focus();
}
function enter(){
if(event.keyCode == 13) {
addTask()
}
}
function toggleCheckBox(){
const task = event.target.parentNode
if (task.style.textDecoration == '') {
task.style.textDecoration = 'line-through';
list.appendChild(task)
}
else {
task.style.textDecoration = ''
for (var i = 0; i < tasks.length; i++) {
if (task.id > list.childNodes[i].id) {
list.insertBefore(task, list.childNodes[i]);
break
}
}
}
}
</script>
</body>
</html>

Manage your tasks list in javascript and update the HTML whenever a checkbox value is changed or task is added:
var inputArea = document.getElementById('todo-input')
var list = document.getElementById("tasks");
var tasks = [];
function loaded() {
inputArea.value = "";
inputArea.focus();
}
function update(){
list.innerHTML = '';
// Sort the tasks on done boolean
tasks.sort(function(x, y) {
return (x.done === y.done)? 0 : x.done ? 1 : -1;
});
for(var i = 0; i < tasks.length; i++){
var item = tasks[i];
var task = document.createElement("li")
var text = document.createElement("span");
var checkBox = document.createElement("input");
text.innerHTML = item.task;
text.style.color = 'black';
checkBox.setAttribute("type", "checkbox");
checkBox.addEventListener("change", (function(t){
return function(){
tasks[t].done = this.checked;
console.log(tasks[t]);
update();
}
}(i)));
if(item.done){
checkBox.checked = true;
text.style.textDecoration = 'line-through'
}
task.appendChild(checkBox);
task.appendChild(text);
list.appendChild(task);
}
}
function addTask() {
tasks.push({
id: tasks.length ? tasks[tasks.length - 1].timestamp.getTime() : +new Date(),
done: false,
timestamp: new Date(),
task: inputArea.value
});
update();
loaded();
}
Codepen

I guess you have to make an object structure as
function Task(id,itemName,timeStamp,isCompleted){
this.id=id;
this.itemName=itemName;
this.time=timeStamp;
this.completed=isCompleted;
}
var Tasks=[];
while adding each task,you have to save in such format.
So whenever a task is completed ,you would set completed to true . For all the uncompleted tasks all you need to do is to sort based on their time or based on their name
Hope this helps

Related

Create an element with a click and remove it by a second click

Still learning so bear with me.
I am building a test project where I have a simple input that I show it on the same page as a list. (grocery or to do list project)
So when a user hits the ok button I create a new li inside a ul element. That goes ok.
I want to implement the following though: When the user clicks on the new element (li) I want to change the text decoration to line-though and show a trash icon where it will remove this li element by clicking on it.
I have managed to do that. The problem is that when the user clicks again on the new element (li) I get a second trash image.
I want help to succeed in this: when a user clicks on the element while it has text-decoration = line-through to hide or remove the trash icon and make text-decoration none again.
Here is a code pen for this project to check out. Just insert a new item on the list and then click twice on it: https://codepen.io/dourvas-ioannis/pen/MWVBjNZ
This is the function I am using when the user hits the add button to add a list item:
function addToList(){
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function(){
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem(){
this.parentNode.remove();
}
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function() {
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>
Here's a quick example implementation of the approach I mentioned in the comments. I've just hacked it together quickly, so there's a small difference for the bin.
I've used an img (without a src) instead of a 'character' from the
font. I've styled the img to be 16x16 for the same reason. It also
makes it visible instead of being 0x0 pixels. I also set the cursor.
"use strict";
window.addEventListener('load', onLoad, false);
function onLoad(evt) {
document.querySelector('button').addEventListener('click', onAddBtnClicked, false);
}
function onAddBtnClicked(evt) {
let userText = document.querySelector('input').value;
let newLi = document.createElement('li');
newLi.textContent = userText;
newLi.addEventListener('click', onIncompleteItemClicked, false);
document.querySelector('ul').appendChild(newLi);
}
function onIncompleteItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = document.createElement('img');
binImg.addEventListener('click', onBinIconClicked, false);
clickedLi.appendChild(binImg);
clickedLi.removeEventListener('click', onIncompleteItemClicked, false);
clickedLi.addEventListener('click', onCompletedItemClicked, false);
}
function onCompletedItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = clickedLi.querySelector('img');
clickedLi.removeChild(binImg);
clickedLi.removeEventListener('click', onCompletedItemClicked, false);
clickedLi.addEventListener('click', onIncompleteItemClicked, false);
}
function onBinIconClicked(evt) {
let clickedBin = this;
let containingLi = clickedBin.parentNode;
containingLi.remove();
}
.itemComplete {
text-decoration: line-through;
}
li>img {
cursor: pointer;
width: 16px;
height: 16px;
}
<input value='blah-blah'></input><button>Add</button>
<ul></ul>
Add a variable indicating that the icon has been already added.
Check if icon is added on click
If yes - skip
If not - set icon
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
// declare boolean variable
let hasTrashIcon = false
newListItem.addEventListener('click', function() {
// if has thrash icon skip
if (hasTrashIcon) return
// set has trash icon
hasTrashIcon = true
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>

javascript on a webpage displaying text wrongly

I have JS code on a webpage that loads questions in from mysql db and displays the text . What happens is that it cuts off words at the end of the line and continues the word on the next line at the start. So all text across the screen starts/ends at the same point.
This seems to be the code where it displays the text.
For example the text will look like at the end of a line 'cont' and then on next line at the start 'inue'.
How do i fix this?
var questions = <?=$questions;?>;
// Initialize variables
//------------------------------------------------------------------
var tags;
var tagsClass = '';
var liTagsid = [];
var correctAns = 0;
var isscorrect = 0;
var quizPage = 1;
var currentIndex = 0;
var currentQuestion = questions[currentIndex];
var prevousQuestion;
var previousIndex = 0;
var ulTag = document.getElementsByClassName('ulclass')[0];
var button = document.getElementById('submit');
var questionTitle = document.getElementById('question');
//save class name so it can be reused easily
//if I want to change it, I have to change it one place
var classHighlight = 'selected';
// Display Answers and hightlight selected item
//------------------------------------------------------------------
function showQuestions (){
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
if (currentIndex != 0) {
// create again submit button only for next pages
ulTag.innerHTML ='';
button.innerHTML = 'Submit';
button.className = 'submit';
button.id = 'submit';
if(quizPage<=questions.length){
//update the number of questions displayed
document.getElementById('quizNumber').innerHTML = quizPage;
}
}
//Display Results in the final page
if (currentIndex == (questions.length)) {
ulTag.innerHTML = '';
document.getElementById('question').innerHTML = '';
if(button.id == 'submit'){
button.className = 'buttonload';
button.innerHTML = '<i class="fa fa-spinner fa-spin"></i>Loading';
}
showResults();
return
}
questionTitle.innerHTML = "Question No:" + quizPage + " "+currentQuestion.question.category_name +"<br/>"+ currentQuestion.question.text;
if(currentQuestion.question.filename !== ''){
var br = document.createElement('br');
questionTitle .appendChild(br);
var img = document.createElement('img');
img.src = currentQuestion.question.filename;
img.className = 'imagecenter';
img.width = 750;
img.height = 350;
questionTitle .appendChild(img);
}
// create a for loop to generate the options and display them in the page
for (var i = 0; i < currentQuestion.options.length; i++) {
// creating options
var newAns = document.createElement('li');
newAns.id = 'ans'+ (i+1);
newAns.className = "notSelected listyle";
var textAns = document.createTextNode(currentQuestion.options[i].optiontext);
newAns.appendChild(textAns);
if(currentQuestion.options[i].file !== ''){
var br = document.createElement('br');
newAns .appendChild(br);
var img1 = document.createElement('img');
img1.src = currentQuestion.options[i].file;
img1.className = 'optionimg';
img1.width = 250;
img1.height = 250;
newAns .appendChild(img1);
newAns .appendChild(br);
}
var addNewAnsHere = document.getElementById('options');
addNewAnsHere.appendChild(newAns);
}
//.click() will return the result of $('.notSelected')
var $liTags = $('.notSelected').click(function(list) {
list.preventDefault();
//run removeClass on every element
//if the elements are not static, you might want to rerun $('.notSelected')
//instead of the saved $litTags
$liTags.removeClass(classHighlight);
//add the class to the currently clicked element (this)
$(this).addClass(classHighlight);
//get id name of clicked answer
for (var i = 0; i < currentQuestion.options.length ; i++) {
// console.log(liTagsid[i]);
if($liTags[i].className == "notSelected listyle selected"){
//store information to check answer
tags = $liTags[i].id;
// tagsClass = $LiTags.className;
tagsClassName = $liTags[i];
}
}
});
//check answer once it has been submitted
button.onclick = function (){
if(button.id == 'submit'){
button.className = 'buttonload';
button.innerHTML = '<i class="fa fa-spinner fa-spin"></i>Loading';
}
setTimeout(function() { checkAnswer(); }, 100);
};
}
//self calling function
showQuestions();
The website is on my local now but i can upload a screenimage if need be and the whole code of the webpage. Or is the issue in html?
edit: here is html/css code
<style>
/*========================================================
Quiz Section
========================================================*/
/*styling quiz area*/
.main {
background-color: white;
margin: 0 auto;
margin-top: 30px;
padding: 30px;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
/*white-space: nowrap;*/
}
/*Editing the number of questions*/
.spanclass {
font-size: x-large;
}
#pages{
border: 3px solid;
display: inline-flex;
border-radius: 0.5em;
float: right;
}
#question{
word-break: break-all;
}
/*format text*/
p {
text-align: left;
font-size: x-large;
padding: 10px 10px 0;
}
.optionimg{
border: 2px solid black;
border-radius: 1.5em;
}
/*Form area width*/
/*formatting answers*/
.listyle {
list-style-type: none;
text-align: left;
background-color: transparent;
margin: 10px 5px;
padding: 5px 10px;
border: 1px solid lightgray;
border-radius: 0.5em;
font-weight: normal;
font-size: x-large;
display: inline-grid;
width: 48%;
height: 300px;
overflow: auto;
}
.listyle:hover {
background: #ECEEF0;
cursor: pointer;
}
/*Change effect of question when the questions is selected*/
.selected, .selected:hover {
background: #FFDEAD;
}
/*change correct answer background*/
.correct, .correct:hover {
background: #9ACD32;
color: white;
}
/*change wrong answer background*/
.wrong, .wrong:hover {
background: #db3c3c;
color: white;
}
/*========================================================
Submit Button
========================================================*/
.main button {
text-transform: uppercase;
width: 20%;
border: none;
padding: 15px;
color: #FFFFFF;
}
.submit:hover, .submit:active, .submit:focus {
background: #43A047;
}
.submit {
background: #4CAF50;
min-width: 120px;
}
/*next question button*/
.next {
background: #fa994a;
min-width: 120px;
}
.next:hover, .next:active, .next:focus {
background: #e38a42;
}
.restart {
background-color:
}
/*========================================================
Results
========================================================*/
.circle{
position: relative;
margin: 0 auto;
width: 200px;
height: 200px;
background: #bdc3c7;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
border-radius: 100px;
overflow: hidden;
}
.fill{
position: absolute;
bottom: 0;
width: 100%;
height: 80%;
background: #31a2ac;
}
.score {
position: absolute;
width: 100%;
top: 1.7em;
text-align: center;
font-family: Arial, sans-serif;
color: #fff;
font-size: 40pt;
line-height: 0;
font-weight: normal;
}
.circle p {
margin: 400px;
}
/*========================================================
Confeeti Effect
========================================================*/
canvas{
position:absolute;
left:0;
top:11em;
z-index:0;
border:0px solid #000;
}
.imagecenter{
display: block;
margin: 0 auto;
}
.buttonload {
background-color: #04AA6D; /* Green background */
border: none; /* Remove borders */
color: white; /* White text */
padding: 12px 24px; /* Some padding */
font-size: 16px; /* Set a font-size */
}
/* Add a right margin to each icon */
.fa {
margin-left: -12px;
margin-right: 8px;
}
#media only screen and (max-width: 900px){
.listyle {
width: 100% !important;
height: auto !important;
}
.imagecenter {
width: 100% !important;
}
.listyle img{
width: inherit !important;
height: unset !important;
}
.ulclass
{
padding:0px !important;
}
}
</style>
<!-- Main page -->
<div class="main">
<!-- Number of Question -->
<div class="wrapper" id="pages">
<span class="spanclass" id="quizNumber">1</span><span class="spanclass">/<?=$count?></span>
</div>
<!-- Quiz Question -->
<div class="quiz-questions" id="display-area">
<p id="question"></p>
<ul class="ulclass" id="options">
</ul>
<div id="quiz-results" class="text-center">
<button type="button" name="button" class="submit" id="submit">Submit</button>
</div>
</div>
</div>
<canvas id="canvas"></canvas>
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
I'm guessing that #question{ word-break: break-all; } is probably the culprit then? –
CB..yes that fixed it:)

If..,else.. in javascript

I am trying to solve my problem with if-else in Javascript.
I would highly appreciate your help.
I wanted to filter the name via gender, also safe the keys - woman / man to local storage.
But I can not find out how to make if-else clause.
Can someone help me?
There is also the link:
https://drive.google.com/file/d/1RNJxbiU_DsFTCqGJWgxpepCgdOhGuzIj/view?usp=sharing
Thanks a lot, it means world to me, I am new here. :-)
$(document).ready(function() {
function displayName() {
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
//find list
let nameUl = $('#list_2');
nameUl.empty(); //.html('')
//making list
$.each(safeName, function(key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//remove link
let jmenoRemoveLink = $('x');
jmenoRemoveLink.click(function(e) {
e.preventDefault();
//name
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
//remove
safeName.splice(key, 1);
//safe name
localStorage.setItem('woman', JSON.stringify(safeName));
//display name
displayName();
});
nameLi.append(jmenoRemoveLink);
nameUl.append(nameLi);
});
}
$('#formular').submit(function(e) {
e.preventDefault();
let zadaneJmeno = $('#name').val();
if (zadaneJmeno) {
//safe
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
safeName.push(zadaneJmeno);
localStorage.setItem('woman', JSON.stringify(safeName)); /// ["Tom"]
//list
displayName();
$('#name').val('');
} else {
// alert
alert('please enter the name"');
$('#name').focus();
}
});
$('#removeAll').click(function() {
localStorage.setItem('woman', '[]'); ///localStorage.setItem('woman', JSON.stringify([]));
displayName();
});
displayName();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formular">
<label for="name">Enter the name</label>
<input type="text" id="name" required />
<label for="section">Gender</label>
<select name="selectSection" id="section" required>
<option value="">---</option>
<option value="man" id="man">man</option>
<option value="woman" id="woman">woman</option>
</select>
<input type="submit" value="add" />
</form>
<button id="removeAll">Remove</button>
<div id="man_div">
<h1>man:</h1>
<ul id="list"></ul>
</div>
<div id="woman_div">
<h1>woman:</h1>
<ul id="list_2"></ul>
</div>
I made a number of changes to your script, do note that as I am solving your problem, I removed the 'x' function on click because it is too verbose to read while solving your problem, do add it back later, and make sure you remove from the correct localStorage.
$(document).ready(function () {
function displayName() {
//Separate the local storage into man and woman keys
let manSafeNameVal = localStorage.getItem('man');
let manSafeName;
let womanSafeNameVal = localStorage.getItem('woman');
let womanSafeName
if (manSafeNameVal) {
manSafeName = JSON.parse(manSafeNameVal);
} else {
manSafeName = [];
}
if (womanSafeNameVal) {
womanSafeName = JSON.parse(womanSafeNameVal);
} else {
womanSafeName = [];
}
//find list
//Use list and list_2 to display
let manUl = $('#list');
let womanUl = $('#list_2');
manUl.empty(); //.html('')
womanUl.empty();
//list for man
$.each(manSafeName, function (key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//do add back your 'x' remove here, because it is too verbose to read when I am trying to read the code
manUl.append(nameLi);
});
//list for woman
$.each(womanSafeName, function (key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//Also here, the 'x' for woman list
womanUl.append(nameLi);
});
}
$('#formular').submit(function (e) {
e.preventDefault();
let zadaneJmeno = $('#name').val();
//get the selected gender, either man or woman
let gender = $('#section').val();
console.log(gender);
console.log(zadaneJmeno);
if (zadaneJmeno && gender !== "") {
//safe into the localStorage of selected gender
let safeNameVal = localStorage.getItem(gender);
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
safeName.push(zadaneJmeno);
localStorage.setItem(gender, JSON.stringify(safeName));/// ["Tom"]
//list
displayName();
$('#name').val('');
} else {
// alert
alert('please enter the name"');
$('#name').focus();
}
});
$('#removeAll').click(function () {
localStorage.setItem('woman', '[]'); ///localStorage.setItem('woman', JSON.stringify([]));
displayName();
});
displayName();
});
const katText = document.getElementById('txtKategorie');
const oText=document.querySelector('input[homework="homework"]');
// selektor tlačítka uložit úkol
const oBttn=document.querySelector('input[type="submit"]');
// selektor tlačítka na odstranění všech úkolů z kategorie
const oDelete=document.querySelector('button#removeAll');
const createlist=function(){
let parent=document.getElementById('lists');
Object.keys(localStorage).forEach(function (key) {
let category = key;
let div = document.createElement('div');
div.id = category;
let h1 = document.createElement('h1');
h1.textContent = category;
let ul = document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
div.onclick = oznacDiv;
parent.appendChild(div);
});
parent.querySelectorAll('div').forEach( div=>{
div.addEventListener('click',function(e){
// odstranění určité položky
if( e.target!=e.currentTarget && e.target.tagName=='A') deleteitem( e );
});
// při načtení stránky načíst úkoly z localStorage a vytvoření listu
// podmmínka -- pokud není úložiště prázdné
let store=div.id;
if( localStorage.getItem(store)!=null )JSON.parse( localStorage.getItem( store ) ).forEach( homework=>{
addlistitem(homework,store);
})
});
}
//na klik oznaci div
function oznacDiv() {
if (oBttn.disabled) oBttn.disabled = false;
document.querySelectorAll('div.active').forEach(div => {
div.classList.remove('active')
});
document.querySelector('div#' + this.id).classList.add('active')
}
const clearstoreitems=function(category){
localStorage.setItem( category, JSON.stringify([]) );
document.querySelector( 'div#' + category ).querySelector('ul').innerHTML='';
};
const deleteitem=function(e){
let parent=e.target.parentNode;
let homework=parent.dataset.homework;
let category=parent.dataset.category;
parent.parentNode.removeChild(parent);
let data=JSON.parse(localStorage.getItem(category));
if( data!=null )data.splice(data.indexOf(homework),1);
localStorage.setItem(category,JSON.stringify(data));
};
const addlistitem=function(homework,category){
let p=document.createElement('button');
p.innerHTML=' Uprava';
p.onclick =function(){
editWorking(li);
}
let a=document.createElement('a');
a.href='#';
a.innerHTML=' Hotovo';
let li=document.createElement('li');
li.value=homework;
li.textContent=homework;
li.dataset.homework=homework;
li.dataset.category=category;
li.appendChild( a );
li.appendChild(p);
document.querySelector( 'div#' + category ).querySelector('ul').appendChild( li );
};
function editWorking(e){
let editValue = prompt('Přejete si upravit úkol?', e.firstChild.nodeValue);
e.firstChild.nodeValue = editValue;
let parent=e.parentNode;
let homework=parent.dataset.homework;
let category=parent.dataset.category;
addlistitem(editValue,category);
addstoreitem(editValue,category);
}
const addstoreitem=function(homework,category){
let data=localStorage.getItem( category );
if( data!=null ){
let json=JSON.parse( data );
json.push(homework);
data=JSON.stringify(json);
}
else
{
data=JSON.stringify([homework]);
}
localStorage.setItem( category, data );
};
//prida novej div s kategorii a poznamkou
const addNewItemList = function () {
let parent = document.getElementById('lists');
let category = katText.value;
let div = document.createElement('div');
div.id = category;
let h1 = document.createElement('h1');
h1.textContent = category;
let ul = document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
div.onclick = oznacDiv;
parent.appendChild(div);
parent.querySelectorAll('div').forEach(div => {
div.addEventListener('click', function (e) {
// odstranění určité položky
if (e.target != e.currentTarget && e.target.tagName == 'A') deleteitem(e);
});
// při načtení stránky načíst úkoly z localStorage a vytvoření listu
// podmmínka -- pokud není úložiště prázdné
let store = div.id;
if (localStorage.getItem(store) != null) JSON.parse(localStorage.getItem(store)).forEach(homework => {
addlistitem(homework, store);
})
});
}
oBttn.addEventListener('click',function(e){
e.preventDefault();
if (oText.value != '') {
if (katText.value != '') {
if (document.querySelector('div#' + katText.value) == null) {
addNewItemList()
}
addlistitem(oText.value, katText.value);
addstoreitem(oText.value, katText.value);
oText.value = '';
return true;
} else {
alert('Zadejte kategorii prosím...');
}
} else {
alert('Zadejte úkol prosím...');
}
});
// vymazat, resetovat pole
oDelete.addEventListener('click', function (e) {
document.querySelectorAll('div.active').forEach(div => {
//clearstoreitems(document.querySelectorAll('div.active').id);
clearstoreitems(div.id);
//div.classList.remove('active')
});
});
createlist();
#charset "UTF-8";
/* CSS Document */
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap');
*{
padding: 100;
margin: 100;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
/**styly pro tělo celé aplikace **/
body{
background: rgb(131,58,180);
background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);
/* background: linear-gradient(139deg, rgba(193,62,62,1) 0%, rgba(230,179,50,1) 100%);
background-image: url("pozadi.png");*/
overflow-x: hidden;
background-repeat: no-repeat;
background-size: cover;
background-position: center;
background-attachment: fixed;
height: 100%;
}
.weather{
width: 100%;
margin: 20px;
padding: 30px;
}
/** pomohla jsem si tady https://the-echoplex.net/flexyboxes/ **/
/**
.flex-container {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-align-content: center;
-ms-flex-line-pack: center;
align-content: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.flex-item:nth-child(1) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
.flex-item:nth-child(2) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 0 100 auto;
-ms-flex: 0 100 auto;
flex: 0 100 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
**/
/**nadpis aplikace **/
#nadpis {
/** margin: auto;
width: 50%;
padding: 5px; **/
text-align: center;
font-size: 40px;
}
.predpoved {
/** width: 30%; **/
border-radius: 15px 50px;
border:4px solid white;
background: black;
-webkit-box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
margin:0 auto;
height: 10%;
width:60%;
padding: 0 auto;
}
.nadpis_1{
font-size: 50px;
color:white;
font:bold;
}
label{
color:white;
font:oblique;
text-transform:inherit;
}
#lists > div{
padding:1rem;
margin:1rem auto;
border-radius: 15px 50px;
border:4px solid white;
margin-left: 30px;
margin-right: 30px;
-webkit-box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
}
.active{
background: linear-gradient(90deg, rgba(252,176,69,1) 0%, rgba(253,29,29,1) 50%, rgba(131,58,180,1)100%);
}
h1{
text-transform:capitalize;
color:white;
}
ul{
list-style: square;
}
ul li{
color:white;
margin-top: 40px;
font-size: 20px;
}
ul a {
color:white;
font:oblique;
padding: 10px;
margin:10px;
margin-left:100px;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
}
ul a:hover {
color:white;
font:oblique;
background:rgba(252,176,69,1);
padding: 10px;
margin:10px;
margin-left:100px;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
}
form{
color: white;
padding: 20px;
width: 600px;
margin: 0 auto;
height: auto;
}
#removeAll{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding:10px;
margin-left: 30px;
margin-right: 30px;
}
#removeAll:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
margin-left: 30px;
margin-right: 30px;
}
#refresh{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding: 10px;
}
#refresh:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
}
#safe{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding: 10px;
}
#safe:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Deadline</title>
<link rel="stylesheet" href="style.css">
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="flex-container">
<div id="nadpis">
<h1>Deadline</h1>
<form>
<label for="txtHomework">Your homework.. </label>
<input type="text" id="txtHomework" homework="homework" required />
<label for="txtKategorie">Category</label>
<input type="text" id="txtKategorie" kategorie="valKategorie" required />
<!--<select name="selectSection" required>
<option selected hidden disabled>---</option>
<option value="škola">Škola</option>
<option value="Práce">Práce</option>
<option value="Doma">Doma</option>
<option value="Jiné">Jiné</option>
</select>-->
<!--</label>-->
<!-- tlačítko uložit je nedostupné dokud nevybereme kategorii a nezapíšeme úkol -->
<input id ="safe" type="submit" value="Uložit" />
</form>
<div id="lists"></div>
<button id="removeAll">Vyčistit kategorii</button>
I know you already have a solution but I offer an alternative, in vanilla Javascript rather than jQuery, that splits the names according to gender - assigns them to individual areas in localStorage based upon gender and has the functionality to remove individual items from the store. Any items stored in any of the generated stores will be used to populate the HTML lists on page load. I don't use jQuery which is why I wrote this in plain js - no doubt you can cherrypick things from it that might be useful - I hope that it is useful anyway.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Gender splitter</title>
<style>
#lists > div{
padding:1rem;
margin:1rem auto;
border:1px dotted gray;
}
.active{
background:whitesmoke
}
h1{text-transform:capitalize}
</style>
</head>
<body>
<form>
<label>Enter the name
<input type='text' name='name' required />
</label>
<label>Gender
<select name='selectSection' required>
<option selected hidden disabled>---
<option value='male'>Male
<option value='female'>Female
<option value='teapot'>Teapot
<option value='crocodile'>Crocodile
</select>
</label>
<!-- initially disabled to prevent adding when no gender is selected -->
<input type='submit' value='add' disabled />
</form>
<button id='removeAll'>Remove</button>
<div id='lists'></div>
<script>
const oSelect=document.querySelector('select[name="selectSection"]');
const oText=document.querySelector('input[name="name"]');
const oBttn=document.querySelector('input[type="submit"]');
const oDelete=document.querySelector('button#removeAll');
// generate the necessary HTML nodes to display names/genders based
// upon the options in the select menu.
const createlist=function(){
let parent=document.getElementById('lists');
oSelect.querySelectorAll('option').forEach( option=>{
if( option.value !== oSelect.childNodes[1].value ){
let gender=option.value;
let div=document.createElement('div');
div.id=gender;
let h1=document.createElement('h1');
h1.textContent=gender;
let ul=document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
parent.appendChild( div );
}
});
parent.querySelectorAll('div').forEach( div=>{
div.addEventListener('click',function(e){
// delete specific item from the store
if( e.target!=e.currentTarget && e.target.tagName=='A') deleteitem( e );
});
// load any names from the store on page load and recreate the lists
let store=div.id;
if( localStorage.getItem(store)!=null )JSON.parse( localStorage.getItem( store ) ).forEach( name=>{
addlistitem(name,store);
})
});
}
// erase store content by gender and clear html list display
const clearstoreitems=function(gender){
localStorage.setItem( gender, JSON.stringify([]) );
document.querySelector( 'div#' + gender ).querySelector('ul').innerHTML='';
};
// delete specific item from particular store
const deleteitem=function(e){
let parent=e.target.parentNode;
let name=parent.dataset.name;
let gender=parent.dataset.gender;
parent.parentNode.removeChild(parent);
let data=JSON.parse(localStorage.getItem(gender));
if( data!=null )data.splice(data.indexOf(name),1);
localStorage.setItem(gender,JSON.stringify(data));
};
// add new item to HTML list based upon gender
const addlistitem=function(name,gender){
let a=document.createElement('a');
a.href='#';
a.innerHTML='X';
let li=document.createElement('li');
li.value=name;
li.textContent=name;
li.dataset.name=name;
li.dataset.gender=gender;
li.appendChild( a );
document.querySelector( 'div#' + gender ).querySelector('ul').appendChild( li );
};
// add new name to the localStorage in gender specific named store
const addstoreitem=function(name,gender){
let data=localStorage.getItem( gender );
if( data!=null ){
let json=JSON.parse( data );
json.push(name);
data=JSON.stringify(json);
} else { data=JSON.stringify([name]); }
localStorage.setItem( gender, data );
};
// Add new item listener
oBttn.addEventListener('click',function(e){
e.preventDefault();
if( oText.value!='' ){
addlistitem(oText.value,oSelect.value);
addstoreitem(oText.value,oSelect.value);
oText.value='';
return true;
}
alert('Name please...');
});
oSelect.addEventListener('change',function(e){
// ensure the "Add" button is enabled
if( oBttn.disabled )oBttn.disabled=false;
document.querySelectorAll('div.active').forEach( div=>{
div.classList.remove('active')
});
// assign a class to visually identify which gender is selected
document.querySelector( 'div#' + this.value ).classList.add('active')
});
// erase this entire store - reset to empty array
oDelete.addEventListener('click',function(e){
clearstoreitems(oSelect.value);
});
createlist();
</script>
</body>
</html>

How to style array elements separately

I have recently taken up programming and my first task is to create a queue at the post office. The code kind of works and does everything I need, except, I need the input array elements to be displayed with some style, more like separate squares with names (similarly to the way the buttons are styled), not only in line separated by commas - see the demo below please.
var guests = new Array();
for (var i=0;i<10;i++){
guests[i] = prompt("Enter your name");
if (guests[0] == null) {
alert("No guests in a queue");
break;
} else if (guests[i] == null) {
break;
} else {
document.getElementById("queue").innerHTML=guests;
}
}
function removePeople() {
guests.shift();
document.getElementById("queue").innerHTML=guests;
}
function reversePeople() {
guests.reverse();
document.getElementById("queue").innerHTML=guests;
}
button:hover {
background-color:beige;
color:black;
}
.button {
background-color: green;
border: 2px solid black;
border-radius:4px;
color: white;
padding: 5px 15px;
text-align: center;
font-size: 16px;
margin: 4px 2px;
}
<body>
<p id="queue"></p>
<button class="button" onclick ="removePeople()">Next</button>
<button class="button" onclick ="reversePeople()">Reverse</button>
</body>
I tried hard to find some hints here but everything seems too complicated for my level of understanding. So, if there is no easy way, I would rather ask for some specific materials where I could find how to deal with it. I am learning through W3Schools and also reading Eloquent Javascript publication, but coulnd't find anything concerning my problem. I hope my question makes sense.
Also, if you have any idea how to logically improve the code, I am open to any discussion.
I've tried to keep your code mostly the same.
To be able to change the css of a single queue item you need to wrap that item in something (in this example i've used a span)
I've created a function createQueueItemsHtml() that returns the array items wrapped in a span now you can use the following css selector to add css to each item #queue span
var guests = new Array();
for (var i = 0; i < 3; i++) {
var guestInput = prompt("Enter your name");
if(guestInput != "") {
guests[i] = guestInput;
}
if (guests[0] == null) {
alert("No guests in a queue");
break;
} else if (guests[i] == null) {
break;
} else {
document.getElementById("queue").innerHTML = createQueueItemsHtml();
}
}
function removePeople() {
guests.shift();
document.getElementById("queue").innerHTML = createQueueItemsHtml();
}
function reversePeople() {
guests.reverse();
document.getElementById("queue").innerHTML = createQueueItemsHtml();
}
function createQueueItemsHtml() {
let queueString = "";
for (var ii = 0; ii < guests.length; ii++) {
queueString += "<span>" + guests[ii] + "</span>";
}
return queueString;
}
button:hover {
background-color: beige;
color: black;
}
.button {
background-color: green;
border: 2px solid black;
border-radius: 4px;
color: white;
padding: 5px 15px;
text-align: center;
font-size: 16px;
margin: 4px 2px;
}
#queue span {
background-color: green;
border: 2px solid black;
border-radius: 4px;
color: white;
padding: 5px 15px;
}
<p id="queue"></p>
<button class="button" onclick ="removePeople()">Next</button>
<button class="button" onclick ="reversePeople()">Reverse</button>
You can make your guests into <div> elements and then style those in any way you want or need. (I haven't touched the rest of your code, only the part that was needed for this particular thing)
Just change this bit
else {
document.getElementById("queue").innerHTML=guests;
}
To this:
} else {
var guest = document.createElement('div');
guest.classList.add('guest');
guest.innerHTML = guests[i];
document.getElementById("queue").appendChild(guest);
}
What it does is create a <div> element for each item in your guests array, add class="guest" to the element and add the name from your prompt to it. Then it appends this element to the #queue.
Your HTML would then look like this:
<p id="queue">
<div class="guest">john</div>
<div class="guest">doe</div>
</p>
I would suggest changing the <p> to <section> or something like that, just for the sake of semantics.
You can then style these elements like this:
.guest {
}
var guests = new Array();
for (var i=0;i<10;i++){
guests[i] = prompt("Enter your name");
if (guests[0] == null) {
alert("No guests in a queue");
break;
} else if (guests[i] == null) {
break;
} else {
var guest = document.createElement('div');
guest.classList.add('guest');
guest.innerHTML = guests[i];
document.getElementById("queue").appendChild(guest);
}
}
guest:hover {
background-color:beige;
color:black;
}
.guest {
background-color: green;
border: 2px solid black;
border-radius:4px;
color: white;
padding: 5px 15px;
text-align: center;
font-size: 16px;
margin: 4px 2px;
display: inline-block
}
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<p id="queue"></p>
</body>
</html>

localStorage does not save/show items

I do my ToDo list. (I learn vanilla JS). And I have some problem with saving some items to localStorage. When I use Google chrome(F12), I see undefiend. Maybe, I do not save correctly to localStorage. I tried to change var task to array, but it does not help. Pleas, show me my mistakes. I know, my code must be rewritten, it is my first code on JS. P.s. in console (in stackOverflow) I have that error
{
"message": "Uncaught SyntaxError: Unexpected identifier",
"filename": "https://stacksnippets.net/js",
"lineno": 348,
"colno": 6
}
but in my browser not.
var task = document.querySelector("ul");
var forTask;
function toLocal(){
forTask = task.innerHTML;
localStorage.setItem("forLocal",forTask);
}
function newElement(newChild) {
let btnDel= document.createElement("button");
btnDel.className = "fa fa-trash-o";
let myEd = document.getElementById("myEdit");
let spanClose1 = document.getElementsByClassName("close1")[0];
let spanRedact = document.getElementsByClassName("redact")[0];
let myDel = document.getElementById("myDelete");
let spanClose = document.getElementsByClassName("close")[0];
let spanYes = document.getElementsByClassName("yes")[0];
//create button
let divWithBut = document.createElement("div");
divWithBut.className = "forButt";
let btnRedact = document.createElement("button");
btnRedact.className = "fa fa-pencil";
//redact but
btnRedact.onclick = function(){
myEd.style.display = "block";
let editText = document.getElementById("editText");
let divWithText = divWithBut.parentElement.getElementsByClassName("todoPost")[0];
editText.value = divWithText.innerHTML;
editText.currentTarget;
spanRedact.onclick = function(){
divWithText.textContent = editText.value;
divWithText.className = "todoPost";
myEd.style.display = "none";
};
spanClose1.onclick = function() {
myEd.style.display = "none";
};
}
/*************************** */
/*done but*/
let doneBut = document.createElement("button");
doneBut.className = "fa fa-check-circle-o";
doneBut.onclick = function(){
let divWithText = divWithBut.parentElement.getElementsByClassName("todoPost")[0];
divWithText.classList.toggle("checked");
}
/******************* */
divWithBut.appendChild(btnRedact);
divWithBut.appendChild(doneBut);
divWithBut.appendChild(btnDel);
/******************/
//for index
let indexDiv = document.createElement("div");
indexDiv.className = "indexDiv";
let numbInd = 1;
indexDiv.innerHTML = numbInd;
/*********************************** */
//create arrow
let divWithArrow = document.createElement("div");
divWithArrow.className = "myArrow";
let arrowUP = document.createElement("i");
arrowUP.className = "fa fa-chevron-up";
let arrowDown = document.createElement("i");
arrowDown.className = "fa fa-chevron-down";
divWithArrow.appendChild(arrowUP);
divWithArrow.appendChild(arrowDown);
//for date
let date = new Date();
let curr_date = date.getDate();
let curr_month = date.getMonth()+1;
let curr_year = date.getFullYear();
let curr_hour = date.getHours();
let curr_minutes = date.getMinutes();
let d = (curr_date + "." + curr_month + "." + curr_year+"<br>"+curr_hour+":"+curr_minutes);
let divTime = document.createElement("div");
divTime.style.textAlign = "center";;
divTime.innerHTML = d;
//***************************/
let div1 = document.createElement("div");
div1.className = "timeComent";
let myli = document.createElement("li");
myli.className = "todoPost";
let addField = document.getElementById("addField").value;
task = document.createTextNode(addField);
myli.appendChild(task);
div1.appendChild(divTime);
div1.appendChild(indexDiv);
div1.appendChild(divWithArrow);
div1.appendChild(myli);
divWithBut.style.display = "flex";
div1.appendChild(divWithBut);
if (addField === '') {
alert("You must write something!");
} else {
document.getElementById("forToDo").appendChild(div1);
toLocal();
}
document.getElementById("addField").value = "";
//delete but
btnDel.onclick = function(){
myDel.style.display = "block";
spanClose.onclick = function() {
myDel.style.display = "none";
};
spanYes.onclick = function() {
myDel.style.display = "none";
div1.remove();
};
}
toLocal();
}
if(localStorage.getItem("forLocal")){
task.innerHTML = localStorage.getItem("forLocal");
}
*{
margin: 0;
padding: 0;
}
header{
width: 100%;
display: flex;
align-items: center;
align-content: center;
justify-content: center;
overflow: auto;
}
.firstBar{
width: 100%;
display: flex;
align-items: center;
align-content: center;
justify-content: center;
overflow: auto;
}
.indexDiv{
font-style: normal;
text-align: center;
color: #fff;
width: 15px;
height: 20px;
margin: 10px;
background-color: #888;
}
.fafaArrow{
font-size: 24px;
color: #000;
}
.timeComent{
margin-top: 15px;
margin-bottom: 15px;
display: flex;
justify-content:center;
align-items: center;
}
.numberpost{
padding: 5px;
color: rgb(255, 255, 255);
background: rgb(141, 112, 112);
}
.todoPost{
background-color: #eee;
width: 50%;
margin: 5px;
overflow: auto;
text-align: justify;
}
.shadow {
background: rgba(102, 102, 102, 0.5);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: none;
}
.window {
width: 300px;
height: 50px;
text-align: center;
padding: 15px;
border: 3px solid #0000cc;
border-radius: 10px;
color: #0000cc;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
background: #fff;
}
.shadow:target {display: block;}
.redact {
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.redact:hover {
background-color: #68f462;
color: white;}
.close{
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close:hover{
background-color: #f44336;
color: white;
}
/* Style the close button */
.close3 {
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.yes {
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.yes:hover{
background-color: #68f462;
color: white;
}
.close1{
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close1:hover{
background-color: #f44336;
color: white;
}
/* When clicked on, add a background color and strike out text */
div li.checked {
background: #888;
color: #fff;
text-decoration: line-through;
}
/* Add a "checked" mark when clicked on */
div li.checked::before {
content: '';
position: absolute;
border-color: #fff;
border-style: solid;
border-width: 0 2px 2px 0;
top: 10px;
left: 16px;
transform: rotate(45deg);
height: 15px;
width: 7px;
}
<!DOCTYPE html>
<html>
<head>
<title>TO DO List</title>
<link rel="stylesheet" type="text/css" href="styles/style.css" >
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<header>
<input id="addField" type="text" size="70%" placeholder="Task" name="Task">
<button type="button" onclick="newElement()">Add</button>
</header>
<div>
<div class="firstBar">
<div class="fafaArrow">
<i class="fa fa-caret-up" ></i>
<i class="fa fa-caret-down"></i>
<input class="inptxt" type="text" size="50%" name="Task">
<i class="fa fa-filter"></i>
</div>
</div>
</div>
<ul id="forToDo" >
</ul>
<div id="myDelete" class="shadow">
<div class="window">Delete item?<br>
<span class="yes">Yes</span>
<span class="close">No</span>
</div>
</div>
<div id="myEdit" class="shadow">
<div class="window">
Edit text?<br>
<label>
<textarea id="editText"></textarea>
</label>
<span class="redact">Save</span>
<span class="close1">Cancel</span>
</div>
</div>
<script src="js/script2.js"></script>
</body>
</html>
When you add an element to the page, at a certain point you do this
task = document.createTextNode(addField);
Since task is a global variable (you declared it at the top), you're overshadowing it with the TextNode you're creating, so that when you then call toLocal and you do
forTask = task.innerHTML;
task has no innerHTML attribute, so it returns undefined.
Also, for some reason, you call toLocal again at the end of newElement. It's not the problem but it's something you may want to think about. I'm not sure it's what you want.
#TakayashiHarano gave a couple of hints to solve this, but I'm not sure what you want is just to have the latest element in the local storage. So I would re-write toLocal so that it takes a string (the text of the item) as input, writes it at the end of a JSON array (already populated with what was in the local storage previously), and puts the array back in local storage.
function toLocal(toAdd) {
let storage = localStorage.getItem('forLocal');
if (storage === null) {
storage = [];
} else {
storage = JSON.parse(storage);
}
storage.push(toAdd);
localStorage.setItem('forLocal', JSON.stringify(storage));
}
Then you should modify the part of the code that reads the local storage (the one at the end) to basically simulate adding a new item as you would do when creating a new task, but for each item in the parsed JSON coming from local storage.
To be fair, your code needs a good dose of rewriting to achieve this, so I'll just leave you with this as an exercise.
The following changes are needed.
1 - Set up two variables separably for the following task variable.
var task = document.querySelector("ul");
task = document.createTextNode(addField);
For example, "ulElement" for the first one, and "task" for the second one.
This is to prevent to override the previously defined value.
2 - Move the timing for obtaining the ul element and load localStorage.
function onReady() {
ulElement = document.querySelector("ul");
if(localStorage.getItem("forLocal")){
ulElement.innerHTML = localStorage.getItem("forLocal");
}
}
window.addEventListener('DOMContentLoaded', onReady, true);
To ensure the element existence, document.querySelector() should be called after the DOMContentLoaded event fired.
https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
3 - Delete toLocal(); in the end of the newElement() function.
As far as my testing code, there is no need this statement.

Categories