KendoUI Combobox Configure for Complex Objects - kendo-ui

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.

Related

Kendo headerTemplate

I am trying to build this dojo with the headerTemplate and the columns title and data fields under it but I am not sure what I am doing wrong I am not getting any errors so its hard to understand what is happening?
https://dojo.telerik.com/#mcdevittnccn/iNinebUm
I would suggest a bit different approach here. Problem is that your data is a complex nested object (an object with an array of objects - basically grid inside grid). Kendo data source best works with flattened data. If you can't change data you can use the kendo grid detailInit event so every object array has an inner table with data. Something like this:
$(document).ready(function () {
$("#kendogrid").kendoGrid({
dataSource: {
data: data,
pageSize: 10
},
pageable: true,
scrollable: false,
persistSelection: true,
toolbar: ["search"],
search: {
fields: ['Name']
},
sortable: true,
columns: [
{
field: "Name",
title: "Name"
}
],
detailTemplate: '<div class="grid"></div>',
detailInit: function (e) {
e.detailRow.find(".grid").kendoGrid({
dataSource: e.data.PanelsMeetingViewModel
});
}
});
});
Example: Kendo grid detail init
Note: because of the inner table quick search will not work.

Kendo grid adding another data source as object to model on save

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.

Setting Value programmatically in KendoUI multiselect

I have my KendoUI MultiSelect widget initialized like this:
$("#" + key).kendoMultiSelect({
placeholder: placeholder,
dataTextField: dataText,
dataValueField: dataValue,
filter: "contains",
autoBind: false,
dataSource: {
type: "jsonp",
transport: {
read: {
url: urlValue
}
},
error: function(e) {
console.log(e);
}
},
value: GetSavedJSONObject(key),
//value: [
//{ Name: "Chang", Id: 2 },
// { Name: "Uncle Bob's Organic Dried Pears", Id: 7 }
//],
select: removeMark,
change: multiselect_checkForChanges,
autoClose: isAutoClose
});
where GetSavedJSONObject(key) is an array of objects like this:
[Object { Id=1, Name="AA"}, Object { Id=2, Name="BB"}]
The issue I'm facing is when the page loads, I can see "AA" and "BB" in the multiselect widget and no call is made to the url. However, when I attempt to add more items to the widget, there are none to be added because the widget thinks the only items available are the items I specified in the "value" field of the widget during initialization.
In the Server Filtering demo, you will see that the example sets the value of the widget just like I did but when you try to add more items to the widget, then a call is made to the url for more data and the widget opens.
I'm sure this is user error but I just need some pointers on what to try next in order to get the widget to display the rest of the data.
EDIT:
When I made GetSavedJSONObject(key) return an array of the Ids so
[1,2,3]
I was able to click on the widget to get the rest of the data. However, the desired outcome is being able to set the values of the widget (because I have the Id/Name pairs) without having to make the call to the datasource and being able to click on the widget to fetch the rest of the data)
Keeping my array of Objects and setting the serverFiltering: true attribute fixed the issue. Hope this saves someone else time. sigh

Setting dataTextField value in Kendo UI kendoComboBox object

I have a Kendo UI combobox object something like this :
widget: "kendoComboBox",
options: {
dataTextField: "#:userFirstName#&nbsp#:userLastName#",
dataValueField: "userId",
template: "#:userFirstName#&nbsp#:userLastName#",
change: function (e) {
that.model.fn.bringUserData();
}
}
I can arrange the template, but i cannot dataTextField value depends on that template. It is possible to make it "userId" etc. But seems not possible to set selected value as #:userFirstName#&nbsp#:userLastName#. (dataTextFieldTemplate doesn't work.)
Could you help me to solve this?
Correct, you cannot make it a composition of two fields. It needs to be a field per se. What you can do is when reading data from the DataSource create an additional field that is the concatenation of those two fields. You can add to you DataSource definition something like this:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "..."
}
},
schema: {
parse: function(response) {
$.each(response, function(idx, elem) {
elem.fullName = elem.firstName + " " + elem.lastName;
});
return response;
}
}
});
Then the options for the combobox are simply:
options: {
dataTextField: "fullName",
dataValueField: "userId",
...
}
See it in action here : http://jsfiddle.net/OnaBai/12hpLeux/1/

Kendo DataSource: How to set filters before fetch without sending two httprequests

Environment:
kendo version: 2013.1.319
dataSource:
productsDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: "http://www.mydomain.com/odata.svc/products",
dataType: "json",
contentType: "application/json"
}
schema: {
type: "json",
data: function(data){
return data.value;
},
total: function(data){
return data['odata.count'];
},
model: product
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true
});
Get data:
productsDataSource.filter([{ field: "Id", operator: "eq", value: 5 }]); //this will send an httprequest
productsDataSource.fetch(function (e) {
tempDataStorage = e.items;
//more logic to dealing with the data;
});
problems:
need to use the fetch method of the dataSource for data processing(widgets initialization, data binding...etc);
avoid sending two httprequests when setting filters before fetch;
the filter condition need to be changed at runtime.
productsDataSource._filter = { logic: 'and', filters: [
{ field: "Id", operator: "eq", value: 5 }]};
I've found this to work. Set the internal property to a full filter object. You can then call fetch afterwards. I've not yet found a way to change the page size without triggering a fetch however.
You can user filter in the DataSource configuration. This should issue only one request with the filtering conditions that you specify in the DataSource configuration.
Set the _filter field in the dataSource using productsDataSource._filter = [{ field: "Id", operator: "eq", value: 5 }]; and then manually initiate the request for remote data when you are ready using productsDataSource.read();
Even though it is an old question, it comes in google results. So even though I don't know if it is valid for kendo version: 2013.1.319, but there is currently a method
dataSource.query({
sort: { field: "ProductName", dir: "desc" },
page: 3,
pageSize: 20
});
This can set multiple options like sort, filter paging etc in a single call and returns a promise.
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-query
Bind event listener to datasource which initializes widget and then use filter method.
datasource.one('requestEnd', function(){
// initialize or/and bind widget
});
datasource.filter({ /*your filter*/ })

Resources