In my Django project I have a table which datas coming from database. There can be hundreds of rows. I can't display all in one page. I want to display my tables 10 rows for each. I got two buttons for next and previous rows. Can I do this with jquery or some python code?
index.html
<table class="table" border=1>
<thead>
<tr>
<th>Full Name</th>
<th>Company</th>
<th>Email</th>
<th>Phone Number</th>
<th>Note</th>
<th>ID</th>
<th>Item Barcode</th>
</tr>
</thead>
<tbody>
{% for x in thelist %}
<tr>
<td>{{x.full_name}}</td>
<td>{{x.company}}</td>
<td>{{x.email}}</td>
<td>{{x.phone_number}}</td>
<td>{{x.note}}</td>
<td>{{x.id}}</td>
<td>{{x.item_barcode}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="button" class="btn btn-primary" name="button">Next</button>
<button type="button" class="btn btn-primary" name="button">Previous</button>
You can use bootstart datatables for this:
<link rel="stylesheet" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">
<table class="table" border=1 id='mydatatable'>
<thead>
<tr>
<th>Full Name</th>
<th>Company</th>
<th>Email</th>
<th>Phone Number</th>
<th>Note</th>
<th>ID</th>
<th>Item Barcode</th>
</tr>
</thead>
<tbody>
{% for x in thelist %}
<tr>
<td>{{x.full_name}}</td>
<td>{{x.company}}</td>
<td>{{x.email}}</td>
<td>{{x.phone_number}}</td>
<td>{{x.note}}</td>
<td>{{x.id}}</td>
<td>{{x.item_barcode}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<script src='https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js'></script>
<script>
$(document).ready(function () {
$('#mydatatable').DataTable();
});
</script>
For More information you can refer https://datatables.net/
You could use the rowIndex and two classes (for example .active and .visible) for the first visible row and the styling via CSS:
If there is no class .active add it to the first row:
if (!document.querySelector('.active')) {
table_rows[0].classList.add('active');
}
In the next step (at best in a separate function, for example showRows()) remove the class .visible from all rows and then add it to so many rows like you defined with the constant visible_rows, beginning with the active row:
function showRows() {
let active_row = document.querySelector('.active');
for (i = 0; i < table_rows.length; i++) {
table_rows[i].classList.remove('visible');
}
for (i = 0; i < visible_rows; i++) {
active_row.classList.add('visible');
if (active_row.nextElementSibling) {
active_row = active_row.nextElementSibling;
}
}
}
In the event handlers for #next and #previous just move the class .active by the number of visible rows, if there are rows left in that direction, and call the function showRows():
document.querySelector('#next').addEventListener('click', function() {
const active_row = document.querySelector('.active');
const active_index = active_row.rowIndex;
if (table_rows.length > active_index + visible_rows - 1) {
active_row.classList.remove('active');
table_rows[active_index + visible_rows - 1].classList.add('active');
showRows();
}
});
document.querySelector('#prev').addEventListener('click', function() {
const active_row = document.querySelector('.active');
const active_index = active_row.rowIndex;
if (active_index > 1) {
active_row.classList.remove('active');
table_rows[active_index - visible_rows - 1].classList.add('active');
showRows();
}
});
Working example:
const visible_rows = 2;
const table_rows = document.querySelectorAll('tbody tr');
if (!document.querySelector('.active')) {
table_rows[0].classList.add('active');
}
function showRows() {
let active_row = document.querySelector('.active');
for (i = 0; i < table_rows.length; i++) {
table_rows[i].classList.remove('visible');
}
for (i = 0; i < visible_rows; i++) {
active_row.classList.add('visible');
if (active_row.nextElementSibling) {
active_row = active_row.nextElementSibling;
}
}
}
document.querySelector('#next').addEventListener('click', function() {
const active_row = document.querySelector('.active');
const active_index = active_row.rowIndex;
if (table_rows.length > active_index + visible_rows - 1) {
active_row.classList.remove('active');
table_rows[active_index + visible_rows - 1].classList.add('active');
showRows();
}
});
document.querySelector('#prev').addEventListener('click', function() {
const active_row = document.querySelector('.active');
const active_index = active_row.rowIndex;
if (active_index > 1) {
active_row.classList.remove('active');
table_rows[active_index - visible_rows - 1].classList.add('active');
showRows();
}
});
showRows();
tbody tr:not(.visible) {
display: none;
}
<table class="table" border=1>
<thead>
<tr>
<th>Full Name</th>
<th>Company</th>
<th>Email</th>
<th>Phone Number</th>
<th>Note</th>
<th>ID</th>
<th>Item Barcode</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>1</td>
<td>D</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>E</td>
<td>F</td>
<td>G</td>
<td>4</td>
<td>H</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>I</td>
<td>J</td>
<td>K</td>
<td>7</td>
<td>L</td>
<td>8</td>
<td>9</td>
</tr>
</tbody>
</table>
<button id="next" type="button" class="btn btn-primary" name="button">Next</button>
<button id="prev" type="button" class="btn btn-primary" name="button">Previous</button>
Related
I am trying to add Price from table column to a total.
I am having problem adding values such as 10.00 or 5.99. I am able to calculate prices with int values, but not with values 10.00 or 5.99, etc.
Here is what I have below.
var table = document.getElementById("myTable"),
sumVal = 0;
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseF(table.rows[i].cells[2].innerHTML);
}
document.getElementById("val").innerHTML = "SubTotal =" + sumVal;
console.log(sumVal);
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoddie</td>
<td class="count-me">15.00</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
</table>
<span id="val"></span>
You have three issues:
You are grabbing the wrong cell index, indices start at 0:
table.rows[i].cells[1]
You need to call the correct parse function:
parseFloat(table.rows[i].cells[1].innerHTML);
You need to format your output:
"SubTotal = $" + sumVal.toFixed(2);
Update: Added functionality for removing rows.
updateSubTotal(); // Initial call
function updateSubTotal() {
var table = document.getElementById("myTable");
let subTotal = Array.from(table.rows).slice(1).reduce((total, row) => {
return total + parseFloat(row.cells[1].innerHTML);
}, 0);
document.getElementById("val").innerHTML = "SubTotal = $" + subTotal.toFixed(2);
}
function onClickRemove(deleteButton) {
let row = deleteButton.parentElement.parentElement;
row.parentNode.removeChild(row);
updateSubTotal(); // Call after delete
}
#myTable td {
padding: 0.25em;
}
#val {
display: block;
margin-top: 0.5em;
}
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoodie</td>
<td class="count-me">15.00</td>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
</table>
<span id="val"></span>
You are accessing the incorrect array element and also need to use parseFloat
The cells array is zero-based so you need to use cells[1] to access the second column:
var table = document.getElementById("myTable"),
sumVal = 0;
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseFloat(table.rows[i].cells[1].innerHTML);
}
document.getElementById("val").innerHTML = "SubTotal =" + sumVal;
console.log(sumVal);
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoddie</td>
<td class="count-me">15.00</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
</table>
<span id="val"></span>
updateSubTotal(); // Initial call
function updateSubTotal() {
var table = document.getElementById("myTable");
let subTotal = Array.from(table.rows).slice(1).reduce((total, row) => {
return total + parseFloat(row.cells[1].innerHTML);
}, 0);
let subTotal2 = Array.from(table.rows).slice(1).reduce((total, row) => {
return total + parseFloat(row.cells[2].innerHTML);
}, 0);
document.getElementById("val").innerHTML = "SubTotal = $" + subTotal.toFixed(2);
document.getElementById("val1").innerHTML = subTotal2.toFixed(2);
}
function onClickRemove(deleteButton) {
let row = deleteButton.parentElement.parentElement;
row.parentNode.removeChild(row);
updateSubTotal(); // Call after delete
}
#myTable td {
padding: 0.25em;
}
#val {
display: block;
margin-top: 0.5em;
}
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>M2</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoodie</td>
<td class="count-me">15.00</td>
<td class="count-me">34.00</th>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td class="count-me">22.34</th>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
</table>
<span id="val"></span>
<span id="val1"></span>
var cell = document.getElementsByClassName("count-me");
var val = 0;
var i = 0;
while (cell[i] != undefined) {
val += parseFloat(cell[i].innerHTML);
i++;
} //end while
document.getElementById("val").innerHTML = parseFloat(val).toFixed(2);
console.log(parseFloat(val).toFixed(2));
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr id="">
<td>Hoddie</td>
<td class="count-me">15.00</td>
<td>
<button onClick="myFunction()">Remove</button>
</td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td>
<button onClick="myFunction()">Remove</button>
</td>
</tr>
</table>
<span id="val"></span>
description cells will starts as hide. The row that I click, will show the description and if i click another row will the current row description and hide the other description
var getTable = document.querySelector("tbody");
var cells = getTable.getElementsByTagName("td");
for (let item of document.getElementsByClassName("desc")) {
item.style.display = "none";
}
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener("click", function () {
var selectedRow =
getTable.getElementsByTagName("tr")[this.parentNode.rowIndex];
if (!this.parentNode.rowIndex) {
$(selectedRow).find(".desc").css("display", "none");
} else {
$(selectedRow).find(".desc").css("display", "block");
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblInventory">
<thead>
<tr>
<th>UPC</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>987456</td>
<td>Product Blanks</td>
<td class="desc">Unfinished template for parts 1000222 to 1000299</td>
</tr>
<tr>
<td>654123</td>
<td>Threaded Rods</td>
<td class="desc">Rods threaded at both ends for Support Brackets</td>
</tr>
</tbody>
</table>
Try this in vanilla:
document.querySelector('#tblInventory').addEventListener('click', (e) =>
{
// Hide other descriptions
document.querySelectorAll('#tblInventory td.desc span').forEach(span => {
span.style.display = 'none';
});
// Show clicked row description
if (e.target.tagName === 'TD') {
e.target.parentNode.querySelector('td.desc span').style.display = 'inline';
}
});
#tblInventory td.desc span {
display: none
}
<table id="tblInventory">
<thead>
<tr>
<th>UPC</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>987456</td>
<td>Product Blanks</td>
<td class="desc"><span>Unfinished template for parts 1000222 to 1000299</span></td>
</tr>
<tr>
<td>654123</td>
<td>Threaded Rods</td>
<td class="desc"><span>Rods threaded at both ends for Support Brackets</span></td>
</tr>
</tbody>
</table>
Or with jQuery:
$('#tblInventory').on('click', 'td', (e) => {
// Hide other descriptions
$('#tblInventory td.desc span').hide();
// Show clicked row description
$(e.target).closest('tr').find('td.desc span').show();
});
#tblInventory td.desc span {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table id="tblInventory">
<thead>
<tr>
<th>UPC</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>987456</td>
<td>Product Blanks</td>
<td class="desc"><span>Unfinished template for parts 1000222 to 1000299</span></td>
</tr>
<tr>
<td>654123</td>
<td>Threaded Rods</td>
<td class="desc"><span>Rods threaded at both ends for Support Brackets</span></td>
</tr>
</tbody>
</table>
Using span is a suggestion, but you can fix the selectors to show/hide the td elements directly as well;
If you don't want to hide previous clicked descriptions, just remove the related code.
In my web application, I have created table and assigned values for table from controller.
Here I want to show the total of column value Amount at the end of table.
So I have done this so far but It didn't show the total value.
var tds = document.getElementById('PayvouchDt').getElementsByTagName('td');
var sum = 0;
for (var i = 0; i < tds.length; i++) {
sum += parseInt(tds[i].cells[3].innerHTML);
}
document.getElementById('PayvouchDt').innerHTML += '<tr><td>' + sum + '</td><td>Total Value</td></tr>';
<table class="table table-striped" id="PayvouchDt">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Cost Center</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
#{int RowNo = 0;} #for (int i = 0; i
< Model.First().PaymentVouchDetails.Count; i++) { <tr>
<td>#{RowNo++;} #RowNo</td>
<td>#Html.DisplayFor(Model => Model.First().PaymentVouchDetails[i].Details)</td>
<td>#Html.DisplayFor(Model => Model.First().PaymentVouchDetails[i].CostCenter)</td>
<td class="count-me">Rs.#Html.DisplayFor(Model => Model.First().PaymentVouchDetails[i].Amount)</td>
</tr>
}
</tbody>
</table>
You need the rows. The cells do not have cells
Also an amount normally have decimals so we need them as floats instead of ints
var trs = document.getElementById('PayvouchDt').getElementsByTagName('tr');
var sum = 0;
for (var i = 0; i < trs.length; i++) {
sum += parseFloat(trs[i].cells[3].textContent);
}
document.getElementById('PayvouchDt').innerHTML += '<tr><td>' + sum.toFixed(2) + '</td><td>Total Value</td></tr>';
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Cost Center</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="PayvouchDt">
<tr>
<td>1</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">1.50</td>
</tr>
<tr>
<td>2</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">3.20</td>
</tr>
</tbody>
</table>
I suggest to use the tbody and a reduce on the converted textContent
const tds = document.querySelectorAll('#PayvouchDt tr td.count-me'); // or td:nth-child(4)
const sum = [...tds].map(td => +td.textContent).reduce((a, b) => a + b)
document.getElementById('PayvouchDt').innerHTML += `<tr><td>${sum.toFixed(2)}</td><td>Total Value</td></tr>`;
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Cost Center</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="PayvouchDt">
<tr>
<td>1</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">1.50</td>
</tr>
<tr>
<td>2</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">3.20</td>
</tr>
</tbody>
</table>
you can sum the elements of the array simply using the javascript [reduce method][1].
for example
const myArray = [{value: 1, name: 'john'}, {value: 2, name: 'doe'}, {value: 3, name: 'john'}, {value: 4, name: 'doe'}];
const v = myArray.reduce((tot, el) => tot + el.value, 0);
console.log(v)
you can take this snippet and adapt it to your need
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce?retiredLocale=it
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 4 years ago.
I have a problem here, that when I click the copy button on the recently copied row. It doesnt work. You guys know how to fix this?
This is my code
var controller = function(num1) {
$('#copy-' + num1).click(function() {
var $tableBody = $('#table_name').find("tbody"),
$trLast = $tableBody.find("#tr-" + num1),
$trNew = $trLast.clone();
// $trNew.find('input').val('');
$trLast.after($trNew);
console.clear()
// refresh_index();
});
}
function refresh_index() {
$('#table_name > tbody > tr').each(function(i) {
i++;
var select = $(this).find('select');
var text = $(this).find('input');
var button = $(this).find('button');
controller(i);
});
}
refresh_index();
This is my code in JSFIDDLE
To attach the click event on dynamically created element use the delegation approach using .on(). This will allow the event to work on the elements those are added in the body at a later time.
Change
$('#copy-' + num1).click(function() {
To
$('body').on('click','#copy-'+num1, function() {
$(function(){
var controller = function(num1){
$('body').on('click','#copy-'+num1, function() {
var $tableBody = $('#table_name').find("tbody"),
$trLast = $tableBody.find("#tr-"+num1),
$trNew = $trLast.clone();
// $trNew.find('input').val('');
$trLast.after($trNew);
console.clear()
// refresh_index();
});
}
function refresh_index(){
$('#table_name > tbody > tr').each(function (i) {
i++;
var select = $(this).find('select');
var text = $(this).find('input');
var button = $(this).find('button');
controller(i);
});
}
refresh_index();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table_name">
<thead>
<tr>
<th>No</th>
<th>Item</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr class="trs" id="tr-1">
<td>1</td>
<td>Mouse</td>
<td><button class="copy" id="copy-1">Copy</button></td>
</tr>
<tr class="trs" id="tr-2">
<td>2</td>
<td>Keyboard</td>
<td><button class="copy" id="copy-2">Copy</button></td>
</tr>
<tr class="trs" id="tr-3">
<td>3</td>
<td>Monitor</td>
<td><button class="copy" id="copy-3">Copy</button></td>
</tr>
</tbody>
</table>
You are adding it after the dom is loaded so it will not find it. If you use the on function to target something that was in the dom before it was dynamically added then add the target in the second variable after "click" then it should work.
$(function(){
var controller = function(num1){
var newThingy = '#copy-' + num1;
$("#table_name").on("click", newThingy, function() {
var $tableBody = $('#table_name').find("tbody"),
$trLast = $tableBody.find("#tr-"+num1),
$trNew = $trLast.clone();
// $trNew.find('input').val('');
$trLast.after($trNew);
console.clear()
// refresh_index();
});
}
function refresh_index(){
$('#table_name > tbody > tr').each(function (i) {
i++;
var select = $(this).find('select');
var text = $(this).find('input');
var button = $(this).find('button');
controller(i);
});
}
refresh_index();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table id="table_name">
<thead>
<tr>
<th>No</th>
<th>Item</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr class="trs" id="tr-1">
<td>1</td>
<td>Mouse</td>
<td><button class="copy" id="copy-1">Copy</button></td>
</tr>
<tr class="trs" id="tr-2">
<td>2</td>
<td>Keyboard</td>
<td><button class="copy" id="copy-2">Copy</button></td>
</tr>
<tr class="trs" id="tr-3">
<td>3</td>
<td>Monitor</td>
<td><button class="copy" id="copy-3">Copy</button></td>
</tr>
</tbody>
</table>
Use delegate event like $tableBody.find('.copy').off('click').on('click',function(){}); and bind click event after cloning the tr better to use class instead of ids. Here is the updated code based on your jsfiddle.
var $tableBody = $('#table_name').find("tbody");
clickEvent();
function clickEvent(){
$tableBody.find('.copy').off('click').on('click',function() {
$trLast = $(this).closest('tr'),
$trNew = $trLast.clone();
$trLast.after($trNew);
clickEvent();
});
function refresh_index(){
$('#table_name > tbody > tr').each(function (i) {
i++;
var select = $(this).find('td').eq(0).text(i);
});
}
refresh_index();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table_name">
<thead>
<tr>
<th>No</th>
<th>Item</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr class="trs" id="tr-1">
<td>1</td>
<td>Mouse</td>
<td><button class="copy" id="copy-1">Copy</button></td>
</tr>
<tr class="trs" id="tr-2">
<td>2</td>
<td>Keyboard</td>
<td><button class="copy" id="copy-2">Copy</button></td>
</tr>
<tr class="trs" id="tr-3">
<td>3</td>
<td>Monitor</td>
<td><button class="copy" id="copy-3">Copy</button></td>
</tr>
</tbody>
</table>
I have an HTML <table> with data. Upon clicking the table rows, I can add the clicked row to another table. But I want to highlight the row with arrow keys and, on pressing the Enter key on the highlighted row, add the data of the highlighted row to the new table.
How can I do that?
What I have tried so far:
$(document).ready(function(){
$('#myTable').focus();
});
function highlight(tableIndex) {
if ((tableIndex + 1) > $('#myTable tbody tr').length) //restart process
tableIndex = 0;
if ($('#myTable tbody tr:eq(' + tableIndex + ')').length > 0) {
$('#myTable tbody tr').removeClass('highlight');
$('#myTable tbody tr:eq(' + tableIndex + ')').addClass('highlight');
}
}
$('#goto_first').click(function() {
highlight(0);
});
$('#goto_prev').click(function() {
highlight($('#myTable tbody tr.highlight').index() - 1);
});
$('#goto_next').click(function() {
highlight($('#myTable tbody tr.highlight').index() + 1);
});
$('#goto_last').click(function() {
highlight($('#myTable tbody tr:last').index());
});
$(document).keydown(function(e) {
switch (e.which) {
case 38:
$('#goto_prev').trigger('click');
break;
case 40:
$('#goto_next').trigger('click');
break;
}
});
$(document).ready(function() {
var items = [];
$("#myTable tr").on('click', function(e) {
var newTr = $(this).closest("tr").clone();
items.push(newTr);
newTr.appendTo($("#cloneTable"));
});
})
<html><head><title>dynamictable</title>
<style>
table { cursor: pointer; }
.highlight { background-color: lightgreen; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<table id="myTable" border="1px" style="width: 30%;">
<thead>
<tr>
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>aaa</td>
<td>aa1</td>
<td>aa</td>
<td>111</td>
</tr>
<tr>
<td>1</td>
<td>aaa</td>
<td>aa1</td>
<td>aa</td>
<td>111</td>
</tr>
</tbody>
</table>
<br>
<br>
<br>
<input type="button" id="goto_first" value="first" class="btn btn-success">
<input type="button" id="goto_prev" value="prev" class="btn btn-secondary">
<input type="button" id="goto_next" value="next" class="btn btn-secondary">
<input type="button" id="goto_last" value="last" class="btn btn-success">
<br>
<br>
<br>
<table id="cloneTable" border="1px" style="width: 30%; float :left;"><!--new table to clone data-->
<thead>
<tr>
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>
Here you go
// highlight first row default
$("#myTable tbody tr:first-child").addClass("highlight");
document.onkeydown = moveAndAdd;
function moveAndAdd(e) {
e = e || window.event;
if (e.keyCode == "38") {
// up arrow
activeRow = $("tr.highlight"); /* get highlighted row */
activeRow.focus();
prevRow = activeRow.prev('tr'); /*very previous siblings*/
if (prevRow.length>0) {
activeRow.removeClass("highlight"); /*remove highlight from active class */
prevRow.addClass("highlight"); /* make very prev row highlighted*/
}
} else if (e.keyCode == "40") {
// down arrow
activeRow = $("tr.highlight"); /* get highlighted row */
activeRow.focus();
nextRow = activeRow.next('tr'); /*very previous siblings*/
if (nextRow.length>0) {
activeRow.removeClass("highlight");
nextRow.addClass("highlight");
}
}
else if (e.which == 13 || e.which == 32) {
// Enter or Spacebar - edit cell
e.preventDefault();
cloneRow = $(".highlight").clone(true); /*clone highlighted row*/
$("#cloneTable").append(cloneRow.removeClass("highlight")); /*append cloned row but remove class */
}
}
table {
color:black;
background-color:white;
}
.highlight{
color:White;
background-color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable" border="1px" style="width: 30%;">
<thead>
<tr >
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
<tr>
<td >1</td>
<td>aaa</td>
<td>aa1</td>
<td>aa</td>
<td>111</td>
</tr>
<tr>
<td>2</td>
<td>bbb</td>
<td>bb2</td>
<td>bb</td>
<td>222</td>
</tr>
<tr>
<td>3</td>
<td>ccc</td>
<td>cc3</td>
<td>cc</td>
<td>333</td>
</tr>
<tr>
<td>4</td>
<td>ddd</td>
<td>dd1</td>
<td>dd</td>
<td>444</td>
</tr>
</tbody>
</table>
<table id="cloneTable" border="1px" style="width: 30%; float :left;">
<thead>
<tr>
<th>##</th>
<th>Name</th>
<th>code</th>
<th>unit</th>
<th>rate</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
I was going to write a custom response but check this out, it addresses your issue: Use arrow keys to navigate an HTML table
You're also missing a closing quotation mark around your "width: 30%" for your opening parent div