I'm using Bootstrap and have a striped table that can be filtered by selecting some options on a form. Javascript interprets the form inputs, and hides rows from the table that don't match the selected criteria.
However, this breaks the table striping on the table depending on which rows are hidden (gray rows next to gray rows, white rows next white rows).
I'd like to reapply the striping based on what rows are visible after filtering the results. How can I do this?
Using .remove() on the table rows is not an option, because I may need to show them again if the filter criteria changes and I'm trying to avoid using AJAX to update the table dynamically based on the filter inputs (I'd like to stick to hiding DOM elements).
Any help is appreciated! I can clarify the question if needed :)
Seems like Bootstrap 4 have a different implementation. Following #Anthony's answer, this is how it would work:
$("tr:visible").each(function (index) {
$(this).css("background-color", !!(index & 1)? "rgba(0,0,0,.05)" : "rgba(0,0,0,0)");
});
Tables are now striped by pure CSS and not by adding the "stripe" class name.
Yes, this is definitely one of the annoying parts of table striping. The better part of valor here is probably just to reapply the striping with jQuery after each update:
$("tr:not(.hidden)").each(function (index) {
$(this).toggleClass("stripe", !!(index & 1));
});
Anthony's answer did not work for me. First, it does not hide the Bootstrap table class table-striped, and second, there is not (or at least does not appear to be) a built-in class stripe for table rows.
Here's my approach, where I've filtered rows in a table with an id of "reports".
Here's a version to use if you define the class "stripe" for <tr> elements:
// un-stripe table, since bootstrap striping doesn't work for filtered rows
$("table#reports").removeClass("table-striped");
// now add stripes to alternating rows
$rows.each(function (index) {
// but first remove class that may have been added by previous changes
$(this).removeClass("stripe");
if ( index % 2 == 0) {
$(this).addClass("stripe");
}
});
If you're too lazy to define the CSS class "stripe" then here's a quick & dirty version:
// un-stripe table, since bootstrap striping doesn't work for filtered rows
$("table#reports").removeClass("table-striped");
// now add stripes to alternating rows
$rows.each(function (index) {
// but first remove color that may have been added by previous changes:
$(this).css("background-color", "inherit");
if ( index % 2 == 0) {
$(this).css("background-color", "#f9f9f9");
}
});
This is the same answer as #Jacobski's answer but will keep the hover effect of a bootstrap table-hover.
$("tr:visible").each(function (index) {
$(this).css("background-color", !!(index & 1) ? "rgba(0,0,0,.05)": "rgba(0,0,0,0)");
if (!(index & 1)) {
$(this).hover(
function () { //On hover over
$(this).css("background-color", "rgba(0,0,0,.07)");
},
function () { //On hover out
$(this).css("background-color", "rgba(0,0,0,0)");
}
)
}
});
My answer build upon what #Jacob and #yehuda suggested.
This works with bootstrap4, for a table that needs both the behavior of ".table-striped" and ".table-hover".
The hover part is handled by CSS, which makes it more efficient (I noticed a small delay due to javascript handler, when testing #yehuda's snippet).
// CSS
<style>
.table-striped tbody tr.visible-odd {
background-color: rgba(0, 0, 0, 0.05);
}
.table-striped tbody tr.visible-even {
background-color: rgba(0, 0, 0, 0.00);
}
.table-hover tbody tr.visible-even:hover {
background-color: rgba(0, 0, 0, 0.075);
}
</style>
// JS
$("tr:visible").each( function(index, obj) {
if (index % 2) {
$(this).addClass('visible-odd').removeClass('visible-even');
} else {
$(this).addClass('visible-even').removeClass('visible-odd');
}
});
For me this works fine with hidden rows and reapplies the striping as expected:
$("table#ProductTable").removeClass("table-striped");
$("table#ProductTable").addClass("table-striped");
#Jacobski's answer was great, but I had some pages with multiple tables and the header row's background would get changed on separate tables. Also my table rows that were always visible had the class "accordion-toggle" not sure if that's a bootstrap 5 thing, but that is how I targeted it! (also I don't know JavaScript so there's probably cleaner syntax to do what I did)
$("tr:visible").each(function (index) {
if ($(this).hasClass("tb-header")) {
rowIndex = 0; // need to reset the rowIndex since we are now on a new table!
} else {
if ($(this).hasClass("accordion-toggle")) {
$(this).css("background-color", !!(rowIndex & 1)? "rgba(0,0,0,0)" : "rgba(0,0,0,.05)");
rowIndex++;
}
}
});
Related
I have created a table to display JSON data via a for loop in a function. Because I have created the table this way, it has no ID/Class.
I have hidden the last three columns of the table in CSS via the following method, where (n) is the column number:
#divIdName table tr td:nth-child(n) {
display: none; }
#divIdName table th:nth-child(n) {
display: none; }
I am trying to display them via three javascript functions, using queryselector but directly coping the CSS i.e.
function showColumnN () {
if (ArrayName.indexOf("StringName")>-1) {
var colNd = document.querySelector("td:nth-child(n)");
var colNh = document.querySelector("th:nth-child(n)");
colNd.style.display = "block";
colNh.style.display = "block"; }
However only one of the hidden columns is displayed, and it contains just the three headings (one on top of another) and first row data (one on top of another) from each of the three.
Does anyone know where I'm going wrong and how I can get the full columns to display?
EDIT: I omitted that there was a conditional in the showColumnN function, to check whether a particular string is in a particular array and proceed with the column unveiling if this were so.
However only one of the hidden columns is displayed
That's because you've only selected the first td and th matching those selectors, but there are (presumably) multiple tds that match (one per row).
To keep going the way you're going (but don't, keep reading), you'd need to loop through those:
function showColumnN(n) {
showAll(document.querySelectorAll("td:nth-child(" + n + ")"));
showAll(document.querySelectorAll("th:nth-child(" + n + ")"));
}
function showAll(list) {
Array.prototype.forEach.call(list, function(element) {
element.style.display = "block";
});
}
However, I'd probably use a CSS solution instead where you could add classes to the table that would show those columns:
table.show1 tr > th:nth-child(1), table.show1 tr > td:nth-child(1) {
display: block;
}
table.show2 tr > th:nth-child(2), table.show2 tr > td:nth-child(2) {
display: block;
}
...and so on. Then showing column 2 (for instance) is:
document.querySelector("selector-for-the-table").classList.add("show2");
(Or better yet, use hideX classes that hide them, and only add those as appropriate. Then you don't have to do the block thing.)
Side note: The default display for td and th isn't block, it's table-cell.
You could do:
var table=document.getElementById("divIdName");
var rows=table.getElementsByTagName("tr");
rows.forEach((row)=>{
elems=row.getElementsByTagName("td");
for(i=0;i<4;i++){
elems[elems.length-4+i].style.display="block";
}
});
However T. J. Crowders answer is much shorter...
I need a way to only allow the user to select a row or a column (or multiple selection of entire rows, and entire columns) using handsontable.
After a bit of research and experimentation, I was able to achieve single-row highlighting without the cell and row handles.
Handsontable options:
var x = new Handsontable(element, {
...
multiSelect: false,
disableVisualSelection: ['current', 'area'],
currentRowClassName: 'currentRow'
}
CSS:
.currentRow, .highlight {
background-color: lightblue;
}
There is an way to select multiple cells, range cells and even single cell by setting: selectionMode='multiple' checkout this link: https://docs.handsontable.com/pro/3.0.0/Options.html#selectionMode
I ended up with this solution:
beforeOnCellMouseDown: function restrictSelectionToWholeRowColumn(event, coords) {
if(coords.row >= 0 && coords.col >= 0) event.stopImmediatePropagation();
}
works like charm!
I want to remove the row where the text is not found, when checkbox unchecked . If checkbox checked, then the table needs to return to its original state . What can you recommend?
function keySearch() {
$('#search').keyup(function (e) {
var search = $(this).val();
$('td').removeClass('found');
$('td').each(function (index, element) {
if ($(element).html() == search) {
$(element).addClass('found');
}
if (!$('#checkbox').prop('checked', true)) {
$(element).parent().hide();
}
else
{
$(element).parent().show();//how replace remove row?
}
});
});
}
Instead of using JavaScript to show and hide the rows, you could use it to add or remove a .checked CSS class on the parent table. Then set up the .found class so that it only hides the rows if the .checked class is present. You'll need to add the .found class to the rows instead of the cells for this to work. Just add .parent() before .addClass('found') in your code. Also, get rid of the code below your first if statement.
Here's what the CSS would look like:
table.checked > * > tr.found {
display: none;
}
Some additional code will be needed to make the checkbox work. Here's how to do it with plain ol' JavaScript (sorry, I don't use jQuery much):
document.querySelector('#checkbox').addEventListener('click', function(e) {
if(e.target.checked)
document.querySelector('#table').classList.add('checked');
else
document.querySelector('#table').classList.remove('checked');
});
(This assumes that your table has an id of 'table').
In the example below highlighting works quite well with individual rows.
In my code I can see that selection of an individual row works, however, the actual highlighting does not work.
I am using Twitter Bootstrap 3 + Datatables.
http://datatables.net/release-datatables/examples/api/select_single_row.html
Any help would be appreciated. I have followed the example as is and I think perhaps I have not configured the table properly in its init or Bootstrap does not quite like highlighting.
var oTable;
$( document ).ready(function() {
/* Add a click handler to the rows - this could be used as a callback */
$("#pTable tbody tr").click( function( e ) {
if ( $(this).hasClass('row_selected') ) {
$(this).removeClass('row_selected');
}
else {
oTable.$('tr.row_selected').removeClass('row_selected');
$(this).addClass('row_selected');
}
});
/* Add a click handler for the delete row */
$('#deletePButton').click( function() {
var anSelected = fnGetSelected( oTable );
if ( anSelected.length !== 0 ) {
oTable.fnDeleteRow( anSelected[0] );
}
});
/* Init the table */
oTable = $('#pTable').dataTable( );
/* Get the rows which are currently selected */
function fnGetSelected( oTableLocal )
{
return oTableLocal.$('tr.row_selected');
}
});
So the deleteButton which is being referenced in the code works if I select a row and delete a row.
Just the highlighting doesnt work!
Is your table id "#pTable"?
Did you try adding a debbug stop on that method, to be sure that the selector is working?
On bootstrap to hightlight a row you must use one of this classes
Class Description
.active Applies the hover color to a particular row or cell
.success Indicates a successful or positive action
.warning Indicates a warning that might need attention
.danger Indicates a dangerous or potentially negative action
Bootstrap 3 Tables
I want to convert this css behaviour into a jquery hover statement (because IE7/8 doesn't support css3). Basically when hovering over a row, I want the whole row to be highlighted except for the last cell.
#mysearchtable tr:hover td:not(:last-child)
{
background-color: #444444;
}
I've tried using this:
$("#mysearchtable tr td:not(:last-child)").hover(
function () { $(this).addClass('hoverclass') },
function () { $(this).removeClass('hoverclass') });
The problem with this is $(this) is only returning the actual cell that was hovered over. I can try and use $(this).parent() but that would give me the whole row. What I want is the highlight the whole row, except the last cell.
Would anyone know a solution?
Cheers.
Untested, but try:
$("#mysearchtable tr").hover(
function () { $(this).find("td:not(:last-child)").addClass('hoverclass') },
function () { $(this).find("td:not(:last-child)").removeClass('hoverclass') }
);
Here you can use this way. Jsfiddle demo
$("table td").not('td:last').hover(function() {
$(this).css('background-color','red');
});