Why does order of defining attributes for a dynamically created checkbox in jquery affect its value?
Asked Answered
L

1

0

I have this code in a js file:

function buildRolePicker() {
    var pnl = $("[id$='staffRoles']");
    $.each(roles["ContactGroupRoles"], function(iteration, item) {
        pnl.append(
                $(document.createElement("input")).attr({
                    id: 'cgr' + item['RoleId'],
                    name: 'cgroles',
                    value: item['RoleId'],
                    title: item['RoleName'],
                    type: 'checkbox'
                })
        );
        pnl.append(
                $(document.createElement('label')).attr({
                    'for': 'cgr' + item['RoleId']
                })
                .text(item['RoleName'])
        );
    });

    alert(document.forms[0].cgroles[8].value);
}

I was wasting some time in other sections of code trying to work out why a call to

alert(document.forms[0].cgroles[8].value);

was returning a value of "on" when it should be returning a long. It turns out the problem is the order in which the attributes are defined. If i change this:

            $(document.createElement("input")).attr({
                id: 'cgr' + item['RoleId'],
                name: 'cgroles',
                value: item['RoleId'],
                title: item['RoleName'],
                type: 'checkbox'
            })

to this:

                $(document.createElement("input")).attr({
                    type: 'checkbox',
                    id: 'cgr' + item['RoleId'],
                    name: 'cgroles',
                    value: item['RoleId'],
                    title: item['RoleName']
                })

everything works fine and I get my long value as expected when i:

alert(document.forms[0].cgroles[8].value);

My question is why?

Test Data:

var roles = {"ContactGroupRoles":[
    {"RoleId":1,"RoleName":"Pending"},
    {"RoleId":2,"RoleName":"CEO"},
    {"RoleId":3,"RoleName":"Financial Controller"},
    {"RoleId":4,"RoleName":"General Manager"},
    {"RoleId":5,"RoleName":"Production Manager"},
    {"RoleId":6,"RoleName":"Sales Manager"},
    {"RoleId":7,"RoleName":"Marketing Manager"},
    {"RoleId":8,"RoleName":"Sales Agent"},
    {"RoleId":9,"RoleName":"Customer Service"},
    {"RoleId":10,"RoleName":"Manager"}
  ]};
Lactobacillus answered 10/7, 2010 at 11:2 Comment(10)
Just a thought, but check out lines 874 and 1384 in jquery-1.4.2 (development version so it's readable, of course). It seems like if there's no value set for a checkbox it defaults to receiving the value "on" -- maybe this is happening in your case? I know you set a value, but perhaps it's not considered a valid value for a checkbox...Riles
Where and how is roles["ContactGroupRoles"] declared? Please post all associated code.Gelsenkirchen
Hi as mentioned, simply changing the order of attribute declaration resolves the issue so its not a problem with the validity of the value. roles["ContactGroupRoles"] is a javascript object. I can alert(item['RoleId']) and always get a value. Thanks Faisal, at least now i know where it was getting its "on" value from. Clearly you have to define the type before setting the value. Seems kind of obvious but i just thought jquery would "sort it" and i dont remember reading this as a requirement anywhere. (I actually dragged the basis of this code off of another SO question). tiny.cc/stc2mLactobacillus
@Lactobacillus - Is this in IE, or another browser?Stevestevedore
Gah, now that ove actually read that other post, i see he was having a similiar problem. I think ive just worked out the answer to his question. lol. Its the order of declaration.Lactobacillus
@Lactobacillus - I'm only seeing this in IE and Opera...Firefox/Chrome are working, though only IE has the type exception, hmm.Stevestevedore
@Nick - Chrome and FF also give me a value of "on" if i dont define the type of the input first. Seems kind of obvious that you should have too. Teach me to drag and drop code i guess. :)Lactobacillus
@Lactobacillus - Is your actual code different? I'm doing a very simple test for this: jsfiddle.net/UAJ5q/3 try it in both :)Stevestevedore
@Nick -My actual code is what ive posted but that is dfifferent from what you're testing. I wonder if the .each loop changes the equation?Lactobacillus
@Lactobacillus - It might, I posted an answer below trying to demonstrate the issue a bit more plainly, it's all moot I guess, since the proper solution is to change the order, you just had be curious as to what's happening. I expected this from IE due to how it handlers <input> type change, or rather doesn't...Opera surprised me though.Stevestevedore
S
2

It seems that for whatever reason, IE (IE8 at least) and Opera don't retain the value attribute (though Chrome/Firefox do) through changing the type. Here's a simplified test:

$(document.body).append(
    $("<input />").attr({
        value: 'Test',
        type: 'checkbox'
    })
);
alert($("input").val());
alert(document.body.innerHTML);

You can try it here

IE8/Opera alerts:

  • "on"
  • <input type="checkbox">

Chrome/Firefox alerts:

  • "Test"
  • <input type="checkbox" value="Test">

I'm not sure why Opera in particular is behaving this way, but in any case...just attempting to better demonstrate the issue, the solution of course is to keep the type attribute first. Perhaps a future jQuery release will process type first in the loop, though if the <input> was defined with any attributes earlier this still wouldn't do much good.

However, the $("<input />", { value: 'Test', type: 'checkbox' }); format suffers the same problem, IMO this should be fixed.

Stevestevedore answered 10/7, 2010 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.