jQuery currently has .next(filter)
and .nextAll(filter)
but I need something that fits in the middle of these - effectively, a .nextWhile(filter)
that repeatedly does next until the filter is no longer true, then stops (rather than continuing to the end).
To demonstrate this, the following is some simplified HTML - (in reality, it is dynamically generated, random order/data, more columns, proper class names, and so on).
<table>
<thead>
<tr>
<th>...</th>
</tr>
</thead>
<tbody>
<tr class="x"><td>a <button>Show/Hide</button></td></tr>
<tr class="x y"><td>a1</td></tr>
<tr class="x y"><td>a2</td></tr>
<tr class="z"><td>b</td></tr>
<tr class="z"><td>c</td></tr>
<tr class="x"><td>d <button>Show/Hide</button></td></tr>
<tr class="x y"><td>d1</td></tr>
<tr class="x y"><td>d2</td></tr>
<tr class="x y"><td>d3</td></tr>
<tr class="z"><td>e</td></tr>
<tr class="x"><td>f</td></tr>
<tr class="x"><td>g <button>Show/Hide</button></td></tr>
<tr class="x y"><td>g1</td></tr>
<tr class="x y"><td>g2</td></tr>
</tbody>
</table>
And against this some JavaScript is run:
<script type="text/javascript">
var $j = jQuery.noConflict();
$j().ready(init);
function init()
{
$j('tr.y').hide();
$j('tr.x button').click( toggleRelated );
}
function toggleRelated()
{
// Only toggles one row
// $j(this).parents('tr').next('.y').toggle();
// Toggles unrelated ones also
$j(this).parents('tr').nextAll('.y').toggle();
// Not currently a jQuery construct
// $j(this).parents('tr').nextWhile('.y').toggle();
}
</script>
Is there an easy way to implement this nextWhile
construct?
Ideally this needs to be achieved without modifying the current HTML.
-
UPDATE: Gave up on the recursion idea and decided to count and slice (see last example).
Initial Attempt:
This code is buggy - it only returns the last two items, so doesn't work for 3+ items.jQuery.fn.nextWhile = function(f) { if( this.next(f).html() ) { return this.next(f).nextWhile(f).andSelf(); } else { return this; } };
Current Version:
jQuery.fn.nextWhile = function(f) { var Next = this.next(f); var Pos = 0; while( Next.length > 0 ) { Pos++; Next = Next.next(f); } return this.nextAll(f).slice(0,Pos); }
This appears to work fine, but I'm not sure if there are any performance penalties to selecting everything and then slicing only a handful from it?
Matthew Crumley : what about just checking this.next(f).length > 0?Peter Boughton : Yes, that makes much more sense; I want to kick myself.Peter Boughton : Wait, this is only returning the last two items - so doesn't work if 3 or more itemsgrammar31 : If performance degrades try tweaking the selector to do the slicing for you: this.nextAll(f + ':lt(' + Pos + ')')
0 comments:
Post a Comment