Robert McAteer
Robert McAteer

Reputation: 61

Deal with multiple ID's in document

I have a problem dealing with duplicate ID's. I'm also aware it's very bad practise to have elements with the same ID but in this case, I'll end up having to change a massive part of the application to change the ID's so they can be unique.

I am having a problem toggling classes on an element in jQuery. My structure is below:

<ul>
<li id="wl-7050"> <!-- This acts as a main data group holder for the below li elements -->
    <span></span>
    <div id="wlHeader-7050"></div>
    <div id="wlBody-7050">
        <ul>
            <li id="wl-7050"> <!-- This is the single element version of the data group header as above -->
                <div id="wlHeader-7050"></div>
            </li>
            <li id="wl-7051"></li>
            <li id="wl-7052"></li>
            <li id="wl-7053"></li>              
        </ul>
    </div>
</li>
</ul>

What I'm needing is a function where if I click the first instance of ID wl-7050, the child elements receive a new class. Whereas, if I select the second (single) element with ID of wl-7050 then only that one element has the new classes added to it.

I've tried using jQuery along with it's :first & :eq(0) attributes but still no luck unfortunately.

I do have classes assigned to each li element and it's child elements but whenever I run $('#wl-7050:eq(0)'), it returns both and the parent wl-7050 element get's used also.

I am flexible with JavaScript and jQuery answers.

Upvotes: 0

Views: 256

Answers (4)

ajm
ajm

Reputation: 20105

I've been there before: I've had to deal with applications that do weird things, where changing them to be "correct" causes more grief than just dealing with it and moving on. You know duplicate IDs are bad, I know duplicate IDs are bad; let's sort the problem. (Yes, they're bad. Yes, they shouldn't be there. Unfortunately, there they are.)

You can treat IDs just like any other attribute on an element: they're attributes, albeit special ones. Code like this will work to select all elements with the same ID: $('[id=wl-7050]').

Now, we need to bind a click event to them. We'll do the same thing as we always do:

var lis = $('[id=wl-7050]').click(function(e){
    console.log(this);
});

Here's the trick, and it would happen even if these elements all had different IDs: when you're clicking in a child LI, that click event will bubble up to the parent. We'll need to shut off event propagation so we don't trigger our click event twice:

var lis = $('[id=wl-7050]').click(function(e){
    e.stopPropagation();
    console.log(this);
});

Now we're in business and can work to figure out which type of LI we're working with: top-level or child.

var lis = $('[id=wl-7050]').click(function(e){
    e.stopPropagation();
    if ($(this).children('li').length > 0) {
        // Top-level LI
    }
    else {
        // Child-level LI
    }
});

That should get you where you need to be. Let's all agree to never speak of those duplicate IDs again.

Upvotes: 1

abgita
abgita

Reputation: 46

If you can't change the IDs, you could try adding a different class name to both elements:

<ul>
<li id="wl-7050" class="wl-7050-main">
<span></span>
<div id="wlHeader-7050"></div>
<div id="wlBody-7050">
    <ul>
        <li id="wl-7050" class="wl-7050-single">
            <div id="wlHeader-7050"></div>
        </li>
        <li id="wl-7051"></li>
        <li id="wl-7052"></li>
        <li id="wl-7053"></li>              
    </ul>
</div>
</li>
</ul>

Then you query with:

$("#wl-7050.wl-7050-main");
$("#wl-7050.wl-7050-single");

Upvotes: 1

user9757842
user9757842

Reputation:

The id attribute specifies a unique id for an HTML element (the value must be unique within the HTML document).

You can't have two wl-7050. Use classes. Then to work on "add new class on click" it's just hard code. If you need a help I can edit my answer. But is just coding. Html IDs is a concept

Upvotes: 2

Sinan Samet
Sinan Samet

Reputation: 6742

You don't need to add an id to each li that would make it overly complicated. Just use classes inside your items and call them this way:

$("#group li").on("click", function(){
	alert($(this).data("id"));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="wl-7050"> <!-- This acts as a main data group holder for the below li elements -->
    <span></span>
    <div id="header"></div>
    <div id="body">
        <ul id="group">
            <li data-id="1"> <!-- This is the single element version of the data group header as above -->
                <div class="wlHeader"></div>
            </li>    
            <li data-id="2"> <!-- This is the single element version of the data group header as above -->
                <div class="wlHeader"></div>
            </li>    
            <li data-id="3"> <!-- This is the single element version of the data group header as above -->
                <div class="wlHeader"></div>
            </li>          
        </ul>
    </div>
</li>
</ul>

Upvotes: 0

Related Questions