Position div and get external js file work onload - javascript

I have a JavaScript and CSS that works in fiddle but not when I use outside fiddle. fiddle
when I plug it in to the html like below, it doesn't work. I believe I am missing some code?
the count div is not in the right position when I am not viewing it from jsfiddle. How can I position it relative to the search input?
it takes a minute to generate the table, is it because my code is badly written?
*well i do have 800rows*8columns
Thank you in advance.
HTML
<head>
<link rel="stylesheet" type="text/css" href="search-table.css">
<script type="text/javascript" src="jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="search-table.js"></script>
</head>
<body>
</body>
<table id="table-body">
<thead>
<tr>
<th>No.</th>
<th>Name</th>
<th>Address</th>
<th>Tel</th>
<th>Fax</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Apple</td>
<td>A1</td>
<td>1-11</td>
<td>1-22</td>
</tr>
<tr>
<td>2</td>
<td>Banana</td>
<td>A2</td>
<td>2-11</td>
<td>2-22</td>
</tr>
<tr>
<td>3Asdqwe</td>
<td>Cherry</td>
<td>A3</td>
<td>3-11</td>
<td>3-22</td>
</tr>
<tr>
<td>4A</td>
<td>Duriaen</td>
<td>A4</td>
<td>4-11</td>
<td>4-22</td>
</tr>
<tr>
<td>1</td>
<td>Apple</td>
<td>A1</td>
<td>5-11</td>
<td>5-22</td>
</tr>
<tr>
<td>2</td>
<td>Banana</td>
<td>A2</td>
<td>6-11</td>
<td>6-22</td>
</tr>
<tr>
<td>3Asdqwe</td>
<td>Cherry</td>
<td>A3</td>
<td>7-11</td>
<td>7-22</td>
</tr>
<tr>
<td>4A</td>
<td>Duriaen</td>
<td>A4</td>
<td>8-11</td>
<td>8-22</td>
</tr>
</tbody>
</table>
</html>
JavaScript
//Perparing table
/*
*comment
*/
$("<div>", {
class: "tablewrapper"
}).insertBefore("table#table-body");
$("<table>", {
class: "header"
}).appendTo($("<div>", {
class: "headerwrapper"
}).appendTo("div.tablewrapper"));
$("table#table-body").appendTo($("<div>", {
class: "bodywrapper"
}).appendTo("div.tablewrapper"));
$("table#table-body>thead").clone().val("").appendTo("table.header");
$("table.header>tr").removeClass("header_hidden");
$("table#table-body").find("thead tr").addClass("header_hidden");
$("table#table-body").find("tbody td:nth-child(2)").addClass("lefty");
$("<input>", {
type: "text"
}).attr("id", "search-criteria").appendTo($("<div>", {
class: "s_box"
}).insertAfter("div.headerwrapper"));
$("<div>").attr("id", "count").insertAfter("div.s_box");
resizeTable();
var bodyTd = $("table#table-body tr td");
$(window).resize(resizeTable);
//search function
$("#search-criteria").on("keyup", function () {
var keyword = $(this).val().replace(/[A-Za-z0-9]/g, function (td_word) {
return String.fromCharCode(td_word.charCodeAt(0) - 0xFEE0);
}).toLowerCase();
var row = "table#table-body tbody>tr";
if (keyword !== "") {
$(row).each(function () {
var td_word = $(this).text().toLowerCase();
//shorthand if function
$(this).closest(row)[td_word.indexOf(keyword) !== -1 ? 'show' : 'hide']();
});
var srowCount = $(row).filter(":visible").length;
document.getElementById('count').innerHTML = srowCount;
if (srowCount === 0) {
if (!$(row).last().hasClass('s_empty')) {
$("table#table-body tbody").last().append('<tr class="s_empty"><td colspan="5" style="text-align:center">Search not found</td></tr>');
}
$("tr.s_empty").show();
} else {
$("tr.s_empty").remove();
}
} else {
$("tr.s_empty").remove();
$(row).show();
document.getElementById('count').innerHTML = $(row).length;
}
});
var row = "table#table-body tbody>tr";
var srowCount = $(row).filter(":visible").length;
document.getElementById('count').innerHTML = srowCount;
function resizeTable() {
//width adjustments
$("table.header").width($("#table-body").width());
$("div.s_box").width(($("div.headerwrapper").width() - 10)).height(($("table.header").height() - 9));
$("input#search-criteria").width(($("div.headerwrapper").width() - 30)).height(($("div.s_box").height() - 0.05));
var counter_h = ($("table.header").height() / 2 + $("table.header").height() - 1);
$("div#count").css({
"top": counter_h
});
var bodyTr = $("table#table-body tbody>tr:visible:eq(0) td");
console.log(bodyTr);
$("table.header tr:first th").each(function (index, value) {
$(this).width(bodyTr.eq(index).width());
});
//apply widths to every TD
$("table#table-body tr:gt(0)").each(function () {
$(this).children().each(function (index) {
$(this).width(bodyTr.eq(index).width());
});
});
}

you have to make s_box relative so that count becomes absolute according to it
.s_box {
position: relative;
}

There will error coming because of this JavaScript $("<div>", {class: "tablewrapper"}) that used. It should be like this $("<div>", {"class": "tablewrapper"}) for all places.
This is suggestion that,before preparing HTML from JavaScript use document ready event OR place your JavaScript at the end of html body elements.
<html>
<head>
<link rel="stylesheet" type="text/css" href="search-table.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
//Perparing table
/*
*comment
*/
$(document).ready(function() {
$("<div>", {"class": "tablewrapper"}).insertBefore("table#table-body");
$("<table>", {"class": "header"}).appendTo($("<div>", {"class": "headerwrapper"}).appendTo("div.tablewrapper"));
$("table#table-body").appendTo($("<div>", {"class": "bodywrapper"}).appendTo("div.tablewrapper"));
$("table#table-body>thead").clone().val("").appendTo("table.header");
$("table.header>tr").removeClass("header_hidden");
$("table#table-body").find("thead tr").addClass("header_hidden");
$("table#table-body").find("tbody td:nth-child(2)").addClass("lefty");
$("<input>", {type: "text"}).attr("id","search-criteria").appendTo($("<div>", {"class":"s_box"}).insertAfter("div.headerwrapper"));
$("<div>").attr("id","count").insertAfter("div.s_box");
resizeTable();
var bodyTd = $("table#table-body tr td");
$(window).resize(resizeTable);
var row = "table#table-body tbody>tr";
var srowCount = $(row).filter(":visible").length;
document.getElementById('count').innerHTML = srowCount;
//search function
$("#search-criteria").on("keyup", function () {
var keyword = $(this).val().replace(/[A-Za-z0-9]/g, function (td_word) {
return String.fromCharCode(td_word.charCodeAt(0) - 0xFEE0);
}).toLowerCase();
var row = "table#table-body tbody>tr";
if (keyword !== "") {
$(row).each(function () {
var td_word = $(this).text().toLowerCase();
//shorthand if function
$(this).closest(row)[td_word.indexOf(keyword) !== -1 ? 'show' : 'hide']();
});
var srowCount = $(row).filter(":visible").length;
document.getElementById('count').innerHTML = srowCount;
if (srowCount === 0) {
if(!$(row).last().hasClass('s_empty'))
{
$("table#table-body tbody").last().append('<tr class="s_empty"><td colspan="5" style="text-align:center">Search not found</td></tr>');
}
$("tr.s_empty").show();
} else {
$("tr.s_empty").remove();
}
} else {
$("tr.s_empty").remove();
$(row).show();
document.getElementById('count').innerHTML = $(row).length;
}
});
});
function resizeTable() {
//width adjustments
$("table.header").width($("#table-body").width());
$("div.s_box").width(($("div.headerwrapper").width()-10)).height(($("table.header").height()-9));
$("input#search-criteria").width(($("div.headerwrapper").width()-30)).height(($("div.s_box").height()-0.05));
var counter_h = ($("table.header").height()/2+$("table.header").height()-1);
$("div#count").css({"top":counter_h});
var bodyTr = $("table#table-body tbody>tr:visible:eq(0) td");
console.log(bodyTr);
$("table.header tr:first th").each(function (index, value) {
$(this).width(bodyTr.eq(index).width());
});
//apply widths to every TD
$("table#table-body tr:gt(0)").each(function () {
$(this).children().each(function (index) {
$(this).width(bodyTr.eq(index).width());
});
});
}
</script>
<style>div.tablewrapper, div.headerwrapper, div.bodywrapper {
border:0px;
}
div.headerwrapper {
background-color:#1BA7F5;
}
div.bodywrapper {
height:100px;
overflow-y:scroll;
border-bottom:solid 2px #1BA7F5;
}
table.header, table#table-body {
border:0px;
border-collapse:collapse;
border-spacing:0px;
text-align:center;
}
table.header {
line-height:32px;
background-color:#1BA7F5;
color:#FFF;
}
table.header th {
padding-left:10px;
text-align:left;
font-weight: normal;
}
table#table-body {
width:100%;
}
table#table-body tr {
line-height:30px;
border-top:1px solid #C4C4C4;
}
table#table-body tr.header_hidden {
display:none;
}
table#table-body tr:hover {
background-color:#FFFF99;
}
table#table-body tbody td.lefty {
text-align:left;
}
div.s_box {
padding: 5px 5px;
background: #c4c4c4;
box-sizing: border-box;
}
input#search-criteria {
-webkit-appearance: none;
padding: 0 10px;
border: none;
border-radius: 6px;
font-size: 13px;
line-height: 23px;
background: #fff;
}
input#search-criteria:focus{
outline:none;
}
div#count {
position: absolute;
right: 17px;
color: #FFF;
background-color: #9EB4C2;
line-height: 19px;
font-size: 15px;
padding: 0 5px;
border-radius: 3px;
}
</style>
</head>
<body>
</body>
<table id="table-body">
<thead>
<tr>
<th>No.</th>
<th>Name</th>
<th>Address</th>
<th>Tel</th>
<th>Fax</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Apple</td>
<td>A1</td>
<td>1-11</td>
<td>1-22</td>
</tr>
<tr>
<td>2</td>
<td>Banana</td>
<td>A2</td>
<td>2-11</td>
<td>2-22</td>
</tr>
<tr>
<td>3Asdqwe</td>
<td>Cherry</td>
<td>A3</td>
<td>3-11</td>
<td>3-22</td>
</tr>
<tr>
<td>4A</td>
<td>Duriaen</td>
<td>A4</td>
<td>4-11</td>
<td>4-22</td>
</tr>
<tr>
<td>1</td>
<td>Apple</td>
<td>A1</td>
<td>5-11</td>
<td>5-22</td>
</tr>
<tr>
<td>2</td>
<td>Banana</td>
<td>A2</td>
<td>6-11</td>
<td>6-22</td>
</tr>
<tr>
<td>3Asdqwe</td>
<td>Cherry</td>
<td>A3</td>
<td>7-11</td>
<td>7-22</td>
</tr>
<tr>
<td>4A</td>
<td>Duriaen</td>
<td>A4</td>
<td>8-11</td>
<td>8-22</td>
</tr>
</tbody>
</table>
</html>

Related

Count visible rows from a specific class in html table using Javascript

How to count total visible rows from a specific class such as ".CountTwo" in html table using JavaScript, I have a code below that filters table rows while typing.
I'm having issues here
count.push(document.querySelectorAll('.CountTwo'))
function myFunction() {
// Declare variables
if (document.getElementById('name').checked) {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("MyTable");
tr = table.getElementsByTagName("tr");
count = [];
rowsFound = [];
// 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")[1]; // change number to any other number to target column for table search
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
rowsFound.push(1)
count.push(document.querySelectorAll('.CountTwo'))
} else {
tr[i].style.display = "none";
}
}
}
document.getElementById("archieve").innerHTML = count.length;
document.getElementById("statistic").innerHTML = rowsFound.length;
}
}
#MyTable tbody tr {
border-bottom: 1px solid #dddddd;
}
#MyTable tbody tr:nth-child(even) {
background-color: #313131;
}
#MyTable tbody tr:last-of-type {
border-bottom: 2px solid #E5BB7F;
}
#MyTable a {
color: rgb(84, 204, 255);
}
#MyTable tbody tr {
background-color: #0a2c5500;
}
<table id="MyTable">
<thead>
<tr>
<th>#</th>
<th>name</th>
<th>number</th>
<th>date</th>
<th>category</th>
<th>link</th>
<th>link2</th>
<th>link3</th>
</tr>
</thead>
<tr>
<td>1</td>
<td>John</td>
<td>1000</td>
<td>1/1/2023</td>
<td>A</td>
<td><a class="CountTwo" target="_BLANK" href="#">Link To File</a></td>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>1000</td>
<td>1/1/2023</td>
<td>A</td>
<td><a class="CountTwo" target="_BLANK" href="#">Link To File</a></td>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>1000</td>
<td>1/1/2023</td>
<td>A</td>
<td><a class="CountTwo" target="_BLANK" href="#">Link To File</a></td>
</tr>
</table>
I added eventListeners and used your HTML
window.addEventListener("DOMContentLoaded", () => { // when page loads
const input = document.getElementById("myInput"),
trs = document.querySelectorAll("#MyTable tbody tr"),
name = document.getElementById('name');
function myFunction() {
let cnt = 0;
if (name.checked) {
const filter = input.value.toUpperCase();
trs.forEach(tr => {
const td = tr.querySelectorAll("td")[1];
const txtValue = td.textContent;
const hide = filter && txtValue.toUpperCase().indexOf(filter) === -1;
tr.hidden = hide;
if (!hide) cnt++;
});
} else {
trs.forEach(tr => tr.hidden = false);
cnt = trs.length;
}
let visible = [...document.querySelectorAll(".CountTwo")].filter(link => !link.closest('tr').hidden).length;
document.getElementById("archieve").innerHTML = cnt;
document.getElementById("statistic").innerHTML = visible;
}
input.addEventListener("input", myFunction);
name.addEventListener("click", myFunction);
myFunction(); // set the values
})
#MyTable tbody tr {
border-bottom: 1px solid #dddddd;
}
#MyTable tbody tr:nth-child(even) {
background-color: #313131;
}
#MyTable tbody tr:last-of-type {
border-bottom: 2px solid #E5BB7F;
}
#MyTable a {
color: rgb(84, 204, 255);
}
#MyTable tbody tr {
background-color: #0a2c5500;
}
Filter <input type="text" id="myInput" /> <label>Name: <input type="checkbox" checked id="name" /></label>
<span id="archieve">0</span>
<span id="statistic">0</span>
<table id="MyTable">
<thead>
<tr>
<th>#</th>
<th>name</th>
<th>number</th>
<th>date</th>
<th>category</th>
<th>link</th>
<th>link2</th>
<th>link3</th>
</tr>
</thead>
<tr>
<td>1</td>
<td>John A</td>
<td>1000</td>
<td>1/1/2023</td>
<td>A</td>
<td><a class="CountTwo" target="_BLANK" href="#">Link To File</a></td>
</tr>
<tr>
<td>1</td>
<td>John B</td>
<td>1000</td>
<td>1/1/2023</td>
<td>A</td>
<td><a class="CountTwo" target="_BLANK" href="#">Link To File</a></td>
</tr>
<tr>
<td>1</td>
<td>JohnC</td>
<td>1000</td>
<td>1/1/2023</td>
<td>A</td>
<td><a class="CountTwo" target="_BLANK" href="#">Link To File</a></td>
</tr>
</table>

Search different columns of table

I'm trying to work a way where you can click a button and search by different columns in a table. I can figure out the buttons and to change the [0] to [1] to search different columns, but how would i make it more dynamic, using javascript. I only want to search by 1 column at a time, so only search by first name or only search by nationality etc...
it is a basic code, I did web programming 20 years ago and im trying to get back up to speed.
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
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) {
txtValue = td.textContent || td.innerText;
if (filter) {
if (txtValue.toUpperCase() == filter) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
} else {
tr[i].style.display = "";
}
}
}
}
<div class="w3-container">
<h2>All Information</h2>
<div class="w3-bar">
<button class="w3-button w3-black" style="width: 10%">#</button>
<button class="w3-button w3-teal" style="width: 10%">First Name</button>
<button class="w3-button w3-red" style="width: 10%">Last Name</button>
<button class="w3-button w3-yellow" style="width: 10%">Address</button>
<button class="w3-button w3-green" style="width: 10%">Age</button>
<button class="w3-button w3-blue" style="width: 10%">Date of Birth</button>
<button class="w3-button w3-purple" style="width: 10%">Nationality</button>
</div>
<input id="myInput" onkeyup="myFunction()" placeholder="Search by ID Number..." title="Type in a number" type="text">
<table id="myTable">
<tr class="header">
<th class="w3-center" style="width: 2%;">#</th>
<th style="text-align: left; width: 17%;">First Name</th>
<th style="text-align: left; width: 17%;">Last Name</th>
<th style="text-align: left; width: 16%;">Address</th>
<th style="text-align: left; width: 16%;">Age</th>
<th style="text-align: left; width: 16%;">Date of Birth</th>
<th style="text-align: left; width: 16%;">Nationality</th>
</tr>
<tr>
<td class="w3-center">1</td>
<td>John</td>
<td>Smith</td>
<td>Pearse Street</td>
<td>45</td>
<td>01/10/1977</td>
<td>English</td>
</tr>
<tr>
<td class="w3-center">11</td>
<td>Tim</td>
<td>Green</td>
<td>Rosedale Avenue</td>
<td>23</td>
<td>17/04/1999</td>
<td>American</td>
</tr>
<tr>
<td class="w3-center">114</td>
<td>Tom</td>
<td>Deane</td>
<td>Greenwood Road</td>
<td>42</td>
<td>27/11/1980</td>
<td>English</td>
</tr>
<tr>
<td class="w3-center">208</td>
<td>Anna</td>
<td>Green</td>
<td>Rosedale Avenue</td>
<td>23</td>
<td>11/06/1999</td>
<td>Scottish</td>
</tr>
<tr>
<td class="w3-center">259</td>
<td>Rachel</td>
<td>Waters</td>
<td>Station Road</td>
<td>87</td>
<td>11/02/1936</td>
<td>Irish</td>
</tr>
<tr>
<td class="w3-center">1</td>
<td>George</td>
<td>Taylor</td>
<td>Beach Avenue</td>
<td>52</td>
<td>30/07/1971</td>
<td>South African</td>
</tr>
<tr>
<td class="w3-center">1</td>
<td>Neil</td>
<td>Smyth</td>
<td>Beach Road</td>
<td>6</td>
<td>15/12/2016</td>
<td>Australian</td>
</tr>
<tr>
<td class="w3-center">1</td>
<td>Sarah</td>
<td>Smyth</td>
<td>Beach Road</td>
<td>30</td>
<td>06/01/1993</td>
<td>Australian</td>
</tr>
</table>
</div>
const column = 3
const searchFor = 'GRE'
for (const cell of document.querySelectorAll(`#myTable tr td:nth-child(${column})`))
if (cell.textContent.toUpperCase().includes(searchFor))
cell.style.background = 'lightgreen'
<table id="myTable">
<tr class="header">
<th class="w3-center" style="width: 2%;">#</th>
<th style="text-align: left; width: 17%;">First Name</th>
<th style="text-align: left; width: 17%;">Last Name</th>
<th style="text-align: left; width: 16%;">Address</th>
<th style="text-align: left; width: 16%;">Age</th>
<th style="text-align: left; width: 16%;">Date of Birth</th>
<th style="text-align: left; width: 16%;">Nationality</th>
</tr>
<tr>
<td class="w3-center">1</td>
<td>John</td>
<td>Smith</td>
<td>Pearse Street</td>
<td>45</td>
<td>01/10/1977</td>
<td>English</td>
</tr>
<tr>
<td class="w3-center">11</td>
<td>Tim</td>
<td>Green</td>
<td>Rosedale Avenue</td>
<td>23</td>
<td>17/04/1999</td>
<td>American</td>
</tr>
<tr>
<td class="w3-center">114</td>
<td>Tom</td>
<td>Deane</td>
<td>Greenwood Road</td>
<td>42</td>
<td>27/11/1980</td>
<td>English</td>
</tr>
<tr>
<td class="w3-center">208</td>
<td>Anna</td>
<td>Green</td>
<td>Rosedale Avenue</td>
<td>23</td>
<td>11/06/1999</td>
<td>Scottish</td>
</tr>
<tr>
<td class="w3-center">259</td>
<td>Rachel</td>
<td>Waters</td>
<td>Station Road</td>
<td>87</td>
<td>11/02/1936</td>
<td>Irish</td>
</tr>
<tr>
<td class="w3-center">1</td>
<td>George</td>
<td>Taylor</td>
<td>Beach Avenue</td>
<td>52</td>
<td>30/07/1971</td>
<td>South African</td>
</tr>
<tr>
<td class="w3-center">1</td>
<td>Neil</td>
<td>Smyth</td>
<td>Beach Road</td>
<td>6</td>
<td>15/12/2016</td>
<td>Australian</td>
</tr>
<tr>
<td class="w3-center">1</td>
<td>Sarah</td>
<td>Smyth</td>
<td>Beach Road</td>
<td>30</td>
<td>06/01/1993</td>
<td>Australian</td>
</tr>
</table>
Looking for something like that ? (first version)
const
btSearch = document.querySelector('#bt-search')
, txt2search = document.querySelector('#txt-2-search')
, searchResult = document.querySelector('#search-result')
, myTable = document.querySelector('#my-table')
;
btSearch.disabled = true
;
myTable.onclick = ({target:TH}) =>
{
if (!TH.matches('th')) return;
clearFounds();
btSearch.disabled = true;
if (TH.classList.toggle('selec'))
{
btSearch.disabled = false;
myTable.querySelectorAll('th.selec')
.forEach(th => th.classList.toggle('selec',th===TH))
}
}
btSearch.onclick=()=>
{
clearFounds();
let txt = txt2search.value.trim()
, Rtxt = new RegExp(txt, 'i')
, nCol = 1 + myTable.querySelector('th.selec').cellIndex
, counter = 0
;
if (txt==='')
{
searchResult.textContent = 'nothing to search...';
return;
}
myTable.querySelectorAll(`tr td:nth-child(${nCol})`).forEach(td =>
{
if(Rtxt.test(td.textContent))
{
counter++;
td.classList.add('found');
}
})
searchResult.textContent = (counter===0) ? 'no result' : `${counter} element(s) found`;
}
function clearFounds()
{
searchResult.textContent = '.';
myTable.querySelectorAll('td.found')
.forEach(td => td.classList.remove('found'));
}
body {
font-family : Arial, Helvetica, sans-serif;
font-size : 16px;
margin : 1rem;
}
table {
border-collapse : separate;
border-spacing : 1px;
background-color : lightslategrey;
}
th { background: cadetblue; padding: .3em .6em; cursor: pointer; }
td { background: whitesmoke; padding: .2em .5em; }
tr *:first-child { text-align: center; font-style: oblique; }
tr * { white-space: nowrap; }
th:not(.selec):hover { background: orange; }
th.selec { background: orangered }
td.found { background: aquamarine; }
caption {
text-align : left;
padding : .4rem;
font-size : 1.2rem;
background-color: #a0dbdd;
}
#search-result {
float : right;
font-size : .9rem;
}
<table id="my-table">
<caption>
Find :
<input type="text" id="txt-2-search" placeholder="select a column first...">
<button id="bt-search"> do search </button>
<span id="search-result">0</span>
</caption>
<thead>
<tr>
<th>#</th><th>First Name</th><th>Last Name</th><th>Address</th><th>Age</th><th>Date of Birth</th><th>Nationality</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td><td>John</td><td>Smith</td><td>Pearse Street</td><td>45</td><td>01/10/1977</td><td>English</td>
</tr>
<tr>
<td>11</td><td>Tim</td><td>Green</td><td>Rosedale Avenue</td><td>23</td><td>17/04/1999</td><td>American</td>
</tr>
<tr>
<td>114</td><td>Tom</td><td>Deane</td><td>Greenwood Road</td><td>42</td><td>27/11/1980</td><td>English</td>
</tr>
<tr>
<td>208</td><td>Anna</td><td>Green</td><td>Rosedale Avenue</td><td>23</td><td>11/06/1999</td><td>Scottish</td>
</tr>
<tr>
<td>259</td><td>Rachel</td><td>Waters</td><td>Station Road</td><td>87</td><td>11/02/1936</td><td>Irish</td>
</tr>
<tr>
<td>1</td><td>George</td><td>Taylor</td><td>Beach Avenue</td><td>52</td><td>30/07/1971</td><td>South African</td>
</tr>
<tr>
<td>1</td><td>Neil</td><td>Smyth</td><td>Beach Road</td><td>6</td><td>15/12/2016</td><td>Australian</td>
</tr>
<tr>
<td>1</td><td>Sarah</td><td>Smyth</td><td>Beach Road</td><td>30</td><td>06/01/1993</td><td>Australian</td>
</tr>
</tbody>
</table>
As the subject interested me...
And sorry, there may be a bit too many technical things here, but I've already spent a bit too many hours there, I'll come back to explain and comment. If any questions come up here in the meantime, I'll do my best to answer them.
const
txt2search = document.querySelector('#txt-2-search')
, searchResult = document.querySelector('#search-result')
, myTable = document.querySelector('#my-table')
, tableHeads = myTable.querySelectorAll('thead th')
, styleColHover = document.querySelector('#style-col-hover')
, mouseHoverTD = ({target: TD}) =>
{
let ref = (!!TD && TD.matches('td')) ? TD.cellIndex +1 : -1;
styleColHover.textContent = `td:nth-child(${ref}) { background: var(--col-hover);}`;
};
myTable.tBodies[0].onmouseenter = mouseHoverTD;
myTable.tBodies[0].onmousemove = mouseHoverTD;
myTable.tBodies[0].onmouseout =_=> mouseHoverTD({target:null});
txt2search.onkeyup = ({key}) =>
{
if (key==='Enter') searchProcess();
}
myTable.onclick = ({target:colElm}) =>
{
if (!colElm.matches('th, td')) return;
if (colElm.matches('td'))
{
tableHeads.forEach(th=>th.classList.remove('selec'));
tableHeads[colElm.cellIndex].classList.add('selec');
}
else if (colElm.classList.toggle('selec'))
{
tableHeads.forEach(th=>th.classList.toggle('selec', th===colElm));
}
searchProcess();
}
function clearSearch()
{
searchResult.textContent = '.';
myTable.querySelectorAll('td.found').forEach(td => td.classList.remove('found'));
}
function searchProcess()
{
let indxElm = myTable.querySelector('thead th.selec')?.cellIndex ?? 'x';
clearSearch();
if(isNaN(indxElm)) return;
let txt = txt2search.value.trim()
, Regtxt = new RegExp(txt, 'i')
, counter = 0
, query = 'tr td:nth-child('+ ++indxElm +')'
;
if (txt==='')
{
searchResult.textContent = 'nothing to search...';
return;
}
myTable.querySelectorAll(query).forEach(td =>
{
if(Regtxt.test(td.textContent))
{
counter++;
td.classList.add('found');
}
})
searchResult.textContent =
(counter===0) ? 'no result' : `${counter} element(s) found`;
}
:root {
--col-hover : #eeafdb;
}
body {
font-family : Arial, Helvetica, sans-serif;
font-size : 16px;
margin : 1rem;
}
table {
border-collapse : separate;
border-spacing : 1px;
background-color : lightslategrey;
}
th { background: cadetblue; padding: .3em .6em; }
td { background: whitesmoke; padding: .2em .5em; }
tr *:first-child { text-align: center; font-style: oblique; }
tr * { white-space: nowrap; cursor: pointer; }
th:not(.selec):hover { background: orange; }
th.selec { background: orangered; }
td.found { background: aquamarine !important; }
caption {
text-align : left;
padding : .4rem;
font-size : 1.2rem;
background : #a0dbdd;
}
#search-result {
float : right;
font-size : .9rem;
}
<style id="style-col-hover"> td:nth-child(-1) { background : var(--col-hover);}</style>
<table id="my-table">
<caption>
Find :
<input type="text" id="txt-2-search" placeholder="select a column first...">
<span id="search-result">0</span>
</caption>
<thead>
<tr>
<th>#</th><th>First Name</th><th>Last Name</th><th>Address</th><th>Age</th><th>Date of Birth</th><th>Nationality</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td><td>John</td><td>Smith</td><td>Pearse Street</td><td>45</td><td>01/10/1977</td><td>English</td>
</tr>
<tr>
<td>11</td><td>Tim</td><td>Green</td><td>Rosedale Avenue</td><td>23</td><td>17/04/1999</td><td>American</td>
</tr>
<tr>
<td>114</td><td>Tom</td><td>Deane</td><td>Greenwood Road</td><td>42</td><td>27/11/1980</td><td>English</td>
</tr>
<tr>
<td>208</td><td>Anna</td><td>Green</td><td>Rosedale Avenue</td><td>23</td><td>11/06/1999</td><td>Scottish</td>
</tr>
<tr>
<td>259</td><td>Rachel</td><td>Waters</td><td>Station Road</td><td>87</td><td>11/02/1936</td><td>Irish</td>
</tr>
<tr>
<td>1</td><td>George</td><td>Taylor</td><td>Beach Avenue</td><td>52</td><td>30/07/1971</td><td>South African</td>
</tr>
<tr>
<td>1</td><td>Neil</td><td>Smyth</td><td>Beach Road</td><td>6</td><td>15/12/2016</td><td>Australian</td>
</tr>
<tr>
<td>1</td><td>Sarah</td><td>Smyth</td><td>Beach Road</td><td>30</td><td>06/01/1993</td><td>Australian</td>
</tr>
</tbody>
</table>
Here's my take Dar.
//Define a column to look in
// const column = 4
//Get the value from the input
// const searchFor = document.getElementById('myInput').value
//Grab all the cells for the column
columnCells = Array.from(document.querySelectorAll(`#myTable tr td:nth-child(${column})`))
//Clear out previous matches
columnCells.forEach(cell=>cell.style.background = 'white')
//Filter the cells by the searchFor term
matchingCells = columnCells.filter(cell=>{
return cell.textContent.toLowerCase().includes(searchFor.toLowerCase()) && searchFor != ""
})
//Color them
matchingCells.forEach(cell=>cell.style.background = 'yellow')

how to use bootstrap filter for searching a name by first letter

I am using bootstrap filter for searching. But,for example when I type 'n' it shows all the name having 'n' like nathan, arjan . I don't want that.I want like this : if i type 'n' it will show only the names which starts with 'n' like nathaan,narima.
my blade.php code here:
<input class="form-control" id="myInput" type="text" placeholder="Search..">
<tbody id="myTable">
<tr>
<td>John</td>
</tr>
<tr>
<td>Anja</td>
</tr>
</tbody>
my script part here
<script>
$(document).ready(function(){
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>
There is a method called startsWith that you can use. The documentation can be found at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
<script>
$(document).ready(function(){
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().startsWith(value))
});
});
});
</script>
you can change the method if you want.
$("#myInput").bind("keyup", function() {
var text = $(this).val().toLowerCase();
var items = $("tr td");
//first, hide all:
items.parent().hide();
//show only those matching user input:
items.filter(function () {
return $(this).text().toLowerCase().indexOf(text) == 0;
}).parent().show();
});
Another way would be using RegExp:
$(document).ready(function() {
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function() {
/* $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1) */
const searchRegEx = new RegExp(`^${value}`, 'i');
$(this).toggle(searchRegEx.test($(this).text().trim()));
});
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<input class="form-control" id="myInput" type="text" placeholder="Search..">
<table class="table table-bordered">
<tbody id="myTable">
<tr>
<td>John</td>
</tr>
<tr>
<td>Anja</td>
</tr>
</tbody>
</table>
Using .charAt(0) for result set to be filtered with first character match
Basic example from w3schools modified
<!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>My Customers</h2>
<input type="text" id="myInput" onkeyup="filterBy()" placeholder="Search..." 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>Marimba</td>
<td>Something</td>
</tr>
<tr>
<td>Marimba</td>
<td>Something</td>
</tr>
<tr>
<td>North/South</td>
<td>UK</td>
</tr>
<tr>
<td>Paris specialites</td>
<td>France</td>
</tr>
</table>
<script>
function filterBy() {
var input, filter, table, tr, td, i, txtValue;
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) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
if (txtValue.toUpperCase().charAt(0) == filter.charAt(0)) {
tr[i].style.display = "";
}
} else {
tr[i].style.display = "none";
}
if(filter.length == 0)
{
tr[i].style.display = "";
}
}
}
}
</script>
</body>
</html>

Finding the table row number of a clicked row

How can functionaity be added to the existing javascript coding below to find out as to what row number is clicked. The table headers should be exempt, and the dataset will start at ID number 0.
So for example, if the 2nd row of the table was clicked, an alert box would popup saying that "ID # is 1"
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#mstrTable {
border: 1px solid black
}
#mstrTable td, th {
border: 1px solid black
}
#mstrTable tr.normal td {
color: black;
background-color: white;
}
#mstrTable tr.highlighted td {
color: white;
background-color: gray;
}
</style>
</head>
<body>
<table id="mstrTable">
<thead>
<tr>
<th>File Number</th>
<th>Date1</th>
<th>Date2</th>
<th>Status</th>
<th>Num.</th>
</tr>
</thead>
<tbody>
<tr>
<td>KABC</td>
<td>09/12/2002</td>
<td>09/12/2002</td>
<td>Submitted</td>
<td>0</td>
</tr>
<tr>
<td>KCBS</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Approved</td>
<td>1 </td>
</tr>
<tr>
<td>WFLA</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Submitted</td>
<td>2</td>
</tr>
<tr>
<td>WTSP</td>
<td>09/15/2002</td>
<td>09/15/2002</td>
<td>In-Progress</td>
<td>3</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
(
function( )
{
var trows = document.getElementById("mstrTable").rows;
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = "normal";
trow.onclick = highlightRow;
}
function highlightRow( )
{
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = ( trow == this && trow.className != "highlighted") ? "highlighted" : "normal";
}
}
}
)();
</script>
</body>
</html>
Checkout rowIndex property here. It starts from 0.
Just put data-row-no attribut to every <tr>. Then from JavaScript call trow.getAttribute('data-row-no') to get current row.
...
<table id="mstrTable">
<thead>
<tr>
<th>File Number</th>
<th>Date1</th>
<th>Date2</th>
<th>Status</th>
<th>Num.</th>
</tr>
</thead>
<tbody>
<tr data-row-no="0">
<td>KABC</td>
<td>09/12/2002</td>
<td>09/12/2002</td>
<td>Submitted</td>
<td>0</td>
</tr>
<tr data-row-no="1">
<td>KCBS</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Approved</td>
<td>1 </td>
</tr>
<tr data-row-no="2">
<td>WFLA</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Submitted</td>
<td>2</td>
</tr>
<tr data-row-no="3">
<td>WTSP</td>
<td>09/15/2002</td>
<td>09/15/2002</td>
<td>In-Progress</td>
<td>3</td>
</tr>
...
(
function( )
{
var trows = document.getElementById("mstrTable").rows;
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = "normal";
trow.onclick = highlightRow;
}
function highlightRow( )
{
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = ( trow == this && trow.className != "highlighted") ? "highlighted" : "normal";
alert(trow.getAttribute('data-row-no'));
}
}
}
)();

Clicked Table Row Returns NaN

I am trying to identify as to what row number the user clicks on and to alert them. I wanted to exempt the table headers from being counted so I have intentionally used the this.rowIndex - 1 but when I click on any row, the alert box is returning a NaN value.
How do you fix this?
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#mstrTable {
border: 1px solid black
}
#mstrTable td, th {
border: 1px solid black
}
#mstrTable tr.normal td {
color: black;
background-color: white;
}
#mstrTable tr.highlighted td {
color: white;
background-color: gray;
}
</style>
</head>
<body>
<table id="mstrTable">
<thead>
<tr>
<th>File Number</th>
<th>Date1</th>
<th>Date2</th>
<th>Status</th>
<th>Num.</th>
</tr>
</thead>
<tbody>
<tr>
<td>KABC</td>
<td>09/12/2002</td>
<td>09/12/2002</td>
<td>Submitted</td>
<td>0</td>
</tr>
<tr>
<td>KCBS</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Approved</td>
<td>1 </td>
</tr>
<tr>
<td>WFLA</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Submitted</td>
<td>2</td>
</tr>
<tr>
<td>WTSP</td>
<td>09/15/2002</td>
<td>09/15/2002</td>
<td>In-Progress</td>
<td>3</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
(
function( )
{
var trows = document.getElementById("mstrTable").rows;
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = "normal";
trow.onclick = highlightRow;
}
function highlightRow(e)
{
alert('Row is ' + this.rowIndex-1)
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = ( trow == this && trow.className != "highlighted") ? "highlighted" : "normal";
}
}
}
)();
</script>
</body>
</html>
Put parentheses around math operations so they take precedence over string concatenation.
alert('Row is ' + (this.rowIndex-1))
Fiddle
Change it to this.rowIndex instead of this.rowIndex-1.

Categories