Reputation: 92691
I have a typical table,
7 columns, (paginated to 100 rows per time).
What I want to do is have a <select multiple="multiple">
and have it list all the columns based off the name is the respective <th></th>
, I then want to hook into the select onchange event, when a change occurs hide all columns that are not selected, for each column hidden decrease the colspan of the <tfoot>
by 1.
The table structure is:
<table>
<thead>
<tr>
<th>first</th>
<th>second</th>
<th>third</th>
<th>fourth</th>
<th>fifth</th>
<th>sixth</th>
<th>seventh</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="7"></td>
</tr>
</tfoot>
</table>
and I suspect the ending select will look like:
<select multiple="multiple">
<option value="1" selected="selected">first</option>
<option value="2" selected="selected">second</option>
<option value="3" selected="selected">third</option>
<option value="4" selected="selected">fourth</option>
<option value="5" selected="selected">fifth</option>
<option value="6" selected="selected">sixth</option>
<option value="7" selected="selected">seventh</option>
</select>
Upvotes: 2
Views: 6156
Reputation: 31270
Take care of edge conditions (e.g. unselecting all options)
$(document).ready(function(){
$(".table-column-selector").change(function(){
var selectedCols = $(this).val();
var cols = $("table.tableClass thead th").length;
var footer = $("table.tableClass tfoot tr td");
footer.attr("colspan", selectedCols.length);
for (col = cols - 1 ; col >= 0 ; col--) {
var columns = $("table.tableClass tbody tr td:nth-child(" + (col + 1) + ")");
var headers = $("table.tableClass thead tr th:nth-child(" + (col + 1) + ")");
if ($.inArray( col + 1 + "", selectedCols ) != -1) {
columns.show();
headers.show();
}
else {
columns.hide();
headers.hide();
}
}
})
});
Upvotes: 1
Reputation: 27415
Here's how I'd do this, http://jsfiddle.net/pxfunc/mFmjb/2/
jQuery:
// setup re-usable variables
var $myGrid = $('#myGrid'),
$colFilter = $('#columnFilter'),
optionElementTemplate = "<option value=\"{0}\">{0}</option>";
// iterate the <th> tags to build the multi-select box
$('th', $myGrid).each(function() {
// create a jquery object to append from the optionElementTemplate and the <th> text
$colFilter.append($(optionElementTemplate.replace(/\{0\}/g, $(this).text())));
});
$colFilter.change(function() {
// store count for footer
var count = 0;
// show all columns
resetTable();
// iterate over the select options for selected values
$('option', this).each(function() {
if(!$(this).attr("selected")) {
count++;
hideColumn($(this).index());
}
});
// adjust the colspan
adjustFooter($('option', this).length - count);
});
function resetTable() {
$('#myGrid td, #myGrid th').show();
$('#myGrid tfoot td').attr("colspan", $('#columnFilter option').length);
}
function hideColumn(index) {
$('#myGrid thead th:eq(' + index + ')').hide();
$('#myGrid tbody td:eq(' + index + ')').hide();
}
function adjustFooter(count) {
$('#myGrid tfoot td').attr("colspan", count);
}
Probably some fine tuning before putting this in production, but the functionality is there.
Upvotes: 0
Reputation: 48485
Here's a working example: JSFiddle link
And here's a summary of the code on how to do it:
<table class="editable_table">
<thead>
<tr>
<th>first</th>
<th>second</th>
<th>third</th>
<th>fourth</th>
<th>fifth</th>
<th>sixth</th>
<th>seventh</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="footer" colspan="7">This is the footer</td>
</tr>
</tfoot>
</table>
<select multiple="multiple">
<option value="1" selected="selected">first</option>
<option value="2" selected="selected">second</option>
<option value="3" selected="selected">third</option>
<option value="4" selected="selected">fourth</option>
<option value="5" selected="selected">fifth</option>
<option value="6" selected="selected">sixth</option>
<option value="7" selected="selected">seventh</option>
</select>
And the javascript:
function hideCol($table, myIndex){
$table.find("tr").each(function(){
$(this).find("th:eq("+myIndex+"), td:eq("+myIndex+")").not('.footer').hide();
});
}
function showCol($table, myIndex){
$table.find("tr").each(function(){
$(this).find("th:eq("+myIndex+"), td:eq("+myIndex+")").not('.footer').show();
});
}
$("select").change(function(){
var $table = $(".editable_table"),
cols = $(this).val();
for (var i = 1; i <= $table.find("th").length; i++){
if (cols.indexOf(i+'') === -1) {
hideCol($table, i-1);
} else {
showCol($table, i-1);
}
}
$table.find("tfoot td").attr('colspan', cols.length);
});
Since your question was rather vague, I assume this is what you wanted. In any case, it should do the trick!
PS - might not be the most efficient way of doing it - but consider improving the efficiency an exercise for the reader, as they say.
Upvotes: 3