tags:

views:

49

answers:

5

For a markup like this:

<div id="set1">
 <div id="100">a div</div>
 <div id="101">another div</div>
 <div id="102">another div 2</div>
 <div id="120">same div</div>
</div>  

<div id="set2">
 <div id="105">a different div>
 <div id="101">another div</div>
 <div id="110">more divs</div>
 <div id="120">same div</div>
</div>

As you can see both #set1 and #set2 contain 2 divs with the same id (101, 120). Is it possible somehow with jQuery to find the common elements and add a class to the divs in #set1 that have the same id with divs in #set2?

In other words after the script run the above code would look like this:

<div id="set1">
 <div id="100">a div</div>
 <div id="101" class="added">another div</div>
 <div id="102">another div 2</div>
 <div id="120" class="added">same div</div>
</div>  

<div id="set2">
 <div id="105">a different div>
 <div id="101">another div</div>
 <div id="110">more divs</div>
 <div id="120">same div</div>
</div>

EDIT playing around with it i did something but i am not sure it can go anywhere. I created an array with the ids in both sets and in Firebug i can see an array with the values

 var arrEl = [];
   $('#set1 div, #set2 div').each( function(index) {
    var id = $(this).attr('id');            
    arrEl.push(id);

 //maybe somehow check the array for the values that appear twice, and add the class to the //matching divs?
   });
+2  A: 

IDs should never be duplicated within the same document, it breaks the spec and jQuery will only ever select the first occurence in the document whenever the ID selector (e.g. '#foo') is called. Furthermore, results will be inconsistent across different browsers. I would suggest using a custom attribute (or $.data) to store those reference numbers.

A custom attribute looks like this:

<div id="foo" custom="test">Hello</div>

You can get the value of custom like this:

alert($("#foo").attr("custom"));
karim79
jQuery will only return the first occurrence when nothing but id selector is used. If you do `$("#set2 #101")` or `$("#set2").find("#101")`, however, it will work as intuitively expected. And could you please elaborate on what are the implications of "breaking the spec" and what are some of the inconsistencies across browsers?
Fyodor Soikin
i would use data(). +never use numbers as ID's its not valid
meo
@Fyodor - 'Breaking the spec' = "This name must be unique in a document." (from the W3C specification). As for inconsistencies across browsers - I do not have an example of that offhand, watch this space. Duplicate IDs per document is a terrible practice. Also, IE tends to choke on numeric IDs (which also break the spec).
karim79
ok guys relax, i m just playing with it, i ll use rel actually, i am aware of the IDs thing lol
tsiger
A: 

Go through set1 in a loop and for each div, see if there is a matching one in set2:

var set2 = $("#set2");
var set1Divs = $("div", $("#set1));

for( var i = 0; i < set1Divs.size(); i++ )
{
    var div = set1Divs[i];
    var divId = div.attr( "id" );
    if ( set2.find( "#" + divId ).size() > 0 ) {
        div.addClass( "added" );
    }
}
Fyodor Soikin
i get an error on this line var divId = div.attr( "id" ); (div.attr is not a function)
tsiger
or you can use: set1Divs.each(functon(o, i){ })
meo
+1  A: 

Given your comment that you're going to use rel instead of id, this way creates arrays (using map()) of each set, storing the value of rel, and compares them.

var set1 = $('#set1').children().map(function() {
    return $(this).attr('rel');
}).get();

var set2 = $('#set2').children().map(function() {
    return $(this).attr('rel');
}).get();

for(var i in set1) {
    if(set1[i] == set2[i])
        $('#set1').children().eq(i).addClass('added')
}

EDIT:

Or perhaps better (shorter anyway), try this:

$('#set2 > div').each(function(){
    $('[rel=' + $(this).attr('rel') + ']', '#set1').addClass('added')
});
patrick dw
nice one! but you could use $('#set2 > div') as selector.
meo
Thanks. Yeah, caught that just after I posted. Even more better-er now.
patrick dw
+2  A: 

Is that really your markup? It would be invalid HTML to have elements with the same ids.

Anyway, I suppose you could loop through all divs in set1 and check if they exist in set2:

var $set2 = $('#set2');
var $duplicates = $.grep($('#set1 > div'), function(el) {
  return $set2.children('#' + el.id).length > 0;
});
$($duplicates).addClass('added');

See this in action here: http://jsfiddle.net/DDtQU/

Shiki
+1 using grep()
meo
no this is not my markup. It was a simplified example :) thanx
tsiger
A: 

even if your code is not gonna be valid, and that it is a very bad practice to have duplicate ID's and using numbers as ID's you can use this code. But don't tell anyone i wrote it :P

var campareTo = $("div#set1 > div") 
var original = $("div#set2 > div")

original.each(function(o, i){
   var tempID = $(this).attr("id")
   if (compareTo.filter("#" + tempID).length){
     compareTo.filter("#" + tempID).addClass('added')
   }
})

test it here: http://jsfiddle.net/DDtQU/1/

meo