searching text within Html table - javascript

I just googling to find a script that I can use to find a text within HTML table.
Like I create a table of student names which have many columns and rows. I have a good script too that display whatever I try to search but it display full row...
function searchSname() {
var input, filter, found, table, tr, td, i, j;
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");
for (j = 0; j < td.length; j++) {
if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
}
}
if (found) {
tr[i].style.display = "";
found = false;
} else {
tr[i].style.display = "none";
}
}
}
<input id='myInput' onkeyup='searchSname()' type='text'>
<table id='myTable'>
<tr>
<td>AB</td>
<td>BC</td>
</tr>
<tr>
<td>CD</td>
<td>DE</td>
</tr>
<tr>
<td>EF</td>
<td>GH</td>
</tr>
</table>
But know I am looking for making some changes to display exact text whatever I searched instead of full row like it will display text that I type to search and hide other unmatched fully....
Kindly let me know is it possible to display text only that I type to search within a table? Like if I try to find student name "AB" then it should display AB only instead of "AB BC".

This is much simpler than you are making it.
var cells = document.querySelectorAll("#myTable td");
var search = document.getElementById("myInput");
search.addEventListener("keyup", function(){
for(var i = 0; i < cells.length; ++i){
// This line checks for an exact match in a cell against what the
// user entered in the search box
//if(cells[i].textContent.toLowerCase() === search.value.toLowerCase()){
// This checks for cells that start with what the user has entered
if(cells[i].textContent.toLowerCase().indexOf(search.value.toLowerCase()) === 0){
cells.forEach(function(element){
element.style.display = "none";
});
cells[i].style.background = "yellow";
cells[i].style.display = "table-cell";
break;
} else {
cells[i].style.background = "white";
cells.forEach(function(element){
if(cells[i] !== element){
element.style.display = "table-cell";
}
});
}
}
});
table, td { border:1px solid black; border-collapse: collapse;}
<input id='myInput'>
<table id='myTable'>
<tr>
<td>AB</td>
<td>BC</td>
</tr>
<tr>
<td>CD</td>
<td>DE</td>
</tr>
<tr>
<td>EF</td>
<td>GH</td>
</tr>
</table>

Related

Filtering html table (JS)

I have an html table in my view that I want to filter with multiple filters. In this case, I have 3 filters, but I can have much more.
Here is a little part of the code, to show the problem
$(document).ready(function () {
$('#datefilterfrom').on("change", filterRows);
$('#datefilterto').on("change", filterRows);
$('#projectfilter').on("change", filterProject);
});
function filterRows() {
var from = $('#datefilterfrom').val();
var to = $('#datefilterto').val();
if (!from && !to) { // no value for from and to
return;
}
from = from || '1970-01-01'; // default from to a old date if it is not set
to = to || '2999-12-31';
var dateFrom = moment(from);
var dateTo = moment(to);
$('#testTable tr').each(function (i, tr) {
var val = $(tr).find("td:nth-child(2)").text();
var dateVal = moment(val, "DD/MM/YYYY");
var visible = (dateVal.isBetween(dateFrom, dateTo, null, [])) ? "" : "none"; // [] for inclusive
$(tr).css('display', visible);
});
}
function filterProject() {
var contentToColor = {
"Заявка отменена": "#9900ff",
"Подтверждено менеджером Vchasno": "green",
"Отменено менеджером Vchasno": "#9900ff",
"Отклонено региональным менеджером": "#9900ff",
"Подтверждено региональным менеджером": "red"
};
var project = this.value;
var filter, table, tr, td, i;
filter = project.toUpperCase();
table = document.getElementById("testTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/moment/moment/2.2.1/min/moment.min.js"></script>
<div class="row">
<div class="col-md-3">
<h4>Дата з</h4>
<input type="date" class="form-control" id="datefilterfrom" data-date-split-input="true">
</div>
<div class="col-md-3">
<h4>Дата до</h4>
<input type="date" class="form-control" id="datefilterto" data-date-split-input="true">
</div>
<div class="col-md-2">
<h4>Проект</h4>
<select id="projectfilter" name="projectfilter" class="form-control"><option value="1">Тестовый проект</option><option value="2">Тест2</option></select>
</div>
</div>
<table id="testTable" class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Дата</th>
<th scope="col">Проект</th>
</tr>
</thead>
<tbody id="report">
<tr>
<td class="proposalId">9</td><td> 17/07/2018</td> <td> Тестовый проект</td>
</tr>
<tr><td class="proposalId">8</td><td> 18/07/2018</td><td> Тестовый проект</td></tr>
<tr><td class="proposalId">7</td><td> 17/07/2018</td><td> Тест2</td></tr>
<tr style=""><td class="proposalId">3</td><td> 19/07/2018</td><td> Тест2</td></tr>
</tbody>
</table>
Here is the full working snippet
https://codepen.io/suhomlineugene/pen/JBBGXa
When I set date filter it filters table great, but when I set the second filter it gets data from the table that I have unfiltered.
Where is my problem?
Thank's for help!
the problem was filter = project.toUpperCase() is returning 1 or 2. I updated the logic to get the innerHTML and the do compare. Here is the modified code
function filterProject() {
var contentToColor = {
"Заявка отменена": "#9900ff",
"Подтверждено менеджером Vchasno": "green",
"Отменено менеджером Vchasno": "#9900ff",
"Отклонено региональным менеджером": "#9900ff",
"Подтверждено региональным менеджером": "red"
};
let dumb = this.options.selectedIndex;
dumb = this.options[dumb].innerHTML;
console.log(dumb);
var filter, table, tr, td, i;
filter = dumb.toUpperCase();
table = document.getElementById("testTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "table-row";
} else {
tr[i].style.display = "none";
}
}
}
}
Code pen link here
When you do filterProject(), check if you have already filtered out the rows you are iterating over:
....
for (i = 0; i < tr.length; i++) {
if(tr[i].style.display !== 'none'){
...
Here's a working codepen:
https://codepen.io/anon/pen/NBBxad
HTML
<input type="text" id="input_id" onkeyup="tableSearch('id', 'table', 0)">
Javascript
function tableSearch(input_id, table_id, col) {
var input, filter, table, tr, td, i;
input = document.getElementById(input_id);
filter = input.value.toUpperCase();
table = document.getElementById(table_id);
tr = table.getElementsByTagName('tr');
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName('td')[col];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}

Is there a way to implement on keyup event except one key?

I'm trying to develop a Javascript function that do some verification every time an input change (I'm using onkeyup event) except when we delete what we enter inside the input. Here is my actual code:
function myFunction() {
var input, filter, table, tr, td, i;
var cpt = 0;
var nbRow = 0;
input = document.getElementById("filterInput");
filter = input.value.toUpperCase();
table = document.getElementById("test");
thead = table.getElementsByTagName("tbody");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
nbRow = nbRow + 1;
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
cpt = cpt + 1;
}
}
}
if (nbRow == cpt) {
alert("The list is empty")
}
}
<input id="filterInput" onkeyup="myFunction()">
<table id="test">
<thead>
<tr>
<th>Titre1</th>
<th>Titre2</th>
<th>Titre3</th>
</tr>
</thead>
<tbody>
<tr>
<td>contenu1</td>
<td>contenu2</td>
<td>contenu3</td>
</tr>
</tbody>
</table>
How can I avoid a repetitive alert show everytime a user deletes one character?
EDIT :
I'm trying to avoid repetitive 'alert' without losing the verification after the user deletes one character.
If you want to ignore delete and backspace with onkeyup, you can add this check to the beginning of your function:
function myFunction(event) {
// capture what key was pressed
var key = event.keyCode || event.charCode;
if( key === 8 || key === 46 )
return; //if it's del or backspace, exit the function
// continue your function here
}
You can implement a validation in the function detecting which key was pressed...
function myFunction(e) {
if(e.keyCode !== 8){ // back key excluded
var input, filter, table, tr, td, i;
var cpt = 0;
var nbRow = 0;
input = document.getElementById("filterInput");
filter = input.value.toUpperCase();
table = document.getElementById("test");
thead = table.getElementsByTagName("tbody");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
nbRow = nbRow + 1;
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
cpt = cpt + 1;
}
}
}
if (nbRow == cpt) {
alert("The list is empty")
}
}
}
<input id="filterInput" onkeyup="myFunction(event)">
<table id="test">
<thead>
<tr>
<th>Titre1</th>
<th>Titre2</th>
<th>Titre3</th>
</tr>
</thead>
<tbody>
<tr>
<td>contenu1</td>
<td>contenu2</td>
<td>contenu3</td>
</tr>
</tbody>
</table>
Of course you would have to add the code for every key you want to exclude

How to better formatting my HTML Table with titles and labels

How would I modify my code (below) to turn the table element (circled in red), into a table with a Title, and then headers above each column ("Load" and "kWh") for the left and right columns, respectively?
The elements, "name" and "watts" are what I want to create a label for ("Load" and "kWh"), in addition to a title above the table which says "Power Usage". Right now, there is no formatting, and I am having trouble going from the tutorials at W3 schools, into my code.
function(){
var wrapper = document.createElement("div");
if(!this.loaded) {
wrapper.innerHTML = "Loading...";
return wrapper;
}
if(this.xml !== null){
var table = document.createElement("table");
table.classList.add("xsmall", "table");
var channels = this.xml.getElementsByTagName("channel");
for(var i = 0; i < channels.length; i++){
var row = document.createElement("tr");
for(var n = 0; n < channels[i].children.length; n++){
if(channels[i].children[n].tagName === "name" || channels[i].children[n].tagName === "watts"){
var element = document.createElement("td");
element.classList.add(channels[i].children[n].tagName);
if (channels[i].children[n].textContent != 0){
element.innerHTML = channels[i].children[n].textContent;
row.appendChild(element);
table.appendChild(row);
}
else {
table.removeChild(row); }
}
}
}
wrapper.appendChild(table);
} else {
console.log("Returned no Data");
wrapper.innerHTML = "NO DATA";
}
return wrapper;
},
First Try:
You just want to build out a table similar to the following using the JS you've already written:
<table>
<caption>Put title here</caption>
<thead>
<tr>
<th>Load</th>
<th>kWh</th>
</tr>
</thead>
<tbody>
<tr>
<td>Kitchen Lights</td>
<td>2.799</td>
</tr>
</tbody>
</table>

How to make a double select filter?

i'm missing something on this code, my goal is to make 2 filter on this table, the select with id="myInput" must be the one who determine the appearing of the table and apply the first filter,that's the js:
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");
table.style.display = '';
// 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";
}
}
}
}
The second one (id="myInput2") should apply an additional filter, hiding the rows who dont match with another column,here's the js:
function myFunction2() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput2");
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")[5];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
That's the html code (forget about br and other bad things, i'm just making an integration of existing code)
<label>Zona</label> <select id="myInput2" onchange="myFunction2()">
<option value="">Tutte le zone</option>
</select> <label>Gruppo</label>
<select id="myInput" onchange="myFunction()">
<option value="">Seleziona un gruppo di categoria</option>
</select> <br>
<br>
<table id="myTable" style="display: none;">
<tr class="header">
<th>Categoria</th>
<th>Descrizione</th>
<th>Classe</th>
<th>Tariffa</th>
<th>Zona</th>
</tr>
<c:forEach var="infoSezioni" items="${outParamInfoSezioni}">
<tr>
<td style="display:none;">${infoSezioni.gruppo}</td>
<td>${infoSezioni.categoria}</td>
<td>${infoSezioni.descr}</td>
<td>${infoSezioni.classe}</td>
<td>${infoSezioni.tariffa}</td>
<td>${infoSezioni.zonaCens}</td>
</tr>
</c:forEach>
</table>
the problem is that:
When i apply 1 of this filters, the other one just doesnt work, how i can fix that?
please review this one
in both filter one and two
//apply filter + checking flag
if (td.innerHTML.toUpperCase().indexOf(filter) < 0 && (!tr[i].dataset.filtered)) {
tr[i].style.display = "none";
//giving flag
tr[i].dataset.filtered = true;
}
Displaying Table when either input1 & input2 has value:
// and myFunction2() as well
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
//remove unnecessary space
filter = input.value.trim().toUpperCase();
//return if no value
if(filter.length > 0) {return;}
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
//displaying table
table.style.display = 'block';
...

Add table values to input field on button click

I have a DataTable that stores names only. I want to have a button that will add all the names in the DataTable to an text input field.
<div id="myTabDiv">
<table name="mytab" id="mytab1">
<thead>
<tr>
<th>name</th>
</tr>
</thead>
<tbody>
<tr>
<td>chris</td>
</tr>
<tr>
<td>mike</td>
</tr>
</tbody>
</table>
<button id="add" >ADD</button>
<input type="text" id="text">
</div>
After click the "add" button, I want the names to appear in the text field separated by a comma.
And if possible, If the button is clicked again, remove the names?
I created the whole solution on codepen. This is the function used:
var clicks = 0;
function csv() {
var box = document.getElementsByName('text')[0];
if(clicks === 0){
var newcsv = "";
var tds = document.getElementsByTagName("TD");
for(var i = 0; i < tds.length; i++)
{
newcsv += tds[i].innerHTML;
if(i != tds.length-1) newcsv += ",";
}
box.value = newcsv;
clicks++;
}
else{
clicks = 0;
box.value = "";
}
}
This is bound to onclick event of a button.
Assign id to input
<input type=text id="textbox"/>
Just loop though table
var table = document.getElementById("mytab1");
var textbox=document.getElementById("textbox")
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
if(textbox.value=="")
{
textbox.value=row.cells[j].innerText;
}
else
{
textbox.value+= textbox.value+','+row.cells[j].innerText;
}
}
}

Categories