1254 lines
54 KiB
JavaScript
1254 lines
54 KiB
JavaScript
/**
|
|
* Kendo UI v2016.1.226 (http://www.telerik.com/kendo-ui)
|
|
* Copyright 2016 Telerik AD. All rights reserved.
|
|
*
|
|
* Kendo UI commercial licenses may be obtained at
|
|
* http://www.telerik.com/purchase/license-agreement/kendo-ui-complete
|
|
* If you do not own a commercial license, this file shall be governed by the trial license terms.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
(function (f, define) {
|
|
define('kendo.angular', ['kendo.core'], f);
|
|
}(function () {
|
|
var __meta__ = {
|
|
id: 'angular',
|
|
name: 'AngularJS Directives',
|
|
category: 'framework',
|
|
description: 'Adds Kendo UI for AngularJS directives',
|
|
depends: ['core'],
|
|
defer: true
|
|
};
|
|
(function ($, angular, undefined) {
|
|
'use strict';
|
|
if (!angular || !angular.injector) {
|
|
return;
|
|
}
|
|
var module = angular.module('kendo.directives', []), $injector = angular.injector(['ng']), $parse = $injector.get('$parse'), $timeout = $injector.get('$timeout'), $defaultCompile, $log = $injector.get('$log');
|
|
function withoutTimeout(f) {
|
|
var save = $timeout;
|
|
try {
|
|
$timeout = function (f) {
|
|
return f();
|
|
};
|
|
return f();
|
|
} finally {
|
|
$timeout = save;
|
|
}
|
|
}
|
|
var OPTIONS_NOW;
|
|
var createDataSource = function () {
|
|
var types = {
|
|
TreeList: 'TreeListDataSource',
|
|
TreeView: 'HierarchicalDataSource',
|
|
Scheduler: 'SchedulerDataSource',
|
|
PanelBar: '$PLAIN',
|
|
Menu: '$PLAIN',
|
|
ContextMenu: '$PLAIN'
|
|
};
|
|
var toDataSource = function (dataSource, type) {
|
|
if (type == '$PLAIN') {
|
|
return dataSource;
|
|
}
|
|
return kendo.data[type].create(dataSource);
|
|
};
|
|
return function (scope, element, role, source) {
|
|
var type = types[role] || 'DataSource';
|
|
var current = scope.$eval(source);
|
|
var ds = toDataSource(current, type);
|
|
scope.$watch(source, function (mew) {
|
|
var widget = kendoWidgetInstance(element);
|
|
if (widget && typeof widget.setDataSource == 'function') {
|
|
if (mew !== current) {
|
|
var ds = toDataSource(mew, type);
|
|
widget.setDataSource(ds);
|
|
current = mew;
|
|
}
|
|
}
|
|
});
|
|
return ds;
|
|
};
|
|
}();
|
|
var ignoredAttributes = {
|
|
kDataSource: true,
|
|
kOptions: true,
|
|
kRebind: true,
|
|
kNgModel: true,
|
|
kNgDelay: true
|
|
};
|
|
var ignoredOwnProperties = {
|
|
name: true,
|
|
title: true,
|
|
style: true
|
|
};
|
|
function createWidget(scope, element, attrs, widget, origAttr, controllers) {
|
|
if (!(element instanceof jQuery)) {
|
|
throw new Error('The Kendo UI directives require jQuery to be available before AngularJS. Please include jquery before angular in the document.');
|
|
}
|
|
var kNgDelay = attrs.kNgDelay, delayValue = scope.$eval(kNgDelay);
|
|
controllers = controllers || [];
|
|
var ngModel = controllers[0], ngForm = controllers[1];
|
|
var ctor = $(element)[widget];
|
|
if (!ctor) {
|
|
window.console.error('Could not find: ' + widget);
|
|
return null;
|
|
}
|
|
var parsed = parseOptions(scope, element, attrs, widget, ctor);
|
|
var options = parsed.options;
|
|
if (parsed.unresolved.length) {
|
|
var promises = [];
|
|
for (var i = 0, len = parsed.unresolved.length; i < len; i++) {
|
|
var unresolved = parsed.unresolved[i];
|
|
var promise = $.Deferred(function (d) {
|
|
var unwatch = scope.$watch(unresolved.path, function (newValue) {
|
|
if (newValue !== undefined) {
|
|
unwatch();
|
|
d.resolve();
|
|
}
|
|
});
|
|
}).promise();
|
|
promises.push(promise);
|
|
}
|
|
$.when.apply(null, promises).then(createIt);
|
|
return;
|
|
}
|
|
if (kNgDelay && !delayValue) {
|
|
var root = scope.$root || scope;
|
|
var register = function () {
|
|
var unregister = scope.$watch(kNgDelay, function (newValue) {
|
|
if (newValue !== undefined) {
|
|
unregister();
|
|
element.removeAttr(attrs.$attr.kNgDelay);
|
|
kNgDelay = null;
|
|
$timeout(createIt);
|
|
}
|
|
});
|
|
};
|
|
if (/^\$(digest|apply)$/.test(root.$$phase)) {
|
|
register();
|
|
} else {
|
|
scope.$apply(register);
|
|
}
|
|
return;
|
|
} else {
|
|
return createIt();
|
|
}
|
|
function createIt() {
|
|
var originalElement;
|
|
if (attrs.kRebind) {
|
|
originalElement = $($(element)[0].cloneNode(true));
|
|
}
|
|
options = parseOptions(scope, element, attrs, widget, ctor).options;
|
|
if (element.is('select')) {
|
|
(function (options) {
|
|
if (options.length > 0) {
|
|
var first = $(options[0]);
|
|
if (!/\S/.test(first.text()) && /^\?/.test(first.val())) {
|
|
first.remove();
|
|
}
|
|
}
|
|
}(element[0].options));
|
|
}
|
|
var object = ctor.call(element, OPTIONS_NOW = options).data(widget);
|
|
exposeWidget(object, scope, attrs, widget, origAttr);
|
|
scope.$emit('kendoWidgetCreated', object);
|
|
var destroyRegister = destroyWidgetOnScopeDestroy(scope, object);
|
|
if (attrs.kRebind) {
|
|
setupRebind(object, scope, element, originalElement, attrs.kRebind, destroyRegister, attrs);
|
|
}
|
|
if (attrs.kNgDisabled) {
|
|
var kNgDisabled = attrs.kNgDisabled;
|
|
var isDisabled = scope.$eval(kNgDisabled);
|
|
if (isDisabled) {
|
|
object.enable(!isDisabled);
|
|
}
|
|
bindToKNgDisabled(object, scope, element, kNgDisabled);
|
|
}
|
|
if (attrs.kNgReadonly) {
|
|
var kNgReadonly = attrs.kNgReadonly;
|
|
var isReadonly = scope.$eval(kNgReadonly);
|
|
if (isReadonly) {
|
|
object.readonly(isReadonly);
|
|
}
|
|
bindToKNgReadonly(object, scope, element, kNgReadonly);
|
|
}
|
|
if (attrs.kNgModel) {
|
|
bindToKNgModel(object, scope, attrs.kNgModel);
|
|
}
|
|
if (ngModel) {
|
|
bindToNgModel(object, scope, element, ngModel, ngForm);
|
|
}
|
|
if (object) {
|
|
propagateClassToWidgetWrapper(object, element);
|
|
}
|
|
return object;
|
|
}
|
|
}
|
|
function parseOptions(scope, element, attrs, widget, ctor) {
|
|
var role = widget.replace(/^kendo/, '');
|
|
var unresolved = [];
|
|
var optionsPath = attrs.kOptions || attrs.options;
|
|
var optionsValue = scope.$eval(optionsPath);
|
|
if (optionsPath && optionsValue === undefined) {
|
|
unresolved.push({
|
|
option: 'options',
|
|
path: optionsPath
|
|
});
|
|
}
|
|
var options = angular.extend({}, attrs.defaultOptions, optionsValue);
|
|
function addOption(name, value) {
|
|
var scopeValue = angular.copy(scope.$eval(value));
|
|
if (scopeValue === undefined) {
|
|
unresolved.push({
|
|
option: name,
|
|
path: value
|
|
});
|
|
} else {
|
|
options[name] = scopeValue;
|
|
}
|
|
}
|
|
var widgetOptions = ctor.widget.prototype.options;
|
|
var widgetEvents = ctor.widget.prototype.events;
|
|
$.each(attrs, function (name, value) {
|
|
if (name === 'source' || name === 'kDataSource' || name === 'kScopeField' || name === 'scopeField') {
|
|
return;
|
|
}
|
|
var dataName = 'data' + name.charAt(0).toUpperCase() + name.slice(1);
|
|
if (name.indexOf('on') === 0) {
|
|
var eventKey = name.replace(/^on./, function (prefix) {
|
|
return prefix.charAt(2).toLowerCase();
|
|
});
|
|
if (widgetEvents.indexOf(eventKey) > -1) {
|
|
options[eventKey] = value;
|
|
}
|
|
}
|
|
if (widgetOptions.hasOwnProperty(dataName)) {
|
|
addOption(dataName, value);
|
|
} else if (widgetOptions.hasOwnProperty(name) && !ignoredOwnProperties[name]) {
|
|
addOption(name, value);
|
|
} else if (!ignoredAttributes[name]) {
|
|
var match = name.match(/^k(On)?([A-Z].*)/);
|
|
if (match) {
|
|
var optionName = match[2].charAt(0).toLowerCase() + match[2].slice(1);
|
|
if (match[1] && name != 'kOnLabel') {
|
|
options[optionName] = value;
|
|
} else {
|
|
if (name == 'kOnLabel') {
|
|
optionName = 'onLabel';
|
|
}
|
|
addOption(optionName, value);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
var dataSource = attrs.kDataSource || attrs.source;
|
|
if (dataSource) {
|
|
options.dataSource = createDataSource(scope, element, role, dataSource);
|
|
}
|
|
options.$angular = [scope];
|
|
return {
|
|
options: options,
|
|
unresolved: unresolved
|
|
};
|
|
}
|
|
function bindToKNgDisabled(widget, scope, element, kNgDisabled) {
|
|
if (kendo.ui.PanelBar && widget instanceof kendo.ui.PanelBar || kendo.ui.Menu && widget instanceof kendo.ui.Menu) {
|
|
$log.warn('k-ng-disabled specified on a widget that does not have the enable() method: ' + widget.options.name);
|
|
return;
|
|
}
|
|
scope.$watch(kNgDisabled, function (newValue, oldValue) {
|
|
if (newValue != oldValue) {
|
|
widget.enable(!newValue);
|
|
}
|
|
});
|
|
}
|
|
function bindToKNgReadonly(widget, scope, element, kNgReadonly) {
|
|
if (typeof widget.readonly != 'function') {
|
|
$log.warn('k-ng-readonly specified on a widget that does not have the readonly() method: ' + widget.options.name);
|
|
return;
|
|
}
|
|
scope.$watch(kNgReadonly, function (newValue, oldValue) {
|
|
if (newValue != oldValue) {
|
|
widget.readonly(newValue);
|
|
}
|
|
});
|
|
}
|
|
function exposeWidget(widget, scope, attrs, kendoWidget, origAttr) {
|
|
if (attrs[origAttr]) {
|
|
var set = $parse(attrs[origAttr]).assign;
|
|
if (set) {
|
|
set(scope, widget);
|
|
} else {
|
|
throw new Error(origAttr + ' attribute used but expression in it is not assignable: ' + attrs[kendoWidget]);
|
|
}
|
|
}
|
|
}
|
|
function formValue(element) {
|
|
if (/checkbox|radio/i.test(element.attr('type'))) {
|
|
return element.prop('checked');
|
|
}
|
|
return element.val();
|
|
}
|
|
var formRegExp = /^(input|select|textarea)$/i;
|
|
function isForm(element) {
|
|
return formRegExp.test(element[0].tagName);
|
|
}
|
|
function bindToNgModel(widget, scope, element, ngModel, ngForm) {
|
|
if (!widget.value) {
|
|
return;
|
|
}
|
|
var value;
|
|
if (isForm(element)) {
|
|
value = function () {
|
|
return formValue(element);
|
|
};
|
|
} else {
|
|
value = function () {
|
|
return widget.value();
|
|
};
|
|
}
|
|
ngModel.$render = function () {
|
|
var val = ngModel.$viewValue;
|
|
if (val === undefined) {
|
|
val = ngModel.$modelValue;
|
|
}
|
|
if (val === undefined) {
|
|
val = null;
|
|
}
|
|
setTimeout(function () {
|
|
if (widget) {
|
|
var kNgModel = scope[widget.element.attr('k-ng-model')];
|
|
if (kNgModel) {
|
|
val = kNgModel;
|
|
}
|
|
if (widget.options.autoBind === false && !widget.listView.bound()) {
|
|
if (val) {
|
|
widget.value(val);
|
|
}
|
|
} else {
|
|
widget.value(val);
|
|
}
|
|
}
|
|
}, 0);
|
|
};
|
|
var haveChangeOnElement = false;
|
|
if (isForm(element)) {
|
|
element.on('change', function () {
|
|
haveChangeOnElement = true;
|
|
});
|
|
}
|
|
var onChange = function (pristine) {
|
|
return function () {
|
|
var formPristine;
|
|
if (haveChangeOnElement) {
|
|
return;
|
|
}
|
|
if (pristine && ngForm) {
|
|
formPristine = ngForm.$pristine;
|
|
}
|
|
ngModel.$setViewValue(value());
|
|
if (pristine) {
|
|
ngModel.$setPristine();
|
|
if (formPristine) {
|
|
ngForm.$setPristine();
|
|
}
|
|
}
|
|
digest(scope);
|
|
};
|
|
};
|
|
widget.first('change', onChange(false));
|
|
if (!(kendo.ui.AutoComplete && widget instanceof kendo.ui.AutoComplete)) {
|
|
widget.first('dataBound', onChange(true));
|
|
}
|
|
var currentVal = value();
|
|
if (!isNaN(ngModel.$viewValue) && currentVal != ngModel.$viewValue) {
|
|
if (!ngModel.$isEmpty(ngModel.$viewValue)) {
|
|
widget.value(ngModel.$viewValue);
|
|
} else if (currentVal != null && currentVal !== '' && currentVal != ngModel.$viewValue) {
|
|
ngModel.$setViewValue(currentVal);
|
|
}
|
|
}
|
|
ngModel.$setPristine();
|
|
}
|
|
function bindToKNgModel(widget, scope, kNgModel) {
|
|
if (typeof widget.value != 'function') {
|
|
$log.warn('k-ng-model specified on a widget that does not have the value() method: ' + widget.options.name);
|
|
return;
|
|
}
|
|
var form = $(widget.element).parents('form');
|
|
var ngForm = scope[form.attr('name')];
|
|
var getter = $parse(kNgModel);
|
|
var setter = getter.assign;
|
|
var updating = false;
|
|
var valueIsCollection = kendo.ui.MultiSelect && widget instanceof kendo.ui.MultiSelect;
|
|
var length = function (value) {
|
|
return valueIsCollection ? value.length : 0;
|
|
};
|
|
var currentValueLength = length(getter(scope));
|
|
widget.$angular_setLogicValue(getter(scope));
|
|
var watchHandler = function (newValue, oldValue) {
|
|
if (newValue === undefined) {
|
|
newValue = null;
|
|
}
|
|
if (updating || newValue == oldValue && length(newValue) == currentValueLength) {
|
|
return;
|
|
}
|
|
currentValueLength = length(newValue);
|
|
widget.$angular_setLogicValue(newValue);
|
|
};
|
|
if (valueIsCollection) {
|
|
scope.$watchCollection(kNgModel, watchHandler);
|
|
} else {
|
|
scope.$watch(kNgModel, watchHandler);
|
|
}
|
|
widget.first('change', function () {
|
|
updating = true;
|
|
if (ngForm && ngForm.$pristine) {
|
|
ngForm.$setDirty();
|
|
}
|
|
digest(scope, function () {
|
|
setter(scope, widget.$angular_getLogicValue());
|
|
currentValueLength = length(getter(scope));
|
|
});
|
|
updating = false;
|
|
});
|
|
}
|
|
function destroyWidgetOnScopeDestroy(scope, widget) {
|
|
var deregister = scope.$on('$destroy', function () {
|
|
deregister();
|
|
if (widget) {
|
|
if (widget.element) {
|
|
widget.destroy();
|
|
}
|
|
widget = null;
|
|
}
|
|
});
|
|
return deregister;
|
|
}
|
|
function propagateClassToWidgetWrapper(widget, element) {
|
|
if (!(window.MutationObserver && widget.wrapper)) {
|
|
return;
|
|
}
|
|
var prevClassList = [].slice.call($(element)[0].classList);
|
|
var mo = new MutationObserver(function (changes) {
|
|
suspend();
|
|
if (!widget) {
|
|
return;
|
|
}
|
|
changes.forEach(function (chg) {
|
|
var w = $(widget.wrapper)[0];
|
|
switch (chg.attributeName) {
|
|
case 'class':
|
|
var currClassList = [].slice.call(chg.target.classList);
|
|
currClassList.forEach(function (cls) {
|
|
if (prevClassList.indexOf(cls) < 0) {
|
|
w.classList.add(cls);
|
|
if (kendo.ui.ComboBox && widget instanceof kendo.ui.ComboBox) {
|
|
widget.input[0].classList.add(cls);
|
|
}
|
|
}
|
|
});
|
|
prevClassList.forEach(function (cls) {
|
|
if (currClassList.indexOf(cls) < 0) {
|
|
w.classList.remove(cls);
|
|
if (kendo.ui.ComboBox && widget instanceof kendo.ui.ComboBox) {
|
|
widget.input[0].classList.remove(cls);
|
|
}
|
|
}
|
|
});
|
|
prevClassList = currClassList;
|
|
break;
|
|
case 'disabled':
|
|
if (typeof widget.enable == 'function' && !widget.element.attr('readonly')) {
|
|
widget.enable(!$(chg.target).attr('disabled'));
|
|
}
|
|
break;
|
|
case 'readonly':
|
|
if (typeof widget.readonly == 'function' && !widget.element.attr('disabled')) {
|
|
widget.readonly(!!$(chg.target).attr('readonly'));
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
resume();
|
|
});
|
|
function suspend() {
|
|
mo.disconnect();
|
|
}
|
|
function resume() {
|
|
mo.observe($(element)[0], { attributes: true });
|
|
}
|
|
resume();
|
|
widget.first('destroy', suspend);
|
|
}
|
|
function setupRebind(widget, scope, element, originalElement, rebindAttr, destroyRegister, attrs) {
|
|
var unregister = scope.$watch(rebindAttr, function (newValue, oldValue) {
|
|
if (!widget._muteRebind && newValue !== oldValue) {
|
|
unregister();
|
|
var templateOptions = WIDGET_TEMPLATE_OPTIONS[widget.options.name];
|
|
if (templateOptions) {
|
|
templateOptions.forEach(function (name) {
|
|
var templateContents = scope.$eval(attrs['k' + name]);
|
|
if (templateContents) {
|
|
originalElement.append($(templateContents).attr(kendo.toHyphens('k' + name), ''));
|
|
}
|
|
});
|
|
}
|
|
var _wrapper = $(widget.wrapper)[0];
|
|
var _element = $(widget.element)[0];
|
|
var isUpload = widget.options.name === 'Upload';
|
|
if (isUpload) {
|
|
element = $(_element);
|
|
}
|
|
var compile = element.injector().get('$compile');
|
|
widget._destroy();
|
|
if (destroyRegister) {
|
|
destroyRegister();
|
|
}
|
|
widget = null;
|
|
if (_element) {
|
|
if (_wrapper) {
|
|
_wrapper.parentNode.replaceChild(_element, _wrapper);
|
|
}
|
|
$(element).replaceWith(originalElement);
|
|
}
|
|
compile(originalElement)(scope);
|
|
}
|
|
}, true);
|
|
digest(scope);
|
|
}
|
|
module.factory('directiveFactory', [
|
|
'$compile',
|
|
function (compile) {
|
|
var kendoRenderedTimeout;
|
|
var RENDERED = false;
|
|
$defaultCompile = compile;
|
|
var create = function (role, origAttr) {
|
|
return {
|
|
restrict: 'AC',
|
|
require: [
|
|
'?ngModel',
|
|
'^?form'
|
|
],
|
|
scope: false,
|
|
controller: [
|
|
'$scope',
|
|
'$attrs',
|
|
'$element',
|
|
function ($scope, $attrs) {
|
|
var that = this;
|
|
that.template = function (key, value) {
|
|
$attrs[key] = kendo.stringify(value);
|
|
};
|
|
$scope.$on('$destroy', function () {
|
|
that.template = null;
|
|
that = null;
|
|
});
|
|
}
|
|
],
|
|
link: function (scope, element, attrs, controllers) {
|
|
var $element = $(element);
|
|
var roleattr = role.replace(/([A-Z])/g, '-$1');
|
|
$element.attr(roleattr, $element.attr('data-' + roleattr));
|
|
$element[0].removeAttribute('data-' + roleattr);
|
|
var widget = createWidget(scope, element, attrs, role, origAttr, controllers);
|
|
if (!widget) {
|
|
return;
|
|
}
|
|
if (kendoRenderedTimeout) {
|
|
clearTimeout(kendoRenderedTimeout);
|
|
}
|
|
kendoRenderedTimeout = setTimeout(function () {
|
|
scope.$emit('kendoRendered');
|
|
if (!RENDERED) {
|
|
RENDERED = true;
|
|
$('form').each(function () {
|
|
var form = $(this).controller('form');
|
|
if (form) {
|
|
form.$setPristine();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
};
|
|
return { create: create };
|
|
}
|
|
]);
|
|
var TAGNAMES = {
|
|
Editor: 'textarea',
|
|
NumericTextBox: 'input',
|
|
DatePicker: 'input',
|
|
DateTimePicker: 'input',
|
|
TimePicker: 'input',
|
|
AutoComplete: 'input',
|
|
ColorPicker: 'input',
|
|
MaskedTextBox: 'input',
|
|
MultiSelect: 'input',
|
|
Upload: 'input',
|
|
Validator: 'form',
|
|
Button: 'button',
|
|
MobileButton: 'a',
|
|
MobileBackButton: 'a',
|
|
MobileDetailButton: 'a',
|
|
ListView: 'ul',
|
|
MobileListView: 'ul',
|
|
TreeView: 'ul',
|
|
Menu: 'ul',
|
|
ContextMenu: 'ul',
|
|
ActionSheet: 'ul'
|
|
};
|
|
var SKIP_SHORTCUTS = [
|
|
'MobileView',
|
|
'MobileDrawer',
|
|
'MobileLayout',
|
|
'MobileSplitView',
|
|
'MobilePane',
|
|
'MobileModalView'
|
|
];
|
|
var MANUAL_DIRECTIVES = [
|
|
'MobileApplication',
|
|
'MobileView',
|
|
'MobileModalView',
|
|
'MobileLayout',
|
|
'MobileActionSheet',
|
|
'MobileDrawer',
|
|
'MobileSplitView',
|
|
'MobilePane',
|
|
'MobileScrollView',
|
|
'MobilePopOver'
|
|
];
|
|
angular.forEach([
|
|
'MobileNavBar',
|
|
'MobileButton',
|
|
'MobileBackButton',
|
|
'MobileDetailButton',
|
|
'MobileTabStrip',
|
|
'MobileScrollView',
|
|
'MobileScroller'
|
|
], function (widget) {
|
|
MANUAL_DIRECTIVES.push(widget);
|
|
widget = 'kendo' + widget;
|
|
module.directive(widget, function () {
|
|
return {
|
|
restrict: 'A',
|
|
link: function (scope, element, attrs) {
|
|
createWidget(scope, element, attrs, widget, widget);
|
|
}
|
|
};
|
|
});
|
|
});
|
|
function createDirectives(klass, isMobile) {
|
|
function make(directiveName, widgetName) {
|
|
module.directive(directiveName, [
|
|
'directiveFactory',
|
|
function (directiveFactory) {
|
|
return directiveFactory.create(widgetName, directiveName);
|
|
}
|
|
]);
|
|
}
|
|
var name = isMobile ? 'Mobile' : '';
|
|
name += klass.fn.options.name;
|
|
var className = name;
|
|
var shortcut = 'kendo' + name.charAt(0) + name.substr(1).toLowerCase();
|
|
name = 'kendo' + name;
|
|
var dashed = name.replace(/([A-Z])/g, '-$1');
|
|
if (SKIP_SHORTCUTS.indexOf(name.replace('kendo', '')) == -1) {
|
|
var names = name === shortcut ? [name] : [
|
|
name,
|
|
shortcut
|
|
];
|
|
angular.forEach(names, function (directiveName) {
|
|
module.directive(directiveName, function () {
|
|
return {
|
|
restrict: 'E',
|
|
replace: true,
|
|
template: function (element, attributes) {
|
|
var tag = TAGNAMES[className] || 'div';
|
|
var scopeField = attributes.kScopeField || attributes.scopeField;
|
|
return '<' + tag + ' ' + dashed + (scopeField ? '="' + scopeField + '"' : '') + '>' + element.html() + '</' + tag + '>';
|
|
}
|
|
};
|
|
});
|
|
});
|
|
}
|
|
if (MANUAL_DIRECTIVES.indexOf(name.replace('kendo', '')) > -1) {
|
|
return;
|
|
}
|
|
make(name, name);
|
|
if (shortcut != name) {
|
|
make(shortcut, name);
|
|
}
|
|
}
|
|
function kendoWidgetInstance(el) {
|
|
el = $(el);
|
|
return kendo.widgetInstance(el, kendo.ui) || kendo.widgetInstance(el, kendo.mobile.ui) || kendo.widgetInstance(el, kendo.dataviz.ui);
|
|
}
|
|
function digest(scope, func) {
|
|
var root = scope.$root || scope;
|
|
var isDigesting = /^\$(digest|apply)$/.test(root.$$phase);
|
|
if (func) {
|
|
if (isDigesting) {
|
|
func();
|
|
} else {
|
|
root.$apply(func);
|
|
}
|
|
} else if (!isDigesting) {
|
|
root.$digest();
|
|
}
|
|
}
|
|
function destroyScope(scope, el) {
|
|
scope.$destroy();
|
|
if (el) {
|
|
$(el).removeData('$scope').removeData('$$kendoScope').removeData('$isolateScope').removeData('$isolateScopeNoTemplate').removeClass('ng-scope');
|
|
}
|
|
}
|
|
var pendingPatches = [];
|
|
function defadvice(klass, methodName, func) {
|
|
if ($.isArray(klass)) {
|
|
return angular.forEach(klass, function (klass) {
|
|
defadvice(klass, methodName, func);
|
|
});
|
|
}
|
|
if (typeof klass == 'string') {
|
|
var a = klass.split('.');
|
|
var x = kendo;
|
|
while (x && a.length > 0) {
|
|
x = x[a.shift()];
|
|
}
|
|
if (!x) {
|
|
pendingPatches.push([
|
|
klass,
|
|
methodName,
|
|
func
|
|
]);
|
|
return false;
|
|
}
|
|
klass = x.prototype;
|
|
}
|
|
var origMethod = klass[methodName];
|
|
klass[methodName] = function () {
|
|
var self = this, args = arguments;
|
|
return func.apply({
|
|
self: self,
|
|
next: function () {
|
|
return origMethod.apply(self, arguments.length > 0 ? arguments : args);
|
|
}
|
|
}, args);
|
|
};
|
|
return true;
|
|
}
|
|
kendo.onWidgetRegistered(function (entry) {
|
|
pendingPatches = $.grep(pendingPatches, function (args) {
|
|
return !defadvice.apply(null, args);
|
|
});
|
|
createDirectives(entry.widget, entry.prefix == 'Mobile');
|
|
});
|
|
defadvice([
|
|
'ui.Widget',
|
|
'mobile.ui.Widget'
|
|
], 'angular', function (cmd, arg) {
|
|
var self = this.self;
|
|
if (cmd == 'init') {
|
|
if (!arg && OPTIONS_NOW) {
|
|
arg = OPTIONS_NOW;
|
|
}
|
|
OPTIONS_NOW = null;
|
|
if (arg && arg.$angular) {
|
|
self.$angular_scope = arg.$angular[0];
|
|
self.$angular_init(self.element, arg);
|
|
}
|
|
return;
|
|
}
|
|
var scope = self.$angular_scope;
|
|
if (scope) {
|
|
withoutTimeout(function () {
|
|
var x = arg(), elements = x.elements, data = x.data;
|
|
if (elements.length > 0) {
|
|
switch (cmd) {
|
|
case 'cleanup':
|
|
angular.forEach(elements, function (el) {
|
|
var itemScope = $(el).data('$$kendoScope');
|
|
if (itemScope && itemScope !== scope && itemScope.$$kendoScope) {
|
|
destroyScope(itemScope, el);
|
|
}
|
|
});
|
|
break;
|
|
case 'compile':
|
|
var injector = self.element.injector();
|
|
var compile = injector ? injector.get('$compile') : $defaultCompile;
|
|
angular.forEach(elements, function (el, i) {
|
|
var itemScope;
|
|
if (x.scopeFrom) {
|
|
itemScope = x.scopeFrom;
|
|
} else {
|
|
var vars = data && data[i];
|
|
if (vars !== undefined) {
|
|
itemScope = $.extend(scope.$new(), vars);
|
|
itemScope.$$kendoScope = true;
|
|
} else {
|
|
itemScope = scope;
|
|
}
|
|
}
|
|
$(el).data('$$kendoScope', itemScope);
|
|
compile(el)(itemScope);
|
|
});
|
|
digest(scope);
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
defadvice('ui.Widget', '$angular_getLogicValue', function () {
|
|
return this.self.value();
|
|
});
|
|
defadvice('ui.Widget', '$angular_setLogicValue', function (val) {
|
|
this.self.value(val);
|
|
});
|
|
defadvice('ui.Select', '$angular_getLogicValue', function () {
|
|
var item = this.self.dataItem(), valueField = this.self.options.dataValueField;
|
|
if (item) {
|
|
if (this.self.options.valuePrimitive) {
|
|
if (!!valueField) {
|
|
return item[valueField];
|
|
} else {
|
|
return item;
|
|
}
|
|
} else {
|
|
return item.toJSON();
|
|
}
|
|
} else {
|
|
return null;
|
|
}
|
|
});
|
|
defadvice('ui.Select', '$angular_setLogicValue', function (val) {
|
|
var self = this.self;
|
|
var options = self.options;
|
|
var valueField = options.dataValueField;
|
|
var text = options.text || '';
|
|
if (val === undefined) {
|
|
val = '';
|
|
}
|
|
if (valueField && !options.valuePrimitive && val) {
|
|
text = val[options.dataTextField] || '';
|
|
val = val[valueField || options.dataTextField];
|
|
}
|
|
if (self.options.autoBind === false && !self.listView.bound()) {
|
|
if (!text && val && options.valuePrimitive) {
|
|
self.value(val);
|
|
} else {
|
|
self._preselect(val, text);
|
|
}
|
|
} else {
|
|
self.value(val);
|
|
}
|
|
});
|
|
defadvice('ui.MultiSelect', '$angular_getLogicValue', function () {
|
|
var value = this.self.dataItems().slice(0);
|
|
var valueField = this.self.options.dataValueField;
|
|
if (valueField && this.self.options.valuePrimitive) {
|
|
value = $.map(value, function (item) {
|
|
return item[valueField];
|
|
});
|
|
}
|
|
return value;
|
|
});
|
|
defadvice('ui.MultiSelect', '$angular_setLogicValue', function (val) {
|
|
if (val == null) {
|
|
val = [];
|
|
}
|
|
var self = this.self;
|
|
var options = self.options;
|
|
var valueField = options.dataValueField;
|
|
var data = val;
|
|
if (valueField && !options.valuePrimitive) {
|
|
val = $.map(val, function (item) {
|
|
return item[valueField];
|
|
});
|
|
}
|
|
if (options.autoBind === false && !options.valuePrimitive && !self.listView.bound()) {
|
|
self._preselect(data, val);
|
|
} else {
|
|
self.value(val);
|
|
}
|
|
});
|
|
defadvice('ui.AutoComplete', '$angular_getLogicValue', function () {
|
|
var options = this.self.options;
|
|
var values = this.self.value().split(options.separator);
|
|
var valuePrimitive = options.valuePrimitive;
|
|
var data = this.self.dataSource.data();
|
|
var dataItems = [];
|
|
for (var idx = 0, length = data.length; idx < length; idx++) {
|
|
var item = data[idx];
|
|
var dataValue = options.dataTextField ? item[options.dataTextField] : item;
|
|
for (var j = 0; j < values.length; j++) {
|
|
if (dataValue === values[j]) {
|
|
if (valuePrimitive) {
|
|
dataItems.push(dataValue);
|
|
} else {
|
|
dataItems.push(item.toJSON());
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return dataItems;
|
|
});
|
|
defadvice('ui.AutoComplete', '$angular_setLogicValue', function (value) {
|
|
if (value == null) {
|
|
value = [];
|
|
}
|
|
var self = this.self, dataTextField = self.options.dataTextField;
|
|
if (dataTextField && !self.options.valuePrimitive) {
|
|
if (value.length !== undefined) {
|
|
value = $.map(value, function (item) {
|
|
return item[dataTextField];
|
|
});
|
|
} else {
|
|
value = value[dataTextField];
|
|
}
|
|
}
|
|
self.value(value);
|
|
});
|
|
defadvice('ui.Widget', '$angular_init', function (element, options) {
|
|
var self = this.self;
|
|
if (options && !$.isArray(options)) {
|
|
var scope = self.$angular_scope;
|
|
for (var i = self.events.length; --i >= 0;) {
|
|
var event = self.events[i];
|
|
var handler = options[event];
|
|
if (handler && typeof handler == 'string') {
|
|
options[event] = self.$angular_makeEventHandler(event, scope, handler);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
defadvice('ui.Widget', '$angular_makeEventHandler', function (event, scope, handler) {
|
|
handler = $parse(handler);
|
|
return function (e) {
|
|
digest(scope, function () {
|
|
handler(scope, { kendoEvent: e });
|
|
});
|
|
};
|
|
});
|
|
defadvice([
|
|
'ui.Grid',
|
|
'ui.ListView',
|
|
'ui.TreeView'
|
|
], '$angular_makeEventHandler', function (event, scope, handler) {
|
|
if (event != 'change') {
|
|
return this.next();
|
|
}
|
|
handler = $parse(handler);
|
|
return function (ev) {
|
|
var widget = ev.sender;
|
|
var options = widget.options;
|
|
var cell, multiple, locals = { kendoEvent: ev }, elems, items, columns, colIdx;
|
|
if (angular.isString(options.selectable)) {
|
|
cell = options.selectable.indexOf('cell') !== -1;
|
|
multiple = options.selectable.indexOf('multiple') !== -1;
|
|
}
|
|
elems = locals.selected = this.select();
|
|
items = locals.data = [];
|
|
columns = locals.columns = [];
|
|
for (var i = 0; i < elems.length; i++) {
|
|
var item = cell ? elems[i].parentNode : elems[i];
|
|
var dataItem = widget.dataItem(item);
|
|
if (cell) {
|
|
if (angular.element.inArray(dataItem, items) < 0) {
|
|
items.push(dataItem);
|
|
}
|
|
colIdx = angular.element(elems[i]).index();
|
|
if (angular.element.inArray(colIdx, columns) < 0) {
|
|
columns.push(colIdx);
|
|
}
|
|
} else {
|
|
items.push(dataItem);
|
|
}
|
|
}
|
|
if (!multiple) {
|
|
locals.dataItem = locals.data = items[0];
|
|
locals.angularDataItem = kendo.proxyModelSetters(locals.dataItem);
|
|
locals.selected = elems[0];
|
|
}
|
|
digest(scope, function () {
|
|
handler(scope, locals);
|
|
});
|
|
};
|
|
});
|
|
defadvice('ui.Grid', '$angular_init', function (element, options) {
|
|
this.next();
|
|
if (options.columns) {
|
|
var settings = $.extend({}, kendo.Template, options.templateSettings);
|
|
angular.forEach(options.columns, function (col) {
|
|
if (col.field && !col.template && !col.format && !col.values && (col.encoded === undefined || col.encoded)) {
|
|
col.template = '<span ng-bind=\'' + kendo.expr(col.field, 'dataItem') + '\'>#: ' + kendo.expr(col.field, settings.paramName) + '#</span>';
|
|
}
|
|
});
|
|
}
|
|
});
|
|
{
|
|
defadvice('mobile.ui.ButtonGroup', 'value', function (mew) {
|
|
var self = this.self;
|
|
if (mew != null) {
|
|
self.select(self.element.children('li.km-button').eq(mew));
|
|
self.trigger('change');
|
|
self.trigger('select', { index: self.selectedIndex });
|
|
}
|
|
return self.selectedIndex;
|
|
});
|
|
defadvice('mobile.ui.ButtonGroup', '_select', function () {
|
|
this.next();
|
|
this.self.trigger('change');
|
|
});
|
|
}
|
|
module.directive('kendoMobileApplication', function () {
|
|
return {
|
|
terminal: true,
|
|
link: function (scope, element, attrs) {
|
|
createWidget(scope, element, attrs, 'kendoMobileApplication', 'kendoMobileApplication');
|
|
}
|
|
};
|
|
}).directive('kendoMobileView', function () {
|
|
return {
|
|
scope: true,
|
|
link: {
|
|
pre: function (scope, element, attrs) {
|
|
attrs.defaultOptions = scope.viewOptions;
|
|
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileView', 'kendoMobileView');
|
|
},
|
|
post: function (scope, element, attrs) {
|
|
attrs._instance._layout();
|
|
attrs._instance._scroller();
|
|
}
|
|
}
|
|
};
|
|
}).directive('kendoMobileDrawer', function () {
|
|
return {
|
|
scope: true,
|
|
link: {
|
|
pre: function (scope, element, attrs) {
|
|
attrs.defaultOptions = scope.viewOptions;
|
|
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileDrawer', 'kendoMobileDrawer');
|
|
},
|
|
post: function (scope, element, attrs) {
|
|
attrs._instance._layout();
|
|
attrs._instance._scroller();
|
|
}
|
|
}
|
|
};
|
|
}).directive('kendoMobileModalView', function () {
|
|
return {
|
|
scope: true,
|
|
link: {
|
|
pre: function (scope, element, attrs) {
|
|
attrs.defaultOptions = scope.viewOptions;
|
|
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileModalView', 'kendoMobileModalView');
|
|
},
|
|
post: function (scope, element, attrs) {
|
|
attrs._instance._layout();
|
|
attrs._instance._scroller();
|
|
}
|
|
}
|
|
};
|
|
}).directive('kendoMobileSplitView', function () {
|
|
return {
|
|
terminal: true,
|
|
link: {
|
|
pre: function (scope, element, attrs) {
|
|
attrs.defaultOptions = scope.viewOptions;
|
|
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileSplitView', 'kendoMobileSplitView');
|
|
},
|
|
post: function (scope, element, attrs) {
|
|
attrs._instance._layout();
|
|
}
|
|
}
|
|
};
|
|
}).directive('kendoMobilePane', function () {
|
|
return {
|
|
terminal: true,
|
|
link: {
|
|
pre: function (scope, element, attrs) {
|
|
attrs.defaultOptions = scope.viewOptions;
|
|
createWidget(scope, element, attrs, 'kendoMobilePane', 'kendoMobilePane');
|
|
}
|
|
}
|
|
};
|
|
}).directive('kendoMobileLayout', function () {
|
|
return {
|
|
link: {
|
|
pre: function (scope, element, attrs) {
|
|
createWidget(scope, element, attrs, 'kendoMobileLayout', 'kendoMobileLayout');
|
|
}
|
|
}
|
|
};
|
|
}).directive('kendoMobileActionSheet', function () {
|
|
return {
|
|
restrict: 'A',
|
|
link: function (scope, element, attrs) {
|
|
element.find('a[k-action]').each(function () {
|
|
$(this).attr('data-' + kendo.ns + 'action', $(this).attr('k-action'));
|
|
});
|
|
createWidget(scope, element, attrs, 'kendoMobileActionSheet', 'kendoMobileActionSheet');
|
|
}
|
|
};
|
|
}).directive('kendoMobilePopOver', function () {
|
|
return {
|
|
terminal: true,
|
|
link: {
|
|
pre: function (scope, element, attrs) {
|
|
attrs.defaultOptions = scope.viewOptions;
|
|
createWidget(scope, element, attrs, 'kendoMobilePopOver', 'kendoMobilePopOver');
|
|
}
|
|
}
|
|
};
|
|
}).directive('kendoViewTitle', function () {
|
|
return {
|
|
restrict: 'E',
|
|
replace: true,
|
|
template: function (element) {
|
|
return '<span data-' + kendo.ns + 'role=\'view-title\'>' + element.html() + '</span>';
|
|
}
|
|
};
|
|
}).directive('kendoMobileHeader', function () {
|
|
return {
|
|
restrict: 'E',
|
|
link: function (scope, element) {
|
|
element.addClass('km-header').attr('data-role', 'header');
|
|
}
|
|
};
|
|
}).directive('kendoMobileFooter', function () {
|
|
return {
|
|
restrict: 'E',
|
|
link: function (scope, element) {
|
|
element.addClass('km-footer').attr('data-role', 'footer');
|
|
}
|
|
};
|
|
}).directive('kendoMobileScrollViewPage', function () {
|
|
return {
|
|
restrict: 'E',
|
|
replace: true,
|
|
template: function (element) {
|
|
return '<div data-' + kendo.ns + 'role=\'page\'>' + element.html() + '</div>';
|
|
}
|
|
};
|
|
});
|
|
angular.forEach([
|
|
'align',
|
|
'icon',
|
|
'rel',
|
|
'transition',
|
|
'actionsheetContext'
|
|
], function (attr) {
|
|
var kAttr = 'k' + attr.slice(0, 1).toUpperCase() + attr.slice(1);
|
|
module.directive(kAttr, function () {
|
|
return {
|
|
restrict: 'A',
|
|
priority: 2,
|
|
link: function (scope, element, attrs) {
|
|
element.attr(kendo.attr(kendo.toHyphens(attr)), scope.$eval(attrs[kAttr]));
|
|
}
|
|
};
|
|
});
|
|
});
|
|
var WIDGET_TEMPLATE_OPTIONS = {
|
|
'TreeMap': ['Template'],
|
|
'MobileListView': [
|
|
'HeaderTemplate',
|
|
'Template'
|
|
],
|
|
'MobileScrollView': [
|
|
'EmptyTemplate',
|
|
'Template'
|
|
],
|
|
'Grid': [
|
|
'AltRowTemplate',
|
|
'DetailTemplate',
|
|
'RowTemplate'
|
|
],
|
|
'ListView': [
|
|
'EditTemplate',
|
|
'Template',
|
|
'AltTemplate'
|
|
],
|
|
'Pager': [
|
|
'SelectTemplate',
|
|
'LinkTemplate'
|
|
],
|
|
'PivotGrid': [
|
|
'ColumnHeaderTemplate',
|
|
'DataCellTemplate',
|
|
'RowHeaderTemplate'
|
|
],
|
|
'Scheduler': [
|
|
'AllDayEventTemplate',
|
|
'DateHeaderTemplate',
|
|
'EventTemplate',
|
|
'MajorTimeHeaderTemplate',
|
|
'MinorTimeHeaderTemplate'
|
|
],
|
|
'TreeView': ['Template'],
|
|
'Validator': ['ErrorTemplate']
|
|
};
|
|
(function () {
|
|
var templateDirectives = {};
|
|
angular.forEach(WIDGET_TEMPLATE_OPTIONS, function (templates, widget) {
|
|
angular.forEach(templates, function (template) {
|
|
if (!templateDirectives[template]) {
|
|
templateDirectives[template] = [];
|
|
}
|
|
templateDirectives[template].push('?^^kendo' + widget);
|
|
});
|
|
});
|
|
angular.forEach(templateDirectives, function (parents, directive) {
|
|
var templateName = 'k' + directive;
|
|
var attrName = kendo.toHyphens(templateName);
|
|
module.directive(templateName, function () {
|
|
return {
|
|
restrict: 'A',
|
|
require: parents,
|
|
terminal: true,
|
|
compile: function ($element, $attrs) {
|
|
if ($attrs[templateName] !== '') {
|
|
return;
|
|
}
|
|
$element.removeAttr(attrName);
|
|
var template = $element[0].outerHTML;
|
|
return function (scope, element, attrs, controllers) {
|
|
var controller;
|
|
while (!controller && controllers.length) {
|
|
controller = controllers.shift();
|
|
}
|
|
if (!controller) {
|
|
$log.warn(attrName + ' without a matching parent widget found. It can be one of the following: ' + parents.join(', '));
|
|
} else {
|
|
controller.template(templateName, template);
|
|
$element.remove();
|
|
}
|
|
};
|
|
}
|
|
};
|
|
});
|
|
});
|
|
}());
|
|
}(window.kendo.jQuery, window.angular));
|
|
return window.kendo;
|
|
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
|
|
(a3 || a2)();
|
|
})); |