The cancel button still exists and the update button never changes back to edit in Kendo UI grid after the ajax call to server?! I guess I have to notify the grid that the update has done, but how ?
<div id="mykendoGrid">
<script>
$(document).ready(function () {
var MydataSource = new kendo.data.DataSource({
transport: {
read: function (options) {
$.ajax({
url: "/_layouts/AjaxCallHandler/Handler.ashx",
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
//data: options.data,
success: function (data) {
//ko.mapping.fromJS(data, self.seats);
options.success(data);
}
});
},
update: function (options) {
$.ajax(
{
type: 'POST',
url: "/_layouts/AjaxCallHandler/Handler.ashx",
data: { 'currency': ko.mapping.toJSON(options.data) },
success: function (response)
{
// do nothing
alert("Successfully Saved.");
},
error: function (repsonse) {
alert("Manage: UpdateReportName -> Ajax Error!");
}
});
return;
}
//parameterMap: function (data, operation) {
// if (operation !== "read") {
// return JSON.stringify({ currency: data })
// //return ko.mapping.fromJS(data, self.seats);
// }
//}
},
batch: false,
pageSize: 10,
schema: {
//data: 'd',
model:
{
id: "ID",
fields:
{
ID: { editable: false, nullable: false },
DisplayName: { editable: true },
Code: { editable: true }
}
}
}
})
$("#mykendoGrid").kendoGrid({
dataSource: MydataSource,
pageable: true,
toolbar: ["create"],
columns: [{ field: "ID", title: "ID" }, { field: "DisplayName", title: "Display Name" }, { field: "Code", title: "Code" }, { command: ["edit"], title: " ", width: "250px" }],
editable: "inline",
scrollable: true
});
});
</script>
</div>
You need to call options.success();
update: function (options) {
$.ajax(
{
type: 'POST',
url: "/_layouts/AjaxCallHandler/Handler.ashx",
data: { 'currency': ko.mapping.toJSON(options.data) },
success: function (response)
{
// do nothing
alert("Successfully Saved.");
options.success();
//or
//options.success(reponse);
},
error: function (response) {
alert("Manage: UpdateReportName -> Ajax Error!");
options.error();
//or
//options.error(reponse);
}
});
return;
}
You need to call yourGrid.saveChanges(); from your JavaScript. This will iterate through each row actioning the necessary create, update and destroy commands for your grids datasource and all your edits will be saved.
Related
Getting error while implementing Kendo Grid inline edit CRUD. When I add a new record and update it, I receive response code 500 with error:
I believe the problem is coming from parameterMap. What is the correct way to pass the model to the controller in Kendo?
Invalid JSON primitive: models.
What are the models?
Source Code:
$(document).ready(function () {
var baseUrl = "/SomeUrl",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: baseUrl + "/GetAccolades?profileId=" + #profileId,
type: "GET",
dataType: "json"
},
create: {
url: baseUrl + "/AddAccolade",
type: "POST",
dataType: "json",
contentType: "application/json",
},
update: {
url: baseUrl + "/UpdateAccolade",
type: "PUT",
dataType: "json",
contentType: "application/json",
},
delete: {
url: baseUrl + "/DeleteAccolade",
type: "DELETE",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
alert(kendo.stringify(options.models));
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
schema: {
model: {
id: "ProfileAccoladeID",
fields: {
ProfileAccoladeID: { editable: false, nullable: false },
ProfileID: { editable: false, nullable: false, defaultValue: #profileId },
Years: { type: "string" },
Name: { type: "string" },
Level: { type: "string" },
Event: { type: "string" },
}
}
}
});
$("#accolades-grid").kendoGrid({
dataSource: dataSource,
pageable: false,
height: 550,
toolbar: ["create"],
columns: [
{ field: "Years", width: "150px" },
{ field: "Name", title: "Name", width: "150px" },
{ field: "Level", title: "Level", width: "150px" },
{ field: "Event", title: "Event", width: "450px" },
{ command: ["edit", "destroy"], title: " ", width: "250px" }],
editable: "inline"
});
});
</script>
Controller method:
[HttpPost]
public JsonResult AddAccolade(ProfileAccolade accolade)
{
using (var db = new XXXEntities())
{
if (accolade != null)
{
var newAccolade = new ProfileAccolade()
{
ProfileID = accolade.ProfileID,
Years = accolade.Years,
Name = accolade.Name,
Level = accolade.Level,
Event = accolade.Event
};
db.ProfileAccolades.Add(newAccolade);
db.SaveChanges();
return Json(new { Success = true });
}
else
{
return Json(new { Success = false, Message = "Error occured" });
}
}
}
How do I fix this error?
Update:
By removing contentType: "application/json", the error Invalid JSON primitive: models. is gone. However, the controller does not get the model.
Any ideas to fix this?
The problem originated by usage of contentType: "application/json" inside both transport.create and transport.update part of kendo.data.DataSource. Since both operations use AJAX call (i.e. jQuery.ajax() method), the contentType setting affects how type of request body will send.
By setting "application/json" content type, the request body will treated as JSON content, but actually transport.parameterMap returns URL encoded version containing models and formatted JSON string as key-value pair (KVP). This is why "Invalid JSON primitive" error occurs, because URL encoded format is not same as JSON format.
If you wish to keep "application/json" setting for AJAX call, add JSON.stringify method to convert URL encoded format of models as JSON data:
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return JSON.stringify({ models: kendo.stringify(options.models) });
}
}
However if you want to send parameterMap as default content type (application/x-www-form-urlencoded), just remove all contentType definitions to set it back:
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: baseUrl + "/GetAccolades?profileId=" + #profileId,
type: "GET",
dataType: "json"
},
create: {
url: baseUrl + "/AddAccolade",
type: "POST",
dataType: "json"
},
update: {
url: baseUrl + "/UpdateAccolade",
type: "PUT",
dataType: "json"
},
delete: {
url: baseUrl + "/DeleteAccolade",
type: "DELETE",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
alert(kendo.stringify(options.models));
return { models: kendo.stringify(options.models) };
}
}
},
// other DataSource definitions
});
Reference:
kendo.data.DataSource (Kendo UI Documentation)
i want get data from webservice method and fill my kendo grid.
my method run and get data but when fill kendo grid show this error:
https://image.ibb.co/jNJB4a/asfasfas.png
my code in web method:
[System.Web.Services.WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]//Specify return format.
public string TierPriceListWithProduct(string ID)
{
BOProduct boProduct = new BOProduct();
boProduct.Id = Convert.ToInt32(ID);
string Result = "";
if (boProduct != null)
{
try
{
IList<DAOTierPrice> daoTierPriceCollection = DAOTierPrice.SelectAllByProductId(boProduct.Id);
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string result = serializer.Serialize(daoTierPriceCollection);
Result = result;
}
catch (Exception ex)
{
Result = "Faild#SystemError#reson#" + ex.Message;
}
}
return Result;
}
And code from client:
$(document).ready(function () {
var ID = getUrlVars()["ID"];
var BOProduct = {};
BOProduct.Id = ID;
var data = JSON.stringify(BOProduct);
//AjaxFunctionsAdminPages.asmx / TierPriceListWithProduct",
$("#tierprices-grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "../../AjaxFunctionsAdminPages.asmx/TierPriceListWithProduct",
type: "POST",
dataType: "json",
data: {
ID: ID
}
},
destroy: {
url: "/Admin/Product/TierPriceDelete",
type: "POST",
dataType: "json",
data: addAntiForgeryToken
}
},
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
fields: {
Store: { editable: true, type: "string" },
StoreId: { editable: true, type: "number" },
CustomerRole: { editable: true, type: "string" },
CustomerRoleId: { editable: true, type: "number" },
Quantity: { editable: true, type: "number" },
Price: { editable: true, type: "number" },
StartDateTimeUtc: { editable: true, type: "date" },
EndDateTimeUtc: { editable: true, type: "date" },
Id: { editable: false, type: "number" }
}
}
},
error: function (e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
}
},
pageable: {
refresh: true,
numeric: false,
previousNext: false,
info: false
},
editable: {
confirmation: "hhhhhh",
mode: "inline"
},
scrollable: false,
columns: [
{
field: "StoreId",
hidden: true,
title: "Store",
template: "#:Store#"
}, {
field: "CustomerRoleId",
title: "Customer",
template: "#:CustomerRole#"
}, {
field: "Quantity",
title: "Quantity",
format: "{0:0}"
}, {
field: "Price",
title: "Price"
}, {
field: "StartDateTimeUtc",
title: "astartdatetimeutc",
type: "date",
format: "{0:G}"
}, {
field: "EndDateTimeUtc",
title: "enddatetimeutc",
type: "date",
format: "{0:G}"
}, {
field: "Id",
title: "Edit",
headerAttributes: { style: "text-align:center" },
attributes: { style: "text-align:center" },
template: "<button onclick=\"javascript:OpenWindow('/Admin/Product/TierPriceEditPopup/#=Id#?btnId=btnRefreshTierPrices&formId=product-form', 800, 600, true); return false;\" class='btn btn-default'><i class='fa fa-pencil'></i>Edit</button>"
}, {
command: { name: "destroy", text: "Delete" },
title: "Delete"
}
]
});
});
The code is:
$.ajax({
type: "POST",
url: '#Url.Action("getFilterActiveData")',
dataType: "json",
mtype: "post",
traditional: true,
data: {
values: arg
},
async: true,
beforeSend: function () {
$("#filter tr").live('click', function () {
document.getElementById('filter_btn').style.pointerEvents = 'none';
});
$('#filter_loading').fadeIn();
},
success: function (data) {
$('#filter_loading').fadeOut();
$("#filter tr").live('click', function () {
alert("does not shown");
if (isSection == false) {
$('#filter_btn').click().promise().done(function () {
document.getElementById('filter_btn').style.pointerEvents = 'auto';
});
}
});
}
});
The alert is not shown, but if I write out side of the AJAX directly like:
$("#filter tr").click(function () {
alert("clicked " + isSection);
Then it will show. Any suggestions please? I can make a function that will be called in success but I don't know about what to do in beforeSend()
Try this one , live method is depreciated long ago. Instead of live you can use the $.on() , $.bind() or something like that..
$.ajax({
type: "POST",
url: 'file url',
dataType: "json",
method : "post",
data: { values: arg },
async: true,
beforeSend: function(){
$("#filter tr").on('click', function () {
document.getElementById('filter_btn').style.pointerEvents = 'none';
});
$('#filter_loading').fadeIn();
},
success: function (data) {
$('#filter_loading').fadeOut();
$("#filter tr").click(function () {
alert("does not shown");
if (isSection == false) {
$('#filter_btn').click().promise().done(function () {
document.getElementById('filter_btn').style.pointerEvents = 'auto';
}
});
}
});
I'm building a Kendo UI Grid using their JS library. This is the code im using:
<div>
<div>
<div id="grid"></div>
<script>
$(document).ready(function () {
var Supplier = kendo.data.Model.define({
id: "SupplierId",
fields: {
SupplierId: { required : true},
PrefixCountryCode: { required: true },
SupplierName: { required: true }
}
});
var customer = kendo.data.Model.define({
id: "CustomerId",
fields: {
CustomerId: { editable: false },
CustomerName: { validation: { required: true } },
CountryCode: { validation: { required: true } },
CustomerERPId: { validation: { required: true } },
Suppliers: {
}
}
});
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '#Url.Action("GetCustomers", "Customer")',
dataType: "json"
},
update: {
url: '#Url.Action("SaveCustomer", "Customer")',
dataType: "json",
type: "POST"
},
destroy: {
url: '#Url.Action("RemoveCustomer", "Customer")',
dataType: "json",
type: "POST"
},
create: {
url: '#Url.Action("CreateCustomer", "Customer")',
dataType: "json",
type: "POST"
},
parameterMap: function (options, operation) {
if (operation !== "read") {
console.log(options);
return options;
}
}
},
pageSize: 20,
schema: {
model: customer
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{
field: "CustomerName",
title: "CustomerName",
width: 200
}, {
field: "CountryCode",
title: "CountryCode",
width: 50
},
{
field: "CustomerERPId",
title: "CustomerERPId",
width: 100
},
{
field: "Suppliers",
title: "Suppliers",
width: 200,
editor: supplierMultiSelect, template: kendo.template($("#supplierTemplate").html())
},
{ command: ["edit", "destroy"], title: " ", width: "200px" }
],
editable: "inline",
});
});
function supplierMultiSelect(container, options) {
console.log(options.field);
$('<input data-text-field="SupplierName" data-value-field="SupplierId" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoMultiSelect({
autoBind: true,
dataTextField: "SupplierName",
dataValueField: "SupplierId",
dataSource: {
type: "json",
transport: {
read: {
url: '#Url.Action("GetSuppliers", "Customer")',
dataType: "json"
}
}
},
});
}
</script>
<script type="text/kendo" id="supplierTemplate">
<ul>
#for(var i = 0; i< Suppliers.length; i++){#
<li>#:Suppliers[i].SupplierName#</li>
#}#
</ul>
</script>
</div>
As you can see i have an kendo multiselect in each row. The problem i got is that when i try to update the values the values from the multiselect doesn't follow along to the controller. In the parameterMap method i have a console log and there i can see that all the values that the grid post to the controller is correct.
The image above is from my chrome console and there i have 3 multiselect models that exists in the object and that is correct.
On the image above you can see what my controller method gets from the post.
It gets all the values from the customer-object and it also gets that there is 3 suppliers to the customer that got posted. But all the values for each of the suppliers is null. I guess this has to something to do with the binding of the multiselect but i just can't figure out why it doesn't work. Plz help!
I can successfully make the AJAX call to my web method using the following code and web method return the JSON which is pasted below:
My Web Method
[WebMethod]
public static string GetJson()
{
string query = "SELECT top 10 cast(ClientUID as varchar) ClientUID FROM <tablename>";
SqlCommand cmd = new SqlCommand(query);
// Populate the DataSet.
DataSet data = GetData(cmd);
// return the Customers table as JSON.
DataTable dt = data.Tables[0];
var returnJSON = (from p in dt.AsEnumerable()
select new
{
ClientUID = p.Field<string>("ClientUID")
}).ToList();
var serializer = new JavaScriptSerializer();
string json = serializer.Serialize(returnJSON);
return json;
}
JSON returned by web method:
[{"ClientUID":"1"},{"ClientUID":"2"},{"ClientUID":"3"},{"ClientUID":"4"},{"ClientUID":"5"},{"ClientUID":"6"},{"ClientUID":"7"},{"ClientUID":"8"},{"ClientUID":"9"},{"ClientUID":"10"}]
Call to web method using AJAX
<script type="text/javascript">
$(document).ready(function() {
$.ajax(
{
type: "POST",
url: "ServeClientCalls.aspx/GetJson",
data: {},
contentType: "application/json;charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function(msg) {
//checking the content return from the above web method
$("#msg").html(msg.d);
//Binding to kendo Grid
$("#grid").kendoGrid({
dataSource: {
data: msg.d,
schema: {
model: {
fields: {
ClientUID: { type: "string" }
}
}
},
pageSize: 20
},
height: 430,
filterable: true,
sortable: true,
pageable: true,
columns: [
{ field: "ClientUID" }
]
});
},
error: function(x, e) {
$("#msg").html(x.responseText);
}
});
});
</script>
Problem : My grid does not bind and only headers are displayed whereas when I use the code in this manner mentioned below it is working
<script type="text/javascript">
$(document).ready(function() {
$.ajax(
{
type: "POST",
url: "ServeClientCalls.aspx/GetJson",
data: {},
contentType: "application/json;charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function(msg) {
//checking the content return from the above web method
$("#msg").html(msg.d);
**var p = [{ ClientUID: 1 }, { ClientUID: 2 }, { ClientUID: 3 }, { ClientUID: 4 }, { ClientUID: 5 }, { ClientUID: 6 }
, { ClientUID: 7 }, { ClientUID: 8 }
, { ClientUID: 9 }, { ClientUID: 10}];**
//Binding to kendo Grid
$("#grid").kendoGrid({
dataSource: {
**data: p,**
schema: {
model: {
fields: {
ClientUID: { type: "string" }
}
}
},
pageSize: 20
},
height: 430,
filterable: true,
sortable: true,
pageable: true,
columns: [
{ field: "ClientUID" }
]
});
},
error: function(x, e) {
$("#msg").html(x.responseText);
}
});
});
</script>
Use data: "d", under schema section. That should work.