I am currently using Datatable in my laravel project for displaying my day configuration from my database. I would like to display my data in the following order, Monday -> Tuesday -> Wednesday etc.
Currently it is being ordered by alphabetical order from my database where the day column is store as string. Below are my javascript codes for my table.
var ophrTables = $('#ophrs_table').DataTable({
stateSave: true,
columnDefs: [{
"searchable": false,
"orderable": false,
"targets": 0
},{
"searchable": true,
"orderable": true,
"targets": 1
},{
"searchable": false,
"orderable": false,
"targets": 2
},{
"searchable": false,
"orderable": false,
"targets": 3
}],
order: [[ 1, 'asc' ]]
});
Here are two approaches:
Use a Column Renderer
You can create a mapping from day names to numbers:
var days = { 'Monday': 1, 'Tuesday': 2, 'Wednesday': 3, 'Thursday': 4, 'Friday': 5, 'Saturday': 6, 'Sunday': 7 };
You can then use that mapping when you create your DataTable.
Here is my test data in my HTML table:
<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Day</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>Monday</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Tuesday</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Wednesday</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Thursday</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Friday</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Saturday</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Sunday</td>
</tr>
</tbody>
</table>
Here is my DataTable definition:
$('#example').DataTable( {
"columnDefs": [ {
"targets": 1,
"render": function ( data, type, row, meta ) {
if (type === 'sort') {
return days[data];
} else {
return data;
}
}
} ]
} );
For the second column (index = 1), I use a render function to map from the name of the day to an integer. DataTables will use this integer for sorting operations (type === 'sort'). Otherwise it will use the name of the day.
The days[data] expression is used to look up the relevant number from my days variable.
The data looks like this when it is sorted by day name:
Warning:
When you use a renderer which produces numeric sort data from data which is alphanumeric, you do have to be careful. Even though numbers are used for sorting, they are treated as alphanumeric. In our case, this makes no difference, because the string values "1" through "7" are sorted the same way as the integer values 1 through 7.
But if you wanted to do something similar with the months of the year, then you would run into problems, as October (10), November (11) and December (12) would potentially be mis-sorted.
One fix for this is to force the column to be treated as if it contains numeric data by default: "type": "num",. Credit to this answer for highlighting this potential issue.
(Forcing the return value to be an integer does not help: return parseInt(days[data]);).
Delegated Sorting
An alternative approach is to populate the relevant number into an extra column when you load your data into the table.
In your DataTable definition, you can hide this column:
"columnDefs": [
{ "visible": false, "targets": 2 }
]
Then you can use the DataTables orderData option to delegate sorting from the visible "day name" column to the hidden "day number" column:
"columnDefs": [
{ "visible": false, "targets": 2 },
{ "orderData": [ 1 ], "targets": 2 }
]
This tells DataTables to use the data in column index 2 when you sort on column index 1.
I don't think that you can order by day. May be you can put a hidden text in the datatable column.
Now
<td>Monday</td>
<td>Tuesday</td>
<td>Friday</td>
Change it to
<td><span style="display:none">1</span>Monday</td>
<td><span style="display:none">2</span>Tuesday</td>
<td><span style="display:none">5</span>Friday</td>
Once you change it to this style, you can order by day.
Related
everything works fine. The only issue that i cannot fix/find is how to create a button and set the value of data: cvpdf inside a href of a button to open the cv
The cvpdf is the file name of a cv stored in the database.
<table id="dtBasicExample" class="table table-striped custom-table mb-0 datatable " >
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>surname</th>
<th>email</th>
<th>position</th>
<th>CV</th>
</tr>
</thead>
<tbody id="atn-tbody">
</tbody>
</table>
function showInformation(str) {
console.log(str);
$("#dtBasicExample").dataTable().fnDestroy();
$(document).ready(function(){
$("#dtBasicExample").dataTable({
scrollX: true,
"ajax":{
url: "data.php?q="+str ,
dataSrc:"",
},
"columns":[
{"data": "id"},
{"data": "name"},
{"data": "surname"},
{"data": "email"},
{"data": "position"},
{"data": "cvpdf"},
]
});
});
};
Let me help you out with this. you can apply this to any column data
columns: [
{
data: function(row){
return `Click This`
}
}
]
the "row" parameter will return the whole data for the current row, so you can access the object through the "row.your_key".
this is the best practice to make your code simpler.
the complete parameter can be accessed through This Link
Hope it can help!
I have 6 datatables with one datatable configuration on a page with a basic layout as follows for all five tables:
<table>
<thead>
<tr>
<th>COL_1</th>
<th>COL_2</th>
<th>COL_1</th>
<th>COL_1</th>
<th>COL_1</th>
</tr>
</thead>
<tbody>
<tr><td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
and my datatable configuration options is as below:
{
order: [[5, "desc"], [2, "asc"]]
.......
}
My issue is I need to order by columns by table. For example, in table 1, I would like to order columns 1 and 4 for second table on columns 3 and 4 and third on columns 0 and 3 etc., Is there a way to do that without having six different configurations for each datatable?
You can parameterize the DataTable initialization code - to a certain extent.
As an example, assume the following three simple tables:
$('#example1').DataTable( {
"paging": true,
"order": [[5, desc"], [2, "asc"]]
} );
$('#example2').DataTable( {
"paging": true,
"order": [[2, "asc"], [3, "asc"]]
} );
$('#example3').DataTable( {
"paging": true,
"order": [[4, "asc"], [2, "desc"]]
} );
The only parts which differ from table to table are:
the table name
the default sort order
We can extract these differences into a JavaScript object and then iterate over it as follows:
var configs = [
{
tableName: 'example1',
order: [[5, "desc"], [2, "asc"]]
},
{
tableName: 'example2',
order: [[2, "asc"], [3, "asc"]]
},
{
tableName: 'example3',
order: [[4, "asc"], [2, "desc"]]
}
];
configs.forEach( function ( config ) {
console.log(config.tableName);
$('#' + config.tableName).DataTable( {
"paging": true,
"order": config.order
} );
} );
The end result is the same as the three separate table definitions.
You can, of course add more data to the config object, such as a source URL, and so on. There may be some configuration items which cannot be handled in this way - for example, nested functions. It depends on how complex you need your table initialization to be.
It's a judgement call as to whether this is worth doing, in your case. There is a loss of readability, which needs to be considered.
I have a simple DataTable that I populate with data from a database, specifically from a single view called 'degree_inventory' as opposed to a traditional table. My application is written with Laravel, so I source my data using a route that pulls all the objects that correspond to a model and import them into my table. An additional level of complexity exists because the table has 'child rows', but those are not present by default.
My table:
<table id="program-table" class="table stripe compact">
<thead>
<tr>
<th>Levels</th>
<th>CIP Code</th>
<th>CIP Title</th>
<th>USF Title</th>
<th>Degree(s)</th>
<!-- <th>Activated Term</th>
<th>Suspended Term</th>
<th>Discontinued Term</th> -->
</tr>
</thead>
<tbody>
</tbody>
</table>
My DT declaration looks like:
$('#program-table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('serverSide') }}",
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"width": '8%',
"defaultContent": ''
},
{ data: 'cip', width: '10%'},
{ data: 'cip_title' },
{ data: 'item_name' },
{ data: 'degree_name_list' }
],
pageLength: 25,
searching: true,
paging: true,
fixedHeader: true, //plugin not working
"order": [[ 1, "asc" ]] //by default order by cip code
});
And my 'serverSide' route that gets called looks like:
Route::get('/serverSide', [
'as' => 'serverSide',
'uses' => function () {
$model = \App\Degree::query();
return DataTables::eloquent($model)->make();
}
]);
The 'Degree' model is entirely empty except for defining the corresponding table to be 'degree_inventory'
The table initially populates, expands child rows, and paginates perfectly, but any query into the search bar returns the following error:
Column not found: 1054 unknown column 'degree_inventory' in 'where clause' followed by the raw query that attempts to find matches to entries in each row.
If anyone has any insight I'd be very appreciative. Thank you!
The issue was that I had a column of buttons to expand and collapse child rows.
The solution was to disable to searchable property of the expand/collapse column because the content of the column is exclusively images.
For example:
$('#example').dataTable( {
"columns": [
{ "searchable": false }, //first column is the expand button
null,
null,
null,
null
] } );
} );
Recently, I got a requirement for an implementation of adding Child rows in a table. I have gone through the few APIs and found that datatables fits into my requirement. As of now I am implementing this web application in Springs and getting the data from the controller.
That is $resultSet.
Now this dynamic data I have to render in jsp page. Here I got stucked because I am not able to implement with datatable. I have seen the example of http://datatables.net/examples/api/row_details.html and tried removing Ajax data and used c:foreach loop in place it. But i didn't get any luck.
So can you guys please tell me how do I use datatables with the dyncamic data in order to display child rows.
My main concern is:
$(document).ready(function() {
var table = $('#example').DataTable( {
"ajax": "../ajax/data/objects.txt",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "salary" }
],
"order": [[1, 'asc']]
} );
How do I represent the above block.
I tried with <table id="xx"> <c:foreach loop to iterate>
You can use data option to feed data into DataTables directly instead of using server-side script to return data via Ajax. This initialization option can be useful when creating a table from a JavaScript data source, or from a custom Ajax data get. However the data has to be of type Array.
I'm not familiar with Spring framework but I'm assuming you can produce a string with data in JSON format and output it in your page to assign to table_data_json. I'm using a sample JSON string var table_data_json = '[ /* skipped */ ]';.
/* Formatting function for row details - modify as you need */
function format ( d ) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<td>Full name:</td>'+
'<td>'+d.name+'</td>'+
'</tr>'+
'<tr>'+
'<td>Extension number:</td>'+
'<td>'+d.extn+'</td>'+
'</tr>'+
'<tr>'+
'<td>Extra info:</td>'+
'<td>And any further details here (images etc)...</td>'+
'</tr>'+
'</table>';
}
$(document).ready(function() {
var table_data_json = '[{"name":"Tiger Nixon","position":"System Architect","salary":"$320,800","start_date":"2011/04/25","office":"Edinburgh","extn":"5421"},{"name":"Garrett Winters","position":"Accountant","salary":"$170,750","start_date":"2011/07/25","office":"Tokyo","extn":"8422"},{"name":"Ashton Cox","position":"Junior Technical Author","salary":"$86,000","start_date":"2009/01/12","office":"San Francisco","extn":"1562"}]';
var table = $('#example').DataTable( {
"data": JSON.parse(table_data_json),
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "salary" }
],
"order": [[1, 'asc']]
} );
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
} );
td.details-control {
background: url('https://raw.githubusercontent.com/DataTables/DataTables/1.10.7/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('https://raw.githubusercontent.com/DataTables/DataTables/1.10.7/examples/resources/details_close.png') no-repeat center center;
}
<link href="//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<table id="example" class="display">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
If I misunderstood your question, please let me know and I will update my answer.
I have a observable array in a viewmodel.
I show the date of array with a template:
<table align="center">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody data-template="row-template" data-bind="source: client"></tbody>
</table>
But if i want to sort array? and show the 'client' order by name or surname?
If your data array is like this (as json, if not convert to json or databind using server)
[{name:'name1',surname:'surname1'},{name:'name2',surname:'surname2'},{name:'name3',surname:'surname3'}]
You can use this code for client side sorting.
$("table").kendoGrid({
dataSource: {
data:[{name:'name1',surname:'surname1'},{name:'name2',surname:'surname2'},{name:'name3',surname:'surname3'}],
sort: {
field: "name",
dir: "desc"
}
},
sortable: true,
columns: [
{
field: "name",
title: "Name"
},
{
field: "surname",
title: "Surname"
}
]});
If i understand you right, this will solve your problem.