Linda Kadz
Linda Kadz

Reputation: 361

localStorage returns wrong value for checkbox

I am using local storage to restore data incase a user accidentally reloads the page, but when they reload a checkbox is checked even when they did not check it.

Below is my code, the only wrong value that's being rendered is the checkbox. I have other fields which value the are being restored are accurate upon reload of the page.

I think I am missing one thing, or two, any help would be really appreciated. Thanks.

var remember_state = {
name: "rememberState",
clearOnSubmit: true,
_defaultNoticeDialog: function() {
  return $("<p />", { "class": "remember_state" })
    .html('Restore previously entered information? <a class="btn btn-sm btn-link" href="#"><i class="mrx far fa-history"></i>Restore</a>');
},
noticeConfirmSelector: "a",
noticeSelector: ".remember_state",
use_ids: false,
objName: false,
restoreState: function(e) {
  var data = JSON.parse(localStorage.getItem(this.objName)),
      $f = this.$el,
      $e;
  for (var i in data) {
    $e = $f.find("[name=\"" + data[i].name + "\"]");
    if ($e.is(":radio")) {
      $e.filter("[value=\"" + data[i].value + "\"]").prop("checked", true);
    }
    else if ($e.is(":checkbox") && data[i].value) {
      $e.prop("checked", true);
    }
    else if ($e.is("select")) {
      $e.find("[value=\"" + data[i].value + "\"]").prop("selected", true);
    }
    else {
      $e.val(data[i].value);
    }
    $e.change();
  }
  this.noticeDialog.remove();
  e && e.preventDefault && e.preventDefault();
},
cancelNotice: function(e) {
  e.preventDefault();
  this.noticeDialog.remove();
},
chooseStorageProp: function() {
  if (this.$el.length > 1) {
    if (console && console.warn) {
      console.warn("WARNING: Cannot process more than one form with the same" +
        " object. Attempting to use form IDs instead.");
    }
    this.objName = this.$el.attr("id");
  }
},
errorNoID: function() {
  if (console && console.log) {
    console.log("ERROR: No form ID or object name. Add an ID or pass" +
      " in an object name");
  }
},
saveState: function(e) {
  var instance = e.data.instance;
  var values = instance.$el.serializeArray();
  // jQuery doesn't currently support datetime-local inputs despite a
  // comment by dmethvin stating the contrary:
  // http://bugs.jquery.com/ticket/5667
  // Manually storing input type until jQuery is patched
  instance.$el.find("input[type='datetime-local']").each(function() {
    var $i = $(this);
    values.push({ name: $i.attr("name"), value: $i.val() });
  });
  values = instance.removeIgnored(values);
  values.length && internals.setObject(instance.objName, values);
},
save: function() {
  var instance = this;
  if (!this.saveState) {
    instance = this.data(remember_state.name);
  }
  instance.saveState({ data: { instance: instance } });
},
bindNoticeDialog: function() {
  if (!this.noticeDialog || !this.noticeDialog.length || !this.noticeDialog.jquery) {
    this.noticeDialog = this._defaultNoticeDialog();
  }
  this.noticeDialog.on("click." + this.name, this.noticeConfirmSelector, $.proxy(this.restoreState, this));
  this.noticeDialog.on("click." + this.name, this.noticeCancelSelector, $.proxy(this.cancelNotice, this));
},
setName: function() {
  this.objName = this.objName || this.$el.attr("id");
  if (!this.objName) { this.errorNoID(); }
},
init: function() {
  this.bindNoticeDialog();
  this.setName();

  if (!this.objName) { return; }

  this.bindResetEvents();
  this.createNoticeDialog();

  $(window).bind("unload." + this.name, { instance: this }, this.saveState);
}

};

EDIT: I did a console.log on the in the for loop and the value of console.log(data.value[i]) at $e.is(":checkbox") is 0

Upvotes: 1

Views: 65

Answers (1)

Linda Kadz
Linda Kadz

Reputation: 361

We are using the jquery library jquery_remember_state and my problem was a bug they had where similar names of checkboxes would return the same value even if they had different values. We are using simple_form and it adds a hidden value for checkbox so it would give us the bug when trying to restore state.

The change I had to make was this:

if ($e.is(":checkbox") && data[i].value) {
          $e = $e.filter("[value=\"" + data[i].value + "\"]");
          if ($e.length) {
            $e.prop("checked", true);
          }
        }

Here's the file with the full code incase anyone ever experiences this problem:

https://github.com/RepairShopr/jquery_remember_state/blob/multiple-checkboxes/source/javascripts/jquery.remember-state.js

Upvotes: 1

Related Questions