views:

126

answers:

3

I'am maintaining a GUI built using JQuery. In one part of the GUI, multiple tabs can be opened to edit data.

When a new tab is opened, it is created by cloning the first tab content div and updating the input fields in the div.

The new tab is given a unique ID based on the tab index, but all other ID's within the cloned tab div are the same as the original tab div.

Now, that seems to cause problems since ID's are not unique any more. When selecting an input field the following works on Firefox 3.6.8:

$('#tabs-2 #scriptName').val( data.name );

This selects the tab div with ID tabs-2 and then selects the input field within that div with the ID scriptName and sets its value. Now this does not work on Chrome or Firefox 3.0.19.

The DOM hierachy looks something like this

<div id="tabs">
     <div id="tabs-1">
         ...
         <input id="scriptName"/>
         ...
     </div>
     ...
     <div id="tabs-2">
         ...
         <input id="scriptName"/>
         ...
     </div>
 </div>

One solution would be to make all ID's wihtin the cloned tab content div unique, but that seems like a brute force aproach. It must be possible to address the content within a div in a more independent way without require a unique ID.

The cloning of the whole div when generating a new tab is of course a crude hack, a more elegant solution would be to reuse the same div but change the content depending on the selected tab, but that is how it is built right now and unfortunately it was developed and tested using a later firefox browser where this selector worked.

Pre-post EDIT

I found a lot of related questions with answers that gave some hints on how to solve this, when I inserted my offline-edited question, but I post this question anyway since good suggestions for how to solve this are always welcome.

EDIT

I'am trying the class approach right now, I do have one problem though, some input fields uses labels with for attribute, the for attribute must point to a unique id. But that can be solved by omitting the for attribute and make the input field a nested element instead.

+1  A: 

ID's are unique identifiers. The moment you introduce a duplicate id, you have an invalid document on your hands.

The best way to get around this is to refrain from using id's on anything that is going to be cloned. Instead, use a "unique" class name to identify the element. Then, when it is cloned, you can walk down the DOM to each copy of the class. jQuery has very good DOM traversal methods for this.

http://api.jquery.com/category/traversing/

Additionally: .children(), .parent(), .parents(), and .siblings() are particularly useful. I'd stay away from .find() unless it cannot be helped. .find() can be slow if you are searching through many, many nodes in the DOM. Since you're building an interface, this might be the case.

Stephen
The ID's are unique was something that struck me initially, I believe that the CSS class should have been used instead.It now works, but I'am struggling with the CSS stylesheet to make it all look right again ;)
Ernelli
+1  A: 

just a suggestion, can you make id of the input as class? So that you don't have a problem when cloning. and your code would be something like, $('#tabs-2 .scriptName').val( data.name );

Reigel
A: 

Hi, I don't know will it helps in your case but you can try .find() jQuery method.

Try something like this expression:

$('#tabs-2').find('#scriptName').val( data.name );
gyromonotron