@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
JavaScript
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;