22

I have 3 buttons with same ID. I need to get each button's value when it's being clicked.

<button id="xyz" type="button" class="btn btn-primary" value="1">XYZ1</button>
<button id="xyz" type="button" class="btn btn-primary" value="2">XYZ2</button>
<button id="xyz" type="button" class="btn btn-primary" value="3">XYZ3</button>

Here is my current jQuery script:

$("#xyz").click(function(){
      var xyz = $(this).val();
      alert(xyz);
});

But it works only for the first button, clicking on the other buttons are being ignored.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Mafaik
  • 221
  • 1
  • 2
  • 5

7 Answers7

47

I have 3 buttons with same id ...

You have invalid HTML. You can't have more than one element in a page with the same id attribute value.

Quoting the spec:

7.5.2 Element identifiers: the id and class attributes

id = name [CS]
This attribute assigns a name to an element. This name must be unique in a document.

Solution: change from id to class:

<button type="button" class="btn btn-primary xyz" value="1">XYZ1</button>
<button type="button" class="btn btn-primary xyz" value="2">XYZ2</button>
<button type="button" class="btn btn-primary xyz" value="3">XYZ3</button>

And the jQuery code:

$(".xyz").click(function(){
    alert(this.value);
    // No need for jQuery :$(this).val() to get the value of the input.
});

But it works only for the first button

jQuery #id selector docs:

Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM. This behavior should not be relied on, however; a document with more than one element using the same ID is invalid.

If you look at the jQuery source you can see when you call $ with an id selecor-($("#id")), jQuery calls the native javascript document.getElementById function:

// HANDLE: $("#id")
} else {
    elem = document.getElementById( match[2] );
}

Though, in the spec of document.getElementById they didn't mention it must return the first value, this is how most of (maybe all?) the browsers implemented it.

DEMO

isherwood
  • 58,414
  • 16
  • 114
  • 157
gdoron
  • 147,333
  • 58
  • 291
  • 367
  • Thanks, i have try it and it works, but with alert(this).val(); Now i have problem with my button css class, as you see, there is two class in button tag – Mafaik Jun 20 '12 at 07:24
  • I have modified my class to: class="btn btn-primary xyz" Thanks for you, it is really helpful Mafaik – Mafaik Jun 20 '12 at 07:27
  • @gdoron you got it innit :P ++ from `stack overflow` +1 from `me` bruv ++1 :P – Tats_innit Jun 20 '12 at 07:31
  • 2
    Looks good to me :) Maybe you can just add one sentence regarding plain DOM methods so we can use it as canonical answer for that case (might have to adjust the question a bit, but I'm writing from my phone). No need to make it community wiki, you deserve the rep :) – Felix Kling Jun 20 '12 at 08:15
  • Although changing id to class is a better idea, you can select multiple ids in a pinch, see below. – Andrew Feb 09 '17 at 17:22
  • @gdoron, any guides / demos / 101s / tutorials on correct usage? Here's the [5 lines or so where I'm using it now](https://i.imgur.com/Sr5lNxu.png) (via imgur). The question I posted to above has the same problem and all answers relied on custom generating `ID` and inserting it via `HtmlAttributes` - if you have a better method, that question might need some updating. Thanks. – KyleMit Nov 29 '17 at 13:12
  • @KyleMit that's Razor, you are creating an element with the same id in a loop. You can override it with an id. Google it. – gdoron Dec 01 '17 at 08:29
  • @gdoron,can't argue with your contribution here, but "google it" isn't exactly the best SO comment - as future visitors will arrive via google in the first place. Plus, I entirely agree, as that's the exact solution I posted in my original comment ([Html.RadioButton of asp.net MVC generates id and name same](https://stackoverflow.com/a/9291998/1366033)) - it's just wonky and not what you'd expect considering radio buttons are *necessarily* produced in groups and razor instantiates the ID for you, so it will be broken by default. – KyleMit Dec 01 '17 at 15:26
6

ID means "Identifier" and is valid only once per document. Since your HTML is wrong at this point, some browsers pick the first, some the last occuring element with that ID.

Change ids for names would be a good step.

Then use $('button[name="xyz"]').click(function(){

campino2k
  • 1,618
  • 1
  • 14
  • 25
  • In fact, if you just use $('button[id="xyz"]'), it will work for all buttons with that id (like the original question wanted). Tested in Chrome. – Tony Wickham Aug 01 '13 at 05:53
1

From my experience, if you use $('button#xyz') selector instead it will work. That's a hack, but it's still invalid HTML.

Michel Hua
  • 1,614
  • 2
  • 23
  • 44
1

Although changing the id's to a class is better, you can get all the elements with the same id using the attribute equals selector:

$('[id="xyz"]')

Or this to get only buttons with id xyz:

$('button[id="xyz"]')

Or divs with id xyz:

$('div[id="xyz"]')

etc.

Alternatively you could use the "Attribute Contains Selector" to get all elements with ids that contain "xyz":

$('[id*="xyz"]')

Of course, this means all elements with id that partially contain "xyz" will get selected by this.

Andrew
  • 18,680
  • 13
  • 103
  • 118
  • 1
    Actually last time I checked, you can even use `$('[id="xyz"]')` and it will work. But yet, it's invalid HTML and should be fixed regardless of undocumented hacks. – gdoron Feb 10 '17 at 08:26
  • Perhaps $('[id="xyz"]') is undocumented (nice by the way), but the attribute contains selector is documented, see above :P. – Andrew Feb 10 '17 at 13:52
1

this also worked if you have multiple element with same id.

 $("button#xyz").click(function(){
  var xyz = $(this).val();
  alert(xyz);
 });

you can check HERE

jagad89
  • 2,603
  • 1
  • 24
  • 30
1

If you have same id in a container you can use on() to access each element for every event

$("#containers").on("click","#xyz",function(){
  alert($(this).val())
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="containers">

<button id="xyz" type="button" class="btn btn-primary" value="1">XYZ1</button>
<button id="xyz" type="button" class="btn btn-primary" value="2">XYZ2</button>
<button id="xyz" type="button" class="btn btn-primary" value="3">XYZ3</button>

</div>

and info about on() is here

Shojaeddin
  • 1,851
  • 1
  • 18
  • 16
0

You can't have the same id because id is unique in page HTML. Change it to class or other attribute name.

$('attributename').click(function(){ alert($(this).attr(attributename))});
JJJ
  • 32,902
  • 20
  • 89
  • 102
aymen
  • 11
  • 2