Why does the jQuery .index () method only work for the first item in the collection when a selector is specified?


I am trying to build up a table by adding values from textbox fields in the tfoot of the same table. The eventual goal is to be able to then inline edit previously added rows while still leaving the capability to add more rows.

I have the following markup:

            <th>Source Port</th>
            <th>Destination Port</th>
                <input type="text" data-function="service" value="foo" />
                <input type="text" data-function="protocol" value="bar" />
                <input type="text" data-function="sourcePort" value="baz" />
                <input type="text" data-function="destPort" value="fob" />
                <button id="addBtn" type="button">Add</button>

The below script stores all of the input[type=text] elements in the tfoot in an inputs variable. From there I am trying to use .index() to identify and then retrieve the value of each textbox:

$(document).ready(function () {
    $('#addBtn').click(function (e) {
        var inputs = $(this).closest('tfoot').find('input[type=text]');

        var serviceIndex = inputs.index('[data-function="service"]');

        // the remaining indexes all return -1

        var protocolIndex = inputs.index('[data-function="protocol"]');

        var sourcePortIndex = inputs.index('[data-function="sourcePort"]');

        var destPortIndex = inputs.index('[data-function="destPort"]');

Unfortunately the selector data-function="X" selector only works for service. All of the other selectors return -1 indicating that a value was not found. The above code is from this jsFiddle which illustrates the problem. I am not wedded to using index, but cannot use the element's id as I need a more general solution.

Why does the jQuery .index() method only work for the first element in the collection, when a selector is specified?

From the docs:

If .index() is called on a collection of elements and a DOM element or jQuery object is passed in, .index() returns an integer indicating the position of the passed element relative to the original collection.

So this should work:


Demo: http://jsfiddle.net/Dfxy9/2/