KendoDropDownList - cascading data from one drop down to another - kendo-ui

I am making a game, and have a specific requirement where players pick a playable character race, and then I want a second drop down list to show the list of available genders for that race. I thought this would be easy to do using the Cascade property of the kendo.ui.DropDownListOptions... like this.
var racesOptions = {
index: -1,
valuePrimitive: true,
dataTextField: "Name",
dataValueField: "Name",
dataSource: {
transport: {
read: {
dataType: 'json',
url: '/api/races/list',
type: 'GET'
}
}
}
};
var genderOptions = {
index: -1,
valuePrimitive: true,
cascadeFrom: 'race',
cascadeFromField: 'Genders'
};
The shape of data coming in from /api/races/list looks like this;
[{
"Name": "race1",
// ... other data ... //
"Genders": [ "Male", "Female", "Other" ]
}, {
"Name": "race2",
// ... other data ... //
"Genders" : ["Female"]
}, {
"Name": "race3",
// ... other data ... //
"Genders": ["Male"]
}]
I thought this was going to be a no-brainer. The second drop down cascades from the first; When the first has a value, I figured the second would get the CascadeFromFieldvalue. But that's not happening... In fact, the only way I've been able to accomplish this is with the following code in the #race widget's change event.
change: function (e) {
// the specific race entity selected
var entity = e.sender.dataItem().toJSON();
// set the selected race's genders
var genders = $('#genders').data('kendoDropDownList');
genders.destroy();
genders = $('#genders').kendoDropDownList({
index: -1,
valuePrimitive: true,
dataSource: {
data: entity.Genders
}
}).data('kendoDropDownList');
genders.select(-1);
genders.trigger('change');
}
That change event does work, but it's messy and kind of obtuse. Is there another way I can get the Cascading to work as I'm expecting?

The value for cascadeFromField: needs to point to the parent ID field. In your case the ID field in the Races datasource.
Here's a small example that should help.
<h4>Race:</h4>
<input id="race" />
<h4>Gender:</h4>
<input id="gender" />
<script>
$("#race").kendoDropDownList({
optionLabel: "Select race...",
dataTextField: "raceName",
dataValueField: "raceID",
dataSource: [
{ raceName: "Race1", raceID: 1 },
{ raceName: "Race2", raceID: 2 },
{ raceName: "Race3", raceID: 3 }
]
});
$("#gender").kendoDropDownList({
optionLabel: "Select gender...",
cascadeFrom: "race",
cascadeFromField: "raceID",
dataTextField: "genderName",
dataValueField: "genderID",
dataSource: [
{ genderName: "Male", genderID: 1, raceID: 1 },
{ genderName: "Female", genderID: 2, raceID: 1 },
{ genderName: "Other", genderID: 3, raceID: 1 },
{ genderName: "Female", genderID: 4, raceID: 2 },
{ genderName: "Male", genderID: 4, raceID: 3 }
]
});
</script>
You can check out this demo using the above code.

Related

Kendo Grid doesn't show any data despite having data within DataSource

So, I'm trying to make a readyonly grid with kendo that shows data, but whatever I do, the data does not get shown.
The grid looks like this
And here's the code:
$("#Materials")
.kendoGrid({
dataSource: {
data: [],
schema: {
model: {
id: "ID",
fields: {
ID: { type: "number", editable: false },
Code: { type: "string", editable: false },
Name: { type: "string", editable: false },
ExtDeviceCode: { type: "string", editable: false , nullable: true },
BaseUomLOVString: { type: "string", editable: false }
}
}
},
pageSize: 20
},
filterable: {
extra: true
},
pageable: true,
columns: [
{ field: "Code", title:"Code"},
{ field: "Name", title: "Name"},
{ field: "ExtDeviceCode", title:"External device code"},
{ field: "BaseUomLOVString", title: "UnitsOfMeasure" }
],
editable: false
});
This makes an empty grid with no data, which I later on fill with an Ajax call. As you can see from above picture, the grid contains the data but does not display it. The data inside the dataSource looks like this. or as Json:
[{
"ID": 21150,
"Code": "3",
"ExtDeviceCode": null,
"Name": "Avio benzin",
"BaseUomLOVString": "Kilogram"
}, {
"ID": 21400,
"Code": "5003",
"ExtDeviceCode": null,
"Name": "Bencin 95",
"BaseUomLOVString": "Litre"
}]
EDIT 1: I'm filling the data with an Ajax call like this:
$.ajax({
url: '#SimpleUrlHelper.UrlObjectToRoot(Url)/FuelPointMaterialTankMask/LookupMaterials',
data: {
//Send list of IDs
'materialIDs': materialList
},
type: "POST",
success: function (response) {
var tmp = [];
if (typeof response !== "undefined" &&
response !== null) {
response.forEach(function(item) {
tmp.push(item);
});
}
grid = $("#Materials").data("kendoGrid");
originalMaterialDataSource = grid.dataSource;
originalMaterialDataSource.data(tmp);
originalMaterialDataSource._destroyed = [];
originalMaterialDataSource.pageSize(pageSize);
originalMaterialDataSource.page(1);
originalMaterialDataSource._total = tmp.length;
grid.pager.refresh();
}
});
You can set your data in your dataSource after your ajax call.
var dataArray = [{
"ID": 21150,
"Code": "3",
"ExtDeviceCode": null,
"Name": "Avio benzin",
"BaseUomLOVString": "Kilogram"
}, {
"ID": 21400,
"Code": "5003",
"ExtDeviceCode": null,
"Name": "Bencin 95",
"BaseUomLOVString": "Litre"
}];
Use .data() to set:
$("#Materials").data('kendoGrid').dataSource.data(dataArray );
Okay so after days of trying to figure out what was wrong I finally found the answer.
Somewhere along the lines I had:
var grids = $('.k-grid');
for (var i = 0; i < grids.length; i++) {
....
grid.dataSource.filter().filters[0] = {
logic: "or",
filters: filters
}
....
So basically I was putting filters on all grids without excluding this one, which was just a bug from my part.

Multiple sort on Kendo Grid columns / DataSource - set sorting dynamically

What I'm trying to accomplish is to apply an "automatic" secondary column sort when a user sorts a column in a kendo grid.
So in this JS fiddle example, if a user sorts by "Value", it'll also sort by "Name". Note that the 0s are sorted together, but the names aren't alphabetical. I'd like them to be alphabetical (the secondary sort).
Here's an attempt at overriding the datasource sorting to accomplish this. I'm taking the user's original sort and the adding an additional sort on "SortedName". Based on the sorting array that's logged, it seems to be close but is still not working.
Any other ideas on how to accomplish this?
Note: I don't want to allow users to sort by multiple columns. The real world example I'm using this for can have up to 50+ columns (unfortunately), so multiple sort can get confusing / unintuitive. And I'd like it to be done behind the scenes without extra user interaction.
Example code for overriding kendo datasource sort():
dataSource.originalSort = dataSource.sort;
dataSource.sort = function () {
// take the user's sort and apply sorting on an additional column
// the sort array should look like this:
[
{ field: "Value", dir: "asc" }, // this is what the user sorted by
{ field: "SortedName", dir: "asc" }, // and I'm adding this
]
return dataSource.originalSort.apply(this, arguments);
}
Please try with the below code snippet.
<div id="grid">
</div>
<script>
var dataSource = new kendo.data.DataSource({
data: [
{ Name: "Lisa", Value: 1 },
{ Name: "Dan", Value: 12 },
{ Name: "Ken", Value: 5 },
{ Name: "Arthur", Value: 15 },
{ Name: "Bob", Value: 0 },
{ Name: "Sally", Value: 0 },
{ Name: "Alexis", Value: 0 },
{ Name: "Cody", Value: 0 },
{ Name: "Steve", Value: 0 },
{ Name: "Andrew", Value: 0 },
{ Name: "Duke", Value: 0 }
],
schema: {
model: {
fields: {
Name: { type: "string" },
Value: { type: "number" }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
dataBound: function (e) {
var isSortedByName = false;
var grid = $("#grid").data("kendoGrid");
var ds = grid.dataSource;
var sort = ds.sort();
if (sort) {
for (var i = 0; i < sort.length; i++) {
if (sort[i].field == "Name") {
isSortedByName = true;
}
}
if (isSortedByName == false) {
sort.push({ field: "Name", dir: "asc" });
ds.sort(sort);
}
}
},
columns: [
{ field: "Name" },
{ field: "Value" }
],
sortable: true
});
</script>

Filter JSON datasource with Kendo UI

I need to populate Kendo drop-down box automatically from the following JSON:
var products=
[
{
id: 1,
title: "Item-1",
active: true
},
{
id: 2,
title: "Item-2",
active: false
}
];
So I use the following code to do this, which works fine:
$("#productList").kendoDropDownList({
dataSource: products,
dataTextField: "title",
dataValueField: "id"
});
The problem is, I want to see only items for which 'active' is true.
How to implement that with Kendo?
Sample Jsfiddle
For Filter, can only be filter on dataSoruce that why creating kendo.data.DataSource and apply filter in filter section.
filter:{fieled:"active",operator:"eq",value:true}
HTML
<div>
<input id="productList" style="width:250px"/>
</div>
Javascript
var products=
[
{
id: 1,
title: "Item-1",
active: true
},
{
id: 2,
title: "Item-2",
active: undefined
},
{
id:3,
title:"Item-3",
active:false
},
{
id:3,
title:"Item-4",
active:undefined
}
];
var dataSource=new kendo.data.DataSource({
data:products,
filter:{
logic:'or',
filters:[
{field:"active",operator:"eq",value:true},
{field:"active",operator:"eq",value:undefined}
]}
});
$("#productList").kendoDropDownList({
dataSource: dataSource,
dataTextField: "title",
dataValueField: "id"
});

Set the selected text or value for a KendoDropDownList

I'm using Durandal and Kendo UI. My current problem is the edit popup event on my grid. I cannot seem to set the selected value on my dropdown.
I can debug and inspect, and I indeed do see the correct value of e.model.InstrumentName nicely populated.
How can I set the value/text of those dropdowns in edit mode ?
Here's my grid init:
positGrid = $("#positGrid").kendoGrid({
dataSource: datasource,
columnMenu: false,
{
field: "portfolioName", title: "Portfolio Name",
editor: portfolioDropDownEditor, template: "#=portfolioName#"
},
{
field: "InstrumentName",
width: "220px",
editor: instrumentsDropDownEditor, template: "#=InstrumentName#",
},
edit: function (e) {
var instrDropDown = $('#InstrumentName').data("kendoDropDownList");
var portfDropDown = $('#portfolioName').data("kendoDropDownList");
instrDropDown.list.width(350); // let's widen the INSTRUMENT dropdown list
if (!e.model.isNew()) { // set to current valuet
//instrDropDown.text(e.model.InstrumentName); // not working...
instrDropDown.select(1);
//portfDropDown.text();
}
},
filterable: true,
sortable: true,
pageable: true,
editable: "popup",
});
Here's my Editor Template for the dropdown:
function instrumentsDropDownEditor(container, options) {
// INIT INSTRUMENT DROPDOWN !
var dropDown = $('<input id="InstrumentName" name="InstrumentName">');
dropDown.appendTo(container);
dropDown.kendoDropDownList({
dataTextField: "name",
dataValueField: "id",
dataSource: {
type: "json",
transport: {
read: "/api/breeze/GetInstruments"
},
},
pageSize: 6,
select: onSelect,
change: function () { },
optionLabel: "Choose an instrument"
}).appendTo(container);
}
thanks a lot
Bob
Your editor configuration is bit unlucky for grid, anyway i have updated my ans on provided code avoiding manual selections:
Assumptions: Instrument dropdown editor only (leaving other fields as strings), Dummy data for grid
<div id="positGrid"></div>
<script>
$(document).ready(function () {
$("#positGrid").kendoGrid({
dataSource: {
data: [
{ PositionId: 1, Portfolio: "Jane Doe", Instrument: { IID: 3, IName: "Auth2" }, NumOfContracts: 30, BuySell: "sfsf" },
{ PositionId: 2, Portfolio: "John Doe", Instrument: { IID: 2, IName: "Auth1" }, NumOfContracts: 33, BuySell: "sfsf" }
],
schema: {
model: {
id: "PositionId",
fields: {
"PositionId": { type: "number" },
Portfolio: { validation: { required: true } },
Instrument: { validation: { required: true } },
NumOfContracts: { type: "number", validation: { required: true, min: 1 } },
BuySell: { validation: { required: true } }
}
}
}
},
toolbar: [
{ name: "create", text: "Add Position" }
],
columns: [
{ field: "PositionId" },
{ field: "Portfolio" },
{ field: "Instrument", width: "220px",
editor: instrumentsDropDownEditor, template: "#=Instrument.IName#" },
{ field: "NumOfContracts" },
{ field: "BuySell" },
{ command: [ "edit", "destroy" ]
},
],
edit: function (e) {
var instrDropDown = $('#InstrumentName').data("kendoDropDownList");
instrDropDown.list.width(400); // let's widen the INSTRUMENT dropdown list
},
//sortable: true,
editable: "popup",
});
});
function instrumentsDropDownEditor(container, options) {
$('<input id="InstrumentName" required data-text-field="IName" data-value-field="IID" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataSource: {
type: "json",
transport: {
read: "../Home/GetMl"
}
},
optionLabel:"Choose an instrument"
});
}
</script>
Action fetching json for dropddown in Home controller:
public JsonResult GetMl()
{
return Json(new[] { new { IName = "Auth", IID = 1 }, new { IName = "Auth1", IID = 2 }, new { IName = "Auth2", IID = 3 } },
JsonRequestBehavior.AllowGet);
}

Kendo Dropdownlist: Grouping data causes undefined

Im trying to use an existing data file to populate a kendo drop down list.The field im interested in populating my drop down list is the "make" field which basically displays a list or car manufacturers.
this works fine...
var makes = $("#makes").kendoDropDownList({
optionLabel: "Select make...",
dataTextField: "make",
dataValueField: "make",
dataSource: {
transport: {
read: {
dataType: "jsonp",
url: "data.php",
}
},
schema: {
data: "data"
}
}
}).data("kendoDropDownList");
However there are many makes repeated as its a list of car specs so i want to be able to group the data by make to hide the repetitions. As soon as i add this line the dropdowlist options become undefined.
group: { field: "make" }
Code after i added group
var makes = $("#makes").kendoDropDownList({
optionLabel: "Select make...",
dataTextField: "make",
dataValueField: "make",
dataSource: {
transport: {
read: {
dataType: "jsonp",
url: "data.php",
}
},
schema: {
data: "data"
},
group: { field: "make" }
}
}).data("kendoDropDownList");
Any idea's guys
thanks
UPDATE!!
Using this below i can now group the data but the cascading isnt working
var data = [
{"make": "Audi", "model": "A1"},
{"make": "Audi", "model": "A2"},
{"make": "Audi", "model": "A3"},
{"make": "Audi", "model": "A4"},
{"make": "Saab", "model": "S500"}
];
$(document).ready(function () {
var makesDatasource = new kendo.data.DataSource({
data: data,
group: { field: "make", value: "make"}
});
var makes = $("#makes").kendoDropDownList({
optionLabel: "Select make...",
dataTextField: "value",
dataValueField: "value",
dataSource: makesDatasource
}).data("kendoDropDownList");
var modelsDatasource = new kendo.data.DataSource({
data: data,
group: { field: "model", value: "model"}
});
var models = $("#models").kendoDropDownList({
autoBind: false,
cascadeFrom: "makes",
optionLabel: "Select model...",
dataTextField: "value",
dataValueField: "value",
dataSource: modelsDatasource
}).data("kendoDropDownList");
});
Grouped data looks like:
[
{ field: "make", value: "Make 1", items: [...]},
...
]
so try changing to:
dataTextField: "value",
dataValueField: "value",

Resources