DataTable ultimate date / time sorting - with custom format - sorting

can somebody please help me?
I'm trying to use a custom sorting format for datable with the "ultimate date / time sorting" plugin.
It partly works... and I need help to get it complety to work.
I have a table and one of the columns named "Laufzeit" is gonna display a running time from a ticket. I let my sql database calculate the difference between a datetime field and NOW(). Then I use javascript to convert the format on client side into the format you can see in the JSFiddle.
The format is like this: 6 Tage 09:47:15 (days 'Tage' hour:minutes:seconds)
For the sorting, I'm trying this: https://datatables.net/blog/2014-12-18
It works so far, except for one small thing... when the data shows "0 days", it is sorted to the last position, not to the first. The rest of the sorting is correct.
Could someone please help me?
Thanks. :)
borsTiHD
<table class="dataTable" id="example"><tbody>
<tr>
<td>0 Tage 00:33:21</td>
</tr>
<tr>
<td>1 Tage 02:39:24</td>
</tr>
<tr>
<td>1 Tage 03:18:25</td>
</tr>
<tr>
<td>1 Tage 03:47:15</td>
</tr>
<tr>
<td>2 Tage 06:47:15</td>
</tr>
<tr>
<td>3 Tage 08:47:15</td>
</tr>
<tr>
<td>4 Tage 18:47:15</td>
</tr>
<tr>
<td>6 Tage 09:47:15</td>
</tr>
<tr>
<td>13 Tage 05:26:59</td>
</tr>
<tr>
<td>13 Tage 18:24:24</td>
</tr>
<tr>
<td>20 Tage 12:12:13</td>
</tr>
<tr>
<td>21 Tage 18:24:56</td>
</tr>
<tr>
<td>34 Tage 22:59:59</td>
</tr>
<tr>
<td>0 Tage 00:11:06</td>
</tr>
<tr>
<td>0 Tage 00:24:22</td>
</tr>
</tbody></table>
<script>
$.fn.dataTable.moment( 'DDD [Tage] HH:mm:ss' );
Table = $("#example").DataTable( {
paging: false,
searching: false,
responsive: true,
"bInfo" : true,
"ordering": true,
"columns": [
{ title: "Laufzeit:" },
],
});
</script>
PS: My fiddle:
https://jsfiddle.net/borsTiHD/Lcnaq5gu/

'0' is not a valid day of year by moment's documentation. When it is parsed to a moment date, the date would be changed to current's date instead. Here's an example:
console.log(moment('1 Tage 01:20:35', 'DDD [Tage] HH:mm:ss').format()) // 1st january
console.log(moment('15 Tage 01:20:35', 'DDD [Tage] HH:mm:ss').format()) // 15th january
console.log(moment('32 Tage 01:20:35', 'DDD [Tage] HH:mm:ss').format()) // 1st february
console.log(moment('0 Tage 01:20:35', 'DDD [Tage] HH:mm:ss').format()) // current date
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js"></script>
So to support 0 day of year, you would need to write a custom sorting function, which would parse your input and handle the sorting. I've written some pretty basic example using regex (tests) and adding the provided dates to the current date:
var types = $.fn.dataTable.ext.type;
// Add type detection
types.detect.unshift(function(d) {
return parseDate(d) ? 'custom-moment' : null;
});
// Add sorting method - use an integer for the sorting
types.order['custom-moment-pre'] = function(d) {
return moment().add(parseDate(d)).unix();
};
function parseDate(d) {
//Format: DDD [Tage] HH:mm:ss
var parsedDate = d.match(/^\s*(\d+) Tage (\d+):(\d+):(\d+)\s*$/);
if (!parsedDate) {
return undefined;
}
return {
days: parsedDate[1],
hours: parsedDate[2],
minutes: parsedDate[3],
seconds: parsedDate[4]
}
}
Table = $("#example").DataTable({
paging: false,
searching: false,
responsive: true,
"bInfo": true,
"ordering": true,
"columns": [{
title: "Laufzeit:"
}, ],
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
<table class="dataTable" id="example"><tbody>
<tr>
<td>0 Tage 00:33:21</td>
</tr>
<tr>
<td>1 Tage 02:39:24</td>
</tr>
<tr>
<td>1 Tage 03:18:25</td>
</tr>
<tr>
<td>1 Tage 03:47:15</td>
</tr>
<tr>
<td>2 Tage 06:47:15</td>
</tr>
<tr>
<td>3 Tage 08:47:15</td>
</tr>
<tr>
<td>4 Tage 18:47:15</td>
</tr>
<tr>
<td>6 Tage 09:47:15</td>
</tr>
<tr>
<td>13 Tage 05:26:59</td>
</tr>
<tr>
<td>13 Tage 18:24:24</td>
</tr>
<tr>
<td>20 Tage 12:12:13</td>
</tr>
<tr>
<td>21 Tage 18:24:56</td>
</tr>
<tr>
<td>34 Tage 22:59:59</td>
</tr>
<tr>
<td>0 Tage 00:11:06</td>
</tr>
<tr>
<td>0 Tage 00:24:22</td>
</tr>
</tbody></table>

Related

How to get the table immediately previous to current table row

Say I get a list of rows like this
var table_stop_rows = (from r in doc.Descendants("TR").Cast<HtmlNode>()
where r.Attributes["name"]?.Value == "laneStop"
select r).ToList();
Now, for each of those "laneStop" rows, I want to refer back to the smaller table containing the "shipment_number" field and read its corresponding node value, eg "abc_123_florida-4". However, I cant simply get a list of all rows where there is a shipment_number, each one has to be in a table that precedes the "laneStop" row in the row collection I'm getting.
I suppose my question then is - if I have a collection of rows, can I then use an xpath statement relative to each row to get back to this shipment_number field in the table preceding?
Here is the html doc, note there would be dozens of these "table pairs". Since I can't control the structure of these files, I need a way to extract the data from the existing structure
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<table border="1">
<tbody>
<tr>
<td>
<table>
<tbody>
<tr>
<td>
<table>
<tbody>
<tr>
<td>Date</td>
<td>11/15/2019</td>
</tr>
<tr>
<td>shipment number</td>
<td>abc_123_florida-45</td>
</tr>
<tr>
<td>Departure time:</td>
<td>0430</td>
</tr>
</tbody>
</table>
</td>
<td>
<table>
<tbody>
<tr>
<td>Time arrival</td>
<td>1715</td>
</tr>
<tr>
<td>customer</td>
<td>bob smith</td>
</tr>
<tr>
<td>box type</td>
<td>square</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<table border="1">
<tbody>
<tr>
<td>
<table>
<tbody>
<tr name="laneStop">
<td>box1</td>
<td>23.45</td>
<td>lane1</td>
<td>south</td>
</tr>
<tr name="laneStop">
<td>box2</td>
<td>17.14</td>
<td>lane1</td>
<td>south</td>
</tr>
<tr name="laneStop">
<td>box3</td>
<td>17.18</td>
<td>lane1</td>
<td>north</td>
</tr>
<tr name="laneStop">
<td>box2</td>
<td>199.14</td>
<td>lane1</td>
<td>west</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Try this xpath expression:
(//tr[#name="laneStop"]/ancestor::table/preceding-sibling::table//tr[2]/td[2])[1]

DataTables moment sort by custom format

I am using DataTables and moment and have custom date format on my table.
How can I sort the column by moment?
Here you can see that sorting does not work correctly updated_at column.
I am using Datatable moment. Update_at format already changed by Carbon on Model.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css">
<div class="table-responsive">
<table id="tickets-table" class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>User name</th>
<th>Last update</th>
</tr>
</thead>
<tbody>
<tr>
<td>saddsfdsafdfsafsa</td>
<td>Sqe Begush</td>
<td>1 hour ago</td>
</tr>
<tr>
<td>testing</td>
<td>User name</td>
<td>8 hours ago</td>
</tr>
<tr>
<td>another</td>
<td>another user</td>
<td>4 days ago</td>
</tr>
<tr>
<td>another testing</td>
<td>user user</td>
<td>1 week ago</td>
</tr>
<tr>
<td>another testingsss</td>
<td>user user11</td>
<td>1 year ago</td>
</tr>
<tr>
<td>another test</td>
<td>user userqww11</td>
<td>4 months ago</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js">
</script>
<script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
<script src="//cdn.datatables.net/plug-ins/1.10.12/sorting/datetime-moment.js"></script>
<script>
$(document).ready(function() {
//$.fn.dataTable.moment("YYYY/MM/DD");
$('.table').DataTable();
});
</script>
The origin of the dates is unclear. If you pass moment().fromNow() yourself then just stop doing it when the display type is sort (see below). If you get already formatted data from a source you can use a library like chrono, which can parse "human dates" into "system dates":
var table = $('#tickets-table').DataTable({
columnDefs: [
{ targets: 2,
render: function(data, type) {
if (type == 'sort') {
var date = chrono.parseDate(data)
return new Date(date).valueOf()
}
return data
}
}
]
})
demo with the <table> above -> http://jsfiddle.net/mw0c3f91/
you have to convert the column dates to required format and then Sort the table.
moment(col[0]).fromNow();

Kendo UI Grid: Hide column when initialize from HTML table?

$(document).ready(function() {
$("#grid").kendoGrid({
height: 550,
sortable: true
});
});
<link href="http://kendo.cdn.telerik.com/2014.1.318/styles/kendo.common.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2014.1.318/js/kendo.all.min.js"></script>
<div id="example">
<table id="grid">
<colgroup>
<col />
<col />
<col />
<col />
<col />
</colgroup>
<thead>
<tr>
<th data-field="make" data-hidden="true">Car Make</th>
<th data-field="model">Car Model</th>
<th data-field="year">Year</th>
<th data-field="category">Category</th>
<th data-field="airconditioner">Air Conditioner</th>
</tr>
</thead>
<tbody>
<tr>
<td>Volvo</td>
<td>S60</td>
<td>2010</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Audi</td>
<td>A4</td>
<td>2002</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>BMW</td>
<td>535d</td>
<td>2006</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>BMW</td>
<td>320d</td>
<td>2006</td>
<td>Saloon</td>
<td>No</td>
</tr>
<tr>
<td>VW</td>
<td>Passat</td>
<td>2007</td>
<td>Saloon</td>
<td>No</td>
</tr>
<tr>
<td>VW</td>
<td>Passat</td>
<td>2008</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Peugeot</td>
<td>407</td>
<td>2006</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Honda</td>
<td>Accord</td>
<td>2008</td>
<td>Saloon</td>
<td>No</td>
</tr>
<tr>
<td>Alfa Romeo</td>
<td>159</td>
<td>2008</td>
<td>Saloon</td>
<td>No</td>
</tr>
<tr>
<td>Nissan</td>
<td>Almera</td>
<td>2001</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Mitsubishi</td>
<td>Lancer</td>
<td>2008</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Opel</td>
<td>Vectra</td>
<td>2008</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Toyota</td>
<td>Avensis</td>
<td>2006</td>
<td>Saloon</td>
<td>No</td>
</tr>
<tr>
<td>Toyota</td>
<td>Avensis</td>
<td>2008</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Toyota</td>
<td>Avensis</td>
<td>2008</td>
<td>Saloon</td>
<td>Yes</td>
</tr>
<tr>
<td>Audi</td>
<td>Q7</td>
<td>2007</td>
<td>SUV</td>
<td>Yes</td>
</tr>
<tr>
<td>Hyundai</td>
<td>Santa Fe</td>
<td>2012</td>
<td>SUV</td>
<td>Yes</td>
</tr>
<tr>
<td>Hyundai</td>
<td>Santa Fe</td>
<td>2013</td>
<td>SUV</td>
<td>Yes</td>
</tr>
<tr>
<td>Nissan</td>
<td>Qashqai</td>
<td>2007</td>
<td>SUV</td>
<td>Yes</td>
</tr>
<tr>
<td>Mercedez</td>
<td>B Class</td>
<td>2007</td>
<td>Hatchback</td>
<td>Yes</td>
</tr>
<tr>
<td>Lancia</td>
<td>Ypsilon</td>
<td>2006</td>
<td>Hatchback</td>
<td>Yes</td>
</tr>
</tbody>
</table>
</div>
Initializing from HTML table, how can I specify a column to be hidden? I need to access the data for that column in JS, but don't want to have that data visible to the end user.
http://demos.telerik.com/kendo-ui/grid/from-table
I've tried to use the attribute: data-hidden="true" on the th tag (data-field is also on th tag, as it is in the demo), but it's not working.
Note, I'd like to be able to specify the hidden option as an html attribute, if possible.
unfortunately you can't use the attribute hidden when initializing from an HTML table:
http://docs.telerik.com/kendo-ui/web/grid/introduction#create-a-grid-from-an-existing-html-table
Relevant quote:
When creating the Grid from an existing table, the following column
settings can be defined via HTML attributes:
data field names via data-field attributes
column widths via width styles applied to the respective elements
define data type via data-type attributes
define a column template via data-template attributes
enable or disable the column menu via data-menu attributes
enable or disable sorting via data-sortable attributes
enable or disable filtering via data-filterable attributes
enable or disable grouping via data-groupable attributes
All attributes should be applied to the <th> elements, except the column width styles.
All other column-related settings cannot be defined via HTML attributes in the <table>. If such settings must be used (e.g. commands, locking, editors, etc.) then the above attribute configuration should be abandoned and all settings should be included in the Grid's Javascript initialization statement (when using declarative widget initialization, the column properties should be set via the data-columns attribute).
For more info on that:
http://www.telerik.com/blogs/mvvm_declarative_initialization_and_html5_data_attributes
This is a good overview of declarative initiation in kendo.
http://www.telerik.com/forums/declarative-initialization-of-the-kendo-ui-grid
This post is a good example of declaritive initialization specific to grids
With that being said, Here's a quick and dirty workaround if you are seriously married to the plain old HTML format (this would allow you to set hidden via a data attribute, rather than hiding individual columns--which may or may not be important to you):
$(document).ready(function() {
var columns = $('#grid th'),
grid = $("#grid").kendoGrid({
height: 550,
sortable: true
}).data("kendoGrid");
for(var i =0; i < columns.length; i++){
if($(columns[i]).data("hidden") === true){
grid.hideColumn($(columns[i]).data("field"));
}
}
});
http://jsbin.com/mapadu/edit?html,js,output
You can hide column after the initialization of the widget. using the data field string
<script>
$(document).ready(function() {
$("#grid").kendoGrid({
height: 550,
sortable: true
});
var grid = $("#grid").data("kendoGrid");
grid.hideColumn("airconditioner");
});
</script>
Here is a working demo, but user can always check the source of the page and view the data because this only set the style of the <td> to display:none

basic grid plugin for jquery

I am looking for a very simple data grid plugin for jquery that will allow me to do the following
populate it
order columns a->z and z->a
add rows on the client
I am using asp.net mvc on the server side.
DataTables is pretty straightforward and easily configurable:
http://datatables.net/
Their examples page lists a number of ready to go implementations.
I've been working with jquery.tablesorter. API is pretty clear; you can override the sorting function to provide custom sorting. In this example, notice that i have a grouping header as well, for which I can disable sorting.
<div style="width: 1024px; overflow: scroll">
<table id="myTable" class="tablesorter">
<thead>
<tr>
<th colspan="2">Skill</th>
<th colspan="2">Resource</th>
<th colspan="2">Project</th>
<th>Role</th>
</tr>
<tr>
<th>Skill</th>
<th>Complexity</th>
<th>Bill</th>
<th>Joe</th>
<th>Project 1</th>
<th>Project 2</th>
<th>Role 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>.Net</td>
<td>2</td>
<td>1</td>
<td>3</td>
<td>4</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>UX</td>
<td>3</td>
<td>1</td>
<td>2</td>
<td>1</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>WCF</td>
<td>3</td>
<td>4</td>
<td>1</td>
<td>3</td>
<td>2</td>
<td>2</td>
</tr>
</tbody>
</table>
(function ($) {
$(document).ready(function () {
$("#myTable").tablesorter({
headers: {
0: { sorter: false },
1: { sorter: false },
2: { sorter: false },
3: { sorter: false }
}
});
});
})(jQuery);
jqGrid is probably the best grid plugin out there, it should do all you need above, and provide ample room for growth down the road if needed.
http://www.trirand.com/blog/
jsGrid is a really lightweight and customizable jQuery grid plugin http://js-grid.com/

Tablesorter not sorting millions

I'm building a mobile real estate website for my wife's business using Tablesorter to sort by price. It works fine for 6 digit numbers (including $s and commas), e.g. $600,000. However it fails when confronting a 7 digit number, e.g. $1,295,000.
In my
<script type="text/javascript" id="js">$(document).ready(function() {
$("table").tablesorter({
// sort on the second column, order asc
sortList: [[1,0]],
headers: {
1: { sorter: 'digit' } // column number, type
}
});
});
<table cellspacing="2" class="tablesorter { 0: { sorter: false}, 1: {sorter: true} }">
<thead>
<tr>
<th width="158" class="headerempty">Property</th>
<th width="130" class="{'sorter':'currency'}">Sort by Price</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><img src="../sales/29 Laurel Way/prepped_images/29lw-for_mobile.jpg" title="Tap for Details" alt="29 Laurel Way" width="150" height="100" border="0"></td>
<td class="{'sorter':'currency'}">$329,000</td>
</tr>
<tr class="odd">
<td><img src="../sales/Aetna Lane/al_for_Mobile.jpg" width="150" height="100"></td>
<td class="{'sorter':'currency'}">$175,000</td>
</tr>
<tr class="odd">
<td><img src="../sales/Atop Smith Hill/prepped/ash_mobile.jpg" width="150" height="100"></td>
<td class="{'sorter':'currency'}">$1,295,000</td>
</tr>
<tr class="odd">
<td><img src="../sales/Beech Hill/bh_mobile.jpg" width="150" height="100"></td>
<td class="{'sorter':'currency'}">$595,000</td>
</tr>
<tr class="odd">
<td class="{'sorter':'currency'}"><img src="../sales/Bluefield/b_mobile.jpg" width="150" height="100"></td>
<td>$299,000</td>
</tr>
</tbody>
</table>
Any thoughts on solving this one? Many thanks in advance, clpix
Constructions like td class="{'sorter':'currency'}" make me scary. You probaly should define table with class sortable and init table sorted in JS using this class, and define sorting parameters in constructor:
$(".sortable").tablesorter({
// sort on the second column, order asc
sortList: [[1,0]],
headers: {
1: { sorter: 'currency' } // column number, type
}
});
<table class='sortable'>
<tr>
<td>$1.000.000</td>
</tr>
......
</table>
And check out delimeter . or ,
This code work fine.

Resources