94

I've run into a bit of an issue. Here's a brief explanation.

I have 12 check boxes on a standard form. What I need to do is loop through each of them and learn which ones are checked and which ones are unchecked.

Using this, I can then build a string which I then enter into a database field. Here is an example.

(Check1 - checked)
(Check2 - not checked)
(Check3 - checked)

1,0,1

So far, I've got this bit of code.

$('input[type=checkbox]').each(function () {
           if (this.checked) {
               console.log($(this).val()); 
           }
});

It works perfectly except that it only brings back the checked ones, not all.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Richard M
  • 1,445
  • 2
  • 13
  • 20
  • 5
    You should redesign your database schema. – SLaks Dec 27 '09 at 03:50
  • Redesign how? Isn't storing a group of check boxes in one field better than having one field for each check box? – Richard M Dec 27 '09 at 04:18
  • 4
    This obviously depends on what the checkboxes are, but you should probably either use individual fields or a child table (with one field per row per [checked] checkbox) – SLaks Dec 27 '09 at 07:14
  • _"Isn't storing a group of check boxes in one field better than having one field for each check box?"_ No, because your ones and zeros aren't stored as bits, they're stored as bytes. If your reason for storing a comma-separated-value bit-list in one field is for efficiency, then lose the comma and use **bitwise and mask** operations instead. Although, mysql these days has implemented the bit data-type, so bitwise and mask may not be necessary, unless you're programming credit card chips or you need something absolutely blazingly fast. –  Apr 23 '20 at 22:02

5 Answers5

148

To build a result string exactly in the format you show, you can use this:

var sList = "";
$('input[type=checkbox]').each(function () {
    sList += "(" + $(this).val() + "-" + (this.checked ? "checked" : "not checked") + ")";
});
console.log (sList);

However, I would agree with @SLaks, I think you should re-consider the structure into which you will store this in your database.

EDIT: Sorry, I mis-read the output format you were looking for. Here is an update:

var sList = "";
$('input[type=checkbox]').each(function () {
    var sThisVal = (this.checked ? "1" : "0");
    sList += (sList=="" ? sThisVal : "," + sThisVal);
});
console.log (sList);
jdecuyper
  • 3,934
  • 9
  • 39
  • 51
Ed Schembor
  • 8,090
  • 8
  • 31
  • 37
  • 1
    As I understand, he wants a string on `1`s and `0`s. – SLaks Dec 27 '09 at 04:09
  • Thanks. I'll try this out and let you know. – Richard M Dec 27 '09 at 04:19
  • Hmm. I tried this, but it displayed the entire js file in the console log. – Richard M Dec 27 '09 at 17:34
  • 1
    I can't use **this** but need to use **$(this)** – V-SHY Jan 14 '16 at 18:53
  • I have this: https://jsfiddle.net/vrctvt65/ based on your EDIT... However, How can I make it so that if check 1 and check 4 is checked, it won't have the extra commas? Thanks. – Si8 Mar 24 '17 at 19:39
  • 1
    @Si8 - I updated the fiddle, so the code ignores the unselected checkboxes, which should alleviate the extra commas: https://jsfiddle.net/m4k6vj8x/ – Ed Schembor Mar 25 '17 at 01:43
  • +1. You beat me to it. I was able to make it work, same way you did. Thanks for the help, even though it is an old answer. – Si8 Mar 27 '17 at 13:37
63

Using Selectors

You can get all checked checkboxes like this:

var boxes = $(":checkbox:checked");

And all non-checked like this:

var nboxes = $(":checkbox:not(:checked)");

You could merely cycle through either one of these collections, and store those names. If anything is absent, you know it either was or wasn't checked. In PHP, if you had an array of names which were checked, you could simply do an in_array() request to know whether or not any particular box should be checked at a later date.

Serialize

jQuery also has a serialize method that will maintain the state of your form controls. For instance, the example provided on jQuery's website follows:

single=Single2&multiple=Multiple&multiple=Multiple3&check=check2&radio=radio2

This will enable you to keep the information for which elements were checked as well.

Community
  • 1
  • 1
Sampson
  • 265,109
  • 74
  • 539
  • 565
16

You can loop through all of the checkboxes by writing $(':checkbox').each(...).

If I understand your question correctly, you're looking for the following code:

var str = "";

$(':checkbox').each(function() {
    str += this.checked ? "1," : "0,";
});

str = str.substr(0, str.length - 1);    //Remove the trailing comma

This code will loop through all of the checkboxes and add either 1, or 0, to a string.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Thanks. Will give this a try as well. – Richard M Dec 27 '09 at 04:20
  • You could also use the value attribute. If you are trying to create a binary value, then give each check box an incramenting power of 2 and just add the checked ones up, the sum in binary will be the same as appending ones and zeros. You will be limited to 32 check boxes (largest numerical value is 2^32 in JavaScript [I think, could be 64]. A better database design would be more flexible) – Jason Sperske Dec 27 '09 at 18:26
0

I don't think enough time was paid attention to the schema considerations brought up in the original post. So, here is something to consider for any newbies.

Let's say you went ahead and built this solution. All of your menial values are conctenated into a single value and stored in the database. You are indeed saving [a little] space in your database and some time coding.

Now let's consider that you must perform the frequent and easy task of adding a new checkbox between the current checkboxes 3 & 4. Your development manager, customer, whatever expects this to be a simple change.

So you add the checkbox to the UI (the easy part). Your looping code would already concatenate the values no matter how many checkboxes. You also figure your database field is just a varchar or other string type so it should be fine as well.

What happens when customers or you try to view the data from before the change? You're essentially serializing from left to right. However, now the values after 3 are all off by 1 character. What are you going to do with all of your existing data? Are you going write an application, pull it all back out of the database, process it to add in a default value for the new question position and then store it all back in the database? What happens when you have several new values a week or month apart? What if you move the locations and jQuery processes them in a different order? All your data is hosed and has to be reprocessed again to rearrange it.

The whole concept of NOT providing a tight key-value relationship is ludacris and will wind up getting you into trouble sooner rather than later. For those of you considering this, please don't. The other suggestions for schema changes are fine. Use a child table, more fields in the main table, a question-answer table, etc. Just don't store non-labeled data when the structure of that data is subject to change.

Nathon
  • 173
  • 1
  • 8
-1
$.extend($.expr[':'], {
        unchecked: function (obj) {
            return ((obj.type == 'checkbox' || obj.type == 'radio') && !$(obj).is(':checked'));
        }
    });

$("input:checked")
$("input:unchecked")
Thulasiram
  • 8,432
  • 8
  • 46
  • 54