Storing multi-button status on localStorage

Asked

Viewed 119 times

0

Friends, I have the following situation:

I have a list with a button on each line, they serve to define a status. When clicked change from "waiting" to "received" and is saved in localStorage. Toggle mode, I change the text and add/remove a class that stylizes the states.

Thus:

the HTML:

<li><button class="status">aguardando</button></li>
<li><button class="status">aguardando</button></li>
<li><button class="status">aguardando</button></li>

the jQuery:

$( document ).ready(function() {
  var savedText = localStorage.getItem('click');

  if(savedText) {
    $('.status').text(savedText);
  }
});

$('.status').click(function(){
    var $this = $(this);
    $this.toggleClass('texto');
    if($this.hasClass('texto')){
        $this.text('recebido');
        $this.addClass('recebido');
        $this.removeClass('aguardando');
    } else {
        $this.text('aguardando');
        $this.addClass('aguardando');
        $this.removeClass('recebido');
    }
    localStorage.setItem('click', $this.text());
});

So I have two difficulties... one is that it is not saved in localStorage only that button that was clicked ($this), affects all classes and all get that state after a refresh. This is kind of obvious that it’s going to happen, but I’m too layy to know how this could be solved, if there’s any way - without having to create a code for each button separately (there are ten of them). The second is that I need addClass/removeClass also be stored with localStorage, because so far I have only been able to save the text.

Here’s a fiddle, if you want: http://jsfiddle.net/hx6qtkvf/2/

  • But the goal is to save the state of each button separately in localStorage ? If yes because it does not use an array corresponding each button to a position ?

  • @Isac, unfortunately I don’t know how to do this. You can give me an example in jsfiddle?

  • I can but I have to understand better how what you’re trying to do works. You switch based on class texto, but none of its elements have this class. And the alternate puts other classes, so it seems kind of strange. Do the classes always coincide with the text or not at all ? In other words, it would be necessary to store the classes in localStorage or Voce can be reproduced by the text the element has ?

  • @Isac, I used this class "text" only to get the toggle effect (toggle), for when clicked change and when clicked back to the previous state. To explain it to you, I have dozens of buttons, all with the word "waiting", with red background. I want them to be changed to "received" and green in the background. And, very importantly, to be memorized in localStorage. That is, being as "received" or "waiting" continue like this when the page reloads.

  • I almost got to that, but I came across the problem that all the buttons were affected. Like, I clicked on one of them, and when I reloaded, they all had the same text, and only it had to be memorized. So I don’t know how to make you memorize each one for yourself without having to repeat the code dozens of times, with each button with a different id or class.

1 answer

1


As I suggested in comment, the best is to keep the state of everything in localStorage, as an array of elements. For what you want to do just save an array with the class to apply to each button, and the application is done in the order in which the buttons appear on the page. That is, the class at position 0 applies to the first button, the one at position 1 on the second button and so on.

Since you always have to save a string, you can save the whole array as JSON through the method JSON.parse. Then to recover what was saved just apply the reverse process with JSON.stringify.

To simplify I turned your status change code into a function applicable to any button.

Solution:

<html>
<head>
<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>

<script>
    function alternaEstado(botao){
        if(botao.hasClass('aguardando')){
            botao.text('recebido');
            botao.addClass('recebido');
            botao.removeClass('aguardando');
        } else {
            botao.text('aguardando');
            botao.addClass('aguardando');
            botao.removeClass('recebido');
        }
    }

    $( document ).ready(function() {
        //obter o array de classes pelo localStorage
        let classesBotoes = JSON.parse(localStorage.getItem("botoes"));
        if (classesBotoes === null){ //se nao houver constroi o array com base nas classes do html
            classesBotoes = [];
            $(".status").each(function(posicao){
                classesBotoes[posicao] = $(this).hasClass('aguardando') ? 'aguardando' : 'recebido';
            });
        }

        //aplica o array de classes nos botões que estão na página
        $(".status").each(function(posicao){
            let classe = classesBotoes[posicao];
            $(this).removeClass('recebido aguardando').addClass(classe).text(classe);
        });

        //no click de cada botão, altera a classe no array e guarda o array todo de novo em localStorage
        $('.status').click(function(){
            alternaEstado($(this));
            let posicaoClicada = $(".status").index($(this)); 
            classesBotoes[posicaoClicada] = $(this).hasClass('aguardando') ? 'aguardando' : 'recebido';     
            localStorage.setItem("botoes", JSON.stringify(classesBotoes));
        });
    });
</script>
<style>
    .aguardando {
        background-color:red;
    }
    .recebido {
        background-color:green;
    }
</style>
</head>
<body>
    <li><button class="status aguardando">aguardando</button></li>
    <li><button class="status aguardando">aguardando</button></li>
    <li><button class="status aguardando">aguardando</button></li>
</body>
</html>

For simplicity I let the text to be assigned to the buttons be the one corresponding to the class they have:

let classe = classesBotoes[posicao];
$(this).removeClass('recebido aguardando').addClass(classe).text(classe);
//                                                     ^------------^

You can apply any other text, but in this case you have to apply an additional logic to generate the text based on the class that the element has.

  • Very well explained and works perfectly. THANK YOU!

  • @Thiagosoubra No problem, we’re here to help :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.