Electron : How to display system RAM and CPU usage in real-time - javascript

so I'm trying to make an app that displays the cpu usage, ram usage, gpu usage and disk usage to a bar graph. I'm at the point where I can display the total percent of ram used but I am not able to update the value in real time and show it to the bar graph. Any help would be greatly appreciated.
Code
dashboard.js
const os = require("os");
const fs = require("fs");
const { memoryUsage } = require("process");
const os_free_mem = os.freemem()
let free_mem = (Math.round(os_free_mem / (1024*1024)))
const os_total_mem = os.totalmem()
let total_mem = (Math.round(os_total_mem / (1024*1024)))
const cpu_usage = document.querySelector(".cpu_usage");
const ram_usage = document.querySelector(".ram_usage");
const gpu_usage = document.querySelector(".gpu_usage");
const disk_usage = document.querySelector(".disk_usage");
const free_mem_lbl = document.getElementById("mem")
const total_mem_lbl = document.getElementById("tmem")
// FUNCTIONS
function update_cpu_usage(cpu_usage, value) {
value = Math.round(value);
cpu_usage.querySelector(".cpu_usage_fill").style.width = `${value}%`;
}
function update_ram_usage(ram_usage, value) {
value = Math.round(value);
ram_usage.querySelector(".ram_usage_fill").style.width = `${value}%`;
}
function update_gpu_usage(gpu_usage, value) {
value = Math.round(value);
gpu_usage.querySelector(".gpu_usage_fill").style.width = `${value}%`;
}
function update_disk_usage(disk_usage, value) {
value = Math.round(value);
disk_usage.querySelector(".disk_usage_fill").style.width = `${value}%`;
}
function find_cpu_percent() {
var free_mem_percent = Math.round((free_mem / total_mem ) * 100);
free_mem_lbl.innerText = `${free_mem_percent}`
}
find_cpu_percent();
tmem.innerText = `${total_mem}`
update_cpu_usage(cpu_usage, 55);
update_ram_usage(ram_usage, free_mem_percent);
update_gpu_usage(gpu_usage, 24);
update_disk_usage(disk_usage, 75)
dashboard.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">
<title>Dashboard</title>
<link rel="stylesheet" href="css/dashboard.css">
<script src="https://kit.fontawesome.com/e637815e35.js" crossorigin="anonymous"></script>
<script type="module" src="https://unpkg.com/ionicons#5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons#5.5.2/dist/ionicons/ionicons.js"></script>
</head>
<body>
<div class="main">
<div class="sidebar">
<ul>
<li><ion-icon name="home-sharp"></ion-icon></li>
<li><ion-icon name="speedometer-outline"></ion-icon></li>
<li><i class="fas fa-clock-rotate-left"></i></li>
<li><i class="fa-brands fa-usb"></i></li>
</ul>
</div>
<div class="main-content">
<h3>System Information</h3>
<!-- Usage Bars -->
<span class="cpu_text">CPU</span>
<div class="cpu_usage">
<div class="cpu_usage_fill"></div>
</div>
<span class="ram_text">RAM</span>
<div class="ram_usage">
<div class="ram_usage_fill"></div>
</div>
<span class="gpu_text">GPU</span>
<div class="gpu_usage">
<div class="gpu_usage_fill"></div>
</div>
<span class="disk_text">DISK</span>
<div class="disk_usage">
<div class="disk_usage_fill"></div>
</div>
<!-- System Specifications -->
<div class="specs">
<h3>System Specifications</h3>
<h5>CPU</h5>
<p class="info" id="cpu_name">CPU : </p>
<p class="info" id="cpu_speed">Speed :</p>
<p class="info" id="cpu_cores">Cores : </p>
<p id="mem" style="margin-left: 200px; font-size:40px"></p>
<p id="tmem" style="margin-left: 200px; font-size:40px"></p>
</div>
<script src="js/dashboard.js"></script>
</div>
</body>
</html>

Related

Javascript timer with a whileloop crashes the page

I'm trying to make a simple countup timer with a start/stop button. I don't understand why the while loop crashes the page even though it has a 1sec delay. Is there a easier way to keep updating the time until I press the button?
let startButton = document.getElementById("btn-start-stop");
let timerOutput = document.getElementById("timer");
let runTimer = false;
let sec = 0;
let startTimer = false;
console.log(startTimer);
startButton.onclick = function () {
startTimer = !startTimer;
while (startTimer) {
setInterval(function () {
console.log(sec);
}, 1000);
}
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="an exercise to manipulate DOM-elements">
<meta name="author" content="lars berg">
<meta name="keywords" content="a template for at exercise">
<link rel="stylesheet" type="text/css" href="css/style.css">
<title>DOM | Manipulate</title>
<script src="https://kit.fontawesome.com/fa41e523cd.js" crossorigin="anonymous"></script>
<script src="scripts/script.js" defer></script>
</head>
<body>
<header>
<h1>DOM | Manipulation</h1>
</header>
<main>
<div class="flex-container">
<div class="counter-container">
<h2 class="h2-counter">How long time will it take to read this information?</h2>
<div id="timer">
00:00:00
</div>
<div class="buttons">
<button id="btn-start-stop" type="button">
<i class="fa-solid fa-play fa-2x"></i>
</button>
<button id="btn-reset" type="button">
<i class="fa-solid fa-arrow-rotate-left fa-2x"></i>
</button>
</div>
</div>
</div>
</main>
<footer>
</footer>
</body>
</html>
You should not use a while() loop as this will block the thread.
Use setInterval() to preform an action at a specific interval (1000ms), and use clearInterval() to stop it on second press
Regarding the seconds to HMS, I'ved used this SO one-liner and made a function of it that will be called after we've bumped the seconds.
let startButton = document.getElementById("btn-start-stop");
let timerOutput = document.getElementById("timer");
let sec = 0;
let timer = null;
startButton.onclick = function () {
if (timer) {
clearInterval(timer);
timer = null;
} else {
timer = setInterval(() => ++sec && update(), 1000);
}
};
function update() {
timerOutput.innerHTML = new Date(sec * 1000).toISOString().substr(11, 8);
}
<script src="https://kit.fontawesome.com/fa41e523cd.js" crossorigin="anonymous"></script>
<header>
<h1>DOM | Manipulation</h1>
</header>
<main>
<div class="flex-container">
<div class="counter-container">
<h2 class="h2-counter">How long time will it take to read this information?</h2>
<div id="timer">
00:00:00
</div>
<div class="buttons">
<button id="btn-start-stop" type="button">
<i class="fa-solid fa-play fa-2x"></i>
</button>
<button id="btn-reset" type="button">
<i class="fa-solid fa-arrow-rotate-left fa-2x"></i>
</button>
</div>
</div>
</div>
</main>
While loop will block your thread because JavaScript is single threaded language.
let startButton = document.getElementById("btn-start-stop");
let timerOutput = document.getElementById("timer");
let runTimer = false;
let sec = 0;
let startTimer = false;
console.log(startTimer);
startButton.onclick = function () {
// you can change your button here
setInterval(function () {
console.log(sec);
sec = sec+1
// implement your logic here for seconds
}, 1000);
};
Because while looping, you are generating a call stack of setTimeout again and again which seems to crash the browser stack
check below sample code while no loop just use recursive approach
let startButton = document.getElementById("btn-start-stop");
let timerOutput = document.getElementById("timer");
let runTimer = false;
let sec = 0;
let startTimer = false;
let clearTime
let count = 0
startButton.onclick = function () {
clearTime = setTimeout("startWatch( )", 1000)
};
function startWatch(){
setInterval(function () {
console.log(count);
count++
}, 1000);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="an exercise to manipulate DOM-elements">
<meta name="author" content="lars berg">
<meta name="keywords" content="a template for at exercise">
<link rel="stylesheet" type="text/css" href="css/style.css">
<title>DOM | Manipulate</title>
<script src="https://kit.fontawesome.com/fa41e523cd.js" crossorigin="anonymous"></script>
<script src="scripts/script.js" defer></script>
</head>
<body>
<header>
<h1>DOM | Manipulation</h1>
</header>
<main>
<div class="flex-container">
<div class="counter-container">
<h2 class="h2-counter">How long time will it take to read this information?</h2>
<div id="timer">
00:00:00
</div>
<div class="buttons">
<button id="btn-start-stop" type="button">
<i class="fa-solid fa-play fa-2x"></i>
</button>
<button id="btn-reset" type="button">
<i class="fa-solid fa-arrow-rotate-left fa-2x"></i>
</button>
</div>
</div>
</div>
</main>
<footer>
</footer>
</body>
</html>

How do I handle multiple created buttons with JavaScript in a ToDo web script that all have the same class name?

I am making a simple ToDo app that when you write in the input form and submit it, it posts it neatly in a flex-box design below.
After it adds Your writing to the ToDo list at the bottom, JavaScript clears the input selection box.
My problem is that all the created ToDo list items are the SAME! They have the same class name and structure. I do not know how to handle all the buttons that are created so that when you click on the <button class='delete-btn'>x</button> it deletes only that button.
I have put all the writing templates created into a simple array called arrayOfText.
I was hoping I could delete the specific <div class='todo-div'>...</div> that the button was clicked from and then rewrite the whole .innerHTML of the ToDo list section.
This basically updates it and removes the div from the ToDo list that the button was clicked from, but I cannot seem to get it to work.
If you need more information, please message me.
"use strict";
const outputSection = document.querySelector("#output-section");
outputSection.innerHTML = "";
const writingArea = document.querySelector("#writing-area");
const publishBtn = document.querySelector(".default-btn");
const deleteBtns = document.getElementsByClassName("delete-btn");
const allToDoDivs = document.getElementsByClassName("todo-div");
const arrayOfText = [];
const cutAndPrintFunc = function (e) {
e.preventDefault();
//take writing in and print it to the current agenda
// clear the writing area
if (writingArea.value != "") {
const date = new Date();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDay()).padStart(2, "0");
const year = date.getFullYear();
const hour = date.getHours() > 12 ? date.getHours() - 12 : date.getHours();
const AMorPM = date.getHours() > 12 ? "PM" : "AM";
const minute = String(date.getMinutes()).padStart(2, "0");
const template = `
<div class="todo-div">
<h1 class="text-content">${writingArea.value}</h1>
<button class="delete-btn">x</button>
<p class="date-p">${month}/${day}/${year} --- requested # ${hour}:${minute} ${AMorPM} </p>
</div>`;
arrayOfText.push(template);
outputSection.insertAdjacentHTML("beforeend", template);
writingArea.value = "";
Array.from(allToDoDivs).forEach((el, ind) => {
if (ind % 2 === 0) {
el.style.backgroundColor = "#3ce815";
el.lastElementChild.style.color = "black";
}
//-----this does not work
// Array.from(allToDoDivs)[
// allToDoDivs.length - 1
// ].children[1].addEventListener("click", () => {
// console.log(this);
// // arrayOfText.pop(this);
// // outputSection.innerHTML = arrayOfText.join("");
// });
});
}
};
//publish text by hitting enter or pressing the plus sign in textbox
publishBtn.addEventListener("click", cutAndPrintFunc);
<!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" />
<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=Comfortaa&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="/style.css" type="text/css" />
<title>Griffin's ToDo List</title>
</head>
<body>
<header>
<h1>
Welcome to <em style="text-decoration: underline">Griffin's</em> To-Do
List
</h1>
<div id="mini-flex-div">
<div class="ball" id="blue"> </div>
<div class="ball" id="orange"> </div>
<div class="ball" id="purple"> </div>
<p>What needs to be done today...</p>
<div class="ball" id="purple"> </div>
<div class="ball" id="orange"> </div>
<div class="ball" id="blue"> </div>
</div>
</header>
<main>
<div id="writer-div">
<form>
<input
id="writing-area"
type="text"
rows="1"
placeholder="Lets get this out of the way..."
maxlength="50"
spellcheck="true"
autofocus
></input>
<button class='default-btn'>+</button>
</form>
</div>
</main>
<div id="bottom-header">
<h1 id="output-h1">The current agenda...<hr id="splitter"></h1>
</div>
<section id="output-section">
<div class="todo-div">
<h1 class="text-content">Mow the lawn</h1>
<button class="delete-btn">x</button>
<p class="date-p">mm/dd/yyyy</p>
</div>
<div class="todo-div">
<h1 class="text-content">Mow the lawn</h1>
<button class="delete-btn">x</button>
<p class="date-p">mm/dd/yyyy</p>
</div>
</section>
<script src="/toDo.js"></script>
</body>
</html>
There are really only rare cases where you want to manipulate the DOM through HTML. So using insertAdjacentHTML and innerHTML is most of the time not what you want to do.
Use createElement, appendChild and removeChild instead.
For the delete button, you can use event delegation, and find the todo div that corresponds to the button using closest.
Alternating coloring per row can be done with a CSS rule.
Using all this you will have a code like that:
"use strict";
const outputSection = document.querySelector("#output-section");
outputSection.innerHTML = "";
const writingArea = document.querySelector("#writing-area");
const publishBtn = document.querySelector(".default-btn");
const cutAndPrintFunc = function(e) {
e.preventDefault();
//take writing in and print it to the current agenda
// clear the writing area
if (writingArea.value != "") {
const date = new Date();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDay()).padStart(2, "0");
const year = date.getFullYear();
const hour = date.getHours() > 12 ? date.getHours() - 12 : date.getHours();
const AMorPM = date.getHours() > 12 ? "PM" : "AM";
const minute = String(date.getMinutes()).padStart(2, "0");
// create an actual div element using createElement
const todoItem = document.createElement('div')
// add the todo-div class to it
todoItem.classList.add('todo-div')
// here you can use innerHTML, but you still might want to
// avoid its usage in general
todoItem.innerHTML = `
<h1 class="text-content">${writingArea.value}</h1>
<button class="delete-btn">x</button>
<p class="date-p">${month}/${day}/${year} --- requested # ${hour}:${minute} ${AMorPM} </p>
`;
// append the created div element to the outputSection
outputSection.appendChild(todoItem);
writingArea.value = "";
}
};
//publish text by hitting enter or pressing the plus sign in textbox
publishBtn.addEventListener("click", cutAndPrintFunc);
// we attach an event listener on outputSection for click
outputSection.addEventListener("click", (evt) => {
// only handle the click if it happend on the delete button
if (evt.target.matches('.delete-btn')) {
evt.preventDefault();
// At this point the evt.target is the delete button the
// click happened on so you need search for the
// ascendant that represents the todo-div using closest
// and remove that element from outputSection
outputSection.removeChild(evt.target.closest('.todo-div'))
}
})
/* use the odd rule to style all odd todo-div elements */
.todo-div:nth-child(odd) {
background-color: #3ce815;
}
<!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" />
<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=Comfortaa&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/style.css" type="text/css" />
<title>Griffin's ToDo List</title>
</head>
<body>
<header>
<h1>
Welcome to <em style="text-decoration: underline">Griffin's</em> To-Do List
</h1>
<div id="mini-flex-div">
<div class="ball" id="blue"> </div>
<div class="ball" id="orange"> </div>
<div class="ball" id="purple"> </div>
<p>What needs to be done today...</p>
<div class="ball" id="purple"> </div>
<div class="ball" id="orange"> </div>
<div class="ball" id="blue"> </div>
</div>
</header>
<main>
<div id="writer-div">
<form>
<input id="writing-area" type="text" rows="1" placeholder="Lets get this out of the way..." maxlength="50" spellcheck="true" autofocus>
<button class='default-btn'>+</button>
</form>
</div>
</main>
<div id="bottom-header">
<h1 id="output-h1">The current agenda...
<hr id="splitter">
</h1>
</div>
<section id="output-section">
<div class="todo-div">
<h1 class="text-content">Mow the lawn</h1>
<button class="delete-btn">x</button>
<p class="date-p">mm/dd/yyyy</p>
</div>
<div class="todo-div">
<h1 class="text-content">Mow the lawn</h1>
<button class="delete-btn">x</button>
<p class="date-p">mm/dd/yyyy</p>
</div>
</section>
<script src="/toDo.js"></script>
</body>
</html>
Unrelated to your problem:
input elements do not have a closing tag </input>
If you simply wish to remove the item from the list, start at the clicked button, use parentNode to find the "grand" parent (parent's parent) element, and remove, removeChild, the button's parent element:
// get all buttons and add a click event listener
document.querySelectorAll("button.delete-btn").forEach(btn => btn.addEventListener("click",
evt => {
// get the button's "grandparent", and remove the parent
evt.target.parentNode.parentNode.removeChild(evt.target.parentNode);
}
))
<!-- SAMPLE TO DO LIST -->
<section id="output-section">
<div class="todo-div" style="background-color: rgb(60, 232, 21);">
<h1 class="text-content">abc</h1>
<button class="delete-btn">x</button>
<p class="date-p" style="color: black;">06/00/2022 --- requested # 7:49 AM </p>
</div>
<div class="todo-div">
<h1 class="text-content">def</h1>
<button class="delete-btn">x</button>
<p class="date-p">06/00/2022 --- requested # 7:49 AM </p>
</div>
<div class="todo-div" style="background-color: rgb(60, 232, 21);">
<h1 class="text-content">ghi</h1>
<button class="delete-btn">x</button>
<p class="date-p" style="color: black;">06/00/2022 --- requested # 7:49 AM </p>
</div>
</section>
here is some improvements in your html and js file.
we provide each inserted div an id based on arrayOfText length so we can direct access id and used it with combine todo-div + id
and remove particular div from its own parent.
"use strict";
const outputSection = document.querySelector("#output-section");
outputSection.innerHTML = "";
const writingArea = document.querySelector("#writing-area");
const publishBtn = document.querySelector(".default-btn");
const deleteBtns = document.getElementsByClassName("delete-btn");
const allToDoDivs = document.getElementsByClassName("todo");
const arrayOfText = [];
const cutAndPrintFunc = function (e) {
e.preventDefault();
//take writing in and print it to the current agenda
// clear the writing area
if (writingArea.value != "") {
const date = new Date();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDay()).padStart(2, "0");
const year = date.getFullYear();
const hour = date.getHours() > 12 ? date.getHours() - 12 : date.getHours();
const AMorPM = date.getHours() > 12 ? "PM" : "AM";
const minute = String(date.getMinutes()).padStart(2, "0");
const indexAdd = (arrayOfText.length === 0) ? 0 : arrayOfText.length;
const template = `
<div class="todo todo-div${indexAdd}">
<h1 class="text-content">${writingArea.value}</h1>
<button class="delete-btn" onclick="removeTodoDiv(${indexAdd})">x</button>
<p class="date-p">${month}/${day}/${year} --- requested # ${hour}:${minute} ${AMorPM} </p>
</div>`;
arrayOfText.push(template);
outputSection.insertAdjacentHTML("beforeend", template);
writingArea.value = "";
Array.from(allToDoDivs).forEach((el, ind) => {
if (ind % 2 === 0) {
el.style.backgroundColor = "#3ce815";
el.lastElementChild.style.color = "black";
}
//-----this does not work
// Array.from(allToDoDivs)[
// allToDoDivs.length - 1
// ].children[1].addEventListener("click", () => {
// console.log(this);
// // arrayOfText.pop(this);
// // outputSection.innerHTML = arrayOfText.join("");
// });
});
}
};
//publish text by hitting enter or pressing the plus sign in textbox
publishBtn.addEventListener("click", cutAndPrintFunc);
function removeTodoDiv(index) {
const findDiv = document.getElementsByClassName('todo-div' + index)[0];
findDiv.parentNode.removeChild(findDiv);
}
<!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" />
<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=Comfortaa&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/style.css" type="text/css" />
<title>Griffin's ToDo List</title>
</head>
<body>
<header>
<h1>
Welcome to <em style="text-decoration: underline">Griffin's</em> To-Do
List
</h1>
<div id="mini-flex-div">
<div class="ball" id="blue"> </div>
<div class="ball" id="orange"> </div>
<div class="ball" id="purple"> </div>
<p>What needs to be done today...</p>
<div class="ball" id="purple"> </div>
<div class="ball" id="orange"> </div>
<div class="ball" id="blue"> </div>
</div>
</header>
<main>
<div id="writer-div">
<form>
<input id="writing-area" type="text" rows="1" placeholder="Lets get this out of the way..." maxlength="50"
spellcheck="true" autofocus></input>
<button class='default-btn'>+</button>
</form>
</div>
</main>
<div id="bottom-header">
<h1 id="output-h1">The current agenda...
<hr id="splitter">
</h1>
</div>
<section id="output-section">
<!-- <div class="todo-div">
<h1 class="text-content">Mow the lawn</h1>
<button class="delete-btn">x</button>
<p class="date-p">mm/dd/yyyy</p>
</div>
<div class="todo-div">
<h1 class="text-content">Mow the lawn</h1>
<button class="delete-btn">x</button>
<p class="date-p">mm/dd/yyyy</p>
</div> -->
</section>
<script src="./index.js"></script>
</body>
</html>

JS click event listener only works once and not with the expected if statement

I'm using a library for comparing different photos, like a "before and after" sort of thing, where they're displayed one on top of the other and there's a button in the center that you can drag left or right to see the differences.
Now, what I'm trying to do is implement two buttons - one on the left of the picture and one on the right.
When you click these buttons, I want the photos to change with the previous two or the next two.
I made an if statement for the buttons, but they don't work properly, although I don't notice any obvious error.
HTML code
<div id="wrapper">
<div class="arrowsContainer">
<div id="leftArrow">
<p>Left</p>
</div>
</div>
<div class="cd-image-container">
<img src="" id="originalImage" alt="Original Image">
<div class="cd-resize-img">
<img src="" id="modifiedImage" alt="Modified Image">
</div>
<span class="cd-handle"></span>
</div>
<div class="arrowsContainer">
<div id="rightArrow">
<p>Right</p>
</div>
</div>
</div>
JavaScript code
let originalImage = document.querySelector('#originalImage');
let modifiedImage = document.querySelector('#modifiedImage');
document.querySelector('#leftArrow').addEventListener("click", function(){
if ((modifiedImage.src = "img/3.jpg") && (originalImage.src = "img/4.jpg")){
modifiedImage.src = "img/1.jpg";
originalImage.src = "img/2.jpg";
}
});
document.querySelector('#rightArrow').addEventListener('click', function(){
if ((modifiedImage.src = "img/1.jpg") && (originalImage.src = "img/2.jpg")){
modifiedImage.src = "img/3.jpg";
originalImage.src = "img/4.jpg";
}
if ((modifiedImage.src = "img/3.jpg") && (originalImage.src = "img/4.jpg")){
modifiedImage.src = "img/5.jpg";
originalImage.src = "img/6.jpg";
}
if ((modifiedImage.src = "img/5.jpg") && (originalImage.src = "img/6.jpg")){
modifiedImage.src = "img/7.jpg";
originalImage.src = "img/8.jpg";
}
});
Right now, if I open the page, photos 1 & 2 are shown. If I click on the "right" button, it will display pics 7 & 8, and from there, if I click on the "left" button it will display pics 1 & 2 again, although the condition I have on the "left" button doesn't even include the scenario where you're at pics 7 & 8.
Please help, I really don't understand what's happening
I think what you are trying to achieve is that, when you click on the right button you want to show the next two images and when you click on the prev button you want to show the previous two images. If that's the case then you can check my solution.
Here is the js file.
let originalImage = document.querySelector("#originalImage");
let modifiedImage = document.querySelector("#modifiedImage");
const totalImages = 8;
let currentCount = 0;
document.querySelector("#leftArrow").addEventListener("click", function() {
currentCount = (currentCount - 2 + totalImages) % totalImages;
originalImage.src = `./img/${currentCount + 1}.jpg`;
modifiedImage.src = `./img/${currentCount + 2}.jpg`;
});
document.querySelector("#rightArrow").addEventListener("click", function() {
currentCount = (currentCount + 2) % totalImages;
originalImage.src = `./img/${currentCount + 1}.jpg`;
modifiedImage.src = `./img/${currentCount + 2}.jpg`;
});
And here is the .html file
<!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>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- <div class="container">Item</div> -->
<div id="wrapper">
<div class="arrowsContainer">
<div id="leftArrow">
<p>Left</p>
</div>
</div>
<div class="cd-image-container">
<img src="./img/1.jpg" id="originalImage" alt="Original Image" />
<div class="cd-resize-img">
<img src="./img/2.jpg" id="modifiedImage" alt="Modified Image" />
</div>
<span class="cd-handle"></span>
</div>
<div class="arrowsContainer">
<div id="rightArrow">
<p>Right</p>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
let originalImage = document.querySelector("#originalImage");
let modifiedImage = document.querySelector("#modifiedImage");
const totalImages = 8;
let currentCount = 0;
document.querySelector("#leftArrow").addEventListener("click", function() {
currentCount = (currentCount - 2 + totalImages) % totalImages;
originalImage.src = `https://i.picsum.photos/id/${currentCount + 1}/200/300.jpg`;
modifiedImage.src = `https://i.picsum.photos/id/${currentCount + 2}/200/300.jpg`;
});
document.querySelector("#rightArrow").addEventListener("click", function() {
currentCount = (currentCount + 2) % totalImages;
originalImage.src = `https://i.picsum.photos/id/${currentCount + 1}/200/300.jpg`;
modifiedImage.src = `https://i.picsum.photos/id/${currentCount + 2}/200/300.jpg`;
});
#wrapper {
display: flex;
}
.cd-image-container {
display: flex;
}
#leftArrow,
#rightArrow {
cursor: pointer;
}
<!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>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- <div class="container">Item</div> -->
<div id="wrapper">
<div class="arrowsContainer">
<div id="leftArrow">
<p>Left</p>
</div>
</div>
<div class="cd-image-container">
<img src="https://i.picsum.photos/id/1/200/300.jpg" id="originalImage" alt="Original Image" />
<div class="cd-resize-img">
<img src="https://i.picsum.photos/id/2/200/300.jpg" id="modifiedImage" alt="Modified Image" />
</div>
<span class="cd-handle"></span>
</div>
<div class="arrowsContainer">
<div id="rightArrow">
<p>Right</p>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
Use == or === in if statement
Give this a shot
if ((modifiedImage.src == "img/1.jpg") && (originalImage.src == "img/2.jpg")){
modifiedImage.src = "img/3.jpg";
originalImage.src = "img/4.jpg";here

How to clear div output when input field is empty?

I have simple weight converter and I would like to clear the output when input field is empty.
I've tried to use reset, clear or empty method, but no one of them worked
const form = document.querySelector('.input');
form.addEventListener('keyup', e => {
e.preventDefault();
const getValue = form.add.value.trim();
const convert = weight => {
document.querySelector('.pounds').innerText = "Pounds: " + Math.round(weight * 2.20462262);
};
if (getValue.length) {
convert(getValue);
}
});
<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">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<title>Todo List</title>
</head>
<body>
<div class="container">
<h1>Weight converter</h1>
<form class="input">
<input type="number" name="add">
</form>
<div class="pounds green "></div>
<div class="ounces red "></div>
<div class="grams blue "></div>
</div>
<script src="app.js"></script>
</body>
</html>
A ternary is useful
Also input handles paste
note I only preventDefault on the submit
const form = document.querySelector('.input');
const output = document.querySelector('.pounds');
const convert = weight => {
return "Pounds: " + Math.round(weight * 2.20462262);
};
form.addEventListener('submit', e => { // handles enter in the field
e.preventDefault();
});
form.addEventListener('input', () => {
const getValue = form.add.value.trim();
output.innerText = getValue.length ? convert(getValue) : "";
});
<div class="container">
<h1>Weight converter</h1>
<form class="input">
<input type="number" name="add" id="add">
</form>
<div class="pounds green "></div>
<div class="ounces red "></div>
<div class="grams blue "></div>
</div>
Full code
const form = document.querySelector('.input');
const convert = weight => {
return {
"pounds": Math.round(weight * 2.20462262),
"ounces": Math.round(weight * 35.274),
"grams": weight * 1000
}
};
form.addEventListener('submit', e => {
e.preventDefault();
})
form.addEventListener('input', () => {
const getValue = form.add.value.trim();
if (getValue.length) {
const weights = convert(getValue);
for (w in weights) {
document.querySelector("." + w).innerText = weights[w]
}
}
});
<div class="container">
<h1>Weight converter</h1>
<form class="input">
<input type="number" name="add" id="add">
</form>
<div class="pounds green "></div>
<div class="ounces red "></div>
<div class="grams blue "></div>
</div>
Try setting the innerText to '' like so :
if (getValue.length) {
convert(getValue);
} else {
document.querySelector('.pounds').innerText = '';
}
This should work

When I rendering my template I would like to display a function of eventHandler

I made a templating with handlebars, so now my problem is simple :
When user put a letter or words or something else in the input field, the function launch the ajax call and he return the result.
But, I think, I took the problem upside down.
So if you would like to help me, you can check the code :
import Handlebars from 'handlebars'
export default class Templating {
constructor() {
this._grabDom();
this._addListener();
this._getData();
this._putData();
}
/* PRIVATE METHODS */
_createBounds() {
['_getData', '_putData', '_prevent']
.forEach((fn) => this[fn] = this[fn].bind(this));
}
_putData() {
for (let i = 0; i < this._parsing.search.length; i++) {
let compiledTemplate = Handlebars.compile(this._dom.cardsTemplate);
let generated = compiledTemplate(this._parsing.search[i]);
this._dom.cardsContainer.innerHTML += generated
}
}
_getData() {
let req = new XMLHttpRequest();
req.open('GET', 'http://joibor.fr/api/search.json', false);
req.send(null);
if (req.status === 200) {
this._parsing = JSON.parse(req.responseText);
}
}
_prevent(pEvt) {
if (pEvt.keyCode === 13) {
pEvt.preventDefault();
this._value = pEvt.target.value;
}
}
/* END PRIVATE METHODS */
/* PUBLIC METHODS */
/* END PUBLIC METHODS */
/* EVENT HANDLER */
_addListener() {
this._dom.searchInput.addEventListener('keydown', this._prevent)
}
/* END EVENT HANDLER */
/* GRAB DOM */
_grabDom() {
this._dom = {};
this._dom.cardsTemplate = document.querySelector('#cards-template').innerHTML;
this._dom.cardsContainer = document.querySelector('.section-bottom__template');
this._dom.searchInput = document.querySelector('.js-search-input');
}
/* END GRAB DOM*/
}
<!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>Search</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div class="section-top">
<form class="form">
<label class="form__label" for="">Lieux</label>
<input type="text" class="form__input js-search-input" placeholder="...">
</form>
</div>
<section class="section-bottom">
<h2 class="section-bottom__title">Les membres qui se trouvent à Reims</h2>
<div class="section-bottom__template"></div>
<script id="cards-template" type="text/x-handlebars-template">
<div class="cards">
<div class="cards__position">
<img class="cards__image" src="{{image}}" alt="profil 1">
<div class="cards-content">
<div class="about about--flex">
<p class="about__name">{{name}}</p>
<p class="about__city">{{city}}</p>
</div>
<div class="text">
<p class="text__content"><span class="text__content__cat">Disponible : </span> {{start}} <span class="text__content__cat">au</span> {{end}}</p>
</div>
<div class="place">
<p class="place__content"><span class="place__content__cat">Nombre max de voyageurs : </span> {{max}}</p>
</div>
</div>
</div>
</div>
</script>
</section>
<script src="js/script.js"></script>
</body>
</html>
Actually, the templating works but not the search I can't solved this problem.

Categories

Resources