Search code examples
jqueryjquery-selectors

jquery .children() selector: form in a table


I have a simple html form:

<form action="/api/userattributes" method=get>
<select name=action>
<option>read_by_user</option>
<option>set</option>
<option>delete</option>
</select>
Attrib Name: <input name=name type=text size=20 value="">
Attrib Value: <input name=value type=text size=50 value="">
<br />
<input type=submit name="Go!">
</form>

And a simple jquery function that wants to touch some of the input fields in the form before they get submitted:

$(function()
{
    $("form").submit(function()
    {
        $(this).children(':input[value=""]').each(
            function() {
                $(this).attr("disabled", "disabled");
        });
        return true; // ensure form still submits
    });
});

That works fine.

But if I format the form with a table, my function no longer does anything.

Well, I thought, maybe the problem is that the children of the form are table elements (though that seems very weird), so I tried .find() instead of .children(), which again works with the vanilla version but not with the table version.

How do I find the form fields if my form is in a table?


Solution

  • Can you post your table code, as I made a guess at some table layout you would have used and had a working example pretty quickly. Embedded example below. jsFiddle can be found here.

    $(function()
    {
        $("form").submit(function()
        {
            $(this).find('input[value=""]').each(
                function() {
                    $(this).attr("disabled", "disabled");
            });
            return true; // ensure form still submits
        });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <form action="/api/userattributes" method="get">        
        <select name="action">
            <option>read_by_user</option>
            <option>set</option>
            <option>delete</option>
        </select>
        <table>
            <tr>
                <td>Attrib Name:</td><td><input name="name" type="text" size="20" value="" /></td>
                <td>Attrib Value:</td><td><input name="value" type="text" size="50" value=""></td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <input type="submit" name="Go!" />
                </td>
            </tr>
        </table>
    </form>

    Note I found two errors:

    1. Your selector was ':input[value=""]' and I changed that to 'input[value=""]'
    2. Need to use find rather than children as you suspected:

    Given a jQuery object that represents a set of DOM elements, the .children() method allows us to search through the immediate children of these elements in the DOM tree

    Source: http://api.jquery.com/children/

    Edit:

    It sounds like you discovered your own solution, and I thought I'd better include it here for reference.

    You were using:

    <table>
      <form>
        <tr>
           <td>
             <input>
           </td>
        </tr>
      </form>
    </table>
    

    Whereas you should have switched the <form> and <table> around (as you did) so that the <table> was nested inside the form.

    As you discovered, you can't have elements freely inside a <table> (everything must be in rows and columns). As a result, while it appears as though the rows and columns are sitting inside the form, it turns out they aren't actually nested inside it at all, and so aren't within the descendants that the find method searches.