i want the entire content of the cell displayed in the cell.
But the content first and the third cell in the first row are overflowing. How do i display the entire content without increasing the width of the table columns?
Can someone suggest a fix:
function sortTable(f,n){
var rows = $('#mytable tbody tr').get();
rows.sort(function(a, b) {
var A = getVal(a);
var B = getVal(b);
if(A < B) {
return -1*f;
}
if(A > B) {
return 1*f;
}
return 0;
});
function getVal(elm){
var v = $(elm).children('td').eq(n).text().toUpperCase();
if($.isNumeric(v)){
v = parseInt(v,10);
}
return v;
}
$.each(rows, function(index, row) {
$('#mytable').children('tbody').append(row);
});
}
var f_errorStringOfCurrentDataSet = 1;
var f_errorStringOfMatchedDataSet = 1;
var f_testCaseNameOfCurrentDataSet = 1;
var f_regexMatched = 1;
$("#errorStringOfCurrentDataSet").click(function(){
f_errorStringOfCurrentDataSet *= -1;
var n = $(this).prevAll().length;
sortTable(f_errorStringOfCurrentDataSet,n);
});
$("#errorStringOfMatchedDataSet").click(function(){
f_errorStringOfMatchedDataSet *= -1;
var n = $(this).prevAll().length;
sortTable(f_errorStringOfMatchedDataSet,n);
});
$("#testCaseNameOfCurrentDataSet").click(function(){
f_testCaseNameOfCurrentDataSet *= -1;
var n = $(this).prevAll().length;
sortTable(f_testCaseNameOfCurrentDataSet,n);
});
$("#regexMatched").click(function(){
f_regexMatched *= -1;
var n = $(this).prevAll().length;
sortTable(f_regexMatched,n);
});
table {
padding: 0;
border-collapse: collapse;
border: 1px solid #ccc;
margin-top: 20px;
table-layout: fixed;
width: 90%;
}
td {
border: 1px solid #ccc;
padding: 5px;
}
tr:nth-child(even) {
background-color: #f2f2f2
}
th, td {
overflow: hidden;
padding: 5px;
text-align: left;
}
<!DOCTYPE html>
<html>
<body>
<style>
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<h2>Summary: </h2>
<br>
<br>
<table border="1" id="mytable">
<thead>
<tr>
<th width="25%" id="testCaseNameOfCurrentDataSet">TESTCASENAME</th>
<th width="5%" id="regexMatched">RegexMatched (Yes/No)</th>
<th width="25%" id="errorStringOfCurrentDataSet">ERROR_STRING_CURRENT_DATASET</th>
<th width="25%" id="errorStringOfMatchedDataSet">ERROR_STRING_REF_DATASET</th>
<th width="5%">PICTU Detail</th>
</tr>
</thead>
<tbody>
<tr style="color: red">
<td>moviee.movieemovieemoviee.movieemovieemoviee.movieemovieemoviee.moviee</td>
<td>NO</td>
<td>ABCDE:[bbb-aa-gg 999-99] (Excellent Check) Monkey String ABCDE:[moviee 990-505] moviee to commit 3 small moviee/moviee/moviee: in file /dogg/summariz/abc/mmmm/movieemoviee/moviee/movieemoviee/moviee/movieemoviee/Small/movieemoviee/movieemoviee.1_</td>
<td>ABCDE:[abc-vd-Common 17-69] moviee moviee: moviee moviee moviee moviee moviee moviee</td>
<td><a href=http://mnbvcz01:5601/app/banana#/template/abc-DELETEDD-PICTU?embed=true&reportType=abc&_a=(filters:!(),options:(darkTheme:!f),query:(query_string:(analyze_wildcard:!t,lowercase_DELETEDD_terms:!f,query:'_id:movieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemoviee.movieemovieemoviee%20OR%20_id:17.movieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemovieemoviee.movieemovieemovieemovieemovieemovieemovieemoviee')),title:'abc%20DELETEDD%20PICTU',uiState:())&_g=(refreshInterval:(display:Off,pause:!f,value:0),time:(from:now-1y,mode:quick,to:now))>link</a></td>
</tr>
</tbody>
</table>
<script>
</script>
</body>
</html>
One solution for this is to add word-break: break-word; to td tags.
Here is a fiddle with your code: fiddle link
You can use word-break css property to solve this problem. here is the code replace your table tag with mine
<table border="1" id="mytable" style ="word-break: break-word;">
Hope this was useful to you
Related
I have combined multiple scripts where I can sort tables, filter which is shown, and search through the tables. I am hoping someone could help me with the issue that only the first search box or '2016' data search works. Ideally, I'd like the searches to all be independent of each other, and obviously, for all of them to work.
I did find a loop around with it by giving all tables/inputs/scripts individual names, but this is not ideal moving forward. All of the sorting and filtering works great, so that is not an issue. Also, if possible, I'd like for it to not display all the data, instead just have the buttons at default view.
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("filterDiv");
if (c == "all") c = "";
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "show");
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
// Add active class to the current button (highlight it)
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
this.className += " active";
});
};
function sortTableByColumn(table, column, asc = true) {
const dirModifier = asc ? 1 : -1;
const tBody = table.tBodies[0];
const rows = Array.from(tBody.querySelectorAll("tr"));
// Sort each row
const sortedRows = rows.sort((a, b) => {
const aColText = a.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();
const bColText = b.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();
return aColText > bColText ? (1 * dirModifier) : (-1 * dirModifier);
});
// Remove all existing TRs from the table
while (tBody.firstChild) {
tBody.removeChild(tBody.firstChild);
}
// Re-add the newly sorted rows
tBody.append(...sortedRows);
// Remember how the column is currently sorted
table.querySelectorAll("th").forEach(th => th.classList.remove("th-sort-asc", "th-sort-desc"));
table.querySelector(`th:nth-child(${ column + 1})`).classList.toggle("th-sort-asc", asc);
table.querySelector(`th:nth-child(${ column + 1})`).classList.toggle("th-sort-desc", !asc);
}
document.querySelectorAll(".table-sortable th").forEach(headerCell => {
headerCell.addEventListener("click", () => {
const tableElement = headerCell.parentElement.parentElement.parentElement;
const headerIndex = Array.prototype.indexOf.call(headerCell.parentElement.children, headerCell);
const currentIsAscending = headerCell.classList.contains("th-sort-asc");
sortTableByColumn(tableElement, headerIndex, !currentIsAscending);
});
});
const myFunction = () => {
const trs = document.querySelectorAll('.table-sortable tr:not(.header)')
const filter = document.querySelector('.myInput').value
const regex = new RegExp(filter, 'i')
const isFoundInTds = td => regex.test(td.innerHTML)
const isFound = childrenArr => childrenArr.some(isFoundInTds)
const setTrStyleDisplay = ({
style,
children
}) => {
style.display = isFound([
...children // <-- All columns
]) ? '' : 'none'
}
trs.forEach(setTrStyleDisplay)
}
.filterDiv {
background-color: #2196F3;
color: #ffffff;
line-height: 100px;
text-align: center;
margin: 2px;
display: none;
}
.table-sortable {
width: 100%;
}
.table-sortable th {
cursor: pointer;
width: 25%;
color: #f3f3f3;
padding: .7%;
text-transform: uppercase;
}
.table-sortable td {
text-align: center;
padding: .5%;
}
.table-sortable thead {
background-color: #0070c0;
}
.table-sortable tbody {
background-color: rgba(232, 232, 232, 1);
}
.table-sortable tr:hover {
background-color: rgba(0, 112, 192, .3);
}
.table-sortable .th-sort-asc::after {
content: "\2963";
}
.table-sortable .th-sort-desc::after {
content: "\2965";
}
.table-sortable .th-sort-asc::after,
.table-sortable .th-sort-desc::after {
margin-left: 5%;
}
.show {
display: block;
}
.container {
margin-top: 20px;
overflow: hidden;
}
/* Style the buttons */
.btn {
border: none;
outline: none;
padding: 12px 16px;
background-color: #f1f1f1;
cursor: pointer;
}
.btn:hover {
background-color: #ddd;
}
.btn.active {
background-color: #666;
color: white;
}
.myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
<h2>Filter DIV Elements</h2>
<div id="myBtnContainer">
<button class="btn active" onclick="filterSelection('all')">Show all</button>
<button class="btn" onclick="filterSelection('2016')">2016</button>
<button class="btn" onclick="filterSelection('2017')">2017</button>
</div>
<div class="container">
<div class="filterDiv 2016">
<input type="text" class="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table class="table-sortable">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Age</th>
<th>Occupation</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Dom</td>
<td>35</td>
<td>Web Developer</td>
</tr>
<tr>
<td>2</td>
<td>Rebecca</td>
<td>29</td>
<td>Teacher</td>
</tr>
<tr>
<td>3</td>
<td>John</td>
<td>30</td>
<td>Civil Engineer</td>
</tr>
<tr>
<td>4</td>
<td>Andre</td>
<td>20</td>
<td>Dentist</td>
</tr>
</tbody>
</table>
</div>
<div class="filterDiv 2017">
<input type="text" class="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table class="table-sortable">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Age</th>
<th>Occupation</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Thomas</td>
<td>89</td>
<td>Fireman</td>
</tr>
<tr>
<td>2</td>
<td>Jack</td>
<td>54</td>
<td>Professor</td>
</tr>
<tr>
<td>3</td>
<td>Bert</td>
<td>30</td>
<td>Fan Manufacturer</td>
</tr>
<tr>
<td>4</td>
<td>Julia</td>
<td>25</td>
<td>Financial Advisor</td>
</tr>
</tbody>
</table>
</div>
Delegate
document.querySelector(".container").addEventListener("input", function(e) {
const tgt = e.target;
if (tgt.matches(".myInput")) {
const parent = tgt.closest(".filterDiv");
const trs = parent.querySelectorAll('.table-sortable tr:not(.header)')
const filter = tgt.value;
I've got a table of records and I've got a text field above it which dynamically filters the records on a specific table column. I implemented it following this handy How-To https://www.w3schools.com/howto/howto_js_filter_table.asp
Now, this works as advertised, but I'm looking to modify it so that the filter looks at all columns, not just one of them. In the example from the How-To, I'd like to be able to type a name or a country and for it to return all matches. I tried to do this in the JavaScript:
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
for (j = 0; j < tr.width; j++) {
td = tr[i].getElementsByTagName("td")[j];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}}}}}
The j variable is where I had hoped to additionally loop through the columns for each i, but doing this seems to break the filtering functionality, ie. typing anything has no effect on the records displayed - all records show at all times. Can someone tell me what I'm doing wrong?
You have a couple of errors there:
1. invalid for loop:
for (j = 0; j < tr.width; j++)
There's no such thing as tr.width. Or rather it's a jQuery function, so you're getting a text of it when you type tr.width.
Thus the script breaks, since the for loop clause if invalid.
If you actually called like this tr.width() you would get the pixel width of the element so it wouldn't help you either.
What you need is the <td> count in it. Here's how you get it:
let rowTds = tr[i].getElementsByTagName("td")
for (j = 0; j < rowTds.length; j++){...}
now you can iterate through the all the <td>s in the row.
2. Hide row logic needs revision to multiple column check:
Now you also need to change the logic of the hiding because it will keep hiding a row if the the last <td> didn't match the filter string.
td = tr[i].getElementsByTagName("td")[j];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
break; // this will break the row looping on j after making the row visible.
} else {
tr[i].style.display = "none";
}
}
}
}
}
Conclusion: Full working code adjusted from the W3schools tutorial:
Link: https://www.w3schools.com/code/tryit.asp?filename=FVXZWZMELE1Q
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<style>
* {
box-sizing: border-box;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}
#myTable th, #myTable td {
text-align: left;
padding: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
background-color: #f1f1f1;
}
</style>
</head>
<body>
<h2>My Customers</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Germany</td>
</tr>
<tr>
<td>Berglunds snabbkop</td>
<td>Sweden</td>
</tr>
<tr>
<td>Island Trading</td>
<td>UK</td>
</tr>
<tr>
<td>Koniglich Essen</td>
<td>Germany</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Italy</td>
</tr>
<tr>
<td>North/South</td>
<td>UK</td>
</tr>
<tr>
<td>Paris specialites</td>
<td>France</td>
</tr>
</table>
<script>
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
let rowTds = tr[i].getElementsByTagName("td")
for (j = 0; j < rowTds.length; j++){
td = tr[i].getElementsByTagName("td")[j];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
break;
} else {
tr[i].style.display = "none";
}
}
}
}
}
</script>
</body>
</html>
I am trying to figure out how to make all 5 columns and rows searchable. At the moment it only searches via the first column (DATE). Could someone please assist me with possibly making it search all the columns and rows please? I have included the HTML, CSS and javascript to try to provide as much information as possible.
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
#myInput {
background-image: url('/css/searchicon.png'); /* Add a search icon to input */
background-position: 10px 12px; /* Position the search icon */
background-repeat: no-repeat; /* Do not repeat the icon image */
width: 100%; /* Full-width */
font-size: 16px; /* Increase font-size */
padding: 12px 20px 12px 40px; /* Add some padding */
border: 1px solid #ddd; /* Add a grey border */
margin-bottom: 12px; /* Add some space below the input */
}
#myTable {
border-collapse: collapse; /* Collapse borders */
width: 100%; /* Full-width */
border: 1px solid #ddd; /* Add a grey border */
font-size: 18px; /* Increase font-size */
}
#myTable th, #myTable td {
text-align: left; /* Left-align text */
padding: 12px; /* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #f1f1f1;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:20%;">Date</th>
<th style="width:20%;">Home</th>
<th style="width:20%;">Time</th>
<th style="width:20%;">Away</th>
<th style="width:20%;">City</th>
</tr>
<tr>
<td>08/01/2018</td>
<td>SPAIN</td>
<td>16:30 ET</td>
<td>USA</td>
<td>BARCELONA</td>
</tr>
<tr>
<td>08/02/2018</td>
<td>BOLIVIA</td>
<td>18:30 ET</td>
<td>PORTUAL</td>
<td>MADRID</td>
</tr>
<tr>
<td>08/03/2018</td>
<td>PUERTO RICO</td>
<td>18:30 ET</td>
<td>CANADA</td>
<td>CHICAGO</td>
</tr>
<tr>
<td>08/04/2018</td>
<td>MEXICO</td>
<td>19:30 ET</td>
<td>ENGLAND</td>
<td>LONDON</td>
</tr>
</table>
Using your existing code, loop through the table cells just as you loop through the table rows.
Below, I hide each row. For each row, if text in a cell matches the search term, that row is shown and the loop continues to the next row.
I'm also ignoring the table header by using tBodies to limit the search to <tr> elements that are within the first <tbody>. Alternatively, you could check that <td> elements exist in the row before searching; something like: if (tds.length) > 0.
function performSearch() {
// Declare search string
var filter = searchBox.value.toUpperCase();
// Loop through first tbody's rows
for (var rowI = 0; rowI < trs.length; rowI++) {
// define the row's cells
var tds = trs[rowI].getElementsByTagName("td");
// hide the row
trs[rowI].style.display = "none";
// loop through row cells
for (var cellI = 0; cellI < tds.length; cellI++) {
// if there's a match
if (tds[cellI].innerHTML.toUpperCase().indexOf(filter) > -1) {
// show the row
trs[rowI].style.display = "";
// skip to the next row
continue;
}
}
}
}
// declare elements
const searchBox = document.getElementById('searchBox');
const table = document.getElementById("myTable");
const trs = table.tBodies[0].getElementsByTagName("tr");
// add event listener to search box
searchBox.addEventListener('keyup', performSearch);
#searchBox {
box-sizing: border-box;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}
#myTable th,
#myTable td {
text-align: left;
padding: 12px;
}
#myTable th {
width: 20%;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
background-color: #f1f1f1;
}
<input type="text" id="searchBox" placeholder="Search for names..">
<table id="myTable">
<thead>
<tr class="header">
<th>Date</th>
<th>Home</th>
<th>Time</th>
<th>Away</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr>
<td>08/01/2018</td>
<td>SPAIN</td>
<td>16:30 ET</td>
<td>USA</td>
<td>BARCELONA</td>
</tr>
<tr>
<td>08/02/2018</td>
<td>BOLIVIA</td>
<td>18:30 ET</td>
<td>PORTUAL</td>
<td>MADRID</td>
</tr>
<tr>
<td>08/03/2018</td>
<td>PUERTO RICO</td>
<td>18:30 ET</td>
<td>CANADA</td>
<td>CHICAGO</td>
</tr>
<tr>
<td>08/04/2018</td>
<td>MEXICO</td>
<td>19:30 ET</td>
<td>ENGLAND</td>
<td>LONDON</td>
</tr>
</tbody>
</table>
100% working for unlimited columns !
<input class="form-control" type="text" id="myInput" placeholder="Search ..." onkeyup="searchTableColumns()">
<table id="myTable">
.....
.....
.....
</table
function searchTableColumns() {
// Declare variables
var input, filter, table, tr, i, j, column_length, count_td;
column_length = document.getElementById('myTable').rows[0].cells.length;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 1; i < tr.length; i++) { // except first(heading) row
count_td = 0;
for(j = 1; j < column_length-1; j++){ // except first column
td = tr[i].getElementsByTagName("td")[j];
/* ADD columns here that you want you to filter to be used on */
if (td) {
if ( td.innerHTML.toUpperCase().indexOf(filter) > -1) {
count_td++;
}
}
}
if(count_td > 0){
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
When you do tr[i].getElementsByTagName("td")[0];, you only select the date column, wich is why it only search in that one. You are going to have to loop through all the coumn and set a boolean to true if you find it at least once.
Something like that:
var found = false;
var td = tr[i].getElementsByTagName("td");
for(j = 0; j < td.length; j++) {
if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
//if found at least once it is set to true
found = true;
}
}
//only hides or shows it after checking all columns
if(found){
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
a compact version of the above code, credit to #showdev
/**
* HTML Search for any table
*
* #param element searchBox
* #param string tableBody
*/
function performSearch(searchBox,tableBody) {
let trs = $('#'+tableBody).find('tr');
// Declare search string
let filter = searchBox.value.toUpperCase();
// Loop through first tbody's rows
for (let rowI = 0; rowI < trs.length; rowI++) {
// define the row's cells
let tds = trs[rowI].getElementsByTagName("td");
// hide the row
trs[rowI].style.display = "none";
// loop through row cells
for (let cellI = 0; cellI < tds.length; cellI++) {
// if there's a match
if (tds[cellI].innerHTML.toUpperCase().indexOf(filter) > -1) {
// show the row
trs[rowI].style.display = "";
// skip to the next row
continue;
}
}
}
}
Use it like onkeyup="performSearch(this,'smsTableBody')"
I'm currently busy with a project that has an html table with games and years they are launched. I'm trying to create a button that when clicked will hide any row that wasn't launched in 2016.
So my thoughts behind this process are that I'll create a forloop to go through each row and column to find the year value and if it's 2016 leave it alone, if not, hide it.
However I'm having an issue on the looping part.
<script>
function GameSearchLoop() {
var table = document.getElementsByClassName(table);
if (table == null) {
console.log("Table Not Found");
}
else {
console.log("Table Found");
}
var rowLength = table.rows.length;
for (var z = 0; z < rowLength; z++) {
var cells = table.rows.item(z).cells;
var cellLength = cells.length;
console.log("Row Checked");
for (var x = 0; x < cellLength; x++) {
console.log("Column Checked");
}
}
//for (var r = 0, n = table.rows.length; r < n; r++) {
// console.log("Row Checked");
// for (var c = 0, m = table.rows[r].cells.length; c < m; c++) {
// alert(table.rows[r].cells[c].innerHTML);
// console.log("Column Checked");
// }
//}
}
</script>
I've got two different for loops here and neither of them seem to work.
The table is created slightly about this with the same script with the class table attached to it.
When running the code and hitting the button I do see "Table Found" in the console but after that I get a "Cannot read property 'length' of undefined at GameSearchLoop".
Thanks
getElementsByClassName returns a NodeList, a collection. You need the first of these elements:
var table = document.getElementsByClassName(table)[0];
assuming that table is in the first instance a variable containing a class-name, and that your table is the first, or only, one of these.
Or alternatively,
var rowLength = table[0].rows.length;
Better yet, give your table an ID and use getElementById.
I found it form W3schools i hope this will help
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
box-sizing: border-box;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}
#myTable th, #myTable td {
text-align: left;
padding: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
background-color: #f1f1f1;
}
</style>
</head>
<body>
<h2>I picked it from W3schools</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Year</th>
<th style="width:40%;">Country</th>
</tr>
<tr>
<td>2016</td>
<td>Germany</td>
</tr>
<tr>
<td>2017</td>
<td>Sweden</td>
</tr>
<tr>
<td>2016</td>
<td>UK</td>
</tr>
<tr>
<td>2018</td>
<td>Germany</td>
</tr>
<tr>
<td>2019</td>
<td>Canada</td>
</tr>
<tr>
<td>2010</td>
<td>Italy</td>
</tr>
<tr>
<td>2016</td>
<td>UK</td>
</tr>
<tr>
<td>2013</td>
<td>France</td>
</tr>
</table>
<script>
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
</body>
</html>
insted of
var table = document.getElementsByClassName(table);
use
var table = document.getElementsByClassName('some class in string');
I want to create a table of buttons that, when generated with x rows and y columns and user generated button captions, each button in a row is as tall as the tallest one in its row, and each button in a column is as wide as the widest one in its column.
Is there a solution to this with flexbox, or do I need to use JS?
.button1 {width:97px; height:37px;}
.button3 {height:37px;}
.button5 {width:61px;}
<table>
<tr>
<td><button class="button1">First</button></td>
<td><button>Second<br>Button</button></td>
<td><button class="button3">Third</button></td>
</tr>
<tr>
<td><button>Fourth is long</button></td>
<td><button class="button5">Fifth</button></td>
<td><button>Sixth</button></td>
</tr>
</table>
Above snippet is also on JS Fiddle.
Thank you
Before we start, quick note, make sure you include a tbody tag inside your table tag; the browser will just add it for you anyway.
Now then: You can't pull this off with CSS alone. The reason is that CSS is a two-dimensional language, not a three-dimensional one. So you can structure your HTML into columns and get all the buttons in a column matching, or you can do a table as you have, and get all the buttons in a row matching, but you can't do both.
Here's an example of making buttons within the same column have the same width (but not height) with flexbox, by reversing the default flex behavior to allow growing but not shrinking:
.button1 {width:97px; height:37px;}
.button3 {height:37px;}
.button5 {width:61px;}
td div {
display: flex;
}
td div button {
flex: 1 0 auto;
}
<table>
<tbody>
<tr>
<td><div><button class="button1">First</button></div></td>
<td><div><button>Second<br>Button</button></div></td>
<td><div><button class="button3">Third</button></div></td>
</tr>
<tr>
<td><div><button>Fourth is long</button></div></td>
<td><div><button class="button5">Fifth</button></div></td>
<td><div><button>Sixth</button></div></td>
</tr>
</tbody>
</table>
And an example of making heights in a row match, but not widths:
.button1 {
width: 97px;
height: 37px;
}
.button3 {
height: 37px;
}
.button5 {
width: 61px;
}
table {
display: flex;
}
tr {
display: flex;
}
td {
display: flex;
}
td div {
display: flex;
flex-direction: column;
}
td div button {
flex: 1 0 auto;
}
<table>
<tbody>
<tr>
<td><div><button class="button1">First</button></div></td>
<td><div><button>Second<br>Button</button></div></td>
<td><div><button class="button3">Third</button></div></td>
</tr>
<tr>
<td><div><button>Fourth is long</button></div></td>
<td><div><button class="button5">Fifth</button></div></td>
<td><div><button>Sixth</button></div></td>
</tr>
</tbody>
</table>
To get around CSS's limitations, we really need a JavaScript solution. We can query the width/height of each button in a given row/column, then set all buttons in that row/column to match that of the widest/tallest one.
The below snippet completes your request by setting both widths and heights in JavaScript, forgoing flexbox entirely. But as you can see from the CSS examples above, it's conceivable that you could use flex CSS to handle one dimension and then pull out the relevant half of the JavaScript below to handle the other dimension.
$(function() {
//for each row
$('table tr').each(function() {
var maxHeight = 0;
var tallestButton = null;
var $element;
//find the tallest button
$(this).find('td').each(function() {
$element = $(this).find('button');
var buttonHeight = $element.height();
if (buttonHeight > maxHeight) {
maxHeight = buttonHeight;
tallestButton = $element;
}
});
//then set each button in that row to the widest button's width
$(this).find('td button').each(function() {
$(this).height(tallestButton.height());
});
});
//find width of table in columns, based on number of cols in first row
var x = $('table tr:first-child td').length;
//for each column
for (var i=1; i<x+1; i++) {
var maxWidth = 0;
var widestButton = null;
var $element;
var cellInCol = $('table tr td:nth-child(' + i + ')');
$(cellInCol).each(function() {
$element = $(this).find('button');
var buttonWidth = $element.width();
if (buttonWidth > maxWidth) {
maxWidth = buttonWidth;
widestButton = $element;
}
});
$(cellInCol).find('button').each(function() {
$(this).width(widestButton.width());
});
}
});
.button1 {
width: 97px;
height: 37px;
}
.button3 {
height: 37px;
}
.button5 {
width: 61px;
}
.button7 {
height: 80px;
}
table {
border-collapse: collapse;
}
table td {
border: 1px solid gray;
padding: 5px;
text-align: center;
}
button {
white-space: no-wrap; /* fix for long captions on PC */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><button class="button1">First</button></td>
<td><button>Second<br>Button</button></td>
<td><button class="button3">3rd</button></td>
</tr>
<tr>
<td><button>Fourth is long</button></td>
<td><button class="button5">Fifth</button></td>
<td><button>Sixth (6th)</button></td>
</tr>
<tr>
<td><button>Six</button></td>
<td><button class="button7">7</button></td>
<td><button>8</button></td>
</tr>
<tr>
<td><button>Nine</button></td>
<td><button>Ten</button></td>
<td><button>Eleven</button></td>
</tr>
</tbody>
</table>