0

I was trying to make a Learning to-do list for PHP. I used bootstrap classes: collapse and list-group. Each list tag has 2 badges which serve for counters.

Badge 1 = no of time I learnt or revise the chapter.

Badge 2 = no of time I actually used the concept from the chapter.

When I click on the badges, the number on them should increase by one. I will add options for adding new chapters and sub chapters later.

For now, I want to save the values of the badges on my local storage for later use.

When I refresh the page, all the badges should be updated with their current values.

I already know how to get and retrieve data from local storage, but I do not know how to implement it in the current situation.

var badges= document.querySelectorAll('.badge');
badges.forEach(function (e) {
 e.addEventListener('click', incrementBadge);
});

function incrementBadge(e){
  let num =Number(e.target.textContent)+1;
  e.target.textContent=num;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">

<div class="container mt-5">
 <div class="row">
 <div class="col-lg-6">
 <button class="btn btn-block btn-info" data-toggle="collapse" data-target="#php">Php</button>
 <div class="collapse" id="php">
  <ul class="list-group  mt-0">
   <li class="list-group-item">Iteration
    <span data-type="revise"class="badge badge-info float-right">4</span>
    <span data-type="practice" class="badge badge-success float-right mr-3">2</span>
   </li>
   <li class="list-group-item">Selection
    <span data-type="revise" class="badge badge-info float-right">0</span>
    <span data-type="practice" class="badge badge-success float-right mr-3">2</span>
   </li> 
  </ul>      
  </div>
 </div>
 </div>
</div>



<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
TechXpert
  • 155
  • 2
  • 3
  • 10
  • It's not difficult to do. Have you tried writing the code yourself? Here's [the documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). Your strategy will be to set up the following logic: 1) assign the badge values from local storage on page load for any values that are set in local storage, and 2) write to local storage in your click event to update the value for the clicked badge. The hardest thing to do will probably be deciding how to uniquely identify the badges when you store them. – Joseph Marikle May 02 '18 at 15:02
  • I already know how to store and retrieve data from local storage. My problem is that I do not know how to uniquely identify the badges for storing and retrieving their values later and implement that in the javascript code. – TechXpert May 02 '18 at 15:09
  • If you run your snippet now, what identifies your two rows? It's the labels of `Iteration` and `Selection`, right? Unless you associate those rows with a numeric ID, that's your unique identifier right there. The next question is how you get that text-based identifier from the markup into your javascript. Do you have any ideas on how that might be accomplished? If it were me, I'd start by adding those strings as an attribute somewhere in the markup. Where do you think that might best go? – Joseph Marikle May 02 '18 at 15:13
  • I initially tried using the chapter title and the current list data for the key of the data to be stored and I got the value of the badge being clicked with some regexp. Thanks Joseph, I think I got an idea. I will use an array with name of the chapter(ie php) and the rows numeric ID will be used as index for the array. but I still cannot think of how to identify which badges and their values and store them in key-value pair and retrieve them later – TechXpert May 02 '18 at 15:20
  • Excellent. How to identify the badge. You already know which one was clicked by accessing `e.target`. From that you are already accessing the value using `.textContent`, which works. You can use `e.target.getAttribute('your-attribute-name')`. With that, you could place your key for that value on the badge itself with ``. You could also access a parent attribute with `e.target.parentNode.getAttribute('whatever')`. That choice is up to you. Could you please update your question with similar logic? – Joseph Marikle May 02 '18 at 15:26
  • I just added ids for the badges(practice and revise) From there, How do I proceed to get their individual values. key= php[Row index], value=?? – TechXpert May 02 '18 at 15:28
  • `id` is an attribute you can use, but you have to be careful with it. They must be unique for your HTML to be valid. Currently your `id`s are not unique. Also, the value you've assigned to them is not so much a unique identifier as category. I would suggest changing them from `id="revise"` and `id="practice"` to `data-type="revise"` and `data-type="practice"` respectively. the `data-` convention is not required but it's more semantically correct to prefix your custom attributes with `data-`. – Joseph Marikle May 02 '18 at 15:31
  • I got your point , and from there, how do I proceed in js to store the values of the badges. Any suggestions. I just can't think right lol. – TechXpert May 02 '18 at 15:36
  • So now you can the type of badge, but you still don't have the row. You can use the same process to identify rows (e.g. `
  • `). From your javascript you access those values using `getAttribute`. Inside your click attribute you can build up the unique identifier (row+type) by accessing `e.target.parentNode.getAttribute('data-id')` and `e.target.getAttribute('data-type')`. From there you can concatenate them to for a unique string (e.g. "iteration.practice") or add them to a javascript object (e.g. `[{id:"iteration",type:"practice"}]`).
  • – Joseph Marikle May 02 '18 at 15:45
  • So using the example above, a unique string can be build using `let key = e.target.parentNode.getAttribute('data-id') + '.' + e.target.getAttribute('data-type')`. That will be you key you use in your local storage. – Joseph Marikle May 02 '18 at 15:46
  • Thanks for your suggestion. The code now can store with key-value pair, but another problem is how to retrieve the values from the LS and display them back to the badges to their respective rows. – TechXpert May 02 '18 at 16:13
  • Correct. What format did you choose for the local storage key? – Joseph Marikle May 02 '18 at 16:19
  • key = e.target.parentNode.getAttribute('data-id') + '.' + e.target.getAttribute('data-type'); e.g iteration.practice = 3; – TechXpert May 02 '18 at 16:20