views:

448

answers:

2

Suggestions other that dumping IE6 that is... I can't control that :)

Quick synopsis of what I am trying to do: I have a form with select elements. When the user selects a specific option in the select (id type2 in the code below), I display a div structure that contains a new select. I want the new div structure and its children to be a clone of an existing one (id pdProgramDiv1) because I use php to populate the select in the div. Once the select is cloned, I need to change the clone's id and name of the div and its child label and select because the form information is getting passed to my submit php script. If they don't have unique ids, then although they are serialized into the query string, the $_POST array in php only includes the last value of a given id.

I have included the code that works absolutely perfectly in Firefox sigh, and fails to change the ids and names in IE6. This code may not be as concise as some; I am still pretty new to jQuery.

$('#type2').change(function() {
    if ($('#type2 option:selected').text() == 'Program Director') {
        $('#pdProgramDiv1').clone().attr({id: 'pdProgramDiv2', name: 'pdProgramDiv2'}).appendTo($('#type2Div'));

        $('#pdProgramDiv2 > #pdProgram1').attr({id: 'pdProgram2', name: 'pdProgram2'});

        $('#pdProgramDiv2 > label').attr('for', 'pdProgram2');
    } else {
        $('#pdProgramDiv2').hide();
    }
}); 

I have looked around, and tried using variables rather than chaining, and individual calls to attr rather than using the object literal (or map), but nothing helps. All the variations work fine in FF, but no joy in IE6.

Is this a known problem, or can anyone tell me way to make the changes happen?

If I can't get this to work, I guess I will have to create all the elements and hide them, but that doesn't seem as good.

Thanks in advance as always!

UPDATE: SOLVED

Thanks so much to the folks that found the error of my ways. I wanted to post the code that ending up solving the problem. As I said in my comment to the accepted answer below, the fix makes perfect sense. A little embarassed I didn't see it, but sometimes a fresh pair of eyes is needed! The only change is with selecting the child select rather than the select ID, and removing the name attr assignment on div, because as mentioned, it does nothing.

$('#type2').change(function() {
    if ($('#type2 option:selected').text() == 'Program Director') {
        $('#pdProgramDiv1').clone()
            .attr('id', 'pdProgramDiv2')
            .appendTo($('#type2Div'));

        $('#pdProgramDiv2 > select').attr({
             id: 'pdProgram2', 
             name: 'pdProgram2'});

        $('#pdProgramDiv2 > label').attr('for', 'pdProgram2');
    } else {
        $('#pdProgramDiv2').hide();
    }
}); 
A: 

I believe you've just crashed in a problem with IE6, because it handles poorly the node cloning, if at all. It precisely fails on fixing the name and id of the clonned elements...

More info here.

Alfabravo
So no jQuery way to make it work? Ugh. I was hoping someone would have one of those "oh you just need to do this..." answers :) I guess my only option is to create them all and hide them. Brute force but it will have to do. I didn't see am answer on the linked site. Maybe I am missing it?
Carvell Fenton
+3  A: 

I think you problem is here...

$('#type2').change(function() {
    /* snip */
        $('#pdProgramDiv1').clone().attr({id: 'pdProgramDiv2', name: 'pdProgramDiv2'}).appendTo($('#type2Div'));

        $('#pdProgramDiv2 > #pdProgram1').attr({id: 'pdProgram2', name: 'pdProgram2'});
    /* snip */
});

You're cloning the container, switching it's ID, and inserting it back into the page. The containers are fine, but the page now cotnains two elements ID'd #pdProgram1. document.getElementById is not going to like that.

Refactor the code to search for the select element by its tag instead of by its ID.

BBonifield
I am a little confused. I thought that calling .attr after the clone call but before the appendTo would change the id and name before affecting the Dom. When I debug in firebug that is what I see. The generated HTML has all unique ids as I would expect. Are you suggesting I select by tag because of IE?
Carvell Fenton
It changes the ID and name of the div, yes. (But, er, divs don't have names, so that doesn't do anything.) It doesn't change the ID of the `<select id="pdProgram1">` that is inside the div. As soon as you insert that into the document you've got two elements with one ID and anything might happen. You need to change all the IDs before you put it back in the document.
bobince
Oh sorry. I think is see what you mean. You think my second line can't find the select because at that instant there are two. So I would $('#pdProgramDiv > select').attr(...) etc for the second line? I will try it. Sorry this is from my iPhone. Forgive typos.
Carvell Fenton
Beautiful! That works perfectly. Thanks so much bbonifield and bobince! Also that makes sense. Given that the fix makes perfect sense to me, I now wonder why my original code worked in FF? I will post the working code tomorrow if I can just to close he loop. Thanks again.
Carvell Fenton