How to format a Footer Total in datatables.net - datatables

I have the following function as part of my datatables implementation. It works well to create a total on the bottom of the table for column 7.
"drawCallback": function () {
var api = this.api();
var column = api.column(7);
$(column.footer()).html(
"Total: " + api.column(7, { page: 'current' }).data().sum()
);
My client wants to format the number with a comma thousand separator. On the fields directly I use the built in function.
render: $.fn.dataTable.render.number(',', '.', 2, '')
How do you apply similar to the HTML builder for the footer total.

Why not use Intl.NumberFormat?
new Intl.NumberFormat('en-US').format(api.column(7, { page: 'current' }).data().sum())

Related

How to use gt/le operator in aurelia slickgrid with Odata

I want to send my own operator in odata request and not use the aurelia slickgrid inbuilt "eq" operator.
This is my column definition
{
id: 'LockoutEndDateUtc', name: 'Status', field: 'LockoutEndDateUtc', minWidth: 85, maxWidth: 95,
type: FieldType.boolean,
sortable: true,
formatter: Formatters.multiple,
params: { formatters: [this.StatusFormatter, Formatters.checkmark] },
filterable: true,
filter: {
collection: [
{ value: 'le ' + (() => {const dt = new Date(); return dt.toISOString().split('.')[0] + "Z";})(), label: 'True' },
{ value: 'gt ' + (() => {const dt = new Date(); return dt.toISOString().split('.')[0] + "Z";})(), label: 'False' }
], //['', 'True', 'False'],
model: Filters.singleSelect,//multipleSelect//singleSelect,
}
}
This is the UI
This is how the request filter looks like..
$filter=(LockoutEndDateUtc%20eq%20le%202022-06-28T12%3A59%3A25Z)
If i remove %20eq from the above request, everything else works. So my question is how to i remove %20eq. Or how do i send my own gt, le in the request.
You can't really do that on a boolean filter (you could however do it on a date filter with operator) and I don't think I've added any ways to provide a custom filter search the way you want to do it, but since you're using OData, you have a bit more control and you could change the query string yourself. To be clear, it's not at all recommended to change the OData query string, it's a last solution trick and at your own risk, but for your use case it might be the only way to achieve what you want.
prepareGrid() {
this.gridOptions = {
// ...
backendServiceApi: {
service: new GridOdataService(),
process: (query) => this.getCustomerApiCall(query),
} as OdataServiceApi
};
}
}
getCustomerApiCall(query: string) {
let finalQuery = query;
// in your case, find the boolean value from the column and modify query
// your logic to modify the query string
// untested code, but it would probably look similar
if (query.includes('LockoutEndDateUtc%20eq%20true')) {
// calculate new date and replace boolean with new date
finalQuery = query.replace('LockoutEndDateUtc%20eq%20true', 'LockoutEndDateUtc%20le%202022-06-28T12%3A59%3A25Z');
}
return finalQuery;
}
Another possible solution but requires a bit more work.
If I'd be using a regular grid, without backend service and without access to the query string, I would probably add an external drop down outside of the grid and also add the date column and then control filters in the grid by using dynamic filtering. You can see a demo at Example 23, the principle is that you keep the column's real nature (date in your case) and filter it, if you want something like a "below today's date" then add an external way of filtering dynamically (a button or a drop down) and control the filter dynamically as shown below (from Example 23)

data change doesn't reflect in vue application

In my Vue application I am trying to create a simple table with changeable column sequence. In the data structure I keep all column data with its thead. I use compute to calculate rows from column data using matrix transposion. However any change I do to dynamicTable.columns doesn't reflect in the view.
function transpose(a)
{
return a[0].map(function (_, c) { return a.map(function (r) { return r[c]; }); });
// or in more modern dialect
// return a[0].map((_, c) => a.map(r => r[c]));
}
var tData = {
columns:[
{thead:'isbn',
tdata:[1,2]},
{thead:'name',
tdata:['rose','flower']},
{thead:'price',
tdata:['10','15']},
{thead:'author',
tdata:['john','jane']},
{thead:'page count',
tdata:['396','149']},
{thead:'print date',
tdata:['2001', '1996']}
]
}
var dynamicTable = new Vue({
el: '#dynamicTable',
data: tData,
computed:{
rows: function(){
arr = [];
this.columns.forEach(function(element){
arr.push(element.tdata);
});
return transpose(arr)
}
}
})
For example I want to change the order of isbn column with price,
a=dynamicTable.columns[0]
b=dynamicTable.columns[2]
dynamicTable.columns[0]=b
dynamicTable.columns[1]=a
data changes but changes are not reflected. What is the problem here?
As mentioned in the documentation, this is a JavaScript limitation. Direct changes to an array are not detected by Vue.
One workaround for this, is to use Vue.set(), as instructed in the link.

Sorting by part of a number in datatables

I have a DataTable where my first column is a VIN number.
Example: FLXVU3822G1000013
Now VIN numbers are just a bunch of information tacked together. The last 6 numbers are the sequence number for that year. You can see that this example vehicle is the 13th one of the year. I'd really like to have my list filtered on those last 6 digits. Is there a way to do that?
You can easily solve this by a custom sorting plugin. In fact you just need to extract the last 6 digits and return them as a number, then dataTables will sort the column using the internal number sorting algorithm :
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"last-6-digits-pre": function ( a ) {
var n = a.substring(a.length - 6, a.length)
return parseInt(n)
}
})
Usage :
var table = $('#example').DataTable({
columnDefs : [
{ targets: 0, type: 'last-6-digits' }
]
})
where targets: 0 is the index of the column you want to be sorted this particular way.
See demo -> http://jsfiddle.net/zhmcLkb9/

Filter other columns based on first columns

I'm using jquery data tables and I'm assigning an array of values to the initialization of the data table. The table basically looks like this.
based on an an radio button I would like to limit the items that are display in the table and the items that are searched in the table.
For my example it would be based on the "Chart column". I want to limit the table to only show the items that are based on chart "D" or Chart "S". Here is how I'm initializing the table.
if (!$.fn.DataTable.isDataTable( '#fundLookUptbl' ) ) {
fundTable = $('#fundLookUptbl').DataTable( {
data: funds,
columns: [
{ "mData": "chart" },
{ "mData": "fund" },
{ "mData": "orgDefault" },
{ "mData": "progDefault" }
]
} );
var filteredData = fundTable
.columns( [0, 1] )
.data()
.eq( 0 )
.filter( function ( value, index ) {
return value = 'D' ? true : false;
} );
}
This is obviously not working, and the filterData variable is a lousy attempt on trying to make it work. I'm having a hard time understanding the API's. So the question is , How can initialize the table to only show the items that are based on a given chart. I know that I can remove the items of the array but i don't want to do that since I would simple like to be able to switch between chart "D" and "S" but still continue to search through the other columns.
I believe that filtering the column would solve your problem.
table.column(0).search('Bruno').draw()
So you could just filter the column when the radio button selection change
Here is a fiddle example
I´m not sure to be understanding what you want to do but here are some options:
One way is selecting by default value example "s". You can use a dropdown is easier to handled .Then select with jQuery the dafault value "s" on that dropdown and add a function
$("#DropdownId").change(function () {
var chart=$("#DropdownId").val();
});
$.ajax({
url: "url")",//url to reload page with new value
type: "POST",
data: {chart:chart},
success: function (data) {
}
});
});
on this way the filter is on backend. If you want to do something on the row depending of a column value you shoud to add something like this
"fnRowCallback": function (nRow, mData, iDisplayIndex, iDisplayIndexFull) {
if (mData["chart"] =="s") {
return nRow;
}
},
Datatables: custom function inside of fnRowCallback.
Good luck
fundTable.order( [0, 'asc'] );
Try that or look at this particular page for reference:
https://datatables.net/reference/api/order%28%29
Basically orders in pair of columnIndex in either asc(ending) or desc(ending) order.

View pictures or images inside Jquery DataTable

May I know if it is possible to put pictures or images into the rows of DataTables (http://datatables.net/) and how does one goes in doing it?
yes, simple way (Jquery Datatable)
<script>
$(document).ready(function () {
$('#example').dataTable({
"processing": true, // control the processing indicator.
"serverSide": true, // recommended to use serverSide when data is more than 10000 rows for performance reasons
"info": true, // control table information display field
"stateSave": true, //restore table state on page reload,
"lengthMenu": [[10, 20, 50, -1], [10, 20, 50, "All"]], // use the first inner array as the page length values and the second inner array as the displayed options
"ajax":{
"url": "#string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"))/Home/AjaxGetJsonData",
"type": "GET"
},
"columns": [
{ "data": "Name", "orderable" : true },
{ "data": "Age", "orderable": false },
{ "data": "DoB", "orderable": true },
{
"render": function (data, type, JsonResultRow, meta) {
return '<img src="Content/Images/'+JsonResultRow.ImageSrcDB+'">';
}
}
],
"order": [[0, "asc"]]
});
});
</script>
[edit: note that the following code and explanation uses a previous DataTables API (1.9 and below?); it translates easily into the current API (in most cases, just ditch the Hungarian notation ("fnRowCallback" just becomes "rowCallback" for example) but I have not done so yet. The backwards compatibility is still in place I believe, but you should look for the newer conventions where possible]
Original reply follows:
What Daniel says is true, but doesn't necessarily say how it's done. And there are many ways. Here are the main ones:
1) The data source (server or otherwise) provides a complete image tag as part of the data set. Don't forget to escape any characters that need escaping for valid JSON
2) The data source provides one or more fields with the information required. For example, a field called "image link" just has the Images/PictureName.png part. Then in fnRowCallback you use this data to create an image tag.
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var imgLink = aData['imageLink']; // if your JSON is 3D
// var imgLink = aData[4]; // where 4 is the zero-origin column for 2D
var imgTag = '<img src="' + imgLink + '"/>';
$('td:eq(4)', nRow).html(imgTag); // where 4 is the zero-origin visible column in the HTML
return nRow;
}
3) Similar to above, but instead of adding a whole tag, you just update a class that has the image as a background. You would do this for images that are repeated elements rather than one-off or unique pieces of data.
You mean an image inside a column of the table?
Yes, just place an html image tag
like this
<img src="Images/PictureName.png">
instead of putting data (some string) into a column just put the above html tag....
Asp.net core DataTables
The following code retrieve the image from a folder in WWWroot and the path in the DB field ImagePath
{
"data": "ImagePath",
"render": function (data) {
return '<img src="' + data + '" class="avatar" width="50" height="50"/>';
}
}
In case the Name of the picturefile is put together out of one or more informations in the table, like in my case:
src="/images/' + Nummer + Belegnummer + '.jpg"
you can make it that way:
var table = $('#Table').DataTable({
columnDefs: [
{
targets: 0,
render: getImg
}
]
});
function getImg(data, row, full) {
var Nummer = full[1];
var Belegnummer = full[4];
return '<img src="/images/' + Nummer + Belegnummer + '.jpg"/>';}
The picture is in the first column, so Targets = 0 and gets the Information from the same row.
It is necessary to add the parameters data and row.
It is not necessary to outsource it into a seperate function, here getImg, but it makes it easier to debug.