RebDev
RebDev

Reputation: 335

'Uncaught TypeError' while dynamically creating select options using jQuery

I'm using jQuery to dynamically set the options available in one select box based on the option selected in another select box. But when I select an option I get the error:

Uncaught TypeError: Cannot use 'in' operator to search for '2' in entop_1

The number listed in this example error as '2' and variable "entop_1" change based on which option is selected. Any help with this issue would be appreciated.

I'm currently using jQuery 2.0.0 min. The form used is:

<form id="addForm">

<!-- Ent Select -->
<select id="ent_id" name="ent_id">
<option value="0">- Select -</option>
<option value="1">Ent 1</option>
<option value="2">Ent 2</option>
<option value="3">Ent 3</option>
</select>

<!-- Cat Select -->
<select id="cat_id" name="cat_id"></select>

</form>

And the script is:

<script type="text/javascript">
var entop_1 = {"- Select -": "0","Option A": "1","Option B": "2",};
var entop_2 = {"- Select -": "0","Option C": "3","Option D": "4",};
var entop_3 = {"- Select -": "0","Option E": "5","Option F": "6",};
$("#ent_id").change(function()
{
    var $cat_set = $("#cat_id");
    $cat_set.empty(); // remove old options
    var $ent_var = $("#ent_id option:selected").val();

    $.each('entop_' + $ent_var, function(key, value) {
        $cat_set.append($("<option></option>").attr("value", value).text(key));
    });

});
</script>

Upvotes: 0

Views: 465

Answers (2)

krishwader
krishwader

Reputation: 11371

You could use eval for that. This line

$.each('entop_' + $ent_var, function(key, value) {

must be

 $.each(eval('entop_' + $ent_var), function(key, value) {

But there are two things wrong with this this approach :

  1. Eval is evil.
  2. $.each must be used only with arrays, not objects. (You'll get a length is undefined error)

A better way would be to format your data objects into one collection, like this :

var keys = {
    1: {
        "- Select -": "0",
        "Option A": "1",
        "Option B": "2",
    },
    2: {
        "- Select -": "0",
        "Option C": "3",
        "Option D": "4",
    },
    3: {
        "- Select -": "0",
        "Option E": "5",
        "Option F": "6",
    }
}

Then you could use for..in

$("#ent_id").change(function () {
    var $cat_set = $("#cat_id");
    $cat_set.empty(); // remove old options
    var $ent_var = $("#ent_id option:selected").val();
    //find the corresponding value in object
    var options = keys[$ent_var];
    //    use for..in, not each
    for (var a in options) {
        $cat_set.append($("<option/>", {
            "text": a,
            "value": options[a]
        }));
    }
});

But, beware of the order. sometimes for..in will not go through the array in order.

Demo : http://jsfiddle.net/f6Jps/

Upvotes: 1

Thor Jacobsen
Thor Jacobsen

Reputation: 8851

If 'entop_' + $ent_var refers to arrays, you should either eval the string, or - if the arrays are located globally - use window['entop_' + $ent_var] to get the array off of the global window object.

Otherwise, jQuery will just try to iterate the string, i guess.

Here's a snip of you code, modified:

$.each(eval('entop_' + $ent_var), function(key, value) {
    $cat_set.append($("<option></option>").attr("value", value).text(key));
});

or

$.each(window['entop_' + $ent_var], function(key, value) {
    $cat_set.append($("<option></option>").attr("value", value).text(key));
});

Upvotes: 0

Related Questions