Kendo UI .. translate datasource data before sending to Grid. - kendo-ui

I have some data that looks like:
{
"Data":[
[
{"Key":"Commonality","Value":0},
{"Key":"Item","Value":"ExampleItem"
]
"Total":2,
"AggregateResults":null,
"Errors":null
]
}
The format of the JSON cannot be changed.
I need to somehow translate the data to:
{
"Data":[
[
{ Commonality:0}, Item:"ExampleItem"}
]
"Total":2,
"AggregateResults":null,
"Errors":null
]
}
Does Kendo UI have a callback I can use to process the data and pass it back to the datasource once it's been received?

Literally moments after posting my question I realised that I was 99% there!
I was just missing the Total, AgggregateResults etc from my translate function
function parseFunction(response) {
var result = [];
var data = response.Data;
for (var irow = 0; irow < data.length; irow++) {
var newRecord = {};
for (var icol = 0; icol < data[irow].length; icol++) {
var record = data[irow][icol];
newRecord[record.Key] = record.Value;
}
result.push(newRecord);
}
response.Data = result;
return response;
}
And here is it being used in a data source :)
function CreateDataSource() {
var source = new kendo.data.DataSource({
transport: {
read: {
url: 'GetFixturesReport',
}
},
pageSize: itemsPerPage,
type: 'aspnetmvc-ajax',
serverPaging: true,
serverFiltering: true,
serverSorting: true,
schema: {
data: 'Data',
total: 'Total',
errors: 'Errors',
//model: { id: 'Fixture' },
parse: parseFunction,
}
});
return source;
}
I now have a way to supply C# Dynamic objects to a grid view so that I can have truly dynamic columns. It has taken me a lot of experimentation though!
Hope this helps someone else.
Kiran

Related

jsGrid preload pages ahead

I want to load items by page since I have tables with large amount of data, but I don't want to load items for each page once the user clicks it.
Instead, I rather preload 1000 items (for example) ahead and only fetch more results if the user moves to a page I still didn't fetch the data for.
Is it possible?
I found a way to solve it.
Here is the basic logic:
Create a local data cache object that will hold arrays of results for each page.
When fetching data from the server, always return data for a few pages ahead and store them in the local cache object
Write a method for the controller.loadData that will check to see if you have the desired page results in the local cache object, if so - return that array, if not - return a promise that will fetch the results with some extra data for a few pages ahead.
An example of the local cache object snapshot:
{
"1": [{name: "ff"}, {name: "fdd"}],
"2": [{name: "fds"}, {name: "dsr"}],
"3": [{name: "drr"}, {name: "ssr"}]
}
script section
<script type="text/javascript">
$(document).ready(function () {
List();
});
function List() {
//$(function () {
loadjsgrid();
$("#jsGrid").jsGrid({
height: "auto",
width: "100%",
filtering: true,
editing: false,
sorting: true,
autoload: true,
paging: true,
pageSize: 10,
pageButtonCount: 5,
pageLoading: true,
controller: {
loadData: function (filter) {
var startIndex = (filter.pageIndex - 1) * filter.pageSize;
var d = $.Deferred();
$.ajax({
type: 'GET',
url: '#Url.Action("[ActionName]", "[Controllername]")',
data: filter,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
if (data.Message == "Failed") {
data.Result = [];
data.Count = 0;
}
console.log(data);
d.resolve(data);
}
});
return d.promise().then(function (q) {
return {
data: q.Result,
itemsCount: q.Count
}
});
}
},
},
fields: [
{ name: "rct_no", type: "text", title: 'Serial Number', autosearch: true, width: '10%' }
],
});
$("#pager").on("change", function () {
var page = parseInt($(this).val(), 10);
$("#jsGrid").jsGrid("openPage", page);
});
}
Controller section
public ActionResult getList(int pageIndex = 1, int pageSize = 10)
{
try
{
var query = #" from rd_receipt_header
var irList = DAL.db.Fetch<[className]>(pageIndex, pageSize, #"select * " + query );
var count = DAL.db.ExecuteScalar<int>("select count(*) " + query);
return Json(new { Message = "Success", Result = irList, Count = count }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex) { return Json(new { Message = "Failed", Result = ex.Message }, JsonRequestBehavior.AllowGet); }
I am using ajax to get data from server as ajax format

Kendo UI grid databinding using mvvm pattern

I am new to Kendo UI, i want to bind kendo ui grid using MVVM pattern, and my datasource is sharepoint list. so i am calling sharepoint list data through CSOM javascript code. I tried different solution but nothing seems to working. I have collection of data from sharepoint list.
var divisionListData = [];
//var divisionsViewModel;
var viewModel = kendo.observable({
isVisible: true,
onSave: function (e) {
alert('hi');
kendoConsole.log("event :: save(" + kendo.stringify(e.values, null, 4) + ")");
},
divisions: new kendo.data.DataSource({
// schema: {
data: divisionListData,
schema: {
data: "rows",
model: {
fields:
{
ID: { type: "string" },
DivisionName: { type: "string" },
DivisionCode: { type: "string" },
OpenDate: { type: "datetime" },
CloseDate: { type: "datetime" },
Description: { type: "string" },
}
}
},
batch: true,
transport: {
read: function (e) {
return divisionListData;
}
})
})
function ReadList() {
//this.set("isDisabled", false);
var clientContext = new SP.ClientContext.get_current();
// denote that we will be performing operations on the current web
var web = clientContext.get_web();
// denote that we will be querying the "Business Divisions" custom SharePoint list
var divisionsList = web.get_lists().getByTitle("Divisions");
// create a CAML query (blank means just return all items)
var camlQuery = new SP.CamlQuery();
// denote that the operation we want to perform is getItems() on the list
var divisionsListItems = divisionsList.getItems(camlQuery);
var fields = 'Include(ID,DivisionCode, DivisionName, OpenDate, CloseDate, Description)';
clientContext.load(divisionsListItems, fields);
clientContext.executeQueryAsync(function () {
// get the list item enumerator
var listItemEnumerator = divisionsListItems.getEnumerator();
// loop through the items in our custom
// "Divisions" SharePoint list
var listItem;
while (listItemEnumerator.moveNext()) {
var division = new Division();
// get the list item we are on
listItem = listItemEnumerator.get_current();
// get the divisions
division.ID = listItem.get_item("ID");
// var lookup_DivisionCode = listItem.get_item("DivisionCode").get_lookupValue();
//lookup_DivisionCode.get_l
var divisionLookupField = new SP.FieldLookupValue();
divisionLookupField = listItem.get_item("DivisionCode");
//var test = divisionLookupField.$2d_1;
if (divisionLookupField != null)
division.DivisionCode = divisionLookupField.$2d_1;
division.DivisionName = listItem.get_item("DivisionName");
division.Description = listItem.get_item("Description");
division.OpenDate = listItem.get_item("OpenDate");
division.CloseDate = listItem.get_item("CloseDate");
divisionListData.push(division);
kendo.bind($("body"), viewModel);
}
})
}
You are pretty close, instead of returning the array inside the read: function(e), you need to call
e.success(yourArrayOfData);

keep the Ids of selected results of Kendo UI Autocomplete in a hidden input

I wrote this code to use kendo UI autocomplete. I need to show the title of the selected result in the textbox and keep the if in some hidden input, how can I get the id. it seems the select doesn't work.
$("[data-autocomplete]").each(function () {
var luurl = $(this).attr('data-lookupurl');
var thisElemt = $(this);
$(this).kendoAutoComplete({
minLength: 3,
separator: ", ",
dataTextField: "title",
select: function (e) {
var selectedOne = this.dataItem(e.item.Index());
console.log(kendo.stringify(selectedOne));
},
dataSource: new kendo.data.DataSource({
serverFiltering: true,
serverPaging: true,
pageSize: 20,
transport: {
read: luurl,
dataType: "json",
parameterMap: function (data) {
return { title: thisElemt.val() };
},
schema: {
model: {
id: "id",
fields: {
id: { type: "id" },
title: { type: "string" }
}
}
}
}
})
});
});
There is a typo error, you should use: e.item.index() instead of e.item.Index() (index is lowercase).
So the select function would be:
select : function (e) {
var selectedOne = this.dataItem(e.item.index());
console.log(kendo.stringify(selectedOne));
},
and easier way is :
var autocomplete = $("#autoCompleteId").data("kendoAutoComplete");
console.log(autocomplete.listView._dataItems[0]);
you can access to select data item in autocomplete.listView._dataItems[0] object
you can use script
<script>
$(document).ready(function () {
$("#categories").change(function () {
var url = '#Url.Content("~/")' + "Limitations/ThanaByDistrict_SelectedState";
var ddlsource = "#categories";
var ddltarget = "#target";
$.getJSON(url, { Sel_StateName: $(ddlsource).val() }, function (data) {
$(ddltarget).empty();
$(ddltarget).val(data);
});
});
});
</script>
in controller like
// Get selected combox value
public JsonResult ThanaByDistrict_SelectedState ( Guid Sel_StateName )
{
JsonResult result = new JsonResult ( );
objects temp=db . objects . Single ( m => m . ob_guid == Sel_StateName );
result . Data = temp.ob_code;
result . JsonRequestBehavior = JsonRequestBehavior . AllowGet;
return result;
}
For details you can see this LINK

Highcharts multiple series from json

My JSON looks like:
[[[773,1363709520],[774,1363709580]],[[1546,1363709520],[1548,1363709580]]]
I would like highcharts to create a new series every time it reaches a new JSON array: [[1546,1363709520],[1548,1363709580]]
I have a hard coded version, but making my data[[]] is not helping...
$(function () {
var data = [];
var data1 = [];
$.ajax({
url: "http://localhost:8080/vdm-stats-core/stats/metrics?from=2&src=org.example.fib&customer=customer0&server=server0&metric=responses.count",
dataType: "jsonp", // Notice! JSONP <-- P (lowercase)
jsonp: "callback",
success: function (inData) {
console.log(inData[0][1][0]);
var xval = new Date();
for (a = 0; a < inData.length; a++) {
for (i = 0; i < inData[a].length; i++) {
var yval = inData[a][i][0];
xval = inData[a][i][1];
var x = [xval, yval];
if (a == 0) {
data.push(x);
}
if (a > 0) {
data1.push(x);
}
}
}
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
title: {
text: 'Test',
},
rangeSelector: {
selected: 1
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'Customer0',
data: data
}, {
name: 'Customer1',
data: data1
}]
});
},
error: function () {
console.log(arguments);
}
});
});
Please help!
I tried to understand your code, here's my intepretation;
function success(inData) {
var customerNr,
timestamp,
VALUE = 0,
TIMESTAMP = 1,
series = {},
len = inData.length,
yval,
item;
for (customerNr = 0; customerNr < len; customerNr++) {
// Init series object literal for customer
series[customerNr] = {
name : 'Customer '+customerNr.toString(),
data : []
};
// Setup data for customer
for (item = 0; item < inData[customerNr].length; item++) {
yval = inData[customerNr][item][VALUE];
timestamp = inData[customerNr][item][TIMESTAMP];
series[customerNr].data.push([timestamp,yval]);
}
// Add series, but redraw only on last customer
chart.addSeries(series[customerNr],customerNr===len-1);
}
};
You recycle the series object for each customer, but I've added a customerNr property. addSeries method in Highchart will by default redraw chart (http://api.highcharts.com/highcharts#Chart.addSeries()). I've selected to only redraw chart on last customer. Forked fiddle example at; http://jsfiddle.net/hkskoglund/VVLNV/
The important thing to keep in mind is that the series object is already a json object...
So the easiest thing to do, assuming you control the creation of the json file, is format the json output as the entire series object:
[{ name: 'Customer0', data: [[773,1363709520],[774,1363709580]] }, { name: 'Customer1', data: [[1546,1363709520],[1548,1363709580]] }]
and then:
series: myData
I got it to work:
Had to reset my series data.
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
title: {
text: 'Test',
},
rangeSelector: {
selected: 1
},
xAxis: {
type: 'datetime'
},
series: []
});
$.ajax({
url: "http://localhost:8080/vdm-stats-core/stats/metrics?from=200&src=org.example.fib&customer=customer0&server=server0&metric=responses.count",
dataType: "jsonp", // Notice! JSONP <-- P (lowercase)
jsonp: "callback",
success: function (inData) {
var xval = new Date();
var series = {
name: 'Customer',
data: []
}
for (a = 0; a < inData.length; a++) {
for (i = 0; i < inData[a].length; i++) {
var yval = inData[a][i][0];
xval = inData[a][i][1];
var x = [xval, yval];
series.data.push(x);
}
chart.addSeries(series);
series.data = [];
}
},
error: function () {
console.log(arguments);
}
});
});

ember ajax calls with promisses access result in templates and controller

I'm making a call to the server to get some data via an ajax request and I use a promise. While my template automatically updates as soon as the data is returned, I'm unlucky accessing the data in the controller, as I don't know exactly when it's there.
To resolve I can make an additional ajax call in the controller to get the same data but that feels ugly. Is there a nicer way to know when to access the data in the controller? As a work around I tried to call the function that needs the data on the didInsertElement but that didn't solve it.
App.ActiveDataSet = Ember.Object.extend({
progress: 0
});
App.ActiveDataSet.reopenClass({
findAll: function(project_id) {
var result = [];
$.ajax({
url: '/active_data_sets.json',
type: 'GET',
data: {'project_id': project_id}
}).then(function(response) {
response.active_data_sets.forEach(function(newset) {
result.addObject(App.ActiveDataSet.create(newset));
});
});
return result;
}
});
App.MapviewShowRoute = Ember.Route.extend({
setupController: function(controller, model) {
this.controllerFor('activedatasetIndex').set('content', App.ActiveDataSet.findAll(model.id));
}
});
App.MapviewShowController = Ember.ObjectController.extend({
needs: ['activedatasetIndex'],
content: null,
dataSets: [],
createDataSets: function() {
// create the datasets
for (var counter = 0; counter < this.get('controllers.activedatasetIndex.content').length; counter++) {
alert(dataSets[counter].ds.name);
}
}
});
App.MapviewShowView = Ember.View.extend({
map: null,
didInsertElement: function() {
var map = null;
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(52.368892, 4.875183),
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(this.$('#map_canvas').get(0), myOptions);
this.set('map', map); //save for future updations
var h = $(window).height(),
offsetTop = 60; // Calculate the top offset
$('#map_canvas').css('height', (h - offsetTop));
// get the datasets
this.controller.createDataSets();
}
});
Have you tried continuing the promises chain:
App.ActiveDataSet.reopenClass({
findAll: function(project_id) {
return $.ajax({
url: '/active_data_sets.json',
type: 'GET',
data: {'project_id': project_id}
}).then(function(response) {
var result = [];
response.active_data_sets.forEach(function(newset) {
result.addObject(App.ActiveDataSet.create(newset));
});
return result;
});
}
});
App.MapviewShowRoute = Ember.Route.extend({
setupController: function(controller, model) {
App.ActiveDataSet.findAll(model.id).then(function(content) {
this.controllerFor('activedatasetIndex').set('content', content);
});
}
});

Resources