21

My control is built dynamically accordingly to user input, there are n textboxes whose IDs are dynamic too.

However, I did not foresee that this HTML would be reused elsewhere within the same html page.

The problem I'm facing now are the duplicated IDs, which are causing my jQuery functions to not work well.

I do understand that IDs should be unique, however, can I avoid the issue by using the outermost <div> with different IDs?

Any experts out there can give me some good advice?

P.S. I'm looking for an effective solution, because if I need to change the ID for each element, it would require a lot of work in my jQuery.

Please help. Thanks!

<div id="Container1">
  <div id="Control">
    <input type="text" id="TextBox1" />
    <input type="text" id="TextBox2" />
  </div>
</div>

<div id="Container2">
  <div id="Control">
    <input type="text" id="TextBox1" />
    <input type="text" id="TextBox2" />
  </div>
</div>

I'm wondering if, in the jQuery functions, I can do something like.. #container1 > #textbox1 in the selection?

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
pekcheng
  • 354
  • 1
  • 5
  • 14
  • If you cant solve it with class names you can add append an incremental number to the id if the dynamically created inputs! – M Reza Saberi Feb 27 '14 at 05:06
  • related: https://stackoverflow.com/q/9454645 – djvg Sep 20 '21 at 07:43
  • If you are writing html dynamically with JS, Svelte, or any other templating system, consider using `data-*` attributes instead of classes. This allows you to completely separate JS/CSS concerns. There are some small performance benefits to worry about, but the benefits to our code maintainability have increased more than the supposed millisecond level slowdowns. https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-* – cassepipe Jun 02 '23 at 16:19

9 Answers9

23

You absolutely should not have duplicate IDs. It may work*, but it is semantically incorrect and you should not do it

You should restructure your jQuery, however much that may stink. The best option would be to use a class, perhaps using the specific id of the parent to specify which one you want

Another less attractive but viable way would be to add a number or something to the end of the ID to make it unique then use jQuery to detect any elements with a specific part of an ID

* - As Arun describes jQuery will accept the selector, but it is NOT favorable because it is incorrect

Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
7

I do understand that "Id" should be unique, however, with the outest with different "id", can it help in solving the problem?

No. Having non-unique element ids will not work. Not consistently, in any case (different browsers and frameworks may handle this case differently).

Any experts out there can give me some good advises?

Prefer using class over using id, particularly for any component which may be reused multiple times on a page.

Set ids against the containing elements themselves instead of the internal component elements, and revise your jQuery selectors accordingly. Or alternately implement your component such that it takes a 'namespace' parameter/attribute when used, and prefix each classname with the namespace inside of your component (this approach works particularly well when creating custom JSP tags).

aroth
  • 54,026
  • 20
  • 135
  • 176
5

I would suggest you to use class instead of id. Duplicate id's are not a good practice.

Rahul Desai
  • 15,242
  • 19
  • 83
  • 138
5

Even though is is wrong there is nothing wrong with the selector in jQuery

$('#Container1 #TextBox1').val(1)
$('#Container2 #TextBox1').val(2)

Demo: Fiddle


A better choice will be use attribute selector

$('#Container1 input[id="TextBox1"]').val(1)
$('#Container2 input[id="TextBox1"]').val(2)

Demo: Fiddle

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Those who down vote please explain, so that others can learn :( – SajithNair Feb 27 '14 at 05:09
  • @SajithNair because ID must be unique and in anyway should not repeat... somebody just wants to make sure that that is not breached – Arun P Johny Feb 27 '14 at 05:09
  • @SajithNair I just wanted to give OP an option to use his current sytesm... (I knew the downvote was coming) – Arun P Johny Feb 27 '14 at 05:10
  • In think this is the answer for this particular scenario question – SajithNair Feb 27 '14 at 05:13
  • 2
    @SajithNair not really... wouldn't recommend it – Arun P Johny Feb 27 '14 at 05:14
  • 1
    @ArunPJohny - That _must_ is a little pedantic. Different browsers (and frameworks) will handle this case differently. In certain cases, it can work roughly as expected. It's not a good idea to rely upon it, as noted. But it can work. – aroth Feb 27 '14 at 05:14
  • @aroth yes... don't why the upvotes though.. may even beat the more better answers – Arun P Johny Feb 27 '14 at 05:14
  • 1
    this will be good test case for SO voting pattern... (how time how crazy it can become) :) – Arun P Johny Feb 27 '14 at 05:22
  • Can anyone show a spec. that says duplicate ids are bad if inside unique containers? I have this issue and my developers don't want to fix it because they say `$('#uniqueContainer #duplicateId')` is ok. – user9645 Mar 30 '16 at 13:45
2

I will suggest use class instead of id. Or add some postfix while generating dynamic ids.

Amit
  • 15,217
  • 8
  • 46
  • 68
  • Or even better, the data-* attributes that are made especially for that use case of embedding data in html tags : https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-* – cassepipe Jun 02 '23 at 16:17
2

Depends on HTML version:

  1. HTML 4 ID must be document-wide unique.
  2. HTML 5 ID unique in its container tree.

but we suggest are not good practice

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
Sunil Shakya
  • 8,097
  • 2
  • 17
  • 20
1

You can't have the same id multiple times. Use class instead.

v42
  • 1,415
  • 14
  • 23
  • Or even better than `class`, the data-* attributes that are made especially for that use case of embedding data in html tags : https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-* – cassepipe Jun 02 '23 at 16:17
0

COMPONENTS: if you write reusable component e.g. ) in your example then if you put two ore more components into one document then you will get INVALID html. So instead id use class.

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • 1
    Or even better than `class`, the data-* attributes that are made especially for that use case of embedding data in html tags : https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-* – cassepipe Jun 02 '23 at 16:17
0

It's not suggested to do this and it's incorrect when writing semantic HTML code.

But it won't throw an error in browser and it won't break the document.querySelectorAll(), test in Chrome, it works as the method used to be.

let a = document.querySelectorAll('#header');
console.log(a.length);
a = document.querySelector('#header');
console.log(a);
<body>
  <h1 id="header">header 1</h1>
  <h1 id="header">header 2</h1>
</body>
Han Jelly
  • 1
  • 1