0

So I am trying to combine the answer of three questions posted here on stackoverflow; Save current state after jquery click function, Save data to local storage, and HTML5 local storage save .toggleClass. What I want to do is toggle between two classes onclick using .one() from jQuery. Then after the classes are toggled.

I would like to save the last added class. My code so far is as following:

jQuery

$(".post-tag").one('click', function() {
  $(this).find('i').toggleClass('fa-meh fa-smile-beam text-warning text-success');

  var likeState = $(this).find('i').hasClass('fa-smile-beam');
  localStorage.setItem('liked', likeState);

  var likedStorage = localStorage.getItem('liked');

  if(likedStorage && $(this).find('i').hasClass('fa-smile-beam')) {
    $(this).find('i').removeClass('fa-meh')
  }
});

HTML

<div class="post-tag-wrapper">
    <div class="post-tag shadow">
        <i class="far fa-meh text-warning"></i>
    </div>
</div>

How can I achieve this?

Heads up: I know it's doable if I add the class into a Field in the Object; if using MongoDB for instance; having default as fa-meh and onclick using some AJAX will update the Field in the Object to fa-smile-beam. But it's required using LocalStorage.

Note: According to MDN, LocalStorage violates policy decision, so it's not the practice to save user interaction.

Tes3awy
  • 2,166
  • 5
  • 29
  • 51
  • I am trying to understand why you're trying to save the class state into the local storage? What is the propose of this? To keep the state across page loads? Or what are you trying to accomplish? There might be a better way of doing it. – Amir Aug 10 '18 at 23:26
  • @Amir I am trying to make a `like button` for posts where its initial state is `fa-meh` and when clicked the class changes to be `fa-smile-beam` so as when I refresh the page the class is still `fa-smile-beam` not `fa-meh`. Is this a helpful comment? – Tes3awy Aug 10 '18 at 23:34
  • @Amir I know it's doable if I add the class into a `Field` in the `Object`; if using MongoDB for instance; having default as `fa-meh` and `onclick` using some `AJAX` will update the `Field` in the `Object` to `fa-smile-beam`. But it's required from me to do it using `LocalStorage`. – Tes3awy Aug 10 '18 at 23:41

1 Answers1

1

Alright you can do something like this. The main problem with your starting point is that you can't do them in the same function. You'll need two separate functions.

  1. To toggle the state back and forth. I recommend using the .on bind method instead of .one, unless you don't want the user to be able to undo their action.

  2. When the document loads, unless you have some other way of setting the correct state of the buttons, you'll have to set the state, that is saved in local storage on the buttons.

HTML

<button class="post-tag" id="some-unique-id">
  <i class="fa-meh"></i> Like
</button>

JavaScript

// This will make sure that the state is toggled on user click
// The user can click back and forth, and the state will be saved each time
$(".post-tag").on('click', e => {
  const $elm = $(e.currentTarget);
  // If you have more than one button you'll need unique IDs for them to make this work
  const uniqueId = $elm.attr('id');
  const $i = $elm.find('i');

  $i.toggleClass('fa-meh fa-smile-beam text-warning text-success');

  const likeState = $i.hasClass('fa-smile-beam');
  localStorage.setItem(`likeState-${id}`, likeState);
});

// To persist the change you'll have to run this on page load as well
$( document ).ready(function() {
  const $postTags = $('.post-tag');
  $postTags.each((elm) => {
    const $elm = $(elm);
    const uniqueId = $elm.attr('id');
    const $i = $elm.find('i');

    // Now you apply the state stored in local sotrage to your buttons.
    const likedStorage = localStorage.getItem(`likeState-${id}`);
    if(likedStorage && $i.hasClass('fa-smile-beam')) {
      $i.removeClass('fa-meh')
    }
  });
});
Amir
  • 4,211
  • 4
  • 23
  • 41