Sort date field (moment js) in bootstrap-table - javascript

I have JSON data which I am rendering to a Bootstrap-Table (bootstrap-4). I want all the columns to be sortable. I am unable to sort the ISO date converted to moment.js format (MMM DD, YYYY). I am not able to sort the date based on header click. Is this possible?
var $table = $('#table')
$(function() {
var data = [
{
'dt': '2020-05-04T00:00:00.000Z',
'name': 'Item 1',
'price': '$1'
},
{
'dt': '2020-06-27T00:00:00.000Z',
'name': 'Item 2',
'price': '$2'
},
{
'dt': '2020-06-17T00:00:00.000Z',
'name': 'Item 3',
'price': '$3'
},
{
'dt': '2020-06-28T00:00:00.000Z',
'name': 'Item 4',
'price': '$4'
},
{
'dt': '2020-05-08T00:00:00.000Z',
'name': 'Item 5',
'price': '$5'
}
]
data.forEach(d=>{
d.dt = moment(d.dt).format('MMM DD, YYYY')
});
function datesSorter(a, b) {
if (new Date(a) < new Date(b)) return 1;
if (new Date(a) > new Date(b)) return -1;
return 0;
}
$table.bootstrapTable({data: data})
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<link href="https://unpkg.com/bootstrap-table#1.17.1/dist/bootstrap-table.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.31/moment-timezone-with-data.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/bootstrap-table#1.17.1/dist/bootstrap-table.min.js"></script>
<table id="table"
data-search="true">
<thead>
<tr>
<th data-field="dt" data-sortable="true" data-sorter="datesSorter">Date</th>
<th data-field="name">Item Name</th>
<th data-field="price">Item Price</th>
</tr>
</thead>
</table>
Is there something similar to the datatable version of $.fn.dataTable.moment? How to I sort dates using bootstrap-tables

Its pretty easy to solve your problem.
Use the sorter that you already have (but switch the < and >).
Then remove the date formatting part:
data.forEach(d=>{
dt = moment(d.dt).format('MMM DD, YYYY')
});
Now you can use a formatter to get the dateformat back.
function dateFormatter(date) {
return moment(date).format('MMM DD, YYYY')
}
(You have to use data-formatter="dateFormatter" on the Date column)
You can test it here.

Related

Morris line chart is not working properly

I created this simple line chart using morris.js. But it is not showing data properly. I don't know why?
Please check it at js fiddle.
Js fiddle: link
new Morris.Line({
element: 'multi-line-mp',
data: [
{
day: 'Jan 1',
sales: '0',
purchases: '1'
},
{
day: 'Jan 2',
sales: '14',
purchases: '3'
},
{
day: 'Jan 3',
sales: '45',
purchases: '0'
},
{
day: 'Jan 4',
sales: '47',
purchases: '32'
},
{
day: 'Jan 5',
sales: '90',
purchases: '10'
}
],
xkey: 'day',
ykeys: ['Sales', 'Purchases'],
labels: ['Sales', 'Purchases'],
resize: true
});
The date format of your xkey (day) is not good, this is rather a string than a real date.
You have 2 choices:
change the format of the xkey to be a real date (like 2021-01-01 instead of Jan 1)
set the option parseTime to false, so that it won't try to format the string to be a date
In case you change the format of xkey, you still can change the way the date is displayed thanks to the function dateFormat (see the documentation for this here: http://morrisjs.github.io/morris.js/lines.html)

Add new column in google DataView dynamically

I'm using google chart datatable getting data from a Json, but I want to add a new column result of divide column 2 by 15000.
Using google.visualization.DataTable()
I'm getting something like this
Colum 1 | Column 2
First row 15.000.000€
Second row 20.000.000€
I want Column 3 like this
Colum 1 | Column 2 | Column 3
First row 15.000.000€ 1.000,00€
Second row 20.000.000€ 1.333,33€
you can use a DataView to add the new column, using a calculated column.
create a data view from the data table
var view = new google.visualization.DataView(data);
then use the setColumns method to change the view columns.
we use the column index of the first two columns,
then use a calculation for the third.
view.setColumns([0, 1, {
calc: function (dt, row) {
return dt.getValue(row, 1) / 15000;
},
label: 'Column 3',
type: 'number'
}]);
see following working snippet...
google.charts.load('current', {
packages: ['table']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Column 1', 'Column 2'],
['First Row', 15000000],
['Second Row', 20000000]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
return dt.getValue(row, 1) / 15000;
},
label: 'Column 3',
type: 'number'
}]);
var table = new google.visualization.Table(document.getElementById('chart_div'));
table.draw(view);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
to format the number,
use google's number formatter,
and object notation for the value.
var formatNumber = new google.visualization.NumberFormat({
pattern: '#,##0.00',
suffix: '€'
});
to format a data table column, use the format method.
formatNumber.format(data, 1);
to format a single value, use the formatValue method.
var value = dt.getValue(row, 1) / 15000;
return {
v: value,
f: formatNumber.formatValue(value)
};
see following working snippet..
google.charts.load('current', {
packages: ['table']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Column 1', 'Column 2'],
['First Row', 15000000],
['Second Row', 20000000]
]);
var formatNumber = new google.visualization.NumberFormat({
pattern: '#,##0.00',
suffix: '€'
});
formatNumber.format(data, 1);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
var value = dt.getValue(row, 1) / 15000;
return {
v: value,
f: formatNumber.formatValue(value)
};
},
label: 'Column 3',
type: 'number'
}]);
var table = new google.visualization.Table(document.getElementById('chart_div'));
table.draw(view);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

DataTables dynamic cells won't render

I'm stuck with getting my datatable cells (column 'price') re-rendered based on drop-down value (currency). But as I select currency, nothing is happening with the table - all the figures just stay the same. Any ideas as of why render function fails to render?
My HTML+JavaScript is as follows:
var oldCurrency = 'usd';
var newCurrency = 'usd';
var myTable = $('#mytable').DataTable({
sDom: 't',
columns:[
{data: 'item', title: 'Item'},
{data: 'descr', title: 'Description'},
{data: 'cost', title: 'Cost', render: function(data, type, row){
var exchangeRate = {usd: 1, eur: 0.87, gbp: 0.78};
row.cost = row.cost*exchangeRate[newCurrency]/exchangeRate[oldCurrency];
return row.cost;
}}
]
});
$('#currency').on('focus', function(){
oldCurrency = this.value;
});
$('#currency').on('change', function(){
newCurrency = this.value;
myTable.draw();
});
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="test.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<select id="currency">
<option value="usd">USD</option>
<option value="eur">EUR</option>
<option value="gbp">GBP</option>
</select>
<table id="mytable">
<thead>
<th>Item</th>
<th>Description</th>
<th>Cost</th>
</thead>
<tbody>
<tr>
<td>pen</td>
<td>writing tool</td>
<td>5.5</td>
</tr>
<tr>
<td>pencil</td>
<td>wooden stick</td>
<td>4.8</td>
</tr>
<tr>
<td>eraser</td>
<td>piece of rubber</td>
<td>1.2</td>
</tr>
</tbody>
</table>
</body>
</html>
First off, I wouldn't do all the tedious HTML on your own - even if your data is static and you don't want all the features offered by ajax-sourced table, I'd rather use javascript source - I may guess, input data format would be closer to what you get from your SQL or MongoDB, or whatever backend storage you might use.
Next, I would split your model from the view in MVC terms and manipulate source data, rather then its visual representation. Even though your price data to certain extent always stays the same, DataTables might percieve those as different number figures. And thus, you may need to clean datatable contents and populate that with new figures.
So, your code with slight tweaks would look like:
var oldCurrency = 'usd';
var newCurrency = 'usd';
var tableData = [
{
item: 'pen',
descr: 'writing tool',
cost: 5.5
},
{
item: 'pencil',
descr: 'wooden stick',
cost: 3.75
},
{
item: 'eraser',
descr: 'piece of rubber',
cost: 1.2
},
];
var dataTable =
$('#mytable').DataTable({
sDom: 't',
data: tableData,
columns:[
{data: 'item', title: 'Item'},
{data: 'descr', title: 'Description'},
{data: 'cost', title: 'Cost', render: function(data, type, row){return row.cost.toPrecision(2)}}
]
});
$('#currency').on('focus', function(){
oldCurrency = this.value;
});
$('#currency').on('change', function(){
newCurrency = this.value;
let exchangeRate = {usd: 1, eur: 0.87, gbp: 0.78};
dataTable.clear();
$.each(tableData, function(){
let entry = JSON.parse(JSON.stringify(this));
entry.cost = this.cost*exchangeRate[newCurrency]/exchangeRate[oldCurrency];
dataTable.row.add(entry);
});
dataTable.draw();
});
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<select id="currency">
<option value="usd">USD</option>
<option value="eur">EUR</option>
<option value="gbp">GBP</option>
</select>
<table id="mytable"></table>
</body>
</html>

How to sort date with dd-MMM-yyyy hh:mm tt format in datatable

I'm currently working on datatable, I found my sorting for date column was not working. here was my screenshot
Here was my code
<table id="tbl" class="table table-small-font table-bordered table-striped">
<thead>
<tr>
<th> </th>
<th class="text-left">Dated</th>
<th class="text-left">Day</th>
<th class="text-center">Remarks</th>
<th class="text-center">State</th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
#{ IEnumerable
<PublicHoliday> PublicHolidays = (IEnumerable
<PublicHoliday>)ViewData["PublicHolidays"]; int Idx = 1; } #foreach (var i in PublicHolidays) {
<tr>
<td>#Idx</td>
<td>#i.Dated.ToString("dd-MMM-yyyy hh:mm tt")</td>
<td>#i.Dated.ToString("ddd")</td>
<td>#Html.DisplayFor(x => i.Remarks)</td>
<td>#i.ForStateName</td>
<td><a data-toggle="tooltip" title="Delete" onclick="DeleteRecord(#i.Id);"><span class="glyphicon glyphicon-remove"></span></a></td>
</tr>
Idx++; }
</tbody>
</table>
<script src="~/lib/jquery-ui-1.12.1/jquery-ui.min.js"></script>
<script src="~/js/jquery.dataTables.min.js"></script>
<script src="~/js/dataTables.bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var tbl = $('#tbl').DataTable({
dom: "<'row'<'col-sm-6 col-xs-7'l><'col-sm-6 col-xs-7'f>>" + "rtip",
order: [
[0, "asc"]
],
pagingType: "numbers",
iDisplayLength: 50
});
});
</script>
the sort column does not work at all, and I can't find any plugin from datatable to use. anyone please help.. thanks in advance
I am not really sure that there is any plugin that supports date-dd-MMM-yyyy hh:mm tt format
So i have made modification to the plugin to support this format.
Here is the code for it.Load this piece of code after loading the datatable plugin
(function() {
var customDateDDMMMYYYYToOrd = function(date) {
var dateTime = date.split(' '),
dateObj = new Date(dateTime[0].replace(/-/g, ' ')),
time = "00:00",
type = "AM";
if (dateTime.length > 1) { // if time part and am/pm part is available
time = dateTime[1],
type = dateTime[2];
}
var splitTime = time.split(":"),
hours = type == "PM" ? Number(splitTime[0]) + 12 : Number(splitTime[0]),
minutes = Number(splitTime[1]),
seconds = 0,
milliseconds = 0;
return new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate(), hours, minutes, seconds, milliseconds);
};
// This will help DataTables magic detect the "dd-MMM-yyyy" format; Unshift
// so that it's the first data type (so it takes priority over existing)
jQuery.fn.dataTableExt.aTypes.unshift(
function(sData) {
"use strict"; //let's avoid tom-foolery in this function
if (/^([0-2]?\d|3[0-1])-(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)-\d{4}/i.test(sData)) {
return 'date-dd-mmm-yyyy';
}
return null;
}
);
// define the sorts
jQuery.fn.dataTableExt.oSort['date-dd-mmm-yyyy-asc'] = function(a, b) {
"use strict"; //let's avoid tom-foolery in this function
var ordA = customDateDDMMMYYYYToOrd(a),
ordB = customDateDDMMMYYYYToOrd(b);
return (ordA < ordB) ? -1 : ((ordA > ordB) ? 1 : 0);
};
jQuery.fn.dataTableExt.oSort['date-dd-mmm-yyyy-desc'] = function(a, b) {
"use strict"; //let's avoid tom-foolery in this function
var ordA = customDateDDMMMYYYYToOrd(a),
ordB = customDateDDMMMYYYYToOrd(b);
return (ordA < ordB) ? 1 : ((ordA > ordB) ? -1 : 0);
};
})();
The above code is the modification of date sort plugin(dd-mmm-yyyy).I have modified the customDateDDMMMYYYYToOrd function to fit this specific example
Add this so that the plugin would know what to be use when date is sorted
var tbl = $('#tbl').DataTable({
dom: "<'row'<'col-sm-6 col-xs-7'l><'col-sm-6 col-xs-7'f>>" + "rtip",
order: [[0, "asc"]],
pagingType: "numbers",
pageLength: 50,
columnDefs: [
{ type: 'date-dd-mmm-yyyy', targets: 1 } //add this part
]
});
You can find the list of sorting plugins available for datatable here
Note:
Please note that this plug-in is **deprecated*. The datetime
plug-in provides enhanced functionality and flexibility
Since 02-Jan-2017 12:00 AM and so on is valid RFC2822 dates, all you have to do is to set the column type to date :
columnDefs: [
{ targets: 1, type: 'date' }
]
Or if you have some odd values in the data, like null values you can just pass back the parsed value and sort as number, by that forcing correct sorting anyway (I guess that is the real problem) :
columnDefs: [
{ targets: 1,
type: 'num',
render: function(data,type) {
if (type == 'sort') return Date.parse( data ).valueOf()
return data
}
}
]
There is really no need for a special sorting plugin here. A third option is to set the unformatted date as data-sort attribute on the itself
<td data-sort="#i.Dated.ToString()">#i.Dated.ToString("dd-MMM-yyyy hh:mm tt")</td>
I use momentjs and lodash, it would like:
var records = [
["1", "28-Jan-2017 12:00 AM"],
["1", "28-May-2017 12:00 AM"],
["1", "28-Mar-2017 12:00 AM"]
];
records = _.map(records, record => {
record.push(moment(record[1], "DD-MMM-YYYY hh:mm A").unix());
return record;
});
$(document).ready(function() {
$('#example').DataTable( {
data: records,
columns: [
{ title: "id" },
{ title: "date" },
{ title: "ts"}
],
'columnDefs': [
{ 'orderData':[2] },
{
'targets': [2],
'visible': false
},
],
});
});
$(document).ready(function() {
$('#example').DataTable( {
data: records,
columns: [
{ title: "id" },
{ title: "date" },
{ title: "ts"}
],
'columnDefs': [
{ 'orderData':[2] },
{
'targets': [2],
'visible': false
},
],
});
});
Here is the jsFiddle
You can add the following sorting method to your options to sort according to date and time , specially if your time in 12 hour(AM/PM) format. I use the following code and it works for me:
$('#tableid').DataTable({
"order": [[, 'desc']],//order column in descending order.
"columnDefs": [
{ "type": "date", "targets": }//date column formatted like "03/23/2018 10:25:13 AM".
],
"pageLength": 25
});

Javascript Slickgrid, change row background on row select

I'm using slickgrid library, I have a grid that I would like it to have the ability of selecting a row on click and then chenge it's background color to red.
I'm using the code below, the grid click event is working I can print in the console the id of each row clicked but I don't know how to change the selected row background.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>SlickGrid example 1: Basic grid</title>
<link rel="stylesheet" href="js/SlickGrid/slick.grid.css" type="text/css"/>
<link rel="stylesheet" href="js/SlickGrid/css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css"/>
<link rel="stylesheet" href="css/exemple.css" type="text/css"/>
</head>
<body>
<table width="100%">
<tr>
<td valign="top" width="50%">
<div id="myGrid" style="width:480px;height:187px;"></div>
</td>
</tr>
</table>
<script src="js/SlickGrid/lib/jquery-1.7.min.js"></script>
<script src="js/SlickGrid/lib/jquery.event.drag-2.2.js"></script>
<script src="js/SlickGrid/slick.core.js"></script>
<script src="js/SlickGrid/plugins/slick.rowselectionmodel.js"></script>
<script src="js/SlickGrid/slick.grid.js"></script>
<script>
var grid;
var columns = [
{id: "title", name: "Title", field: "title",selectable: true},
{id: "duration", name: "Duration", field: "duration"},
{id: "%", name: "% Complete", field: "percentComplete"},
{id: "start", name: "Start", field: "start"},
{id: "finish", name: "Finish", field: "finish"},
{id: "effort-driven", name: "Effort Driven", field: "effortDriven"}
];
var options = {
enableCellNavigation: true,
enableColumnReorder: false
};
$(function () {
var data = [];
for (var i = 0; i < 5; i++) {
data[i] = {
title: "Task " + i,
duration: "5 days",
percentComplete: Math.round(Math.random() * 100),
start: "01/01/2009",
finish: "01/05/2009",
effortDriven: (i % 5 == 0)
};
}
grid = new Slick.Grid("#myGrid", data, columns, options);
grid.setSelectionModel(new Slick.RowSelectionModel());
grid.onClick.subscribe(function (e) {
var cell = grid.getCellFromEvent(e);
console.log(cell.row);//Here is the row id, I want to change this row background color
grid.setSelectedRows(cell.row);
e.stopPropagation();
});
})
</script>
</body>
</html>
This is a link to a page if you want to test Sample Page
It looks like you're missing a css file. When I load your sample page and look at the console, this file is missing:
http://payclix.biz/MobiusTrac/slick-default-theme.css
This piece of css would color the row for you:
.slick-row.active .slick-cell {
background-color: #FFB;
}
or with jQuery:
$(".slick-row").click( function(){
$(this).css("background-color", "#FBB");
});
Active row has class "active" and you can add properties to the CSS for this class.

Categories

Resources