How do I filter for a "tagged" subset of rows in an HTML table without iteration?
I have a CGI script that generates an HTML table with an arbitrarily large number of rows, in an arbitrary order.
Each row is a member of one or more subsets, and there are 26 subsets total (26 representing a small relative constant).
While I am generating the page, I know which subsets each row belongs to, and can tag them in any way necessary.
I then wish to provide 26 buttons on the page with which the user can press any one of them to filter the table to that subset of rows. The order in which the rows appear is significant relative to each other, but no information is lost by hiding rows that do not belong to the subset the user desires to view.
The first priority is that the computations for the filtering are done client-side, not server-side, and the client does not re-request the page, as it is significant in size and the server is very busy doing other things. (read as: Javascript, r开发者_如何转开发ight?) The page is not requested very often, but many filter operations are normally requested for each page request.
The second priority is that the client-side filtering is done as efficiently as possible. The dataset is very large.
The third priority is the widest possible browser interoperability.
I am not a web programmer by any stretch, if you can't already tell.
I originally tried to do this by representing each tag as a CSS class, assigning multiple classes to each row as necessary, and then using JavaScript to modify the CSS definitions, but it started to give me a headache. If this works, I can't quite figure it out.
CSS way, check it out - JSFiddle
And maybe someone could do something about ie6-7, if that matters.
<!DOCTYPE html>
<html>
<body>
<style>
#table tr { display: none }
#table.all tr { display: table-row }
#table.bar tr.bar { display: table-row }
#table.foo tr.foo { display: table-row }
</style>
<input type="button" value="Foo" onclick="filter('foo')">
<input type="button" value="Bar" onclick="filter('bar')">
<table id="table" class="all">
<tr class="foo"><td>1</td></tr>
<tr class="bar"><td>2</td></tr>
<tr class="foo bar"><td>3</td></tr>
</table>
<script type="text/javascript">
var table = document.getElementById('table')
function filter (cat) {
table.className = cat
}
</script>
</body>
</html>
Use jQuery
. Then use the .show()
and .hide()
methods.
HTML:
<tr class="category1">
...
</tr>
<div id="toggleButtons">
<a href="#" class="category1">Hide Category 1</a>
</div>
JavaScript:
$(function(){
$("#toggleButtons a").click(function(){
$("tr." + $(this).attr("class")).hide();
}, function(){
$("tr." + $(this).attr("class")).show();
});
});
I can't really test it on larger data sets, but it shouldn't be too dificult to work around any issue, if it arrived (like chunking the data set in some way etc.).
I doubt that there is any real performance issue here - if your browser can show them, but that's just a guess. You should think about paginating your data anyway, if it's that large. Or allow filtering to poll the server for more, if user requests it. Showing the user a big wall of text is rarely a good usability decision.
You will have to test that on browsers, but I don't see any browser problem.
With that said, I hope the below can serve you as an example (that can be played with on this JSFiddle ). It's not terribly efficient, but should give you an idea. Additionally - match
part should probably be made better to avoid false positives etc.
<html>
<body>
<table id="table" style="width: 200px; text-align: center;">
<tr style="border: 1px gray dashed;" class="1"><td>1</td></tr>
<tr style="border: 1px gray dashed;" class="2 4"><td>2 4</td></tr>
<tr style="border: 1px gray dashed;" class="3"><td>3</td></tr>
<tr style="border: 1px gray dashed;" class="4 5"><td>4 5</td></tr>
<tr style="border: 1px gray dashed;" class="5"><td>5</td></tr>
<tr style="border: 1px gray dashed;" class="3"><td>3</td></tr>
<tr style="border: 1px gray dashed;" class="4"><td>4</td></tr>
<tr style="border: 1px gray dashed;" class="5 1"><td>5 1</td></tr>
</table>
<button onClick="show('1')">1</button>
<button onClick="show('2')">2</button>
<button onClick="show('3')">3</button>
<button onClick="show('4')">4</button>
<button onClick="show('5')">5</button>
<button onClick="reset()">Reset</button>
<script>
var table = document.getElementById( 'table' );
function show( className )
{
reset();
for( var i = 0, l = table.rows.length; i < l; i++ )
{
var row = table.rows[i];
if( !row.className.match( className ) )
{
row.style.visibility = 'hidden';
}
}
}
function reset()
{
for( var i = 0, l = table.rows.length; i < l; i++ )
{
var row = table.rows[i];
row.style.visibility = 'visible';
}
}
</script>
</body>
</html>
精彩评论