Search code examples
javascripthtmljquerycss

how to save changes even user refersh page in jQuery


I had a button that change page theme to dark-mode. when you click on, it works but when refershing the page, changes will be not save. pls help me to fix that🙏🏻

html:

<div class="container">
    <label for="check">change theme: </label
    ><input type="checkbox" name="" id="check" class="checkbox" />
</div>

jQuery:

jQuery(document).ready(function () {
    jQuery('#check').change(function () {
        let data = {
            "night_details": "div",
            "night": "body",
            "tik":"checked",
        }
        localStorage.setItem("night-theme", JSON.stringify(data));  
        let theme = localStorage.getItem('night-theme');
        if(this.checked) {
            jQuery('body').addClass(JSON.parse(theme).night);
            jQuery('.container').addClass(JSON.parse(theme).night_details);
            console.log(JSON.parse(theme));
            jQuery(this).attr("checked", JSON.parse(theme).tik);
        }else {
            localStorage.clear(theme);
            jQuery('body').removeClass(JSON.parse(theme).night);
            jQuery('.container').removeClass(JSON.parse(theme).night_details);
            jQuery(this).removeAttr("checked");
        }

        if(localStorage.getItem('night-theme')) {
            let theme = localStorage.getItem('night-theme');
            jQuery('body').addClass(JSON.parse(theme).night);
            jQuery('.container').addClass(JSON.parse(theme).night_details);
            jQuery('#check').attr("checked", JSON.parse(theme).tik);
        }
        else {
            localStorage.clear(theme);
            jQuery('body').removeClass(JSON.parse(theme).night);
            jQuery('.container').removeClass(JSON.parse(theme).night_details);
            jQuery('#check').removeAttr("checked");
        }
    });
});

Solution

  • You save the state of the checkbox and theme when the checkbox is updated, but you don't read that back out and update the DOM when the page first loads. You just need to move your second if statement in to document.ready instead of within the checkbox change handler.

    Also note that the logic can be improved. Call JSON.parse() and JSON.stringify() once and save their values in a variable that you can re-use. Also, you don't need to explicitly set the state of the DOM if there is no theme data in localStorage as the page will already be in that state. In addition, the tik property in the theme object is redundant, as you already know what state the checkbox will be in given if any theme data is present in localStorage.

    With all that said, try this:

    <div class="container">
      <label for="check">change theme: </label>
      <input type="checkbox" name="" id="check" class="checkbox" />
    </div>
    
    let data = {
      "night_details": "div",
      "night": "body"
    }
    
    jQuery($ => {
      const $body = $('body');
      const $container = $('.container');
      const $check = $('#check');
    
      // set theme on load
      let theme = JSON.parse(localStorage.getItem('night-theme') || '{}');
      if (!$.isEmptyObject(theme)) {
        $body.addClass(theme.night);
        $container.addClass(theme.night_details);
        $check.prop("checked", true);
      }
    
      // set theme when checkbox is updated
      $check.on('change', e => {
        if (e.target.checked) {
          localStorage.setItem("night-theme", JSON.stringify(data));
          $body.addClass(data.night);
          $container.addClass(data.night_details);
        } else {
          localStorage.clear('night-theme');
          $body.removeClass(data.night);
          $container.removeClass(data.night_details);
        }
      });
    });
    

    Here's a working example in jsFiddle, because SO snippets are sandboxed to disallow localStorage access