Reputation: 23
I have HTML table data I want to search records from the table and then highlight specifically selected row using the up and down arrow keys. my code works well if not using the search function or at the start when all table data load. but when I search record it still checks all table indexes. for example, the total records in the table are 10 when I search for something and get 2 records first record is on the 5th index and the second record on the 9th index. I need to press 5 times down arrow key to highlight 5th index record instead of 1 and then press the down arrow 4 times instead of 1 to highlight the 9th index of the table. please guide me on how to do this. here is my code
$(function() {
const UP = 38;
const DOWN = 40;
const ARROWS = [UP, DOWN];
const HIGHLIGHT = 'highlight_row';
let $table = $('.child-div');
$('#searchbar').on('input keydown', function(e) {
$table = $('.child-div');
let key = e.which;
if (ARROWS.includes(key)) {
let selectedRow = -1;
let $rows = $table.find('tr');
$rows.each(function(i, row) {
if ($(row).hasClass(HIGHLIGHT)) {
selectedRow = i;
}
});
if (key == UP && selectedRow > 0) {
$rows.removeClass(HIGHLIGHT);
$rows.eq(selectedRow - 1).addClass(HIGHLIGHT);
} else if (key == DOWN && selectedRow < $rows.length - 1) {
$rows.removeClass(HIGHLIGHT);
$rows.eq(selectedRow + 1).addClass(HIGHLIGHT);
}
$(document).on('keypress',function(e) {
if(e.which == 13) {
alert($rows[selectedRow].cells[1].innerText);
}
});
}
});
});
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("searchbar");
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) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
.highlight_row {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<input type="text" onkeyup="myFunction()" class="form-control form-rounded rounded-pill"
placeholder="Text input" id="searchbar">
<table id="myTable" class="table child-div" >
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<th scope="row">3</th>
<td>farry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<th scope="row">3</th>
<td>marry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<th scope="row">3</th>
<td>narry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
Upvotes: 0
Views: 1259
Reputation: 394
I think some little, but key changes needed. In my opinion easier to use classes, because jquery selector fill out unnecessary elements.
Eg:
.hidden {
display:none;
}
After that change:
tr[i].style.display = "";
to
$(tr[i]).removeClass("hidden");
and
tr[i].style.display = "none";
to
$(tr[i]).addClass("hidden");
This add and remove the hidden class which hide your "bad" tr-s. And change:
let $rows = $table.find('tr');
to
let $rows = $table.find('tbody tr:not(".hidden")');
This will only select the visible tr elements.
The whole code found here:
$(function() {
const UP = 38;
const DOWN = 40;
const ARROWS = [UP, DOWN];
const HIGHLIGHT = 'highlight_row';
let $table = $('.child-div');
var pressed = false;
$('#searchbar').on('input keydown', function(e) {
$table = $('.child-div');
let key = e.which;
if (ARROWS.includes(key)) {
let selectedRow = -1;
//let $rows = $table.find('tr');
let $rows = $table.find('tbody tr:not(".hidden")');
$rows.each(function(i, row) {
if ($(row).hasClass(HIGHLIGHT)) {
selectedRow = i;
}
});
if (key == UP && selectedRow > 0) {
$rows.removeClass(HIGHLIGHT);
$rows.eq(selectedRow - 1).addClass(HIGHLIGHT);
} else if (key == DOWN && selectedRow < $rows.length - 1) {
$rows.removeClass(HIGHLIGHT);
$rows.eq(selectedRow + 1).addClass(HIGHLIGHT);
}
$(".input-element").on('keyup',function(e) {
if(e.which == 13 && pressed == false) {
alert($table.find("tbody tr.highlight_row td:first").html());
pressed = true;
setTimeout(function() {
pressed = false;
}, 500);
}
});
}
});
});
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("searchbar");
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) {
$(tr[i]).removeClass("hidden");
} else {
$(tr[i]).addClass("hidden");
}
}
}
}
.highlight_row {
background-color: red;
}
.hidden {
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<input type="text" onkeyup="myFunction()" class="input-element form-control form-rounded rounded-pill"
placeholder="Text input" id="searchbar">
<table id="myTable" class="table child-div" >
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<th scope="row">3</th>
<td>farry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<th scope="row">3</th>
<td>marry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<th scope="row">3</th>
<td>narry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
Upvotes: 2