JavaScript - Onclick navigation arrow function issue - javascript

I'm trying to be create a simple app with a navigation function. My issue is that when the user clicks the navigation it pops up but if the user click outside the navigation content, the content disappears and the navigation arrow doesn't work. Given below is my code,
const menuButtons = document.querySelectorAll('.clickfun');
menuButtons.forEach(button => button.addEventListener('click', toggleButton, false));
function toggleButton() {
const id = this.dataset.id;
const panel = document.getElementById(id);
if (panel.style.display === 'block') {
panel.style.display = 'none';
} else {
panel.style.display = 'block';
}
}
var boxArray = ['box1','box2'];
window.addEventListener('mouseup', function(event) {
for(var i=0; i < boxArray.length; i++){
var box = document.getElementById(boxArray[i]);
if(event.target != box && event.target.parentNode != box) {
box.style.display = 'none';
}
}
});
var anchors = Array.from(document.querySelectorAll('a'));
anchors.map(anchor => {
if(anchor.classList.contains('btn-open') || anchor.classList.contains('btn-down')) {
anchor.addEventListener('click', () => {
if(anchor.classList.contains('btn-open')) {
anchor.classList.remove('btn-open');
anchor.classList.add('btn-down');
}
else {
anchor.classList.add('btn-open');
anchor.classList.remove('btn-down');
}
});
}
});
#box1 {
position: absolute;
top: 67px;
left: 140px;
width: 260px;
height: 55px;
padding: 6px;
display: none;
background: #E2E2E2;
}
.btn-open:after, a {
font-family: "FontAwesome";
content: "\f0de";
color: #333;
font-size: 18px;
}
.btn-down:after, a {
font-family: "FontAwesome";
content: "\f0dd";
color: #333;
font-size: 18px;
text-decoration: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>
<div id="box1">
<h2>Options Main Page</h2>
</div>
<h2>Page Content....</h2>
<div id="box2">
<h2>Pops Out two</h2>
</div>
<nav>
<a data-id="box1" class="clickfun btn-down " href="javascript:void(0);"> About us </a><br>
I would really appreciate some help with this. Thanks.

What you need is this in window.addEventListener('mouseup', function(event) { you need to prevent displaying none if click is on clickfun.
!event.target.classList.contains('clickfun')
Please check code here
const menuButtons = document.querySelectorAll('.clickfun');
menuButtons.forEach(button => button.addEventListener('click', toggleButton, false));
function toggleButton() {
const id = this.dataset.id;
const panel = document.getElementById(id);
if (panel.style.display === 'block') {
panel.style.display = 'none';
} else {
panel.style.display = 'block';
}
ChangeArrows();
}
var boxArray = ['box1', 'box2'];
window.addEventListener('mouseup', function(event) {
for (var i = 0; i < boxArray.length; i++) {
var anchor = document.querySelectorAll('.clickfun');
var box = document.getElementById(boxArray[i]);
if (event.target != box && !boxArray.some(a=> a===event.target.parentNode.id) && !event.target.classList.contains('clickfun') && anchor[0].classList.contains('btn-open')) {
box.style.display = 'none';
ChangeArrows();
event.preventDefault();
return;
}
}
});
function ChangeArrows() {
var anchor = document.querySelectorAll('.clickfun');
if (anchor[0].classList.contains('btn-open')) {
anchor[0].classList.remove('btn-open');
anchor[0].classList.add('btn-down');
} else {
anchor[0].classList.add('btn-open');
anchor[0].classList.remove('btn-down');
}
}
#box1 {
position: absolute;
top: 67px;
left: 140px;
width: 260px;
height: 55px;
padding: 6px;
display: none;
background: #E2E2E2;
}
.btn-open:after,
a {
font-family: "FontAwesome";
content: "\f0de";
color: #333;
font-size: 18px;
}
.btn-down:after,
a {
font-family: "FontAwesome";
content: "\f0dd";
color: #333;
font-size: 18px;
text-decoration: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
<div id="box1">
<h2>Options Main Page</h2>
</div>
<h2>Page Content....</h2>
<div id="box2">
<h2>Pops Out two</h2>
</div>
<nav>
<a data-id="box1" class="clickfun btn-down" href="javascript:void(0);"> About us </a><br>

Related

Is there any other way to sort a drag and drop todo list without using the index of the items?

I'm working on a javascript to-do list where you can view all the elements on the list or you can view just the active items or the completed items.
Each of the views has its own array which I sorted out using the index of each element
but when I reorder the list on one of the views, the change is not implemented in the other views.
How do I rectify this?
const dragArea1 = document.querySelector('#task1');
const dragArea2 = document.querySelector('#task2');
const dragArea3 = document.querySelector('#task3');
const addnew = document.querySelector('[name="addnew"]')
const add = document.querySelector('[name="new"]')
const countIt = document.querySelector('#count')
var all = [];
var active = [];
var complete = [];
var lists = document.querySelectorAll('ul');
var views = document.querySelectorAll('.action .views a');
var mobileViews = document.querySelectorAll('#views a');
var list = document.querySelector('.list');
countIt.innerHTML = active.length;
addnew.addEventListener('click', () => {
var newItem
if (addnew.checked == true) {
newItem = {
val: add.value,
checked: false
}
all.push(newItem);
active.push(newItem);
window.setTimeout(() => {
addnew.checked = false;
add.value = '';
}, 300);
displayAll();
count();
}
})
list.addEventListener('click', (ev) => {
if (ev.target.tagName === 'LABEL' || ev.target.tagName === 'P' || ev.target.tagName === 'LI') {
ev.target.classList.toggle('checked');
sortAllList();
if (lists[1].style.display == 'block') {
activeToComplete();
}
if (lists[2].style.display == 'block') {
completeToActive();
}
sortActive();
sortComplete();
}
if (all.length == 0) {
var htmlCode = `<em style="text-align: center; width: 100%; padding: 20px;">add a todo item</em>`;
lists[0].innerHTML = htmlCode;
}
if (active.length == 0) {
var htmlCode = `<em style="text-align: center; width: 100%; padding: 20px;">add a todo item</em>`;
lists[1].innerHTML = htmlCode;
}
if (complete.length == 0) {
var htmlCode = `<em style="text-align: center; width: 100%; padding: 20px;">complete a todo item</em>`;
lists[2].innerHTML = htmlCode;
}
// console.log(ev.target.tagName);
})
function count() {
// to keep count of active items
countIt.innerHTML = active.length;
}
views[0].classList.add('view')
mobileViews[0].classList.add('view')
function displayAll() {
sortActive();
sortComplete();
var htmlCode = "";
if (all.length !== 0) {
for (let i = 0; i < all.length; i++) {
htmlCode += `
<li draggable="true">
<div class="check">
<input type="checkbox" name="listItem" id="item${i}">
<label for="item${i}"></label>
</div>
<p class="itemdesc">${all[i].val}</p>
<span onclick="del(${i})">╳</span>
</li>
`
}
lists[0].innerHTML = htmlCode;
}
lists[0].style.display = 'block';
lists[1].style.display = 'none';
lists[2].style.display = 'none';
views[0].classList.add('view')
views[1].classList.remove('view')
views[2].classList.remove('view')
mobileViews[0].classList.add('view')
mobileViews[1].classList.remove('view')
mobileViews[2].classList.remove('view')
count()
keepChecked();
}
function sortActive() {
// to add active items to the active array
var fit
fit = all.filter(el => el.checked == false)
active = fit
count();
}
function sortComplete() {
//to add completed items to the complete array
var com
com = all.filter(el => el.checked == true)
complete = com
// console.log('complete', complete);
}
function sortAllList() {
// to sort the items into active and completed
const items = document.querySelectorAll('#task1 li');
for (let i = 0; i < all.length; i++) {
if (items[i].classList.contains('checked') == true) {
all[i].checked = true
} else {
all[i].checked = false
}
}
}
function activeToComplete() {
let newA
const items = document.querySelectorAll('#task2 li')
for (let i = 0; i < active.length; i++) {
if (items[i].classList.contains('checked') == true) {
active[i].checked = true;
// active.splice(i,1);
// console.log(active.splice());
} else {
active[i].checked = false
}
}
newA = active.filter(el => el.checked !== true)
console.log(newA);
active = newA;
}
function keepChecked() {
// to keep the completed items checked afetr changing views
const allItems = document.querySelectorAll('#task1 li');
for (let i = 0; i < all.length; i++) {
if (all[i].checked == true) {
allItems[i].classList.add('checked')
}
}
}
function completeToActive() {
const items = document.querySelectorAll('#task3 li')
for (let i = 0; i < complete.length; i++) {
if (items[i].classList.contains('checked') == true) {
complete[i].checked = true;
} else {
complete[i].checked = false
complete.splice(i, 1);
console.log(complete.splice());
}
}
}
function displayActive() {
sortAllList();
sortActive();
var htmlCode = "";
if (active.length !== 0) {
for (let i = 0; i < active.length; i++) {
htmlCode += `
<li draggable="true">
<div class="check">
<input type="checkbox" name="listItem" id="item${i}">
<label for="item${i}"></label>
</div>
<p class="itemdesc">${active[i].val}</p>
<span onclick="del(${i})">╳</span>
</li>
`
}
lists[1].innerHTML = htmlCode;
}
lists[1].style.display = 'block';
lists[0].style.display = 'none';
lists[2].style.display = 'none';
views[1].classList.add('view')
views[0].classList.remove('view')
views[2].classList.remove('view')
mobileViews[1].classList.add('view')
mobileViews[0].classList.remove('view')
mobileViews[2].classList.remove('view')
count()
}
function displayCompleted() {
let unique = [...new Set(complete)]
// console.log(unique[0].val);
var htmlCode = "";
if (unique.length !== 0) {
for (let i = 0; i < unique.length; i++) {
htmlCode += `
<li draggable="true" class="checked">
<div class="check">
<input type="checkbox" name="listItem" id="item${i}">
<label for="item${i}"></label>
</div>
<p class="itemdesc">${unique[i].val}</p>
<span onclick="del(${i})">╳</span>
</li>
`
}
lists[2].innerHTML = htmlCode;
}
lists[2].style.display = 'block';
lists[1].style.display = 'none';
lists[0].style.display = 'none';
views[2].classList.add('view')
views[0].classList.remove('view')
views[1].classList.remove('view')
mobileViews[2].classList.add('view')
mobileViews[1].classList.remove('view')
mobileViews[0].classList.remove('view')
count()
}
function clearComplete() {
var htmlCode = `<em style="text-align: center; width: 100%; padding: 20px;">complete a todo item</em>`;
complete = [];
lists[2].innerHTML = htmlCode;
}
function del(theIndex) {
let i = theIndex;
if (lists[0].style.display == 'block') {
all.splice(i, 1);
displayAll();
}
if (lists[1].style.display == 'block') {
active.splice(i, 1);
let removeFromAll = all.find(el => {
el == active.splice()
})
all.splice(removeFromAll, 1);
displayActive();
}
if (lists[2].style.display == 'block') {
complete.splice(i, 1);
let removeFromAll = all.find(el => {
el == complete.splice()
})
all.splice(removeFromAll, 1);
displayCompleted();
}
sortActive();
sortComplete();
}
new Sortable(dragArea1, {
animation: 350
})
new Sortable(dragArea2, {
animation: 350
})
new Sortable(dragArea3, {
animation: 350
})
:root {
--blue: hsl(220, 98%, 61%);
/* vd -> Very Drak */
--vdblue: hsl(235, 21%, 11%);
--vdDesaturatedblue: hsl(235, 24%, 19%);
--lightgrayblue: hsl(234, 39%, 85%);
--lightgrayblueh: hsl(236, 33%, 92%);
--darkgrayblue: hsl(234, 11%, 52%);
--vdGrayishblueh: hsl(233, 14%, 35%);
--vdGrayishblue: hsl(237, 14%, 26%);
--checkbg: linear-gradient(rgba(87, 221, 255, .7), rgba(192, 88, 243, .7));
--font: 'Josefin Sans', sans-serif;
font-size: 18px;
}
* {
padding: 0;
margin: 0;
font-family: var(--font);
/* font-weight: 700; */
}
*,
*::after,
*::before {
box-sizing: border-box;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
border: none;
-webkit-text-fill-color: white;
background-color: transparent !important;
-webkit-box-shadow: 0 0 0px 1000px #00000000 inset;
transition: background-color 5000s ease-in-out 0s;
}
input:focus, input:active, input:visited, textarea:focus, textarea:active, textarea:visited{
background-color: transparent;
border: none;
outline: none;
}
a, em, span{
display: inline-block;
cursor: pointer;
}
a{
text-decoration: none;
display: inline-block;
}
header, main, footer{
width: 100%;
max-width: 30rem;
padding: 10px;
}
main {
display: flex;
flex-direction: column;
gap: 30px;
align-items: center;
}
main #new,
li {
display: flex;
align-items: center;
gap: 20px;
padding: 1rem;
width: 100%;
}
main section,
main #views {
width: 100%;
}
main section,
main #new,
main #views {
border-radius: 5px;
}
main .list {
min-height: 2.5rem;
max-height: 20rem;
/* height: 10rem; */
position: relative;
overflow-y: auto;
}
main .list ul {
/* position: absolute; */
/* top: 20px; */
width: 100%;
display: none;
}
main .list ul:nth-child(1) {
display: block;
}
main #new input[name="new"] {
padding: 10px;
height: inherit;
}
input {
background-color: transparent;
width: calc(100% - 70px);
border: none;
font-size: 1rem;
}
li {
justify-content: flex-start;
}
li .check {
position: relative;
}
main #new .check input,
li .check input {
display: none;
}
main #new .check label,
li .check label {
width: 30px;
height: 30px;
border-radius: 30px;
display: inline-block;
}
main #new .check input:checked~label,
li.checked .check label {
background-image: var(--checkbg), url(images/icon-check.svg);
background-position: center center;
background-repeat: no-repeat;
}
li p {
width: 85%;
}
li.checked label {
background-color: #66666696;
}
li.checked p {
text-decoration: line-through;
}
li span {
/* justify-self: flex-end; */
display: none;
}
li:hover span {
display: flex;
}
main .action {
display: flex;
justify-content: space-between;
/* gap: 2rem; */
padding: 1.1rem;
font-size: .8rem;
}
.views a,
#views a {
font-weight: 700;
}
.action a.view {
color: var(--blue);
}
main #views {
padding: .8rem;
text-align: center;
font-size: .8rem;
display: none;
}
#views a.view {
color: var(--blue);
}
main #views+p {
font-size: .7rem;
}
li,
em {
border-bottom: 1px solid var(--darkgrayblue);
}
li,
li p,
main .action a:hover {
color: var(--lightgrayblue);
}
a,
em,
li.checked p,
p,
span,
input,
li span {
color: var(--darkgrayblue);
}
header img {
content: url("images/icon-sun.svg");
}
main #new {
background-color: var(--vdDesaturatedblue);
}
main #new .check label,
li .check label {
border: 1px solid var(--vdGrayishblue);
}
main #new .check label:hover,
li .check label:hover {
border: 1px solid var(--vdGrayishblue);
}
main section,
main #views {
background-color: var(--vdDesaturatedblue);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.0/Sortable.min.js"></script>
<main role="main">
<div id="new">
<div class="check">
<input type="checkbox" name="addnew" id="addnew">
<label for="addnew"></label>
</div>
<input type="text" name="new" placeholder="Create a new todo...">
</div>
<section>
<div class="list">
<ul id="task1">
<em style="text-align: center; width: 100%; padding: 20px;">add a todo item</em>
</ul>
<ul id="task2">
<em style="text-align: center; width: 100%; padding: 20px;">add a todo item</em>
</ul>
<ul id="task3">
<em draggable="true" style="text-align: center; width: 100%; padding: 20px;">complete a todo item</em>
</ul>
</div>
<div class="action">
<p>
<span id="count"></span> items left
</p>
<div class="views">
All
Active
Completed
</div>
Clear Completed
</div>
</section>
<div id="views">
All
Active
Completed
</div>
<p>Drag and drop to reorder list</p>
</main>

JavaScript, how to limit todo list number?

I was making a to-do list and I couldn't figure out how can I limit the number of creating li. I want to stop it from creating li when it reaches 4 li by not showing it on ul and stop submitting it. This is the one I wrote. If anyone can give me advice or ideas on how to solve this one. Thank you.
const form = document.querySelector('form')
const input = document.querySelector('input')
const memo = document.querySelector('ul')
form.addEventListener('submit', function(e) {
const line = document.ul.child
if (line > 5) {
e.preventDefault()
ToDo()
input.value = ""
}
})
function ToDo() {
if (input.value == '') {
alert('please write')
} else {
const value = input.value
const newList = document.createElement('li')
newList.textContent = value
memo.append(newList)
const deleteBtn = document.createElement('button')
newList.append(' ', ' ', deleteBtn)
deleteBtn.textContent = "DELETE"
console.log(newList)
}
}
memo.addEventListener('click', function(e) {
if (e.target.nodeName === 'BUTTON') {
e.target.closest('LI').remove();
}
})
whole code: here
This lineconst line = document.ul.child would give an error, as it is not valid way to query things from the DOM. Also e.preventDefault() shouldn't be in the if block even if it were correct. This would work:
const form = document.querySelector("form");
const input = document.querySelector("input");
const memo = document.querySelector("ul");
form.addEventListener("submit", function (e) {
e.preventDefault();
const liNumber = document.querySelectorAll("ul li").length;
if (liNumber < 4) {
ToDo();
input.value = "";
} else {
alert("Maximum number reached");
}
});
function ToDo() {
if (input.value == "") {
alert("please write");
} else {
const value = input.value;
const newList = document.createElement("li");
newList.textContent = value;
memo.append(newList);
const deleteBtn = document.createElement("button");
newList.append(" ", " ", deleteBtn);
deleteBtn.textContent = "DELETE";
}
}
memo.addEventListener("click", function (e) {
if (e.target.nodeName === "BUTTON") {
e.target.closest("LI").remove();
}
});
body {
background-image: linear-gradient(
83.2deg,
rgba(150, 93, 233, 1) 10.8%,
rgba(99, 88, 238, 1) 94.3%
);
}
h1 {
text-align: center;
font-size: 50px;
font-weight: 500;
font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande",
"Lucida Sans Unicode", Geneva, Verdana, sans-serif;
color: #fbfbf2;
}
.option {
margin-top: 4rem;
display: flex;
justify-content: center;
align-content: center;
flex-direction: row-reverse;
}
#input {
width: 400px;
height: 60px;
border-radius: 10px;
box-shadow: none;
font-size: 20px;
}
#submit {
margin-right: 5px;
padding: 10px 10px;
border-radius: 10px;
background-color: #5a189a;
color: #fbfbf2;
}
#input,
#submit {
padding: 10px 10px;
border: none;
}
.lists {
background-color: #efd9ce;
height: 400px;
border-radius: 15px;
}
.memo {
padding: 15px;
font-size: 30px;
}
ul li {
margin: 20px;
}
button {
background-color: #5a189a;
border-radius: 15px;
color: #fbfbf2;
font-size: 20px;
}
<form>
<h1>TO DO LIST</h1>
<div class="option">
<input type="text" id="input" placeholder="enter a task" />
<button type="submit" id="submit">SUBMIT</button>
</div>
</form>
<div class="lists">
<ul class="memo"></ul>
</div>

Javascript todo list app. I can't delete the last remaining li and clear all button is not working, only local storage gets deleted

I encountered 2 problems regarding my todo app. I am just coding along from one of the Youtube tutorials to improve my Javascript knowledge. I cannot delete the last remaining li in my todo list but the local storage shows it is already deleted. Same as my clear all button, the local storage is already been deleted but my li's are still showing. Aside from that, after I click clear all button, I cannot delete the li's one by one even if it's still showing(my guess is the local storage is already empty and there is no more data to be deleted). Thank you for the future responses!
const inputBox = document.querySelector('.input-container input')
const addBtn = document.querySelector('.input-container button')
const todo = document.querySelector('.todo-list')
const deleteAllBtn = document.querySelector('.footer button')
// input button
inputBox.onkeyup = () => {
let userData= inputBox.value;
if (userData.trim() != 0 ) {
addBtn.classList.add('active')
} else {
addBtn.classList.remove('active');
}
}
showTask();
//adding it to local storage
addBtn.onclick = () => {
let userData = inputBox.value;
let getLocalStorage = localStorage.getItem("New Todo")
if (getLocalStorage == null) {
listArr = [];
} else {
listArr = JSON.parse(getLocalStorage);
}
listArr.push(userData);
localStorage.setItem("New Todo", JSON.stringify(listArr));
showTask();
addBtn.classList.remove('active');
}
//add task
function showTask() {
let getLocalStorage = localStorage.getItem("New Todo")
if (getLocalStorage == null) {
listArr = [];
} else {
listArr = JSON.parse(getLocalStorage);
}
const pendingNumb = document.querySelector('.pending');
pendingNumb.textContent= listArr.length;
let newLiTag = '';
listArr.forEach((element, index) => {
newLiTag += `<li> ${element} <span onclick="deleteTask(${index})";><i class="fas fa-trash-alt"></i></span></li>
`;
todo.innerHTML = newLiTag;
inputBox.value = '';
});
}
//delete task
function deleteTask(index) {
let getLocalStorage = localStorage.getItem("New Todo");
listArr = JSON.parse(getLocalStorage);
listArr.splice(index, 1);
localStorage.setItem("New Todo", JSON.stringify(listArr));
showTask();
}
//delete all task
deleteAllBtn.onclick = () => {
listArr = [];
localStorage.setItem("New Todo", JSON.stringify(listArr));
showTask();
}
.todo-list {
margin: 10px 0;
width: 360px;
height: 260px;
max-height: 250px;
overflow-y: auto;
}
.todo-list li {
position: relative;
list-style-type: none;
background: #f2f2f2;
margin: 5px 0;
display: flex;
justify-content: space-between;
padding: 5px 5px;
overflow: hidden;
}
.todo-list li span {
position: absolute;
right: -30px;
top: 0;
background: #d00000;
color: #fff;
width: 35px;
height: 35px;
padding-top: 5px;
text-align: center;
transition: all 0.3s ease;
cursor: pointer;
}
.todo-list li:hover span {
right: 0;
}
.footer {
font-size: 17px;
font-weight: bold;
margin: 0 10px;
}
.footer span {
margin: 0 10px;
}
.footer button {
height: 2.5rem;
width: 5rem;
font-size: 1rem;
color: #fff;
background: #d00000;
border: none;
cursor: pointer;
}
<div class="container">
<h1>TODO list</h1>
<div class="input-container">
<input type="text" class="input" placeholder="Input Text Here">
<button><i class="fas fa-plus"></i></button>
</div>
<ul class="todo-list">
</ul>
<div class="footer">
<span>You have<span class="pending">0</span>pending task left</span>
<button>Clear All</button>
</div>
you should update todo element outside of forEach
function showTask() {
let getLocalStorage = localStorage.getItem("New Todo")
if (getLocalStorage == null) {
listArr = [];
} else {
listArr = JSON.parse(getLocalStorage);
}
const pendingNumb = document.querySelector('.pending');
pendingNumb.textContent = listArr.length;
let newLiTag = '';
listArr.forEach((element, index) => {
newLiTag += `<li> ${element} <span onclick="deleteTask(${index})";><i class="fas fa-trash-alt"></i></span></li>
`;
});
//move it here
todo.innerHTML = newLiTag;
inputBox.value = '';
}

Move li items on click between lists does not work properly

I have to lists and am using a jquery function to move items from one list (id="columns")to the other (id="columns1") when I click on the items in the first list (id="columns").
That part of it works fine, but when I add a new item in the first list (id="columns"), the previously moved items show up in the first list (id="columns").
Is there a way to prevent the moved items to show up in the first list? Is there a way to do it with vanilla js or do I need to use jquery?
This is all part of an to do list app I am creating where you could add tasks, remove them, click on the task to consider it a finished task, etc.
// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
myNodelist[i].appendChild(span);
}
// Click on a close button to hide the current list item
function closeEvent() {
var close = document.getElementsByClassName("close");
for (var i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
renderGraph();
}
}
}
// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function (ev) {
if (ev.target.tagName !== 'LI') return;
ev.target.classList.toggle('checked');
renderGraph();
}, false);
// Create a new list item when clicking on the "Add" button
function newElement() {
var li = document.createElement("li");
li.className = "column";
li.draggable = "true";
// order according to time
li.setAttribute("data-time", document.getElementById("myInput1").value);
// order according to time
var inputValue = document.getElementById("myInput").value;
var inputValue1 = document.getElementById("myInput1").value;
var tine = document.getElementById("myInput1");
tine.dateTime = "6:00"
// inputValue2.datetime = "6:00";
var tt = document.createTextNode(inputValue1 + " - ");
li.appendChild(tt);
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === '') {
alert("You must write a task!");
} else {
document.getElementById("columns").appendChild(li);
// order according to time start
setTimeout(function () {
var sortItems = document.querySelectorAll("[data-time]");
var elemArray = Array.from(sortItems);
elemArray.sort(function (a, b) {
if (a.getAttribute('data-time') < b.getAttribute('data-time')) { return -1 } else { return 1 }
});
//
document.getElementById("columns").innerHTML = "";
elemArray.forEach(appendFunction);
function appendFunction(item, index) {
document.getElementById("columns").innerHTML += item.outerHTML;
}
afterUpdate();
});
// order according to time end
}
document.getElementById("myInput").value = "";
document.getElementById("myInput1").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
}
}
}
// Add tasks by pressing enter
// Get the input field
var input = document.getElementById("myInput");
// Execute a function when the user releases a key on the keyboard
input.addEventListener("keyup", function (event) {
// Number 13 is the "Enter" key on the keyboard
if (event.keyCode === 13) {
// Cancel the default action, if needed
event.preventDefault();
// Trigger the button element with a click
document.getElementById("myBtn").click();
}
});
// //
// //
var btn = document.querySelector('.add');
var remove = document.querySelector('.column');
function dragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
};
function dragEnter(e) {
this.classList.add('over');
}
function dragLeave(e) {
e.stopPropagation();
this.classList.remove('over');
}
function dragOver(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
return false;
}
function dragDrop(e) {
if (dragSrcEl != this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
closeEvent();
}
return false;
}
function dragEnd(e) {
var listItems = document.querySelectorAll('.column');
[].forEach.call(listItems, function (item) {
item.classList.remove('over');
});
this.style.opacity = '1';
}
function addEventsDragAndDrop(el) {
el.addEventListener('dragstart', dragStart, false);
el.addEventListener('dragenter', dragEnter, false);
el.addEventListener('dragover', dragOver, false);
el.addEventListener('dragleave', dragLeave, false);
el.addEventListener('drop', dragDrop, false);
el.addEventListener('dragend', dragEnd, false);
}
function addDragAndDrop() {
var listItems = document.querySelectorAll('.column');
listItems.forEach(addEventsDragAndDrop);
}
afterUpdate();
function afterUpdate() {
closeEvent();
addDragAndDrop();
renderGraph();
}
function addNewItem() {
var newItem = document.querySelector('.input').value;
if (newItem != '') {
document.querySelector('.input').value = '';
var li = document.createElement('li');
var attr = document.createAttribute('column');
var ul = document.querySelector('ul');
li.className = 'column';
attr.value = 'true';
li.setAttributeNode(attr);
li.appendChild(document.createTextNode(newItem));
ul.appendChild(li);
addEventsDragAndDrop(li);
}
}
#myInput1 {
width: 180px;
height: 36px;
margin-right: 10px;
/* margin-left: -40px; */
/* padding: 10px; */
/* color: red; */
/* box-sizing: border-box; */
/* background-color: blue; */
/* display: inline-block; */
}
[draggable] {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
/* Required to make elements draggable in old WebKit */
-khtml-user-drag: element;
-webkit-user-drag: element;
}
/* Include the padding and border in an element's total width and height */
* {
box-sizing: border-box;
font-family: 'Josefin Sans', sans-serif;
}
p {
font-weight: 300;
}
h1 {
font-weight: 300;
}
#x-text {
color: #f97350;
font-size: 1.5rem;
}
::placeholder{
color: #777d71;
}
#myInput1:before {
content:'Time:';
margin-right:.6em;
color: #777d71;
}
/* Remove margins and padding from the list */
ul {
margin: 0;
padding: 0;
list-style: none;
}
/* Style the list items */
ul li {
cursor: pointer;
position: relative;
padding: 12px 8px 12px 40px;
background: #f7f6e7;
font-size: 18px;
transition: 0.2s;
color: rgb(94, 91, 91);
/* make the list items unselectable */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Set all odd list items to a different color (zebra-stripes) */
ul li:nth-child(odd) {
background: #dfddc5;
}
/* Darker background-color on hover */
ul li:hover {
background: rgb(207, 205, 205);
}
/* When clicked on, add a background color and strike out text */
ul li.checked {
background: #888;
color: #fff;
text-decoration: line-through;
}
/* Add a "checked" mark when clicked on */
ul 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;
}
/* Style the close button */
.close {
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
color: #f97350;
/* font-size: 1.5rem; */
}
.close:hover {
background-color: #f97350;
color: white;
}
/* Style the header */
.header {
background-color: #777d71;
padding: 30px 40px;
color: white;
text-align: center;
}
/* Clear floats after the header */
.header:after {
content: "";
display: table;
clear: both;
}
/* Style the input */
input {
margin: 0;
border: none;
border-radius: 0;
width: 75%;
padding: 10px;
float: left;
font-size: 16px;
}
/* Style the "Add" button */
/* .addBtn {
padding: 10px;
width: 25%;
background: #d9d9d9;
color: #555;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
} */
/* .addBtn:hover {
background-color: #bbb;
} */
#finished-tasks {
/* box-sizing: border-box; */
padding: 20px;
display: grid;
align-content: center;
justify-content: center;
background-color:#bbd38b ;
color: white;
margin-bottom: -20px;
margin-top: 40px;
}
#finished-tasks-p {
/* box-sizing: border-box; */
padding: 20px;
display: grid;
align-content: center;
justify-content: center;
background-color:#bbd38b ;
color: white;
margin-bottom: 0;
margin-top: 0;
}
/* #myChart{
margin-top: 50px;
width: 50vw;
height: 100px;
padding-left: 200px;
padding-right: 200px;
} */
/* canvas{
width:1000px !important;
height:auto !important;
margin: auto;
} */
#media only screen and (max-width: 855px){
input {
margin: 10px;
}
#myInput {
display: grid;
width:70vw;
/* align-content: center; */
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myDIV" class="header">
<h1>My Daily Tasks</h1>
<p>Add a time and task then press enter. When finished task click on task bar</p>
<p>To delete task click on <span id="x-text">x</span> in the corner of task bar</p>
<input type="time" id="myInput1" value="06:00">
<input name="text" type="text" id="myInput" placeholder="My task...">
<span onclick="newElement()" class="addBtn" id="myBtn"></span>
</div>
<ul id="columns">
<!-- <li draggable="true" class="column">test</li>
<li draggable="true" class="column">test1</li> -->
<!-- <li class="column" draggable="true">w</li>
<li class="column" draggable="true">ff</li>
<li class="column" draggable="true">uuu</li> -->
</ul>
<ul id="columns2">
<h1 id="finished-tasks">finished Tasks</h1>
<p id="finished-tasks-p">Finished tasks would show up here once you have clicked on the task</p>
</ul>
<!-- adding a graph -->
<canvas id="myChart" width="400" height="400"></canvas>
<script src="/graph.js"></script>
<script src="/app.js"></script>
<!--
<div id="element"></div>
<script>
document.getElementById('element').innerHTML = 'Hi';
</script>-->
<script>
$("#columns").on('click', 'li', function () {
$(this).appendTo('#columns2');
});
$("#listC").on('click', 'li', function () {
$(this).appendTo('#listB');
});
</script>
Change your setTimeout call to this:
setTimeout(function () {
var sortItems = Array.from(document.querySelectorAll("[data-time]"))
.filter((item) => !item.classList.contains('checked'))
.sort(function (a, b) {
if (a.getAttribute('data-time') < b.getAttribute('data-time')) { return -1 } else { return 1 }
});
document.getElementById("columns").innerHTML = "";
sortItems.forEach(appendFunction);
function appendFunction(item, index) {
document.getElementById("columns").innerHTML += item.outerHTML;
}
afterUpdate();
});
The key passage is here:
.filter((item) => !item.classList.contains('checked'))
Before, you were selecting all of the items, even the ones that were already checked. This filters those out.
Here's a working JSFiddle you can experiment with. I had to add an event listener to the addBtn to get it to work on there, but your original script is fine when running from my local machine.

EventListener Click does not working on H tag inside

I have this simple Modal that's shows up upon clicking button and a Page inside it, depends of which button is click,
uno is for page1, dos is for page2 tres is for page3.
the whole box is a button and i have h3 inside it(It's for the title of that button), but when i click the green area which is H3 my pages does not shos up.
I know the problem is that when it clicks h3 it targets the h3 and h3 has ni ID in it.
Can someone help me to make my h3 act as div when i click it?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.myBtn {
width: 100px;
height: 100px;
background-color: aqua;
margin: 10px;
text-align: center;
}
.myBtn h3 {
background-color:green;
line-height: 2;
cursor: pointer;
}
.myBtn:hover {
background-color: aquamarine;;
}
.btns {
float: left;
}
.modal {
display: none;
background-color: aqua;
float: right;
width: 400px;
height: 600px;
}
.page1 {
position: absolute;
display: none;
background-color: burlywood;
margin: 20px;
width: 300px;
height: 150px;
}
.p1 {
border: 2px solid red;
}
.p2 {
border: 2px solid blue;
}
.p3 {
border: 2px solid green;
}
</style>
</head>
<body>
<p>Click the button to Show Modal.</p>
<div class="btns">
<div class="myBtn" id="uno">
<h3>uno</h3>
</div>
<div class="myBtn " id="dos">
<h3>dos</h3>
</div>
<div class="myBtn "id="tres">
<h3>tres</h3></div>
</div>
<div class="modal">
Modal
<div class="page1 p1">Page1</div>
<div class="page1 p2">Page2</div>
<div class="page1 p3">Page3</div>
</div>
<!--JS-->
<script>
var btn = document.querySelectorAll('.myBtn');
var getModal = document.querySelector('.modal');
var getPages = document.querySelectorAll('.page1');
//console.log(getPages);
for(let i=0; i<btn.length;i++ ){
btn[i].addEventListener('click', () => {
hideModal();
getId();
displayPage()});
}
function hideModal(){
getModal.style.display = "block";
}
function getId(){
//console.log(event.target.id);
}
function hideall(){
for(let i=0; i<getPages.length;i++ ){
getPages[i].style.display = 'none';
}
}
function displayPage(){
hideall();
var btnId = event.target.id;
console.log(btnId);
if(btnId == "uno"){
getPages[0].style.display = "block";
}else if(btnId == "dos"){
getPages[1].style.display = "block";
}else if(btnId == "tres"){
getPages[2].style.display = "block";
}
console.log(getPages[0]);
}
window.addEventListener('click', closeIfOutside);
function closeIfOutside(e) {
if(e.target == getModal)
{
getModal.style.display = 'none';
}
}
</script>
</body>
</html>
<html>
You can add pointer-events: none to your h3 elements so that any clicks will fall through to the containing parent div behind it, allowing you to get the correct id to show the correct page:
.myBtn h3 {
background-color: green;
line-height: 2;
cursor: pointer;
pointer-events: none;
}
See example below:
var btn = document.querySelectorAll('.myBtn');
var getModal = document.querySelector('.modal');
var getPages = document.querySelectorAll('.page1');
//console.log(getPages);
for (let i = 0; i < btn.length; i++) {
btn[i].addEventListener('click', () => {
hideModal();
getId();
displayPage()
});
}
function hideModal() {
getModal.style.display = "block";
}
function getId() {
//console.log(event.target.id);
}
function hideall() {
for (let i = 0; i < getPages.length; i++) {
getPages[i].style.display = 'none';
}
}
function displayPage() {
hideall();
var btnId = event.target.id;
//console.log(btnId);
if (btnId == "uno") {
getPages[0].style.display = "block";
} else if (btnId == "dos") {
getPages[1].style.display = "block";
} else if (btnId == "tres") {
getPages[2].style.display = "block";
}
//console.log(getPages[0]);
}
window.addEventListener('click', closeIfOutside);
function closeIfOutside(e) {
if (e.target == getModal) {
getModal.style.display = 'none';
}
}
.myBtn {
width: 100px;
height: 100px;
background-color: aqua;
margin: 10px;
text-align: center;
}
.myBtn h3 {
background-color: green;
line-height: 2;
cursor: pointer;
pointer-events: none;
}
.myBtn:hover {
background-color: aquamarine;
;
}
.btns {
float: left;
}
.modal {
display: none;
background-color: aqua;
float: right;
width: 400px;
height: 600px;
}
.page1 {
position: absolute;
display: none;
background-color: burlywood;
margin: 20px;
width: 300px;
height: 150px;
}
.p1 {
border: 2px solid red;
}
.p2 {
border: 2px solid blue;
}
.p3 {
border: 2px solid green;
}
<p>Click the button to Show Modal.</p>
<div class="btns">
<div class="myBtn" id="uno">
<h3>uno</h3>
</div>
<div class="myBtn " id="dos">
<h3>dos</h3>
</div>
<div class="myBtn " id="tres">
<h3>tres</h3>
</div>
</div>
<div class="modal">
Modal
<div class="page1 p1">Page1</div>
<div class="page1 p2">Page2</div>
<div class="page1 p3">Page3</div>
</div>

Categories

Resources