Hi,
I have a TreeView for a filter on a dashboard, and it's not processing the click on the checkbox the second time. I've attached a screen shot with more details.
I'm not sure what I have wrong.
Creating the TreeView:
How it's used in my program, including several variations on binding.
I have a TreeView for a filter on a dashboard, and it's not processing the click on the checkbox the second time. I've attached a screen shot with more details.
I'm not sure what I have wrong.
Creating the TreeView:
/* Topics illustrated in this file:* How to define a custom widget* How to configure options from base* How to define and access custom options* How to capture scope* How to manipulate the DOM of "this"* How to expose custom methods* How to expose an event handler delegate*/define([ 'jquery', 'underscore', 'utils/helpers', 'text!views/schoolFilterItem.html', 'kendoui/kendo.treeview.min',], function ($, _, Helpers, schoolFilterItemTemplate) { var schoolData; // This defines a Kendo widget object var TreeView = kendo.ui.TreeView.extend({ init: function (element, options) { // Assigning this to another variable name captures the context of init, which is "this TreeView" var me = this; options.dataSource = { transport: { read: function (options) { $.getJSON(Helpers.toServicesUrl("/GetfltSchoolByDistrict"), { // If you tried to use "this" in here, it would refer to the dataSource instead of the TreeView userName: me.options.userName, districtId: me.options.districtId, schoolCodes: me.options.schoolCodes }, function (data) { options.success([]); schoolData = data.GetfltSchoolByDistrictResult.RootResults; schoolData = [ { text: "Schools", expanded: false, items: _(schoolData) .chain() .groupBy("SchoolTypeName") .map(function (groupItems, groupKey) { return { SchoolTypeName: groupKey, items: groupItems, expanded: false } }) .value() } ]; me.dataSource.data(schoolData); }); } }, schema: { model: { children: "items" } } }; options.dataBound = function (e) { me.element.find("input:checkbox:first").prop("disabled", true); me.element.find("input:checkbox").on("change", function (e) { var parentItems = $(e.target).parents(".k-item"); var node = parentItems.eq(0); var parentNode = parentItems.eq(1); // Toggle children to match parent node.find("input:checkbox").prop("checked", e.target.checked); // Update parent's state var parentCheckBox = parentNode.find("input:checkbox:first"); if (!parentCheckBox.prop("disabled")) { var hasChecked = parentNode.find(".k-group input:checked").length > 0; var hasUnchecked = parentNode.find(".k-group input:not(:checked)").length > 0; parentCheckBox.prop("checked", hasChecked); parentCheckBox.prop("indeterminate", hasChecked && hasUnchecked); } // The rest is unchecking other SchoolTypes if a different SchoolType is checked. If "this" is unchecked, no further action required. if (!e.target.checked) return; var dataItem = me.dataItem(node); if (!dataItem.SchoolTypeName) { e.target.checked = false; return; } me.element.find("input:checked").each(function () { var eachDataItem = me.dataItem($(this).closest(".k-item")) if (eachDataItem.SchoolTypeName !== dataItem.SchoolTypeName) { this.checked = false; this.indeterminate = false; //lah testing adding something here. // me.schoolTypeChanged(e); me.onSchoolChange(e); } //gmo when school names don't match if (eachDataItem.SchoolName !== dataItem.SchoolName) { this.checked = false; me.onSchoolChange(e); } }); }); } kendo.ui.TreeView.fn.init.call(this, element, options); }, options: { // This is what determines the name of the custom method, e.g. .kendoSchoolFilterTreeView name: "TreeViewSchoolFilterSingle", // Declare new options with default values. Options must be declared here in order to be accepted and passed through to init(). userName: "", districtId: 0, schoolCodes: function () { return "" }, // Anything else you pass in options will get passed to the base widget dataTextField: ["text", "SchoolTypeName", "SchoolName"], checkboxes: true }, getSelectedSchoolType: function () { var me = this; return _(this.element.find("input:checked").closest(".k-item")) .chain() // .map(function (item) { return ktvSchoolFilter.dataItem(item).SchoolType; }) .map(function (item) { return me.dataItem(item).SchoolType; }) .filter(function (item) { return item; }) .value()[0]; }, // This is how to get the selected school from the radio group getSelectedSchoolCodes: function () { var me = this; return _(this.element.find("input:checked").closest(".k-item")) .chain() // .map(function (item) { return ktvSchoolFilter.dataItem(item).SchoolCode; }) .map(function (item) { return me.dataItem(item).SchoolCode; }) .filter(function (item) { return item; }) .value() .join(","); }, onSchoolChange: function (e) { return; }, schoolTypeChanged: function (e) { return; } }); // This is what registers the custom widget and adds the kendo* method to the jQuery object kendo.ui.plugin(TreeView);});How it's used in my program, including several variations on binding.
ktvSchoolFilter = $("#schoolFilterTree").kendoTreeViewSchoolFilterSingle({ userName: WSIPCContext.UserName, districtId: WSIPCContext.DistrictId, schoolCodes: WSIPCContext.SchoolCodes, onSchoolChange: schoolCodeChanged, change: schoolCodeChanged, schoolTypeChanged: schoolCodeChanged, checkbox: { onClick: schoolCodeChanged } }).data("kendoTreeViewSchoolFilterSingle");//This code allows the grade level and risk categories to change when a checkbox //is selected, not just the label. ktvSchoolFilter.dataSource.bind("change", schoolCodeChanged); ktvSchoolFilter.dataSource.bind("select", schoolCodeChanged); ktvSchoolFilter.dataSource.bind("selecting", schoolCodeChanged); ktvSchoolFilter.dataSource.bind("navigate", schoolCodeChanged); ktvSchoolFilter.bind("change", schoolCodeChanged); ktvSchoolFilter.bind("select", schoolCodeChanged); ktvSchoolFilter.bind("selecting", schoolCodeChanged); ktvSchoolFilter.bind("navigate", schoolCodeChanged