how does forEach works in this case? - javascript

I have 2 buttons which they activate/deactivate divs, button next activate next div and button prev deactivate current div.
function update gets called in each click, im trying to understand how comparing the index of the array and currentActive is helping us in this case.
I comment out the rest of the code to follow the value of idx but I get confused with the output....................
const progress = document.getElementById('progress');
const prev = document.getElementById('prev');
const next = document.getElementById('next');
const circles = document.querySelectorAll('.circle');
let currentActive = 1;
next.addEventListener('click', () => {
currentActive++;
if (currentActive > circles.length) {
currentActive = circles.length;
}
update();
});
prev.addEventListener('click', () => {
currentActive--;
if (currentActive < 1) {
currentActive = 1;
}
update();
});
function update() {
console.log(' - - - - - - - - ')
console.log('update function, currentActive = '+ currentActive )
circles.forEach((circle, idx) => {
console.log('idx->'+ idx + ', ==Active?->' + (idx===currentActive) + ', div->' + circle.textContent )
// if (idx < currentActive) {
// console.log('index is:' + idx, 'current is :' + currentActive);
// circle.classList.add('active');
// }
/* else {
circle.classList.remove('active');
}
});
if (currentActive === 1) {
prev.disabled = false;
} else if (currentActive === circles.length) {
next.disabled = true;
prev.disabled = false;
} else {
prev.disabled = false;
next.disabled = false;
} */
});
}
.as-console-wrapper {
top : 0;
left : 30% !important;
max-height : 100% !important;
width : 70%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
<link rel="stylesheet" href="style.css" />
<title>Progress Steps</title>
<div class="container">
<div class="progress-container">
<div class="progress" id="progress"></div>
<div class="circle active">1</div>
<div class="circle">2</div>
<div class="circle">3</div>
<div class="circle">4</div>
</div>
<button class="btn" id="prev" disabled>Prev</button>
<button class="btn" id="next">Next</button>
</div>
</head>
<body>
<script src="script.js"></script>
</body>
</html>

I think what bothers you is that in computing, the first index of a list is zero.
here is your code (revisited)
const progress = document.getElementById('progress')
, bt_prev = document.getElementById('prev')
, bt_next = document.getElementById('next')
, divs_circle = document.querySelectorAll('.circle')
, Last_circle = divs_circle.length -1
, progressText =
[ 'payment first step'
, 'payment second step'
, 'payment third step'
, 'payment last step'
, 'payment done !'
]
;
var currentActive = 0 // the first index is zero
;
function setActivCircle()
{
divs_circle.forEach((circle, idx )=>
{
if ( idx === currentActive ) circle.classList.add('active')
else circle.classList.remove('active')
if( idx < currentActive ) circle.classList.add('done')
else circle.classList.remove('done')
})
progress.textContent = progressText[currentActive]
bt_prev.disabled = (currentActive === 0) || (currentActive > Last_circle)
bt_next.disabled = (currentActive > Last_circle)
bt_next.textContent = (currentActive === Last_circle) ? 'Terminate' : 'Next'
console.clear()
console.log(`currentActive value is ${currentActive}, last Idx value is ${Last_circle}`)
}
setActivCircle() // first attempt
bt_next.onclick = () =>
{
++currentActive
setActivCircle()
}
bt_prev.onclick = () =>
{
--currentActive
setActivCircle()
}
div.circle {
padding : .2em;
width : 5em;
border : 1px solid grey;
margin : .2em;
}
div.active {
background-color : lightblue;
}
div.done {
background-color : lightgreen;
}
<div class="container">
<div class="progress-container">
<div class="progress" id="progress"></div>
<div class="circle" >1</div>
<div class="circle" >2</div>
<div class="circle" >3</div>
<div class="circle" >4</div>
</div>
<button class="btn" id="prev" > Prev</button>
<button class="btn" id="next" > Next</button>
</div>

“….im trying to understand how comparing the index of the array and currentActive is helping us in this case.”
Think your first idx is 0, and onload your currentActive=1 then your condition is saying if idx<currentActive , it will receive a class active.
Now see what happens when you click the next,
As your currentActive is 1 onload, when you click next then happens currentActive++ that makes 2, now see your condition, if idx<currentActive (this time idx is 1) and the condition is true, so it will receive a class active, but the prev will remove the class active (and on each click it resets the values as per your condition) …. Now see your other codes and try to understand also the prev click and other codes.

Related

Trigger function to roll a dice

I have a function to get a random value (1->6) to roll a dice:
const rollDice = () => {
document.dispatchEvent(
new CustomEvent('rollDice', {
detail: { value: Math.floor(Math.random() * 6) + 1 },
bubbles: true,
cancelable: false
})
);
};
Get the value from rollDice() and put in the correct positions, but I don't know why it work incorrectly. The result need show as the picture:
Result
I am newbie here, Can anyone help point out where I'm going wrong?
const rollDice = () => {
document.dispatchEvent(
new CustomEvent('rollDice', {
detail: {
value: Math.floor(Math.random() * 6) + 1
},
bubbles: true,
cancelable: false
})
);
};
let btn = document.querySelector("#roll-button");
btn.addEventListener('click', function() {
var varones = toNumber(parseInt(document.querySelector("#ones p").textContent));
var vartwos = toNumber(parseInt(document.querySelector("#twos p").textContent));
var varthrees = toNumber(parseInt(document.querySelector("#threes p").textContent));
var varfours = toNumber(parseInt(document.querySelector("#fours p").textContent));
var varfives = toNumber(parseInt(document.querySelector("#fives p").textContent));
var varsixes = toNumber(parseInt(document.querySelector("#sixes p").textContent));
rollDice();
document.addEventListener('rollDice', (e) => {
alert(e.detail.value);
if (e.detail.value == 1) {
varones = varones + 1;
}
if (e.detail.value == 2) {
vartwos = vartwos + 1;
}
if (e.detail.value == 3) {
varthrees = varthrees + 1;
}
if (e.detail.value == 4) {
varfours = varfours + 1;
}
if (e.detail.value == 5) {
varfives = varfives + 1;
}
if (e.detail.value == 6) {
varsixes = varsixes + 1;
}
total = varones + vartwos + varthrees + varfours + varfives + varsixes;
document.querySelector("#ones p").textContent = varones;
document.querySelector("#twos p").textContent = vartwos;
document.querySelector("#threes p").textContent = varthrees;
document.querySelector("#fours p").textContent = varfours;
document.querySelector("#fives p").textContent = varfives;
document.querySelector("#sixes p").textContent = varsixes;
document.querySelector("#totals p span").textContent = total;
});
});
function toNumber(a) {
if (isNaN(a)) {
a = 0;
}
return a;
}
<h1>Events Triggered and Emitted</h1>
<h2>Dice Rolls</h2>
<div id="rolls">
<div id="ones">
<span class="dice">⚀</span>
<p>-</p>
</div>
<div id="twos">
<span class="dice">⚁</span>
<p>-</p>
</div>
<div id="threes">
<span class="dice">⚂</span>
<p>-</p>
</div>
<div id="fours">
<span class="dice">⚃</span>
<p>-</p>
</div>
<div id="fives">
<span class="dice">⚄</span>
<p>-</p>
</div>
<div id="sixes">
<span class="dice">⚅</span>
<p>-</p>
</div>
<div id="dice">
<button id="roll-button"><span class="dice">⚂</span></button>
</div>
<div id="totals">
<p>Total rolls: <span>0</span></p>
</div>
</div>
<!-- Template for dice roll 1 -->
<template id="template1"><span class="dice">⚀</span></template>
<!-- Template for dice roll 2 -->
<template id="template2"><span class="dice">⚁</span></template>
<!-- Template for dice roll 3 -->
<template id="template3"><span class="dice">⚂</span></template>
<!-- Template for dice roll 4 -->
<template id="template4"><span class="dice">⚃</span></template>
<!-- Template for dice roll 5 -->
<template id="template5"><span class="dice">⚄</span></template>
<!-- Template for dice roll 6 -->
<template id="template6"><span class="dice">⚅</span></template>
I don't understand all your code, but I think you should write your rollDice event listener out of you click button event listener, because in your example, the event is triggered before the document is listening to this event.
btn.addEventListener('click', () => {
// do something
rollDice()
})
document.addEventListener('rollDice', () => {
// do something
})
First of all, don't type more code than necessary inside an eventListener. If you had refactored your code into a method, you would see that you tried to create an event listener inside an event listener. Here is how an eventListener should be set up:
btn.addEventListener('click', rollDice);
I don't understand why you created an event listener inside rollDice(). Was that part of an assignment? I just called the correct method straight away.
The second part I did was to try to reduce code by looking at similarities in the code. I can use the :nth-child selector to get the proper dice container by using the randomized roll.
rollsDiv.querySelector(`div:nth-child(${roll}) > p`)
The third thing to remember, is to write as short methods as possible, by having them do at most one thing. If you can't do that, try to write methods as a table of content. A person should be able to read the code and understand what's happening just by how it's written. That means refactor complex code, like getCorrectDiceElement(), or using variables and naming them to make each row comprehensible.
These are more tips for intermediate coding, but it could be nice to know this on beforehand. Otherwise, you won't understand your own code when looking at it after a half year. :)
As a present, I added a four more lines (a, b) for functionality that I guess you would like to implement in the future. Good luck!
const rollsDiv = document.getElementById("rolls");
// const totalsDiv = document.getElementById("totals"); // a
const btn = document.getElementById("roll-button");
// var numberOfRolls = 0; // a
const randomize = (max = 6, min = 1) => {
return Math.floor(Math.random() * max) + min;
};
const rollDice = () => {
var roll = randomize();
let diceElement = getCorrectDiceElement(roll);
let previousNumber = toNumber(diceElement.textContent);
// let diceSymbol = document.getElementById("template" + roll).textContent; // b
// console.log(roll, diceElement.parentNode.id)
previousNumber++;
// numberOfRolls++; // a
diceElement.textContent = previousNumber;
}
const getCorrectDiceElement= (roll) => {
return rollsDiv.querySelector(`div:nth-child(${roll}) > p`)
}
function toNumber(a) {
return isNaN(a) ? 0 : a;
}
btn.addEventListener('click', rollDice);
#rolls {
display: flex;
margin-bottom: 1rem;
}
#rolls > div,
#roll-button
{
text-align: center;
font-size: 2rem;
padding: 0rem 1rem;
}
#rolls p {
margin: 0;
}
<h2>Dice Rolls</h2>
<div id="rolls">
<div id="ones">
<span class="dice">⚀</span>
<p>-</p>
</div>
<div id="twos">
<span class="dice">⚁</span>
<p>-</p>
</div>
<div id="threes">
<span class="dice">⚂</span>
<p>-</p>
</div>
<div id="fours">
<span class="dice">⚃</span>
<p>-</p>
</div>
<div id="fives">
<span class="dice">⚄</span>
<p>-</p>
</div>
<div id="sixes">
<span class="dice">⚅</span>
<p>-</p>
</div>
</div>
<div>
<div id="dice">
<button id="roll-button">Roll</button>
</div>
<div id="totals">
<p>Total rolls: <span>0</span></p>
</div>
</div>
<!-- Template for dice roll 1 -->
<template id="template1"><span class="dice">⚀</span></template>
<!-- Template for dice roll 2 -->
<template id="template2"><span class="dice">⚁</span></template>
<!-- Template for dice roll 3 -->
<template id="template3"><span class="dice">⚂</span></template>
<!-- Template for dice roll 4 -->
<template id="template4"><span class="dice">⚃</span></template>
<!-- Template for dice roll 5 -->
<template id="template5"><span class="dice">⚄</span></template>
<!-- Template for dice roll 6 -->
<template id="template6"><span class="dice">⚅</span></template>
[EDIT] Added back the original rollDice() method.
const rollsDiv = document.getElementById("rolls");
// const totalsDiv = document.getElementById("totals"); // a
const btn = document.getElementById("roll-button");
// var numberOfRolls = 0; // a
const randomize = (max = 6, min = 1) => {
return Math.floor(Math.random() * max) + min;
};
const rollDice = () => { // NEW
let eventName = "rollDice";
let eventDetail = {'value': randomize()};
let eventProperties = {detail: eventDetail, 'bubbles': true, 'cancelable': false};
let customEvent = new CustomEvent(eventName, eventProperties);
document.dispatchEvent(customEvent);
};
const handleDiceResult = (event) => {
var eventDetail = event.detail; // NEW
var roll = eventDetail.value;
let diceElement = getCorrectDiceElement(roll);
let previousNumber = toNumber(diceElement.textContent);
// let diceSymbol = document.getElementById("template" + roll).textContent; // b
// console.log(roll, diceElement.parentNode.id)
previousNumber++;
// numberOfRolls++; // a
diceElement.textContent = previousNumber;
}
const getCorrectDiceElement= (roll) => {
return rollsDiv.querySelector(`div:nth-child(${roll}) > p`);
}
function toNumber(a) {
return isNaN(a) ? 0 : a;
}
btn.addEventListener('click', rollDice);
document.addEventListener('rollDice', handleDiceResult); // NEW
#rolls {
display: flex;
margin-bottom: 1rem;
}
#rolls > div,
#roll-button
{
text-align: center;
font-size: 2rem;
padding: 0rem 1rem;
}
#rolls p {
margin: 0;
}
<h2>Dice Rolls</h2>
<div id="rolls">
<div id="ones">
<span class="dice">⚀</span>
<p>-</p>
</div>
<div id="twos">
<span class="dice">⚁</span>
<p>-</p>
</div>
<div id="threes">
<span class="dice">⚂</span>
<p>-</p>
</div>
<div id="fours">
<span class="dice">⚃</span>
<p>-</p>
</div>
<div id="fives">
<span class="dice">⚄</span>
<p>-</p>
</div>
<div id="sixes">
<span class="dice">⚅</span>
<p>-</p>
</div>
</div>
<div>
<div id="dice">
<button id="roll-button">Roll</button>
</div>
<div id="totals">
<p>Total rolls: <span>0</span></p>
</div>
</div>
<!-- Template for dice roll 1 -->
<template id="template1"><span class="dice">⚀</span></template>
<!-- Template for dice roll 2 -->
<template id="template2"><span class="dice">⚁</span></template>
<!-- Template for dice roll 3 -->
<template id="template3"><span class="dice">⚂</span></template>
<!-- Template for dice roll 4 -->
<template id="template4"><span class="dice">⚃</span></template>
<!-- Template for dice roll 5 -->
<template id="template5"><span class="dice">⚄</span></template>
<!-- Template for dice roll 6 -->
<template id="template6"><span class="dice">⚅</span></template>

How to add dot navigation to slider

I have a working slider that I would like to add dot navigation to. However I'm not quite sure how I can pull it off. I've tried to add my own jQuery to the code, but it just breaks the slider. Does anyone have a suggestion on how to add dot navigation to the bottom of this slider?
(function () {
function init(item) {
var items = item.querySelectorAll("li"),
current = 0,
autoUpdate = true,
timeTrans = 400000000;
//create nav
var nav = document.createElement("nav");
// nav.className = "nav_arrows";
//create button prev
var prevbtn = document.createElement("button");
prevbtn.className = "fp_go_prev_slide";
prevbtn.setAttribute("aria-label", "Prev");
//create button next
var nextbtn = document.createElement("button");
nextbtn.className = "fp_go_next_slide";
nextbtn.setAttribute("aria-label", "Next");
if (items.length > 1) {
nav.appendChild(prevbtn);
nav.appendChild(nextbtn);
item.appendChild(nav);
}
items[current].className = "current_slide";
if (items.length > 1) items[items.length - 1].className = "prev_slide";
if (items.length > 1) items[current + 1].className = "next_slide";
rightClick();
var navigate = function (dir) {
items[current].className = "current_slide";
if (dir === "right") {
current = current < items.length - 1 ? current + 1 : 0;
} else if (dir === "left") {
current = current > 0 ? current - 1 : items.length - 1;
} else {
current = current > 0 ? current - 1 : items.length - 1;
}
var nextCurrent = current < items.length - 1 ? current + 1 : 0,
prevCurrent = current > 0 ? current - 1 : items.length - 1;
items[current].className = "current_slide";
items[prevCurrent].className = "prev_slide";
items[nextCurrent].className = "next_slide";
if (dir === "right") {
rightClick();
}
if (dir === "left") {
leftClick();
}
};
item.addEventListener("mouseenter", function () {
autoUpdate = false;
});
item.addEventListener("mouseleave", function () {
rightClick();
autoUpdate = true;
});
setInterval(function () {
if (autoUpdate) navigate("right");
}, timeTrans);
prevbtn.addEventListener("click", function () {
navigate("left");
});
nextbtn.addEventListener("click", function () {
navigate("right");
});
function rightClick() {
var n = document.getElementsByClassName("next_slide");
var c = document.getElementsByClassName("current_slide");
var p = document.getElementsByClassName("prev_slide");
}
function leftClick() {
var n = document.getElementsByClassName("next_slide");
var c = document.getElementsByClassName("current_slide");
var p = document.getElementsByClassName("prev_slide");
}
}
[].slice
.call(document.querySelectorAll(".fp_slider_container_top_main"))
.forEach(function (item) {
init(item);
});
})();
And here's the html
<section class="featured-project-slider">
<div class="row fp-top-slider">
<div class="col-lg-8 fp-front-left">
<h1 class="fp-header extended-black-l">Featured Projects</h1>
</div>
<div class="col-lg-4 fp-front-right">
<button class="top-right-button extended-black-s">See all projects ></button>
</div>
<div class="col-lg-10 offset-lg-1 col-12 fp-center">
<!-- // * Slider starts -->
<section class="fp_slider_container_top_main">
<!-- all slides container starts -->
<ul class="fp_slider_container_top">
<?php $loop = new WP_Query(array('post_type' => 'project', 'cat' => '4', 'orderby' => 'ID', 'order' => 'ASC' )); ?>
<?php while ($loop->have_posts()): $loop->the_post(); ?>
<!-- slide starts -->
<li>
<div class="fp_slider_container_top_img_container">
<img src="<?php the_field('top_image'); ?>" alt="slider image" class="fp_slider_container_top_img"
loading="lazy">
<div class="fp-project-box">
<p class="fp-small extended-black-s">Our History</p>
<h1 class="condensed-semibold-l"><?php echo the_title(); ?></h1>
<p class="regular-m"><?php the_field('short_description'); ?></p>
<button class="extended-black-s">Learn More ></button>
</div>
</div>
</li>
<!-- slide ends -->
<?php endwhile;
wp_reset_query(); ?>
<?php
?>
</ul>
<!-- all slides container ends -->
</section>
<!-- // * Slider ends -->
</div>
<div class="col-lg-6 offset-lg-6 col-12 fp-front-right-red">
<div>
</div>
</section>

Filter active tasks, completed tasks, and all tasks in a to Do List with javascript

I am having some difficulty filtering through a list of tasks in To Do List project.
I use an object to store the core properties of each task created like the id, content, completed, and date.
The filter should occurs after the user selects an option in a drop down menu.
I use an Event Listener to catch the id of the option selected, but I don't know what to do with that Id. For example, when the user selects the option 'completed' the app should only display the completed task, or the tasks that have a property of 'completed:true'.
I also want to filter the list in a fancy way such as make tasks fade out when filtering.
URL: https://alonzocarlos95.github.io/WDD-330/
//html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--ClockPicker libraries-->
<link rel="stylesheet" href="https://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.css"></link>
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Moment JS library CDN -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.1/moment.min.js"></script> -->
<!--Material Icons and Fonts-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght#0,200;1,100&display=swap" rel="stylesheet">
<!--Small view-->
<link rel="stylesheet" href="css/small.css" media="screen">
<title>Document</title>
</head>
<body>
<header>
<nav>
<ul>
<li><span class="material-icons">done</span></li>
<li class="drop-down" ><div class="dropdown"><button class="dropbtn" onclick="showModal()">All Lists<span class="material-icons" style="vertical-align: middle;">arrow_drop_down</span></button><div id="myDropdown" class="dropdown-content"><span id="select1">All Lists</span><span id="select2">Active</span><span id="select3">Completed</span></div></div></li>
<li><span class="label_list">BYU-Idaho To do List</span></li>
<li><span class="material-icons">search</span></li>
<li><img src="images/b2-removebg-preview.png" alt="logo"></li>
</ul>
</nav>
</header>
<main>
<div class="notes">
<img id="no_tasks" src="images/palms-300x220.png" alt="No tasks">
</div>
<div class="main_list" id="main_list">
<ul id="parentList">
</ul>
</div>
<div class="new_task_container" id="container_schedule">
<div class="new_task" id="new_todo">
<label>What is to be done?</label>
<div class="new_input">
<input type="text" name="todo" id="todo" placeholder="Enter task here">
<span class="material-icons">keyboard_voice</span>
</div>
<label>Due Date</label>
<input type="date" id="date" name="date" placeholder="Date not set">
</div>
<div class="new_task_group2">
<div class="new_time" id="new_time_container">
<input type="text" name="time" id="time" placeholder="Time not set(all day)">
<span class="material-icons">schedule</span>
<!-- <input type="checkbox" style="display: none;"> -->
</div>
</div>
</div>
</main>
<div class="add_task">
<button id="add" class="bounce">+</button>
</div>
<script src="https://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.js"></script>
<script src="js/todo.js"></script>
</body>
</html>
//Javacript
let toDoList = [];
let options = {weekday:'long', year:'numeric', month:'long', day:'numeric'};
let indicador = 0;
let list_container = document.getElementById('main_list');
document.getElementById('container_schedule').style.display = 'none';
const chosenDate = document.getElementById("date");
const time = document.getElementById('new_time_container');
let ulTasks = document.getElementById('parentList');
time.style.display = 'none';
document.getElementById('add').addEventListener('click', () => {
document.getElementById('container_schedule').style.display = 'block';
document.getElementById('add').innerHTML = '<span class="material-icons">done</span>';
let inputNewTask = document.getElementById("todo");
let valInputNewTask = inputNewTask.value;
let valInputNewTask2 = inputNewTask.value;
let dateSet = document.getElementById('date').value;
if(indicador === 0){
indicador = 1;
list_container.style.display = "none";
}else {
if(!isBlank(valInputNewTask)){ //Valida si el valor del input no es null o undefined o whitespace
indicador = 0;
inputNewTask.value = "";
inputNewTask.focus();
let newDateSet = valDate(dateSet);
taskCreated();
manageTask(valInputNewTask2,newDateSet);
}
else {
alert("Enter task at first.");
}
}
} );
document.getElementById('date').addEventListener('change',() => {
// alert("New date");
time.style.display = 'flex';
});
function taskCreated(){
document.getElementById('container_schedule').style.display = 'none';
// debugger;
if(document.getElementsByClassName('notes').length >= 1){
document.getElementsByClassName('notes')[0].remove();
}
document.getElementById('add').textContent = '+';
}
/*Clock picker functionality*/
$("input[name=time]").clockpicker({
placement: 'bottom',
align: 'left',
autoclose: true,
default: 'now',
donetext: "Select",
init: function() {
console.log("colorpicker initiated");
},
beforeShow: function() {
console.log("before show");
},
afterShow: function() {
console.log("after show");
},
beforeHide: function() {
console.log("before hide");
},
afterHide: function() {
console.log("after hide");
},
beforeHourSelect: function() {
console.log("before hour selected");
},
afterHourSelect: function() {
console.log("after hour selected");
},
beforeDone: function() {
console.log("before done");
},
afterDone: function() {
console.log("after done");
}
});
function isBlank(str) {
//debugger;
return (!str || /^\s*$/.test(str));
}
function valDate(dateToDo){
// debugger;
if(dateToDo === null || dateToDo === ''){
dateToDo = "No date";
return dateToDo;
}
else {
dateToDo = new Date(dateToDo);
dateToDo.setDate(dateToDo.getDate()+1);
// testDate = new Date(Date.UTC(dateToDo));
dateToDo = dateToDo.toLocaleString('en-US',options);
return dateToDo;
}
}
function manageTask(getTask,dateSet){
const todo = {
id: Date.now(),
content: getTask,
completed: false,
date: dateSet
}
toDoList.push(todo);
addToLocalStorage(toDoList);
// storeData(todo);
}
function addToLocalStorage(toDoList){
// debugger;
localStorage.setItem('toDoList',JSON.stringify(toDoList));
renderTodos(toDoList);
}
function renderTodos(toDoList){
// debugger;
ulTasks.innerHTML = '';
toDoList.forEach(function(valInputNewTask2,index){
console.log(index);
const checked = toDoList.completed ? 'checked': null;
let currentTasks = document.createElement('li');
currentTasks.id = valInputNewTask2.id;
currentTasks.setAttribute('style','display:flex;background-color:#519872;width:100%;border-radius:7px;margin:0 0 10px 0;padding:6px 4px 6px 4px;min-height:3em;box-shadow: rgba(14, 30, 37, 0.12) 0px 2px 4px 0px, rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;');
currentTasks.innerHTML = '<input id='+index+' type = "checkbox" class="checkInactive"><div style="display:flex;flex-direction:column;flex-grow:2;"><span style="margin-left:2em;">'+valInputNewTask2.content+'</span><span style="margin-left:2em;color:#17301C;">'+valInputNewTask2.date+'</span></div><div class="clear"><span class="material-icons">clear</span></div>';
if(valInputNewTask2.completed === true){
currentTasks.classList.add('checkActive');
currentTasks.firstChild.checked = true;
}
document.getElementById('parentList').appendChild(currentTasks);
});
list_container.style.display = "block";
}
function getFromLocalStorage(){
const getReference = localStorage.getItem('toDoList');
if(getReference){
document.querySelector('.notes').style.display = 'none';
toDoList = JSON.parse(getReference);
renderTodos(toDoList);
}
}
function showModal(){
document.getElementById('myDropdown').classList.toggle('show');
}
getFromLocalStorage();
function toggle(id){
toDoList.forEach(function(item){
if(item.id == id){
item.completed = !item.completed;
}
});
addToLocalStorage(toDoList);
}
function deleteToDo(id){
debugger
// alert(id);
toDoList = toDoList.filter(function(getTask){
return getTask.id != id;
});
addToLocalStorage(toDoList);
}
debugger;
ulTasks.addEventListener('click',function(event){
debugger;
if(event.target.type === 'checkbox'){
toggle(event.target.parentElement.getAttribute('id'));
}
if(event.target.parentElement.classList.contains('clear')){
debugger;
deleteToDo(event.target.parentElement.parentElement.getAttribute('id'));
}
});
//Close the dropdown if the user clicks outside it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
//Drop down Events
document.getElementById("myDropdown").addEventListener('click',function(event){
debugger;
if(event.target.localName === 'span'){
alert(event.target.id);
}
});
I don't know about the animations but at least for the filtering:
Ideally you should be using the select html element to create a dropdown menu and use the value attribute of the option elements to perform actions when an option is selected. Read more here: https://www.w3schools.com/tags/tag_select.asp
In your case, we can use the text inside the span tag, instead of the id to see which option was selected and render the todos based on the selected option.
We can then use the JS ES6 array function .filter(item => condition), which loops over the items in the array and returns a new array with all the items that match the provided condition.
document.getElementById('myDropdown').addEventListener('click', function(event) {
if (e.target.localName === 'span'){
let selectedOption = e.target.innerText;
if(selectedOption === 'All Tasks')
renderToDos(toDoList); // render everything
else if(selectedOption === 'Active'){
let activeToDos = toDoList.filter(todo => todo.completed === false);
renderToDos(activeToDos); // only render the todos which have not been completed
}
else if(selectedOption === 'Completed'){
let completedToDos = toDoList.filter(todo => todo.completed === true);
renderToDos(completedToDos); // only render the todos which have not been completed
}
}
});

Show javascript function output in html

My JavaScript contains two functions. One function gets a number from the user and returns a string that shows if the number is a prime or not and then store the number and the result in an array.
results = new Array();
i = 0;
function isPrime(num) {
flag = false;
if (num > 1) {
for (i = 2; i < num; i++) {
if (num % i == 0) {
flag = true;
break;
}
}
}
return !flag;
}
function getNumberPrime(number) {
condition = (isPrime(number)) ? ('is') : ('is not');
console.log('' + number + ' ' + condition + ' prime');
dict = {}
dict['number'] = number
dict['isPrime'] = isPrime(number);
results.push(dict);
}
function getAll() {
for (i = 0; i < results.length; i++) {
condition = (results[i]['isPrime']) ? ('is') : ('is not');
number = results[i]['number']
console.log('' + number + ' ' + condition + ' prime');
}
}
My HTML has an input and two buttons. One button returns the output of the first function and the second should show the items of array.
<!DOCTYPE html>
<html lang="fa">
<head>
<title>Prime Number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="prime.js"></script>
</head>
<body>
<div class="container">
<h2>Find Prime Numbers</h2>
<form>
<div class="form-group">
<label class="control-label col-sm-2">Numbers:</label>
<div class="col-sm-10">
<input class="form-control" id="inp" name="nums" style="margin-left: -11%">
</div>
</div>
<button type="submit" class="btn btn-default" style=" margin-top: 2%;" onclick="getNumberPrime()">Check</button>
<button type="submit" class="btn btn-default" style="margin-top: 2%;" onclick="document.getElementById('showprime').innerHTML =getAll()">Show Result</button>
<p id="showprime"></p>
</form>
</div>
</body>
</html>
But the first button doesn't work and I don't know how to implement the second button.
Prime numbers must be blue and none primes must be red.
First: Your buttons need to have type="button" to prevent a reload because of the submit.
Your function getNumberPrime() wants a parameter number which you aren't offering in your inline event handler. Therefor you should get the number in that function by selecting the input and getting its value:
let number = document.querySelector('#inp').value;
Your function getAll() doesn't return anything and therefor the result isn't inserted in #showprime. Instead of loging the values to the console you could add them to an output string and return that string after the for loop:
let output = '';
for (i = 0; i < results.length; i++) {
...
output += number + ' ' + condition + ' prime<br>';
}
return output;
If you want the output to be colored you could wrap each result in a paragraph tag and give it a class dependent on the condition. In this case #showprime should be container element like a div. The class would be styled with CSS.
Inside the for loop:
check = (results[i]['isPrime']) ? true : false;
condition = check ? ('is') : ('is not');
...
output += '<p class=' + check + '>' + number + ' ' + condition + ' prime</p>';
In your CSS-file:
.true {
color: blue;
}
.false {
color: red;
}
Last: It's better to devide Javascript and HTML and not to use inline event handlers. Therefor you should change this:
<button ... onclick="getNumberPrime()">Check</button>
<button ... onclick="document.getElementById('showprime').innerHTML = getAll()">Show Result</button>
to this:
<button id="check" ...>Check</button>
<button id="show" ...>Show Result</button>
document.querySelector('#check').addEventListener('click', getNumberPrime);
document.querySelector('#show').addEventListener('click', function() {
document.getElementById('showprime').innerHTML = getAll();
});
Working example:
results = new Array();
i = 0;
function isPrime(num) {
flag = false;
if (num > 1) {
for (i = 2; i < num; i++) {
if (num % i == 0) {
flag = true;
break;
}
}
}
return !flag;
}
function getNumberPrime() {
let number = document.querySelector('#inp').value;
condition = (isPrime(number)) ? ('is') : ('is not');
console.log('' + number + ' ' + condition + ' prime');
dict = {}
dict['number'] = number
dict['isPrime'] = isPrime(number);
results.push(dict);
}
function getAll() {
let output = '';
for (i = 0; i < results.length; i++) {
check = (results[i]['isPrime']) ? true : false;
condition = check ? ('is') : ('is not');
number = results[i]['number'];
output += '<p class=' + check + '>' + number + ' ' + condition + ' prime</p>';
}
return output;
}
document.querySelector('#check').addEventListener('click', getNumberPrime);
document.querySelector('#show').addEventListener('click', function() {
document.getElementById('showprime').innerHTML = getAll();
});
.true {
color: blue;
}
.false {
color: red;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="container">
<h2>Find Prime Numbers</h2>
<form>
<div class="form-group">
<label class="control-label col-sm-2">Numbers:</label>
<div class="col-sm-10">
<input class="form-control" id="inp" name="nums" style="margin-left: -11%">
</div>
</div>
<button id="check" type="button" class="btn btn-default" style=" margin-top: 2%;">Check</button>
<button id="show" type="button" class="btn btn-default" style="margin-top: 2%;">Show Result</button>
<div id="showprime"></div>
</form>
</div>

Insert Process into Queue to work Asynchronously

I am trying to make a simple web page in which when we enter the text value in the textbox, and as soon as a user inserts a comma between the two texts, a new button gets generated. When the user presses the enter key, the buttons class should toggle between warning and danger.
I am able to achieve it so I also tried to add a delay, but the problem is all buttons class toggling takes place together and not one by one in a random manner. To create a random toggling sequence I created a random permutation of numbers for it, but since all buttons classes are toggling simultaneously I am not getting the required result.
The required result is that first for one buttons toggling should be completed and then for another button - how can I achieve this?
let element = document.querySelector('.textarea');
let cont = document.querySelector('.groupofbtns');
let lastlen = 0;
const pause = (timeoutMsec) => new Promise(resolve => setTimeout(resolve, timeoutMsec))
async function main(grp) {
// here is the delay I am trying to create between toggling but it is executing for all buttons simultaneously.
grp.classList.remove("btn-warning");
grp.classList.add("btn-danger");
await pause(3 * 1000)
grp.classList.remove("btn-danger");
grp.classList.add("btn-warning");
}
element.addEventListener("keyup", function (event) {
if (event.keyCode === 13) {
let grp = document.querySelectorAll('.btn')
let l = grp.length - 1, arr = [];
console.log(grp.length)
do {
let num = Math.floor(Math.random() * l + 1);
arr.push(num);
arr = arr.filter((item, index) => {
return arr.indexOf(item) === index
});
} while (arr.length < l);
// console.log(arr);
arr.push(0)
for (let i = 0; i <= l; i++) {
main(grp[arr[i]])
}
}
else if (event.keyCode === 8) {
let val = element.value;
//console.log(val)
let strArr = val.split(',')
let b, f;
let grp = document.querySelectorAll('.btn');
if (strArr.length > 1) {
b = strArr;
while (b[b.length - 1] == "")
b.pop()
if (b.length < strArr.length) {
cont.removeChild(grp[grp.length - 1]);
lastlen--;
}
f = b[b.length - 1];
}
if (grp.length == b.length)
grp[grp.length - 1].innerText = `${f}`;
else {
let diff = grp.length - b.length
let i = 0;
while (diff > 0) {
cont.removeChild(grp[grp.length - 1 - i]);
i++;
diff--;
lastlen--;
}
}
}
});
element.addEventListener('input', function (event) {
let val = element.value;
//console.log(val)
let strArr = val.split(',')
let b, f;
if (strArr.length > 1) {
b = strArr;
while (b[b.length - 1] == "")
b.pop()
f = b[b.length - 1];
if (event.keyCode !== 8) {
if (strArr.length > lastlen) {
let butt = document.createElement('button');
butt.classList.add('btn')
butt.classList.add('btn-warning')
//butt.classList.add('container')
butt.classList.add('active')
butt.innerText = `${f}`
cont.appendChild(butt)
lastlen = strArr.length
//cont.innerHTML += `<button type="button" class="btns" >${f}</button>`;
}//element.value = val;
else {
let b = document.querySelectorAll('.btn')
b[b.length - 1].innerText = `${f}`
}
}
}
})
.h
{
display:flex;
flex-direction: column;
width: 50%;
margin-top:30%;
align-items: center;
text-align: center;
}
.lab
{
color:white;
}
.btn
{
margin: 0.8% 0.8%;
}
.groupofbtns
{
width:50%;
margin-top: 2%;
align-items: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<title>Random color picker</title>
<link rel="stylesheet" href="randomcolorcss.css">
</head>
<body style="background-color: blue;">
<div class="container h">
<div class="input-group">
<label for="text" class="lab">Enter your choices here separate them with
commas, Press
Enter when you are
done</label>
<br>
<textarea cols="5" rows="5" class=" textarea form-control" placeholder="Enter Choices here" name="text"
style="width: fit-content; display: block;"></textarea>
</div>
</div>
<div class="groupofbtns container">
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.min.js"
integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s"
crossorigin="anonymous"></script>
<script src="randomcolor.js"></script>
</body>
</html>

Categories