'How can I sort the order of links based on the user's number of clicks and save it to local storage using JavaScript?
I'm trying to add the feature to sort the order of links in a specific div based on the number of times a user clicked a link. It's to pin to top Favorite links of the user. It also has to be saved in localStorage...
For example, I have this:
function clickCounter1() {
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem(`clickcount1`)) {
localStorage.setItem(`clickcount1`, Number(localStorage.getItem(`clickcount1`)) + 1);
} else {
localStorage.setItem(`clickcount1`, 1);
}
document.getElementById(`result1`).textContent = `Btn ABC: ` + localStorage.getItem(`clickcount1`);
}
}
function clickCounter2() {
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem(`clickcount2`)) {
localStorage.setItem(`clickcount2`, Number(localStorage.getItem(`clickcount2`)) + 1);
} else {
localStorage.setItem(`clickcount2`, 1);
}
document.getElementById("result2").textContent = "Btn 123: " + localStorage.clickcount2;
}
}
function clickCounter3() {
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem(`clickcount3`)) {
localStorage.setItem(`clickcount3`, Number(localStorage.getItem(`clickcount3`)) + 1);
} else {
localStorage.setItem(`clickcount3`, 1);
}
document.getElementById("result3").textContent = "Btn ZZZ: " + localStorage.clickcount3;
}
}
function clickCounter4() {
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem(`clickcount4`)) {
localStorage.setItem(`clickcount4`, Number(localStorage.getItem(`clickcount4`)) + 1);
} else {
localStorage.setItem(`clickcount4`, 1);
}
document.getElementById("result4").textContent = "Btn ZZZ: " + localStorage.clickcount4;
}
}
function clickCounter5() {
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem(`clickcount5`)) {
localStorage.setItem(`clickcount5`, Number(localStorage.getItem(`clickcount5`)) + 1);
} else {
localStorage.setItem(`clickcount5`, 1);
}
document.getElementById("result5").textContent = "Btn ZZZ: " + localStorage.clickcount5;
}
}
a {
display: block;
}
<div id="links-list">
<a href="#" id="one" onclick="clickCounter1()">A</a>
<a href="#" id="two" onclick="clickCounter2()">B</a>
<a href="#" id="three" onclick="clickCounter3()">C</a>
<a href="#" id="four" onclick="clickCounter4()">D</a>
<a href="#" id="five" onclick="clickCounter5()">E</a>
</div>
<br>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>
<div id="result4"></div>
<div id="result5"></div>
If a user clicks C the most, it should be at the top.. I've been trying to search online but couldn't find such a solution for this.
Solution 1:[1]
The messy code below should work according to your needs. It stores the number of clicks in localStorage and reorder them according to it. I rewrote the click counter code because it is much more efficient and less repetitive.
Note: The below code won’t work in the snippet, because Stack Overflow doesn't allow localStorage in their snippets.
function updateClicks(ele) {
const storage = window.localStorage.getItem(ele.innerHTML + "Clicks");
if (storage === null) {
window.localStorage.setItem(ele.innerHTML + "Clicks", "1");
} else {
var clicks = parseInt(window.localStorage.getItem(ele.innerHTML + "Clicks")) + 1;
localStorage.removeItem(ele.innerHTML + "Clicks");
window.localStorage.setItem(ele.innerHTML + "Clicks", clicks);
}
}
function orderItems() {
var order = [];
var href = [];
var links = document.getElementById("links-list");
var link = links.getElementsByTagName("a");
for (i = 0; i < link.length; i++) {
href.push(link[i].href);
}
links = links.innerHTML.split("</a>");
document.getElementById("links-list").innerHTML = "";
for (i = 0; i < links.length - 1; i++) {
var lastChar = links[i].charAt(links[i].length - 1);
var clicks = parseInt(window.localStorage.getItem(lastChar + "Clicks"));
if (isNaN(clicks)) {
clicks = 0;
}
order.push([lastChar, clicks, href[i]]);
}
order.sort(function(a, b) {
return a[1] - b[1]
});
order.reverse();
console.log(order)
for (i = 0; i < order.length; i++) {
document.getElementById("links-list").innerHTML += "<a href='" + order[i][2] + "' onclick='updateClicks(this)'>" + order[i][0] + "</a>";
}
}
a {
display: block;
}
<div id="links-list">
<a href="#" onclick="updateClicks(this)">A</a>
<a href="#" onclick="updateClicks(this)">B</a>
<a href="#" onclick="updateClicks(this)">C</a>
<a href="#" onclick="updateClicks(this)">D</a>
<a href="#" onclick="updateClicks(this)">E</a>
</div>
Solution 2:[2]
Here's my solution. Comments are inside: fiddle to test: https://jsfiddle.net/ikiK_Cro/7cutpj20/7/
// Create data for links in an array
let arr = [{
id: 1,
clicks: 0,
text: "A",
href: "#",
},
{
id: 2,
clicks: 0,
text: "B",
href: "#",
},
{
id: 3,
clicks: 0,
text: "C",
href: "#",
},
{
id: 4,
clicks: 0,
text: "D",
href: "#",
},
{
id: 5,
clicks: 0,
text: "E",
href: "#",
},
];
const makeLIst = (data) => {
// Get div for the list and empty it
const list = document.querySelector("#links-list");
list.innerHTML = "";
// If localStorage exists with name "list", use that data.
// If not, use the initial array.
localStorage.list ?
(data = JSON.parse(localStorage.list)) :
(data = arr);
// Sort data by the 'clicks' property
data.sort((a, b) => b.clicks - a.clicks);
// Create DOM, an href element for each link, and append to list div
data.forEach((i) => {
list.insertAdjacentHTML(
"beforeend",
'<a href="' + i.href + '" id="' + i.id + '" >' + i.text + "</a></br>"
);
});
// Add an Event Listener on links
document.querySelectorAll("#links-list a").forEach((item) => {
item.addEventListener("click", (event) => {
// Get the id and index of the clicked element in the data array
const foundIndex = data.findIndex((x) => x.id == event.target.id);
// Add a new click to it
data[foundIndex].clicks = data[foundIndex].clicks + 1;
// Save it
localStorage.setItem("list", JSON.stringify(data));
// Call this function again to apply the new sorted link
makeLIst(data);
});
});
};
// Call on load
makeLIst(arr);
<div id="links-list"></div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Peter Mortensen |
| Solution 2 | Peter Mortensen |
