ollie314
ollie314

Reputation: 490

Selecting first child based on attributes

I wanna be able to select a specific set of child in which an attribute is defined.

But how to select childs which are first child of the root selector that having the attribute data-role

first-of-type selector doesn't work due to the type of the element.

Here we have a sample of the DOM.

<body>
    <div data-role="ca:panel" title="foo">
        <div data-role="ca:vbox" width="100%">
            <div data-role="ca:form">
                <div data-role="ca:formitem">
                    <div data-role="ca:hbox">
                        <input data-role="ca:textinput">
                        <div data-role="ca:menu"></div>
                    </div>
                </div>
                <div data-role="ca:formitem">
                    <input data-role="ca:passwordinput">
                </div>
                <div data-role="ca:formitem">
                    <select data-role="ca:combobox">
                        <option>[...]</option>
                    </select>
                </div>
            </div>
            <table>
                <tbody>
                    <tr>
                        <td>
                            <span data-role="ca:label"></span>
                        </td>
                        <td>
                            <button data-role="ca:button"></button>
                        </td>
                        <td>
                            <button data-role="ca:button"></button>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

</body>

My filter should select only

It should work in any case, meanings, it shouldn't be linked to a specific structure of the dom and must use data-role as 'selector'.

I'm not a relevant jQuery developer. I tried some selector such as $('[data-role]:first-of-type'); but it doesn't work.

Do you have an idea to select the right set of child.

Note: Finding the first parent is not a concern.

Upvotes: 2

Views: 156

Answers (3)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93551

It is possible to do this generically using a filter, so long as you have a start node:

JSFilter: http://jsfiddle.net/TrueBlueAussie/2uppww9s/5/

var root = $('[data-role="ca:vbox"]');
var matches = root.find('[data-role]').filter(function(){
    return $(this).parentsUntil(root, '[data-role]').length == 0;
});
alert(matches.length);

Upvotes: 1

SpYk3HH
SpYk3HH

Reputation: 22570

If you want first of all overall specifications, then you can simply use selector on all three tag types and filter them as so:

$('div, span, button').filter(function(i){
    if (this.tagName == 'DIV' && $(this).data('role') == 'ca:form') return true;
    if (this.tagName == 'SPAN' && $(this).data('role') == 'ca:label') return true;
    if (this.tagName == 'BUTTON' && $(this).data('role') == 'ca:button') return true;
}).first();

Using .first grabs the first of them.

Also, filter can be used in a million ways to get what you want and sounds like it may get you to what you need. Just set what you're filtering for in an if/for/switch statement and return true on items that match.

jsFiddle


However, if you wanted first of each you could do something like:

$('div[data-role="ca:form"]:first, span[data-role="ca:label"]:first, button[data-role="ca:button"]:first')

If variable driven in someway, just use string concatenation.

jsFiddle

Upvotes: 0

Ole Haugset
Ole Haugset

Reputation: 3797

You can use the :first pseudonym to select the first occurance of a element like for example:

var elm = $('*[data-role="ca:form"]:first');

this will select * any type of DOM-element, with the data-role that matches "ca:form"

Since you want to return two buttons with the same data-role, we cant use ":first" for that. You would have to get the first child of a that matches in that case

var elm = $('td').children('button[data-role="ca:button"]:first');

This will look through the child elements of all TD-tags and find the first button with data-role matching "ca:button"

Upvotes: 0

Related Questions