I have a pretty simple grid with data source that retrieves data correctly
For that cause I have a schema.parse function defined
The problem is that when I try to update/create new row the schema.parse() called again and the parameter that is passed to it is a string that contains the HTML of my page. cannot really get what the hell is going on there.
thanks
var _dataSource = new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: layerDefProvider.getLayerUrlById("surveys") + "/query",
data: {
f: "json",
//token: token,
outFields: "*",
//outSR: 3857,
where: "1=1"
},
type: "POST"
},
create: function (options) {
console.debug("called");//never gets called
},
update: function (options) {
console.debug("called");//never gets called
},
destroy: function (options) {
console.debug("called");//never gets called
}
},
filter: {
field: "OBJECTID", operator: "eq", value: 0
},
schema: {
data:function(response) {
},
parse: function (data) {//on loading it is fine, on updating the data param is a string of my HTML of the page
var rows = [];
var features = data.features;
if (!features) {
return [];
}
for (var i = 0; i < features.length; i++) {
var dataRow = {};
dataRow.OBJECTID = features[i].attributes.OBJECTID;
dataRow.Name = features[i].attributes.Name;
dataRow.Date = features[i].attributes.Date;
dataRow.Comment = features[i].attributes.Comment;
rows.push(dataRow);
}
return rows;
},
model: {
id: "OBJECTID",
fields: {
OBJECTID: { type: "number", editable: false },
Name: { type: "string" },
Date: { type: "string" },
Comment: { type: "string" }
}
}
}
});
var _surveysPicker = $(config.table).kendoGrid({
toolbar: ["create","save"],
editable: true,
dataSource: _dataSource,
height: 300,
sortable: true,
selectable: "multiple",
columnMenu: true,
resizable: true,
columns: [{
field: "OBJECTID",
width: 40
}, {
field: "Name",
width: 40
}, {
field: "Date",
width: 40
}, {
field: "Comment",
width: 100
}]
});
You need to move your parse function inside read event if you need to parse data only on read action.
Related
I'm getting array of properties and I want to show all of them in grid.
How to do it? Is it possible?
This is my code:
function StartBuild(ProfileProperties) {
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
$(document).ready(function () {
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
$("#grid").kendoGrid({
dataSource: datasource,
pegable: true,
sortable: {
mode: "single",
allowUnsort: false
},
columns: [{
field: "name",
title: "name",
filterable: {
cell: {
enabled:true
}
}
}, {//[Bild, nameP, email,phonework, Mobile, ManagerName]
field: "email",
title: "email"
}, {
field: "phoneWork",
title: "phoneWork"
}, {
field: "Mobile",
title: "Mobile"
}, {
field: "Manager",
title: "Manager"
}],
filterable: {
mode: "row"
},
});
});
}
Only if I write details[0] it shows the first properties otherwise it doesn't show anything.
It looks like there are a couple of problems.
http://dojo.telerik.com/#Stephen/uVOjAk
First, the transport setup is incorrect. pageSize, batch, and schema are not part of the transport configuration...you need to take them out of the transport block and just have them in the datasource block.
You want:
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
}
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
});
Instead of(what you have):
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
Second, the details needs to be an array of objects, not an array of an array of an object.
You want:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details.push({ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] });
}
Instead of:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
Two other issues that are not directly causing a problem, but are incorrect are:
Your dataSource.schema configuration does not match your actual data at all. The schema really needs to match the fields of the actual data otherwise it cannot match up the configuration.
You spelled "pageable" wrong in the grid configuration.
I have working on Keno UI grid and I have added a comboBox as a column in the grid which also supports autocomplete feature. Apparently, comboBox is working fine but when I type half of world and focus out of the comboBox cell then it shows undefined. I have tried to handle it on combobox change event, but it is still showing undefined value? Below is my code for combobox and grid.
function productDropDownEditor(container, options) {
$('<input id="ProductDropDown" style="width:250px;" data-bind="value:' + options.field + '"/>')
.appendTo(container).kendoComboBox({
dataSource: dataSource,
autoBind: false,
dataTextField: 'ProductName',
dataValueField: 'ProductID',
filter: "contains",
suggest: true,
index: 3,
change: function (e) {
debugger;
var cmb = this;
// selectedIndex of -1 indicates custom value
if (cmb.selectedIndex < 0) {
cmb.value(0); // or set to the first item in combobox
}
},
close: function (e) {
debugger;
var cmb = this;
}
});
And here is following code for kendo grid.
$(function () {
$("#grid").kendoGrid({
columns: [
{
field: "Products", width: "250px",
editor: productDropDownEditor,
title: "Product",
template: "#=Products.ProductName#",
attributes: {
"class": "select2_single"
}
},
{ field: "PurchasePrice", width: "150px" },
{ field: "PurchaseQuantity", width: "150px" },
{ field: "SaleRate", title: "Sale Rate", width: "150px" },
{ field: "Amount", title: "Amount", width: "150px" },
{ command: "destroy", title: "Delete", width: "110px" },
],
editable: true, // enable editing
pageable: true,
navigatable: true,
sortable: true,
editable: "incell",
toolbar: ["create"], // specify toolbar commands
edit: function (e) {
//debugger;
//// var parentItem = parentGrid.dataSource.get(e.model.PurchaseID);
////e.model.set("ShipCountry", parentItem.Country);
//if (e.model.isNew()) {
// // set the value of the model property like this
// e.model.set("PropertyName", Value);
// // for setting all fields, you can loop on
// // the grid columns names and set the field
//}
},
//editable: "inline",
dataSource: {
serverPaging: true,
requestStart: function () {
kendo.ui.progress($("#loading"), true);
},
requestEnd: function () {
kendo.ui.progress($("#loading"), false);
},
serverFiltering: true,
serverSorting: true,
batch: true,
pageSize: 3,
schema: {
data: "data",
total: "Total",
model: { // define the model of the data source. Required for validation and property types.
id: "Id",
fields: {
PurchaseID: { editable: false, nullable: true },
PurchasePrice: { nullable: true },
PurchaseQuantity: { validation: { required: true, min: 1 } },
SaleRate: { validation: { required: true, min: 1 } },
Amount: { type: "number", editable: false },
Products: {
nullable: false,
validation: { required: true},
defaultValue: {ProductID:1, ProductName:"Googo" },
//from: "Products.ProductName",
parse: function (data) {
debugger;
if (data == null) {
data = { ProductID: 1};
}
return data;
},
type: "object"
}
}
}
},
batch: true, // enable batch editing - changes will be saved when the user clicks the "Save changes" button
change: function (e) {
debugger;
if (e.action === "itemchange" && e.field !== "Amount") {
var model = e.items[0],
type = model.Type,
currentValue = model.PurchasePrice * model.PurchaseQuantity;//formulas[type](model);
if (currentValue !== model.Amount) {
model.Amount = currentValue;
$("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(4)").text(currentValue);
}
//if (e.field == "Products") {
// $("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(0)").text(model.Products);
//}
}
},
transport: {
read: {
url: "#Url.Action("Read", "Purchase")", //specify the URL which should return the records. This is the Read method of the HomeController.
contentType: "application/json",
type: "POST", //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
},
parameterMap: function (data, operation) {
debugger;
if (operation != "read") {
// post the products so the ASP.NET DefaultModelBinder will understand them:
// data.models[0].ProductID = data.models[0].Product.ProductID;
var result = {};
// data.models[0].ProductID = $("#ProductDropDown").val();
for (var i = 0; i < data.models.length; i++) {
var purchase = data.models[i];
for (var member in purchase) {
result["purchaseDetail[" + i + "]." + member] = purchase[member];
}
}
return result;
} else {
var purchaseID = $("#hdnPurchaseId").val();
//output = '{ purchaseID: ' + purchaseID + '}';
data.purchaseID = purchaseID; // Got value from MVC view model.
return JSON.stringify(data)
}
}
}
},
}).data("kendoGrid");
I am using ajax api calls for getting data from a SQL database as below:
function getJsonData(type, period1, period2, id) {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
type: "GET",
url: createURL(type, period1, period2, id),
dataType: "json",
contentType: "application/json; chartset=utf-8"
}
},
});
return dataSource;
}
Using the above datasource, I am creating a Kendo chart as below:
function stepsChart(container, title, period1, period2) {
var dSource = getJsonData("Summary", period1, period2, "<% = id %>");
$(container).kendoChart({
dataSource: dSource,
seriesColors: ["orangered"],
chartArea: {
background: ""
},
title: {
text:title
},
legend: {
visible: false
},
chartArea: {
background: ""
},
seriesDefaults: {
type: "column",
gap:5
},
series: [{
name: "steps",
field: "steps",
categoryField: "createddate",
aggregate: "sum"
}],
categoryAxis: {
type: "date",
baseUnit: getBaseUnit(period1, period2),
labels: {
rotation: -45,
dateFormats: {
days : getDateFormat(period1, period2),
weeks: getDateFormat(period1, period2),
years: getDateFormat(period1, period2)
},
step: getSteps(period1, period2)
},
majorGridLines: {
visible: false
}
},
valueAxis: {
majorGridLines: {
visible: true
},
labels: {
template: "#= kendo.format('{0}',value/1000)#K"
},
title: {
text: "Steps"
}
}
});
}
I also want to use the data from the above datasource for showing a summary of the information in a div below the chart. But if I add something like
var k = dSource.data;
there will not be any data in k. Is there a way to get the json data in the function which creates the chart?
DataSource.data is a function. I think your code should be:
var k = dSource.data();
That would also return an empty array if the data hasn't already been read, so you might need to do:
dSource.one("change", function () {
var k = dSource.data();
});
dSource.fetch();
because the .fetch() is async.
What i am trying to do on Kendo grid is to pass selected column's id to controller and returned data will be datasource of 2nd kendo grid on same page without any page load or refresh.
Everthing works well on server side.Desired data Data will be returned to view as json format but 2nd grid cannot show the data.
Js:
e.preventDefault();
var tr = $(e.target).closest("tr"); // get the current table row (tr)
var dataItem = this.dataItem($(e.target).closest("tr"));
//Data that coming from kendo grid's selected column
var code = dataItem.CODE;
// alert(code);
var crudServiceBaseUrl = "/Administrator/DefinitionDetailRead/",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl,
data: { DefinitionCode: code },
dataType: "json"
},
update: {
url: crudServiceBaseUrl + "/Products/Update",
dataType: "json"
},
destroy: {
url: crudServiceBaseUrl + "/Products/Destroy",
dataType: "json"
},
create: {
url: crudServiceBaseUrl + "/Products/Create",
dataType: "json"
},
},
//batch: true,
pageSize: 9,
schema: {
model: {
ID: "ID",
fields: {
ID: { editable: false, nullable: true },
DESCRIPTION: { validation: { required: true } }
}
}
}
});
$("#detailsGrid").kendoGrid({
dataSource: dataSource,
attributes: {
style: "padding-left: 0px; font-size: 14px"
},
pageable: {
refresh: false,
pageSizes: false,
buttonCount: 5
},
toolbar: ["create"],
columns: [
{
field: "DESCRIPTION",
title: "DESCRIPTION",
//filterable: {
// ui: titleFilter
//},
width: "200px"
},
{ command: ["edit", "destroy"], title: "Operation", width: "100px" }],
editable: "popup"
});
Controller: Everthing works here.
public ActionResult DefinitionDetailRead([DataSourceRequest] DataSourceRequest request, string DefinitionCode)
{
DataSourceResult result = null;
var lang = CultureHelper.GetCulture();
using (var client = SoapProxyFactory.CreateDSrvGDSoapClient())
{
var pSize = request.PageSize;
var pIndex = request.Page;
var totalsize = client.GetDefinitionDetailsTotalCount(DefinitionCode, lang);
var dataresult = client.GetDefinitionDetails(DefinitionCode, lang, false);
var items = dataresult.RootResults;
result = items.ToDataSourceResult(request, totalsize, null);
}
return Json(result, JsonRequestBehavior.AllowGet);
#endregion
}
Json Data that coming from controller :
{"Data":[{"ExtensionData":{},"CODE":"ABNORMAL","CODETYPE":null,"COUNT":0,"DESCRIPTION":"Abnormal (check under Resp)","ENTRYDATE":null,"ID":"1b0a0cd8-8fed-4b34-9054-1e73942a16d2","ISACTIVE":false,"ISDEFAULT":false,"ISSELECTED":false,"LANG":null,"NOTE1":null,"NOTE2":null,"ORDERINDEX":null,"PARENTDESCRIPTION":null,"PARENTID":"00000000-0000-0000-0000-000000000000","REFERENCEID":"3df1f5d7-bc04-4554-bf01-1a9d5b95eebb","VALUE":null}
The problem is that you are not saying where in the returned data is actually the array with the data.
Your model definition should be:
schema: {
data: "Data",
model: {
ID: "ID",
fields: {
ID: {
editable: false,
nullable: true
},
DESCRIPTION: {
validation: { required: true }
}
}
}
}
Where I've added data: "Data" informing KendoUI Grid that need to check Data.
Your example modified here : http://jsfiddle.net/OnaBai/ZEndW/
Specify the type of the dataSource to be "aspnet-mvc". Before that make sure that you have loaded the kendo.aspnetmvc.min.js file.
Also you have to specify the schema configuration.
It should look something like this:
"dataSource": {
"transport": {
"prefix": "",
"read": {
"url": ""
}
},
"pageSize": 20,
"page": 1,
"total": 0,
"type": "aspnetmvc-ajax",
"schema": {
"data": "Data",
"total": "Total",
"errors": "Errors",
"model": {
"fields": {
"id": {
"type": "number"
},
"quantity": {
"type": "number"
},
"name": {
"type": "string"
}
}
}
}
}
I'm currently implementing a kendo grid and i'm populating it with local data.
That is; I have generated a JSON string from my action and supplying that string on the view page.
In the end i would like to know if it is possible to implement full CRUD functions with local data?
here's a sample of the code written so far;
<div id="example" class="k-content">
<div id="grid"></div>
<script>
$(document).ready(function() {
var myData = ${coursemodules},
dataSource = new kendo.data.DataSource({
data: myData,
batch: true,
pageSize: 30,
schema: {
model: {
id: "id",
fields: {
id: { editable: false, nullable: true},
name: { type: "string", validation: { required: true }},
qualificationLevel: { type: "string", validation: { required: true }},
description: { type: "string", validation: { required: true }},
published: { type: "boolean" },
gateApprove: { type: "boolean" },
duration: { type: "number", validation: { min: 1, required: true } },
academicBody: { type: "string" }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
height: 350,
scrollable: true,
sortable: true,
pageable: true,
toolbar: ["create", "save", "cancel"],
columns: [
{
field: "id",
title: "ID",
width: '3%'
},
{
field: "name",
title: "Course Title",
width: '20%'
},
{
field: "description",
title:"Description",
width: '35%'
},
{
field: "published",
title: "Published",
width: '7%'
},
{
field: "gateApprove",
title: "Gate Approve",
width: '7%'
},
{
field: "duration",
title: "Duration",
width: '5%'
},
{
field: "academicBody.shortName",
title: "Academic Body",
width: '10%'
}
],
editable: true
});
});
</script>
</div>
I have realise that for the datasource, you have to declare transport to implement the CRUD. However, I need to declare "data". I tried declaring both transport and data. That doesn't seem to work.
Yes you can Here is JSFiddle Hope this will help you.
// this should be updated when new entries are added, updated or deleted
var data =
[{
"ID": 3,
"TopMenuId": 2,
"Title": "Cashier",
"Link": "www.fake123.com"},
{
"ID": 4,
"TopMenuId": 2,
"Title": "Deposit",
"Link": "www.fake123.com"}
];
$("#grid").kendoGrid({
dataSource: {
transport: {
read: function(options) {
options.success(data);
},
create: function(options) {
alert(data.length);
},
update: function(options) {
alert("Update");
},
destroy: function(options) {
alert("Destroy");
alert(data.length);
}
},
batch: true,
pageSize: 4,
schema: {
model: {
id: "ID",
fields: {
ID: {
editable: false,
nullable: true
},
TopMenuId: {
editable: false,
nullable: true
},
Title: {
editable: true,
validation: {
required: true
}
},
Link: {
editable: true
}
}
},
data: "",
total: function(result) {
result = result.data || result;
return result.length || 0;
}
}
},
editable: true,
toolbar: ["create", "save", "cancel"],
height: 250,
scrollable: true,
sortable: true,
filterable: false,
pageable: true,
columns: [
{
field: "TopMenuId",
title: "Menu Id"},
{
field: "Title",
title: "Title"},
{
field: "Link",
title: "Link"},
{
command: "destroy"}
]
});
When binding local data, the Grid widget utilizes an abstraction that represents a local transport. Therefore, it does not require a custom transport; modifications made in the grid are reflected to the bound data source. This includes rollbacks through a cancellation.
There is fully functional example of this in telerik documentation
What you need is define transport block in dataSource object with custom CRUD funtions which update local source.
transport: {
create: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
options.data.ID = localData[localData.length-1].ID + 1;
localData.push(options.data);
localStorage["grid_data"] = JSON.stringify(localData);
options.success(options.data);
},
read: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
options.success(localData);
},
update: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
for(var i=0; i<localData.length; i++){
if(localData[i].ID == options.data.ID){
localData[i].Value = options.data.Value;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(options.data);
},
destroy: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
for(var i=0; i<localData.length; i++){
if(localData[i].ID === options.data.ID){
localData.splice(i,1);
break;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(localData);
},
}