3

I've stumbled upon a tricky one, that I haven't been able to find any references to (except one here on Stackoverflow, that was written quite inefficiently in Plain Old Javascript - where I would like it written in jQuery).

Problem

I need to retrieve all child-elements where the attribute-name (note: not the attribute-value) starts with a given string.

So if I have:

<a data-prefix-age="22">22</a>
<a data-prefix-weight="82">82</a>
<a href="#">meh</a>

My query would return a collection of two elements, which would be the first two with the data-prefix--prefix

Any ideas on how to write up this query?

I was going for something like:

$(document).find("[data-prefix-*]")

But of course that is not valid

Hopefully one of you has a more keen eye on how to resolve this.

Solution

(See accepted code example below)

There is apparently no direct way to query on partial attribute names. What you should do instead (this is just one possible solution) is

  1. select the smallest possible collection of elements you can
  2. iterate over them
  3. and then for each element iterate over the attributes of the element
  4. When you find a hit, add it to a collection
  5. then leave the loop and move on to the next element to be checked.

You should end up with an array containing the elements you need.

Hope it helps :)

  • Which was the solution you found? – Felix Kling Jul 26 '12 at 22:44
  • This one: http://stackoverflow.com/questions/10313312/how-to-get-all-html-attributes-which-start-with-something-the-attribute-names - I tried the jQuery example, but I don't get the right results. I also found http://stackoverflow.com/questions/9543733/jquery-attribute-name-contains which I'm testing right now. –  Jul 26 '12 at 22:47
  • here http://api.jquery.com/category/selectors/ I can't see any suitable selector for the function find(). You may just enum all attributes from each child element recursively, select matching ones and return? – Diego D Jul 26 '12 at 22:49
  • There's nothing wrong with a solution in "Plain Old Javascript" – sachleen Jul 26 '12 at 22:51
  • @sachleen: I don't disagree - I simply prefer keeping to the jQuery paradigm, whenever possible. Generally because I get less surprises, cleaner code and generally better performance :-) –  Jul 26 '12 at 22:53

2 Answers2

2

Perhaps this will do the trick -

    // retrieve all elements within the `#form_id` container
    var $formElements = $("form#form_id > *");

    var selectedElements = [];
    // iterate over each element
    $formElements.each(function(index,elem){
        // store the JavaScript "attributes" property
        var elementAttr = $(this)[0].attributes;
        // iterate over each attribute
        $(elementAttr).each(function(attIndex,attr){
            // check the "nodeName" for the data prefix
            if (attr.nodeName.search('data-.*') !== -1){
               // we have found a matching element!
               if (selectedElements.length < 2){
                 selectedElements.push(elem);
                 break;
               }else{
                 if (selectedElements.length == 2){
                   break(2);
                 }
               }
            }
        });
    });

selectedElements will now hold the first two matching elements.

jsFiddle

Community
  • 1
  • 1
Lix
  • 47,311
  • 12
  • 103
  • 131
  • if I were to run this again all elements in a
    -tag, how would that look ? can you refactor it to show that ?
    –  Jul 26 '12 at 23:01
  • 1
    So far I am able to get the elements I need so it seems this is pretty close to what I am looking for. Thanks alot! –  Jul 26 '12 at 23:15
  • 1
    A small fix to the above code, shouldn't you instead do: if (attr.nodeName.search('data-.*') !== -1) { selectedElements.push(elem); return false; } to exit the ".each" after a find and push ? –  Jul 26 '12 at 23:31
  • Indeed - that is a great point @cod! I'll edit that in as well - thanks! – Lix Jul 26 '12 at 23:36
0

You can use jquerys filter() method to have a selections elements being processed by a function. Inside that function you are free to do whatever you want to.

So start with selecting all elements inside the dom tree and filter out everything you dislike. Not especially fast, but working.

arkascha
  • 41,620
  • 7
  • 58
  • 90