UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

1,437 lines (1,157 loc) 74.5 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ({ /***/ 0: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(1026); /***/ }), /***/ 3: /***/ (function(module, exports) { module.exports = function() { throw new Error("define cannot be used indirect"); }; /***/ }), /***/ 1006: /***/ (function(module, exports) { module.exports = require("./kendo.core"); /***/ }), /***/ 1015: /***/ (function(module, exports) { module.exports = require("./kendo.data"); /***/ }), /***/ 1026: /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1006), __webpack_require__(1015) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); })(function(){ var __meta__ = { // jshint ignore:line id: "binder", name: "MVVM", category: "framework", description: "Model View ViewModel (MVVM) is a design pattern which helps developers separate the Model (the data) from the View (the UI).", depends: [ "core", "data" ] }; /*jshint eqnull: true */ (function ($, undefined) { var kendo = window.kendo, Observable = kendo.Observable, ObservableObject = kendo.data.ObservableObject, ObservableArray = kendo.data.ObservableArray, toString = {}.toString, binders = {}, Class = kendo.Class, proxy = $.proxy, VALUE = "value", SOURCE = "source", EVENTS = "events", CHECKED = "checked", CSS = "css", deleteExpando = true, FUNCTION = "function", CHANGE = "change"; (function() { var a = document.createElement("a"); try { delete a.test; } catch(e) { deleteExpando = false; } })(); var Binding = Observable.extend( { init: function(parents, path) { var that = this; Observable.fn.init.call(that); that.source = parents[0]; that.parents = parents; that.path = path; that.dependencies = {}; that.dependencies[path] = true; that.observable = that.source instanceof Observable; that._access = function(e) { that.dependencies[e.field] = true; }; if (that.observable) { that._change = function(e) { that.change(e); }; that.source.bind(CHANGE, that._change); } }, _parents: function() { var parents = this.parents; var value = this.get(); if (value && typeof value.parent == "function") { var parent = value.parent(); if ($.inArray(parent, parents) < 0) { parents = [parent].concat(parents); } } return parents; }, change: function(e) { var dependency, ch, field = e.field, that = this; if (that.path === "this") { that.trigger(CHANGE, e); } else { for (dependency in that.dependencies) { if (dependency.indexOf(field) === 0) { ch = dependency.charAt(field.length); if (!ch || ch === "." || ch === "[") { that.trigger(CHANGE, e); break; } } } } }, start: function(source) { source.bind("get", this._access); }, stop: function(source) { source.unbind("get", this._access); }, get: function() { var that = this, source = that.source, index = 0, path = that.path, result = source; if (!that.observable) { return result; } that.start(that.source); result = source.get(path); // Traverse the observable hierarchy if the binding is not resolved at the current level. while (result === undefined && source) { source = that.parents[++index]; if (source instanceof ObservableObject) { result = source.get(path); } } // second pass try to get the parent from the object hierarchy if (result === undefined) { source = that.source; //get the initial source while (result === undefined && source) { source = source.parent(); if (source instanceof ObservableObject) { result = source.get(path); } } } // If the result is a function - invoke it if (typeof result === "function") { index = path.lastIndexOf("."); // If the function is a member of a nested observable object make that nested observable the context (this) of the function if (index > 0) { source = source.get(path.substring(0, index)); } // Invoke the function that.start(source); if (source !== that.source) { result = result.call(source, that.source); } else { result = result.call(source); } that.stop(source); } // If the binding is resolved by a parent object if (source && source !== that.source) { that.currentSource = source; // save parent object // Listen for changes in the parent object source.unbind(CHANGE, that._change) .bind(CHANGE, that._change); } that.stop(that.source); return result; }, set: function(value) { var source = this.currentSource || this.source; var field = kendo.getter(this.path)(source); if (typeof field === "function") { if (source !== this.source) { field.call(source, this.source, value); } else { field.call(source, value); } } else { source.set(this.path, value); } }, destroy: function() { if (this.observable) { this.source.unbind(CHANGE, this._change); if(this.currentSource) { this.currentSource.unbind(CHANGE, this._change); } } this.unbind(); } }); var EventBinding = Binding.extend( { get: function() { var source = this.source, path = this.path, index = 0, handler; handler = source.get(path); while (!handler && source) { source = this.parents[++index]; if (source instanceof ObservableObject) { handler = source.get(path); } } return proxy(handler, source); } }); var TemplateBinding = Binding.extend( { init: function(source, path, template) { var that = this; Binding.fn.init.call(that, source, path); that.template = template; }, render: function(value) { var html; this.start(this.source); html = kendo.render(this.template, value); this.stop(this.source); return html; } }); var Binder = Class.extend({ init: function(element, bindings, options) { this.element = element; this.bindings = bindings; this.options = options; }, bind: function(binding, attribute) { var that = this; binding = attribute ? binding[attribute] : binding; binding.bind(CHANGE, function(e) { that.refresh(attribute || e); }); that.refresh(attribute); }, destroy: function() { } }); var TypedBinder = Binder.extend({ dataType: function() { var dataType = this.element.getAttribute("data-type") || this.element.type || "text"; return dataType.toLowerCase(); }, parsedValue: function() { return this._parseValue(this.element.value, this.dataType()); }, _parseValue: function (value, dataType){ if (dataType == "date") { value = kendo.parseDate(value, "yyyy-MM-dd"); } else if (dataType == "datetime-local") { value = kendo.parseDate(value, ["yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mm"] ); } else if (dataType == "number") { value = kendo.parseFloat(value); } else if (dataType == "boolean"){ value = value.toLowerCase(); if(kendo.parseFloat(value) !== null){ value = Boolean(kendo.parseFloat(value)); }else{ value = (value.toLowerCase() === "true"); } } return value; } }); binders.attr = Binder.extend({ refresh: function(key) { this.element.setAttribute(key, this.bindings.attr[key].get()); } }); binders.css = Binder.extend({ init: function(element, bindings, options) { Binder.fn.init.call(this, element, bindings, options); this.classes = {}; }, refresh: function(className) { var element = $(this.element), binding = this.bindings.css[className], hasClass = this.classes[className] = binding.get(); if(hasClass){ element.addClass(className); }else{ element.removeClass(className); } } }); binders.style = Binder.extend({ refresh: function(key) { this.element.style[key] = this.bindings.style[key].get() || ""; } }); binders.enabled = Binder.extend({ refresh: function() { if (this.bindings.enabled.get()) { this.element.removeAttribute("disabled"); } else { this.element.setAttribute("disabled", "disabled"); } } }); binders.readonly = Binder.extend({ refresh: function() { if (this.bindings.readonly.get()) { this.element.setAttribute("readonly", "readonly"); } else { this.element.removeAttribute("readonly"); } } }); binders.disabled = Binder.extend({ refresh: function() { if (this.bindings.disabled.get()) { this.element.setAttribute("disabled", "disabled"); } else { this.element.removeAttribute("disabled"); } } }); binders.events = Binder.extend({ init: function(element, bindings, options) { Binder.fn.init.call(this, element, bindings, options); this.handlers = {}; }, refresh: function(key) { var element = $(this.element), binding = this.bindings.events[key], handler = this.handlers[key]; if (handler) { element.off(key, handler); } handler = this.handlers[key] = binding.get(); element.on(key, binding.source, handler); }, destroy: function() { var element = $(this.element), handler; for (handler in this.handlers) { element.off(handler, this.handlers[handler]); } } }); binders.text = Binder.extend({ refresh: function() { var text = this.bindings.text.get(); var dataFormat = this.element.getAttribute("data-format") || ""; if (text == null) { text = ""; } $(this.element).text(kendo.toString(text, dataFormat)); } }); binders.visible = Binder.extend({ refresh: function() { if (this.bindings.visible.get()) { this.element.style.display = ""; } else { this.element.style.display = "none"; } } }); binders.invisible = Binder.extend({ refresh: function() { if (!this.bindings.invisible.get()) { this.element.style.display = ""; } else { this.element.style.display = "none"; } } }); binders.html = Binder.extend({ refresh: function() { this.element.innerHTML = this.bindings.html.get(); } }); binders.value = TypedBinder.extend({ init: function(element, bindings, options) { TypedBinder.fn.init.call(this, element, bindings, options); this._change = proxy(this.change, this); this.eventName = options.valueUpdate || CHANGE; $(this.element).on(this.eventName, this._change); this._initChange = false; }, change: function() { this._initChange = this.eventName != CHANGE; this.bindings[VALUE].set(this.parsedValue()); this._initChange = false; }, refresh: function() { if (!this._initChange) { var value = this.bindings[VALUE].get(); if (value == null) { value = ""; } var type = this.dataType(); if (type == "date") { value = kendo.toString(value, "yyyy-MM-dd"); } else if (type == "datetime-local") { value = kendo.toString(value, "yyyy-MM-ddTHH:mm:ss"); } this.element.value = value; } this._initChange = false; }, destroy: function() { $(this.element).off(this.eventName, this._change); } }); binders.source = Binder.extend({ init: function(element, bindings, options) { Binder.fn.init.call(this, element, bindings, options); var source = this.bindings.source.get(); if (source instanceof kendo.data.DataSource && options.autoBind !== false) { source.fetch(); } }, refresh: function(e) { var that = this, source = that.bindings.source.get(); if (source instanceof ObservableArray || source instanceof kendo.data.DataSource) { e = e || {}; if (e.action == "add") { that.add(e.index, e.items); } else if (e.action == "remove") { that.remove(e.index, e.items); } else if (e.action != "itemchange") { that.render(); } } else { that.render(); } }, container: function() { var element = this.element; if (element.nodeName.toLowerCase() == "table") { if (!element.tBodies[0]) { element.appendChild(document.createElement("tbody")); } element = element.tBodies[0]; } return element; }, template: function() { var options = this.options, template = options.template, nodeName = this.container().nodeName.toLowerCase(); if (!template) { if (nodeName == "select") { if (options.valueField || options.textField) { template = kendo.format('<option value="#:{0}#">#:{1}#</option>', options.valueField || options.textField, options.textField || options.valueField); } else { template = "<option>#:data#</option>"; } } else if (nodeName == "tbody") { template = "<tr><td>#:data#</td></tr>"; } else if (nodeName == "ul" || nodeName == "ol") { template = "<li>#:data#</li>"; } else { template = "#:data#"; } template = kendo.template(template); } return template; }, add: function(index, items) { var element = this.container(), parents, idx, length, child, clone = element.cloneNode(false), reference = element.children[index]; $(clone).html(kendo.render(this.template(), items)); if (clone.children.length) { parents = this.bindings.source._parents(); for (idx = 0, length = items.length; idx < length; idx++) { child = clone.children[0]; element.insertBefore(child, reference || null); bindElement(child, items[idx], this.options.roles, [items[idx]].concat(parents)); } } }, remove: function(index, items) { var idx, element = this.container(); for (idx = 0; idx < items.length; idx++) { var child = element.children[index]; unbindElementTree(child, true); if (child.parentNode == element) { element.removeChild(child); } } }, render: function() { var source = this.bindings.source.get(), parents, idx, length, element = this.container(), template = this.template(); if (source == null) { return; } if (source instanceof kendo.data.DataSource) { source = source.view(); } if (!(source instanceof ObservableArray) && toString.call(source) !== "[object Array]") { source = [source]; } if (this.bindings.template) { unbindElementChildren(element, true); $(element).html(this.bindings.template.render(source)); if (element.children.length) { parents = this.bindings.source._parents(); for (idx = 0, length = source.length; idx < length; idx++) { bindElement(element.children[idx], source[idx], this.options.roles, [source[idx]].concat(parents)); } } } else { $(element).html(kendo.render(template, source)); } } }); binders.input = { checked: TypedBinder.extend({ init: function(element, bindings, options) { TypedBinder.fn.init.call(this, element, bindings, options); this._change = proxy(this.change, this); $(this.element).change(this._change); }, change: function() { var element = this.element; var value = this.value(); if (element.type == "radio") { value = this.parsedValue(); this.bindings[CHECKED].set(value); } else if (element.type == "checkbox") { var source = this.bindings[CHECKED].get(); var index; if (source instanceof ObservableArray) { value = this.parsedValue(); if (value instanceof Date) { for(var i = 0; i < source.length; i++){ if(source[i] instanceof Date && +source[i] === +value){ index = i; break; } } }else{ index = source.indexOf(value); } if (index > -1) { source.splice(index, 1); } else { source.push(value); } } else { this.bindings[CHECKED].set(value); } } }, refresh: function() { var value = this.bindings[CHECKED].get(), source = value, type = this.dataType(), element = this.element; if (element.type == "checkbox") { if (source instanceof ObservableArray) { var index = -1; value = this.parsedValue(); if(value instanceof Date){ for(var i = 0; i < source.length; i++){ if(source[i] instanceof Date && +source[i] === +value){ index = i; break; } } }else{ index = source.indexOf(value); } element.checked = (index >= 0); }else{ element.checked = source; } } else if (element.type == "radio") { if (type == "date") { value = kendo.toString(value, "yyyy-MM-dd"); } else if (type == "datetime-local") { value = kendo.toString(value, "yyyy-MM-ddTHH:mm:ss"); } if (value !== null && typeof(value) !== "undefined" && element.value === value.toString()) { element.checked = true; } else { element.checked = false; } } }, value: function() { var element = this.element, value = element.value; if (element.type == "checkbox") { value = element.checked; } return value; }, destroy: function() { $(this.element).off(CHANGE, this._change); } }) }; binders.select = { source: binders.source.extend({ refresh: function(e) { var that = this, source = that.bindings.source.get(); if (source instanceof ObservableArray || source instanceof kendo.data.DataSource) { e = e || {}; if (e.action == "add") { that.add(e.index, e.items); } else if (e.action == "remove") { that.remove(e.index, e.items); } else if (e.action == "itemchange" || e.action === undefined) { that.render(); if(that.bindings.value){ if (that.bindings.value) { var val = retrievePrimitiveValues(that.bindings.value.get(), $(that.element).data("valueField")); if(val === null) { that.element.selectedIndex = -1; } else { that.element.value = val; } } } } } else { that.render(); } } }), value: TypedBinder.extend({ init: function(target, bindings, options) { TypedBinder.fn.init.call(this, target, bindings, options); this._change = proxy(this.change, this); $(this.element).change(this._change); }, parsedValue : function() { var dataType = this.dataType(); var values = []; var value, option, idx, length; for (idx = 0, length = this.element.options.length; idx < length; idx++) { option = this.element.options[idx]; if (option.selected) { value = option.attributes.value; if (value && value.specified) { value = option.value; } else { value = option.text; } values.push(this._parseValue(value, dataType)); } } return values; }, change: function() { var values = [], element = this.element, source, field = this.options.valueField || this.options.textField, valuePrimitive = this.options.valuePrimitive, option, valueIndex, value, idx, length; for (idx = 0, length = element.options.length; idx < length; idx++) { option = element.options[idx]; if (option.selected) { value = option.attributes.value; if (value && value.specified) { value = option.value; } else { value = option.text; } if (field) { values.push(value); } else { values.push(this._parseValue(value, this.dataType())); } } } if (field) { source = this.bindings.source.get(); if (source instanceof kendo.data.DataSource) { source = source.view(); } for (valueIndex = 0; valueIndex < values.length; valueIndex++) { for (idx = 0, length = source.length; idx < length; idx++) { var sourceValue = source[idx].get(field); var match = (String(sourceValue) === values[valueIndex]); if (match) { values[valueIndex] = source[idx]; break; } } } } value = this.bindings[VALUE].get(); if (value instanceof ObservableArray) { value.splice.apply(value, [0, value.length].concat(values)); } else if (!valuePrimitive && (value instanceof ObservableObject || value === null || value === undefined || !field)) { this.bindings[VALUE].set(values[0]); } else { this.bindings[VALUE].set(values[0].get(field)); } }, refresh: function() { var optionIndex, element = this.element, options = element.options, value = this.bindings[VALUE].get(), values = value, field = this.options.valueField || this.options.textField, found = false, type = this.dataType(), optionValue; if (!(values instanceof ObservableArray)) { values = new ObservableArray([value]); } element.selectedIndex = -1; for (var valueIndex = 0; valueIndex < values.length; valueIndex++) { value = values[valueIndex]; if (field && value instanceof ObservableObject) { value = value.get(field); } if (type == "date") { value = kendo.toString(values[valueIndex], "yyyy-MM-dd"); } else if (type == "datetime-local") { value = kendo.toString(values[valueIndex], "yyyy-MM-ddTHH:mm:ss"); } for (optionIndex = 0; optionIndex < options.length; optionIndex++) { optionValue = options[optionIndex].value; if (optionValue === "" && value !== "") { optionValue = options[optionIndex].text; } if (value != null && optionValue == value.toString()) { options[optionIndex].selected = true; found = true; } } } }, destroy: function() { $(this.element).off(CHANGE, this._change); } }) }; function dataSourceBinding(bindingName, fieldName, setter) { return Binder.extend({ init: function(widget, bindings, options) { var that = this; Binder.fn.init.call(that, widget.element[0], bindings, options); that.widget = widget; that._dataBinding = proxy(that.dataBinding, that); that._dataBound = proxy(that.dataBound, that); that._itemChange = proxy(that.itemChange, that); }, itemChange: function(e) { bindElement(e.item[0], e.data, this._ns(e.ns), [e.data].concat(this.bindings[bindingName]._parents())); }, dataBinding: function(e) { var idx, length, widget = this.widget, items = e.removedItems || widget.items(); for (idx = 0, length = items.length; idx < length; idx++) { unbindElementTree(items[idx], false); } }, _ns: function(ns) { ns = ns || kendo.ui; var all = [ kendo.ui, kendo.dataviz.ui, kendo.mobile.ui ]; all.splice($.inArray(ns, all), 1); all.unshift(ns); return kendo.rolesFromNamespaces(all); }, dataBound: function(e) { var idx, length, widget = this.widget, items = e.addedItems || widget.items(), dataSource = widget[fieldName], view, parents, hds = kendo.data.HierarchicalDataSource; if (hds && dataSource instanceof hds) { // suppress binding of HDS items, because calling view() on root // will return only root items, and widget.items() returns all items return; } if (items.length) { view = e.addedDataItems || dataSource.flatView(); parents = this.bindings[bindingName]._parents(); for (idx = 0, length = view.length; idx < length; idx++) { if (items[idx]) { bindElement(items[idx], view[idx], this._ns(e.ns), [view[idx]].concat(parents)); } } } }, refresh: function(e) { var that = this, source, widget = that.widget, select, multiselect, dropdowntree; e = e || {}; if (!e.action) { that.destroy(); widget.bind("dataBinding", that._dataBinding); widget.bind("dataBound", that._dataBound); widget.bind("itemChange", that._itemChange); source = that.bindings[bindingName].get(); if (widget[fieldName] instanceof kendo.data.DataSource && widget[fieldName] != source) { if (source instanceof kendo.data.DataSource) { widget[setter](source); } else if (source && source._dataSource) { widget[setter](source._dataSource); } else { select = kendo.ui.Select && widget instanceof kendo.ui.Select; multiselect = kendo.ui.MultiSelect && widget instanceof kendo.ui.MultiSelect; dropdowntree = kendo.ui.DropDownTree && widget instanceof kendo.ui.DropDownTree; if(!dropdowntree){ widget[fieldName].data(source); }else{ widget.treeview[fieldName].data(source); } if (that.bindings.value && (select || multiselect)) { widget.value(retrievePrimitiveValues(that.bindings.value.get(), widget.options.dataValueField)); } } } } }, destroy: function() { var widget = this.widget; widget.unbind("dataBinding", this._dataBinding); widget.unbind("dataBound", this._dataBound); widget.unbind("itemChange", this._itemChange); } }); } binders.widget = { events : Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this.handlers = {}; }, refresh: function(key) { var binding = this.bindings.events[key], handler = this.handlers[key]; if (handler) { this.widget.unbind(key, handler); } handler = binding.get(); this.handlers[key] = function(e) { e.data = binding.source; handler(e); if (e.data === binding.source) { delete e.data; } }; this.widget.bind(key, this.handlers[key]); }, destroy: function() { var handler; for (handler in this.handlers) { this.widget.unbind(handler, this.handlers[handler]); } } }), checked: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this._change = proxy(this.change, this); this.widget.bind(CHANGE, this._change); }, change: function() { this.bindings[CHECKED].set(this.value()); }, refresh: function() { this.widget.check(this.bindings[CHECKED].get() === true); }, value: function() { var element = this.element, value = element.value; if (value == "on" || value == "off" || this.element.type == "checkbox") { value = element.checked; } return value; }, destroy: function() { this.widget.unbind(CHANGE, this._change); } }), start: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this._change = proxy(this.change, this); this.widget = widget; this.widget.bind(CHANGE, this._change); }, change: function() { this.bindings.start.set(this.widget.range().start); }, refresh: function() { var that = this; var start = this.bindings.start.get(); var end = that.widget._range ? that.widget._range.end: null; this.widget.range({start: start, end: end}); }, destroy: function() { this.widget.unbind(CHANGE, this._change); } }), end: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this._change = proxy(this.change, this); this.widget = widget; this.widget.bind(CHANGE, this._change); }, change: function() { this.bindings.end.set(this.widget.range().end); }, refresh: function() { var that = this; var end = this.bindings.end.get(); var start = that.widget._range ? that.widget._range.start: null; this.widget.range({start: start, end: end}); }, destroy: function() { this.widget.unbind(CHANGE, this._change); } }), visible: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function() { var visible = this.bindings.visible.get(); this.widget.wrapper[0].style.display = visible ? "" : "none"; } }), invisible: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function() { var invisible = this.bindings.invisible.get(); this.widget.wrapper[0].style.display = invisible ? "none" : ""; } }), enabled: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function() { if (this.widget.enable) { this.widget.enable(this.bindings.enabled.get()); } } }), disabled: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function() { if (this.widget.enable) { this.widget.enable(!this.bindings.disabled.get()); } } }), source: dataSourceBinding("source", "dataSource", "setDataSource"), value: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this._change = $.proxy(this.change, this); this.widget.first(CHANGE, this._change); var value = this.bindings.value.get(); this._valueIsObservableObject = !options.valuePrimitive && (value == null || value instanceof ObservableObject); this._valueIsObservableArray = value instanceof ObservableArray; this._initChange = false; }, _source: function() { var source; if (this.widget.dataItem) { source = this.widget.dataItem(); if (source && source instanceof ObservableObject) { return [source]; } } if (this.bindings.source) { source = this.bindings.source.get(); } if (!source || source instanceof kendo.data.DataSource) { source = this.widget.dataSource.flatView(); } return source; }, change: function() { var value = this.widget.value(), field = this.options.dataValueField || this.options.dataTextField, isArray = toString.call(value) === "[object Array]", isObservableObject = this._valueIsObservableObject, valueIndex, valueLength, values = [], sourceItem, sourceValue, idx, length, source; this._initChange = true; if (field) { if (value === "" && (isObservableObject || this.options.valuePrimitive)) { value = null; } else { source = this._source(); if (isArray) { valueLength = value.length; values = value.slice(0); } for (idx = 0, length = source.length; idx < length; idx++) { sourceItem = source[idx]; sourceValue = sourceItem.get(field); if (isArray) { for (valueIndex = 0; valueIndex < valueLength; valueIndex++) { if (sourceValue == values[valueIndex]) { values[valueIndex] = sourceItem; break; } } } else if (sourceValue == value) { value = isObservableObject ? sourceItem : sourceValue; break; } } if (values[0]) { if (this._valueIsObservableArray) { value = values; } else if (isObservableObject || !field) { value = values[0]; } else { value = values[0].get(field); } } } } this.bindings.value.set(value); this._initChange = false; }, refresh: function() { if (!this._initChange) { var widget = this.widget; var options = widget.options; var textField = options.dataTextField; var valueField = options.dataValueField || textField; var value = this.bindings.value.get(); var text = options.text || ""; var idx = 0, length; var values = []; if (value === undefined) { value = null; } if (valueField) { if (value instanceof ObservableArray) { for (length = value.length; idx < length; idx++) { values[idx] = value[idx].get(valueField); } value = values; } else if (value instanceof ObservableObject) { text = value.get(textField); value = value.get(valueField); } } if (options.autoBind === false && !options.cascadeFrom && widget.listView && !widget.listView.bound()) { if (textField === valueField && !text) { text = value; } if (!text && (value || value === 0) && options.valuePrimitive) { widget.value(value); } else { widget._preselect(value, text); } } else { widget.value(value); } } this._initChange = false; }, destroy: function() { this.widget.unbind(CHANGE, this._change); } }), dropdowntree: { value: Binder.extend({ init: function(widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this._change = $.proxy(this.change, this); this.widget.first(CHANGE, this._change); this._initChange = false; }, change: function() { var that = this, oldValues = that.bindings[VALUE].get(), valuePrimitive = that.options.valuePrimitive, selectedNode = that.widget.treeview.select(), nonPrimitiveValues = that.widget._isMultipleSelection() ? that.widget._getAllChecked(): (that.widget.treeview.dataItem(selectedNode) || that.widget.value()), newValues = (valuePrimitive || that.widget.options.autoBind === false) ? that.widget.value() : nonPrimitiveValues; var field = this.options.dataValueField || this.options.dataTextField; newValues = newValues.slice ? newValues.slice(0): newValues; that._initChange = true; if (oldValues instanceof ObservableArray) { var remove = []; var newLength = newValues.length; var i = 0, j = 0; var old = oldValues[i]; var same = false;