Reputation: 9476
I have a list of checkboxes with certain settings that I store in a variable on pageload. Now I want to check every change of them against the original state, so that I can do something if the original state is restored.
Unfortunately I have no idea how to check the states against the ones in the variable. Can someone point me in the right direction?
Here is what I got so far:
var ocs = $('.abocenter .subscriptions-lists input[type="checkbox"]');
$('.abocenter .subscriptions-lists').on('change', 'input[type="checkbox"]', function() {
//Check against ocs somehow
});
The checkboxes have 4 different name types with mostly repeating values.
SOLUTION
I went for the simplest solution in my eyes. As a requirement I gave each check box element a data custom attribute, like this:
<input type="checkbox" name="weekly" value="company" data-checked="true" checked>Company News
<input type="checkbox" name="weekly" value="structured" data-checked="false">Structured Finance
Now I just loop through each checkbox and compare the values with the current state:
$(".subscriptions-lists").on('change', 'input[type="checkbox"]', function() {
var indicator = true;
$(".subscriptions-lists input[type='checkbox']").each(function() {
if($(this).prop('checked') !== $(this).data('checked')) {
indicator = false;
//No more original state
}
if(indicator === false) {
return;
}
}).promise().done( function() {
if(indicator === true) {
//Original State restored, do sth. :)
}
});
});
Although I had some good answers to my question, I believe this is the best and simplest solution for me.
Thank you all for your help!
Upvotes: 2
Views: 590
Reputation: 2022
The solution I worked out works by adding a custom data storage property to each checkbox so they all maintain their own state independently.
I added a JQuery extension method like so:
$.fn.IsOriginalState = function () {
var data = $(this).prop("stateData");
if (data == null || data == undefined) {
data = {
OriginalState: $(this).prop("checked"),
CurrentState: $(this).prop("checked")
}
$(this).prop("stateData", data);
data = $(this).prop("stateData");
}
return data.OriginalState == data.CurrentState;
};
Then, you can find out if an individual checkbox is in the original state by selecting it normally and invoking this function.
$("#checkbox1").IsOriginalState();
On page load, you then populate this by invoking the method on each checkbox:
$(document).ready(function () {
$("input[type='checkbox']").each(function() {
$(this).IsOriginalState(); //Set the initial values
});
});
The final step is to setup a change event handler for each one to change the CurrentState
property.
$("input[type='checkbox']").change(function (data) {
$(this).prop("stateData").CurrentState = $(this).prop("checked");
});
I have put together a jsFiddle to demonstrate: http://jsfiddle.net/xDaevax/1qmtkds9/
If you need an event to handle the condition when all checkboxes are in their original state (checked each time one is changed), I would create a custom event that is triggered each time a checkbox is changed that compares the checkbox states like this:
$(document).bind("check-changed", function (e) {
var originalCount = 0;
$("input[type='checkbox']").each(function () {
if ($(this).IsOriginalState()) {
originalCount++;
}
});
var isOriginal = originalCount == $("input[type='checkbox']").length;
if (isOriginal) {
alert("Checkboxes are in their original state.");
} // end if
});
Then make the change event behave this way:
$("input[type='checkbox']").change(function (data) {
$(this).prop("stateData").CurrentState = $(this).prop("checked");
$(document).trigger("check-changed");
});
Upvotes: 1
Reputation: 13735
Assuming all of the elements have a "name", I'd personally do this-
var $subscriptionsLists = $('.abocenter').find('.subscriptions-lists'); // This is more efficient than a chained selector
var ocs = {}; // Plain JavaScript object
$subscriptionsLists.find('input[type="checkbox"]').each(function (index, checkbox) { // See http://api.jquery.com/each/ for details of the method
ocs[checkbox.name] = checkbox.checked; // checkbox is a DOM element and not jQuery in each loop. See https://developer.mozilla.org/en-US/docs/Web/API/Element.name and https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input
});
$subscriptionsLists.on('change', 'input[type="checkbox"]', function (event) {
if (ocs[this.name] !== this.checked) {
// Do something
}
});
This could also be adapted to use ID if name is not available.
I have created a working jsfiddle.net example at http://jsfiddle.net/oL28y3yx/
Upvotes: 1
Reputation: 288120
You can't use ocs
to get the original states because it only contains references to the html elements. Then, when they change, the data you see in ocs
changes too.
But if you want to know the default checked state, you can use
this.hasAttribute('checked')
Note this will only work if you changed their checked state in the proper way, that is, using checked
property or jQuery's prop()
. If you used setAttribute()
or jQuery's attr()
, it won't work.
Upvotes: 1