So I’m working on learning Kendo in an effort to push our employer closer towards purchasing a few licenses for our new web development agenda.
I have an Core2 API set up and functioning on an internal web server and am attempting to use that to create an administration page for another application.
What would cause this (described below) to occur and what's the best way to handle it or what I'm attempting?
Setting up the grid and displays is done but having a problem getting data back to the API, correctly.
It seems to be an odd problem related to having drop down lists as the data source for 2 fields.
When the page first loads, the model matches that as defined in the data source schema.
schema: {
model: {
id: "id",
fields: {
projectName: { validation: { required: true, max: 150 } },
projectDescr: { validation: { required: true, max: 500 } },
projectOwner: { validation: { required: true, max: 125 } },
projectCoder: {type:"number", required:true, validation: { required: true }, from:"projectCoder"},
projectCoderNavigation: { from: "projectCoderNavigation", nullable:false},
projectEstHours: {type: "number", validation: {min: 0}},
statusId: { validation: { required: true }, from:"statusId"},
statusReason: { validation: { max: 125 },from:"statusReason" }
}
}
Kendo grid columns
columns: [
{field: "projectName", title: "Project Name"},
{field: "projectDescr", title: "Description", editor: descrEditor},
{field: "projectOwner", title: "Project Owner"},
{field: "projectCoder", title: "Programmer", editor: programmerDDL, template:"#= projectCoderNavigation.adName#" },
{field: "statusId", title:"Status", editor: statusDDL, template:"#= statusReason#"},
{field: "projectEstHours", title: "Estimated Hours"}
Model data returned from server (chrome dev tools). Here it matches above model, with the exception that the projectCoderNavigation property also includes projectTime, Tasks, and a repeat of projects.
When I click the add new record button, the model data is updated with blank data correctly.
However once I hit save, the model changes and a new object “adName” is added and matches the data source for the drop down list used for selection.
The projectCoder remains 0, projectCoderNavigation remains null, and the other fields are updated.
And of course, POST fails due to invalid model state.
EDIT
This is the function to populate the DDL editor.
function programmerDDL(container, options) {
// var input = $("<input/>");
//input.attr("projectCoderNavigation.adName",options.field);
// input.append(container);
$('<input type="text" class="k-input k-textbox" name="adName"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
//valuePrimitive: true,
dataTextField: "adName",
dataValueField: "id",
dataSource: usersListDs,
text: "Select someone"
});
}
This is assigning the editor to the dropdown.
{field: "projectCoder", title: "Programmer", editor: programmerDDL,
template:"#= projectCoderNavigation.adName#" },
Note:
I have managed to work it out so that I assign the projectCoder via the parameter map, but still have the empty projectCoderNavigation property and the unwanted "adName" object in the options.models.
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
console.log("model: "+options.models);
if (operation === "create") {
options.models[0].projectCoder = options.models[0].adName.id;
}
console.log(options.models);
console.log(kendo.stringify(options.models));
return options.models;
}
}
EDIT 2
So I've progressed to where I can verify the request is reaching the API and will probably close this question, but I'll provide more information first.
When save is clicked, the API receives the POST request. However, the data from the payload isn't used by the method.
The response is HTTP code 500, as the model was null and the insert failed due to foreign key constraints.
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_att_projects_att_Users". The conflict occurred in database
"ASSIST_TimeTracking", table "dbo.att_users", column 'id'. The
statement has been terminated.
Related
I am using free jqgrid.I am using following code as a simple example.Data comes out be correct without grouping but with grouping it is unable to capture data(placeid) not shown in the row.I understand that on grouping, rowObject does not have placeid but how do I go about resolving the issue.
jsfiddle link: http://jsfiddle.net/johnnash03/6jhqgxw8/5/
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}]
var cols = ["place","code"];
$("#grid").jqGrid({
datatype: "local",
height: 250,
colNames: cols,
colModel: [{
name: 'place',
}, {
name: 'code',
formatter: function( cellvalue, options, rowObject ) {
return rowObject['placeid']
}
}]
});
for(var i=0;i<rows.length;i++)
$("#grid").jqGrid('addRowData',i+1,rows[i]);
// Data comes correct on commenting following line.
$("#grid").jqGrid( 'groupingGroupBy', 'place');
The main problem in your demo is the usage of the property placeid, which isn't in any columns of the grid. You fills additionally the grid using addRowData method called in the loop. It's the slowest way to fill the grid, which I know. The most important in your case is that the internal data of the grid will be filled only with place, code and id properties. No placeid property will be saved locally. Thus one don't see it during the later groping the grid.
One can solves the problem by usage additionalProperties option, which specify the names of additional properties of input items, which needed be saved in the local data. Adding
additionalProperties: ["placeid"]
option solves the issue. See the modified demo http://jsfiddle.net/OlegKi/6jhqgxw8/8/
I'd strictly recommend you to modify the code to about the following:
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}];
$("#grid").jqGrid({
data: rows,
colModel: [
{ name: "place" },
{ name: "code",
formatter: function (cellvalue, options) {
return options.rowData.placeid;
}
}
],
grouping: true,
groupingView : {
groupField : ["place"]
},
localReader: { id: "placeid" }
});
Where one can add optionally additionalProperties: ["placeid"] too. See http://jsfiddle.net/OlegKi/6jhqgxw8/9/.
The above code create, fills and group the data at once. It uses localReader: { id: "placeid" } additionally to inform that placeid property has the rowid information (the unique values used as the values of id property of the rows: <tr> elements) instead of default id property.
Here my snipet. I have two problems. First, i can't view selected item, after i select item in dropdown and save. Second, if create new item without select domain, it has wrong site code. Domain can't be zero because site_data not contains item with code 0;
Help me please
You don't see the selected item because you did not set selectable to true in the ListView.
You get value 0 for domain because you did not define a default value for site in your dataSource so being a number the default value is 0 and it is not important the fact that there is no 0 in the list of values that you provide (there is no such validation). So you should have it as:
document.provider_source = new kendo.data.DataSource({
pageSize: 6,
schema: {
model: {
id: "code",
fields: {
code: { editable: false, nullable: true },
site: { type: "number", defaultValue: 1 },
login: { type: "string" },
pass: { type: "string" }
}
}
},
data: provider_data
});
Where I set defaultValue for site to 1 (first value in the list).
Your code modified here: http://dojo.telerik.com/#OnaBai/Ihab
I am binding the Combobox to a complex Object, the binding is such that ID field is available as a direct property on this object but the Text Property is coming from a child objects property.
I have been able to configure it show the values correctly, but running into problem to specify the optionLabel saying "select" not able to specify Parent.Childproperty getting runtime error (Uncaught TypeError: Cannot read property 'Childproperty' of undefined )
How can i specify Complex Objects in the Model defination and below for the empty selection ?
$('<input id="DegreeDDL" name="' + options.field + '"/>').appendTo(container).kendoDropDownList({
autoBind: true,
serverFiltering: true,
optionLabel: {
'Parent.Childproperty': "--- Select ---",
ABCD_PK: null
},
dataSource: {
transport: {
read: {
url: function (e) {
return "api/Org/XXXXXXXX?abcdPK=" + efgh;
},
dataType: "json" // <-- The default was "jsonp"
}
},
},
dataTextField: "Parent.ChildProperty",
dataValueField: "ABCD_PK"
});
Also running into similar propblem when defining model for the grid
var model = {
id: "ABCD_PK",
fields: {
Parent.Child.ChilProperty:
}
}
To answer your first question: use optionLabel as string if creating object here causes errors:
optionLabel: "--- Select ---",
Here is working JSFiddle: http://jsfiddle.net/a6Ek2/11/
To answer your second question just use dataSource.schema to parse your json for non complex object. More in this topic: How can I use nested Json to populate Kendo UI grid?. Grid official do not working with complex data objects. But if you wanna give a try you delclare only parent object in model eg:
fields: {
ABCD_PK: { editable: false },
Parent: { editable: true },
}
If you still got problem with this just update this JSFiddle and show exacly where this is. I'll try improve my answers then.
I'm using a kendo gird. When I sort my grid, It doesn't sort next page data. It is only sorted on first page. I want to sort whole data in the grid. How can I do it??
$("#ProductGrid").kendoGrid({
columns: [
{ field: "ProductID", title: 'Product Id' ,width:50},
{ field: "ProductName", title: 'Product Name' },
{ field: "Price", title: 'Price' },
],
groupable: true,
sortable: true,
pageable: true,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
scrollable: true,
filterable: true,
dataSource: new kendo.data.DataSource({
transport: {
read: "../api/Product/FindByPartyIDForGrid?partyID=" + PartyID
},
serverPaging: true,
serverSorting: true,
pageSize: 50,
schema: {
data: "Data",
total: "Count"
}
})
});
My server side method
[System.Web.Http.AcceptVerbs("GET", "POST")]
[System.Web.Http.HttpGet]
[ActionName("FindByPartyIDForGrid")]
public Responce FindByPartyIDForGrid(string partyID)
{
int take = httpRequest["take"] == null ? 10 : int.Parse(httpRequest["take"]);
int skip = httpRequest["skip"] == null ? 0 : int.Parse(httpRequest["skip"]);
var content = new ProductBS().FindByPartyID(Convert.ToInt32(partyID));
if (content != null)
{
return new Models.Responce(content.Skip(skip).Take(take).ToArray(), content.Count());
}
else
{
return new Responce(new Array[0], 0);
}
}
Seems like this is not a client side (kendo) issue. Kendo grid is configured correct as I can see. In your FindByPartyIDForGrid method you need to do the sorting and return relevant page correctly.
Check your server logic, If you can post it here we can have a look in to it.
EDIT
Seems like you haven't handle the sorting in the server,you have two options,
1.You can do it using Odata protpcol
2. You can do it by handling sorting yourself,
This occurs because you have enabled serverSorting. Then you should perform the sorting yourself.
If you don't bind the grid to lots items you can use client-side sorting. Simply remove the serverSorting: true option of the data source.
i have developed a web application using kendo ui tools and theres a kendo grid with batch edit mode..
but when i press the delete button for any record in kendo grid it will erase from the list in grid but actually not in the data source.when i reload the page or grid the deleted item will still exist..
here is the code of my grid
<div id="grid">
</div>
<script type="text/javascript">
$("#submitMarketUser").click(function () {
var grid = $("#grid").data("kendoGrid");
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "WholeSaleTrade/GetTradeProductDetail",
dataType: "json",
data: {
test: $("#Names").val()
}
},
destroy: {
url: "WholeSaleTrade/DeletePro",
type: "POST",
dataType: "jsonp",
data: {
DAKy: $("#Names").val(),
DIKy: $("#btntxt").val()
}
},
create: {
url: "WholeSaleTrade/CreateProduct",
type: "POST",
dataType: "jsonp",
data: {
AKy: $("#Names").val(),
IKy: $("#btntxt").val()
}
}
},
pageSize: 5,
schema: {
model: {
id: "ProductKey",
fields: {
ProductKey: { editable: false, nullable: true },
ProductName: { validation: { required: true} }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
editable: true,
toolbar: ["create", "save"],
autobind: true,
pageable: true,
columns: [
{ field: "ProductName", title: "Product Name",
editor: function (container, options) {
var model = options.model;
$('<input id="btntxt" name="' + options.field + '"/>').appendTo(container).kendoComboBox({
dataSource: {
type: "POST",
transport: {
read: {
url: "MarketInformation/PopulateProducts",
success: function (data) {
var prod = data[0];
model.set("ProductName", prod.ItmNm);
model.set("ItmKy", prod.ItmKy);
model.set("UserKey", $("#Names").val());
}
}
}
},
dataValueField: "ItmKy",
dataTextField: "ItmNm"
});
}
},
{ command: ["destroy"], title: " " }
]
});
});
</script>
can not identify that where is the fault going and can somebody please help me to solve this matter.
There are three common reasons delete won't work:
1. Not setting editable of grid to inline or popup. The deleted items will be automatically processed through transport destroy only for "inline"/"popup" edit modes. Ex:
editable: {
mode: "inline",
}
//or
editable: "inline"
2. If 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(). Ex:
var dataSource = new kendo.data.DataSource({
batch: true,
//.....
});
//... in some where e.g in a save button click event call the following line:
dataSource.sync();
3. You should define id to your primary key of database field name inside model of datasource. Ex:
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
}
}
So the problem with your code is first one, i.e you did not set editable to inline or popup
If you choose not to include editable.mode in order to utilize the in-cell editing, you can set the toolbar of the grid to include the option save:
$("#grid").kendoGrid({
dataSource: {
transport: {
....
},
schema: {
....
}
},
toolbar: ["create", "save", "cancel"],
columns: [
....
],
editable: true
});
This will create a save button at the toolbar of the grid. After deleting any records by clicking the destroy command button, click on the save button to have the grid to make an Ajax call to the server to delete the record.
If you would rather delete the record automatically without including the save button, you could add a change event handler to the datasource of the grid:
$("#grid").kendoGrid({
dataSource: {
transport: {
....
},
schema: {
....
},
change: function(e) {
if (e.action === "remove") {
this.sync();
}
}
},
columns: [
....
],
editable: true
});
This will automatically sync the changes you made to the grid with the server when there's a data change.
Hmm try not including type: "POST", and see if it now works since as far as I can see that bit isn't included on the demo's and I don't think I included it when I last did inline edits/deletes.
I had put an arbitray name for an int on the server Delete Method.
[HttpPost]
public ActionResult DeleteRandomTest(Int32 randomTestId)
{
...
}
The default modelbinder was probably looking for a property called Id (same as the primary key of my type according to the configuration of the model).
.Model(config => config.Id(p => p.Id))
In fact, I proved this by changing the signature to the following:
[HttpPost]
public ActionResult DeleteRandomTest(Int32 Id)
{
...
}
My break point was hit after that.
Ultimately, I used the full type as the parameter as shown in the Kendo examples because I didn't want to have poorly named parameter names (not camel case) in the action. Shown as follows:
[HttpPost]
public ActionResult DeleteRandomTest([DataSourceRequest]
DataSourceRequest request, RandomDrugTest randomDrugTest)
{
...
}
This seems to the be the reason it wasn't working.
I had the same issue. My issue was caused by having a data property in the kendo model. Example:
{id: 1, data: ""}