Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery each looping once

Tags:

html

jquery

<script type="text/javascript">
    $(document).ready(function () {
        var country = ["United States", "Canada", "Australia", "United Kingdom"];
        var state = {
            "United States": "Alaska",
            "United States" : "Alabama"
        };
        $(this).click(function () {
            if ($.inArray($(this).val(), country)) {
                $.each(state, function (key, val) {
                    if ($("#country").val() == key) {
                        $("#state").append("<option value=" + val + ">" + val + "</option>");
                    }
                });
            }
        });
    });
</script>

Basically what I'm trying to do is, I have a Multi-select for the Countries, I want to populate "#state" based on what a user clicks on for Countries, right now it's only showing the first item "Alaska" under the multiple select.

Not exactly sure what i'm doing wrong.

like image 301
Anthony Vasquez Avatar asked Dec 17 '14 09:12

Anthony Vasquez


2 Answers

You cannot do:

var state = {
    "United States" : "Alaska",
    "United States" : "Alabama"
};

Keys in an object must be unique. Your second "United States" key overwrites the first "United States" key, leaving your object being just:

var state = {
    "United States" : "Alabama"
};

Instead, you'll need to store an object, which maps countries to states:

var state = {
    "United States" : ["Alaska", "Alabama"],
    "United Kingdom" : ["Scotland", "England"] // "states" in the UK?
};

... and then alter your click handler accordingly:

$(this).click(function () {
    if ($.inArray($(this).val(), country)) {
        $.each(state, function (key, val) {
            if ($("#country").val() == key) {
                $.each(val, function (i, name) { 
                    $("#state").append("<option value=" + name + ">" + name + "</option>");
                });
            }
        });
    }
});

Note:

  1. Your $(this).click() selector is likely wrong. It should likely be an ID or class selector (e.g. $('#your_id'), $('.your-class')).

  2. You'll probably want to empty the $('#state') select before you append to it. To do this, add $(this).children().remove() within the click handler (but outside of the loops).

  3. I'm not sure why you're keeping an array of country names, as well as a object mapping country names to states; do-away with country, and just use the keys of state to get your countries.

  4. Remember that $().val() for a multi-select returns an array of the results, not a single value.

With all of these notes taken into account, and with some misc. tidying, here's the code I've come up with:

$(document).ready(function () {
    var countries = {
        "United States": ["Alaska", "Alabama"],
        "United Kingdom": ["Scotland", "England"] // "states" in the UK?
    };

    // SETUP: Ignore this bit.
    Object.keys(countries).forEach(function (val) {
       $('#multiselect').append('<option value="' + val + '">' + val + '</option>');
    });
    // END SETUP.

    $('#multiselect').change(function () {
        var vals = $(this).val();
        var states = $('#state');
        
        states.children().remove();
        
        jQuery.each(vals, function (i, name) {          
            var country = countries[name];
            
            jQuery.each(country, function (i, val) {
                states.append('<option value="' + val + '">' + val + '</option>');
            });
        });
    });    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select multiple="multiple" id="multiselect"></select>
<select multiple="multiple" id="state"></select>

See it working here: http://jsfiddle.net/6dnbgf24/1/

like image 124
Matt Avatar answered Nov 15 '22 03:11

Matt


It is not possible to set multiple values with the same key, you have to wrap the values into an array this way:

var state = {
"United States" : ["Alaska", "Alabama"]
};

And then update your code accordingly:

$.each(state, function(key, val){           
    for( var i in val){
        $("#state").append("<option value="+val[i]+">"+val[i]+"</option>");
        }
    });

The above code has not been tested, may contain unmatched parenthesis.

like image 44
Daniels118 Avatar answered Nov 15 '22 04:11

Daniels118