Bootstrap: data-sort on dynamic table - javascript

I have a bootstrap table as follows:
<table id="fullDataTable"
class="table table-bordered"
data-toggle="table"
data-classes="table"
data-striped="true"
data-sort-name="numFrame"
data-sort-order="desc">
<thead>
<tr>
<th class="col-sm-1"
data-field="numFrame"
data-sortable="true">numFrame</th>
<th class="col-sm-1"
data-field="timeStamp"
data-sortable="false">timeStamp</th>
<th class="col-sm-1"
data-field="id_robot"
data-sortable="false">idRobot</th>
</tr>
</thead>
<tbody id="dataTable">
</tbody>
</table>
The table is then filled dynamically with values from a MySQL database with Javascript:
socket.on('gotDataQuality', function(message) {
if(message == 0){
alert('No Quality datas for this session');
clearElement("dataTable");
}else{
clearElement("dataTable");
for (var i = message.length-1; i >= 0; i--) {
$('#dataTable').prepend('<tr><td>'+message[i].numFrame+'</td><td>'+message[i].timeStamp+ '</td><td>'+message[i].idRobot+'</td></tr>');
}
}
});
The table fills correctly but when I attempt to sort it (by clicking on one of the sortable headers) the contents of the table is erased. I'm not entirely sure how the data-sort element works, what can I do to resolve this?

You can use List JS
You can make use of this example
var options = {
valueNames: [ 'id', 'firstname', 'lastname','username' ]
};
var userList = new List('table', options);
.table [data-sort] {
cursor: pointer;
}
.table [data-sort]::after {
margin-left: .25rem;
content: url('data:image/svg+xml;utf8,<svg width=\'6\' height=\'10\' viewBox=\'0 0 6 10\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'><path fill-rule=\'evenodd\' clip-rule=\'evenodd\' d=\'M3 0L6 4H0L3 0ZM3 10L0 6H6L3 10Z\' fill=\'%238898aa\'/></svg>');
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<div id="table">
<table class="table">
<thead>
<tr>
<th scope="col" class="sort" data-sort="id">#</th>
<th scope="col" class="sort" data-sort="firstname">First Name</th>
<th scope="col" class="sort" data-sort="lastname">Last Name</th>
<th scope="col" class="sort" data-sort="username">Username</th>
</tr>
</thead>
<tbody class="list">
<tr>
<th scope="row" class="id">1</th>
<td class="firstname">Mark</td>
<td class="lastname">Otto</td>
<td class="username">#mdo</td>
</tr>
<tr>
<th scope="row" class="id">2</th>
<td class="firstname">Jacob</td>
<td class="lastname">Thornton</td>
<td class="username">#fat</td>
</tr>
<tr>
<th scope="row" class="id">3</th>
<td class="firstname">Larry</td>
<td class="lastname">the Bird</td>
<td class="username">#twitter</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
CodePen

Related

js vanilla on click delegate on tr of a table

I'm trying to find on click a data attribute from the tr element of a table with the delegated click event, but it doesn't return anything, what am I wrong?
I made a fiddle to try and test
document.querySelector('table#listaCar tbody').addEventListener('click', e => {
if (e.target.matches(".car-item")) {
alert(e.target.getAttribute('data-id-car'));
}
});
table#listaCar tbody tr {
cursor: pointer;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="listaCar" class="table table-bordered table-hover bg-white">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Status</th>
<th scope="col">Date</th>
<th scope="col">N. IUV</th>
</tr>
</thead>
<tbody>
<tr data-id-car="4140" class="car-item">
<td>4140</td><td>TO PAY</td><td>13-05-2022</td><td>10</td>
</tr>
<tr data-id-car="4129" class="car-item">
<td>4129</td><td>TO PAY</td><td>12-05-2022</td><td>15</td>
</tr>
</tbody>
</table>
e.target is the td, not the tr.
Easiest solution is to use .parentNode to get the td's parent: the tr then you can test using matches and get the data attribute as desired
const tr = e.target.parentNode;
if (tr.matches(".car-item")) {
alert(tr.getAttribute('data-id-car'));
}
document.querySelector('table#listaCar tbody').addEventListener('click', e => {
const tr = e.target.parentNode;
if (tr.matches(".car-item")) {
alert(tr.getAttribute('data-id-car'));
}
});
table#listaCar tbody tr {
cursor: pointer;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="listaCar" class="table table-bordered table-hover bg-white">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Status</th>
<th scope="col">Date</th>
<th scope="col">N. IUV</th>
</tr>
</thead>
<tbody>
<tr data-id-car="4140" class="car-item">
<td>4140</td><td>TO PAY</td><td>13-05-2022</td><td>10</td>
</tr>
<tr data-id-car="4129" class="car-item">
<td>4129</td><td>TO PAY</td><td>12-05-2022</td><td>15</td>
</tr>
</tbody>
</table>
You need to do a test on the element click to see if it is a table cell (TD) and if it is grab the parent.
In my example I am looping through all the rows to apply the click.
document.querySelectorAll('.car-item').forEach(item => {
item.addEventListener('click', e => {
let el = e.target.tagName === "TD" ? e.target.parentElement : e.target;
alert(el.getAttribute('data-id-car'));
});
});
table#listaCar tbody tr {
cursor: pointer;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="listaCar" class="table table-bordered table-hover bg-white">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Status</th>
<th scope="col">Date</th>
<th scope="col">N. IUV</th>
</tr>
</thead>
<tbody>
<tr data-id-car="4140" class="car-item">
<td>4140</td><td>TO PAY</td><td>13-05-2022</td><td>10</td>
</tr>
<tr data-id-car="4129" class="car-item">
<td>4129</td><td>TO PAY</td><td>12-05-2022</td><td>15</td>
</tr>
</tbody>
</table>

How to delete table rows uisng javascript

I want to delete every row from the table using javascirpt Here's the code
I tried using .remove function but it did'nt work out...
HTML TABLE CODE
<div class="card-body">
<table class="table text-center">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Total</th>
<th scope="col">Reaming Paid</th>
<th scope="col">To Be Paid</th>
</tr>
</thead>
<tbody id="table_body">
<tr>
<td>2</td>
<td> mess fee </td>
<td> 2500 </td>
<td>0 </td>
<td> <input type="number" id="remaing_amount" name="remaing_amount[]" class="form-control" placeholder="Enter Paid Amount"></td>
</tr>
</tbody>
</table>
</div>
JAVASCRIPT CODE
if(tablebody.children.length > 0)
{
for (let i = 0; i < tablebody.children.length; i++)
{
tablebody.children[i].remove()
}
}
Explination
This will get all tr (rows) for the tables body.
Then it will delete (remove) any that it finds
Solution
let trs = document.querySelectorAll('#table_body tr');
trs.forEach((tr)=>{
tr.remove();
});
Find all table rows, iterate over them using for of then remove each row with Element.remove().
const rows = document.querySelectorAll("#table_body tr");
for (const row of rows) {
row.remove();
}
<div class="card-body">
<table class="table text-center">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Total</th>
<th scope="col">Reaming Paid</th>
<th scope="col">To Be Paid</th>
</tr>
</thead>
<tbody id="table_body">
<tr>
<td>2</td>
<td>mess fee</td>
<td>2500</td>
<td>0</td>
<td>
<input
type="number"
id="remaing_amount"
name="remaing_amount[]"
class="form-control"
placeholder="Enter Paid Amount"
/>
</td>
</tr>
</tbody>
</table>
</div>
If you want to delete all tr maybe you should do something like this
document.getElementById('table_body').innerHTML = ''
<div class="card-body">
<table class="table text-center">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Total</th>
<th scope="col">Reaming Paid</th>
<th scope="col">To Be Paid</th>
</tr>
</thead>
<tbody id="table_body">
<tr>
<td>2</td>
<td> mess fee </td>
<td> 2500 </td>
<td>0 </td>
<td> <input type="number" id="remaing_amount" name="remaing_amount[]" class="form-control" placeholder="Enter Paid Amount"></td>
</tr>
</tbody>
</table>
</div>
Try this way...
const tBody = document.querySelector('#table_body');
const tRow =document.querySelector('#table_body tr')
if (tBody.contains(tRow) {
tRow.remove();
}
try this code:
<div class="card-body">
<table class="table text-center">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Total</th>
<th scope="col">Reaming Paid</th>
<th scope="col">To Be Paid</th>
</tr>
</thead>
<tbody id="table_body">
<tr id = "row1">
<td>2</td>
<td> mess fee </td>
<td> 2500 </td>
<td>0 </td>
<td> <input type="number" id="remaing_amount" name="remaing_amount[]" class="form-control" placeholder="Enter Paid Amount"></td>
</tr>
</tbody>
</table>
<button onclick = "deletetr()">
Click here
</button>
<script>
function deletetr() {
document.getElementById("row1").remove();
}
</script>
</div>

How to populate a table td

I've created a table and I need to populate the tds using JavaScript because the data is coming from the server.
Here is my table:
<table id="report" class="infoRecurso" id='testExportId' style="width: 100%; color: #363636">
<thead style="color: #363636">
<tr class='btn-danger' style="background-color: lightgray; color: #363636">
<th class="thData">Data</th>
<th id="timeIniticial" class="thInicio">Início</th>
<th class="thTermino">Término</th>
<th class="thDuracao">Duração</th>
<th class="thAtividades">Atividades</th>
</tr>
</thead>
<tbody id="myTable">
<tr>
<td style="text-align: left;"></td>>
<td id="inicialTime"></td>
<td>Hora Final</td>
<td style="text-align: left;">Duração</td>
<td colspan="1" class="quebraLinha" style="text-align: left;"></td>
</tr>
<tr>
<th class="horasTotaisTh" colspan="3"> Horas Totais </th>
<th class="resultadoHorasTotaisTh" colspan="4">Hora Total</th>
</tr>
</tbody>
I am trying to populate the td with the id inicialTime that is corresponding to the tr timeIniticial. I've tried using this code:
var data = [{"product": "RD0"}, {"product": "RD1-184"}, {"product": "RD1-185"}];
var table = $('.infoRecurso');
$.each(data, function(i, value) {
table.find('tr').eq(i).find("td[id='inicialTime']").text(value.product);
});
but this code only populates the first position.
How can I populate the rest of tds positions?
Your question leaves a few points open, so I can only guess what you really want. In the following snippet I have compiled a solution that will .prepend() some html code to your table, to the effect that your second column is always filled with the code from your data array. I changed the id attribute of this <td> element to class since IDs must always be unique.
I also "corrected" your colspan attributes of the last table row since there are only 5 columns in total.
var data = [{"product": "RD0"}, {"product": "RD1-184"}, {"product": "RD1-185"}];
var html=data.map(({product})=>
`<tr><td></td><td class="inicialTime">${product}</td><td>Hora Final</td>
<td>Duração</td><td class="quebraLinha"></td></tr>`).join('')
$('.infoRecurso tbody').prepend(html);
td {text-align:left}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="report" class="infoRecurso" id='testExportId' style="width: 100%; color: #363636">
<thead style="color: #363636">
<tr class='btn-danger' style="background-color: lightgray; color: #363636">
<th class="thData">Data</th>
<th class="thInicio">Início</th>
<th class="thTermino">Término</th>
<th class="thDuracao">Duração</th>
<th class="thAtividades">Atividades</th>
</tr>
</thead>
<tbody id="myTable">
<tr>
<th class="horasTotaisTh" colspan="3"> Horas Totais </th>
<th class="resultadoHorasTotaisTh" colspan="2">Hora Total</th>
</tr>
</tbody>

How to change bootstrap-table row background?

If the result is "good", I want the entire row to turn green. But it does not change anything.
https://jsfiddle.net/Tonato_/tnw3j5p2/7/
Here is the code.
I do not realize at all what is the problem. I think I did it all correctly.
function rowStyle(row, index) {
const obj = {};
var classes = ['active', 'success', 'info', 'warning', 'danger'];
if (Object.keys(row).map(key => row[key]).some(value => String(value).includes('BAD'))) {
return Object.assign({}, obj, {
classes: 'danger'
});
}
if (Object.keys(row).map(key => row[key]).some(value => String(value).includes('GOOD'))) {
return Object.assign({}, obj, {
classes: 'success'
});
}
return obj;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/css/bootstrap.min.css" rel="stylesheet" />
<table data-row-style="rowStyle" class="table table-bordered table-hover thead-dark thead-inverse">
<thead>
<tr>
<th scope="col" style="width: 8%" class="text-center">Number</th>
<th scope="col" style="width: 20%" class="text-center">Name</th>
<th scope="col" style="width: 61%" class="text-center">Present</th>
<th scope="col" style="width: 10%" class="text-center">Result</th>
</tr>
</thead>
<tr>
<td class="text-center">01</td>
<td class="text-center">$title01</td>
<td>$present01</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
<tr>
<td class="text-center">02</td>
<td class="text-center">$title02</td>
<td>$present02</td>
<td scope="row" class="text-center">BAD</td>
</tr>
<tr>
<td class="text-center">03</td>
<td class="text-center">$title03</td>
<td>$present03</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
</table>
You can achieve it by using simple jQuery code, Run the snippet below
$('table tr').each(function() {
if($(this).find('td:last-child').html() === 'GOOD'){
$(this).css('background-color', 'green');
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table data-row-style="rowStyle" class="table table-bordered table-hover thead-dark thead-inverse">
<thead>
<tr>
<th scope="col" style="width: 8%" class="text-center">Number</th>
<th scope="col" style="width: 20%" class="text-center">Name</th>
<th scope="col" style="width: 61%" class="text-center">Present</th>
<th scope="col" style="width: 10%" class="text-center">Result</th>
</tr>
</thead>
<tr>
<td class="text-center">01</td>
<td class="text-center">$title01</td>
<td>$present01</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
<tr>
<td class="text-center">02</td>
<td class="text-center">$title02</td>
<td>$present02</td>
<td scope="row" class="text-center">BAD</td>
</tr>
<tr>
<td class="text-center">03</td>
<td class="text-center">$title03</td>
<td>$present03</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
</table>
I just update your code with few jQuery changes. Try this I hope it'll help you out. Thanks
$(document).ready(function() {
$('.table tr td').each(function(i, v){
if(v.textContent === 'GOOD') {
$(v.parentElement).addClass('table-success');
} else if(v.textContent === 'BAD') {
$(v.parentElement).addClass('table-danger');
}
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/css/bootstrap.min.css" rel="stylesheet" />
<table data-row-style="rowStyle" class="table table-bordered table-hover thead-dark thead-inverse">
<thead>
<tr>
<th scope="col" style="width: 8%" class="text-center">Number</th>
<th scope="col" style="width: 20%" class="text-center">Name</th>
<th scope="col" style="width: 61%" class="text-center">Present</th>
<th scope="col" style="width: 10%" class="text-center">Result</th>
</tr>
</thead>
<tr>
<td class="text-center">01</td>
<td class="text-center">$title01</td>
<td>$present01</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
<tr>
<td class="text-center">02</td>
<td class="text-center">$title02</td>
<td>$present02</td>
<td scope="row" class="text-center">BAD</td>
</tr>
<tr>
<td class="text-center">03</td>
<td class="text-center">$title03</td>
<td>$present03</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
</table>
First add an id to the table, and then wrap the tr with <tbody>.
<table id='my-table' data-row-style="rowStyle" class="table table-bordered table-hover thead-dark thead-inverse">
<thead>
<tr>
<th scope="col" style="width: 8%" class="text-center">Number</th>
<th scope="col" style="width: 20%" class="text-center">Name</th>
<th scope="col" style="width: 61%" class="text-center">Present</th>
<th scope="col" style="width: 10%" class="text-center">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">01</td>
<td class="text-center">$title01</td>
<td>$present01</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
<tr>
<td class="text-center">02</td>
<td class="text-center">$title02</td>
<td>$present02</td>
<td scope="row" class="text-center">BAD</td>
</tr>
<tr>
<td class="text-center">03</td>
<td class="text-center">$title03</td>
<td>$present03</td>
<td scope="row" class="text-center">GOOD</td>
</tr>
</tbody>
</table>
Then by jQuery use can loop through each tr of tbody in your table. Then based on your result, add css to that row.
$('#my-table tbody tr').each(function(i, item){
var result = $(item).find('td').last().text();
if(result === 'GOOD') $(item).css('background-color', 'green');
else $(item).css('background-color', 'red');
})

Loop table to even row amount in JQuery

The question I have a table pulling from the backend for events, will list out in the font in 3 different column with specific categories, but sometimes only have 1 event or 2, but I need to at least display 3 items.
So I try to use jQuery each function to check how many rows in the table if only have 1 add 2 rows if only have 1 row add 2 instead.
So the table will be same height no matter how many events display.
My code doesn't work correctly, so I was hoping anyone can help me out with this.
Here's my sample code:http://jsfiddle.net/s2devfrg/
Here's the jQuery:
jQuery(function(){
jQuery('#table-amount tbody').each(function(){
let number =jQuery(this).find('tr').length;
console.log('amount' + number);
//if table only have one add two extra row
if(number === 1){
jQuery(this).append("<tr> </tr>");
jQuery(this).append("<tr> </tr>");
} else {
//if table only have two add one roe
if(number === 2 ){
jQuery(this).append("<tr> </tr>");
}
}
})
})
The selector you are using on .each is wrong. There are no elements with the passed id.
Also there are couple of blank tr's in your html which I have removed.
Try this code below:
jQuery(function(){
jQuery(".table tbody").each(function(){
let number =jQuery(this).find('tr').length;
console.log('amount' + number);
//if table only have one add two extra row
if(number === 1){
jQuery(this).append("<tr><td> </td></tr><tr><td> </td></tr");
} else if(number === 2 ){
jQuery(this).append("<tr><td> </td></tr>");
}
})
})
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<div class="container">
<div class="row">
<div class="col">
<table class="table">
<thead class="table-amount">
<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>
</tbody>
</table>
</div>
<div class="col">
<table class="table">
<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>
</tbody>
</table>
</div>
<div class="col">
<table class="table">
<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>
</tbody>
</table>
</div>
</div>
</div>
Updated fiddle link
I have reviewed you sample code, first of all kindly note that in jQuery
when you find tr it will count total number of rows including tr inside thead.
So your
total counts are always one more than actual rows.
Second thing you should not append just tr you should provide same structure
as in
your existing rows.
Also in first table structure you had one extra th may be typo.
In first and third table structure you have one tr extra with empty
structure
instead, you should have same structure as you have for others.
here is the link for modified JS Fiddle link
https://jsfiddle.net/patelmurtuza/kj8zgqad/

Categories