Sebsemillia
Sebsemillia

Reputation: 9476

Check checkbox state against original state in variable

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

Answers (3)

xDaevax
xDaevax

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

pwdst
pwdst

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

Oriol
Oriol

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

Related Questions