Sorting dataTables for date columns - sorting

I have a datatable but sorting on its date column treats the data as a text instead of a date. I'm trying to make it sort as a date instead but stuck on it.
I tried adding datetime sorting plugin but it didnt work, or I couldnt make it work.
Here's the complete script of the page
$(document).ready(function () {
$('.datetimeclass').datepicker({
format: "dd/mm/yyyy",
language: "tr"
});
var responsiveHelper_dt_basic = undefined;
var breakpointDefinition = {
laptop: 1366,
tablet: 1024,
phone: 480
};
$('#dt_basic').dataTable({
// Tabletools options:
// https://datatables.net/extensions/tabletools/button_options
"sDom": "<'dt-toolbar'<'col-sm-4 col-xs-4 hidden-xs'T>r>" +
"t" +
"<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i>>",
"oTableTools": {
"aButtons": [
"copy",
//"csv",
"xls",
{
"sExtends": "print",
"sMessage": "Generated by Derimod <i>(press Esc to close)</i>"
}
],
"sSwfPath": "/Scripts/plugin/datatables/swf/copy_csv_xls_pdf.swf",
"columnDefs": [
{ "type": "datetime", targets: 7 }
]
},
"autoWidth": true,
"preDrawCallback": function () {
// Initialize the responsive datatables helper once.
if (!responsiveHelper_dt_basic) {
responsiveHelper_dt_basic = new ResponsiveDatatablesHelper($('#dt_basic'), breakpointDefinition);
}
},
"rowCallback": function (nRow) {
responsiveHelper_dt_basic.createExpandIcon(nRow);
},
"drawCallback": function (oSettings) {
responsiveHelper_dt_basic.respond();
}
, paging: false
// , "aLengthMenu": [[10, 50, 100, -1], [10, 50, 100, "All"]],
//"iDisplayLength": 10,
//,'sPaginationType': 'full_numbers'
});
});
How can I solve my problem?
EDIT: An example of my date format: 14.6.2017 11:49:47

Related

Datatables PDF export right to left

I've managed to make a new font and add it to the datatable, but when I generated the PDF the text was aligned from left to right which is the opposite of what I wants, is there any configurations that I could use to make is right to left.
Also I'm using server side processing, and multi-column filtering, and the PDF button only prints the current page, what is the configuration to make it print the whole filter result.
Thanks in advance
You need to use specific pdfmake configuration options to manipulate the exported PDF:
https://datatables.net/reference/button/pdfHtml5
This will make the text to align right, it won't make the text run from right-to-left, however:
buttons: [
{
extend: 'pdf',
customize: function ( doc ) {
doc.content[0].alignment = 'right';
}
}
]
hi here is my code for persian ltr to rtl this is a function that's can use in datatable to export as pdf :
function buttonForDatatable(columns, margins, prtrait = "portrait",title='',message='') {
return [
{
extend: 'copy',
text:"کپی",
exportOptions: {
columns: columns.reverse(),
},
}, {
extend: 'csv',
text:"سی اس وی",
exportOptions: {
columns: columns.reverse(),
},
}, {
extend: 'print',
text:"پرینت",
exportOptions: {
columns: columns.reverse(),
},
}, {
extend: 'excel',
text:"اکسل",
exportOptions: {
columns: columns,
},
} ,{
extend: 'pdfHtml5',
orientation: prtrait,
footer: true,
alignment: "center",
title: title,
messageTop:message,
text: "PDF",
exportOptions: {
alignment: "center",
orthogonal: "PDF",
columns: columns,
modifier: {order: 'index', page: 'current'}
},
customize: function (doc) {
doc.styles.message.alignment = "right";
doc.styles.tableBodyEven.alignment = "center";
doc.styles.tableBodyOdd.alignment = "center";
doc.styles.tableFooter.alignment = "center";
doc.styles.tableHeader.alignment = "center";
doc.content[0]['text'] = doc.content[0]['text'].split(' ').reverse().join(' ');
doc.content[1].margin = margins;
doc.content[2].margin = margins;
for (var i = 0; i < doc.content[2].table.body.length; i++) {
// console.log(doc.content[1].table.body[i].length);
for (var j = 0; j < doc.content[2].table.body[i].length; j++) {
doc.content[2].table.body[i][j]['text'] = doc.content[2].table.body[i][j]['text'].split(' ').reverse().join(' ');
}
}
}
}
];
}
and after that you are can use same as here :
table = $('#mydatatable').DataTable({
language: language,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "all"]],
dom: 'Blfrtip',
buttons: buttonForDatatable([2, 3, 4], [0, 0, 0, 0]),
processing: true,
serverSide: true,
.....

Formatter works only once when used with rowObject

I have following jqGrid. The 'ActiveStatusText' column is populated using IsActive column value of rowObject, using a formatter.
{
name: 'ActiveStatusText',
width: 100,
formatter: function (cellvalue, options, rowObject) {
return rowObject.IsActive == true ? 'Active' : 'Retired';
}
}
When button is clicked, the status display text (“'ActiveStatusText'” ) need to be updated.
When “Retire” button click complete, the status display should become “Retired” and the button text should be “Activate”. This works fine.
When “Activate” button click complete, the status display should become “Active” and the button text should be “Retire”. The status column does not get updated.
Why is the text change happen only first time? How to fix this?
Fiddle
$(document).ready(function () {
function updateActiveStatus(rowid, isToActive) {
alert(isToActive);
$("#list").jqGrid('setCell', rowid, 'IsActive', isToActive);
$("#list").jqGrid('getLocalRow', rowid).IsActive = isToActive;
//Set display text
$("#list").jqGrid('setCell', rowid, 'ActiveStatusText', isToActive);
}
var myData = [
{ "id": "35", "firstname": null, "codeval": "G", "note": "xx7866", "amount": "23", "IsActive": true },
{ "id": "73", "firstname": null, "codeval": "W", "note": "dd1047", "amount": "34", "IsActive": true },
{ "id": "75", "firstname": "LORA", "codeval": "H", "note": "rr7323", "amount": "56", "IsActive": true },
{ "id": "95", "firstname": "EST", "codeval": "M", "note": "gg574", "amount": "55", "IsActive": false }
],
myGrid = $("#list");
myGrid.jqGrid({
datatype:'local',
data: myData,
colNames: ['ID', 'Note','Status', 'Action'],
colModel:[
{name:'id',width:70,align:'center',sorttype: 'int'},
{name:'note',index:'note',width:100,sortable:false},
{
name: 'ActiveStatusText',
width: 100,
formatter: function (cellvalue, options, rowObject) {
return rowObject.IsActive == true ? 'Active' : 'Retired';
}
},
{
name: 'IsActive',
width: 100,
formatter: function (cellvalue, options, rowObject) {
if (cellvalue == true) {
return '<div><button class="ui-button ui-widget ui-state-default app-custom-button-retire" >' +
'Retire' +'</button></div>';
}
else {
return '<div><button class="ui-button ui-widget ui-state-default app-custom-button-activate" >' +
'Activate' +
'</button></div>';
}
}
}
],
rowNum:10,
pager: '#pager',
gridview:true,
ignoreCase:true,
rownumbers:true,
viewrecords: true,
sortorder: 'desc',
height: '100%',
beforeSelectRow: function (rowid, e) {
var $self = $(this),
$td = $(e.target).closest("tr.jqgrow>td"),
rowid = $td.parent().attr("id"),
rowData = $self.jqGrid("getRowData", rowid),
iCol = $td.length > 0 ? $td[0].cellIndex : -1,
colModel = $self.jqGrid("getGridParam", "colModel");
celValue = $self.jqGrid('getCell', rowid, 'FirstName');
if (iCol >= 0 && colModel[iCol].name === "IsActive") {
if ($(e.target).hasClass("app-custom-button-retire")) {
updateActiveStatus(rowid,false);
return false;
}
if ($(e.target).hasClass("app-custom-button-activate")) {
updateActiveStatus(rowid, true);
return false;
}
}
//Avoid selection of row
return false;
}
});
});
HTML
<body>
<table id="list"><tr><td/></tr></table>
<div id="pager"></div>
</body>
I wrote you in the answer on your previous question, that jqGrid 4.6 is old (3 years old) and it contains many bugs, which are fixed later. I recommend you to upgrade jqGrid to the latest version of free jqGrid (it's 4.13.6 today). You code will start working.
In any way you can easy verify that the formatter will do called by setCell, but with the wrong parameter rowObject. jqGrid 4.6 uses DOM element of <tr> instead of real rowObject (see the line of code, where ind is assigned here). rowObject.IsActive will be undefined and the formatter of ActiveStatusText will return always 'Retired'.
Only if you really can't migrate to free jqGrid, then you can use the following workaround:
{
name: 'ActiveStatusText',
width: 100,
formatter: function (cellvalue, options, rowObject) {
var isActive = rowObject.IsActive;
if (isActive === undefined) {
// be called by setCell from buggy version of jqGrid
isActive = $(this).jqGrid('getLocalRow', options.rowId).IsActive;
}
return isActive == true ? 'Active' : 'Retired';
}
}
See the modified demo https://jsfiddle.net/OlegKi/fp7mL659/2/, which uses the code. By the way I wrote you in the answer on your previous answer, that setCell changes the local data too. Thus the call $("#list").jqGrid('getLocalRow', rowid).IsActive = isToActive; after $("#list").jqGrid('setCell', rowid, 'IsActive', isToActive); is absolutely unneeded.

Kendo chart performance issue

I am working on kendo chart. I am loading 30k data on the chart.
You can see in the code I have attached that, when I zoom in and out with mouse scroll, the process becomes very slow. Is it possible to reduce time of execution for each processes? And also first time loading of the chart is also very slow.
I want to know that is 30k data on Kendo chart should be loaded? Is there any limit that Kendo has set for data loading on the chart?
var Chartdata = [];
function createChart() {
$("#chart").kendoChart({
dataSource: {
data: Chartdata
},
series: [{
type: "scatterLine",
xField: "date",
yField: "close"
}, {
type: "scatterLine",
xField: "date",
yField: "volume"
}, {
type: "scatterLine",
xField: "date",
yField: "high"
}, {
type: "scatterLine",
xField: "date",
yField: "low"
}, {
type: "scatterLine",
xField: "date",
yField: "open"
}, {
type: "scatterLine",
xField: "date",
yField: "symbol"
}],
xAxis: {
name: "Date",
baseUnit: "minutes",
BaseUnitSteps: {
second: [1]
},
labels: {
visible: true,
step: 50,
font: "8px Arial,Helvetica,sans-serif",
template: "#= kendo.toString(new Date(value), 'MM/dd/yyyy HH:mm:ss') #"
},
majorUnit: 1,
majorTickType: "none",
majorGridLines: {
step: 5,
},
minorGridLines: {
visible: true,
step: 1,
},
minorTickType: "none",
majorTickType: "none",
},
yAxis: {
majorUnit: 25,
majorTickType: "none",
majorGridLines: {
step: 1,
},
minorGridLines: {
visible: true,
step: 1,
},
minorTickType: "none",
majorTickType: "none",
},
transitions: false,
zoomable: {
mousewheel: {
lock: "y"
},
selection: {
lock: "y"
}
},
zoom: setRange,
}).data("kendoChart");
}
function setRange(e) {
var chart = e.sender;
var options = chart.options;
e.originalEvent.preventDefault();
var xRange = e.axisRanges.Date;
if (xRange) {
var xMinonzoom = xRange.min;
var xMaxonzoom = xRange.max;
var dMaxonzoom = new Date(xMaxonzoom.getYear(), xMaxonzoom.getMonth(), xMaxonzoom.getDay(), xMaxonzoom.getHours(), xMaxonzoom.getMinutes(), xMaxonzoom.getSeconds());
var dMinonzoom = new Date(xMinonzoom.getYear(), xMinonzoom.getMonth(), xMinonzoom.getDay(), xMinonzoom.getHours(), xMinonzoom.getMinutes(), xMinonzoom.getSeconds());
var diff = dMaxonzoom - dMinonzoom;
if (xMaxonzoom - xMinonzoom < 10) {
return;
}
options.xAxis.min = xMinonzoom;
options.xAxis.max = xMaxonzoom;
chart.refresh();
}
}
$(document).ready(function() {
$.ajax({
type: "GET",
cache: true,
url: "https://api.myjson.com/bins/1uan0",
async: false
}).success(function(result) {
var dataresult = result;
$(dataresult).each(function(e, data) {
Chartdata.push({
"date": new Date(Date.parse(data.date)),
"close": data.close,
"volume": data.volume,
"high": data.high,
"low": data.low,
"open": data.open,
"symbol": data.symbol
});
});
createChart();
});
});
#chart circle {
display: none;
}
<link href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.mobile.all.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://kendochart.webashlar.com/kendochart/Javascripts/kendo.all.min.js"></script>
<div id="chart"></div>
Thank you
I have created a dojo for you so hopefully this points you to the right direction.
Chart Dojo
All I have done is added in some simple filtering so that based on the min and max zoom you have selected for the grid it will only call those items into the datasource for you rather than the entire dataset.
This is achieved via this bit of code:
var datasource = chart.dataSource;
console.log("DataSource Total before Filtering is:: " + datasource.total());
datasource.filter();
datasource.filter([{field:"date", operator:"gte",value : xMinonzoom }, {field:"date", operator: "lte", value:xMaxonzoom}]);
console.log("DataSource Total after Filtering is:: " + datasource.total());
So this shows you the effect the filtering is having on the data source you are returning back.
If you wanted to speed things up further you could potentially look at grouping for larger data sets i.e. when you first load the grid up as the data to me at that point is just noise (in my opinion) and is not really meaningful to me (but it maybe in your use case).
Think how mapping works with instances zoomed out summarized as a number rather than trying to show all the individual data points until you start zooming in and seeing the data individually.
If you need more info then let me know and I will expand the answer/ provide more info if I can.

datatable yadcf plugin init() not working

i am using datatable with bootstrap3. i want to apply filter after button is clicked. but when i clicked button it gives me TypeError: oTable.settings is not a function error. my datatable version is 1.10.6 and yadcf version is 0.8.7
here is my code
function init_datatable(table_id, records) {
// console.log('init table',$.parseJSON(records));
var oTable = $(table_id).dataTable({
aaData: $.parseJSON(records),
"sPaginationType": "bootstrap",
"bFilter": false,
"bInfo": false,
"sPageButtonActive": "active",
"aaSorting": [[0, 'desc']],
"bDeferRender": true,
"sDom": '<"top"if>rt<"bottom"lp><"clear">',
"aLengthMenu": [
[10, 20, 30, 50, -1],
[10, 20, 30, 50, "All"] // change per page values here
],
"iDisplayLength": 10,
"oLanguage": {
"sEmptyTable": "No data available"
},
"aoColumnDefs": [{
"aTargets": [0],
"bVisible": false,
"bSearchable": false
},
{
"bSortable": false,
"aTargets": [-1], // <-- gets last column and turns off sorting
"mData": null,
"mRender": function(data, type, full) {
return '<a data-original-title="Edit" id="edit_' + full[0] + '" data-placement="top" class="btn btn-xs btn-teal tooltips edit" href="javascript:void(0)"><i class="fa fa-edit"></i> Edit</a>';
}
}]
});
// .yadcf([
// {column_number: 1}
// ]);
$(table_id + '_wrapper .dataTables_length select').addClass("m-wrap");
$(table_id + '_wrapper .dataTables_length select').select2();
return oTable;
}
here is code for apply column filter
var pTable = init_datatable('#tbl_sample', data);
function apply_column_filter() {
yadcf.init(pTable, [
{column_number: 1}
]);
}
commented code in "init_datatble function is working. but when i use init it gives me error
yadcf.init should be use only for the new API with the capital D and since you are not using the new API, you should use the following way to init yadcf
$(table_id).dataTable({
......
}).yadcf([......]);
See comments in the code snippets on the showcase
//----------------------------------------------
//Example on how to define a custom filter function
//this function is goinf to be passesd to yadcf as custom_func parameter value
//and going to be tested against each value in the column
//----------------------------------------------
b.t.w if you want to filter some column pragmatically you should use the
exFilterColumn function , see docs
You can still use "yadcf.init" by getting the table reference. And this is how can get the reference of a table:
var api = new jQuery.fn.dataTable.Api(settings);
var oTable = api.table();
yadcf.init(oTable, [ {}]);

Jquery resize the form "formAddNewRow"

When I click on Add button , the formAddNewRow form opens , but I want to increase the widht of this form how do I achieve this ?
Here is what I tried
$(document).ready(function () {
var r;
var oTable = $('#Lookup').dataTable({
"sPaginationType": "full_numbers",
"aLengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
"iDisplayLength": 25
}
).makeEditable({
oAddNewRowFormOptions: { title: 'Add user', width: 800 },
"aoColumns": [
{
cssclass: 'required'
},
{ tooltip: 'Click to edit',
cssclass: 'required'
},
{ tooltip: 'Click to edit',
cssclass: 'required'
}
],
fnShowError: function (message, action) {
switch (action) {
case "update":
jAlert(message, "Update failed");
break;
case "add":
jAlert(message, "Update failed");
break;
}
}
});
});
But the Addnewform stays the same , the width of the form is not increased ? Any suggestions . can you please point me in the right direction
I also had the same problem, but after some searching I found the answer: place this in your document.ready function: (if you just want to change the width as the same of your content, just change it to auto)
$("#formAddNewRow").dialog({width:'650px'})

Resources