I have got the following data (sample):
"data": {
"eventsHeading": "Upcoming events",
"eventsToBeDisplayed": 3,
"allEventLinkText": "See all events",
"eventsList": [
{
"eventDate": "23/10/2016",
"eventTitle": "EVENT INFO 1"
},
{
"eventDate": "22/10/2016",
"eventTitle": "EVENT INFO 2"
},
{
"eventDate": "24/10/2016",
"eventTitle": "EVENT INFO 3"
},
{
"eventDate": "21/10/2016",
"eventTitle": "EVENT INFO 4"
}
]
}
And I have something like this:
<table>
<tbody>
{{#eventsList:i}}
{{#i < eventsToBeDisplayed}}
<tr>
<td class="date-column">{{eventDate}}</td>
<td class="text-link truncate-text"><ux-anchor class="text-link" href="{{link}}">{{eventTitle}}</ux-anchor>
</tr>
{{/}}
{{/}}
</tbody>
</table>
So currently, this will loop to fetch only 3 Data and it will show:
23/10/2016 EVENT INFO 1
22/10/2016 EVENT INFO 2
24/10/2016 EVENT INFO 3
What i want to do is sort first the eventDate so i will fetch the incoming eventDate, so it will be like this:
21/10/2016 EVENT INFO 4
22/10/2016 EVENT INFO 2
23/10/2016 EVENT INFO 1
What is the best approach to do this?
You should sort the data in some lifecycle event (or perhaps on observed changes / custom events?) in your ractive instance. Since you have your dates as date strings, you need to parse them into a date object before you can compare them.
this.set("eventsList",this.get("eventsList").sort( function (a, b) {
var aParts = a.eventDate.split("/");
var bParts = b.eventDate.split("/");
return new Date(aParts[2],aParts[1],aParts[0]) < new Date(bParts[2],bParts[1],bParts[0]) ? -1 : 1;
}));
Working fiddle: http://jsfiddle.net/pq7yrncv/
Related
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.
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 am using Ajax Datatable, I want to feed the table with Json data, which i am returning from MVC Action method. This is what i have tried so far,
My Controller action method
public ActionResult Index()
{
_dbcontext = new dbContext();
List<Employee> employees = new List<Employee>();
var query = (from e in _dbcontext.Employees select new { e.FirstName, e.LastName, e.Username, e.Password }).ToList();
return Json(query,JsonRequestBehavior.AllowGet);
}
And here is my Javascript on Index page
</script>
$(document).ready(function () {
$('#example').dataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "Home/Index",
"dataType": "jsonp"
}
});
});
</script>
But on page load only the plain Json data can be seen and no data table, I think It is not even rendering the Html on the index page and hence neither Datatable as I can not see anything in chrome debugger.
Also, Html and script referencing is all Ok as I can see the results when I feed the datatable from a .txt file having array of data.
I don't know what is the right way to do that, If somebody has the solution for that, then please help, Thanks.
I think what you need to do is simply the following
</script>
$(document).ready(function () {
$('#example').dataTable({
"ajax": "/Home/Index",
"columns": [
{ "data": "FirstName" },
{ "data": "LastName" },
{ "data": "Username" },
{ "data": "Password" },
]
});
});
</script>
No need for the processing and serverside and they are used when you have large data and would like to have paging and sorting done on the server side which is not the case in your code
One possible way is to define your "regular" table markup in a razor view/partial/ view - id your table, ie, id="DataTables-Employee". Your controller code looks just fine but with an ActionResult return a View with the model data. This let you control the data by using razor syntax in your view, which I have found much easier than complex JSON results. (Also, I like to use AutoMapper to project my model data to - give it a try!)
Note: this is only one of several ways to do this. Server-side processing helps when working with huge datasets, but give the client-side a try. I use ajax but flatten your model result. More likely than not you will need to define your columns and map them to your JSON. If you want to post your table results, add a form tag. I use ajax for this and serialize my form before sending. I hope this helps!
public ActionResult Index()
{
_dbcontext = new dbContext();
List<Employee> employees = new List<Employee>();
var query = (from e in _dbcontext.Employees
select new {e.FirstName, e.LastName, e.Username, e.Password};
//I would recommend using AutoMapper and project your model to this
return View(query.ToArray());
}
Say you are working with an Index view:
#model dynamic
... //typical HTML table
<table class="display compact table table-striped table-hover dataTables_sizing table-condensed" id="dataTables-Employee">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>User Name</th>
<th class="no-sort">Actions</th>
</tr>
</thead>
#foreach (var emp in Model)
{
<tr>
<td>#emp.FirstName</td>
<td>#emp.LastName</td>
<td>#UserName</td>
<td style="width: 100px;">
<i class="fa fa-search"></i>
#Ajax.ActionLink("View", "Index", new { id = #app.EmployeeId },
new AjaxOptions
{
dateTargetId = "resultSection",
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace
})
</td>
</tr>
}
</table>
//Know make it a DataTable
$('#dataTables-Employee').DataTable({
scrollY: '330px',
scrollCollapse: true,
paging: true,
scrollX: false,
"columnDefs": [{
"orderable": false,
"targets": 2
}, {
className: "dt-center",
"targets": [3]
}],
"aria": {
"sortAscending": ": activate to sort column ascending",
"sortDescending": ": activate to sort column descending"
},
"options": {
"emptyTable": "No records to display..."
}
});
Example of results with Bootstrap styles:
There is already an example of jqxGrid that is labeled "jqGrid integration with existing Durandal solution". However, I don't have the option of using jqxGrid.
Does any one have an example of using jqGrid with durandal. This is what I'm trying now and it is not working.
Unable to parse bindings.
Bindings value: attr: { href: 'animals/' + id, title: name }, text: id
Message: id is not defined;
viewmodel.js
///
define(['durandal/app', 'jqgrid', 'kojqgrid'], function (app) {
var initialData = [
{ id: 1, name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ id: 2, name: "Speedy Coyote", sales: 89, price: 190.00 },
{ id: 3, name: "Furious Lizard", sales: 152, price: 25.00 },
{ id: 4, name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ id: 5, name: "Brooding Dragon", sales: 0, price: 6350 },
{ id: 6, name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ id: 7, name: "Optimistic Snail", sales: 420, price: 1.50 }
];
var ctor = function () {
this.animals = ko.observableArray([]);
this.disabled = ko.observable(false);
this.activate = function () {
this.animals(initialData);
return true;
}
};
//Note: This module exports a function. That means that you, the developer, can create multiple instances.
//This pattern is also recognized by Durandal so that it can create instances on demand.
return ctor;
});
View
-------------------------------------------------------------------
<h3>Customers</h3>
<table id="animals" data-bind="grid: { data: animals }" >
<caption>Amazing Animals</caption>
<thead>
<tr>
<th data-field="actions" style="width:27px;"></th>
<th data-field="name" width="150px">Item Name</th>
<th data-field="sales">Sales Count</th>
<th data-field="price">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td data-field="actions">
<a class="grid-edit" data-bind="attr: { href: 'animals/' + id, title: name }, text: id"></a>
</td>
</tr>
</tbody>
</table>
Any help would be greatly appreciated.
The reason you are getting id is undefined is because the ctor function does not expose id or name attribute but the animals observableArray. In your view you need to loop over the animals obserbavbleArray to get access to id and name attribute for each animal. Try the following code:
<tbody data-bind='foreach:animals'>
<tr>
<td data-field="actions">
<a class="grid-edit" data-bind="attr: { href: 'animals/' + id, title: name }, text: id"></a>
</td>
</tr>
</tbody>
You need to put your activate handler on the prototype:
ctor.prototype.activate = function () {...}
Durandal likely cannot find your activate handler and, therefore, never initializes the data.
Also, I can only assume that the jqGrid binding is looking at the table definition and harvesting from the DOM what it needs to build a proper binding. The reason I say that is that, strictly speaking, #nimrig is right: there needs to be a foreach somewhere. It must be that the jqGrid is building that foreach.
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.