Manipulating data before drawing columns with DataTables jQuery Library - javascript

I currently have a table that loads data from a REST API endpoint via AJAX:
$(document).ready(function() {
var table = $('#pendingTable').DataTable({
ajax: {
type: "GET",
url: url + '/rest/endpoint,
dataSrc: "_deployments"
},
columns: [
{ data: "service_name" },
{ data: "git_organization" },
{ data: "id" },
{ data: "timestamp" },
{ data: "username" },
{ data: "environment" },
{ data: "site" },
{ data: "status" }
],
fnCreatedRow: function( nRow, aData, iDataIndex ) {
$(nRow).attr('onclick', "openModal(" + aData["id"] + ")");
},
order: [
[2, 'sc']
]
});
$('.table-responsive').css('opacity', '0').fadeTo(500, 1, 'swing');
$('#pendingTable_filter input').attr("placeholder", "by User, Org & More");
});
I have been exploring the DataTables.net docs, but am having issues determining the best course of action for manipulating the "timestamp" data (i.e., format it into a proper date), prior to the table being drawn.
The API offers the ability to modify individual cells which I may be able to iterate through, columns, or both. How would I go about formatting this time-stamp? (the value is just a string representing milliseconds). Would I need to have some form of a callback, or should I manipulate the data after the table has already been drawn?
Any examples would be greatly appreciated. Apologies that I do not have any examples to offer of what I've tried, a majority of it has been pseudo-code that isn't doing what I thought it would.

This is how I've done it using render, which allows you to manipulate the data before it's displayed.
{ data: "id" },
{
'render': function (data, type, full, meta) {
var date = new Date(parseInt(data.substr(6), 0));
return ISODateString(date);
}
},
{ data: "username" },
I created a function called ISODateString that returns the date, month and year parts of the timestamp (obviously you can also return the time parts if necessary).
function ISODateString(d) {
function pad(n) { return n < 10 ? '0' + n : n }
return pad(d.getDate()) + '/' + pad(d.getMonth() + 1) + '/' + d.getFullYear();
}

Related

Unable To Display Json Data in html Table Using jquery DataTable

i have C# function That Return Me Json Formated Data , function is below
void DisplayProjectMasterList()
{
string JSONString = "";
DataTable Dt = DB.GetDataTable("Sp_GetProjectMasterList");
if (Dt.Rows.Count > 0)
{
JSONString = JsonConvert.SerializeObject(Dt);
}
Context.Response.Write(JSONString);
}
and I am Calling This Function Via Ajax .in console i am getting json data But i dont know how to pass it to Jquery data table to display.. below is the javascript function... please help Me
function DisplayProjectMasterList() {
$.ajax({
url: 'project-master.ashx',
type: "POST",
dataType: 'json',
data: {
'fun': 'DisplayProjectMasterList'
},
success: function (data) {
console.log(data);
if (Chk_Res(data.errorMessage) == false) {
$('#tbl').dataTable({
paging: true,
sort: true,
searching: true,
scrollY: 200,
data: data,
columns: [
{ 'data':data.Prj_Id },
{ 'data':data.Prj_No },
{ 'data':data.Prj_Name },
{ 'data':data.Cus_Company_Name },
{ 'data':data.Prj_StartDate },
{ 'data':data.Prj_CompletionDate },
]
});
}
}
});
}
i am Getting FOllowing error while doing So:
DataTables warning: table id=tbl - Requested unknown parameter '0' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
Hi make sure the data you are being returned is in the following format:
{
"data": [
{
"Prj_Id": 1,
"Prj_No": 1,
"Prj_Name": "name",
"Cus_Company_Name": "company",
"Prj_StartDate": "2011/04/25",
"Prj_CompletionDate": "2011/04/25"
},
{
"Prj_Id": 1,
"Prj_No": 1,
"Prj_Name": "name",
"Cus_Company_Name": "company",
"Prj_StartDate": "2011/04/25",
"Prj_CompletionDate": "2011/04/25"
}
]
}
jquery Datatables by default looks for data property for the array of objects
https://datatables.net/reference/option/ajax.dataSrc
https://datatables.net/examples/ajax/objects.html

datatables selected row get undefined value

i'm pretty new using datatables and amaze with good fiture in datatables for handling a lots of data. i have read the documentation but still don't get the answer, too much example make me confuse which one is fit for my problem.
so, i trying to generated button which can edit value of selected row, but i think to complex for doing a button each row, i made it more simple with hyperlink text generated each button and can edit selected row which taken the ID of selected row.
The problem is when i succeed with generating link each row, the id of row is undefined.
on comment code name try 1, my table not showing and keep processing for long time
and comment code name try 2, my table working but when i hit edit the value is undefined.
here is my code :
$(document).ready(function(){
var dataTable = $('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'ajax': {
'url':'ajaxfile.php',
'data': function(data){
var gender = $('#searchByGender').val();
var name = $('#searchByName').val();
data.searchByGender = gender;
data.searchByName = name;
}
},
'columns': [
{ data: 'id' },
{ data: 'nama' },
{ data: 'grade' },
{ data: 'dept' },
{ data: 'id' },
{ data: 'id',
render: function(data, type, row, meta)
{
//try 1 :
//var data = table.row( this ).data().id;
//return 'edit';
//try 2 :
//var i = row[0];
//return 'edit';
}
},
]
});
undefined ID Image, and
normally this should be ID ie:2200085 not undefined.
any help would be appreciated, sorry if the question just hit little scope but i think out there many people have same problem like me. Thankyou.
you are missing one step after columns[].
$(document).ready(function(){
var dataTable = $('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'ajax': {
'url':'ajaxfile.php',
'data': function(data){
var gender = $('#searchByGender').val();
var name = $('#searchByName').val();
data.searchByGender = gender;
data.searchByName = name;
}
},
'columns': [
{ data: 'id' },
{ data: 'nama' },
{ data: 'grade' },
{ data: 'dept' },
{ data: 'id' },
{ data: 'id',
render: function(data, type, row, meta)
{
//try 1 :
//var data = table.row( this ).data().id;
//return 'edit';
//try 2 :
//var i = row[0];
//return 'edit';
}
},
],
createdRow: function ( row, data, index ) {
$(row).attr('title','Category ID : '+data[0]);
$(row).attr('id',data[0]);
$(row).click(function(){
alert(this.id+' is clicked');
});
}
});

DataTables adding data-order

I'm trying to sort my table by adding data-order in createdCell callback - it's working fine but seems table cache is not updating after that - sorting by first column (date with timestamp in data-order) simply not working.
I have tried table.rows/cells().invalidate() - no effect.
$.ajax({
type: "POST",
url: getLayoutData().urls.get_validation_history,
data: {
build_pk: build_pk,
type: validation_type,
},
success: function(response){
var response_data = JSON.parse(response);
var table = $("#validationHistoryTable").DataTable({
data: response_data.snapshots,
destroy: true,
autoWidth: false,
columns: [
{data: 'updated'},
{data: 'updated_by'},
{data: 'type'},
{data: 'status'},
{data: 'comment'},
],
columnDefs: [
{"width": "30%", "targets": 4},
{"targets": 0,
"createdCell": function(td, cellData, rowData, row, col){
raw = $(td).text().split(" ");
date = raw[0].split(".");
iso_time = date[2]+'-'+date[1]+'-'+date[0]+' '+raw[1];
$(td).attr('data-order', Date.parse(iso_time).getTime());
}
}
],
You cannot insert orthogonal data by manipulating nodes. You can manipulate existing and recognized data-* values through nodes and invalidate(), but not as part of the post processing of DOM nodes. Look at https://datatables.net/manual/data/orthogonal-data. data-* values can be specified by
Markup
A render literal that points to an alternative JSON property
A render callback
See proof of concept in this little example -> http://jsfiddle.net/rtu0bjz6/
{
targets: 2,
createdCell: function(td, cellData, rowData, row, col){
counter++
$(td).attr('data-order', counter)
}
}
Does not have any effect. The column is sorted by its original data, not its data-order. However, if you are using a render() function and return a special value upon type "sort" then it works as expected.
{
targets: 3,
render: function ( data, type, row, meta ) {
return type == 'sort' ? meta.row : data
}
}
So in your case, you could do something like (not tested) :
{
targets: 0,
render: function ( data, type, row, meta ) {
if (type == 'sort') {
var raw = data.split(" ");
var date = raw[0].split(".");
var iso_time = date[2]+'-'+date[1]+'-'+date[0]+' '+raw[1];
return Date.parse(iso_time).getTime()
} else {
return data
}
}
}

Unable to sort jqGrid column with sorttype function

Trying to sort a grid with custom sort. I am building jqgrid with dynamic columns and data. Everything works well except sorting of one of the column. I am using javax.json to build the json and I am using jqgrid 4.7.0. Here is the grid code:
var resultsGrid = $("#resultsGrid");
var url = "grid/GridDataController?action=runSearch&searchText="+getSearchText()+"&_ts"+$.now();
var csvUrl = "grid/GridDataController?action=downloadCsv&_ts"+$.now();
var gridPagerId="#resultsPager";
var drawSearchResultsGrid = function(colNames,colModel,data) {
resultsGrid.disableSelection(); //disales highlioghting cells outside selection like ghosting.
resultsGrid.jqGrid({
url: url,
datatype: 'jsonstring',
loadonce: true,
mtype: "GET",
height: 300,
width: 700,
colNames: colNames,
colModel: colModel,
datastr : data,
rowNum: 100000,
sortname: "invid",
sortorder: "asc",
rownumbers: true,
viewrecords: true,
pager: gridPagerId,
pginput : false,
pgbuttons : false,
viewrecords : false,
gridview: true,
autoencode: true,
onSelectRow : function(id) {
logMessage("row selected ["+id+"]");
},
loadComplete: function(data) {
logMessage("load completed");
},
ondblClickRow : function(rowid) {
logMessage("Double clicked");
$(escapeColon("#contentForm:viewPropertiesButton")).click();
}
});
// Set navigator with search enabled.
resultsGrid.jqGrid('navGrid',gridPagerId,{add:false,edit:false,del:false,search:false,refresh:false});
// add custom button to export the data to excel
resultsGrid.jqGrid('navButtonAdd',gridPagerId,{
caption:"Export",
onClickButton : function () {
resultsGrid.jqGrid('excelExport',{"url":csvUrl});
}
});
}; //end drawResultGrid function
//get grid config...
$.ajax({
type: "GET",
url: url,
data: "",
dataType: "json",
success: function(response)
{
if (response.result == "0")
{
logMessage("Drawing results grid...");
drawSearchResultsGrid(response.colNames,response.colModel,response.data);
resizeGrid();
logMessage("Results grid drawing done.");
}
else
{
logMessage("Error : " + response.message);
alert(response.message);
}
},
error: function(x, e)
{
alert(x.readyState + " "+ x.status +" "+ e.msg);
}
});
Here is my dynamic colModel looks like:
{
"result":"0",
"message":"",
"data":{
"records":18,
"total":1,
"page":"1",
"rows":[ ]
},
"colNames":[
"IP Address/Cidr",
"Name",
"IP Decimal",
"Cidr"
],
"colModel":[
{
"name":"adressCidr",
"width":50,
"sortable":true,
"hidden":false,
"sorttype":"function (cellValue,rowObject) { console.log('sorting by ['+rowObject.ipDecimal+']'); return parseInt(rowObject.ipDecimal,10);}"
},
{
"name":"name",
"width":50,
"sortable":true,
"hidden":false
},
{
"name":"ipDecimal",
"width":50,
"sortable":true,
"hidden":false,
"sorttype":"int"
},
{
"name":"cidr",
"width":0,
"sortable":false,
"hidden":true
}
]
}
ipDecimal is a hidden column but I am displaying it for testing purpose. Requirement is first column 'addressCidr' is a string column but i want to sort it using hidden ipDecimal column. The function neither does show console.log message nor does any sorting properly. However, If i sort by ipDecimal with sorttype as 'int' by clicking on its header, it works fine. Only thing i can think of is the double quote around the sorttype function itself. Please let me know if you see any other issue here, or what is the best way to solve this case. Here is snippet where I build json function:
private JsonObjectBuilder createColumn(JsonBuilderFactory factory,
String name,int width,boolean sortable,boolean hidden,boolean sorttype)
{
JsonObjectBuilder column =this.createColumn(factory, name, width, sortable, hidden);
StringBuilder fnBuilder = new StringBuilder("");
//this is not generic but can easily be made one :(
fnBuilder.append("function (cellValue,rowObject) {");
fnBuilder.append(" console.log('sorting by ['+rowObject.ipDecimal+']');");
fnBuilder.append(" return parseInt(rowObject.ipDecimal,10);");
fnBuilder.append("}");
column.add("sorttype", fnBuilder.toString()); // this works, not sure why above function does not work :(
return column;
}
private JsonObjectBuilder createColumn(JsonBuilderFactory factory,
String name,int width,boolean sortable,boolean hidden)
{
JsonObjectBuilder column;
column = factory.createObjectBuilder();
column.add("name", name);
column.add("width", width);
column.add("sortable", sortable);
column.add("hidden", hidden);
return column;
}
Data I used for testing is:
IpAddressCidr ipDecimal
5.1.0.0/24--83951616
5.1.1.0/24--83951872
5.1.2.0/24--83952128
5.1.3.0/24--83952384
5.1.4.0/24--83952640
5.3.0.0/24--84082688
5.9.2.0/24--84476416
6.0.0.0/24--100663296
6.0.1.0/24--100663552
6.0.2.0/24--100663808
6.0.3.0/24--100664064
6.0.4.0/24--100664320
6.0.5.0/24--100664576
7.1.0.0/24--117506048
7.1.1.0/24--117506304
7.1.2.0/24--117506560
7.1.3.0/24--117506816
198.186.198.0/24--3334129152
But here is that I see
Ip 198.186.198.0 should have appeared at the top as it has highest ipDecimal, but it gets pushed to the bottom.
To add more test information. If I remove enclosed double quotes, sort works fine, but not with it.
Following works:
{ name: "adressCidr", width:50, sortable: true,
sorttype: function (cellValue,rowObject) { console.log('sorting by ['+rowObject.ipDecimal+']');return parseInt(rowObject.ipDecimal,10);}},
Following does not:
{ name: "adressCidr", width:50, sortable: true,
sorttype: "function (cellValue,rowObject) { console.log('sorting by ['+rowObject.ipDecimal+']');return parseInt(rowObject.ipDecimal,10);}"},
The reason of your problem is the usage of sorttype which you defines as string instead of function:
{
"name":"adressCidr",
"width":50,
"sortable":true,
"hidden":false,
"sorttype":"function (cellValue,rowObject) { console.log('sorting by ['+rowObject.ipDecimal+']'); return parseInt(rowObject.ipDecimal,10);}"
}
You use jqGrid 4.7 which contains new feature which I suggested (see here). So you can include the code like
$.extend($.jgrid, {
cmTemplate: {
myIpAddress: {
sorttype: function (cellValue, rowObject) {
console.log('sorting by [' + rowObject.ipDecimal + ']');
return parseInt(rowObject.ipDecimal, 10);
},
width: 50
}
}
});
Now you can change the data returned from the server to
{
"name":"adressCidr",
"sortable":true,
"hidden":false,
"template":"myIpAddress"
}

Select2: how to set data after init?

I need to set an array of data after initializing select2. So I want to make something like this:
var select = $('#select').select2({});
select.data([
{id: 1, text: 'value1'},
{id: 1, text: 'value1'}
]);
But I get the following error:
Option 'data' is not allowed for Select2 when attached to a element.;
My HTML:
<select id="select" class="chzn-select"></select>
What should I use instead of a select element?
I need to set the source of items for search
In onload:
$.each(data, function(index, value) {
$('#selectId').append(
'<option value="' + data[index].id + '">' + data[index].value1 + '</option>'
);
});
Make an <input type="hidden"> element and bind select2 to that. Using .select2 on a regular select box doesn't let you play with the data, it just mostly gives you the UI and post-selection methods.
Source:
Select2 Documentation
Source: https://select2.org/programmatic-control/add-select-clear-items
Add item:
var data = {
id: 1,
text: 'Barn owl'
};
var newOption = new Option(data.text, data.id, false, false);
$('#mySelect2').append(newOption).trigger('change');
Clear items:
$('#mySelect2').val(null).trigger('change');
For v4 you'll have to destroy and reconstruct select2 with updated data. Check https://github.com/select2/select2/issues/2830
I've recently had the scenario where changing one select2 object alters the contents of a second (parent - child groupings effectively). I used an ajax call to retrieve a new set of Json data, which was then picked up by the second select2 object. I've included the code below:
$("#group").on('change', function () {
var uri = "/Url/RetrieveNewResults";
$.ajax({
url: uri,
data: {
format: 'json',
Id: $("#group :selected").val()
},
type: "POST",
success: function (data) {
$("#groupchild").html('');
$("#groupchild").select2({
data: data,
theme: 'bootstrap',
placeholder: "Select a Type"
});
},
error: function () {
console.log("Error")
}
});
});
I found that I had to include the $("#groupchild").html('') in order to clear out the previous set of data in the second select2. Hope this helps.
You can rerender and trigger the select2
render select2
$('.select2').select2({
placeholder: 'Slect value',
allowClear: true
});
after need to change the data data
let dataChange = [
{
id: 0,
text: 'enhancement'
},
{
id: 1,
text: 'bug'
},
{
id: 2,
text: 'duplicate'
},
{
id: 3,
text: 'invalid'
},
{
id: 4,
text: 'wontfix'
}
];
rerender the select2
$('.select2').select2('destroy');
$('.select2').empty();
$('.select2').select2({
placeholder: 'Slect value',
allowClear: true,
data: dataChange
});
trigger select2
$('.select2').trigger('change');
Hope this is the answer for you :3
Here's what I did.
1. Extend select2
Select2.prototype.setAjax = function (ajaxOptions)
{
// Set the new ajax properties
var oAjaxOpts = this.options.get('ajax');
if (oAjaxOpts != undefined && oAjaxOpts != null)
{
for (var sKey in ajaxOptions)
{
oAjaxOpts[sKey] = ajaxOptions[sKey];
}
}
var DataAdapter = this.options.get('dataAdapter');
this.dataAdapter = new DataAdapter(this.$element, this.options);
}
2. Initialize as usual (for example --- yours could be different)
jHtmlFrag.select2({
dropdownParent: $(oData.jDiv),
placeholder: "Select Option",
allowClear: true,
minimumInputLength: 2,
ajax: {
url: "",
method: "POST",
dataType: 'json',
delay: 250,
processResults: function (oResults, params)
{
let page = params.page || 1;
// console.log(oResults, (params.page * 10));
return {
results: oResults.data,
pagination: {
more: (page * 10) < oResults.recordsFiltered
}
};
}
}
}).val(null).trigger('change');
3. Set Ajax options dynamically when you feel like by calling the new extension func
jCombo.select2('setAjax', {
url: sUrl,
data: function (params)
{
let query = {
search: params.term,
type: params._type,
page: params.page || 1,
}
return query;
},
});

Categories

Resources