Kendo UI Grid with object ID translation - json

I'm trying to make a grid with KendoUI with external data via JSON (php+mysql engine) from TABLE A and one of columns of these data, get text labels from another TABLE B.
Example, data are: idPermission=1, user_id=1, business_unit_id=1, permission=10
The user_id=1 I want get from another table (Users) their names, 1=John Doe, 2=Martin Brown.
I want to see "John Doe" instead id 1 in the visualization of grid, and "Martin Brown" instead id 2. When inline (or popup) editing of the records I've already reached the target, and I've a select box with the names and not the ids!
Here is my code:
<script>
$(function() {
var crudServiceBaseUrl = "http://localhost/ajax/";
var dataTable = "UsersPermissions";
// This is the datasource of the grid
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "table_action.php?op=R&tbl="+dataTable,
dataType: "json"
},
update: {
url: crudServiceBaseUrl + "table_action.php?op=U&tbl="+dataTable,
type: "POST"
},
destroy: {
url: crudServiceBaseUrl + "table_action.php?op=D&tbl="+dataTable,
type: "POST"
},
create: {
url: crudServiceBaseUrl + "table_action.php?op=C&tbl="+dataTable,
type: "POST"
}
},
batch: true,
pageSize: 10,
schema: {
model: {
id: "idPermission",
fields: {
idPermission: { editable: false, nullable: true },
user_id: { validation: { required: true } },
business_unit_id: {},
permission: { validation: { required: true } },
}
}
}
});
// This is the datasource of the user_id column
usersSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "table_action.php?op=R&tbl=Users",
dataType: "json"
}
},
batch: true,
schema: {
model: {
id: "idUser",
fields: {
idUser: {},
email: {},
password: {},
name: {},
last_login: {},
status: {}
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
sortable: {
mode: "single",
allowUnsort: false
},
reorderable: true,
resizable: true,
scrollable: false,
toolbar: ["create"],
columns: [
{
field: "user_id",
editor: function (container, options) { // This is where you can set other control types for the field.
$('<input name="' + options.field + '"/>').appendTo(container).kendoComboBox({
dataSource: usersSource,
dataValueField: "idUser",
dataTextField: "name",
});
},
title: "ID Utente"
},
{ field: "business_unit_id", title: "Business Unit"},
{ field: "permission", title: "Permission"},
{ command: ["edit", "destroy"], width: "230px"}],
editable: "inline"
});
});
</script>
How I can make the same thing I've done in editing mode, in view mode?

For achieving that you have to first edit the query of the read operation seeing your sample data it must be like this
SELECT a.idPermission, b.name, a.business_unit_id, a.permission
FROM TABLE_A AS a
JOIN TABLE_B(users) AS B ON a.user_id=b.user_id;
json encode the data and send to client
and in your kendo grid change column user_id to name

I know you were asking about the HTML/JavaScript way, but using MVC, this is a good, alternative way to do it:
http://decisivedata.net/kendo-ui-grid-and-entity-framework-code-first-foreign-key-fields/

Related

Prevent Kendo Grid from auto saving

How can I stop the kendo grid/datasource automatically posting changes to the server?
I've tried intercepting Grid's saveChanges but it isn't being triggered by the Updated command. As per the docs, DataSource's auto-sync by default should be false, but I went ahead and set it anyway but to no effect.
$("#items-grid").kendoGrid({
dataSource: {
autoSync: false,
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("
ItemList ", "
PurchaseRequisition ", new {prId = #Model.Id }))",
type: "POST",
dataType: "json",
},
update: {
url: "#Html.Raw(Url.Action("
ItemEdit ", "
PurchaseRequisition "))",
type: "POST",
dataType: "json",
}
},
sync: function(e) {
console.log("sync complete");
},
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
fields: {
/...
}
}
},
},
saveChanges: function(e) {
// not fired from Update command
e.preventDefault();
},
columns: [{
// ...
}, {
command: [{
name: "edit",
text: {
edit: "Edit",
update: "Update",
cancel: "Cancel"
}
}],
width: 100
}]
});
});
You can try with dataSource batch set to true.
var dataSource = new kendo.data.DataSource({
transport: {...},
batch: true
...}
$("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
height: 550,
toolbar: ["create", "save", "cancel"],
columns: [...],
editable: true
});
NOTE: this is inline editing.
You can see an example on the official page: Batch editing

Pagination using kendo grid does not work on page load

In my js. i am loading data using kendoGridOptions. I have mapped the data source which fetches all the records. I have configured pageable = true. However noticed that when page load the pagination option are not available they become available only on when i sort one of the columns. following is the configuration of my grid and data source
var enhancedGridOptions = mydataKendoGridManager.kendoGridOptions({
dataSource: myGridDataSource,
sortable: true,
scrollable: true,
editable:false,
resizable: true,
reorderable: true,
pageable: true,
columnResize: function (e) {
adjustLastColumn(e, this);
},
columns:
[
{
field: "dealType",
title: $.i18n.prop('buyType.label'),
width: "108px"
},
{
field: "myStatus",
title: $.i18n.prop('myStatus.label'),
width: "105px"
},
{
field: "action",
title: $.i18n.prop('action.label'),
width: "105px"
},
],
pdf:
{
fileName: "my_List_" + (new Date()).toString(myformat + "_HH:mm") + ".pdf",
allPages: true,
},
excel:
{
fileName: "my_List_" + (new Date()).toString(myformat + "_HH:mm") + ".xlsx",
allPages: true,
}
}
and my data source is configured as below
transport: {
read: function (e) {
myapi.rootGet("data/mylist?dealId=" + id, function (response) {
var data;
// console.log(response.data)
if (_.isString(response.data)) {
response.data = JSON.parse(response.data);
data = response.data;
setTimeout(function () {
e.success(data);
}, 10000);
}
else {
e.error("XHR response", response.status, JSON.parse(response.data));
}
});
},
},
schema:
{
model: {
id: "id",
fields: {
dealType: {
type: "string"
},
myStatus: {
type: "string"
},
action: {
type: "string"
},
}
},
parse:function(data)
{
return parseData(data);
}
},
serverSorting: false,
serverFiltering: false,
serverPaging: false
};
appreciate if someone can guide what is missing on pagination that does not work on page load.
Thanks,
Anjana
If you are getting "NaN - NaN of 500 items" like error at left bottom corner in grid, then you should add pageSize in dataSource Property.
var enhancedGridOptions = mydataKendoGridManager.kendoGridOptions({
dataSource: {
data: myGridDataSource,
pageSize: 50
},
....
....
....
pageable: {
pageSizes: [20, 30, 50, 100],
buttonCount: 5
}
});

Kendo Grid UI transport.destroy is not firing the service in datasource

I am new to Kendo UI, While I am using the Kendo Grid UI which is consuming the service, the read operation is working fine and the Grid is populated with the data from services but the delete operation is not working
I have tested the delete service using the fiddler getting a perfect response,but I confused why the delete button in kendo grid is not firing the endpoint
I struggled for past one week but no improvement
This is my code,
var carsDataSource1 = new kendo.data.DataSource(
{
batch: true,
transport: {
read: {
url: "/DesktopModules/MyServicesTest/API/DropData/Drop",
dataType: "json",
type: "GET",
contentType: "application/json; charset=utf-8",
},
destroy: {
url: function(options)
{
return 'DesktopModules/MyServicesTest/API/DeleteCategory/
Delete' + options.models[0].id;
},
dataType: "json",
type: "DELETE"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
var CategoryID = options.models[0].id;
console.log(CategoryID);
return CategoryID;
}
}
},
shema:
{
model: {
id: "CategoryID",
field: {
CategoryID:
{
editable: false,
nullable: true,
type: "number"
},
CategoryName:
{
editable: false,
nullable: false,
type: "string"
},
}
}
}
});
$("#grid1").kendoGrid({
dataSource: carsDataSource1,
height: "500px",
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns: [
{
field: "CategoryID",
title: "number "
},
{
field: "CategoryName",
title: "Name"
},
{ command:"destroy"}
],
toolbar: ["create"],
editable: "inline",
destroy:true,
});
});

Web API Odata not returning correct metadata

I'm using OData v4 with Web API to communicate with my AngularJS web application.
More specifically I'm trying to display my data using Kendo UI Grid.
My problem is, that my Web API does not return the correct metadata, resulting in Kendos datasource not being able to display the data.
I'm doing paging, and to do that I need the "count" property in my response for Kendo UI Grid datasource to be able work properly.
The response I'm expecting the Web API should look something like this:
http://docs.oasis-open.org/odata/odata-json-format/v4.0/errata02/os/odata-json-format-v4.0-errata02-os-complete.html#_Toc403940644
However, the result I'm seeing in the response is:
{
"#odata.context":"http://localhost:1983/odata/$metadata#TestReports","value":[
{
"Id":1,"Name":"Test Testesen","Purpose":"Kendo UI Grid Test","Type":"Rumraket","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":2,"Name":"Gunner Testesen","Purpose":"OData Web API Test","Type":"Sutsko","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":3,"Name":"Bertram Didriksen","Purpose":"Server Paging Test","Type":"Flyver","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":4,"Name":"Oluf Petersen","Purpose":"Test","Type":"B\u00e5d","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":5,"Name":"Alfred Butler","Purpose":"Opvartning","Type":"Batmobil","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
}
]
}
My code for retrieving the data is:
$scope.pendingReports = {
dataSource: {
type: "odata",
transport: {
read: {
beforeSend: function (req) {
req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
},
url: "/odata/TestReports",
dataType: "odata"
},
parameterMap: function (options, type) {
var paramMap = kendo.data.transports.odata.parameterMap(options);
console.log(paramMap);
delete paramMap.$inlinecount; // <-- remove inlinecount parameter
delete paramMap.$format; // <-- remove format parameter
console.log(paramMap);
return paramMap;
}
},
schema: {
data: function (data) {
return data; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data.length; // <-- The total items count is the data length, there is no .Count to unpack.
}
},
pageSize: 5,
serverPaging: true,
serverSorting: true
},
sortable: true,
pageable: true,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "Name",
title: "Navn"
}, {
field: "ReportedDate",
title: "Indberetet den"
}, {
field: "Purpose",
title: "Formål"
}, {
field: "Type",
title: "Type"
}, {
field: "options",
title: "Muligheder"
}
]
};
My WebApiConfig class is corrently like this:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create());
config.MapODataServiceRoute(
routeName: "odata",
routePrefix: "odata",
model: GetModel()
);
}
public static Microsoft.OData.Edm.IEdmModel GetModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<TestReport>("TestReports");
return builder.GetEdmModel();
}
}
Does anyone have any suggestions on how I get the Web API to return the correct metadata?
Apparently Kendo UI Grid is not supporting OData v4.
The fix was to modify the parameterMap of the Kendo datasource, and tell it to use $count instead of $inlinecount.
Besides that I had to tell the schema to read "#odata.count" as the "total" value.
After I edited the before posted code to the ode below, I got the correct data in my response:
$scope.pendingReports = {
dataSource: {
type: "odata",
transport: {
read: {
beforeSend: function (req) {
req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
},
url: "/odata/TestReports",
dataType: "json"
},
parameterMap: function (options, type) {
var d = kendo.data.transports.odata.parameterMap(options);
delete d.$inlinecount; // <-- remove inlinecount parameter
d.$count = true;
return d;
}
},
schema: {
data: function (data) {
return data.value; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data['#odata.count']; // <-- The total items count is the data length, there is no .Count to unpack.
}
},
pageSize: 5,
serverPaging: true,
serverSorting: true
},
sortable: true,
pageable: true,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "Name",
title: "Navn"
}, {
field: "ReportedDate",
title: "Indberetet den"
}, {
field: "Purpose",
title: "Formål"
}, {
field: "Type",
title: "Type"
}, {
field: "options",
title: "Muligheder"
}
]
};

Kendo UI Grid JSON DataSource not loading data

For some reason I seem to be unable to get any more than the following in the Kendo UI Grid:
HTML:
<div id="grid"></div>
<script>
var remoteDataSource = new kendo.data.DataSource(
{
transport:
{
read: {
type: "POST",
dataType: "json",
url: "/home/getopportunities/"
}
},
pageSize: 4
})
$("#grid").kendoGrid(
{
dataSource: remoteDataSource,
columns: [
{
title: "Title",
headerAttributes: {
style: "text-align:center"
},
attributes: {
"class": "table-cell"
},
width: 600,
filterable: true
},
{
title: "Activity Type",
headerAttributes: {
},
attributes: {
"class": "table-cell",
style: "text-align:center"
},
width: 100,
filterable: true
},
{
title: "Specialty",
filterable: true,
headerAttributes: {
style: "text-align:center"
},
attributes: {
"class": "table-cell",
style: "text-align:center"
}
},
{
title: "Total Credits",
format: "{0}",
headerAttributes: {
style: "text-align:center"
},
attributes: {
"class": "table-cell",
style: "text-align:center"
}
}
],
height: 430,
scrollable: true,
sortable: true,
pageable: true,
filterable: {
extra: false,
operators: {
string: {
contains: "Contains",
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to"
},
number: {
eq: "Is equal to",
neq: "Is not equal to",
gte: "Greater Than",
lte: "Less Than"
}
}
}
});
</script>
This is the JSON that is returned to it:
[
{"ActivityID":367,"Title":"Non Webinar Test For Calendar","ActivityType":"Other","TotalCredits":2,"Specialty":"[AB] [AE]"},
{"ActivityID":370,"Title":"Stage - Test SI Changes Part II","ActivityType":"Other","TotalCredits":2,"Specialty":"[NE]"},
{"ActivityID":374,"Title":"Webinar Test Event For Calendar","ActivityType":"Webinar","TotalCredits":2,"Specialty":"[FE] [NE] "},
{"ActivityID":401,"Title":"Module #1 Webinar: Learn Stuff","ActivityType":"Webinar","TotalCredits":2,"Specialty":"[AB] ",},
{"ActivityID":403,"Title":"Module #3 Webinar: Learn Even More Stuff","ActivityType":"Webinar","TotalCredits":2,"Specialty":"[AB] [AE]",}
]
I feel like I'm really close but am missing the last piece. Any help would be GREATLY appreciated as I'm on a deadline.
common troubles are with missing schema attribute !
add it to grid's - datasource, and check if it is set when you make your json.
(when plain array is serialized/to_json, the data array needs a property indicating the shema)
here an example to make it clear:
js: sample grid initialisation / datasource:
$("#grid").kendoGrid({ dataSource: { transport: { read: "/getdata/fromthisurl" }, schema: { data: "data" } } });
when you make / output your json, see if shema information is in the encoded result:
php:
$somedata= get_my_data();
header("Content-type: application/json");
echo "{\"data\":" .json_encode($somedata). "}";
or:
$viewdata['data'] = get_my_data();
header("Content-type: application/json");
echo (json_encode($viewdata));
so the json that is sent to the grid would look like:
{data:
[
{item}
{item}
]
}
instead of just:
[
{item}
{item}
]
Code looks good. I wonder if you change data source creation as below . Change type from POST to GET and see if it works,
var remoteDataSource = new kendo.data.DataSource(
{
transport:
{
read: {
type: "GET",
dataType: "json",
url: "/home/getopportunities/"
}
},
pageSize: 4
})
Try this,
$(document).ready(function () {
var remoteDataSource = new kendo.data.DataSource(
{
transport:
{
read: {
type: "POST",
dataType: "json",
url: "/home/getopportunities/"
}
},
pageSize: 4
});
});
You can see what part of code raise an exception in some debug tool (I'd recommend you Chrome's DevTools (just press F12 key in Chrome).
I'm pretty sure the problem is misssing field attribute in your grid's columns array, so Kendo don't know what data from datasource to display in what column of grid.
columns: [
{
field: "Title", // attr name in json data
title: "Title", // Your custom title for column (it may be anything you want)
headerAttributes: {
style: "text-align:center"
},
attributes: {
"class": "table-cell"
},
width: 600,
filterable: true
},
Don't forget to change request type from "POST" to "GET".
What I found when inspecting the JSON coming back from the grid datasource json query was the field names were being JavaScripted -- what was ActivityID in C# became activityID on the wire...
This is unclean, and I discovered it by accident, but what worked for me was returning Json(Json(dataList)) from the controller instead of Json(dataList).