Mikko Ohtamaa Mikko Ohtamaa - 2 months ago 20
jQuery Question

jQuery: find() children until a certain threshold element is encountered

I have a nested table structure like

<table>

<td id="first">

<div class="wrapper">
<input name=1>
</div>

<input name=2>

<table>

<td id="second">

<input name=3>


I have jQuery selection
$("#first")
. I'd like to traverse and
find()
all children
<input>s
within this
<td>
context, but not to descent into the nested
<table>
s.

So I need a jQuery trick which


  • Will
    find()
    all children elements of a certain element

  • Will descent n levels down in DOM tree

  • But will stop descending if certain a element (
    <table>
    ) is encountered, so that the selector doesn't select inputs of a nested tables (which will be handled separately)

  • There could be any number of nested
    <table>
    levels, so the solution should work no matter how many parent
    <table>
    or children
    <table>
    are encountered within the scope of $("#first")
    <td>
    or any other
    <td>



I checked other jQuery find until questions. They have answers, but seems like they do not fill the last criteria

Answer

I had a similar issue in this other question. I ended up finally figuring out a plugin on my own after going back and forth with some people trying to think of a find selector.

USAGE : ExclusiveInputs = $('#first').findExclude('input','table');

// Find-like method which masks any descendant
// branches matching the Mask argument.
$.fn.findExclude = function( Selector, Mask, result){

    // Default result to an empty jQuery object if not provided
    var result = typeof result !== 'undefined' ?
                result :
                new jQuery();

    // Iterate through all children, except those match Mask
    this.children().each(function(){

        var thisObject = jQuery( this );
        if( thisObject.is( Selector ) ) 
            result.push( this );

        // Recursively seek children without Mask
        if( !thisObject.is( Mask ) )
            thisObject.findExclude( Selector, Mask, result );
    });

    return result;
}

(Condensed Version):

$.fn.findExclude = function( selector, mask, result )
{
    var result = typeof result !== 'undefined' ? result : new jQuery();
    this.children().each( function(){
        var thisObject = jQuery( this );
        if( thisObject.is( selector ) ) 
            result.push( this );
        if( !thisObject.is( mask ) )
            thisObject.findExclude( selector, mask, result );
    });
    return result;
}