Bind KendoUI grid with Model data in MVC 4 - asp.net-mvc-4

For example, I have a view with model IEnumerable<Correspondence>. I want to bind it to KendoUI grid. What should I do? I've tried
#model IEnumerable<Correspondence>
<div id="Correspondence"></div>
<script>
$(document).ready(function () {
$('#Correspondence').kendoGrid({
dataSource: {
data: #Html.Raw(Json.Encode(Model)),
editable: { destroy: true },
batch: true,
pageSize: 15,
schema: {
model: {
id: "Id",
fields: {
Subject: { type: "string" },
CorrespondenceType: { type: "number" },
SentDate: { type: "date" }
}
}
}
},
navigatable: true,
selectable: "row",
filterable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true
},
columns: [
{
title: "Subject",
field: "Subject"
},
{
title: "Type",
field: "CorrespondenceType"
},
{
title: "Sent Date",
field: "SentDate",
format: "{0:MM/dd/yyyy}"
},
{
command: [{ name: "openCorrespondence", text: "Open", className: "k-grid-openLaboratory", imageClass: "k-icon k-i-maximize", click: Open },
{ name: "deleteCorrespondence", text: "Delete", className: "k-grid-deleteLaboratory", imageClass: "k-icon k-delete", click: Delete },
{ name: "EditCorrespondence", text: "Edit", className: "k-grid-editLaboratory", imageClass: "k-icon k-edit", click: Edit }],
title: "Action"
}
]
});
}); // end ready
</script>
But it doesn't work. The table even doesn't show up. Please help me. Thank you.
Edited!!!

I have solved my own problem. Because I used command column, so I have to add 3 functions: Open, Edit, and Delete. Then, the grid showed successfully.

Related

vue good table - 3 requests to the service

I use vue-good-table object to render table in Vue.js. I use paging and sorting serverside.
My code:
<vue-good-table v-if="authorizations"
id="AuthorizationsTable"
ref="refToAuthorizationsTable"
#on-page-change="onPageChange"
#on-sort-change="onSortChange"
#on-column-filter="onColumnFilter"
#on-per-page-change="onPerPageChange"
mode="remote"
:columns="columns"
:rows="authorizations"
:totalRows="totalRecords"
:pagination-options="{
enabled: true,
mode: 'pages',
nextLabel: 'następna',
prevLabel: 'poprzednia',
ofLabel: 'z',
pageLabel: 'strona',
rowsPerPageLabel: 'wierszy na stronie',
allLabel: 'wszystko',
dropdownAllowAll: false
}"
:sort-options="{
enabled: true,
initialSortBy: {
field: 'id',
type: 'asc'
}
}">
(...)
export default {
name: 'AuthoritiesAdministration',
components: {},
data() {
return {
totalRecords: 0,
serverParams: {
columnFilters: {},
sort: {
field: 'id',
type: 'asc'
},
page: 1,
perPage: 10
},
rows: [],
columns: [
{
label: 'ID',
field: 'id',
type: 'number',
tdClass: 'vue-good-table-col-100'
},
{
label: 'Data wystawienia',
field: 'issueDate',
formatFn: this.formatDate,
tdClass: 'vue-good-table-col-200',
},
{
label: 'Nazwa operatora',
field: 'operator',
sortable: true,
formatFn: this.formatOperatorName,
},
{
label: 'Login',
field: 'operator.login'
},
{
label: 'Spółka',
field: 'company.description',
type: 'text',
},
{
label: 'Data ważności',
field: 'endDate',
type: 'text',
formatFn: this.formatDate,
},
{
label: 'Akcje',
field: 'btn',
tdClass: 'vue-good-table-col-250',
sortable: false
}
],
}
},
(...)
methods: {
updateParams(newProps) {
this.serverParams = Object.assign({}, this.serverParams, newProps);
},
onPageChange(params) {
this.updateParams({page: params.currentPage});
this.loadAuthorizations();
},
onPerPageChange(params) {
this.updateParams({
perPage: params.currentPerPage
});
this.loadAuthorizations();
},
onSortChange(params) {
this.updateParams({
sort: {
type: params[0].type,
field: params[0].field
}
});
this.loadAuthorizations();
},
onColumnFilter(params) {
this.updateParams(params);
this.loadAuthorizations();
},
loadAuthorizations() {
getAllAuthorizationsLightWithPagination(this.$store.getters.loggedUser.token, this.serverParams).then(response => {
this.totalRecords = response.data.totalRecords;
this.rows = response.data.authorizations;
}).catch(err => {
this.$showError(err, true);
});
},
I have noticed that there are sent 3 requests to the server instead of 1: there are called methods like onPageChange, onPerPageChange and onSortChange but only the first time when my page is loaded. It is unnecessary. I have one method in "mounted" section where I load the first 10 results (sorting and paging by default). It's common, well-known problem with vue-good-table? Or maybe should I add an additional flag to not to invoke these 3 methods unnecessarily when the page is loaded?
Your onSortChange method is called at the table loading because you made a initialSortBy with specific values. To remove this calling juste remove
initialSortBy: {
field: 'id',
type: 'asc'
}
from you table configuration, but your sort will not be set, so I think this should be a legit function call.
The onPerPageChange and onPageChange are triggered by the config below
:pagination-options="{
enabled: true,
...
}
just remove the colon before pagination-options to have a config like this
pagination-options="{
enabled: true,
...
}

How to display a List of object in Kendo Grid in jquery?

I am working on a project in which I need to display List of objects in Kendo Grid.
below is the code for data binding.
$("#GridProperty").kendoGrid({
dataSource: {
transport: {
read: {
dataType: "json",
url: $_BindPropertyData,
data: { "LegalEntityId": LegalEntityId, "DatasetId": DatasetId },
async: true,
}
},
schema: {
model: {
fields: {
GeoId: { type: "int" },
GeoDescription: { type: "string" },
GeoAbbreviation: { type: "string" },
//ComponentDesc: { type: "string", from: "CompModelList.ComponentDesc" },
Id: { type: "int" },
Amount1: { type: "decimal", from: "CompModelList.SaDataModel.Amount1" },
Amount2: { type: "decimal"}
//lstcompModel: {type: ""}
}
}
},
},
noRecords: {
template: "<p style='margin-top:5px;'>There are currently no items available<p>"
},
height: 525,
reorderable: true,
groupable: true,
sortable: true,
filterable: true,
resizable: true,
columnMenu: true,
selectable: "row",
dataBound: function () {
},
columns: Columns
});
Description :
I am returning list of objects as json from my Action . but i am not able to bind the list of objects in kendo grid.
I am breaking my head for last four days. Please help.
Thanks

Passing data in view model to controller via kendo grid

So far, I'm just trying to instantiate my kendogrid and passing through values from my view model. I got the following piece of code from Telerik's documentation for vb.net. The thing is, an exception is thrown from .Grid ->
"Type parameter for public overridable overloads function grid(of T as a class) as a gridbuilder(of t) cannot be inferred"
Html.Kendo().Grid().Name("kendogrid")
I'm not sure what this error means and I don't know how to go about fixing it.
View
$(document).ready(function () {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "TestAjax",
dataType: "json",
type: "GET",
},
update: {
url: "update",
dataType: "json",
type: "POST"
},
create: {
url: "CreateInvoiceRecord",
dataType: "json",
type: "GET",
},
parameterMap: function (options, operation) {
console.log(operation);
console.log(options);
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "itemID",
fields: {
ItemName: { type: "string" },
Amount: { type: "number", editable: false, validation: { required: true } },
ProductLine: { type: "string" },
Status: { type: "string" },
}
}
},
aggregate: [{ field: "Amount", aggregate: "sum" }
]
});
$("#kendogrid").kendoGrid({
DataSource: dataSource,
pageable: true,
height: 550,
toolbar: ["create", "save"],
columns: [
{ field: "ItemName", title: "Item", width: "150px" },
{ field: "Amount", title: "Amount", format: "{0:c}", width: "100px", aggregates: ["sum"], footerTemplate: "Total Amount: #=sum#" },
{ field: "ProductLine", title: "Product Line", width: "150px", editor: productLineDropDownEditor},
{ field: "Status", title: "Status", width: "150px", editor: statusDropDownEditor },
{ command: "Update", title: "Update" , width:"150px"}],
editable: true
});
});
Model
Public Class MyViewModel
Public Property id As String
Public Property id2 As String
End Class
The VB grid syntax from http://docs.telerik.com/kendo-ui/aspnet-mvc/vb#grid
is:
Html.Kendo().Grid(Of YourViewModelClassThatYouWantToBindTheGridTo)() _
.Name("grid") _
...additional configuration.
You are missing the part where you tell the grid what type of object you are binding to(the "Of NameOfYourClass" part.
You should post your whole grid definition.
Also...C# syntax is sooooo much cleaner(I know that's not helpful).
Edit
OK, so this question isn't about the correct VB.NET Razor syntax anymore....
This is how you get "extra" data passed to the controller methods from a dataSource: you use the dataSource.transport.read.data configuration (http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.read.data)
Using an object:
transport: {
read: {
url: "TestAjax",
dataType: "json",
type: "GET",
data: {
parameterToPassToReadAction: valueYouWantToPassToReadAction
}
},
Using a function:
transport: {
read: {
url: "TestAjax",
dataType: "json",
type: "GET",
data: extraDataFunction
},
function extraDataFunction () {
return {
parameterToPassToReadAction: valueYouWantToPassToReadAction
};
}
Where parameterToPassToReadAction is the name of the parameter in your server method and valueYouWantToPassToReadAction is the value you want it to be...which is stored where ever you stored it when the page loaded. If it is in a ViewModel of your vbhtml file and your javascript is in the script block of that same file, the syntax will be something like:
function extraDataFunction () {
return {
parameterToPassToReadAction: #Model.FieldYouWantToSend
};
}
But it is not clear where you have this value stored.
Finally got what I wanted working using a hack for create and then ajax for read. Not totally sure why this works the way it does so I'll need to look into it some more. I needed to pass parameters to controllers that are connected to kendogrid - specifically the read and create operations. I created a view model to store the values that I obtained from my Index controller and then used the view model to pass the values from kendogrid to the read and create operation controllers. For some reason, I was only able to pass parameters to the read operation using ajax.
Note: Still not the best solution. It calls readData controller twice and I don't want that.
Javascript
<Script>
$(document).ready(function () {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "readData",
dataType: "json",
type: "GET",
},
create: {
url: "CreateInvoiceRecord?trxid=#Model.id2&bcid=#Model.id",
dataType: "json",
type: "GET",
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "itemID",
fields: {
ItemName: { type: "string" },
Amount: { type: "number", validation: { required: true } },
ProductLine: { type: "string" },
Status: { type: "string" }
}
}
},
aggregate: [{ field: "Amount", aggregate: "sum" }]
});
$("#kendogrid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
height: 550,
toolbar: ["create", "save"],
columns: [
{ field: "ItemName", title: "Item", width: "150px" },
{ field: "Amount", title: "Amount", format: "{0:c}", width: "100px", aggregates: ["sum"], footerTemplate: "Total Amount: #=sum#" },
{ field: "ProductLine", title: "Product Line", width: "150px", editor: productLineDropDownEditor},
{ field: "Status", title: "Status", width: "150px", editor: statusDropDownEditor },
{ command: "Update", title: "Update" , width:"150px"}],
editable: true
});
});
function productLineDropDownEditor(container, options) {
$('<input required name="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
valuePrimitive: true,
dataTextField: "name",
dataValueField: "name",
dataSource: {
transport: {
read: {
url: "/Customs/getProdLines",
dataType: "json"
}
},
schema: {
data: "Data",
model: {
fields: {}
}
},
}
});
}
function statusDropDownEditor(container, options) {
var data = [
{ text: "Active", value: "1" },
{ text: "Paid", value: "2" },
{ text: "Cancelled", value: "3" }
]
$('<input required name="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
valuePrimitive: true,
dataTextField: "text",
dataValueField: "value",
autobind: false,
dataSource: data
});
}
//function testAjax() {
//}
//data: { 'name': ItemName, 'amount': Amount, 'prodline': ProductLine, 'status': Status },
$.ajax({
type: "Get",
data: { id: "#Model.id", id2:"#Model.id2" },
url: "readData/",
dataType: "json",
success: function (itemList) {
console.log(itemList);
}
});
</script>
Model
Public Class MyViewModel
Public Property id As String
Public Property id2 As String
End Class

Kendo Grid - Create Transport, ID not set

See this question with no response: Kendo Grid does not update the grid with newly created id after creation
When creating a new link, my method is hit, and I return the full item with the ID set:
[HttpPost]
public JsonResult Create(string LINK_TEXT, string HREF, string CATEGORY)
{
var link = new LinkDTO {LINK_TEXT = LINK_TEXT, HREF = HREF, CATEGORY = CATEGORY};
var insertedLink = LinkService.Create(link);
return Json(new[] {insertedLink}, JsonRequestBehavior.AllowGet);
}
In the client, the response is:
{"ID":86,"LINK_TEXT":"Test2","HREF":"http://www.google.com","CATEGORY":"Category1"}
I've also tried only returning the ID:
{"ID":86}
Upon inspection of the kendo data:
CATEGORY: "Category1"
HREF: "http://www.google.com"
ID: 0
LINK_TEXT: "Test2"
_events: Object
dirty: false
id: 0
parent: function (){return r}
uid: "4739cc3d-a270-44dd-9c63-e9d378433d98"
The ID is 0. When I try to edit this link it thinks it is new, so it calls create again, thus duplicating the link.
Here is my grid definition:
$(document).ready(function () {
$("#link-results").kendoGrid({
dataSource: {
transport: {
create: {
url: '#Url.Action("Create", "Link")',
dataType: 'json',
type: 'POST'
},
read: {
url: '#Url.Action("Read", "Link")',
dataType: 'json',
type: 'GET',
data: {
CATEGORY: '#Model.CategoryName'
}
},
update: {
url: '#Url.Action("Update", "Link")',
dataType: 'json',
type: 'POST',
data: {
CATEGORY: '#Model.CategoryName'
}
},
destroy: {
url: '#Url.Action("Delete", "Link")',
dataType: 'json',
type: 'POST'
}
},
pageSize: 10,
schema: {
data: "Links",
total: "ResultCount",
model: {
id: "ID",
fields: {
ID: {type: "number"},
LINK_TEXT: { type: "string", required: true },
HREF: { type: "string", defaultValue: "", validation: { required: true } },
CATEGORY: { type: "string", defaultValue: '#Model.CategoryName', editable: false }
}
}
}
},
pageable: true,
toolbar: ["create"],
columns: [
{ field: "ID", hidden: true },
{ field: "LINK_TEXT", title: "Name", width: "40px"/*, template: "<a href='#=HREF#'>#=LINK_TEXT#</a>"*/ },
{ field: "HREF", title: "Link", width: "100px",filterable: false/*, template: "<a href='#=HREF#'>#=HREF#</a>"*/ },
{ field: "CATEGORY", title: "Category", width: "50px", filterable: false},
{
command: [
{ name: "edit", text: "" },
{ name: "destroy", text: "" }
],
title: " ",
width: "70px"
}
],
editable: "inline",
filterable: true,
sortable: "true"
});
I added the ID: {type: "number"}, part in an attempt to get this to work, I realize I should not need this in my fields definition since it is defined with id: "ID".
I figured out what the problem was, here is the text from another answer I provided regarding the same issue (see Kendo Grid does not update the grid with newly created id after creation):
I've had the same problem and think I may have found the answer. If in the schema you define the object that holds the results, you must return the result of the created link in that same object. Example:
schema: {
data: "data",
total: "total", ....
}
Example MVC method:
public JsonResult CreateNewRow(RowModel rowModel)
{
// rowModel.id will be defaulted to 0
// save row to server and get new id back
var newId = SaveRowToServer(rowModel);
// set new id to model
rowModel.id = newId;
return Json(new {data= new[] {rowModel}});
}

Kendo UI: Sum in footertemplate

I'm trying to get my footerTemplate working with a Kendo UI grid. I want to get the sum of 'hours_worked' in the footer of the tabel. I've tryed several options from the Kendo UI example but it doesn't work for me. What im doing wrong?
$(document).ready(function() {
$("#grid").kendoGrid({
dataSource: {
transport:
read: {
url: "mods/hours/data/get_hours.php?id=<?php echo $volunteer_id; ?>",
dataType: "json"
}
},
schema: {
model: {
fields: {
hours_id: { type: "number" },
volunteer_first_name: { type: "string" },
volunteer_last_name: { type: "string" },
hours_date: { type: "date" },
location_name: { type: "string" },
work_type_name: { type: "string" },
volunteer_id: { type: "number" },
hours_worked: { type: "number" }
}
}
},
aggregate:[{ field:"hours_worked", aggregate:"sum" }],
pageSize: 10
},
height: 350,
filterable: true,
sortable: true,
pageable: true,
selectable:true,
columns: [
{
title:"Naam",
template:"#=volunteer_last_name#, #=volunteer_first_name#",
},{
title:"Locatie",
field:"location_name",
},{
title:"Werkzaamheden",
field:"work_type_name",
},{
title:"Uren",
field:"hours_worked",
footerTemplate:"Sum: #=sum#",
},{
title:"Datum",
field:"hours_date",
},{
width:"200px",
title:"Opties",
filterable: false,
template:"<a href='?p=edit_reported_hours&id=#=volunteer_id#&hours_id=#=hours_id#' class='k-button'>Bewerken</a> <a href='?p=manage_reported_hours&o=delete&id=#=volunteer_id#&hours_id=#=hours_id#' class='k-button'>Delete</a>"
},
]
});
});
</script>
Add a curly bracket after transport and it will work.
transport: {
read: {
url: "mods/hours/data/get_hours.php?id=<?php echo $volunteer_id; ?>",
dataType: "json"
}
},
See it here: http://jsfiddle.net/OnaBai/bWS7C/