Reputation: 3621
I am using a DataTable in a bootstrap app and it is working great.
You can see the app running at (for example): https://opencalaccess.org/calaccess/filingdate/2022-11-09
But. I have:
<script>
$(document).ready(function () {
$('#filings').DataTable(
{
"columns": [
{"name": "Filing ID", "orderable": true},
{"name": "Filer ID", "orderable": true},
{"name": "Filer Name", "orderable": true},
{"name": "Filer Type", "orderable": true},
{"name": "Period", "orderable": true},
{"name": "Form", "orderable": true},
{"name": "Amounts", "orderable": false},
{"name": "Rpt Covers", "orderable": false}
]
}
);
});
</script>
And, like I said, it works great. But I want to sort of the Amounts column also.
But the Amounts column is actually put together from several possible values. I would like to sort on the sum of those values, but I do not need to display the sum of those values.
So, say I have two rows:
<tr>
<td>col1</td>
<td>
thing1: 100,
thing2: 100,
thing3: 200
<div style="visibility: hidden;">sum: 400</div>
</td>
</tr>
<tr>
<td>col1</td>
<td>
thing1: 100,
thing2: 1000
<div style="visibility: hidden;">sum: 1100</div>
</td>
</tr>
I would like to have the standard sort buttons on the column, but I want them to sort on the sum value in each row.
Possible?
I see things to try that might work but they all seem very awkward and ugly.
FYI, the versions of the libraries that I am using are:
https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js
Is this relevant? In DataTable, how to sort a column by partial value? Is jquery DataTable the same as the bootstrap DataTable?
What ended up working. The cell contents are:
This is a bit tricky to test. The cell now looks like:
<td style = "white-space: nowrap;">
<div style="visibility: hidden;">5898748</div>
debt-amt_incur: $38,001.00<br/>
debt-amt_paid: $4,824.00<br/>
expn-amount: $271,681.00<br/>
rcpt-amount: $234,479.00<br/>
smry-amount_a: $3,662,227.00<br/>
smry-amount_b: $1,362,306.00<br/>
splt-elec_amount: $325,230.00<br/>
</td>
and the final js is:
{"name": "Amounts",
"render": function(data, type, row, meta) {
if (type === 'display' || type === 'filter') {
return data;
}
else { // type is 'sort' in this case:
return Number($.parseHTML(data)[0].innerHTML);
}
}
},
Upvotes: 1
Views: 337
Reputation: 21993
Here is an example approach using a column render function and orthogonal data.
It uses similar table data to the data provided in the question.
$(document).ready(function() {
$('#filings').DataTable({
columns: [{
name: "Col One",
},
{
name: "Col Two",
render: function(data, type, row, meta) {
if (type === 'display' || type === 'filter') {
return data;
}
else { // type is 'sort' in this case:
let sum = Number($.parseHTML(data)[1].innerHTML.split(':')[1]);
return sum;
}
}
}
]
});
});
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/dataTables.bootstrap.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.13.1/js/dataTables.bootstrap.js"></script>
</head>
<body>
<div style="margin: 20px;">
<table id="filings" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Col One</th>
<th>Col Two</th>
</tr>
</thead>
<tbody>
<tr>
<td>col1b</td>
<td>
thing1: 100, thing2: 200, thing3: 200
<div style="visibility: hidden;">sum: 500</div>
</td>
</tr>
<tr>
<td>col1a</td>
<td>
thing1: 100, thing2: 1000
<div style="visibility: hidden;">sum: 1100</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
The demo uses this:
let sum = Number($.parseHTML(data)[1].innerHTML.split(':')[1]);
to extract the sum value from each hidden <div>
. It's just for demo purposes, to show you the approach. I am sure there are more robust approaches. And this only works for the very specific sample data provided in the question.
Reference: parseHTML
Upvotes: 1