Kendo grid edit popup mvvm binding seems failed - kendo-ui

Grid popup mvvm binding seems fail when I add a new row and to set value of model attribute in edit eventHandler(model.set("port","udp")) but the select input doesn't change value and from debugger console it shows that event.model's value of property keep unchanged.
But after i manually selecting the port,I try to model.set("port","tcp"),it works!
I am confused of the timing of the binding mechanism of the value field of input element and kendo model binding...
Html part as below:
<div class="k-block k-shadow">
<table style="width:100%;">
<tr><td><button class="btn-add" id="ButtonNew" type="button" onclick="addSetting()">New</button></td></tr></table>
</div>
<div class="k-block k-shadow">
<div id="logForwardingGrid"></div>
</div>
javascript as below:
var dataSource = new kendo.data.DataSource({
data:{"items":[{"seq":8,"ip":"10.0.0.99","port":36,"protocol":"udp","enable":false}]},
schema: {
data: "items",
model: {
id: "seq",
fields: {
seq: { type: "int", editable: false, validation: { required: false} },
port: { type: "int",editable: true, validation: { required: true} },
protocol: { type: "string",editable: true, validation: { required: true} },
enable: { type: "boolean", validation: { required: true} },
}
}
},
});
$("#logForwardingGrid").kendoGrid({
dataSource: dataSource,
columns: [{
field: "seq",
hiddenEdit: true,
hidden: true
}, {
field: "ip",
title: "IP",
}, {
field: "port",
title: "Port",
}, {
field: "protocol",
title: "Protocol",
editor: protocalEditor
}],
editable: {
mode:"popup",
},
edit: function(e) {
if (e.model.isNew()) {
//fail !! e.model's value of property("protocol") keep unchanged
e.model.set("protocol","udp")
console.log(e.model)
}
}
});
function protocalEditor(container,options){
var data = [{ text: "udp", value: "udp" },{ text: "tcp", value: "tcp" }]
$('<input id="protocol" name="protocol" required data-bind="value:'+ options.field +'"/>')
.appendTo(container).kendoDropDownList({
dataSource:data,
dataTextField: "text",
dataValueField: "value",
});
}
function addSetting(){
$("#logForwardingGrid").data("kendoGrid").addRow();
}

Try supplying a defaultValue for the field in your model declaration:
var dataSource = new kendo.data.DataSource({
data:{"items": [{"seq":8,"ip":"10.0.0.99","port":36,"protocol":"udp","enable":false}]},
schema: {
data: "items",
model: {
id: "seq",
fields: {
seq: { type: "int", editable: false, validation: { required: false} },
port: { type: "int",editable: true, validation: { required: true} },
protocol: { type: "string",editable: true, validation: { required: true}, defaultValue: "tcp" },
enable: { type: "boolean", validation: { required: true} },
}
}
},
});
I don't know why, but that seems to fix the problem. See dojo for working example.

Related

Kendo UI Inline grid not receiving Date Fields but other fields value getting in controller

I have used Kendo UI grid with inline editing, all filed received in controller but date field not receiving why?
This is my code, please help me
Grid---
$(document).ready(function() {
$("#orders-grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("CustomerList", "Customer"))",
type: "POST",
dataType: "json",
},
create: {
url: "#Html.Raw(Url.Action("CustomerAdd", "Customer"))",
type: "POST",
dataType: "json"
},
update: {
url:"#Html.Raw(Url.Action("CustomerUpdate", "Customer"))",
type: "POST",
dataType: "json"
},
destroy: {
url: "#Html.Raw(Url.Action("CustomerDelete", "Customer"))",
type: "POST",
dataType: "json"
},
},
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
fields: {
stfName: { editable: true, type: "string", validation: { required: true } },
Id: { editable: false, type: "number" },
stmName: { editable: true, type: "string", validation: { required: true } },
dtdob: { editable: true, type: "Date",format : "dd/MMM/yyyy", validation: { required: true } },
strefName: { editable: true, type: "string", validation: { required: true } },
}
}
},
requestEnd: function (e) {
if (e.type == "create" || e.type == "update") {
this.read();
}
},
error: function(e) {
//display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
pageable: {
refresh: true,
pageSizes: [10]
}, //scrollable: false,
// dataBound: onDataBound,
sortable: true,
scrollable: {
virtual: true
},
toolbar: ["create"],
editable: {
confirmation: false,
mode: "inline"
},
columns: [
{
field: "Id",
title: "ID",
width: 50
},{
field: "stfName",
title: "First Name",
//attributes: { "class": "upper" },
width: 200
},
{
field: "dtdob",
title: "D.O.B.",
//editor: customDateEditor,
type: "Date",
template: "#=kendo.toString(dtdob,'dd/MMM/yyyy')#",
//template: '<input type="date" name="dtdob" />',
width: 200,
//parseFormats: ["yyyy-MM-dd'T'HH:mm:ss.zz"]
},
{
field: "strefName",
title: "Reference",
width: 200
},
{
command: [{
name: "edit",
text: "Edit"
}, {
name: "destroy",
text: "Delete"
}],
width: 200,
filterable: true
}]
});
var customDateEditor = function (container, options) {
$('<input />')
.appendTo(container)
.kendoDatePicker({
format: "dd/MMM/yyyy"
});
};
});
--model
public partial class tblCustomer
{
public int Id { get; set; }
public string stfName { get; set; }
public DateTime dtdob { get; set; }
}
}
Controller----
public ActionResult CustomerUpdate(tblCustomer model) <-All Value receive in model except date field dtdob
{
}
I have check in firebug there is ajax call and all fields pass properly event date too, but not receiving in controller why?
Regards,
Vinit Patel
Please go through the link given below. It does have couple of solutions for the issue you are fixing. Please revert if the issue persists.
Passing dates from Kendo UI to ASP.NET MVC

Kendo grid - Posted Edit is null at Controller

Using kendo grid with Popup edit. I verified the data is posted from the view (I can see it in the Network Tab, here is a look at it:
{"LetterId":12,"BodyText":"This is a test","CreatedDate":"07/31/2013","CreatedBy":"Grace Rodgers","ModifiedDate":"07/31/2013","ModifiedBy":"Grace Rodgers","PersonId":18,"FirstName":"Jason","LastName":"Bigby"}:
However, I have a breakpoint at the json method in the controller, and when hovering over the model parameter, in shows all fields are null. Here is the first couple lines of the controller code:
[HttpPost]
public JsonResult JsonEditLetter(LetterViewModel model)
{
and the kendo code in the view:
var PersId = $("#PersonId").val();
var ds_LettersGrid = new kendo.data.DataSource({
transport: {
read: {
url: '#Url.Action("JsonGetLetterList", "Letter")/' + PersId,
dataType: 'json'
},
update: {
url: '#Url.Action("JsonEditLetter", "Letter")',
dataType: 'json',
type: "POST"
},
parameterMap: function (data, type) {
if (type == "update") {
data.models[0].CreatedDate = kendo.toString(new Date(data.models[0].CreatedDate), "MM/dd/yyyy");
data.models[0].ModifiedDate = kendo.toString(new Date(data.models[0].ModifiedDate), "MM/dd/yyyy");
return kendo.stringify(data.models[0]);
}
},
},
batch: true,
schema: {
model: {
id: "LetterId",
fields: {
BodyText: { editable: true },
CreatedDate: { editable: false, type: "date"},
ModifiedDate: { editable: false, type: "date" },
CreatedBy: { editable: false},
ModifiedBy: { editable: false },
PersonId: { defaultValue: PersId }
}
}
},
pageSize: 10
});
$(document).ready(function () {
$("#letter-list").kendoGrid({
dataSource: ds_LettersGrid,
sortable: true,
filterable: { extra: false, operators: {
string: { startswith: "Starts with", eq: "Is equal to" }
}
},
pageable: true,
columns: [{
field: "BodyText", title: "Letter Content", width: 400, filterable: false
}, {
field: "CreatedBy", title: "Author", filterable: false
}, {
field: "CreatedDate", title: "Original Date", format: "{0:g}", filterable: { ui: "datetimepicker" }
}, {
field: "ModifiedBy", title: "Edited By", filterable: false
}, {
field: "ModifiedDate", title: "Editted On", format: "{0:g}", filterable: { ui: "datetimepicker" }
}, {
command: [ "edit" ], title: "", width: "110px"
}],
height: "300px",
resizable: true,
editable: "popup"
});
});
You need to add default value to your id field , becouse the client side generates new id value, what you already have in server autoincrement generated id value and its shooting error
schema: {
model: {
id: "LetterId",
fields: {
LetterId: {defaultValue: 16000}
BodyText: { editable: true },
CreatedDate: { editable: false, type: "date"},
ModifiedDate: { editable: false, type: "date" },
CreatedBy: { editable: false},
ModifiedBy: { editable: false },
PersonId: { defaultValue: PersId }
}
}
}
I figured it out, it wanted a specific content type. The type being passed was a form, but the controller wanted json. So the Transport now looks like:
update: {
url: '#Url.Action("JsonEditLetter", "Letter")',
dataType: 'json',
>>>>>>>> contentType: "application/json",
type: "POST"
},

Detecting server-side error when editing or creating Kendo Grid entries

I have an editable Kendo Grid to manage (create/modify) user accounts. Editing is done in a popup (versus inline or batch). I have client-side validation to help ensure that valid data is provided to the server, however I cannot figure out how to handle the response from the server in the event that the create/update fails server-side. I'm not talking 'failed' as in the request failed with a HTTP 404 or 500, for example; I'm talking failed as in the script on the server didn't like something about the data and refuses to oblige.
Can someone please show me how I can accomplish this? What I would like to be able to do is after the update is sent to the server, wait for the response. If the response says everything is OK, then great. If the response says something didn't go so well, I'd like to be able to (A) keep the popup editing window open and populated and (B) provide feedback to the user regarding the reason for the rejection. The data should not be committed to the grid unless the response says everything is OK. Likewise, the edit popup should remain open until the server says OK.
I'm flexible with how the server's response should be formatted, as long as I can accomplish what I want.
Before you direct me to the Kendo official API documentation, I am already well aware of it and refer to it daily. However, to say the least, it is incomplete and I cannot find anything relating to this topic. If you have found something in the documentation that you think could help me then by all means point me to the documentation =)
As requested, below is the code I have for creating the grid.
$("#kendo_user_grid").kendoGrid({
columns: [{
title: "Last name",
field: "lName"
},{
title: "First name",
field: "fName"
},{
title: "Business unit",
field: "businessUnit"
},{
title: "Username",
field: "loginId"
},{
title: "Email address",
field: "email"
},{
title: "Phone",
field: "phone"
},{
title: "Address",
field: "address"
},{
title: "City",
field: "city"
},{
title: "State",
field: "state"
},{
title: "Zip code",
field: "zipcode"
},{
title: "Country",
field: "country"
},{
title: "Time zone",
field: "timezone"
},{
title: "Privileges",
field: "privs"
},{
command: ["edit","destroy"],
title: " "
}],
scrollable: false,
dataSource: {
transport: {
read: {
url: "manageUsers.phtml",
data: { mode: "fetch" },
dataType: "json",
type: "POST"
},
update: {
url: "manageUsers.phtml",
data: { mode: "update" },
type: "POST"
},
destroy: {
url: "manageUsers.phtml",
data: { mode: "destroy" },
type: "POST"
},
create: {
url: "manageUsers.phtml",
data: { mode: "create" },
type: "POST"
},
batch: false
},
schema: {
data: "records",
total: "total",
model: {
id: "userId",
fields: {
userId: { editable: false, nullable: true },
lName: { type: "string", editable: true, validation: { required: true } },
fName: { type: "string", editable: true, validation: { required: true } },
businessUnit: { type: "string", editable: true, validation: { required: true } },
loginId: { type: "string", validation: { required: true } },
email: { type: "string", validation: { required: true } },
phone: { type: "string" },
address: { type: "string" },
city: { type: "string" },
state: { type: "string" },
zipcode: { type: "string" },
country: { type: "string" },
timezone: { type: "string" },
privs: { type: "string" }
}
}
},
pageSize: 20,
serverPaging: false,
serverFiltering: false,
serverSorting: false
},
filterable: true,
sortable: true,
pageable: true,
editable: {
mode: "popup",
template: kendo.template($("#kendo_edit_user_template").html())
},
toolbar: ["create","save","cancel"]
});
There are two point to keep in mind:
Schema.errors The field from the server response which contains server-side errors.
error is an event that will be fired if there was an error.
Basically you need to:
add to your schema an errors definition that provides access to the status sent back from the server.
Implement error event handler that, for example, restore previous value.
If your server returns the error message in a field called myError then you would have something like:
schema: {
errors: "myError",
data: "records",
total: "total",
model: {
id: "userId",
fields: {
userId: { editable: false, nullable: true },
lName: { type: "string", editable: true, validation: { required: true } },
fName: { type: "string", editable: true, validation: { required: true } },
...
or:
schema: {
errors: function(response) {
if (response.myError && response.myError !== "OK") {
return response.myError;
}
return false;
},
data: "records",
total: "total",
model: {
id: "userId",
fields: {
userId: { editable: false, nullable: true },
lName: { type: "string", editable: true, validation: { required: true } },
fName: { type: "string", editable: true, validation: { required: true } },
...
and the event would be:
dataSource: {
error : function (e) {
if (e.errors !== false) {
alert("Error: " + e.errors);
// This will cancel any change done
this.cancelChanges();
}
},
transport: {
read: {
url: "manageUsers.phtml",
data: { mode: "fetch" },
dataType: "json",
type: "POST"
},
EDIT : If what you want is to keep the popup open you should do:
dataSource: {
error : function (e) {
if (e.errors !== false) {
alert("Error: " + e.errors);
// This will keep the popup open
grid.one("dataBinding", function (e) {
e.preventDefault(); // cancel grid rebind
});
}
},
transport: {
read: {
url: "manageUsers.phtml",
data: { mode: "fetch" },
dataType: "json",
type: "POST"
},
Where I bind to databinding event just once using jQuery.one

Kendo UI DataSource not triggering transport.destroy

I am using Kendo UI with ASP.NET Web API. There is a ProjectsController that has all the necessary methods.
My issue is that when I click on Delete button, Kendo UI grid will raise remove() event, but DataSource never invokes transport.destroy. Rather, it seems that tansport.create is being invoked. In transport.parameterMap I can see that the operation is create instead of destroy.
Here is a sample JavaScript code:
$(document).ready(function () {
var apiUrl = '/api/projects/';
var dataType = 'json';
var dataSource = new kendo.data.DataSource({
batch: true,
autoSync: false,
transport: {
read: {
url: apiUrl,
dataType: dataType,
type: "GET"
},
update: {
url: apiUrl,
dataType: dataType,
type: "PUT"
},
destroy: {
url: apiUrl,
type: "DELETE"
},
create: {
url: apiUrl,
contentType: "application/json;charset=utf-8",
dataType: dataType,
type: "POST"
},
parameterMap: function (data, operation) {
console.log("Operation: " + operation);
if (operation === "create" && data.models) {
for (var i in data.models) {
var model = data.models[i];
if (model.ProjectId === 0) {
return kendo.stringify(model);
}
}
} else if (operation === "destroy") {
console.log("Data.Models: " + data.models);
console.log("Data.id: " + data.ProjectId);
return { id: data.ProjectId };
}
return data;
}
},
schema: {
id: "ProjectId",
model: {
fields: {
ProjectId: { type: "number", editable: false, nullable: false, defaultValue: 0 },
ProjectName: { type: "string", validation: { required: true } },
Status: { type: "string", validation: { required: true } },
IsActive: { type: "boolean" }
}
}
},
pageSize: 10,
serverPaging: false,
serverFiltering: false,
serverSorting: false
});
$("#projectsGrid").kendoGrid({
dataSource: dataSource,
groupable: false,
sortable: true,
pageable: {
refresh: true,
pageSizes: true
},
pageSize: 10,
toolbar: ["create"],
editable: "popup",
columns: [
{ field: "ProjectId", width: 30, title: "ID" },
{ field: "ProjectName", width: 180, title: "Project" },
{ field: "Status", width: 90, title: "Status" },
{ field: "IsActive", width: 40, title: "Is Active", type: "boolean", template: '<input type="checkbox" #if (IsActive) {# checked="checked" #}# disabled="disabled" />' },
{ command: ["edit", "destroy"], title: "&nbsp", width: "80px" }
],
remove: function (e) {
console.log("Delete button clicked.");
console.log("Project ID: " + e.model.ProjectId);
//dataSource.remove(e.model);
//dataSource.sync();
}
});
});
Web API works fine when requests are issued via Fiddler, but Kendo UI Grid shows:
POST http://localhost:port/api/Projects
when it should be DELETE.
Thanks everyone in advance!
On your datasource, you have the batch flag set to true, this means the datasource will make the call only after you tell it to, e.g calling sync().
http://docs.kendoui.com/api/framework/datasource#configuration-batch
As well as
Make sure you have defined Id in the model, as OnaBai explained here Why does the KendoUI Grid Transport Create event gets raised multiple times, and even when the action is Update? , your id is outside the model, should be in :
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
}
}
if someone has defined the id in model as answered in above ,but dataSource not triggering transport.destroy yet ,below configuration could be helpful:
editable: {
..
mode: "inline", //or "popup
...
}
//or
editable: "inline" //or "popup"
http://www.telerik.com/forums/transport-destroy-of-grid-editor-is-not-working

filter kendo ui grid with filed type object

I have this grid
$("#address-grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "operations/get_sales_reps_addresses.php?salesRepsId=" + salesRepsId,
type: "GET"
},
update: {
url: "operations/edit_address.php?salesRepsId=" + salesRepsId,
type: "POST",
complete: function (e) {
$("#address-grid").data("kendoGrid").dataSource.read();
}
},
destroy: {
url: "operations/delete_address.php",
type: "POST",
complete: function (e) {
$("address-grid").data("kendoGrid").dataSource.read();
}
},
create: {
url: "operations/add_address.php?salesRepsId=" + salesRepsId,
type: "POST",
complete: function (e) {
$("#address-grid").data("kendoGrid").dataSource.read();
}
},
},
schema: {
data: "data",
total: "data.length", //total amount of records
model: {
id: "SalesRepId",
fields: {
AddressType: {
defaultValue: {
AddressTypeid: 1,
AddressTypeName: "Work"
}
},
Country: {
defaultValue: {
CountryId: 38,
CountryName: "Canada"
}
},
State: {
defaultValue: {
StateId: 4223,
StateName: "British Colombia"
}
},
City: {
defaultValue: {
CityId: 59450,
CityName: "Vancouver"
}
},
PostalCode: {
type: "string"
},
AddressText: {
type: "string"
},
IsMainAddress: {
type: "boolean"
},
AddressId: {
type: "integer"
}
}
}
},
pageSize: 3,
},
ignoreCase: true,
height: 250,
filterable: true,
sortable: true,
pageable: true,
reorderable: false,
groupable: false,
batch: true,
navigatable: true,
toolbar: ["create", "save", "cancel"],
editable: true,
columns: [{
field: "AddressType",
title: "Type",
editor: AddressTypeDropDownEditor,
template: "#=AddressType.AddressTypeName#",
}, {
field: "Country",
title: "Country",
editor: CountryDropDownEditor,
template: "#=Country.CountryName#",
}, {
field: "State",
title: "State",
editor: StateDropDownEditor,
template: "#=State.StateName#",
}, {
field: "City",
title: "City",
editor: CityTypeDropDownEditor,
template: "#=City.CityName#",
}, {
field: "PostalCode",
title: "Postal Code",
}, {
field: "AddressText",
title: "Address",
}, {
field: "IsMainAddress",
title: "Main?",
width: 65,
template: function (e) {
if (e.IsMainAddress == true) {
return '<img align="center" src ="images/check-icon.png" />';
} else {
return '';
}
}
// hidden: true
}, {
command: "destroy",
title: " ",
width: 90
},
]
});
The problem is when I try to filter by Country or State or City I got an error
TypeError: "".toLowerCase is not a function
I tried to change the type of Country to string, I use comobox, so the values were undefined. I also tried to change the type to Object, the values displayed correctly but I couldn't filter. I got the same error( toLowerCase)
How can I fix this ??
My grid is very similar this example
and here is the jsFiddle . I've just added the filter. and I still get previous error
I want to filter on the Category, any help ??
This is how you filter a dataSource Kendo dataSource , filter
So get the dataSource of your grid,
var gridDatasource = $("#address-grid").data('kendoGrid').dataSource;
and filter it like this example.
gridDatasource.filter({ ... });
If you provide a working jsFiddle, you may get a more specific answer.
Specific answer:
You added the filter, so for Category it didn't work because as I said, it is an observable, not a filed you can filter as a string.
So you must specify better your filter for this column, like this:
field: "Category",
title: "Category",
width: "160px",
editor: categoryDropDownEditor,
template: "#=Category.CategoryName#",
filterable: {
extra: false,
field:"Category.CategoryName",
operators: {
string: {
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to"
}
}
}
see this jsFiddle -- > http://jsfiddle.net/blackjim/Sbb5Z/463/

Resources