'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