HTML fragment generations incorrectly result in duplicate IDs on the page. This makes using a conventional ID selector problematic.
The best way to solve this problem is not to have it. What I mean by that is changing HTML fragment generation logic – whether it be JSPs to AngularJS – is the optimal solution, rather than working around it. Element IDs are supposed to be unique across the entire page for it to be considered valid HTML. However, it’s not always possible to do the proper solution for a variety of reasons, so this can provide a stopgap.
Assumptions / Prerequisites
- The duplicate IDs exist in a known structure (HTML fragment)
- JQuery is either currently used or can be used
Rather than writing to the console, to denote what got selected, I chose to write to the “output” divs contained within the document. The results are under the “*** Output ***” text section.
//syntax $("ancestor desiredElement")
This is an effective way when you have a known ancestor. We drill down through the ancestor to find the desired element ID. As example #2 demonstrates – the level of nesting does not matter.
Another method, in example #2, is using the next sibling selector.
//syntax $("startAtSibling ~ desiredElement")
This is a useful way when you have a known sibling. In this instance, we have a known class on a sibling that will differ in each section (fragment). Note, it does not have to be a class, it could be a sibling’s ID.
The final method, in example #2, uses a combination of selectors – the contains selector, the first selector, and the next sibling selector. The result is being able to find the desired ID with a known piece of text near it.
//syntax $("elementType:contains('Some Text'):first ~ desiredElement)
This last example is the most elaborate of them all. It uses a combination of selectors. The “contains” selector returns multiple elements matching the criteria, but for our purposes we only want one. So we use the “first” selector which returns the first instance. Even if there is only one to be returned, we still need to use it, so the sibling operator can work on one element and not an array.
While it’s best to not even have this issue (and need to work around it) – JQuery’s selectors provide what is needed to accomplish the task.