Asp.net mvc4 to datatables js - c#

The problems is Datatables JS stays in state "processing" and the Chrome debug throws:
Uncaught TypeError: Cannot read property 'length' of undefined
The code in question that "feeds" datatables js is (data is some linq query):
var jsonData = Json(data);
return jsonData;
The response is (textual response):
[{
"TotalCredito": 1649112940.000000,
"TotalClientes": 1040,
"Balance7": 188974066.000000,
"Balance37": 25152742.000000,
"Balance67": 53268069.000000,
"Mes": 1
}, {
"TotalCredito": 1910576150.000000,
"TotalClientes": 941,
"Balance7": 332301396.000000,
"Balance37": 84407873.000000,
"Balance67": -7053061.000000,
"Mes": 2
}, {
"TotalCredito": 1852843443.000000,
"TotalClientes": 809,
"Balance7": 300589569.000000,
"Balance37": 87170595.000000,
"Balance67": 41900708.000000,
"Mes": 3
}, {
"TotalCredito": 1736522626.000000,
"TotalClientes": 747,
"Balance7": 235758479.000000,
"Balance37": 107699635.000000,
"Balance67": 60831390.000000,
"Mes": 4
}, {
"TotalCredito": 1611546395.000000,
"TotalClientes": 702,
"Balance7": 201209547.000000,
"Balance37": 59028449.000000,
"Balance67": 64171607.000000,
"Mes": 5
}, {
"TotalCredito": 1306131513.000000,
"TotalClientes": 697,
"Balance7": 552835099.000000,
"Balance37": 67349028.000000,
"Balance67": 50490441.000000,
"Mes": 6
}]
And the script function in the view is:
<script>
$(document).ready(function () {
var datatable = $('#informe').dataTable({
"language": { "url": "http://cdn.datatables.net/plug-ins/28e7751dbec/i18n/Spanish.json" },
"bFilter": false,
"processing": true,
"serverSide": true,
"ajax": {
"url": "somesupercoolurl",
"type": "POST",
"dataType": "json"
},
"columns": [
{ "data": "Balance7" },
{ "data": "Balance37" },
{ "data": "Balance67" },
{ "data": "Mes" },
{ "data": "TotalClientes" },
{ "data": "TotalCredito" }
],
});
});
Finally, the table is:
<table id="informe">
<thead>
<tr>
<th>Balance7</th>
<th>Balance37</th>
<th>Balance67</th>
<th>Mes</th>
<th>TotalClientes</th>
<th>TotalCredito</th>
</tr>
</thead>
</table>
I find it strange that while the information is properly formatted, is not able to process.

Finally, i resolve this
after seeing many examples, I noticed it's necessary include this 3 variables to json before parse the json object to datatables js; In the controller:
var totalDatos = data.Count();
var jsonData = Json(new {
iTotalDisplayRecords = totalDatos,
iTotalRecords = totalDatos,
aaData = data
});
return jsonData;
Whit this 'function', the json object is like this
{"iTotalDisplayRecords":6,"iTotalRecords":6,"aaData":[{"TotalCredito":1649112940.000000,"TotalClientes":1040,"Balance7":188974066.000000,"Balance37":25152742.000000,"Balance67":53268069.000000,"Mes":1},{"TotalCredito":1910576150.000000,"TotalClientes":941,"Balance7":332301396.000000,"Balance37":84407873.000000,"Balance67":-7053061.000000,"Mes":2},{"TotalCredito":1852843443.000000,"TotalClientes":809,"Balance7":300589569.000000,"Balance37":87170595.000000,"Balance67":41900708.000000,"Mes":3},{"TotalCredito":1736522626.000000,"TotalClientes":747,"Balance7":235758479.000000,"Balance37":107699635.000000,"Balance67":60831390.000000,"Mes":4},{"TotalCredito":1611546395.000000,"TotalClientes":702,"Balance7":201209547.000000,"Balance37":59028449.000000,"Balance67":64171607.000000,"Mes":5},{"TotalCredito":1306131513.000000,"TotalClientes":697,"Balance7":552835099.000000,"Balance37":67349028.000000,"Balance67":50490441.000000,"Mes":6}]}
The table, in the view:
<table id="informe">
<thead>
<tr>
<th>Mes</th>
<th>TotalCredito</th>
<th>TotalClientes</th>
<th>Balance7</th>
<th>Balance37</th>
<th>Balance67</th>
</tr>
</thead>
</table>
The Script is:
<script>
$(document).ready(function () {
var arrayDatos = {
'canal': $(" #ListaCanales ").val(),
'anio': $(" #ListaAnios ").val(),
'vendedorsigla': $(" #ListaVendedores ").val()
};
var datatable = $('#informe').dataTable({
"language": { "url": "http://cdn.datatables.net/plug-ins/28e7751dbec/i18n/Spanish.json" },
"bFilter": false,
"processing": true,
"serverSide": true,
"ajax": {
"url": "mensualajax",
"type": "POST",
"dataType": "json",
"data": arrayDatos
},
"columns": [
{ "data": "Mes", "bSortable": false },
{ "data": "TotalCredito" },
{ "data": "TotalClientes" },
{ "data": "Balance7" },
{ "data": "Balance37" },
{ "data": "Balance67" }
],
});
$(" #FiltrarResultados ").click(function () {
var arrayDatos = {
'canal': $(" #ListaCanales ").val(),
'anio': $(" #ListaAnios ").val(),
'vendedorsigla': $(" #ListaVendedores ").val()
};
datatable.fnClearTable();
$('#informe').dataTable({
"bDestroy": true,
"language": { "url": "http://cdn.datatables.net/plug-ins/28e7751dbec/i18n/Spanish.json" },
"bFilter": false,
"processing": true,
"serverSide": true,
"ajax": {
"url": "mensualajax",
"type": "POST",
"dataType": "json",
"data": arrayDatos
},
"columns": [
{ "data": "Mes", "bSortable": false },
{ "data": "TotalCredito" },
{ "data": "TotalClientes" },
{ "data": "Balance7" },
{ "data": "Balance37" },
{ "data": "Balance67" }
],
});
});
});
is important remark, i use the 'click' function to reload whit ajax the datatables, the 'click' function is nearly equal to the another, but i aggregate "bDestroy": true,in the datatable constructor to reload the datatables (It is not very elegant, but work).
Finally, my new superduper controller to render, capture and updating data with DatatablesJs
//repository with the query
var repositorio = new Repositorios.InformeMensualController();
//capture ajax
string canal = String.Join("", Request.Form.GetValues("canal"));
string auxAnio = String.Join("", Request.Form.GetValues("anio"));
int anio = Convert.ToInt32(auxAnio);
string auxVendedorCodigo = String.Join("", Request.Form.GetValues("vendedorsigla"));
int vendedorCodigo = Convert.ToInt32(auxVendedorCodigo);
//set up data
var data = repositorio.CargaDatos(canal, anio, vendedorCodigo);
//Transformación a JSON y Datatables JS.
var totalDatos = data.Count();
var jsonData = Json(new {
iTotalDisplayRecords = totalDatos,
iTotalRecords = totalDatos,
aaData = data});
return jsonData;
I hope this is useful to someone
regards! :)

Related

Using jsTree, how could I add a new item to the subgroup of an existing parent, if that parent is selected/highlighted?

<script>
$(function () {
#{
var rootGroup = Model.Groups.FirstOrDefault(group => group.ParentGroupId == null);
}
let selectedGroup = "";
let selectedNode = null;
let groups = {};
#foreach(var group in Model.Groups) {
#:groups["#group.GroupId"] = { delete:false ,id: "#group.GroupId", parent: "#group.ParentGroupId", name: "#group.Title", order: "#group.OrderNum" };
}
$('#groupTree').jstree({
"checkbox": { "three_state": false },
"core": {
"check_callback": true,
'data': [
#foreach (var item in Model.Groups) {
#if (item.ParentGroupId == null)
{
#:{ "id": "#item.GroupId", "parent": "#", "text": "#item.Title", "state": { "disabled": true } },
}
else
{
#:{ "id": "#item.GroupId", "parent": "#item.ParentGroupId", "text": "#item.Title" },
}
}
],
"themes": {
"icons": false
},
},
"plugins": ["themes","dnd"]
}).on('loaded.jstree', function () {
$("#groupTree").jstree("open_all");
}).on("select_node.jstree", function (evt, data) {
$("#group-name-input").val(groups[data.node.id].name);
selectedGroup = data.node.id;
selectedNode = data.node;
$("#group-name-input").prop('disabled', false);
$("#save-group-button").prop('disabled', false);
$("#delete-group-button").prop('disabled', false);
}).on("move_node.jstree", function (evt, data) {
groups[data.node.id].parent = data.parent;
groups[data.node.id].order = data.position;
$("#SerializedGroupInformation").val(JSON.stringify(groups));
})
$("#save-group-button").click(function () {
if (selectedGroup != "") {
groups[selectedGroup].name = $("#group-name-input").val();
$("#groupTree").jstree('rename_node', selectedNode, $("#group-name-input").val());
$("#SerializedGroupInformation").val(JSON.stringify(groups));
$("#group-name-input").prop('disabled', true);
$("#save-group-button").prop('disabled', true);
$("#delete-group-button").prop('disabled', true);
$("#group-name-input").val("");
}
})
$("#delete-group-button").click(function () {
if (selectedNode.children.length > 0) {
swal({
title: 'Error!',
text: 'The group can not have any children.',
icon: 'error'
});
return;
}
groups[selectedGroup].delete = true;
$("#groupTree").jstree('delete_node', selectedNode);
$("#SerializedGroupInformation").val(JSON.stringify(groups));
$("#group-name-input").prop('disabled', true);
$("#save-group-button").prop('disabled', true);
$("#delete-group-button").prop('disabled', true);
$("#group-name-input").val("");
})
$("#new-group-button").click(function () {
var name = $("#new-group-input").val();
var group = { name: name, order: "0", id: "", parent:"" }
var node = { id: name, text: name };
$('#groupTree').jstree('create_node', "#rootGroup.GroupId", node, 'last');
groups[name] = group;
$("#SerializedGroupInformation").val(JSON.stringify(groups));
$("#group-name-input").prop('disabled', true);
$("#save-group-button").prop('disabled', true);
$("#delete-group-button").prop('disabled', true);
$("#group-name-input").val("");
$("#new-group-input").val("");
})
});
</script>
Considering the code above, How could I add the new group as a child to the selected parent node? I have failed at doing so. Can anyone help? I am new to development and I hate to admit that JS is not my strong suit...yet :)
I have tried multiple things and will continue to do so, but this is the original code without my attempts at solving this. Thanks in advance!
Here is a demo to show how to add new item to selected parent:
View:
<div id="jstree">
</div>
<button id="create">create button</button>
Js code:
#section scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<script type="text/javascript">
$(function () {
var managerTeam = [{
"id": "m1",
"text": "M1",
"children": [{
"id": "m2",
"parent": "m1",
"text": "M2"
}, {
"id": "t1",
"parent": "m1",
"text": "T1"
}, {
"id": "m3",
"parent": "m1",
"text": "M3",
"children": [{
"id": "t2",
"parent": "m3",
"text": "T2"
}, {
"id": "t3",
"parent": "m3",
"text": "T3"
}],
"state": { "opened": true }
}],
"state": { "opened": true }
}];
$('#create').on('click', function () {
var position = 'inside';
var newNode = { state: "open", data: "New nooooode!" };
var parent = $('#jstree').jstree('get_selected')[0];
$('#jstree')
.jstree({
"core": {
"check_callback": true
}
})
.create_node(parent, newNode, position, false, false);
});
});
</script>
}
result:

How to dynamically make columns of jQuery DataTable disappear

Here is the information about my development environment:
Microsoft Visual Studio Professional 2013
.NET Framework 4.0
jQuery-2.1.4.min.js
jQuery DataTables 1.10.7
Newtonsoft.Json.7.0.1
jQuery UI 1.11.2
var GetAUsersLogs = function (sortColumn, isDescending) {
$('#PersonalUsersLogTable').DataTable({
"aoColumns": [
{ "sTitle": "LogBsonValueId" },
{ "sTitle": "UserID" },
{ "sTitle": "Driver Name" },
{ "sTitle": "Log Date" },
{ "sTitle": "Duty Cycle" },
{
"mData": null,
"mRender": function (obj) {
return '<a href="#" id="' + obj.DT_RowId + '" onclick="ViewLogAuditHistory(this)" >Log Hist</a>';
}
},
{
"sTitle": "Details",
"mData": null,
"mRender": function (obj) {
return '<a href="#" id="' + obj.DT_RowId + '" onclick="ViewParticularLogsInfo(this)" >View</a>';
}
}
],
"aoColumnDefs": [{ "bVisible": false, "aTargets": [0, 1, 5] }],
"iDisplayLength": 5,
"sDom": '<"clear">frtip',
"bProcessing": true,
"bServerSide": true,
"bLengthChange": false,
"bPaginate": true,
"bDestroy": true,
"bSort": false,
"bInfo": true,
"bFilter": false,
"sAjaxSource": 'LogsList.aspx/BindPersonalUsersLogDataTable',
"bJQueryUI": true,
"bDeferRender": true,
"sPaginationType": "full_numbers",
"fnServerParams": function (aoData) {
aoData.push(
{ "name": "sortColumn", "value": sortColumn },
{ "name": "isDescending", "value": isDescending }
);
},
"fnServerData": function (sSource, aoData, fnCallback) {
$.ajax({
"dataType": 'json',
"contentType": "application/json; charset=utf-8",
"type": "GET",
"url": sSource,
"data": aoData,
"success":
function (msg) {
var json = jQuery.parseJSON(msg.d);
fnCallback(json);
},
beforeSend: function () {
$('.loader').show()
},
complete: function () {
$('.loader').hide()
}
});
}
}); // end of PersonalUsersLogTable DataTable method
}
// end of Code used to Bind Data to Table
The invocation to BindPersonalUsersLogDataTable method is in a C# file.
Within BindPersonalUsersLogDataTable, I will code that will determine if logged in user is an Admin or plain user.
If the logged in user is a plain user, then I want to dynamically make some of the columns in the jQuery DataTable Invisible.
Could some please tell me the changes I need to make in order to the aforementioned code to get the desired functionality?
You can use column().visible() or columns().visible() API methods to dynamically show/hide a single column or a set of columns.
"success": function (msg) {
var api = $('#PersonalUsersLogTable').DataTable();
var json = jQuery.parseJSON(msg.d);
// Enable/disable columns based on user type
if(json.isAdminUser){
api.columns([2,3]).visible(true);
} else {
api.columns([2,3]).visible(false);
}
fnCallback(json);
},

How to populate dataTable with strongly typed Razor View Page

I have a dataTable in strongly typed Razor View Page.Now as per my requirement I need to populate this with my Model of the page but i am not getting how to do it.Here is my dataTable Code..
$(document).ready(function () {
var dt;
var dataSet = [];
dt = $("#Setup").dataTable({
"data": dataSet,
"paging": false,
"responsive": true,
"stateSave": true,
"columns": [
{ "title": "<input type='checkbox' id='selectAll'>", "bSortable": false, "width": "5px", },
{ "title": "", "bSortable": false, "width": "5px" },
{ "title": "Code", "width": "50px" },
{ "title": "Name" }
]
});
});
My page is Razor View Page .Please help me to get it done..Thanks..
Generally you should be able to inline your data from razor like this:
#{
StringBuilder sb = new StringBuilder();
foreach(row in model.MyTable)
{
sb.AppendFormat("['{0}', '{1}', '{2}', '{3}'],",
row.Field1, row.Field2, row.Field3, row.Field4);
}
}
$(document).ready(function () {
var dt;
var dataSet = [#Html.Raw(sb.ToString(0, sb.Length - 1))];
dt = $("#Setup").dataTable({
"data": dataSet,
"paging": false,
"responsive": true,
"stateSave": true,
"columns": [
{ "title": "<input type='checkbox' id='selectAll'>", "bSortable": false, "width": "5px", },
{ "title": "", "bSortable": false, "width": "5px" },
{ "title": "Code", "width": "50px" },
{ "title": "Name" }
]
});
});
You should use sb.Length - 1 in order to remove the last comma (,) from the output array. Using Html.Raw() prevents Razor from encoding the string which would ruin the JavaScript syntax.
It's easier: "data": #Html.Raw(Json.Encode(Model.MyList)) - For me it works.

Dynamic Attributes (nested) used as Grid Columns in ExtJS

I tried to use the dynamic attributes approach within my prototype mongoDB application.
Basically the approach just gives you something like this:
{
SKU: "Y32944EW",
type: "shoes",
attr: [
{ "k": "manufacturer",
"v": "ShoesForAll",
},
{ "k": "color",
"v": "blue",
},
{ "k": "style",
"v": "comfort",
},
{ "k": "size",
"v": "7B"
}
]
}
(Source: http://askasya.com/post/dynamicattributes).
The problem is that for example Kendo Grid does not support such nested structures in their data source.
Does anyone know if Sencha ExtJS Grid Component can do this?
Update: SKU should be a column and each v of the attr array should be a column.
Update: I am trying to setup a sencha fiddle with the help of your answer.
https://fiddle.sencha.com/#fiddle/evc
app.js (rev2)
// create the new type
Ext.data.Types.DYNAMIC = {
convert: function(value, record) {
for (var i = 0, ln = value.length; i < ln; i++) {
var item = value[i];
record.set(item.k, item.v);
}
return '';
},
type: 'dynamic',
sortType: Ext.data.SortTypes.none
};
// define a model
Ext.define('TestModel', {
extend: 'Ext.data.Model',
fields: [{name: "_id",type: "string"},
{name: "attr",type: Ext.data.Types.DYNAMIC}],
idProperty: '_id'
});
// create a store with the model assigned
Ext.create('Ext.data.Store', {
storeId: 'MyStore',
model: 'TestModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/data.json',
reader: {
idProperty: '_id',
type: 'json',
root: 'data'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Grid',
store: Ext.data.StoreManager.lookup('MyStore'),
columns: []
});
Ext.widget('window',{height: 200,width: 400, items: [grid ] }).show();
store.on('metachange', function(store, meta) {
grid.reconfigure(store, meta.columns);
});
data.json (rev2)
{
"metaData": {
"idProperty": "_id",
"rootProperty": "data",
"fields": [
{ "name": "_id","type": "string" },
{ "name": "de", "type":"string" },
{ "name": "en", "type":"string" },
{ "name": "fr", "type":"string" },
{ "name": "attr", "type": "dynamic"}
],
"columns": [
{
"header": "de",
"dataIndex": "de"
},
{
"header": "en",
"dataIndex": "en"
}
,
{
"header": "fr",
"dataIndex": "fr"
}
]
},
"data":
[
{"_id": "MyTextId1",
"attr":[
{
"k": "de",
"v": "GermanText Sample"
},
{
"k": "en",
"v": "English Text Sample"
},
{
"k": "fr",
"v": "French Text Sample"
},
]
},
{"_id": "MyTextId2",
"attr":[
{
"k": "de",
"v": "GermanText Sample 1"
},
{
"k": "en",
"v": "English Text Sample 1"
},
{
"k": "fr",
"v": "French Text Sample1 1"
},
]
}
]
}
Error Message:
Uncaught Error: [Ext.createByAlias] Unrecognized alias: data.field.[object Object]
Update:
Works with the snippet posted in the last edit of sra. Thank you!
Yes you can. And most of it is already Build in. Lets's start with the basics
Response MetaData
The server can return metadata in its response, in addition to the record data, that describe attributes of the data set itself or are used to reconfigure the Reader. To pass metadata in the response you simply add a metaData attribute to the root of the response data. The metaData attribute can contain anything, but supports a specific set of properties that are handled by the Reader if they are present:
root: the property name of the root response node containing the record data
totalProperty: property name for the total number of records in the data
successProperty: property name for the success status of the response
messageProperty: property name for an optional response message
fields: Config used to reconfigure the Model's fields before converting the response data into records
An initial Reader configuration containing all of these properties might look like this ("fields" would be included in the Model definition, not shown):
reader: {
type : 'json',
root : 'root',
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
If you were to pass a response object containing attributes different from those initially defined above, you could use the metaData attribute to reconifgure the Reader on the fly. For example:
{
"count": 1,
"ok": true,
"msg": "Users found",
"users": [{
"userId": 123,
"name": "Ed Spencer",
"email": "ed#sencha.com"
}],
"metaData": {
"root": "users",
"totalProperty": 'count',
"successProperty": 'ok',
"messageProperty": 'msg'
}
}
You can also place any other arbitrary data you need into the metaData attribute which will be ignored by the Reader, but will be accessible via the Reader's metaData property (which is also passed to listeners via the Proxy's metachange event (also relayed by the store). Application code can then process the passed metadata in any way it chooses.
A simple example for how this can be used would be customizing the fields for a Model that is bound to a grid. By passing the fields property the Model will be automatically updated by the Reader internally, but that change will not be reflected automatically in the grid unless you also update the column configuration. You could do this manually, or you could simply pass a standard grid column config object as part of the metaData attribute and then pass that along to the grid. Here's a very simple example for how that could be accomplished:
// response format:
{
...
"metaData": {
"fields": [
{ "name": "userId", "type": "int" },
{ "name": "name", "type": "string" },
{ "name": "birthday", "type": "date", "dateFormat": "Y-j-m" }
],
"columns": [
{ "text": "User ID", "dataIndex": "userId", "width": 40 },
{ "text": "User Name", "dataIndex": "name", "flex": 1 },
{ "text": "Birthday", "dataIndex": "birthday", "flex": 1, "format": 'Y-j-m', "xtype": "datecolumn" }
]
}
}
The Reader will automatically read the meta fields config and rebuild the Model based on the new fields, but to handle the new column configuration you would need to handle the metadata within the application code. This is done simply enough by handling the metachange event on either the store or the proxy, e.g.:
var store = Ext.create('Ext.data.Store', {
...
listeners: {
'metachange': function(store, meta) {
myGrid.reconfigure(store, meta.columns);
}
}
});
That for the basics. Now the details for your data-structure:
first we need a converter function to read the custom data
convert: function(value,record) {
for(var i=0,ln=value.length;i<ln;i++) {
var item = value[i];
record.set(item.k,item.v);
}
return ''; let's save memory an drop it
}
and we can publish the basic fields (and columns (not displayed)) - but we don't need becaouse the metachange can handle it all
{ name: "SKU", type:"string") }, // don't forget to mark this as the idProperty in the reader and in the model
{ name: "type", type:"string") },
{ name: "attr", type:"auto", convert: convert() }
all fields & columns below are published by the server with metachange
"metaData": {
"fields": [
{ name: "SKU", type:"string") },
{ name: "type", type:"string") },
{ name: "attr", type:"auto", convert: convert() },
// and the dynamic datafields
{ name: "manufacturer", type:"string" },
{ name: "style", type:"string" },
// ... and so on
],
"columns": [
{ "text": "ID", "dataIndex": "SKU", "width": 40 },
{ "text": "ID", "dataIndex": "SKU", "width": 40 },
// and the dynamic datacolumns
{ "text": "Manufacturer", "dataIndex": "manufacturer" },
{ "text": "Style", "dataIndex": "stlye" },
// ... and so on
]
}
Edit:
I recommend to either create your own reader which transform the data to a normalized JSON before processing it further or your own Ext.data.Types type. Because I think it is a bit faster I recommend to create your own data-type. The downside in your case is, that the field with this property need to be always AFTER the dynamic field, otherwise the reader will override the dynamic fields.
Here is a snipped that I tested with 4.2.3
// create the new type
Ext.data.Types.DYNAMIC = {
convert: function(value, record) {
for (var i = 0, ln = value.length; i < ln; i++) {
var item = value[i];
record.data[item.k] = item.v;
}
return '';
},
type: 'dynamic',
sortType: Ext.data.SortTypes.none
};
// define a model
Ext.define('TestModel', {
extend: 'Ext.data.Model',
fields: [{name: "_id",type: "string"},
{name: "attr",type: "dynamic"}],
idProperty: '_id'
});
// create a store with the model assigned
Ext.create('Ext.data.Store', {
storeId: 'MyStore',
model: 'TestModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/data.json',
reader: {
idProperty: '_id',
type: 'json',
root: 'data'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Grid',
store: Ext.data.StoreManager.lookup('MyStore'),
columns: []
});
Ext.widget('window',{height: 200,width: 400, items: [grid ] }).show();
store.on('metachange', function(store, meta) {
grid.reconfigure(store, meta.columns);
});
And the data
{
"metaData": {
"idProperty": "_id",
"rootProperty": "data",
"fields": [
{ "name": "_id","type": "string" },
{ "name": "de", "type":"string" },
{ "name": "en", "type":"string" },
{ "name": "fr", "type":"string" },
{ "name": "attr", "type": "dynamic" }
],
"columns": [
{
"header": "de",
"dataIndex": "de"
},
{
"header": "en",
"dataIndex": "en"
}
,
{
"header": "fr",
"dataIndex": "fr"
}
]
},
"data":
[
{"_id": "MyTextId1",
"attr":[
{
"k": "de",
"v": "GermanText Sample"
},
{
"k": "en",
"v": "English Text Sample"
},
{
"k": "fr",
"v": "French Text Sample"
},
]
},
{"_id": "MyTextId2",
"attr":[
{
"k": "de",
"v": "GermanText Sample 1"
},
{
"k": "en",
"v": "English Text Sample 1"
},
{
"k": "fr",
"v": "French Text Sample1 1"
},
]
}
]
}
Edit:
This snipped is tested in 5.1 and it worked
Ext.data.Types.DYNAMIC = {
convert: function(value, record) {
for (var i = 0, ln = value.length; i < ln; i++) {
var item = value[i];
record.data[item.k] = item.v;
}
return '';
},
type: 'dynamic',
sortType: Ext.data.SortTypes.none
};
Ext.define('Ext.data.field.Dynamic', {
extend: 'Ext.data.field.Field',
alias: 'data.field.dynamic',
sortType: 'none',
isDynamicField: true,
convert: function(value, record) {
for (var i = 0, ln = value.length; i < ln; i++) {
var item = value[i];
record.data[item.k] = item.v;
}
return '';
},
getType: function() {
return 'dynamic';
}
});
Ext.define('TestModel', {
extend: 'Ext.data.Model',
fields: [{name: "_id",type: "string"},{name: "attr",type: "dynamic"}],
idProperty: '_id'
});
var store = Ext.create('Ext.data.Store', {
storeId: 'MyStore',
model: 'TestModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/qat/Content/TST/data.js',
reader: {
idProperty: '_id',
type: 'json',
rootProperty: 'data'
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
title: 'Grid',
store: Ext.data.StoreManager.lookup('MyStore'),
dockedItems: [{xtype: 'pagingtoolbar',store: Ext.data.StoreManager.lookup('MyStore'), dock: 'bottom',displayInfo: false}],
columns: []
});
Ext.widget('window',{height: 200,width: 400, items: [grid ] }).show();
store.on('metachange', function(store, meta) {
// Apply the column definitions to the Grid
grid.reconfigure(store, meta.columns);
});

fill jquery datatable with Json array MVC 4

i got a view with a jquery datatable, i want on a single button to repopulate the data from the table instantly with another Json list or whatever array he received from the controller.
This is the code in my view :
$.ajax({
type: "GET",
url: "EmpTruck/getJson/",
data: { search: station },
dataType: "Json",
error: function (xhr, status, error) {
alert(error);
},
success: function (json) {
alert(json.aaData);
var table = $(".dynamicTableEmployee").dataTable();
table.fnClearTable();
table.LoadDataRow(json);
}
});
This is the code from controller :
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult getJson()
{
List<Employees> list = new List<Employees>();
list = db.Employees.Where(c => c.Station.Equals("ATL")).ToList();
return this.Json(list, JsonRequestBehavior.AllowGet);
}
This code only clear the datatable.
I have set a breakpoint to see if there is something in the Json array and there is.
I don't know how to populate the datatable from the json array, do i need to serialize it ? Do the json need to be the same size as the datatable?
Thanks
If you are just looking to reload the data you can use the fnReloadAjax() API plug-in: http://datatables.net/plug-ins#api_fnReloadAjax
If you want to completely alter the table like change columns etc... I'd just nuke the old one and replace it with the new. Just paste the code into your script (before you initialise you table!), then whenever you want to reload the data, call fnReloadAjax() on the table object.
This example might help: http://datatables.net/examples/example_plugin_api.html
(from http://www.datatables.net/forums/discussion/52/load-new-data-via-ajax/p1)
<link href="#Url.Content("~/Content/Table.css")" rel="stylesheet" type="text/css" />
#section scripts
{
<script src="#Url.Content("~/Scripts/ datatable.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/test.js")" type="text/javascript"> </script>
}
<div id="tabs-SecDeal" style=" background-color: white">
<table id="secdeal" class="display">
<thead>
<tr>
<th style="background-color: #990033">col1</th>
<th style="background-color: #990033"> col2</th>
<th style="background-color: #990033"> col3 </th>
<th style="background-color: #990033"> col4</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4" class="dataTables_empty"></td>
</tr>
</tbody>
</table>
</div>
$(function () {
Loadtestview();
function Loadtestview () {
var divSecTable = $('#secdeal');
oSecTable = divSecTable.dataTable({
"processing": true,
"serverSide": true,
"aaSorting": [1, 'asc'],
"info": true,//localtable.bInfo,
"autoWidth": false,//localtable.AutoWidth,
"scrollY": 700,
"scrollX": "150%",
"scrollCollapse": true,
'destroy': true,
"pagingType": "full_numbers",
'lengthChange': false,
"searching": false,
'sAjaxSource': '../ReportsMvc/GetSecuritizationDeal',
"iDisplayLength": 100,
"columns": [
{ "targets": 0,"data":"col1","title":"col1", "className": "center textNoWrap" },
{ "targets": 1,"data":"col2","title":"col2", "className": "center textNoWrap" },
{ "targets": 2,"data":"col3","title":"col3", "className": "center textNoWrap" },
{ "targets": 3,"data":"col4","title":"col4", "className": "center textNoWrap" },
],
'fnServerData': function (sSource, aoData, fnCallback) {
aoData.push({ "name": "rgid", "value": $("#ddlBatchdate").val() });
$.get(sSource, aoData, function (rsp) {
fnCallback(rsp);
});
},
"fnInitComplete": function () {
new $.fn.dataTable.FixedColumns(oSecTable, { leftColumns: 4 });
}
});
}
});
[HttpGet]
public JsonResult GetSecuritizationDeal(jQueryDataTableParamModel param)
{
if (param.rgid <= 0)
{
return Json(new
{
sEcho = "1",
iTotalRecords = 0,
iTotalDisplayRecords = 0,
aaData = (IEnumerable<SecDealDatacs>)new List<SecDealDatacs>()
},
JsonRequestBehavior.AllowGet);
}
try
{
//No session cache for reports page!!!
List<SecDealDatacs> listObj = _bao.GetSecuritizationDeal(param.rgid);
if (listObj == null)
throw new HttpException(500, "Data Server Errors...");
int totalRecords = listObj.Count();
//Pagenation
IEnumerable<SecDealDatacs> listObjDisplay = listObj
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
var result = listObjDisplay.Select((o, index) => new
{
o.col1,
o.col2,
col3= o.col3.ToString("#,#"),
col4=o. col4.ToString("0.0000"),
}).ToList();
var listObj1 = result;
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = totalRecords,
iTotalDisplayRecords = totalRecords,
aaData = result
},JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
//log error into DB and File
throw new HttpException(500, ex.Message);
}
}
$(function () {
Loadtestview();
function Loadtestview () {
var divSecTable = $('#secdeal');
oSecTable = divSecTable.dataTable({
"processing": true,
"serverSide": true,
"aaSorting": [1, 'asc'],
"info": true,//localtable.bInfo,
"autoWidth": false,//localtable.AutoWidth,
"scrollY": 700,
"scrollX": "150%",
"scrollCollapse": true,
'destroy': true,
"pagingType": "full_numbers",
'lengthChange': false,
"searching": false,
'sAjaxSource': '../ReportsMvc/GetSecuritizationDeal',
"iDisplayLength": 100,
"columns": [
{ "targets": 0,"data":"col1","title":"col1", "className": "center textNoWrap" },
{ "targets": 1,"data":"col2","title":"col2", "className": "center textNoWrap" },
{ "targets": 2,"data":"col3","title":"col3", "className": "center textNoWrap" },
{ "targets": 3,"data":"col4","title":"col4", "className": "center textNoWrap" },
],
'fnServerData': function (sSource, aoData, fnCallback) {
aoData.push({ "name": "rgid", "value": $("#ddlBatchdate").val() });
$.get(sSource, aoData, function (rsp) {
fnCallback(rsp);
});
},
"fnInitComplete": function () {
new $.fn.dataTable.FixedColumns(oSecTable, { leftColumns: 4 });
}
});
}
});

Categories