Here is my grid:
$("#category-gridview").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: function (options) {
return '/Product/GetCategories?id=' + $("#selectedProductId").val() + '&company=' + $("#company-dropdown").val() + '&language=' + $("#country-dropdown").val();
},
dataType: "json",
type: "POST"
},
destroy: {
url: '/Product/DeleteProductCategory',
dataType: "json",
type: "POST",
contentType: "application/json"
},
parameterMap: function (options, operation) {
console.log("HÄÄR");
console.log(options);
if (operation !== "read" && options.models) {
return JSON.stringify({
category: options
});
}
}
},
schema: {
model: {
fields: {
id: {
type: "string"
},
name: {
type: "string"
},
}
}
},
},
columns: [{
field: "id",
hidden: true
}, {
field: "name",
title: "Category",
width: "30px"
}, {
command: "destroy",
title: " ",
width: 15
}],
editable: false,
});
somehow the read function works as expected but when i press the delete button i won't even reach my parameter map function.
When i look in chrome console there is no request sent to my controller.
here is my controller method:
[HttpPost]
public JsonResult DeleteProductCategory(CategoryResponse category)
{
return Json(category);
}
Let me try to answer, but to note that i change your transport and the column setting to match the field using kendo because obviously i can't use yours. Similar to this
transport: {
read: {
url: "http://demos.telerik.com/kendo-ui/service/products",
dataType: "jsonp"
},
destroy: {
url: "http://demos.telerik.com/kendo-ui/service/products/destroy",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
At first glance i notice you use "POST" on read and delete call, actually you don't need them?
But then you said that you couldn't reach the parametermap, i came to
think of
You set editable : false, how can you edit it if you
set it to false? you should make it to editable : true(note: also you can try to set it to false and then you can see the delete function will not work)
DEMO
Instead of stringifing {param:value} Simply stringify value i.e stringify(options.models) for parameter category
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return { category: kendo.stringify(options.models) };
}
}
Related
I define a grid in my page :
<div id="grid"></div>
<script>
$(document).ready(function () {
var crudServiceBaseUrl = "http://demos.kendoui.com/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/Grid/GetPerson",
dataType: "json",
contentType: 'application/json; charset=utf-8',
type: 'Get'
},
update: {
url: function (person) {
debugger;
return "/Grid/Update";
},
contentType: 'application/json; charset=utf-8',
type: "POST",
},
destroy: {
url: crudServiceBaseUrl + "/Products/Destroy",
dataType: "jsonp"
},
create: {
url: crudServiceBaseUrl + "/Products/Create",
dataType: "jsonp"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "ID",
fields: {
ID: { type: "number", editable: false, nullable: true },
Name: { validation: { required: true } },
Family: { validation: { required: true, min: 1 } },
Tel: {}
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [
{ field: "Name", title: "نام" },
{ field: "Family", title: "فامیل" },
{ field: "Tel", title: "تلفن", width: "100px" },
{ command: [{ name: "edit", text: "ویرایش" }, { name: "destroy", text: "حذف" }], title: "عملیات", width: "160px" }],
messages: {
editable: {
cancelDelete: "لغو",
confirmation: "آیا مایل به حذف این رکورد هستید؟",
confirmDelete: "حذف"
},
commands: {
create: "افزودن ردیف جدید",
cancel: "لغو کلیهی تغییرات",
save: "ذخیرهی تمامی تغییرات",
destroy: "حذف",
edit: "ویرایش",
update: "ثبت",
canceledit: "لغو"
}
},
editable: "popup"
});
});
In person parameter in update function, i can access changed row by :
person.models[0]
it gives me :
Object {ID:1,Name:"pejman",Family:"kam",Tel:"098787887"}
SO i want to send this data to the server, so i have a action in GridController:
[HttpPost]
public void Update(TblPerson person)
{
//do update
}
for doing it, i try :
url: function (person) {
return "/Grid/Update/" + JSON.stringify(person.models[0])
},
in the update method, but it doesn't work, how can i do it?
NOTE: when i using above in Network tab of browser give me Bad Reuest error:
URL:http://localhost:2145/Grid/Update/%7B%22ID%22:1,%22Name%22:%22pejman%22,%22Family%22:%22kam%22,%22Tel%22:%22098787878%22%7D
Status Code:400 Bad Request
The problem is that kendo.stringify(options.models) sends your object in JSON string. So I believe that your js code can stay as it is. Just change your Update method in controller to something like:
[HttpPost]
public void Update(string models)
{
var values = JsonConvert.DeserializeObject<IEnumerable<TblPerson>>(models);
foreach (var value in values)
{
//Your action
}
}
The approach above just assume that you can send more models to update. Don't forget using Newtonsoft.Json
Here i my c sharp code of controller api class DefComapny whose value are always null while posting a data from kendo grid thats why not entering any thing to database?
[HttpPost]
public void SaveDefCompny()
{
var result = new List<DefCompany>();
using (var data = new RPDBEntities())
{
DefCompanyDTO productViewModel = new DefCompanyDTO();
var product = new DefCompany
{
//same problem of all entites getting no value from grid
Id = productViewModel.Id, // getting no value from grid
CurrentCurrencyCode = productViewModel.CurrentCurrencyCode,
ShortName= productViewModel.ShortName,
FullName= productViewModel.FullName,
ContactPerson= productViewModel.ContactPerson,
Address1= productViewModel.Address1,
CompanyCity= productViewModel.CompanyCity,
CompanyState= productViewModel.CompanyState,
CompanyCountry= productViewModel.CompanyCountry,
ZipPostCode= productViewModel.ZipPostCode,
TelArea= productViewModel.TelArea
};
result.Add(product);
data.DefCompanies.Add(product);
data.SaveChanges();
}
}
here is my viewmodel code
document.onreadystatechange = function () {
var viewModel = kendo.observable({
products: new kendo.data.DataSource({
schema: {
//data:"Data",
total: "Count",
model: {
Id: "Id",
fields: {
Id: { editable: true, type: "int" },
ShortName: { editable:true, type: "string" },
FullName: { editable: true, type: "string" },
ContactPerson: { editable: true, type: "string" },
CurrentCurrencyCode: { editable: true, type: "int" },
Adress1: { editable: true, type: "string" },
CompanyState: { editable: true, type: "string" },
CompanyCity: { editable: true, type: "string" },
CompanyCountry: { editable: true, type: "string" },
ZipPostCode: { editable: true, type: "string" },
TelArea: { editable: true, type: "string" }
}
}
},
batch: true,
transport: {
read: {
url: "/api/Companies/GetAllCompanies",
dataType: "json"
},
create:{
url: "/api/Companies/SaveDefCompny",
dataType: "json"
},
update: {
url: "/api/Companies/SaveDefCompny", // here you need correct api url
dataType: "json"
},
destroy: {
url: "/api/Companies/Delete", // here you need correct api url
dataType: "json"
},
parameterMap: function (data, operation) {
if (operation !== "read" && data) {
return kendo.stringify(data) ;
}
}
}
})
});
kendo.bind(document.getElementById("example"), viewModel);
}
how should i pass my inline kendo grid values to my controller so that it save it in database?
Check Kendo documentation and see what kind of parameters SaveDefCompny should expect. You should then be able to read whatever you require using those parameters.
url: "/api/Companies/SaveDefCompny", dataType: "json"
This most likely is sending your controller method the required data in json format.
Again: your answer lies in the Kendo documentation.
EDIT:
See this and this.
From their example:
public ActionResult Products_Create([DataSourceRequest]DataSourceRequest request, ProductViewModel product)
{
if (ModelState.IsValid)
{
using (var northwind = new NorthwindEntities())
{
// Create a new Product entity and set its properties from the posted ProductViewModel
var entity = new Product
{
ProductName = product.ProductName,
UnitsInStock = product.UnitsInStock
};
// Add the entity
northwind.Products.Add(entity);
// Insert the entity in the database
northwind.SaveChanges();
// Get the ProductID generated by the database
product.ProductID = entity.ProductID;
}
}
// Return the inserted product. The grid needs the generated ProductID. Also return any validation errors.
return Json(new[] { product }.ToDataSourceResult(request, ModelState));
}
This is my grid:
$(document).ready(function () {
datasource = new kendo.data.DataSource({
transport: {
read: {
url: '/Discount/Get',
dataType: "json",
},
update: {
url: '/Discount/Update',
dataType: "json",
type: "POST"
},
destroy: {
url: '/Discount/Delete',
dataType: "json",
type: "POST"
},
create: {
url: '/Discount/Add',
dataType: "json",
type: "POST"
},
parameterMap: function (options, operation) {
console.log(operation);
if (operation !== "read") {
return options;
}
}
},
schema: {
model: {
id: "Id",
fields: {
TopItemName: { type: "string" },
DiscountValue: { type: "number" },
}
}
}
});
$("#grid").kendoGrid({
dataSource: datasource,
batch: true,
toolbar: ["create", "save", "cancel"],
height: 400,
navigatable: true,
pageable: true,
columns: [
{
field: "TopItemName",
editor: topItemDropDown,
template: "#=TopItemName#"
},
{
field: "DiscountValue",
format: "{0:p0}",
editor: function (container, options) {
$("<input name='DiscountValue'>")
.appendTo(container)
.kendoNumericTextBox(
{
min: 0,
max: 1.00,
step: 0.01
});
}
},
{
command: "destroy",
title: " ",
width: 150
}],
editable: true
});
function topItemDropDown(container, options) {
console.log(options);
$('<input required data-text-field="TopItemName" data-value-field="TopItemName" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: {
serverFiltering: true,
transport: {
read: {
url: '/Discount/GetTopItemName',
dataType: "json",
type: "POST",
contentType: "application/json"
}
}
}
});
}
});
and somehow when I press the delete button it deletes the row from the grid but it never calls my action method so that the row gets removed from my database. But if I after i have pressed the delete button press add new record and then save changes then it calls my add action method and my delete action method. How can I make it call the delete action method when the delete button is pressed and not when save changes is pressed?
This is how the default editing works by default - the user has to click the "Save Changes" button to submit all changes to the server.
You can do one of the following
Set the autoSync option of the data source to true
Use a different editing mode - for example inline.
Handle the remove event of the grid and call this.dataSource.sync() to automatically sync the changes.
This is my grid:
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: {
url: '/Discount/Get',
dataType: "jsonp",
type: "POST"
},
update: {
url: '/Discount/Update',
dataType: "jsonp",
type: "POST"
},
destroy: {
url: '/Discount/Delete',
dataType: "jsonp",
type: "POST"
},
create: {
url: '/Discount/Add',
dataType: "jsonp",
type: "POST"
},
parameterMap: function (options, operation) {
console.log(operation);
console.log(options);
if (operation == "update") {
return { discountId: options.models.DiscountId, discountValue: options.models.DiscountValue }
}
if (operation == "create") {
return JSON.stringify({ discountValue: options.models.DiscountValue, topItemName: options.models.TopItemName });
}
if (operation == "destroy") {
return { discountId: options.models.DiscountId }
}
}
},
schema: {
model: {
id: "DiscountId",
fields: {
DiscountId: { type: "number" },
TopItemName: { type: "string" },
DiscountValue: { type: "number" }
}
}
}
},
toolbar: ["create", "save", "cancel"],
height: 400,
sortable: true,
pageable: true,
columns: [
{
field: "TopItemName",
filterable: true
},
{
field: "DiscountValue",
format: "{0:p0}",
editor: function (container, options) {
$("<input name='DiscountValue'>")
.appendTo(container)
.kendoNumericTextBox(
{
min: 0,
max: 1.0,
step: 0.01
});
}
}],
editable: true
});
In the grid I have a custom editor which will make the textbox to a percentage.
In my console.log when I make a create call and I got this
Object {DiscountId: 0, TopItemName: "asdasd", DiscountValue: "0.05"}
So there is a value for DiscountValue. But still i get the error:
Uncaught TypeError: Cannot read property 'DiscountValue' of undefined
Is this something about DiscountValue being a float value?
Uncaught TypeError: Cannot read property 'DiscountValue' of undefined
This error doesn't mean there is no field 'DiscountValue', it means you are trying to read a property of an undefined variable.
So if the error is from here :
options.models.DiscountValue
It means options.models is undefined.
Your log output printed the definition of options, not options.models.
You might confound with options.DiscountValue ?
I am developing a web application which deals with interactive grids. I am using Kendo UI for displaying grids and doing CRUD operations. I am new to Kendo UI. We are performing database calls using jquery, Ajax only. I was able to make it read the data from the database and display it. But I am stuck at CRUD operations. How to get the event that a specific row or a specific single data is changed and perform the update. Please help me to understand how to do the crud operations. I couldn't find it in detail anywhere. There are 8 parameters which are in the first column. The user should be able to change the rest of the data except the parameters.
following is the code for Grid. CreateWBDGridData triggers the database service call and creates the table. gridSource is JSON data getting from the database after converting through Json convert function.
$(document).ready(function()
{
var param ="HOLE_DIAMETER|4.875_CASING_ID|5.5_GRAVEL_PACK|NET_PERF_THICKNESS|PERF_DIAMETER|PERF_GRAVEL_PERM_#19k|GRAVEL_BETA_FACTOR_#19K|SHOT_DENSITY";
$.when(GetWBDGridDataByWell(param)).then(function (data) {
});
});
function CreateWBDGridData(gridSource) {
if (gridSource == undefined) return;
console.log(gridSource);
$("#grid").kendoGrid({
dataSource: {
data: gridSource,
schema: {
model: {
fields: {
ParameterName: { type: "string" },
Zone_1: { type: "number" },
Zone_2: { type: "number" },
Zone_3: { type: "number" },
}
}
},
// pageSize: 20
},
//height: 550,
//scrollable: true,
//sortable: true,
//filterable: true,
//reorderable: true,
resizable:true,
//pageable: {
// input: true,
//numeric: false
//},
columns: [
{ field: "ParameterName", title: "Lucius 01", width: 300 },
{ field: "Zone_1", title: "Zone 1", width: 100 },
{ field: "Zone_2", title: "Zone 2", width: 100 },
{ field: "Zone_3", title: "Zone 3", width: 100 },
]
});
}
Controller
var dspstore = "System.Sources.Db.MsSql.DSPStore";
function GetWBDGridData(queryName, param) {
var varData = CreateParamQuery(dspstore, queryName, param);
CallService(GetWBDGridDataCompleted, varData);
}
var GetWBDGridDataCompleted = function (result) {
if (varDataType == "json") {
var myItems = $.parseJSON(result.GetDataItemsResult);
CreateWBDGridData(myItems);
}
}
Service call
function CallService(ServiceCompleted, varData) {
$.support.cors = true;
$.ajax({
context: this,
disableCaching: false,
headers: {
"Access-Control-Allow-Origin": '*',
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type: varType, //GET or POST or PUT or DELETE verb
url: varUrl, // Location of the service
data: varData, //Data sent to server
//contentType: varContentType, // content type sent to server
dataType: varDataType, //Expected data format from server
processdata: varProcessData, //True or False
success: function (msg) {//On Successfull service call
ServiceCompleted(msg);
},
error: ServiceFailed// When Service call fails
});
}
Ok, as I Understand there 8 parameters which are the first column, have had has 3 more items which user can edit if so do as below.
$("#grid").kendoGrid({
dataSource: {
transport: {
read: function (options) {
$.ajax({
url: "/Your Controller/your read Action",
dataType: "json",
cache: false,
success: function (result) {
options.success(result);
},
error: function (result) {
options.error(result);
}
});
},
update: function (options) {
$.ajax({
url: "/Your Controller/your Update Action",
dataType: "json",
cache: false,
data:{model:options.data.models},
success: function (result) {
options.success(result);
},
error: function (result) {
options.error(result);
}
});
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
schema: {
model: {
fields: {
ParameterName: { type: "string",editable: false },
Zone_1: { type: "number",editable: true, validation: { required: true } },
Zone_2: { type: "number",editable: true, validation: { required: true } },
Zone_3: { type: "number" ,editable: true, validation: { required: true }},
}
}
},
pageSize: 10
},
resizable:true,
columns: [
{ field: "ParameterName", title: "Lucius 01", width: 300 },
{ field: "Zone_1", title: "Zone 1", width: 100 },
{ field: "Zone_2", title: "Zone 2", width: 100 },
{ field: "Zone_3", title: "Zone 3", width: 100 },
]
});
}
Use the model to specify the editable and non-editable fields and Your Data Source Data parameter does not use unless you're doing local calls, to do server calls call it as a function as shown above.
and your Controller action should look like below : (I Assume your using MVC)
[HttpGet]
public ActionResult ReadGridJson()
{
return Json(yourlist, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public ActionResult UpdateGridJson(YourModelType model)
{
//update the DB and return the updated item
return Json(updateItem, JsonRequestBehavior.AllowGet);
}
Hope this helps, For more info check out the API DOC http://docs.telerik.com/kendo-ui/api/web/grid