Remember checkbox value

I have some checkboxes that are used to show or hide the columns of an HTML table. These checkboxes are present on every page of the site. Is there a way to “remember” the state of the checkboxes while going from one page to another?

Cookies are how to remember information.

See this cookies documentation page which goes through the issues, and gives you functions to manage them.

Thanks for the link, that page explains cookies very well.

Only thing I’m trying to understand now is: what’s the best way to use them in my case (I ask you because you already have an idea of the other javascript files I’m using :stuck_out_tongue: )? Should I create a cookie for each checkbox (keeping info about their state) and then check their state before initializing the checkboxes to the standard checked/unchecked configuration?

What is your case?

Sorry I don’t remember.

It’s likely to be better to store all checkboxes values as a single cookie value.

You could use something like this to bring all of the checkbox values together in to one string:


var checkboxSettings = $(':checkbox').map(function () {
    return this.value;
}).get().join();
// gives "0,0,0,0,0,1,1"
// then save as a cookie

And you could use this to extract those values back out to the checkboxes


var checkboxSettings = '0,0,0,0,0,1,1'; // or retrieve from a cookie
$(checkboxSettings.split(',')).each(function (i) {
    $(':checkbox:eq(' + i + ')').attr('checked', (this.toString() === '1'));
});
// sets the checkboxes according to the values in the string

Thanks for your help, I’m getting close to a solution here.

So, first of all I had to change this part of your code


var checkboxSettings = $(':checkbox').map(function () {
    return this.value;
}).get().join();

to


var checkboxSettings = $(':checkbox').map(function () {
    return $(this).attr("checked");
}).get().join();

to see if a checkbox is checked or not, otherwise, with your code, I would receive its the value of the value attribute (sorry for this sentence :smiley: ).

Now I can succesfully create cookies but I have a problem restoring the checkboxes to the correct value. This code doesn’t seem to be working:


$(checkboxSettings.split(',')).each(function (i) {
    $(':checkbox:eq(' + i + ')').attr('checked', (this.toString() === '1'));
});

I also tried changing it to


$(checkboxSettings.split(',')).each(function (i) {
    $(':checkbox:eq(' + i + ')').attr('checked', (this.toString() === '1'));
});

Since “this” now is either true or false, based on if the checkbox is selected or not.

When this script runs, all the checkboxes become unselected :shifty:

What does the updated cookie string look like?
When you updated the code, you may have changed it from storing ‘1’ to storing ‘true’ or something else.

The restore process needs to check against the expected value in the cookie string, which may be ‘true’ or something else now.

So, what does the updated cookie string look like?

It’s a series of true and false, separated by a comma.

I just realized that I had made a mistake in my previous post. This is the correct code.

You’ll have to clarify.

Is that is the correct code that works, or that is the correct version of the code that you’re still having trouble with?

That is the correct version of the code I am having trouble with :slight_smile:

Currently you are assigning a string value of ‘true’ or ‘false’ to the checked attribute.
Things may work better if you assign a boolean value there instead.

The code I was using used (this.toString() === ‘1’) to convert it to a boolean value.
Given that your cookie stores variations of ‘true’ or ‘false’, you could check against ‘true’ instead:

(this.toString() === 'true')

The reason for using this.toString() is that jQuery provides an object to the this keyword, so it needs to be converted to a string if you desire an exact match.

It is also possible to use the jQuery val method too, which could look like:

($(this).val() === 'true')

Thank you very much for your help :slight_smile:

PS: how did you learn all these things? :smiley:

Mostly by solving problems. I didn’t know about jQuery passing the this keyword as an object until I tried to solve your problem.

I set a breakpoint in the function itself, checked the this keyword to find out why it was not equalling a string.

Once it became clear that the this keyword is not provided by jQuery as a string, but instead as an object, it became clear that we need to handle that in some way.

A lazy way would be to use the equal operator with only two equal signs:

(this == 'true')

but Douglas Crockford would yell at me for that :slight_smile:

So, the this keyword needs to be treated instead, resulting in the previous post’s solution.

Understood. And why wouldn’t it be good to use the == operator?

The == operator is quite loose in what it allows. It can be very difficult to even remember what is and what isn’t allowed as an equal comparison. Just look at what happens when comparing a == b

Source: MDC Doc Centre - Comparison Operators

When type conversion is needed, JavaScript converts String, Number, Boolean, or Object operands as follows.

[list][]When comparing a number and a string, the string is converted to a number value. JavaScript attempts to convert the string numeric literal to a Number type value. First, a mathematical value is derived from the string numeric literal. Next, this value is rounded to nearest Number type value.
[
]If one of the operands is Boolean, the Boolean operand is converted to 1 if it is true and +0 if it is false.
[*]If an object is compared with a number or string, JavaScript attempts to return the default value for the object. Operators attempt to convert the object to a primitive value, a String or Number value, using the valueOf and toString methods of the objects. If this attempt to convert the object fails, a runtime error is generated.[/list]

With a === b you have a much better chance of ensuring that what you are comparing are actually equal. It’s much better to know when things aren’t matching as they should, than for loose comparisons to allow through things that you didn’t intend.