Reputation: 17
I have a list of items with the same class and a button for each that toggles offline class when clicked. I've used the for loop and forEach loop to iterate through the list using an event listener "click" then check if the item class list contains "offline".If it contains offline the button innerText changes to offline as well as the styling. Now the issue is when I reload the page everything resets. I've tried using local storage but it restores the offline class to every item.
let statusBtn = document.getElementsByClassName("statusBtn");
let status = localStorage.getItem("status");
// Array.prototype.forEach.call(statusBtn, (Btn) => {
// Btn.addEventListener("click", () => {
// Btn.classList.toggle("offline");
// if (Btn.classList.contains("offline") == true) {
// Btn.innerText = "Offline";
// localStorage.setItem("status", "offline");
// } else {
// Btn.innerText = "Online";
// Btn.classList.remove("offline");
// localStorage.setItem("status", "online");
// }
// });
// });
for (let i = 0; i < statusBtn.length; i++) {
statusBtn[i].addEventListener("click", () => {
statusBtn[i].classList.toggle("offline");
if (statusBtn[i].classList.contains("offline") == true) {
statusBtn[i].innerText = "Offline";
localStorage.setItem("status", "offline");
} else {
statusBtn[i].innerText = "Online";
statusBtn[i].classList.remove("offline");
localStorage.setItem("status", "online");
}
});
}
for (let i = 0; i < statusBtn.length; i++) {
if (localStorage.getItem("status") === "offline") {
statusBtn[i].innerText = "Offline";
statusBtn[i].classList.add("offline");
}
}
.offline {
background: #f00;
color: #fff;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<div id="inputContainer">
<input type="text" name="search" id="myInput" placeholder=" Type The Store Name Here" />
</div>
<ul id="myUL">
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 935/932
<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Anthos: Gauteng, Krugersdorp
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 873<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Athlone: Westerncape, Athlone
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1067<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Arbour-Crossing: KwaZulu-Natal, Amazimtoti
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1052<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Amanzimtoti - KZN Amanzimtoti
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 927/950<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Arcadia: Gauteng, Arcadia, Arcadia
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 889/891<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Atteridgeville: Gauteng, Atteridgeville
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1106<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Avon-Wood: Western Cape, Avonwood
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1159<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Ballito: KwaZulu-Natal, Ballito
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 937<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Beaufort West: Western Cape, Beaufort West
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 968/969<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Bellville Mall: Western Cape, Kuilsriver
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 892<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Benmore: No Collection
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 828/829<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> BirchAcres Mall: Gauteng, Thembisa
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 881<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> BlueDowns: Westerncape, BlueDowns
</a>
</li>
</ul>
</div>
<script src="popup.js"></script>
</body>
</html>
Upvotes: 0
Views: 150
Reputation: 177684
Here is a vastly simplified version
This will make it easier to debug and fix whatever is wrong.
Note I have commented out the localStorage for the snippet. It is not recommended to get the status in a loop.
I store an array and use JSON.parse to read and JSON.stringify to write
const ul = document.getElementById("myUL");
const input = document.getElementById("myInput");
const statusBtn = document.querySelectorAll(".statusBtn");
let status = ["online","offline"] // JSON.parse(localStorage.getItem("status"));
function myFunction() {
// Declare variables
let input, filter, ul, li, a, i, txtValue;
filter = input.value.toUpperCase();
lia = ul.querySelectorAll("li a");
// Loop through all list items, and hide those who don't match the search query
lia.forEach(a => {
const txtValue = a.textContent.toUpperCase();
a.closest("li")
.classList
.toggle("hide", input && txtValue.indexOf(filter) === -1)
})
}
document.getElementById("myInput").addEventListener("keyup", myFunction);
// When the user scrolls the page, execute myFunction
window.onscroll = function() {
stickySearch();
};
// Get the navbar
let search = document.getElementById("inputContainer");
// Get the offset position of the navbar
let sticky = search.offsetTop;
// Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position
function stickySearch() {
search.classList.toggle("sticky", window.pageYOffset >= sticky);
}
ul.addEventListener("click", (e) => {
const tgt = e.target
tgt.classList.toggle("offline");
const isOnline = tgt.classList.contains("online")
tgt.textContent = isOnline ? "Offline" : "Online";
status[+tgt.dataset.idx]=isOnline ? "offline" : "online";
// localStorage.setItem("status", JSON.stringify(status));
});
statusBtn.forEach((btn,i) => {
const isOnline = status[i] === "online";
btn.textContent = isOnline ? "Online" : "Offline";
btn.dataset.idx=i;
btn.classList.add(isOnline ? "online" : "offline");
})
@import url("https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@700&display=swap");
body {
padding: 0;
scroll-behavior: smooth;
background: #18202d;
}
.container {
width: 300px;
font-family: "Roboto Condensed", sans-serif;
max-height: 200px;
scrollbar-width: thin;
}
input {
height: 25px;
width: 95%;
margin-right: 5%;
border: 1px solid #18202d;
border-radius: 0.1rem;
display: flex;
justify-content: center;
margin: 0 auto;
}
#myUL {
list-style-type: none;
padding: 0;
margin: 0;
max-height: 100px;
z-index: -1;
}
#myUL li {
border-top: solid 1px #ccc;
z-index: -1;
}
#myUL li:nth-child(even) {
background: #2b3546c2;
}
#myUL li a {
padding: 5px;
text-decoration: none;
font-size: 13px;
color: #fff;
display: block;
}
#inputContainer {
padding: 2%;
background: #18202d;
}
#myUL .ext {
color: #ccc;
padding-bottom: 1%;
}
::-webkit-scrollbar {
display: none !important;
}
.sticky {
position: fixed;
top: 0;
width: 92%;
}
.backToTop {
color: #fff;
z-index: 1;
}
.float-end {
float: right;
border-radius: 0.1rem;
border: 1px solid #ccc;
cursor: pointer;
}
.statusBtn {
background: #0f0;
}
.offline {
background: #f00;
color: #fff;
}
.hide {
display: none
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<div id="inputContainer">
<input type="text" name="search" id="myInput" placeholder=" Type The Store Name Here" />
</div>
<ul id="myUL">
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 935/932
<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Anthos: Gauteng, Krugersdorp
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 873<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Athlone: Westerncape, Athlone
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1067<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Arbour-Crossing: KwaZulu-Natal, Amazimtoti
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1052<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Amanzimtoti - KZN Amanzimtoti
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 927/950<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Arcadia: Gauteng, Arcadia, Arcadia
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 889/891<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Atteridgeville: Gauteng, Atteridgeville
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1106<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Avon-Wood: Western Cape, Avonwood
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 1159<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Ballito: KwaZulu-Natal, Ballito
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 937<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Beaufort West: Western Cape, Beaufort West
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 968/969<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Bellville Mall: Western Cape, Kuilsriver
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 892<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> Benmore: No Collection
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 828/829<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> BirchAcres Mall: Gauteng, Thembisa
</a>
</li>
<li>
<a href="#">
<div class="ext"> <i class="bi bi-arrow-right-circle"></i> Ext: 881<button class="float-end statusBtn">Online</button></div>
<i class="bi bi-geo-alt-fill"></i> BlueDowns: Westerncape, BlueDowns
</a>
</li>
</ul>
</div>
<script src="popup.js"></script>
</body>
</html>
Upvotes: 0
Reputation: 55
Note that with localStorage
functions setItem(key, value)
getItem(key)
removeItem(key)
you can only store pair of key and value from type String.
If your project grows with too much stored keys but localStorage is still fine enough another way can be parsing the values from an array by statusArray .join(' ')
to one string and get them by statusValue.split(' ')
.
for (let i = 0; i < statusBtn.length; i++) {
statusBtn[i].addEventListener("click", () => {
statusBtn[i].classList.toggle("offline")
let statusArray = localStorage.getItem("status").split(' ');
if (statusBtn[i].classList.contains("offline") == true) {
status[i].innerText = "Offline";
statusArray[i] = "offline";
} else {
statusBtn[i].innerText = "Online";
statusBtn[i].classList.remove("offline");
statusArray[i] = "online";
}
localStorage.setItem("status", statusArray.join(' '));
});
}
//LOAD STATE FROM STORAGE
let statusArray = localStorage.getItem("status").split(' ');
for (let i = 0; i < statusBtn.length; i++) {
if (statusArray[i] === "offline") {
statusBtn[i].innerText = "Offline";
statusBtn[i].classList.add("offline");
}
}
Upvotes: 0
Reputation: 7676
You can simply add an index and store the status of each button, you can think of each button as a person's name since no two persons should have the same name if you want to store the details of each one reliably
for (let i = 0; i < statusBtn.length; i++) {
statusBtn[i].addEventListener("click", () => {
statusBtn[i].classList.toggle("offline")
if (statusBtn[i].classList.contains("offline") == true) {
statusBtn[i].innerText = "Offline";
localStorage.setItem("status_of_"+ i , "offline");
} else {
statusBtn[i].innerText = "Online";
statusBtn[i].classList.remove("offline");
localStorage.setItem("status_of_"+i , "online");
}
});
}
//LOAD STATE FROM STORAGE
for (let i = 0; i < statusBtn.length; i++) {
if (localStorage.getItem("status_of_"+i) === "offline") {
statusBtn[i].innerText = "Offline";
statusBtn[i].classList.add("offline");
}
}
Upvotes: 1