I have a page that provides the user 5 dropdown lists with Security Questions. They are set via a local DataSource object, that is basically 10 questions in an object. I want to bind all 5 dropdown lists to the same DataSource, and one Question is selected, remove it from the DataSource, so you can't select it for any of the next questions. Here is my code so far:
var questions =
[{
value: "Your first pet\'s name?"
},
{
value: "Your favorite teacher?"
},
{
value: "The city you were born in?"
},
{
value: "Your mother\'s maiden name?"
},
{
value: "The high school you attended?"
},
{
value: "First name of the first person you kissed?"
},
{
value: "What did you want to be when you grow up?"
},
{
value: "The brand of your first car?"
},
{
value: "Your favorite city?"
}];
var localDataSource = new kendo.data.DataSource({
data: questions
});
var dropdown = $('.dropdownlist');
dropdown.kendoDropDownList({
dataTextField: "value",
dataValueField: "value",
dataSource: localDataSource
});
And my HTML to render the fields:
<input class="dropdownlist w250px" name="questions[1][question]" />
Times 5 for every question.
To achieve the desired behavior, you can use the same data, but separate DataSource instances, otherwise you will not be able to filter them differently for each DropDownList.
Here is an example that you can use as a starting point and customize it further to match your scenario.
http://dojo.telerik.com/aJeHa
Used APIs include:
DropDownList change event
DropDownList value method
DropDownList dataSource field
DataSource filter method
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Related Kendo UI DropDownLists</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1118/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1118/styles/kendo.default.min.css">
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.3.1118/js/kendo.all.min.js"></script>
</head>
<body>
<p><input id="ddl1" name="ddl1" class="related-dropdown" /></p>
<p><input id="ddl2" name="ddl2" class="related-dropdown" /></p>
<p><input id="ddl3" name="ddl3" class="related-dropdown" /></p>
<script>
var data = [
{ id: 1, text: "question 1" },
{ id: 2, text: "question 2" },
{ id: 3, text: "question 3" }
];
for (var j = 1; j <= data.length; j++) {
$("#ddl" + j).kendoDropDownList({
dataSource: {
data: data,
filter: {}
},
dataTextField: "text",
dataValueField: "id",
optionLabel: "Select a question",
change: onChange
});
}
function onChange(e) {
if (e.sender.value()) {
var otherDropDowns = $("input.related-dropdown").not(e.sender.element);
for (var j = 0; j < otherDropDowns.length; j++) {
var ddl = $(otherDropDowns[j]).data("kendoDropDownList");
var newCondition = { field: "id", operator: "neq", value: e.sender.value() };
var currentFilter = ddl.dataSource.filter();
if (currentFilter && currentFilter.filters) {
currentFilter.filters.push(newCondition);
ddl.dataSource.filter(currentFilter);
} else {
ddl.dataSource.filter(newCondition);
}
}
} else {
// clear the freed question from the DropDownLists' filter criteria
}
}
</script>
</body>
</html>
Related
I'm trying to select child nodes on parent node clicked. I couldn't find any example for select api. Should i use checkbox instead?
<button id="btn">Highlight third row</button>
<div id="treeList"></div>
<script>
$("#treeList").kendoTreeList({
columns: [
{ field: "id" },
{ field: "name" },
{ field: "age" }
],
dataSource: [
{ id: 1, parentId: null, name: "Jane Doe", age: 22, expanded: true },
{ id: 2, parentId: 1, name: "John Doe", age: 24 },
{ id: 3, parentId: 1, name: "Jenny Doe", age: 3 }
],
selectable: "multiple row"
});
</script>
I am trying to do that if select "1" (top parent), select 2,3 (child nodes). Hope there is native solution for javascript implementation. Thanks in advice!
The selection state is maintained by TreeList in the data items row rendering<tr k-state-selected>, and that state is not reflected in the TreeList dataSource. Also, the data source is the only place the child relationship is discoverable. So there is a bit of back and forth to deal with selections and children.
Also TreeList does not have a select event like TreeView so out of the box you do not know which nodes were selected or deselected.
The change event fires when one action causes one or more rows (like shift-click can do) are caused to be selected or deselected. Within your change handler you can only know the current state of all selected rows using the select() method.
Thus, within change, you need to track prior selection state and current selection state to find which rows changed selection state, which would merit their children to be selected or deselected according to your requirement.
See this Dojo for an example. It's not perfect because in the change event you can only determine selected nodes and not know if a 'reselection' occurred (i.e. clicked on a selected row again). Anyway, the descent down the hierarchy of the TreeList is performed recursively and relies on the dataSource data item property .hasChildren and dataSource method .childNodes()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TreeList select (change)</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/kendo.all.min.js"></script></head>
<body>
<p><a target="_blank" href="https://docs.telerik.com/kendo-ui/api/javascript/ui/treelist">TreeList docs</a></p>
<div id="treeList"></div>
<script>
selected_uids = []; // track selected uids
autoselecting = false;
$("#treeList").kendoTreeList({
columns: [
{ field: "id" },
{ field: "name" },
{ field: "age" }
],
dataSource: [
{ id: 1, parentId: null, name: "Jane Doe", age: 22, expanded: false },
{ id: 2, parentId: 1, name: "John Doe", age: 24 },
{ id: 3, parentId: 1, name: "Jenny Doe", age: 3 },
{ id: 4, parentId: null, name: "Jane Mack", age: 22, expanded: false },
{ id: 5, parentId: 4, name: "John Mack", age: 24 },
{ id: 6, parentId: 4, name: "Jenny Mack", age: 3 }
],
selectable: "multiple row",
change: function(e) {
if (autoselecting) {
e.preventDefault();
return;
}
debugger;
autoselecting = true;
var selected_rows = this.select();
console.log ('desel',selected_rows, selected_uids);
// check for new deselections
for (var index = 0; index < selected_uids.length; index++) {
var selected_uid = selected_uids[index];
if (selected_uid) {
var row = $("tr[data-uid='" + selected_uid + "'].k-state-selected");
if (row.length == 0) {
// no such selected row for one that was previously tracked as selected
deselectChildren(this, selected_uid);
selected_uids[index] = null; // untrack
}
}
}
var selected_rows = this.select();
console.log ('sel',selected_rows,selected_uids);
// check for new selections
for (var index = 0; index < selected_rows.length; index++) {
var data = this.dataItem(selected_rows[index]);
console.log('data',data);
if (jQuery.inArray(data.uid, selected_uids) == -1) {
// new selection
selected_uids.push(data.uid);
selectChildren(this, data);
}
}
for (var i=0, j=0; i < selected_uids.length; i++) {
if (selected_uids[i] != null) {
if (i > j) {
selected_uids[j] = selected_uids[i];
}
j++;
}
}
selected_uids.length = j;
autoselecting = false;
},
});
function selectChildren(treeList, data) {
if (!data.hasChildren) return;
var children = treeList.dataSource.childNodes(data);
for (var index = 0; index < children.length; index++) {
var child = children[index];
if (jQuery.inArray(child.uid, selected_uids) == -1) {
selected_uids.push(child.uid);
treeList.select($("tr[data-uid='" + child.uid + "']"));
selectChildren(treeList,child);
}
}
}
function deselectChildren(treeList, uid) {
var data = treeList.dataSource.getByUid(uid);
if (!(data && data.hasChildren)) return;
var children = treeList.dataSource.childNodes(data);
for (var index = 0; index < children.length; index++) {
var child = children[index];
var row = $("tr[data-uid='" + child.uid + "'].k-state-selected");
if (row.length == 1) {
var at = selected_uids.indexOf(child.uid);
if (at >= 0) selected_uids[at] = null;
row.removeClass('k-state-selected');
}
deselectChildren(treeList,child.uid);
}
}
$("#treeList").data("kendoTreeList").select($("#treeList tbody>tr:nth(0)"));
</script>
</body>
</html>
How to get data from kendogrid2 and set it to kendogrid1?
I have the 2 kendogrid using checklist grid.
This is the jquery code:
$("#btnAddPortfolio").click(function () {
var grid2 = $("#portfolioGrid2").data("kendoGrid");
var dt = grid2.dataItem
var ds = new kendo.data.DataSource({
data: [{ "Portfolio": "Data of checklist selected item"}]
});
$("#portfolioGrid1").data("kendoGrid").setDataSource(ds);
$('#grid2_modal').modal('toggle');
});
How to get the value of selected item on #portofolioGrid2?
A simple way to achieve it:
$("#grid1").kendoGrid({
dataSource: {
data: [{ Name: "John Doe" }, { Name: "Jane Doe" },
{ Name: "Doe John" }, { Name: "Doe Jane" }]
},
columns: [{
template: '<input type="checkbox" />',
width: 40
}, {
field: "Name"
}]
});
$("#grid2").kendoGrid({
columns: [{
field: "Name"
}]
});
$("#transfer-items").on("click", function() {
let grid1 = $("#grid1").data("kendoGrid"),
grid2 = $("#grid2").data("kendoGrid"),
$checkboxes = grid1.tbody.find('input:checked').toArray();
if ($checkboxes.length) {
$checkboxes.forEach($chk => {
let item = grid1.dataItem($chk.closest("tr"));
grid2.dataSource.add(item);
});
}
else {
window.alert("No item has been selected.");
}
});
Demo
I'm trying to make grouped filters for KendoUI grid. I have to create a text field that filters the grid by name and a kendo numeric field that filters grid by Units in stock.
How could I make grouped filters?
I tried the following but it's not working - bad request 404 error:
$('body').bind('keyup mouseup', '#UnitsInStock', function () {
var value = $('#UnitsInStock').val();
var val = $('#ProductName').val();
if (value) {
grid.data("kendoGrid").dataSource.filter(myFilters(val, value));
} else {
grid.data("kendoGrid").dataSource.filter();
}
});
function myFilters(name='', price='') {
var filters = {
logic: "or",
filters: [
{ field: "ProductName", operator: "startswith", value: name},
{ field: "UnitsInStock", operator: "gte", value: price}
]
}
return filters;
}
<div id="grid"></div>
<script type="text/x-kendo-template" id="template">
<div class="toolbar">
<label for="category">Search by Product Name:</label>
<input type="search" id="ProductName" />
<input id="UnitsInStock" type="number" />
</div>
</script>
Since you have fields to be filtered on of multiple types, make sure the types are preserved when creating the filter object. for example, you could predefined your filter fields as such..
var filterFields = [{ field: "Units", type: "number" }, { field: "Name", type: "string" }]
and get the user input
var searchString = // user input
and a method to generate the filters similar to this
var getFilter = function (filterFields, searchString) {
var filterInt = function (value) {
if (/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
return true;
return false;
}
var filters = [];
var i = 0;
for (var i = 0; i < filterFields.length; i++) {
if (filterFields[i].type === "string") {
filters.push({
field: filterFields[i].field,
operator: "startswith",
value: searchString.toString()
});
}
if (filterFields[i].type === "number") {
if (filterInt(searchString)) {
filters.push({
field: filterFields[i].field,
operator: "gte",
value: parseInt(searchString)
});
}
}
}
return {
logic: "or",
filters: filters
};
}
finally, filter your grid
grid.data("kendoGrid").dataSource.filter(getFilter(filterFields, searchString))
also, to be certain that your endpoint works, use a tool such as postman and do a GET (http://............./Units?$filter=Id eq 1 and Name eq 'name').
I am using ui-grid to show a list of data and on display of the grid I am trying to expand some of the rows depending on the data.
I am trying to do this in the onRegisterApi event:
scope.GridOptions = {
data: properties,
columnDefs:
[
{ name: "Full Address", field: "FullAddress" },
{ name: "Suburb", field: "Suburb" },
{ name: "Property Type", field: "PropertyType" },
{ name: "Price", field: "Price", cellFilter: 'currency'},
{ name: "Status", field: "Status" },
{ name: "Sale Type", field: "SaleType" },
{ name: "Date Created", field: "CreateDate", cellFilter: "date:'dd/MM/yyyy HH:mma'"}
],
expandableRowTemplate: 'template.html',
expandableRowHeight: 200,
onRegisterApi: (gridApi) =>
{
gridApi.expandable.expandAllRows();
}
};
The problem is gridApi.expandable.expandAllRows() expands all of the grouped sections. I see there is a expandRow function, but I am not sure how to use it in place of the expandAllRows function. I really would like to expand the group that has the column Status set to a particular value. Can someone help me figure this out?
Here is a way to handle expanding of selective rows. I have created a Plunker link (http://plnkr.co/edit/CSaROQqKxYnkoxm2Tl6b?p=preview) where I am expanding all the even rows. In a similar way, you can iterate over the array and expand the required rows.
Include:
"$timeout" dependency in the controller
To expand first row:
$timeout(function() {
var rows = $scope.gridApi.grid.rows;
var entity = (rows.length && rows[0]) ? rows[0].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
});
May be I am late to answer.
But it may help others.
I have taken the same plunker example as SaiGiridhar posted, but modified
$timeout(function() {
var rows = $scope.gridApi.grid.rows;
for(var i=0; i < rows.length; i++){
if(i%2 === 0){
var entity = (rows.length && rows[i]) ? rows[i].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
}
}
});
to
$scope.$$postDigest(function() {
var rows = $scope.gridApi.grid.rows;
for(var i=0; i < rows.length; i++){
if(i%2 === 0){
var entity = (rows.length && rows[i]) ? rows[i].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
}
}
});
How can I populate a telerik drop-down list at page load?
I get the following error(at emphasized line below) when I try to populate dropdownlist:
Error: 'data(...)' is null or not an object
Here is how I try to populate the telerik ddl:
$(function(){
var values = [];
for (var i = 1; i < 10; i++) {
values.push({ Text: i, Value: i });
}
****$("#MyDdl").data("tDropDownList").dataBind(values);****
});
Tried it this way as well:
$(function(){
onDataBinding();
});
function onDataBinding(e) {
var MyDdl = $('#MyDdl').data('tDropDownList');
var values = [];
for (var i = 1; i < 10; i++) {
values.push({ Text: i, Value: i });
}
****MyDdl.dataBind(values);****
};
But get following undefined error at emphasized line above:
Error: 'undefined' is null or not an object
Note:
Adding a button and loading the ddl on button click event does populate telerik drop-down list.
Doing it this way works perfectly fine:
$(function(){
var values = [];
for (var i = 1; i < 10; i++) {
values.push({ Text: i, Value: i });
}
$("#MyDdl").data("tDropDownList").dataBind(values);
});
Any help is much appreciated.
you need to populate it in DropDownList's OnLoad event handler:
.ClientEvents(events => events.OnLoad("ddl_onLoad").OnChange("ddl_onChange")
handlers:
function ddl_onLoad(e) {
var ddl = $(this).data('tDropDownList');
ddl.dataBind([
{ Text: 'Product 1', Value: '1' },
{ Text: 'Product 2', Value: '2', Selected: true },
{ Text: 'Product 3', Value: '3' },
{ Text: 'Product 4', Value: '4' }
]);
}
function ddl_onChange(e) {
//var ddl = $(this).data('tDropDownList');
console.log(e.value);
}
Don't call the onDataBinding() function directly ..try to link it to the client side event of the control.
View:
<%= Html.Telerik().DropDownList()
.Name("DropDownList")
.ClientEvents(events => events
.OnDataBinding("onDropDownListDataBinding"))
%>
JS:
<script type="text/javascript">
function onDropDownListDataBinding(e) {
var MyDdl = $('#MyDdl').data('tDropDownList');
MyDdl .dataBind([
{ Text: "Product 1", Value: "1" },
{ Text: "Product 2", Value: "2", Selected: true },
{ Text: "Product 3", Value: "3" },
{ Text: "Product 4", Value: "4" },
{ Text: "Product 5", Value: "5" }
]);
};
</script>