0

http://jsfiddle.net/4px4whk0/
I have two question

  1. when first click the checkbox (a), the first console.log should be print the dom with empty data-selected-list attribute, I don't know why it filled what I click already (["a"]) ?
    I have to set timeout wrap the container.attr('data-selected-list', selectedList); then it works like what I want.

  2. when click other checkbox (b), I hope it will be ["a","b"] store in attribute. but it only store ["b"] , why?

I hope it can be solve by store data in html attribute not only store in jquery data api

$(document).ready(function() {
	$('.container').on('click', 'input[type="checkbox"]', function() {
        var container = $(this).closest('.container');
        var input = $(this);
        console.log(container);
        
        var selectedList = container.data('selected-list');
        if (selectedList == '') {
          selectedList = [];
        }
        
        
        if (input.is(":checked")) {
          selectedList.push(input.val());
        }
        
        console.log(selectedList);
        selectedList = JSON.stringify(selectedList);
        
        container.attr('data-selected-list', selectedList);
    });
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container" data-selected-list="">
    <input type="checkbox" value="a">a
    <input type="checkbox" value="b">b
    <input type="checkbox" value="c">c
</div>

1 Answer 1

3

You have several mistakes:

  1. if you want to print the results of your array before you change it, then move the console.log call to before you push to the array
  2. you were using attr and data interchangeably. These do two different things. attr stores the data in the DOM and data is a jquery method that stores the data somewhere within jquery itself.
  3. finally, if you're using attr you need to do JSON.stringify to serialize your array before storing it (which you did do correctly) but when you pull the data out of the DOM you have to convert it back to an array with JSON.parse
  4. jquery's attr returns undefined for an undefined DOM tag, not empty string

the right solution with these problems fixed is:

$(document).ready(function() {
    var container = $('.container');
    container.on('click', 'input[type="checkbox"]', function() {
        var input = $(this);
        console.log(container);

        var selectedList = container.attr('data-selected-list');
        if (!selectedList) {
          selectedList = [];
        }else{
          selectedList = JSON.parse(selectedList);
        }


        console.log(selectedList);
        if (input.is(":checked")) {
          selectedList.push(input.val());
        }

        selectedList = JSON.stringify(selectedList);

        container.attr('data-selected-list', selectedList);
    });

});

here's a fiddle: http://jsfiddle.net/yLz6uv1q/

Sign up to request clarification or add additional context in comments.

17 Comments

"then move the console.log call to before you push to the array" Not necessarily. Consoles are known for giving a live preview of objects. It all depends on the console and version.
Another note is perhaps drop input.is(":checked") in favour of input.checked to save an unneeded call to jQuery
@BenedictLewis: input is a jQuery object already. It would have to be this.checked and this.value for that to work.
@Macmee: Also, there's no selected-list attribute, so your .attr() call will fail.
@squint not true - container.attr('selected-list') will return undefined, which causes selectedList to be set to an empty array - same as in your answer (infact the code for this is what I wrote myself so you either c&p'd that from my answer or somehow ended up in my jsfiddle fork :P )
|