How do I keep single checkbox stay checked after refreshing the page?

冷暖自知 提交于 2021-02-07 06:49:19

问题


HTML code:

    <div class="wrap">
        <h3>Background Swap:</h3>
        <form action="" method="POST">
            <div id="checkbox-container">
                Shadowless background: <input type="checkbox" name="new_background" id="checker" <?php echo (isset($_POST['new_background']))? "checked='checked'": "";?>/><br /><br />
            </div>
            <input type="submit" name="submit" value="Upgrade Background" class="button" />
        </form>
    </div>

This will make the checkbox stays checked, but when page is refresh or exit and comes back, the checkbox will be unchecked. Therefore, after some research, I tried the localStorage, but doesn't seem to quite figure it out yet.

localStorage code:

    var checkboxValue = JSON.parse(localStorage.getItem('checkboxValue')) || {};
    var $checkbox = $("#checkbox-container :checkbox");

    $checkbox.on("change", function(){
        $checkbox.each(function(){
            checkboxValue[this.id] = this.checked; 
        });
        localStorage.setItem("checkboxValue", JSON.stringify(checkboxValue));
    });

    //on page load
    $.each(checkboxValue, function(key, value){
        $("#" + key).prop('checked', value);
    });

I have script tags around the localStorage code and after implementing these codes, my checkbox still doesn't stays checked.

Both code as a whole:

<div class="wrap">
<h3>Background Swap:</h3>
<form action="" method="POST">
    <div id="checkbox-container">
        Background Swap: <input type="checkbox" name="new_background"/>
    </div>
    <script>
        var checkboxValue = JSON.parse(localStorage.getItem('checkboxValue')) || {}
        var $checkbox = $("#checkbox-container :checkbox");

        $checkbox.on("change", function(){
            $checkbox.each(function(){
                checkboxValue[this.id] = this.checked; 
            });
            localStorage.setItem("checkboxValue", JSON.stringify(checkboxValue));
        });

        //on page load
        $.each(checkboxValue, function(key, value){
            $("#" + key).prop('checked', value);
        });
        </script>
        <input type="submit" name="submit" value="Upgrade Background" class="button"/>
</form>
</div>

I would like to thank everyone that took time to help me figure out the solution to my question with the biggest thanks to @Pranav C Balan!!! Check out the finished code @ http://stackoverflow.com/a/44321072/3037257


回答1:


I think your code is executing before the form elements are loading, so place it at the end of your code or wrap it using document ready handler to execute only after the elements are loaded. If you were placed the code before the element $("#checkbox-container :checkbox") would select nothing since it is not yet loaded in the DOM.

One more thing to do, in your code the checkbox doesn't have any id so add a unique id to the element to make it work since the JSON is generating using the id value.

<div class="wrap">
  <h3>Background Swap:</h3>
  <form action="" method="POST">
    <div id="checkbox-container">
      Background Swap: <input type="checkbox" id="name" name="new_background" />
    </div>

    <input type="submit" name="submit" value="Upgrade Background" class="button" />
  </form>
  <script>
    var checkboxValue = JSON.parse(localStorage.getItem('checkboxValue')) || {}
    var $checkbox = $("#checkbox-container :checkbox");

    $checkbox.on("change", function() {
      $checkbox.each(function() {
        checkboxValue[this.id] = this.checked;
      });
      localStorage.setItem("checkboxValue", JSON.stringify(checkboxValue));
    });

    //on page load
    $.each(checkboxValue, function(key, value) {
      $("#" + key).prop('checked', value);
    });
  </script>
</div>

Working demo : FIDDLE


<script>
  // document ready handler
  // or $(document).ready(Function(){...
  jQuery(function($) {
    var checkboxValue = JSON.parse(localStorage.getItem('checkboxValue')) || {}
    var $checkbox = $("#checkbox-container :checkbox");

    $checkbox.on("change", function() {
      $checkbox.each(function() {
        checkboxValue[this.id] = this.checked;
      });
      localStorage.setItem("checkboxValue", JSON.stringify(checkboxValue));
    });

    //on page load
    $.each(checkboxValue, function(key, value) {
      $("#" + key).prop('checked', value);
    });
  });
</script>
<div class="wrap">
  <h3>Background Swap:</h3>
  <form action="" method="POST">
    <div id="checkbox-container">
      Background Swap: <input type="checkbox" id="name" name="new_background" />
    </div>

    <input type="submit" name="submit" value="Upgrade Background" class="button" />
  </form>

</div>

Working demo : FIDDLE




回答2:


An alternative to localStorage that only utilizes document.cookie:

$('input:checkbox').change(function() {
    saveCookies();
});

To register the function and the actual function:

function saveCookies() {
    var checkArray = [];
    $('input.comic-check').each(function() {
        if ($(this).is(':checked')) {
            checkArray.push(1);
        } else {
            checkArray.push(0);
        }
    });
    document.cookie = "checks=" + checkArray;
}

This is an alternative to localStorage, and depends on whether you want it to persist longer

And to retrieve the saved (on load)

var checks = getCookie("checks");
if (checks != "") {
    checkArray = checks.split(',');
    //unchecks boxes based on cookies
    //also has backwards compatability provided we only append to the list in landing.ejs/generator.js
    for (var i = 0; i < checkArray.length; i++) {
        if (checkArray[i] == "0" && $('input.comic-check').length > i) {
            var checkBox = $('input.comic-check')[i];
            $(checkBox).prop('checked', false);
        }
    }
}
function getCookie(cname) {
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}



回答3:


Three situations you will need to check the checkbox

  1. PHP have it set to checked="checked" (checked)

  2. localStorage have it as true (checked)

  3. all other situations this should be unchecked

all you need is to make sure first two situation you check the checkbox, then by default it is unchecked, but in your each you are also uncheck checkbox, therefore ignored the PHP part (as php set it to checked but localStorege set it to unchecked)

Example here: https://jsfiddle.net/dalinhuang/efwc7ejb/

//on page load
$.each(checkboxValue, function(key, value) {
    if(value){
       $("#" + key).prop('checked', value);
    }
});



回答4:


I would change:

<?php echo (isset($_POST['new_background']))? "checked='checked'": "";?>

for:

<?php echo (isset($_POST['new_background']) && $_POST['new_background']=="on")? "checked" : "";?>

In inline HTML, you don't need the checked attribute to be checked=checked.
Just checked is enought.

checked=checked is used in JavaScript to programatically check a checkbox.

EDIT
About your localStorage...

I made an example for you on CodePen

//on page load, check the appropriate checkboxes.
var onloadChecks = JSON.parse(localStorage.getItem("checkboxValue"))
$.each(onloadChecks, function(key, value){
  $("#" + key).prop('checked', value);
});

// ================ Saving checks

// Checkboxes collection.
var allCheckboxes = $("input[type='checkbox']");

// On change handler.
allCheckboxes.on("change", function() {

  // Check how many checkboxes we have.
  var jsonCheckboxes = {};
  console.log("There is "+allCheckboxes.length+" checkboxes.");

  // Building the json.
  for(i=0;i<allCheckboxes.length;i++){
    console.log(allCheckboxes.eq(i).attr("id"));
    console.log(allCheckboxes.eq(i).is(":checked"));
    jsonCheckboxes[allCheckboxes.eq(i).attr("id")] = allCheckboxes.eq(i).is(":checked");
  }
  console.log("jsonCheckboxes: "+JSON.stringify(jsonCheckboxes));

  // Setting localStorage.
  localStorage.setItem("checkboxValue", JSON.stringify(jsonCheckboxes));
  console.log("LocalStorage: "+ localStorage.getItem("checkboxValue") );
});



回答5:


Working around your comment : my goal is to find something that will make my checkbox stays checked if the user choose to, here's a way to have the localStorage handle it :

jQuery (3.2.1)

$(document).ready(function() {

var bground = localStorage.getItem('background'); // get the value if exists

if (bground == 'shadow') { // checkbox has been previously checked
    $('#checker').attr('checked', 'checked');
}
if (bground == 'shadowless') { // checkbox has been previously unchecked
    $('#checker').attr('');
}

$('#submit').submit(function() { // when form is submitted
    bground = localStorage.getItem('background'); // get the value in LS
    if($('#checker').is(':checked')) // is it checked or not ?
    { sh = 'shadow'; } else { sh = 'shadowless'; }
    localStorage.setItem('background', sh); // update LS with new value
}); 

});

HTML (added id="submit" to form)

<form action="" id="submit" method="POST">
  <div id="checkbox-container">
  Shadowless background: <input type="checkbox" name="new_background" id="checker" /><br />
  </div>
  <input type="submit" name="submit" value="Upgrade Background" class="button" />
</form>

This will make the checkbox stays checked, and when page is refreshed, the checkbox will be checked/unchecked depending on user's previous choice.

You could also use the jQuery change function instead of form submitting. Just modify the line :

$('#submit').submit(function() { // comment/delete this line
// to the one below
// $('#checker').change(function() { // uncomment this line


来源:https://stackoverflow.com/questions/44310386/how-do-i-keep-single-checkbox-stay-checked-after-refreshing-the-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!