4

I'm trying to write a jquery selector that will select objects that have the same value for two of their attributes.

Something like this:

$('div[attr1=attr2]')

Given:

<div attr1="foo" attr2="bar">A</div>
<div attr1="bar" attr2="bar">B</div>
<div attr1="foo" attr2="bar">C</div>
<div attr1="foo" attr2="foo">D</div>

I want it to return links to the B and D divs.

Any thoughts?

5 Answers 5

7

You can do this with custom selectors with arguments.

$('div:attrEqual(attr1 attr2)')

You define the custom selector like this:

$.expr[':'].attrEqual = function(obj, index, meta, stack) {
  var attrs = meta[3].split(" ");
  return $(obj).attr(attrs[1]) == $(obj).attr(attrs[0]);
};

For performance, add [attr1][attr2] to the selector so that the native DOM filters out nodes that don't have both attributes.

Sign up to request clarification or add additional context in comments.

4 Comments

I think this is exactly what he wanted.
Very sexy. Im not sure if i fully get it: Is this gonna work regardless of the name of the attr?
hm, odd, meo is right, doesn't seem to work, or are we just using it wrong?
the equalAttr name is the culprit. Sorry, did this off the top of my head. Rename equalAttr to attrEqual and it works. Answer edited to reflect that. Also, embedded quotes are not needed around the attribute names in the selector.
5

I think the attribute selector only allows you to compare with a constant value. But you can use the .filter() function to do the comparison:

$('div[attr1][attr2]').filter(function(index) {
  return $(this).attr('attr1') == $(this).attr('attr2');
})

1 Comment

you need to remove the leading $(' in your example in order to make it work.
1

Something like this would do the trick (The Fiddle):

function GetWithSameAttributes (parID)
{
    var output = new Array();

    $('#'+parID).children().each(function ()
    {
        if ($(this).is('[attr1="'+$(this).attr('attr2')+'"]'))
            output.push($(this).html());
    });
   return output;
}

$(function ()
{
    for (val in GetWithSameAttributes('Items'))
        document.writeln(val + ' has the same attributes<BR/>');
});

with the html something like:

<div id="Items">
    <div attr1="foo" attr2="bar">A</div>
    <div attr1="bar" attr2="bar">B</div>
    <div attr1="foo" attr2="bar">C</div>
    <div attr1="foo" attr2="foo">D</div>
</div>

Comments

1

If i get you right, you want to know if any attribute has the same value, regardless of its name. You could do it like this:

http://jsfiddle.net/zuwZh/2/

$("div").filter(function(){
var attributes = this.attributes,
    i = attributes.length,
    attrValues = [],
    $that = $(this);
    if(i !== 1) {
     while( i-- ) {
        var attr = attributes[i];
        attrValues.push(attr.value);
     }
    attrValues = attrValues.sort();
    if(attrValues[0] === attrValues[1]) {
        return $that; //only checks between two attributes, but you could extend that
    }
})

Comments

0

use a double equals sign (==) to check for equality in an statement. single equals(=) is for assignment. So if($('div[attr1] == div[attr2]') { do something });

2 Comments

The attribute equals selector in jQuery uses only one equals sign. See api.jquery.com/attribute-equals-selector
yes, the selector uses one equals sign, but the question seems to indicate that it is looking for equality checking between the values of multiple attributes. Maybe I am misreading the documentation, but it appears the single equals is used to associate the attribute with its value, not equality checking between two values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.