%PDF- %PDF-
Direktori : /home/jalalj2hb/public_html/ftm-admin/assets/js/ |
Current File : /home/jalalj2hb/public_html/ftm-admin/assets/js/kendoui_custom.js |
/** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.core', ['jquery'], f); }(function () { var __meta__ = { id: 'core', name: 'Core', category: 'framework', description: 'The core of the Kendo framework.' }; (function ($, window, undefined) { var kendo = window.kendo = window.kendo || { cultures: {} }, extend = $.extend, each = $.each, isArray = $.isArray, proxy = $.proxy, noop = $.noop, math = Math, Template, JSON = window.JSON || {}, support = {}, percentRegExp = /%/, formatRegExp = /\{(\d+)(:[^\}]+)?\}/g, boxShadowRegExp = /(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+)?/i, numberRegExp = /^(\+|-?)\d+(\.?)\d*$/, FUNCTION = 'function', STRING = 'string', NUMBER = 'number', OBJECT = 'object', NULL = 'null', BOOLEAN = 'boolean', UNDEFINED = 'undefined', getterCache = {}, setterCache = {}, slice = [].slice; kendo.version = '2016.2.805'.replace(/^\s+|\s+$/g, ''); function Class() { } Class.extend = function (proto) { var base = function () { }, member, that = this, subclass = proto && proto.init ? proto.init : function () { that.apply(this, arguments); }, fn; base.prototype = that.prototype; fn = subclass.fn = subclass.prototype = new base(); for (member in proto) { if (proto[member] != null && proto[member].constructor === Object) { fn[member] = extend(true, {}, base.prototype[member], proto[member]); } else { fn[member] = proto[member]; } } fn.constructor = subclass; subclass.extend = that.extend; return subclass; }; Class.prototype._initOptions = function (options) { this.options = deepExtend({}, this.options, options); }; var isFunction = kendo.isFunction = function (fn) { return typeof fn === 'function'; }; var preventDefault = function () { this._defaultPrevented = true; }; var isDefaultPrevented = function () { return this._defaultPrevented === true; }; var Observable = Class.extend({ init: function () { this._events = {}; }, bind: function (eventName, handlers, one) { var that = this, idx, eventNames = typeof eventName === STRING ? [eventName] : eventName, length, original, handler, handlersIsFunction = typeof handlers === FUNCTION, events; if (handlers === undefined) { for (idx in eventName) { that.bind(idx, eventName[idx]); } return that; } for (idx = 0, length = eventNames.length; idx < length; idx++) { eventName = eventNames[idx]; handler = handlersIsFunction ? handlers : handlers[eventName]; if (handler) { if (one) { original = handler; handler = function () { that.unbind(eventName, handler); original.apply(that, arguments); }; handler.original = original; } events = that._events[eventName] = that._events[eventName] || []; events.push(handler); } } return that; }, one: function (eventNames, handlers) { return this.bind(eventNames, handlers, true); }, first: function (eventName, handlers) { var that = this, idx, eventNames = typeof eventName === STRING ? [eventName] : eventName, length, handler, handlersIsFunction = typeof handlers === FUNCTION, events; for (idx = 0, length = eventNames.length; idx < length; idx++) { eventName = eventNames[idx]; handler = handlersIsFunction ? handlers : handlers[eventName]; if (handler) { events = that._events[eventName] = that._events[eventName] || []; events.unshift(handler); } } return that; }, trigger: function (eventName, e) { var that = this, events = that._events[eventName], idx, length; if (events) { e = e || {}; e.sender = that; e._defaultPrevented = false; e.preventDefault = preventDefault; e.isDefaultPrevented = isDefaultPrevented; events = events.slice(); for (idx = 0, length = events.length; idx < length; idx++) { events[idx].call(that, e); } return e._defaultPrevented === true; } return false; }, unbind: function (eventName, handler) { var that = this, events = that._events[eventName], idx; if (eventName === undefined) { that._events = {}; } else if (events) { if (handler) { for (idx = events.length - 1; idx >= 0; idx--) { if (events[idx] === handler || events[idx].original === handler) { events.splice(idx, 1); } } } else { that._events[eventName] = []; } } return that; } }); function compilePart(part, stringPart) { if (stringPart) { return '\'' + part.split('\'').join('\\\'').split('\\"').join('\\\\\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t') + '\''; } else { var first = part.charAt(0), rest = part.substring(1); if (first === '=') { return '+(' + rest + ')+'; } else if (first === ':') { return '+$kendoHtmlEncode(' + rest + ')+'; } else { return ';' + part + ';$kendoOutput+='; } } } var argumentNameRegExp = /^\w+/, encodeRegExp = /\$\{([^}]*)\}/g, escapedCurlyRegExp = /\\\}/g, curlyRegExp = /__CURLY__/g, escapedSharpRegExp = /\\#/g, sharpRegExp = /__SHARP__/g, zeros = [ '', '0', '00', '000', '0000' ]; Template = { paramName: 'data', useWithBlock: true, render: function (template, data) { var idx, length, html = ''; for (idx = 0, length = data.length; idx < length; idx++) { html += template(data[idx]); } return html; }, compile: function (template, options) { var settings = extend({}, this, options), paramName = settings.paramName, argumentName = paramName.match(argumentNameRegExp)[0], useWithBlock = settings.useWithBlock, functionBody = 'var $kendoOutput, $kendoHtmlEncode = kendo.htmlEncode;', fn, parts, idx; if (isFunction(template)) { return template; } functionBody += useWithBlock ? 'with(' + paramName + '){' : ''; functionBody += '$kendoOutput='; parts = template.replace(escapedCurlyRegExp, '__CURLY__').replace(encodeRegExp, '#=$kendoHtmlEncode($1)#').replace(curlyRegExp, '}').replace(escapedSharpRegExp, '__SHARP__').split('#'); for (idx = 0; idx < parts.length; idx++) { functionBody += compilePart(parts[idx], idx % 2 === 0); } functionBody += useWithBlock ? ';}' : ';'; functionBody += 'return $kendoOutput;'; functionBody = functionBody.replace(sharpRegExp, '#'); try { fn = new Function(argumentName, functionBody); fn._slotCount = Math.floor(parts.length / 2); return fn; } catch (e) { throw new Error(kendo.format('Invalid template:\'{0}\' Generated code:\'{1}\'', template, functionBody)); } } }; function pad(number, digits, end) { number = number + ''; digits = digits || 2; end = digits - number.length; if (end) { return zeros[digits].substring(0, end) + number; } return number; } (function () { var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\' }, rep, toString = {}.toString; if (typeof Date.prototype.toJSON !== FUNCTION) { Date.prototype.toJSON = function () { var that = this; return isFinite(that.valueOf()) ? pad(that.getUTCFullYear(), 4) + '-' + pad(that.getUTCMonth() + 1) + '-' + pad(that.getUTCDate()) + 'T' + pad(that.getUTCHours()) + ':' + pad(that.getUTCMinutes()) + ':' + pad(that.getUTCSeconds()) + 'Z' : null; }; String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function () { return this.valueOf(); }; } function quote(string) { escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === STRING ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' : '"' + string + '"'; } function str(key, holder) { var i, k, v, length, mind = gap, partial, value = holder[key], type; if (value && typeof value === OBJECT && typeof value.toJSON === FUNCTION) { value = value.toJSON(key); } if (typeof rep === FUNCTION) { value = rep.call(holder, key, value); } type = typeof value; if (type === STRING) { return quote(value); } else if (type === NUMBER) { return isFinite(value) ? String(value) : NULL; } else if (type === BOOLEAN || type === NULL) { return String(value); } else if (type === OBJECT) { if (!value) { return NULL; } gap += indent; partial = []; if (toString.apply(value) === '[object Array]') { length = value.length; for (i = 0; i < length; i++) { partial[i] = str(i, value) || NULL; } v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; gap = mind; return v; } if (rep && typeof rep === OBJECT) { length = rep.length; for (i = 0; i < length; i++) { if (typeof rep[i] === STRING) { k = rep[i]; v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } else { for (k in value) { if (Object.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; gap = mind; return v; } } if (typeof JSON.stringify !== FUNCTION) { JSON.stringify = function (value, replacer, space) { var i; gap = ''; indent = ''; if (typeof space === NUMBER) { for (i = 0; i < space; i += 1) { indent += ' '; } } else if (typeof space === STRING) { indent = space; } rep = replacer; if (replacer && typeof replacer !== FUNCTION && (typeof replacer !== OBJECT || typeof replacer.length !== NUMBER)) { throw new Error('JSON.stringify'); } return str('', { '': value }); }; } }()); (function () { var dateFormatRegExp = /dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|HH|H|hh|h|mm|m|fff|ff|f|tt|ss|s|zzz|zz|z|"[^"]*"|'[^']*'/g, standardFormatRegExp = /^(n|c|p|e)(\d*)$/i, literalRegExp = /(\\.)|(['][^']*[']?)|(["][^"]*["]?)/g, commaRegExp = /\,/g, EMPTY = '', POINT = '.', COMMA = ',', SHARP = '#', ZERO = '0', PLACEHOLDER = '??', EN = 'en-US', objectToString = {}.toString; kendo.cultures['en-US'] = { name: EN, numberFormat: { pattern: ['-n'], decimals: 2, ',': ',', '.': '.', groupSize: [3], percent: { pattern: [ '-n %', 'n %' ], decimals: 2, ',': ',', '.': '.', groupSize: [3], symbol: '%' }, currency: { name: 'US Dollar', abbr: 'USD', pattern: [ '($n)', '$n' ], decimals: 2, ',': ',', '.': '.', groupSize: [3], symbol: '$' } }, calendars: { standard: { days: { names: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], namesAbbr: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], namesShort: [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ] }, months: { names: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], namesAbbr: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] }, AM: [ 'AM', 'am', 'AM' ], PM: [ 'PM', 'pm', 'PM' ], patterns: { d: 'M/d/yyyy', D: 'dddd, MMMM dd, yyyy', F: 'dddd, MMMM dd, yyyy h:mm:ss tt', g: 'M/d/yyyy h:mm tt', G: 'M/d/yyyy h:mm:ss tt', m: 'MMMM dd', M: 'MMMM dd', s: 'yyyy\'-\'MM\'-\'ddTHH\':\'mm\':\'ss', t: 'h:mm tt', T: 'h:mm:ss tt', u: 'yyyy\'-\'MM\'-\'dd HH\':\'mm\':\'ss\'Z\'', y: 'MMMM, yyyy', Y: 'MMMM, yyyy' }, '/': '/', ':': ':', firstDay: 0, twoDigitYearMax: 2029 } } }; function findCulture(culture) { if (culture) { if (culture.numberFormat) { return culture; } if (typeof culture === STRING) { var cultures = kendo.cultures; return cultures[culture] || cultures[culture.split('-')[0]] || null; } return null; } return null; } function getCulture(culture) { if (culture) { culture = findCulture(culture); } return culture || kendo.cultures.current; } kendo.culture = function (cultureName) { var cultures = kendo.cultures, culture; if (cultureName !== undefined) { culture = findCulture(cultureName) || cultures[EN]; culture.calendar = culture.calendars.standard; cultures.current = culture; } else { return cultures.current; } }; kendo.findCulture = findCulture; kendo.getCulture = getCulture; kendo.culture(EN); function formatDate(date, format, culture) { culture = getCulture(culture); var calendar = culture.calendars.standard, days = calendar.days, months = calendar.months; format = calendar.patterns[format] || format; return format.replace(dateFormatRegExp, function (match) { var minutes; var result; var sign; if (match === 'd') { result = date.getDate(); } else if (match === 'dd') { result = pad(date.getDate()); } else if (match === 'ddd') { result = days.namesAbbr[date.getDay()]; } else if (match === 'dddd') { result = days.names[date.getDay()]; } else if (match === 'M') { result = date.getMonth() + 1; } else if (match === 'MM') { result = pad(date.getMonth() + 1); } else if (match === 'MMM') { result = months.namesAbbr[date.getMonth()]; } else if (match === 'MMMM') { result = months.names[date.getMonth()]; } else if (match === 'yy') { result = pad(date.getFullYear() % 100); } else if (match === 'yyyy') { result = pad(date.getFullYear(), 4); } else if (match === 'h') { result = date.getHours() % 12 || 12; } else if (match === 'hh') { result = pad(date.getHours() % 12 || 12); } else if (match === 'H') { result = date.getHours(); } else if (match === 'HH') { result = pad(date.getHours()); } else if (match === 'm') { result = date.getMinutes(); } else if (match === 'mm') { result = pad(date.getMinutes()); } else if (match === 's') { result = date.getSeconds(); } else if (match === 'ss') { result = pad(date.getSeconds()); } else if (match === 'f') { result = math.floor(date.getMilliseconds() / 100); } else if (match === 'ff') { result = date.getMilliseconds(); if (result > 99) { result = math.floor(result / 10); } result = pad(result); } else if (match === 'fff') { result = pad(date.getMilliseconds(), 3); } else if (match === 'tt') { result = date.getHours() < 12 ? calendar.AM[0] : calendar.PM[0]; } else if (match === 'zzz') { minutes = date.getTimezoneOffset(); sign = minutes < 0; result = math.abs(minutes / 60).toString().split('.')[0]; minutes = math.abs(minutes) - result * 60; result = (sign ? '+' : '-') + pad(result); result += ':' + pad(minutes); } else if (match === 'zz' || match === 'z') { result = date.getTimezoneOffset() / 60; sign = result < 0; result = math.abs(result).toString().split('.')[0]; result = (sign ? '+' : '-') + (match === 'zz' ? pad(result) : result); } return result !== undefined ? result : match.slice(1, match.length - 1); }); } function formatNumber(number, format, culture) { culture = getCulture(culture); var numberFormat = culture.numberFormat, decimal = numberFormat[POINT], precision = numberFormat.decimals, pattern = numberFormat.pattern[0], literals = [], symbol, isCurrency, isPercent, customPrecision, formatAndPrecision, negative = number < 0, integer, fraction, integerLength, fractionLength, replacement = EMPTY, value = EMPTY, idx, length, ch, hasGroup, hasNegativeFormat, decimalIndex, sharpIndex, zeroIndex, hasZero, hasSharp, percentIndex, currencyIndex, startZeroIndex, start = -1, end; if (number === undefined) { return EMPTY; } if (!isFinite(number)) { return number; } if (!format) { return culture.name.length ? number.toLocaleString() : number.toString(); } formatAndPrecision = standardFormatRegExp.exec(format); if (formatAndPrecision) { format = formatAndPrecision[1].toLowerCase(); isCurrency = format === 'c'; isPercent = format === 'p'; if (isCurrency || isPercent) { numberFormat = isCurrency ? numberFormat.currency : numberFormat.percent; decimal = numberFormat[POINT]; precision = numberFormat.decimals; symbol = numberFormat.symbol; pattern = numberFormat.pattern[negative ? 0 : 1]; } customPrecision = formatAndPrecision[2]; if (customPrecision) { precision = +customPrecision; } if (format === 'e') { return customPrecision ? number.toExponential(precision) : number.toExponential(); } if (isPercent) { number *= 100; } number = round(number, precision); negative = number < 0; number = number.split(POINT); integer = number[0]; fraction = number[1]; if (negative) { integer = integer.substring(1); } value = groupInteger(integer, 0, integer.length, numberFormat); if (fraction) { value += decimal + fraction; } if (format === 'n' && !negative) { return value; } number = EMPTY; for (idx = 0, length = pattern.length; idx < length; idx++) { ch = pattern.charAt(idx); if (ch === 'n') { number += value; } else if (ch === '$' || ch === '%') { number += symbol; } else { number += ch; } } return number; } if (negative) { number = -number; } if (format.indexOf('\'') > -1 || format.indexOf('"') > -1 || format.indexOf('\\') > -1) { format = format.replace(literalRegExp, function (match) { var quoteChar = match.charAt(0).replace('\\', ''), literal = match.slice(1).replace(quoteChar, ''); literals.push(literal); return PLACEHOLDER; }); } format = format.split(';'); if (negative && format[1]) { format = format[1]; hasNegativeFormat = true; } else if (number === 0) { format = format[2] || format[0]; if (format.indexOf(SHARP) == -1 && format.indexOf(ZERO) == -1) { return format; } } else { format = format[0]; } percentIndex = format.indexOf('%'); currencyIndex = format.indexOf('$'); isPercent = percentIndex != -1; isCurrency = currencyIndex != -1; if (isPercent) { number *= 100; } if (isCurrency && format[currencyIndex - 1] === '\\') { format = format.split('\\').join(''); isCurrency = false; } if (isCurrency || isPercent) { numberFormat = isCurrency ? numberFormat.currency : numberFormat.percent; decimal = numberFormat[POINT]; precision = numberFormat.decimals; symbol = numberFormat.symbol; } hasGroup = format.indexOf(COMMA) > -1; if (hasGroup) { format = format.replace(commaRegExp, EMPTY); } decimalIndex = format.indexOf(POINT); length = format.length; if (decimalIndex != -1) { fraction = number.toString().split('e'); if (fraction[1]) { fraction = round(number, Math.abs(fraction[1])); } else { fraction = fraction[0]; } fraction = fraction.split(POINT)[1] || EMPTY; zeroIndex = format.lastIndexOf(ZERO) - decimalIndex; sharpIndex = format.lastIndexOf(SHARP) - decimalIndex; hasZero = zeroIndex > -1; hasSharp = sharpIndex > -1; idx = fraction.length; if (!hasZero && !hasSharp) { format = format.substring(0, decimalIndex) + format.substring(decimalIndex + 1); length = format.length; decimalIndex = -1; idx = 0; } if (hasZero && zeroIndex > sharpIndex) { idx = zeroIndex; } else if (sharpIndex > zeroIndex) { if (hasSharp && idx > sharpIndex) { idx = sharpIndex; } else if (hasZero && idx < zeroIndex) { idx = zeroIndex; } } if (idx > -1) { number = round(number, idx); } } else { number = round(number); } sharpIndex = format.indexOf(SHARP); startZeroIndex = zeroIndex = format.indexOf(ZERO); if (sharpIndex == -1 && zeroIndex != -1) { start = zeroIndex; } else if (sharpIndex != -1 && zeroIndex == -1) { start = sharpIndex; } else { start = sharpIndex > zeroIndex ? zeroIndex : sharpIndex; } sharpIndex = format.lastIndexOf(SHARP); zeroIndex = format.lastIndexOf(ZERO); if (sharpIndex == -1 && zeroIndex != -1) { end = zeroIndex; } else if (sharpIndex != -1 && zeroIndex == -1) { end = sharpIndex; } else { end = sharpIndex > zeroIndex ? sharpIndex : zeroIndex; } if (start == length) { end = start; } if (start != -1) { value = number.toString().split(POINT); integer = value[0]; fraction = value[1] || EMPTY; integerLength = integer.length; fractionLength = fraction.length; if (negative && number * -1 >= 0) { negative = false; } number = format.substring(0, start); if (negative && !hasNegativeFormat) { number += '-'; } for (idx = start; idx < length; idx++) { ch = format.charAt(idx); if (decimalIndex == -1) { if (end - idx < integerLength) { number += integer; break; } } else { if (zeroIndex != -1 && zeroIndex < idx) { replacement = EMPTY; } if (decimalIndex - idx <= integerLength && decimalIndex - idx > -1) { number += integer; idx = decimalIndex; } if (decimalIndex === idx) { number += (fraction ? decimal : EMPTY) + fraction; idx += end - decimalIndex + 1; continue; } } if (ch === ZERO) { number += ch; replacement = ch; } else if (ch === SHARP) { number += replacement; } } if (hasGroup) { number = groupInteger(number, start + (negative ? 1 : 0), Math.max(end, integerLength + start), numberFormat); } if (end >= start) { number += format.substring(end + 1); } if (isCurrency || isPercent) { value = EMPTY; for (idx = 0, length = number.length; idx < length; idx++) { ch = number.charAt(idx); value += ch === '$' || ch === '%' ? symbol : ch; } number = value; } length = literals.length; if (length) { for (idx = 0; idx < length; idx++) { number = number.replace(PLACEHOLDER, literals[idx]); } } } return number; } var groupInteger = function (number, start, end, numberFormat) { var decimalIndex = number.indexOf(numberFormat[POINT]); var groupSizes = numberFormat.groupSize.slice(); var groupSize = groupSizes.shift(); var integer, integerLength; var idx, parts, value; var newGroupSize; end = decimalIndex !== -1 ? decimalIndex : end + 1; integer = number.substring(start, end); integerLength = integer.length; if (integerLength >= groupSize) { idx = integerLength; parts = []; while (idx > -1) { value = integer.substring(idx - groupSize, idx); if (value) { parts.push(value); } idx -= groupSize; newGroupSize = groupSizes.shift(); groupSize = newGroupSize !== undefined ? newGroupSize : groupSize; if (groupSize === 0) { parts.push(integer.substring(0, idx)); break; } } integer = parts.reverse().join(numberFormat[COMMA]); number = number.substring(0, start) + integer + number.substring(end); } return number; }; var round = function (value, precision) { precision = precision || 0; value = value.toString().split('e'); value = Math.round(+(value[0] + 'e' + (value[1] ? +value[1] + precision : precision))); value = value.toString().split('e'); value = +(value[0] + 'e' + (value[1] ? +value[1] - precision : -precision)); return value.toFixed(precision); }; var toString = function (value, fmt, culture) { if (fmt) { if (objectToString.call(value) === '[object Date]') { return formatDate(value, fmt, culture); } else if (typeof value === NUMBER) { return formatNumber(value, fmt, culture); } } return value !== undefined ? value : ''; }; kendo.format = function (fmt) { var values = arguments; return fmt.replace(formatRegExp, function (match, index, placeholderFormat) { var value = values[parseInt(index, 10) + 1]; return toString(value, placeholderFormat ? placeholderFormat.substring(1) : ''); }); }; kendo._extractFormat = function (format) { if (format.slice(0, 3) === '{0:') { format = format.slice(3, format.length - 1); } return format; }; kendo._activeElement = function () { try { return document.activeElement; } catch (e) { return document.documentElement.activeElement; } }; kendo._round = round; kendo.toString = toString; }()); (function () { var nonBreakingSpaceRegExp = /\u00A0/g, exponentRegExp = /[eE][\-+]?[0-9]+/, shortTimeZoneRegExp = /[+|\-]\d{1,2}/, longTimeZoneRegExp = /[+|\-]\d{1,2}:?\d{2}/, dateRegExp = /^\/Date\((.*?)\)\/$/, offsetRegExp = /[+-]\d*/, FORMATS_SEQUENCE = [ [], [ 'G', 'g', 'F' ], [ 'D', 'd', 'y', 'm', 'T', 't' ] ], STANDARD_FORMATS = [ [ 'yyyy-MM-ddTHH:mm:ss.fffffffzzz', 'yyyy-MM-ddTHH:mm:ss.fffffff', 'yyyy-MM-ddTHH:mm:ss.fffzzz', 'yyyy-MM-ddTHH:mm:ss.fff', 'ddd MMM dd yyyy HH:mm:ss', 'yyyy-MM-ddTHH:mm:sszzz', 'yyyy-MM-ddTHH:mmzzz', 'yyyy-MM-ddTHH:mmzz', 'yyyy-MM-ddTHH:mm:ss', 'yyyy-MM-dd HH:mm:ss', 'yyyy/MM/dd HH:mm:ss' ], [ 'yyyy-MM-ddTHH:mm', 'yyyy-MM-dd HH:mm', 'yyyy/MM/dd HH:mm' ], [ 'yyyy/MM/dd', 'yyyy-MM-dd', 'HH:mm:ss', 'HH:mm' ] ], numberRegExp = { 2: /^\d{1,2}/, 3: /^\d{1,3}/, 4: /^\d{4}/ }, objectToString = {}.toString; function outOfRange(value, start, end) { return !(value >= start && value <= end); } function designatorPredicate(designator) { return designator.charAt(0); } function mapDesignators(designators) { return $.map(designators, designatorPredicate); } function adjustDST(date, hours) { if (!hours && date.getHours() === 23) { date.setHours(date.getHours() + 2); } } function lowerArray(data) { var idx = 0, length = data.length, array = []; for (; idx < length; idx++) { array[idx] = (data[idx] + '').toLowerCase(); } return array; } function lowerLocalInfo(localInfo) { var newLocalInfo = {}, property; for (property in localInfo) { newLocalInfo[property] = lowerArray(localInfo[property]); } return newLocalInfo; } function parseExact(value, format, culture) { if (!value) { return null; } var lookAhead = function (match) { var i = 0; while (format[idx] === match) { i++; idx++; } if (i > 0) { idx -= 1; } return i; }, getNumber = function (size) { var rg = numberRegExp[size] || new RegExp('^\\d{1,' + size + '}'), match = value.substr(valueIdx, size).match(rg); if (match) { match = match[0]; valueIdx += match.length; return parseInt(match, 10); } return null; }, getIndexByName = function (names, lower) { var i = 0, length = names.length, name, nameLength, matchLength = 0, matchIdx = 0, subValue; for (; i < length; i++) { name = names[i]; nameLength = name.length; subValue = value.substr(valueIdx, nameLength); if (lower) { subValue = subValue.toLowerCase(); } if (subValue == name && nameLength > matchLength) { matchLength = nameLength; matchIdx = i; } } if (matchLength) { valueIdx += matchLength; return matchIdx + 1; } return null; }, checkLiteral = function () { var result = false; if (value.charAt(valueIdx) === format[idx]) { valueIdx++; result = true; } return result; }, calendar = culture.calendars.standard, year = null, month = null, day = null, hours = null, minutes = null, seconds = null, milliseconds = null, idx = 0, valueIdx = 0, literal = false, date = new Date(), twoDigitYearMax = calendar.twoDigitYearMax || 2029, defaultYear = date.getFullYear(), ch, count, length, pattern, pmHour, UTC, matches, amDesignators, pmDesignators, hoursOffset, minutesOffset, hasTime, match; if (!format) { format = 'd'; } pattern = calendar.patterns[format]; if (pattern) { format = pattern; } format = format.split(''); length = format.length; for (; idx < length; idx++) { ch = format[idx]; if (literal) { if (ch === '\'') { literal = false; } else { checkLiteral(); } } else { if (ch === 'd') { count = lookAhead('d'); if (!calendar._lowerDays) { calendar._lowerDays = lowerLocalInfo(calendar.days); } if (day !== null && count > 2) { continue; } day = count < 3 ? getNumber(2) : getIndexByName(calendar._lowerDays[count == 3 ? 'namesAbbr' : 'names'], true); if (day === null || outOfRange(day, 1, 31)) { return null; } } else if (ch === 'M') { count = lookAhead('M'); if (!calendar._lowerMonths) { calendar._lowerMonths = lowerLocalInfo(calendar.months); } month = count < 3 ? getNumber(2) : getIndexByName(calendar._lowerMonths[count == 3 ? 'namesAbbr' : 'names'], true); if (month === null || outOfRange(month, 1, 12)) { return null; } month -= 1; } else if (ch === 'y') { count = lookAhead('y'); year = getNumber(count); if (year === null) { return null; } if (count == 2) { if (typeof twoDigitYearMax === 'string') { twoDigitYearMax = defaultYear + parseInt(twoDigitYearMax, 10); } year = defaultYear - defaultYear % 100 + year; if (year > twoDigitYearMax) { year -= 100; } } } else if (ch === 'h') { lookAhead('h'); hours = getNumber(2); if (hours == 12) { hours = 0; } if (hours === null || outOfRange(hours, 0, 11)) { return null; } } else if (ch === 'H') { lookAhead('H'); hours = getNumber(2); if (hours === null || outOfRange(hours, 0, 23)) { return null; } } else if (ch === 'm') { lookAhead('m'); minutes = getNumber(2); if (minutes === null || outOfRange(minutes, 0, 59)) { return null; } } else if (ch === 's') { lookAhead('s'); seconds = getNumber(2); if (seconds === null || outOfRange(seconds, 0, 59)) { return null; } } else if (ch === 'f') { count = lookAhead('f'); match = value.substr(valueIdx, count).match(numberRegExp[3]); milliseconds = getNumber(count); if (milliseconds !== null) { milliseconds = parseFloat('0.' + match[0], 10); milliseconds = kendo._round(milliseconds, 3); milliseconds *= 1000; } if (milliseconds === null || outOfRange(milliseconds, 0, 999)) { return null; } } else if (ch === 't') { count = lookAhead('t'); amDesignators = calendar.AM; pmDesignators = calendar.PM; if (count === 1) { amDesignators = mapDesignators(amDesignators); pmDesignators = mapDesignators(pmDesignators); } pmHour = getIndexByName(pmDesignators); if (!pmHour && !getIndexByName(amDesignators)) { return null; } } else if (ch === 'z') { UTC = true; count = lookAhead('z'); if (value.substr(valueIdx, 1) === 'Z') { checkLiteral(); continue; } matches = value.substr(valueIdx, 6).match(count > 2 ? longTimeZoneRegExp : shortTimeZoneRegExp); if (!matches) { return null; } matches = matches[0].split(':'); hoursOffset = matches[0]; minutesOffset = matches[1]; if (!minutesOffset && hoursOffset.length > 3) { valueIdx = hoursOffset.length - 2; minutesOffset = hoursOffset.substring(valueIdx); hoursOffset = hoursOffset.substring(0, valueIdx); } hoursOffset = parseInt(hoursOffset, 10); if (outOfRange(hoursOffset, -12, 13)) { return null; } if (count > 2) { minutesOffset = parseInt(minutesOffset, 10); if (isNaN(minutesOffset) || outOfRange(minutesOffset, 0, 59)) { return null; } } } else if (ch === '\'') { literal = true; checkLiteral(); } else if (!checkLiteral()) { return null; } } } hasTime = hours !== null || minutes !== null || seconds || null; if (year === null && month === null && day === null && hasTime) { year = defaultYear; month = date.getMonth(); day = date.getDate(); } else { if (year === null) { year = defaultYear; } if (day === null) { day = 1; } } if (pmHour && hours < 12) { hours += 12; } if (UTC) { if (hoursOffset) { hours += -hoursOffset; } if (minutesOffset) { minutes += -minutesOffset; } value = new Date(Date.UTC(year, month, day, hours, minutes, seconds, milliseconds)); } else { value = new Date(year, month, day, hours, minutes, seconds, milliseconds); adjustDST(value, hours); } if (year < 100) { value.setFullYear(year); } if (value.getDate() !== day && UTC === undefined) { return null; } return value; } function parseMicrosoftFormatOffset(offset) { var sign = offset.substr(0, 1) === '-' ? -1 : 1; offset = offset.substring(1); offset = parseInt(offset.substr(0, 2), 10) * 60 + parseInt(offset.substring(2), 10); return sign * offset; } function getDefaultFormats(culture) { var length = math.max(FORMATS_SEQUENCE.length, STANDARD_FORMATS.length); var patterns = culture.calendar.patterns; var cultureFormats, formatIdx, idx; var formats = []; for (idx = 0; idx < length; idx++) { cultureFormats = FORMATS_SEQUENCE[idx]; for (formatIdx = 0; formatIdx < cultureFormats.length; formatIdx++) { formats.push(patterns[cultureFormats[formatIdx]]); } formats = formats.concat(STANDARD_FORMATS[idx]); } return formats; } kendo.parseDate = function (value, formats, culture) { if (objectToString.call(value) === '[object Date]') { return value; } var idx = 0; var date = null; var length; var tzoffset; if (value && value.indexOf('/D') === 0) { date = dateRegExp.exec(value); if (date) { date = date[1]; tzoffset = offsetRegExp.exec(date.substring(1)); date = new Date(parseInt(date, 10)); if (tzoffset) { tzoffset = parseMicrosoftFormatOffset(tzoffset[0]); date = kendo.timezone.apply(date, 0); date = kendo.timezone.convert(date, 0, -1 * tzoffset); } return date; } } culture = kendo.getCulture(culture); if (!formats) { formats = getDefaultFormats(culture); } formats = isArray(formats) ? formats : [formats]; length = formats.length; for (; idx < length; idx++) { date = parseExact(value, formats[idx], culture); if (date) { return date; } } return date; }; kendo.parseInt = function (value, culture) { var result = kendo.parseFloat(value, culture); if (result) { result = result | 0; } return result; }; kendo.parseFloat = function (value, culture, format) { if (!value && value !== 0) { return null; } if (typeof value === NUMBER) { return value; } value = value.toString(); culture = kendo.getCulture(culture); var number = culture.numberFormat, percent = number.percent, currency = number.currency, symbol = currency.symbol, percentSymbol = percent.symbol, negative = value.indexOf('-'), parts, isPercent; if (exponentRegExp.test(value)) { value = parseFloat(value.replace(number['.'], '.')); if (isNaN(value)) { value = null; } return value; } if (negative > 0) { return null; } else { negative = negative > -1; } if (value.indexOf(symbol) > -1 || format && format.toLowerCase().indexOf('c') > -1) { number = currency; parts = number.pattern[0].replace('$', symbol).split('n'); if (value.indexOf(parts[0]) > -1 && value.indexOf(parts[1]) > -1) { value = value.replace(parts[0], '').replace(parts[1], ''); negative = true; } } else if (value.indexOf(percentSymbol) > -1) { isPercent = true; number = percent; symbol = percentSymbol; } value = value.replace('-', '').replace(symbol, '').replace(nonBreakingSpaceRegExp, ' ').split(number[','].replace(nonBreakingSpaceRegExp, ' ')).join('').replace(number['.'], '.'); value = parseFloat(value); if (isNaN(value)) { value = null; } else if (negative) { value *= -1; } if (value && isPercent) { value /= 100; } return value; }; }()); function getShadows(element) { var shadow = element.css(kendo.support.transitions.css + 'box-shadow') || element.css('box-shadow'), radius = shadow ? shadow.match(boxShadowRegExp) || [ 0, 0, 0, 0, 0 ] : [ 0, 0, 0, 0, 0 ], blur = math.max(+radius[3], +(radius[4] || 0)); return { left: -radius[1] + blur, right: +radius[1] + blur, bottom: +radius[2] + blur }; } function wrap(element, autosize) { var browser = support.browser, percentage, isRtl = element.css('direction') == 'rtl'; if (!element.parent().hasClass('k-animation-container')) { var shadows = getShadows(element), width = element[0].style.width, height = element[0].style.height, percentWidth = percentRegExp.test(width), percentHeight = percentRegExp.test(height); if (browser.opera) { shadows.left = shadows.right = shadows.bottom = 5; } percentage = percentWidth || percentHeight; if (!percentWidth && (!autosize || autosize && width)) { width = element.outerWidth(); } if (!percentHeight && (!autosize || autosize && height)) { height = element.outerHeight(); } element.wrap($('<div/>').addClass('k-animation-container').css({ width: width, height: height, marginLeft: shadows.left * (isRtl ? 1 : -1), paddingLeft: shadows.left, paddingRight: shadows.right, paddingBottom: shadows.bottom })); if (percentage) { element.css({ width: '100%', height: '100%', boxSizing: 'border-box', mozBoxSizing: 'border-box', webkitBoxSizing: 'border-box' }); } } else { var wrapper = element.parent('.k-animation-container'), wrapperStyle = wrapper[0].style; if (wrapper.is(':hidden')) { wrapper.show(); } percentage = percentRegExp.test(wrapperStyle.width) || percentRegExp.test(wrapperStyle.height); if (!percentage) { wrapper.css({ width: element.outerWidth(), height: element.outerHeight(), boxSizing: 'content-box', mozBoxSizing: 'content-box', webkitBoxSizing: 'content-box' }); } } if (browser.msie && math.floor(browser.version) <= 7) { element.css({ zoom: 1 }); element.children('.k-menu').width(element.width()); } return element.parent(); } function deepExtend(destination) { var i = 1, length = arguments.length; for (i = 1; i < length; i++) { deepExtendOne(destination, arguments[i]); } return destination; } function deepExtendOne(destination, source) { var ObservableArray = kendo.data.ObservableArray, LazyObservableArray = kendo.data.LazyObservableArray, DataSource = kendo.data.DataSource, HierarchicalDataSource = kendo.data.HierarchicalDataSource, property, propValue, propType, propInit, destProp; for (property in source) { propValue = source[property]; propType = typeof propValue; if (propType === OBJECT && propValue !== null) { propInit = propValue.constructor; } else { propInit = null; } if (propInit && propInit !== Array && propInit !== ObservableArray && propInit !== LazyObservableArray && propInit !== DataSource && propInit !== HierarchicalDataSource) { if (propValue instanceof Date) { destination[property] = new Date(propValue.getTime()); } else if (isFunction(propValue.clone)) { destination[property] = propValue.clone(); } else { destProp = destination[property]; if (typeof destProp === OBJECT) { destination[property] = destProp || {}; } else { destination[property] = {}; } deepExtendOne(destination[property], propValue); } } else if (propType !== UNDEFINED) { destination[property] = propValue; } } return destination; } function testRx(agent, rxs, dflt) { for (var rx in rxs) { if (rxs.hasOwnProperty(rx) && rxs[rx].test(agent)) { return rx; } } return dflt !== undefined ? dflt : agent; } function toHyphens(str) { return str.replace(/([a-z][A-Z])/g, function (g) { return g.charAt(0) + '-' + g.charAt(1).toLowerCase(); }); } function toCamelCase(str) { return str.replace(/\-(\w)/g, function (strMatch, g1) { return g1.toUpperCase(); }); } function getComputedStyles(element, properties) { var styles = {}, computedStyle; if (document.defaultView && document.defaultView.getComputedStyle) { computedStyle = document.defaultView.getComputedStyle(element, ''); if (properties) { $.each(properties, function (idx, value) { styles[value] = computedStyle.getPropertyValue(value); }); } } else { computedStyle = element.currentStyle; if (properties) { $.each(properties, function (idx, value) { styles[value] = computedStyle[toCamelCase(value)]; }); } } if (!kendo.size(styles)) { styles = computedStyle; } return styles; } function isScrollable(element) { if (element && element.className && typeof element.className === 'string' && element.className.indexOf('k-auto-scrollable') > -1) { return true; } var overflow = getComputedStyles(element, ['overflow']).overflow; return overflow == 'auto' || overflow == 'scroll'; } function scrollLeft(element, value) { var webkit = support.browser.webkit; var mozila = support.browser.mozilla; var el = element instanceof $ ? element[0] : element; var isRtl; if (!element) { return; } isRtl = support.isRtl(element); if (value !== undefined) { if (isRtl && webkit) { el.scrollLeft = el.scrollWidth - el.clientWidth - value; } else if (isRtl && mozila) { el.scrollLeft = -value; } else { el.scrollLeft = value; } } else { if (isRtl && webkit) { return el.scrollWidth - el.clientWidth - el.scrollLeft; } else { return Math.abs(el.scrollLeft); } } } (function () { support._scrollbar = undefined; support.scrollbar = function (refresh) { if (!isNaN(support._scrollbar) && !refresh) { return support._scrollbar; } else { var div = document.createElement('div'), result; div.style.cssText = 'overflow:scroll;overflow-x:hidden;zoom:1;clear:both;display:block'; div.innerHTML = ' '; document.body.appendChild(div); support._scrollbar = result = div.offsetWidth - div.scrollWidth; document.body.removeChild(div); return result; } }; support.isRtl = function (element) { return $(element).closest('.k-rtl').length > 0; }; var table = document.createElement('table'); try { table.innerHTML = '<tr><td></td></tr>'; support.tbodyInnerHtml = true; } catch (e) { support.tbodyInnerHtml = false; } support.touch = 'ontouchstart' in window; support.msPointers = window.MSPointerEvent; support.pointers = window.PointerEvent; var transitions = support.transitions = false, transforms = support.transforms = false, elementProto = 'HTMLElement' in window ? HTMLElement.prototype : []; support.hasHW3D = 'WebKitCSSMatrix' in window && 'm11' in new window.WebKitCSSMatrix() || 'MozPerspective' in document.documentElement.style || 'msPerspective' in document.documentElement.style; each([ 'Moz', 'webkit', 'O', 'ms' ], function () { var prefix = this.toString(), hasTransitions = typeof table.style[prefix + 'Transition'] === STRING; if (hasTransitions || typeof table.style[prefix + 'Transform'] === STRING) { var lowPrefix = prefix.toLowerCase(); transforms = { css: lowPrefix != 'ms' ? '-' + lowPrefix + '-' : '', prefix: prefix, event: lowPrefix === 'o' || lowPrefix === 'webkit' ? lowPrefix : '' }; if (hasTransitions) { transitions = transforms; transitions.event = transitions.event ? transitions.event + 'TransitionEnd' : 'transitionend'; } return false; } }); table = null; support.transforms = transforms; support.transitions = transitions; support.devicePixelRatio = window.devicePixelRatio === undefined ? 1 : window.devicePixelRatio; try { support.screenWidth = window.outerWidth || window.screen ? window.screen.availWidth : window.innerWidth; support.screenHeight = window.outerHeight || window.screen ? window.screen.availHeight : window.innerHeight; } catch (e) { support.screenWidth = window.screen.availWidth; support.screenHeight = window.screen.availHeight; } support.detectOS = function (ua) { var os = false, minorVersion, match = [], notAndroidPhone = !/mobile safari/i.test(ua), agentRxs = { wp: /(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/, fire: /(Silk)\/(\d+)\.(\d+(\.\d+)?)/, android: /(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.(\d+(\.\d+)?)/, iphone: /(iPhone|iPod).*OS\s+(\d+)[\._]([\d\._]+)/, ipad: /(iPad).*OS\s+(\d+)[\._]([\d_]+)/, meego: /(MeeGo).+NokiaBrowser\/(\d+)\.([\d\._]+)/, webos: /(webOS)\/(\d+)\.(\d+(\.\d+)?)/, blackberry: /(BlackBerry|BB10).*?Version\/(\d+)\.(\d+(\.\d+)?)/, playbook: /(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/, windows: /(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/, tizen: /(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i, sailfish: /(sailfish).*rv:(\d+)\.(\d+(\.\d+)?).*firefox/i, ffos: /(Mobile).*rv:(\d+)\.(\d+(\.\d+)?).*Firefox/ }, osRxs = { ios: /^i(phone|pad|pod)$/i, android: /^android|fire$/i, blackberry: /^blackberry|playbook/i, windows: /windows/, wp: /wp/, flat: /sailfish|ffos|tizen/i, meego: /meego/ }, formFactorRxs = { tablet: /playbook|ipad|fire/i }, browserRxs = { omini: /Opera\sMini/i, omobile: /Opera\sMobi/i, firefox: /Firefox|Fennec/i, mobilesafari: /version\/.*safari/i, ie: /MSIE|Windows\sPhone/i, chrome: /chrome|crios/i, webkit: /webkit/i }; for (var agent in agentRxs) { if (agentRxs.hasOwnProperty(agent)) { match = ua.match(agentRxs[agent]); if (match) { if (agent == 'windows' && 'plugins' in navigator) { return false; } os = {}; os.device = agent; os.tablet = testRx(agent, formFactorRxs, false); os.browser = testRx(ua, browserRxs, 'default'); os.name = testRx(agent, osRxs); os[os.name] = true; os.majorVersion = match[2]; os.minorVersion = match[3].replace('_', '.'); minorVersion = os.minorVersion.replace('.', '').substr(0, 2); os.flatVersion = os.majorVersion + minorVersion + new Array(3 - (minorVersion.length < 3 ? minorVersion.length : 2)).join('0'); os.cordova = typeof window.PhoneGap !== UNDEFINED || typeof window.cordova !== UNDEFINED; os.appMode = window.navigator.standalone || /file|local|wmapp/.test(window.location.protocol) || os.cordova; if (os.android && (support.devicePixelRatio < 1.5 && os.flatVersion < 400 || notAndroidPhone) && (support.screenWidth > 800 || support.screenHeight > 800)) { os.tablet = agent; } break; } } } return os; }; var mobileOS = support.mobileOS = support.detectOS(navigator.userAgent); support.wpDevicePixelRatio = mobileOS.wp ? screen.width / 320 : 0; support.kineticScrollNeeded = mobileOS && (support.touch || support.msPointers || support.pointers); support.hasNativeScrolling = false; if (mobileOS.ios || mobileOS.android && mobileOS.majorVersion > 2 || mobileOS.wp) { support.hasNativeScrolling = mobileOS; } support.delayedClick = function () { if (support.touch) { if (mobileOS.ios) { return true; } if (mobileOS.android) { if (!support.browser.chrome) { return true; } if (support.browser.version < 32) { return false; } return !($('meta[name=viewport]').attr('content') || '').match(/user-scalable=no/i); } } return false; }; support.mouseAndTouchPresent = support.touch && !(support.mobileOS.ios || support.mobileOS.android); support.detectBrowser = function (ua) { var browser = false, match = [], browserRxs = { edge: /(edge)[ \/]([\w.]+)/i, webkit: /(chrome)[ \/]([\w.]+)/i, safari: /(webkit)[ \/]([\w.]+)/i, opera: /(opera)(?:.*version|)[ \/]([\w.]+)/i, msie: /(msie\s|trident.*? rv:)([\w.]+)/i, mozilla: /(mozilla)(?:.*? rv:([\w.]+)|)/i }; for (var agent in browserRxs) { if (browserRxs.hasOwnProperty(agent)) { match = ua.match(browserRxs[agent]); if (match) { browser = {}; browser[agent] = true; browser[match[1].toLowerCase().split(' ')[0].split('/')[0]] = true; browser.version = parseInt(document.documentMode || match[2], 10); break; } } } return browser; }; support.browser = support.detectBrowser(navigator.userAgent); support.detectClipboardAccess = function () { var commands = { copy: document.queryCommandSupported ? document.queryCommandSupported('copy') : false, cut: document.queryCommandSupported ? document.queryCommandSupported('cut') : false, paste: document.queryCommandSupported ? document.queryCommandSupported('paste') : false }; if (support.browser.chrome) { commands.paste = false; if (support.browser.version >= 43) { commands.copy = true; commands.cut = true; } } return commands; }; support.clipboard = support.detectClipboardAccess(); support.zoomLevel = function () { try { var browser = support.browser; var ie11WidthCorrection = 0; var docEl = document.documentElement; if (browser.msie && browser.version == 11 && docEl.scrollHeight > docEl.clientHeight && !support.touch) { ie11WidthCorrection = support.scrollbar(); } return support.touch ? docEl.clientWidth / window.innerWidth : browser.msie && browser.version >= 10 ? ((top || window).document.documentElement.offsetWidth + ie11WidthCorrection) / (top || window).innerWidth : 1; } catch (e) { return 1; } }; support.cssBorderSpacing = typeof document.documentElement.style.borderSpacing != 'undefined' && !(support.browser.msie && support.browser.version < 8); (function (browser) { var cssClass = '', docElement = $(document.documentElement), majorVersion = parseInt(browser.version, 10); if (browser.msie) { cssClass = 'ie'; } else if (browser.mozilla) { cssClass = 'ff'; } else if (browser.safari) { cssClass = 'safari'; } else if (browser.webkit) { cssClass = 'webkit'; } else if (browser.opera) { cssClass = 'opera'; } else if (browser.edge) { cssClass = 'edge'; } if (cssClass) { cssClass = 'k-' + cssClass + ' k-' + cssClass + majorVersion; } if (support.mobileOS) { cssClass += ' k-mobile'; } docElement.addClass(cssClass); }(support.browser)); support.eventCapture = document.documentElement.addEventListener; var input = document.createElement('input'); support.placeholder = 'placeholder' in input; support.propertyChangeEvent = 'onpropertychange' in input; support.input = function () { var types = [ 'number', 'date', 'time', 'month', 'week', 'datetime', 'datetime-local' ]; var length = types.length; var value = 'test'; var result = {}; var idx = 0; var type; for (; idx < length; idx++) { type = types[idx]; input.setAttribute('type', type); input.value = value; result[type.replace('-', '')] = input.type !== 'text' && input.value !== value; } return result; }(); input.style.cssText = 'float:left;'; support.cssFloat = !!input.style.cssFloat; input = null; support.stableSort = function () { var threshold = 513; var sorted = [{ index: 0, field: 'b' }]; for (var i = 1; i < threshold; i++) { sorted.push({ index: i, field: 'a' }); } sorted.sort(function (a, b) { return a.field > b.field ? 1 : a.field < b.field ? -1 : 0; }); return sorted[0].index === 1; }(); support.matchesSelector = elementProto.webkitMatchesSelector || elementProto.mozMatchesSelector || elementProto.msMatchesSelector || elementProto.oMatchesSelector || elementProto.matchesSelector || elementProto.matches || function (selector) { var nodeList = document.querySelectorAll ? (this.parentNode || document).querySelectorAll(selector) || [] : $(selector), i = nodeList.length; while (i--) { if (nodeList[i] == this) { return true; } } return false; }; support.pushState = window.history && window.history.pushState; var documentMode = document.documentMode; support.hashChange = 'onhashchange' in window && !(support.browser.msie && (!documentMode || documentMode <= 8)); support.customElements = 'registerElement' in window.document; }()); function size(obj) { var result = 0, key; for (key in obj) { if (obj.hasOwnProperty(key) && key != 'toJSON') { result++; } } return result; } function getOffset(element, type, positioned) { if (!type) { type = 'offset'; } var result = element[type](); if (support.browser.msie && (support.pointers || support.msPointers) && !positioned) { result.top -= window.pageYOffset - document.documentElement.scrollTop; result.left -= window.pageXOffset - document.documentElement.scrollLeft; } return result; } var directions = { left: { reverse: 'right' }, right: { reverse: 'left' }, down: { reverse: 'up' }, up: { reverse: 'down' }, top: { reverse: 'bottom' }, bottom: { reverse: 'top' }, 'in': { reverse: 'out' }, out: { reverse: 'in' } }; function parseEffects(input) { var effects = {}; each(typeof input === 'string' ? input.split(' ') : input, function (idx) { effects[idx] = this; }); return effects; } function fx(element) { return new kendo.effects.Element(element); } var effects = {}; $.extend(effects, { enabled: true, Element: function (element) { this.element = $(element); }, promise: function (element, options) { if (!element.is(':visible')) { element.css({ display: element.data('olddisplay') || 'block' }).css('display'); } if (options.hide) { element.data('olddisplay', element.css('display')).hide(); } if (options.init) { options.init(); } if (options.completeCallback) { options.completeCallback(element); } element.dequeue(); }, disable: function () { this.enabled = false; this.promise = this.promiseShim; }, enable: function () { this.enabled = true; this.promise = this.animatedPromise; } }); effects.promiseShim = effects.promise; function prepareAnimationOptions(options, duration, reverse, complete) { if (typeof options === STRING) { if (isFunction(duration)) { complete = duration; duration = 400; reverse = false; } if (isFunction(reverse)) { complete = reverse; reverse = false; } if (typeof duration === BOOLEAN) { reverse = duration; duration = 400; } options = { effects: options, duration: duration, reverse: reverse, complete: complete }; } return extend({ effects: {}, duration: 400, reverse: false, init: noop, teardown: noop, hide: false }, options, { completeCallback: options.complete, complete: noop }); } function animate(element, options, duration, reverse, complete) { var idx = 0, length = element.length, instance; for (; idx < length; idx++) { instance = $(element[idx]); instance.queue(function () { effects.promise(instance, prepareAnimationOptions(options, duration, reverse, complete)); }); } return element; } function toggleClass(element, classes, options, add) { if (classes) { classes = classes.split(' '); each(classes, function (idx, value) { element.toggleClass(value, add); }); } return element; } if (!('kendoAnimate' in $.fn)) { extend($.fn, { kendoStop: function (clearQueue, gotoEnd) { return this.stop(clearQueue, gotoEnd); }, kendoAnimate: function (options, duration, reverse, complete) { return animate(this, options, duration, reverse, complete); }, kendoAddClass: function (classes, options) { return kendo.toggleClass(this, classes, options, true); }, kendoRemoveClass: function (classes, options) { return kendo.toggleClass(this, classes, options, false); }, kendoToggleClass: function (classes, options, toggle) { return kendo.toggleClass(this, classes, options, toggle); } }); } var ampRegExp = /&/g, ltRegExp = /</g, quoteRegExp = /"/g, aposRegExp = /'/g, gtRegExp = />/g; function htmlEncode(value) { return ('' + value).replace(ampRegExp, '&').replace(ltRegExp, '<').replace(gtRegExp, '>').replace(quoteRegExp, '"').replace(aposRegExp, '''); } var eventTarget = function (e) { return e.target; }; if (support.touch) { eventTarget = function (e) { var touches = 'originalEvent' in e ? e.originalEvent.changedTouches : 'changedTouches' in e ? e.changedTouches : null; return touches ? document.elementFromPoint(touches[0].clientX, touches[0].clientY) : e.target; }; each([ 'swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap' ], function (m, value) { $.fn[value] = function (callback) { return this.bind(value, callback); }; }); } if (support.touch) { if (!support.mobileOS) { support.mousedown = 'mousedown touchstart'; support.mouseup = 'mouseup touchend'; support.mousemove = 'mousemove touchmove'; support.mousecancel = 'mouseleave touchcancel'; support.click = 'click'; support.resize = 'resize'; } else { support.mousedown = 'touchstart'; support.mouseup = 'touchend'; support.mousemove = 'touchmove'; support.mousecancel = 'touchcancel'; support.click = 'touchend'; support.resize = 'orientationchange'; } } else if (support.pointers) { support.mousemove = 'pointermove'; support.mousedown = 'pointerdown'; support.mouseup = 'pointerup'; support.mousecancel = 'pointercancel'; support.click = 'pointerup'; support.resize = 'orientationchange resize'; } else if (support.msPointers) { support.mousemove = 'MSPointerMove'; support.mousedown = 'MSPointerDown'; support.mouseup = 'MSPointerUp'; support.mousecancel = 'MSPointerCancel'; support.click = 'MSPointerUp'; support.resize = 'orientationchange resize'; } else { support.mousemove = 'mousemove'; support.mousedown = 'mousedown'; support.mouseup = 'mouseup'; support.mousecancel = 'mouseleave'; support.click = 'click'; support.resize = 'resize'; } var wrapExpression = function (members, paramName) { var result = paramName || 'd', index, idx, length, member, count = 1; for (idx = 0, length = members.length; idx < length; idx++) { member = members[idx]; if (member !== '') { index = member.indexOf('['); if (index !== 0) { if (index == -1) { member = '.' + member; } else { count++; member = '.' + member.substring(0, index) + ' || {})' + member.substring(index); } } count++; result += member + (idx < length - 1 ? ' || {})' : ')'); } } return new Array(count).join('(') + result; }, localUrlRe = /^([a-z]+:)?\/\//i; extend(kendo, { widgets: [], _widgetRegisteredCallbacks: [], ui: kendo.ui || {}, fx: kendo.fx || fx, effects: kendo.effects || effects, mobile: kendo.mobile || {}, data: kendo.data || {}, dataviz: kendo.dataviz || {}, drawing: kendo.drawing || {}, spreadsheet: { messages: {} }, keys: { INSERT: 45, DELETE: 46, BACKSPACE: 8, TAB: 9, ENTER: 13, ESC: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, END: 35, HOME: 36, SPACEBAR: 32, PAGEUP: 33, PAGEDOWN: 34, F2: 113, F10: 121, F12: 123, NUMPAD_PLUS: 107, NUMPAD_MINUS: 109, NUMPAD_DOT: 110 }, support: kendo.support || support, animate: kendo.animate || animate, ns: '', attr: function (value) { return 'data-' + kendo.ns + value; }, getShadows: getShadows, wrap: wrap, deepExtend: deepExtend, getComputedStyles: getComputedStyles, webComponents: kendo.webComponents || [], isScrollable: isScrollable, scrollLeft: scrollLeft, size: size, toCamelCase: toCamelCase, toHyphens: toHyphens, getOffset: kendo.getOffset || getOffset, parseEffects: kendo.parseEffects || parseEffects, toggleClass: kendo.toggleClass || toggleClass, directions: kendo.directions || directions, Observable: Observable, Class: Class, Template: Template, template: proxy(Template.compile, Template), render: proxy(Template.render, Template), stringify: proxy(JSON.stringify, JSON), eventTarget: eventTarget, htmlEncode: htmlEncode, isLocalUrl: function (url) { return url && !localUrlRe.test(url); }, expr: function (expression, safe, paramName) { expression = expression || ''; if (typeof safe == STRING) { paramName = safe; safe = false; } paramName = paramName || 'd'; if (expression && expression.charAt(0) !== '[') { expression = '.' + expression; } if (safe) { expression = expression.replace(/"([^.]*)\.([^"]*)"/g, '"$1_$DOT$_$2"'); expression = expression.replace(/'([^.]*)\.([^']*)'/g, '\'$1_$DOT$_$2\''); expression = wrapExpression(expression.split('.'), paramName); expression = expression.replace(/_\$DOT\$_/g, '.'); } else { expression = paramName + expression; } return expression; }, getter: function (expression, safe) { var key = expression + safe; return getterCache[key] = getterCache[key] || new Function('d', 'return ' + kendo.expr(expression, safe)); }, setter: function (expression) { return setterCache[expression] = setterCache[expression] || new Function('d,value', kendo.expr(expression) + '=value'); }, accessor: function (expression) { return { get: kendo.getter(expression), set: kendo.setter(expression) }; }, guid: function () { var id = '', i, random; for (i = 0; i < 32; i++) { random = math.random() * 16 | 0; if (i == 8 || i == 12 || i == 16 || i == 20) { id += '-'; } id += (i == 12 ? 4 : i == 16 ? random & 3 | 8 : random).toString(16); } return id; }, roleSelector: function (role) { return role.replace(/(\S+)/g, '[' + kendo.attr('role') + '=$1],').slice(0, -1); }, directiveSelector: function (directives) { var selectors = directives.split(' '); if (selectors) { for (var i = 0; i < selectors.length; i++) { if (selectors[i] != 'view') { selectors[i] = selectors[i].replace(/(\w*)(view|bar|strip|over)$/, '$1-$2'); } } } return selectors.join(' ').replace(/(\S+)/g, 'kendo-mobile-$1,').slice(0, -1); }, triggeredByInput: function (e) { return /^(label|input|textarea|select)$/i.test(e.target.tagName); }, onWidgetRegistered: function (callback) { for (var i = 0, len = kendo.widgets.length; i < len; i++) { callback(kendo.widgets[i]); } kendo._widgetRegisteredCallbacks.push(callback); }, logToConsole: function (message, type) { var console = window.console; if (!kendo.suppressLog && typeof console != 'undefined' && console.log) { console[type || 'log'](message); } } }); var Widget = Observable.extend({ init: function (element, options) { var that = this; that.element = kendo.jQuery(element).handler(that); that.angular('init', options); Observable.fn.init.call(that); var dataSource = options ? options.dataSource : null; if (dataSource) { options = extend({}, options, { dataSource: {} }); } options = that.options = extend(true, {}, that.options, options); if (dataSource) { options.dataSource = dataSource; } if (!that.element.attr(kendo.attr('role'))) { that.element.attr(kendo.attr('role'), (options.name || '').toLowerCase()); } that.element.data('kendo' + options.prefix + options.name, that); that.bind(that.events, options); }, events: [], options: { prefix: '' }, _hasBindingTarget: function () { return !!this.element[0].kendoBindingTarget; }, _tabindex: function (target) { target = target || this.wrapper; var element = this.element, TABINDEX = 'tabindex', tabindex = target.attr(TABINDEX) || element.attr(TABINDEX); element.removeAttr(TABINDEX); target.attr(TABINDEX, !isNaN(tabindex) ? tabindex : 0); }, setOptions: function (options) { this._setEvents(options); $.extend(this.options, options); }, _setEvents: function (options) { var that = this, idx = 0, length = that.events.length, e; for (; idx < length; idx++) { e = that.events[idx]; if (that.options[e] && options[e]) { that.unbind(e, that.options[e]); } } that.bind(that.events, options); }, resize: function (force) { var size = this.getSize(), currentSize = this._size; if (force || (size.width > 0 || size.height > 0) && (!currentSize || size.width !== currentSize.width || size.height !== currentSize.height)) { this._size = size; this._resize(size, force); this.trigger('resize', size); } }, getSize: function () { return kendo.dimensions(this.element); }, size: function (size) { if (!size) { return this.getSize(); } else { this.setSize(size); } }, setSize: $.noop, _resize: $.noop, destroy: function () { var that = this; that.element.removeData('kendo' + that.options.prefix + that.options.name); that.element.removeData('handler'); that.unbind(); }, _destroy: function () { this.destroy(); }, angular: function () { }, _muteAngularRebind: function (callback) { this._muteRebind = true; callback.call(this); this._muteRebind = false; } }); var DataBoundWidget = Widget.extend({ dataItems: function () { return this.dataSource.flatView(); }, _angularItems: function (cmd) { var that = this; that.angular(cmd, function () { return { elements: that.items(), data: $.map(that.dataItems(), function (dataItem) { return { dataItem: dataItem }; }) }; }); } }); kendo.dimensions = function (element, dimensions) { var domElement = element[0]; if (dimensions) { element.css(dimensions); } return { width: domElement.offsetWidth, height: domElement.offsetHeight }; }; kendo.notify = noop; var templateRegExp = /template$/i, jsonRegExp = /^\s*(?:\{(?:.|\r\n|\n)*\}|\[(?:.|\r\n|\n)*\])\s*$/, jsonFormatRegExp = /^\{(\d+)(:[^\}]+)?\}|^\[[A-Za-z_]*\]$/, dashRegExp = /([A-Z])/g; function parseOption(element, option) { var value; if (option.indexOf('data') === 0) { option = option.substring(4); option = option.charAt(0).toLowerCase() + option.substring(1); } option = option.replace(dashRegExp, '-$1'); value = element.getAttribute('data-' + kendo.ns + option); if (value === null) { value = undefined; } else if (value === 'null') { value = null; } else if (value === 'true') { value = true; } else if (value === 'false') { value = false; } else if (numberRegExp.test(value)) { value = parseFloat(value); } else if (jsonRegExp.test(value) && !jsonFormatRegExp.test(value)) { value = new Function('return (' + value + ')')(); } return value; } function parseOptions(element, options) { var result = {}, option, value; for (option in options) { value = parseOption(element, option); if (value !== undefined) { if (templateRegExp.test(option)) { value = kendo.template($('#' + value).html()); } result[option] = value; } } return result; } kendo.initWidget = function (element, options, roles) { var result, option, widget, idx, length, role, value, dataSource, fullPath, widgetKeyRegExp; if (!roles) { roles = kendo.ui.roles; } else if (roles.roles) { roles = roles.roles; } element = element.nodeType ? element : element[0]; role = element.getAttribute('data-' + kendo.ns + 'role'); if (!role) { return; } fullPath = role.indexOf('.') === -1; if (fullPath) { widget = roles[role]; } else { widget = kendo.getter(role)(window); } var data = $(element).data(), widgetKey = widget ? 'kendo' + widget.fn.options.prefix + widget.fn.options.name : ''; if (fullPath) { widgetKeyRegExp = new RegExp('^kendo.*' + role + '$', 'i'); } else { widgetKeyRegExp = new RegExp('^' + widgetKey + '$', 'i'); } for (var key in data) { if (key.match(widgetKeyRegExp)) { if (key === widgetKey) { result = data[key]; } else { return data[key]; } } } if (!widget) { return; } dataSource = parseOption(element, 'dataSource'); options = $.extend({}, parseOptions(element, widget.fn.options), options); if (dataSource) { if (typeof dataSource === STRING) { options.dataSource = kendo.getter(dataSource)(window); } else { options.dataSource = dataSource; } } for (idx = 0, length = widget.fn.events.length; idx < length; idx++) { option = widget.fn.events[idx]; value = parseOption(element, option); if (value !== undefined) { options[option] = kendo.getter(value)(window); } } if (!result) { result = new widget(element, options); } else if (!$.isEmptyObject(options)) { result.setOptions(options); } return result; }; kendo.rolesFromNamespaces = function (namespaces) { var roles = [], idx, length; if (!namespaces[0]) { namespaces = [ kendo.ui, kendo.dataviz.ui ]; } for (idx = 0, length = namespaces.length; idx < length; idx++) { roles[idx] = namespaces[idx].roles; } return extend.apply(null, [{}].concat(roles.reverse())); }; kendo.init = function (element) { var roles = kendo.rolesFromNamespaces(slice.call(arguments, 1)); $(element).find('[data-' + kendo.ns + 'role]').addBack().each(function () { kendo.initWidget(this, {}, roles); }); }; kendo.destroy = function (element) { $(element).find('[data-' + kendo.ns + 'role]').addBack().each(function () { var data = $(this).data(); for (var key in data) { if (key.indexOf('kendo') === 0 && typeof data[key].destroy === FUNCTION) { data[key].destroy(); } } }); }; function containmentComparer(a, b) { return $.contains(a, b) ? -1 : 1; } function resizableWidget() { var widget = $(this); return $.inArray(widget.attr('data-' + kendo.ns + 'role'), [ 'slider', 'rangeslider' ]) > -1 || widget.is(':visible'); } kendo.resize = function (element, force) { var widgets = $(element).find('[data-' + kendo.ns + 'role]').addBack().filter(resizableWidget); if (!widgets.length) { return; } var widgetsArray = $.makeArray(widgets); widgetsArray.sort(containmentComparer); $.each(widgetsArray, function () { var widget = kendo.widgetInstance($(this)); if (widget) { widget.resize(force); } }); }; kendo.parseOptions = parseOptions; extend(kendo.ui, { Widget: Widget, DataBoundWidget: DataBoundWidget, roles: {}, progress: function (container, toggle) { var mask = container.find('.k-loading-mask'), support = kendo.support, browser = support.browser, isRtl, leftRight, webkitCorrection, containerScrollLeft; if (toggle) { if (!mask.length) { isRtl = support.isRtl(container); leftRight = isRtl ? 'right' : 'left'; containerScrollLeft = container.scrollLeft(); webkitCorrection = browser.webkit ? !isRtl ? 0 : container[0].scrollWidth - container.width() - 2 * containerScrollLeft : 0; mask = $('<div class=\'k-loading-mask\'><span class=\'k-loading-text\'>' + kendo.ui.progress.messages.loading + '</span><div class=\'k-loading-image\'/><div class=\'k-loading-color\'/></div>').width('100%').height('100%').css('top', container.scrollTop()).css(leftRight, Math.abs(containerScrollLeft) + webkitCorrection).prependTo(container); } } else if (mask) { mask.remove(); } }, plugin: function (widget, register, prefix) { var name = widget.fn.options.name, getter; register = register || kendo.ui; prefix = prefix || ''; register[name] = widget; register.roles[name.toLowerCase()] = widget; getter = 'getKendo' + prefix + name; name = 'kendo' + prefix + name; var widgetEntry = { name: name, widget: widget, prefix: prefix || '' }; kendo.widgets.push(widgetEntry); for (var i = 0, len = kendo._widgetRegisteredCallbacks.length; i < len; i++) { kendo._widgetRegisteredCallbacks[i](widgetEntry); } $.fn[name] = function (options) { var value = this, args; if (typeof options === STRING) { args = slice.call(arguments, 1); this.each(function () { var widget = $.data(this, name), method, result; if (!widget) { throw new Error(kendo.format('Cannot call method \'{0}\' of {1} before it is initialized', options, name)); } method = widget[options]; if (typeof method !== FUNCTION) { throw new Error(kendo.format('Cannot find method \'{0}\' of {1}', options, name)); } result = method.apply(widget, args); if (result !== undefined) { value = result; return false; } }); } else { this.each(function () { return new widget(this, options); }); } return value; }; $.fn[name].widget = widget; $.fn[getter] = function () { return this.data(name); }; } }); kendo.ui.progress.messages = { loading: 'Loading...' }; var ContainerNullObject = { bind: function () { return this; }, nullObject: true, options: {} }; var MobileWidget = Widget.extend({ init: function (element, options) { Widget.fn.init.call(this, element, options); this.element.autoApplyNS(); this.wrapper = this.element; this.element.addClass('km-widget'); }, destroy: function () { Widget.fn.destroy.call(this); this.element.kendoDestroy(); }, options: { prefix: 'Mobile' }, events: [], view: function () { var viewElement = this.element.closest(kendo.roleSelector('view splitview modalview drawer')); return kendo.widgetInstance(viewElement, kendo.mobile.ui) || ContainerNullObject; }, viewHasNativeScrolling: function () { var view = this.view(); return view && view.options.useNativeScrolling; }, container: function () { var element = this.element.closest(kendo.roleSelector('view layout modalview drawer splitview')); return kendo.widgetInstance(element.eq(0), kendo.mobile.ui) || ContainerNullObject; } }); extend(kendo.mobile, { init: function (element) { kendo.init(element, kendo.mobile.ui, kendo.ui, kendo.dataviz.ui); }, appLevelNativeScrolling: function () { return kendo.mobile.application && kendo.mobile.application.options && kendo.mobile.application.options.useNativeScrolling; }, roles: {}, ui: { Widget: MobileWidget, DataBoundWidget: DataBoundWidget.extend(MobileWidget.prototype), roles: {}, plugin: function (widget) { kendo.ui.plugin(widget, kendo.mobile.ui, 'Mobile'); } } }); deepExtend(kendo.dataviz, { init: function (element) { kendo.init(element, kendo.dataviz.ui); }, ui: { roles: {}, themes: {}, views: [], plugin: function (widget) { kendo.ui.plugin(widget, kendo.dataviz.ui); } }, roles: {} }); kendo.touchScroller = function (elements, options) { if (!options) { options = {}; } options.useNative = true; return $(elements).map(function (idx, element) { element = $(element); if (support.kineticScrollNeeded && kendo.mobile.ui.Scroller && !element.data('kendoMobileScroller')) { element.kendoMobileScroller(options); return element.data('kendoMobileScroller'); } else { return false; } })[0]; }; kendo.preventDefault = function (e) { e.preventDefault(); }; kendo.widgetInstance = function (element, suites) { var role = element.data(kendo.ns + 'role'), widgets = [], i, length; if (role) { if (role === 'content') { role = 'scroller'; } if (suites) { if (suites[0]) { for (i = 0, length = suites.length; i < length; i++) { widgets.push(suites[i].roles[role]); } } else { widgets.push(suites.roles[role]); } } else { widgets = [ kendo.ui.roles[role], kendo.dataviz.ui.roles[role], kendo.mobile.ui.roles[role] ]; } if (role.indexOf('.') >= 0) { widgets = [kendo.getter(role)(window)]; } for (i = 0, length = widgets.length; i < length; i++) { var widget = widgets[i]; if (widget) { var instance = element.data('kendo' + widget.fn.options.prefix + widget.fn.options.name); if (instance) { return instance; } } } } }; kendo.onResize = function (callback) { var handler = callback; if (support.mobileOS.android) { handler = function () { setTimeout(callback, 600); }; } $(window).on(support.resize, handler); return handler; }; kendo.unbindResize = function (callback) { $(window).off(support.resize, callback); }; kendo.attrValue = function (element, key) { return element.data(kendo.ns + key); }; kendo.days = { Sunday: 0, Monday: 1, Tuesday: 2, Wednesday: 3, Thursday: 4, Friday: 5, Saturday: 6 }; function focusable(element, isTabIndexNotNaN) { var nodeName = element.nodeName.toLowerCase(); return (/input|select|textarea|button|object/.test(nodeName) ? !element.disabled : 'a' === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) && visible(element); } function visible(element) { return $.expr.filters.visible(element) && !$(element).parents().addBack().filter(function () { return $.css(this, 'visibility') === 'hidden'; }).length; } $.extend($.expr[':'], { kendoFocusable: function (element) { var idx = $.attr(element, 'tabindex'); return focusable(element, !isNaN(idx) && idx > -1); } }); var MOUSE_EVENTS = [ 'mousedown', 'mousemove', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'mouseup', 'click' ]; var EXCLUDE_BUST_CLICK_SELECTOR = 'label, input, [data-rel=external]'; var MouseEventNormalizer = { setupMouseMute: function () { var idx = 0, length = MOUSE_EVENTS.length, element = document.documentElement; if (MouseEventNormalizer.mouseTrap || !support.eventCapture) { return; } MouseEventNormalizer.mouseTrap = true; MouseEventNormalizer.bustClick = false; MouseEventNormalizer.captureMouse = false; var handler = function (e) { if (MouseEventNormalizer.captureMouse) { if (e.type === 'click') { if (MouseEventNormalizer.bustClick && !$(e.target).is(EXCLUDE_BUST_CLICK_SELECTOR)) { e.preventDefault(); e.stopPropagation(); } } else { e.stopPropagation(); } } }; for (; idx < length; idx++) { element.addEventListener(MOUSE_EVENTS[idx], handler, true); } }, muteMouse: function (e) { MouseEventNormalizer.captureMouse = true; if (e.data.bustClick) { MouseEventNormalizer.bustClick = true; } clearTimeout(MouseEventNormalizer.mouseTrapTimeoutID); }, unMuteMouse: function () { clearTimeout(MouseEventNormalizer.mouseTrapTimeoutID); MouseEventNormalizer.mouseTrapTimeoutID = setTimeout(function () { MouseEventNormalizer.captureMouse = false; MouseEventNormalizer.bustClick = false; }, 400); } }; var eventMap = { down: 'touchstart mousedown', move: 'mousemove touchmove', up: 'mouseup touchend touchcancel', cancel: 'mouseleave touchcancel' }; if (support.touch && (support.mobileOS.ios || support.mobileOS.android)) { eventMap = { down: 'touchstart', move: 'touchmove', up: 'touchend touchcancel', cancel: 'touchcancel' }; } else if (support.pointers) { eventMap = { down: 'pointerdown', move: 'pointermove', up: 'pointerup', cancel: 'pointercancel pointerleave' }; } else if (support.msPointers) { eventMap = { down: 'MSPointerDown', move: 'MSPointerMove', up: 'MSPointerUp', cancel: 'MSPointerCancel MSPointerLeave' }; } if (support.msPointers && !('onmspointerenter' in window)) { $.each({ MSPointerEnter: 'MSPointerOver', MSPointerLeave: 'MSPointerOut' }, function (orig, fix) { $.event.special[orig] = { delegateType: fix, bindType: fix, handle: function (event) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; if (!related || related !== target && !$.contains(target, related)) { event.type = handleObj.origType; ret = handleObj.handler.apply(this, arguments); event.type = fix; } return ret; } }; }); } var getEventMap = function (e) { return eventMap[e] || e; }, eventRegEx = /([^ ]+)/g; kendo.applyEventMap = function (events, ns) { events = events.replace(eventRegEx, getEventMap); if (ns) { events = events.replace(eventRegEx, '$1.' + ns); } return events; }; var on = $.fn.on; function kendoJQuery(selector, context) { return new kendoJQuery.fn.init(selector, context); } extend(true, kendoJQuery, $); kendoJQuery.fn = kendoJQuery.prototype = new $(); kendoJQuery.fn.constructor = kendoJQuery; kendoJQuery.fn.init = function (selector, context) { if (context && context instanceof $ && !(context instanceof kendoJQuery)) { context = kendoJQuery(context); } return $.fn.init.call(this, selector, context, rootjQuery); }; kendoJQuery.fn.init.prototype = kendoJQuery.fn; var rootjQuery = kendoJQuery(document); extend(kendoJQuery.fn, { handler: function (handler) { this.data('handler', handler); return this; }, autoApplyNS: function (ns) { this.data('kendoNS', ns || kendo.guid()); return this; }, on: function () { var that = this, ns = that.data('kendoNS'); if (arguments.length === 1) { return on.call(that, arguments[0]); } var context = that, args = slice.call(arguments); if (typeof args[args.length - 1] === UNDEFINED) { args.pop(); } var callback = args[args.length - 1], events = kendo.applyEventMap(args[0], ns); if (support.mouseAndTouchPresent && events.search(/mouse|click/) > -1 && this[0] !== document.documentElement) { MouseEventNormalizer.setupMouseMute(); var selector = args.length === 2 ? null : args[1], bustClick = events.indexOf('click') > -1 && events.indexOf('touchend') > -1; on.call(this, { touchstart: MouseEventNormalizer.muteMouse, touchend: MouseEventNormalizer.unMuteMouse }, selector, { bustClick: bustClick }); } if (typeof callback === STRING) { context = that.data('handler'); callback = context[callback]; args[args.length - 1] = function (e) { callback.call(context, e); }; } args[0] = events; on.apply(that, args); return that; }, kendoDestroy: function (ns) { ns = ns || this.data('kendoNS'); if (ns) { this.off('.' + ns); } return this; } }); kendo.jQuery = kendoJQuery; kendo.eventMap = eventMap; kendo.timezone = function () { var months = { Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 }; var days = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 }; function ruleToDate(year, rule) { var date; var targetDay; var ourDay; var month = rule[3]; var on = rule[4]; var time = rule[5]; var cache = rule[8]; if (!cache) { rule[8] = cache = {}; } if (cache[year]) { return cache[year]; } if (!isNaN(on)) { date = new Date(Date.UTC(year, months[month], on, time[0], time[1], time[2], 0)); } else if (on.indexOf('last') === 0) { date = new Date(Date.UTC(year, months[month] + 1, 1, time[0] - 24, time[1], time[2], 0)); targetDay = days[on.substr(4, 3)]; ourDay = date.getUTCDay(); date.setUTCDate(date.getUTCDate() + targetDay - ourDay - (targetDay > ourDay ? 7 : 0)); } else if (on.indexOf('>=') >= 0) { date = new Date(Date.UTC(year, months[month], on.substr(5), time[0], time[1], time[2], 0)); targetDay = days[on.substr(0, 3)]; ourDay = date.getUTCDay(); date.setUTCDate(date.getUTCDate() + targetDay - ourDay + (targetDay < ourDay ? 7 : 0)); } return cache[year] = date; } function findRule(utcTime, rules, zone) { rules = rules[zone]; if (!rules) { var time = zone.split(':'); var offset = 0; if (time.length > 1) { offset = time[0] * 60 + Number(time[1]); } return [ -1000000, 'max', '-', 'Jan', 1, [ 0, 0, 0 ], offset, '-' ]; } var year = new Date(utcTime).getUTCFullYear(); rules = jQuery.grep(rules, function (rule) { var from = rule[0]; var to = rule[1]; return from <= year && (to >= year || from == year && to == 'only' || to == 'max'); }); rules.push(utcTime); rules.sort(function (a, b) { if (typeof a != 'number') { a = Number(ruleToDate(year, a)); } if (typeof b != 'number') { b = Number(ruleToDate(year, b)); } return a - b; }); var rule = rules[jQuery.inArray(utcTime, rules) - 1] || rules[rules.length - 1]; return isNaN(rule) ? rule : null; } function findZone(utcTime, zones, timezone) { var zoneRules = zones[timezone]; if (typeof zoneRules === 'string') { zoneRules = zones[zoneRules]; } if (!zoneRules) { throw new Error('Timezone "' + timezone + '" is either incorrect, or kendo.timezones.min.js is not included.'); } for (var idx = zoneRules.length - 1; idx >= 0; idx--) { var until = zoneRules[idx][3]; if (until && utcTime > until) { break; } } var zone = zoneRules[idx + 1]; if (!zone) { throw new Error('Timezone "' + timezone + '" not found on ' + utcTime + '.'); } return zone; } function zoneAndRule(utcTime, zones, rules, timezone) { if (typeof utcTime != NUMBER) { utcTime = Date.UTC(utcTime.getFullYear(), utcTime.getMonth(), utcTime.getDate(), utcTime.getHours(), utcTime.getMinutes(), utcTime.getSeconds(), utcTime.getMilliseconds()); } var zone = findZone(utcTime, zones, timezone); return { zone: zone, rule: findRule(utcTime, rules, zone[1]) }; } function offset(utcTime, timezone) { if (timezone == 'Etc/UTC' || timezone == 'Etc/GMT') { return 0; } var info = zoneAndRule(utcTime, this.zones, this.rules, timezone); var zone = info.zone; var rule = info.rule; return kendo.parseFloat(rule ? zone[0] - rule[6] : zone[0]); } function abbr(utcTime, timezone) { var info = zoneAndRule(utcTime, this.zones, this.rules, timezone); var zone = info.zone; var rule = info.rule; var base = zone[2]; if (base.indexOf('/') >= 0) { return base.split('/')[rule && +rule[6] ? 1 : 0]; } else if (base.indexOf('%s') >= 0) { return base.replace('%s', !rule || rule[7] == '-' ? '' : rule[7]); } return base; } function convert(date, fromOffset, toOffset) { if (typeof fromOffset == STRING) { fromOffset = this.offset(date, fromOffset); } if (typeof toOffset == STRING) { toOffset = this.offset(date, toOffset); } var fromLocalOffset = date.getTimezoneOffset(); date = new Date(date.getTime() + (fromOffset - toOffset) * 60000); var toLocalOffset = date.getTimezoneOffset(); return new Date(date.getTime() + (toLocalOffset - fromLocalOffset) * 60000); } function apply(date, timezone) { return this.convert(date, date.getTimezoneOffset(), timezone); } function remove(date, timezone) { return this.convert(date, timezone, date.getTimezoneOffset()); } function toLocalDate(time) { return this.apply(new Date(time), 'Etc/UTC'); } return { zones: {}, rules: {}, offset: offset, convert: convert, apply: apply, remove: remove, abbr: abbr, toLocalDate: toLocalDate }; }(); kendo.date = function () { var MS_PER_MINUTE = 60000, MS_PER_DAY = 86400000; function adjustDST(date, hours) { if (hours === 0 && date.getHours() === 23) { date.setHours(date.getHours() + 2); return true; } return false; } function setDayOfWeek(date, day, dir) { var hours = date.getHours(); dir = dir || 1; day = (day - date.getDay() + 7 * dir) % 7; date.setDate(date.getDate() + day); adjustDST(date, hours); } function dayOfWeek(date, day, dir) { date = new Date(date); setDayOfWeek(date, day, dir); return date; } function firstDayOfMonth(date) { return new Date(date.getFullYear(), date.getMonth(), 1); } function lastDayOfMonth(date) { var last = new Date(date.getFullYear(), date.getMonth() + 1, 0), first = firstDayOfMonth(date), timeOffset = Math.abs(last.getTimezoneOffset() - first.getTimezoneOffset()); if (timeOffset) { last.setHours(first.getHours() + timeOffset / 60); } return last; } function getDate(date) { date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); adjustDST(date, 0); return date; } function toUtcTime(date) { return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); } function getMilliseconds(date) { return date.getTime() - getDate(date); } function isInTimeRange(value, min, max) { var msMin = getMilliseconds(min), msMax = getMilliseconds(max), msValue; if (!value || msMin == msMax) { return true; } if (min >= max) { max += MS_PER_DAY; } msValue = getMilliseconds(value); if (msMin > msValue) { msValue += MS_PER_DAY; } if (msMax < msMin) { msMax += MS_PER_DAY; } return msValue >= msMin && msValue <= msMax; } function isInDateRange(value, min, max) { var msMin = min.getTime(), msMax = max.getTime(), msValue; if (msMin >= msMax) { msMax += MS_PER_DAY; } msValue = value.getTime(); return msValue >= msMin && msValue <= msMax; } function addDays(date, offset) { var hours = date.getHours(); date = new Date(date); setTime(date, offset * MS_PER_DAY); adjustDST(date, hours); return date; } function setTime(date, milliseconds, ignoreDST) { var offset = date.getTimezoneOffset(); var difference; date.setTime(date.getTime() + milliseconds); if (!ignoreDST) { difference = date.getTimezoneOffset() - offset; date.setTime(date.getTime() + difference * MS_PER_MINUTE); } } function setHours(date, time) { date = new Date(kendo.date.getDate(date).getTime() + kendo.date.getMilliseconds(time)); adjustDST(date, time.getHours()); return date; } function today() { return getDate(new Date()); } function isToday(date) { return getDate(date).getTime() == today().getTime(); } function toInvariantTime(date) { var staticDate = new Date(1980, 1, 1, 0, 0, 0); if (date) { staticDate.setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); } return staticDate; } return { adjustDST: adjustDST, dayOfWeek: dayOfWeek, setDayOfWeek: setDayOfWeek, getDate: getDate, isInDateRange: isInDateRange, isInTimeRange: isInTimeRange, isToday: isToday, nextDay: function (date) { return addDays(date, 1); }, previousDay: function (date) { return addDays(date, -1); }, toUtcTime: toUtcTime, MS_PER_DAY: MS_PER_DAY, MS_PER_HOUR: 60 * MS_PER_MINUTE, MS_PER_MINUTE: MS_PER_MINUTE, setTime: setTime, setHours: setHours, addDays: addDays, today: today, toInvariantTime: toInvariantTime, firstDayOfMonth: firstDayOfMonth, lastDayOfMonth: lastDayOfMonth, getMilliseconds: getMilliseconds }; }(); kendo.stripWhitespace = function (element) { if (document.createNodeIterator) { var iterator = document.createNodeIterator(element, NodeFilter.SHOW_TEXT, function (node) { return node.parentNode == element ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; }, false); while (iterator.nextNode()) { if (iterator.referenceNode && !iterator.referenceNode.textContent.trim()) { iterator.referenceNode.parentNode.removeChild(iterator.referenceNode); } } } else { for (var i = 0; i < element.childNodes.length; i++) { var child = element.childNodes[i]; if (child.nodeType == 3 && !/\S/.test(child.nodeValue)) { element.removeChild(child); i--; } if (child.nodeType == 1) { kendo.stripWhitespace(child); } } } }; var animationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { setTimeout(callback, 1000 / 60); }; kendo.animationFrame = function (callback) { animationFrame.call(window, callback); }; var animationQueue = []; kendo.queueAnimation = function (callback) { animationQueue[animationQueue.length] = callback; if (animationQueue.length === 1) { kendo.runNextAnimation(); } }; kendo.runNextAnimation = function () { kendo.animationFrame(function () { if (animationQueue[0]) { animationQueue.shift()(); if (animationQueue[0]) { kendo.runNextAnimation(); } } }); }; kendo.parseQueryStringParams = function (url) { var queryString = url.split('?')[1] || '', params = {}, paramParts = queryString.split(/&|=/), length = paramParts.length, idx = 0; for (; idx < length; idx += 2) { if (paramParts[idx] !== '') { params[decodeURIComponent(paramParts[idx])] = decodeURIComponent(paramParts[idx + 1]); } } return params; }; kendo.elementUnderCursor = function (e) { if (typeof e.x.client != 'undefined') { return document.elementFromPoint(e.x.client, e.y.client); } }; kendo.wheelDeltaY = function (jQueryEvent) { var e = jQueryEvent.originalEvent, deltaY = e.wheelDeltaY, delta; if (e.wheelDelta) { if (deltaY === undefined || deltaY) { delta = e.wheelDelta; } } else if (e.detail && e.axis === e.VERTICAL_AXIS) { delta = -e.detail * 10; } return delta; }; kendo.throttle = function (fn, delay) { var timeout; var lastExecTime = 0; if (!delay || delay <= 0) { return fn; } var throttled = function () { var that = this; var elapsed = +new Date() - lastExecTime; var args = arguments; function exec() { fn.apply(that, args); lastExecTime = +new Date(); } if (!lastExecTime) { return exec(); } if (timeout) { clearTimeout(timeout); } if (elapsed > delay) { exec(); } else { timeout = setTimeout(exec, delay - elapsed); } }; throttled.cancel = function () { clearTimeout(timeout); }; return throttled; }; kendo.caret = function (element, start, end) { var rangeElement; var isPosition = start !== undefined; if (end === undefined) { end = start; } if (element[0]) { element = element[0]; } if (isPosition && element.disabled) { return; } try { if (element.selectionStart !== undefined) { if (isPosition) { element.focus(); element.setSelectionRange(start, end); } else { start = [ element.selectionStart, element.selectionEnd ]; } } else if (document.selection) { if ($(element).is(':visible')) { element.focus(); } rangeElement = element.createTextRange(); if (isPosition) { rangeElement.collapse(true); rangeElement.moveStart('character', start); rangeElement.moveEnd('character', end - start); rangeElement.select(); } else { var rangeDuplicated = rangeElement.duplicate(), selectionStart, selectionEnd; rangeElement.moveToBookmark(document.selection.createRange().getBookmark()); rangeDuplicated.setEndPoint('EndToStart', rangeElement); selectionStart = rangeDuplicated.text.length; selectionEnd = selectionStart + rangeElement.text.length; start = [ selectionStart, selectionEnd ]; } } } catch (e) { start = []; } return start; }; kendo.compileMobileDirective = function (element, scope) { var angular = window.angular; element.attr('data-' + kendo.ns + 'role', element[0].tagName.toLowerCase().replace('kendo-mobile-', '').replace('-', '')); angular.element(element).injector().invoke([ '$compile', function ($compile) { $compile(element)(scope); if (!/^\$(digest|apply)$/.test(scope.$$phase)) { scope.$digest(); } } ]); return kendo.widgetInstance(element, kendo.mobile.ui); }; kendo.antiForgeryTokens = function () { var tokens = {}, csrf_token = $('meta[name=csrf-token],meta[name=_csrf]').attr('content'), csrf_param = $('meta[name=csrf-param],meta[name=_csrf_header]').attr('content'); $('input[name^=\'__RequestVerificationToken\']').each(function () { tokens[this.name] = this.value; }); if (csrf_param !== undefined && csrf_token !== undefined) { tokens[csrf_param] = csrf_token; } return tokens; }; kendo.cycleForm = function (form) { var firstElement = form.find('input, .k-widget').first(); var lastElement = form.find('button, .k-button').last(); function focus(el) { var widget = kendo.widgetInstance(el); if (widget && widget.focus) { widget.focus(); } else { el.focus(); } } lastElement.on('keydown', function (e) { if (e.keyCode == kendo.keys.TAB && !e.shiftKey) { e.preventDefault(); focus(firstElement); } }); firstElement.on('keydown', function (e) { if (e.keyCode == kendo.keys.TAB && e.shiftKey) { e.preventDefault(); focus(lastElement); } }); }; (function () { function postToProxy(dataURI, fileName, proxyURL, proxyTarget) { var form = $('<form>').attr({ action: proxyURL, method: 'POST', target: proxyTarget }); var data = kendo.antiForgeryTokens(); data.fileName = fileName; var parts = dataURI.split(';base64,'); data.contentType = parts[0].replace('data:', ''); data.base64 = parts[1]; for (var name in data) { if (data.hasOwnProperty(name)) { $('<input>').attr({ value: data[name], name: name, type: 'hidden' }).appendTo(form); } } form.appendTo('body').submit().remove(); } var fileSaver = document.createElement('a'); var downloadAttribute = 'download' in fileSaver && !kendo.support.browser.edge; function saveAsBlob(dataURI, fileName) { var blob = dataURI; if (typeof dataURI == 'string') { var parts = dataURI.split(';base64,'); var contentType = parts[0]; var base64 = atob(parts[1]); var array = new Uint8Array(base64.length); for (var idx = 0; idx < base64.length; idx++) { array[idx] = base64.charCodeAt(idx); } blob = new Blob([array.buffer], { type: contentType }); } navigator.msSaveBlob(blob, fileName); } function saveAsDataURI(dataURI, fileName) { if (window.Blob && dataURI instanceof Blob) { dataURI = URL.createObjectURL(dataURI); } fileSaver.download = fileName; fileSaver.href = dataURI; var e = document.createEvent('MouseEvents'); e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); fileSaver.dispatchEvent(e); setTimeout(function () { URL.revokeObjectURL(dataURI); }); } kendo.saveAs = function (options) { var save = postToProxy; if (!options.forceProxy) { if (downloadAttribute) { save = saveAsDataURI; } else if (navigator.msSaveBlob) { save = saveAsBlob; } } save(options.dataURI, options.fileName, options.proxyURL, options.proxyTarget); }; }()); kendo.proxyModelSetters = function proxyModelSetters(data) { var observable = {}; Object.keys(data || {}).forEach(function (property) { Object.defineProperty(observable, property, { get: function () { return data[property]; }, set: function (value) { data[property] = value; data.dirty = true; } }); }); return observable; }; }(jQuery, window)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.color', ['kendo.core'], f); }(function () { var __meta__ = { id: 'color', name: 'Color utils', category: 'framework', advanced: true, description: 'Color utilities used across components', depends: ['core'] }; (function ($, parseFloat, parseInt) { var Color = function (value) { var color = this, formats = Color.formats, re, processor, parts, i, channels; if (arguments.length === 1) { value = color.resolveColor(value); for (i = 0; i < formats.length; i++) { re = formats[i].re; processor = formats[i].process; parts = re.exec(value); if (parts) { channels = processor(parts); color.r = channels[0]; color.g = channels[1]; color.b = channels[2]; } } } else { color.r = arguments[0]; color.g = arguments[1]; color.b = arguments[2]; } color.r = color.normalizeByte(color.r); color.g = color.normalizeByte(color.g); color.b = color.normalizeByte(color.b); }; Color.prototype = { toHex: function () { var color = this, pad = color.padDigit, r = color.r.toString(16), g = color.g.toString(16), b = color.b.toString(16); return '#' + pad(r) + pad(g) + pad(b); }, resolveColor: function (value) { value = value || 'black'; if (value.charAt(0) == '#') { value = value.substr(1, 6); } value = value.replace(/ /g, ''); value = value.toLowerCase(); value = Color.namedColors[value] || value; return value; }, normalizeByte: function (value) { return value < 0 || isNaN(value) ? 0 : value > 255 ? 255 : value; }, padDigit: function (value) { return value.length === 1 ? '0' + value : value; }, brightness: function (value) { var color = this, round = Math.round; color.r = round(color.normalizeByte(color.r * value)); color.g = round(color.normalizeByte(color.g * value)); color.b = round(color.normalizeByte(color.b * value)); return color; }, percBrightness: function () { var color = this; return Math.sqrt(0.241 * color.r * color.r + 0.691 * color.g * color.g + 0.068 * color.b * color.b); } }; Color.formats = [ { re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, process: function (parts) { return [ parseInt(parts[1], 10), parseInt(parts[2], 10), parseInt(parts[3], 10) ]; } }, { re: /^(\w{2})(\w{2})(\w{2})$/, process: function (parts) { return [ parseInt(parts[1], 16), parseInt(parts[2], 16), parseInt(parts[3], 16) ]; } }, { re: /^(\w{1})(\w{1})(\w{1})$/, process: function (parts) { return [ parseInt(parts[1] + parts[1], 16), parseInt(parts[2] + parts[2], 16), parseInt(parts[3] + parts[3], 16) ]; } } ]; Color.namedColors = { aliceblue: 'f0f8ff', antiquewhite: 'faebd7', aqua: '00ffff', aquamarine: '7fffd4', azure: 'f0ffff', beige: 'f5f5dc', bisque: 'ffe4c4', black: '000000', blanchedalmond: 'ffebcd', blue: '0000ff', blueviolet: '8a2be2', brown: 'a52a2a', burlywood: 'deb887', cadetblue: '5f9ea0', chartreuse: '7fff00', chocolate: 'd2691e', coral: 'ff7f50', cornflowerblue: '6495ed', cornsilk: 'fff8dc', crimson: 'dc143c', cyan: '00ffff', darkblue: '00008b', darkcyan: '008b8b', darkgoldenrod: 'b8860b', darkgray: 'a9a9a9', darkgrey: 'a9a9a9', darkgreen: '006400', darkkhaki: 'bdb76b', darkmagenta: '8b008b', darkolivegreen: '556b2f', darkorange: 'ff8c00', darkorchid: '9932cc', darkred: '8b0000', darksalmon: 'e9967a', darkseagreen: '8fbc8f', darkslateblue: '483d8b', darkslategray: '2f4f4f', darkslategrey: '2f4f4f', darkturquoise: '00ced1', darkviolet: '9400d3', deeppink: 'ff1493', deepskyblue: '00bfff', dimgray: '696969', dimgrey: '696969', dodgerblue: '1e90ff', firebrick: 'b22222', floralwhite: 'fffaf0', forestgreen: '228b22', fuchsia: 'ff00ff', gainsboro: 'dcdcdc', ghostwhite: 'f8f8ff', gold: 'ffd700', goldenrod: 'daa520', gray: '808080', grey: '808080', green: '008000', greenyellow: 'adff2f', honeydew: 'f0fff0', hotpink: 'ff69b4', indianred: 'cd5c5c', indigo: '4b0082', ivory: 'fffff0', khaki: 'f0e68c', lavender: 'e6e6fa', lavenderblush: 'fff0f5', lawngreen: '7cfc00', lemonchiffon: 'fffacd', lightblue: 'add8e6', lightcoral: 'f08080', lightcyan: 'e0ffff', lightgoldenrodyellow: 'fafad2', lightgray: 'd3d3d3', lightgrey: 'd3d3d3', lightgreen: '90ee90', lightpink: 'ffb6c1', lightsalmon: 'ffa07a', lightseagreen: '20b2aa', lightskyblue: '87cefa', lightslategray: '778899', lightslategrey: '778899', lightsteelblue: 'b0c4de', lightyellow: 'ffffe0', lime: '00ff00', limegreen: '32cd32', linen: 'faf0e6', magenta: 'ff00ff', maroon: '800000', mediumaquamarine: '66cdaa', mediumblue: '0000cd', mediumorchid: 'ba55d3', mediumpurple: '9370d8', mediumseagreen: '3cb371', mediumslateblue: '7b68ee', mediumspringgreen: '00fa9a', mediumturquoise: '48d1cc', mediumvioletred: 'c71585', midnightblue: '191970', mintcream: 'f5fffa', mistyrose: 'ffe4e1', moccasin: 'ffe4b5', navajowhite: 'ffdead', navy: '000080', oldlace: 'fdf5e6', olive: '808000', olivedrab: '6b8e23', orange: 'ffa500', orangered: 'ff4500', orchid: 'da70d6', palegoldenrod: 'eee8aa', palegreen: '98fb98', paleturquoise: 'afeeee', palevioletred: 'd87093', papayawhip: 'ffefd5', peachpuff: 'ffdab9', peru: 'cd853f', pink: 'ffc0cb', plum: 'dda0dd', powderblue: 'b0e0e6', purple: '800080', red: 'ff0000', rosybrown: 'bc8f8f', royalblue: '4169e1', saddlebrown: '8b4513', salmon: 'fa8072', sandybrown: 'f4a460', seagreen: '2e8b57', seashell: 'fff5ee', sienna: 'a0522d', silver: 'c0c0c0', skyblue: '87ceeb', slateblue: '6a5acd', slategray: '708090', slategrey: '708090', snow: 'fffafa', springgreen: '00ff7f', steelblue: '4682b4', tan: 'd2b48c', teal: '008080', thistle: 'd8bfd8', tomato: 'ff6347', turquoise: '40e0d0', violet: 'ee82ee', wheat: 'f5deb3', white: 'ffffff', whitesmoke: 'f5f5f5', yellow: 'ffff00', yellowgreen: '9acd32' }; var namedColorRegexp = ['transparent']; for (var i in Color.namedColors) { if (Color.namedColors.hasOwnProperty(i)) { namedColorRegexp.push(i); } } namedColorRegexp = new RegExp('^(' + namedColorRegexp.join('|') + ')(\\W|$)', 'i'); function parseColor(color, nothrow) { var m, ret; if (color == null || color == 'none') { return null; } if (color instanceof _Color) { return color; } color = color.toLowerCase(); if (m = namedColorRegexp.exec(color)) { if (m[1] == 'transparent') { color = new _RGB(1, 1, 1, 0); } else { color = parseColor(Color.namedColors[m[1]], nothrow); } color.match = [m[1]]; return color; } if (m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})\b/i.exec(color)) { ret = new _Bytes(parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16), 1); } else if (m = /^#?([0-9a-f])([0-9a-f])([0-9a-f])\b/i.exec(color)) { ret = new _Bytes(parseInt(m[1] + m[1], 16), parseInt(m[2] + m[2], 16), parseInt(m[3] + m[3], 16), 1); } else if (m = /^rgb\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/.exec(color)) { ret = new _Bytes(parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10), 1); } else if (m = /^rgba\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9.]+)\s*\)/.exec(color)) { ret = new _Bytes(parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10), parseFloat(m[4])); } else if (m = /^rgb\(\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*\)/.exec(color)) { ret = new _RGB(parseFloat(m[1]) / 100, parseFloat(m[2]) / 100, parseFloat(m[3]) / 100, 1); } else if (m = /^rgba\(\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9.]+)\s*\)/.exec(color)) { ret = new _RGB(parseFloat(m[1]) / 100, parseFloat(m[2]) / 100, parseFloat(m[3]) / 100, parseFloat(m[4])); } if (ret) { ret.match = m; } else if (!nothrow) { throw new Error('Cannot parse color: ' + color); } return ret; } function hex(n, width, pad) { if (!pad) { pad = '0'; } n = n.toString(16); while (width > n.length) { n = '0' + n; } return n; } function hue2rgb(p, q, t) { if (t < 0) { t += 1; } if (t > 1) { t -= 1; } if (t < 1 / 6) { return p + (q - p) * 6 * t; } if (t < 1 / 2) { return q; } if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; } return p; } var _Color = kendo.Class.extend({ toHSV: function () { return this; }, toRGB: function () { return this; }, toHex: function () { return this.toBytes().toHex(); }, toBytes: function () { return this; }, toCss: function () { return '#' + this.toHex(); }, toCssRgba: function () { var rgb = this.toBytes(); return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat((+this.a).toFixed(3)) + ')'; }, toDisplay: function () { if (kendo.support.browser.msie && kendo.support.browser.version < 9) { return this.toCss(); } return this.toCssRgba(); }, equals: function (c) { return c === this || c !== null && this.toCssRgba() == parseColor(c).toCssRgba(); }, diff: function (c2) { if (c2 == null) { return NaN; } var c1 = this.toBytes(); c2 = c2.toBytes(); return Math.sqrt(Math.pow((c1.r - c2.r) * 0.3, 2) + Math.pow((c1.g - c2.g) * 0.59, 2) + Math.pow((c1.b - c2.b) * 0.11, 2)); }, clone: function () { var c = this.toBytes(); if (c === this) { c = new _Bytes(c.r, c.g, c.b, c.a); } return c; } }); var _RGB = _Color.extend({ init: function (r, g, b, a) { this.r = r; this.g = g; this.b = b; this.a = a; }, toHSV: function () { var min, max, delta, h, s, v; var r = this.r, g = this.g, b = this.b; min = Math.min(r, g, b); max = Math.max(r, g, b); v = max; delta = max - min; if (delta === 0) { return new _HSV(0, 0, v, this.a); } if (max !== 0) { s = delta / max; if (r == max) { h = (g - b) / delta; } else if (g == max) { h = 2 + (b - r) / delta; } else { h = 4 + (r - g) / delta; } h *= 60; if (h < 0) { h += 360; } } else { s = 0; h = -1; } return new _HSV(h, s, v, this.a); }, toHSL: function () { var r = this.r, g = this.g, b = this.b; var max = Math.max(r, g, b), min = Math.min(r, g, b); var h, s, l = (max + min) / 2; if (max == min) { h = s = 0; } else { var d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h *= 60; s *= 100; l *= 100; } return new _HSL(h, s, l, this.a); }, toBytes: function () { return new _Bytes(this.r * 255, this.g * 255, this.b * 255, this.a); } }); var _Bytes = _RGB.extend({ init: function (r, g, b, a) { this.r = Math.round(r); this.g = Math.round(g); this.b = Math.round(b); this.a = a; }, toRGB: function () { return new _RGB(this.r / 255, this.g / 255, this.b / 255, this.a); }, toHSV: function () { return this.toRGB().toHSV(); }, toHSL: function () { return this.toRGB().toHSL(); }, toHex: function () { return hex(this.r, 2) + hex(this.g, 2) + hex(this.b, 2); }, toBytes: function () { return this; } }); var _HSV = _Color.extend({ init: function (h, s, v, a) { this.h = h; this.s = s; this.v = v; this.a = a; }, toRGB: function () { var h = this.h, s = this.s, v = this.v; var i, r, g, b, f, p, q, t; if (s === 0) { r = g = b = v; } else { h /= 60; i = Math.floor(h); f = h - i; p = v * (1 - s); q = v * (1 - s * f); t = v * (1 - s * (1 - f)); switch (i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; } } return new _RGB(r, g, b, this.a); }, toHSL: function () { return this.toRGB().toHSL(); }, toBytes: function () { return this.toRGB().toBytes(); } }); var _HSL = _Color.extend({ init: function (h, s, l, a) { this.h = h; this.s = s; this.l = l; this.a = a; }, toRGB: function () { var h = this.h, s = this.s, l = this.l; var r, g, b; if (s === 0) { r = g = b = l; } else { h /= 360; s /= 100; l /= 100; var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } return new _RGB(r, g, b, this.a); }, toHSV: function () { return this.toRGB().toHSV(); }, toBytes: function () { return this.toRGB().toBytes(); } }); Color.fromBytes = function (r, g, b, a) { return new _Bytes(r, g, b, a != null ? a : 1); }; Color.fromRGB = function (r, g, b, a) { return new _RGB(r, g, b, a != null ? a : 1); }; Color.fromHSV = function (h, s, v, a) { return new _HSV(h, s, v, a != null ? a : 1); }; Color.fromHSL = function (h, s, l, a) { return new _HSL(h, s, l, a != null ? a : 1); }; kendo.Color = Color; kendo.parseColor = parseColor; }(window.kendo.jQuery, parseFloat, parseInt)); }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.data', [ 'kendo.core', 'kendo.data.odata', 'kendo.data.xml' ], f); }(function () { var __meta__ = { id: 'data', name: 'Data source', category: 'framework', description: 'Powerful component for using local and remote data.Fully supports CRUD, Sorting, Paging, Filtering, Grouping, and Aggregates.', depends: ['core'], features: [ { id: 'data-odata', name: 'OData', description: 'Support for accessing Open Data Protocol (OData) services.', depends: ['data.odata'] }, { id: 'data-signalr', name: 'SignalR', description: 'Support for binding to SignalR hubs.', depends: ['data.signalr'] }, { id: 'data-XML', name: 'XML', description: 'Support for binding to XML.', depends: ['data.xml'] } ] }; (function ($, undefined) { var extend = $.extend, proxy = $.proxy, isPlainObject = $.isPlainObject, isEmptyObject = $.isEmptyObject, isArray = $.isArray, grep = $.grep, ajax = $.ajax, map, each = $.each, noop = $.noop, kendo = window.kendo, isFunction = kendo.isFunction, Observable = kendo.Observable, Class = kendo.Class, STRING = 'string', FUNCTION = 'function', CREATE = 'create', READ = 'read', UPDATE = 'update', DESTROY = 'destroy', CHANGE = 'change', SYNC = 'sync', GET = 'get', ERROR = 'error', REQUESTSTART = 'requestStart', PROGRESS = 'progress', REQUESTEND = 'requestEnd', crud = [ CREATE, READ, UPDATE, DESTROY ], identity = function (o) { return o; }, getter = kendo.getter, stringify = kendo.stringify, math = Math, push = [].push, join = [].join, pop = [].pop, splice = [].splice, shift = [].shift, slice = [].slice, unshift = [].unshift, toString = {}.toString, stableSort = kendo.support.stableSort, dateRegExp = /^\/Date\((.*?)\)\/$/, newLineRegExp = /(\r+|\n+)/g, quoteRegExp = /(?=['\\])/g; var ObservableArray = Observable.extend({ init: function (array, type) { var that = this; that.type = type || ObservableObject; Observable.fn.init.call(that); that.length = array.length; that.wrapAll(array, that); }, at: function (index) { return this[index]; }, toJSON: function () { var idx, length = this.length, value, json = new Array(length); for (idx = 0; idx < length; idx++) { value = this[idx]; if (value instanceof ObservableObject) { value = value.toJSON(); } json[idx] = value; } return json; }, parent: noop, wrapAll: function (source, target) { var that = this, idx, length, parent = function () { return that; }; target = target || []; for (idx = 0, length = source.length; idx < length; idx++) { target[idx] = that.wrap(source[idx], parent); } return target; }, wrap: function (object, parent) { var that = this, observable; if (object !== null && toString.call(object) === '[object Object]') { observable = object instanceof that.type || object instanceof Model; if (!observable) { object = object instanceof ObservableObject ? object.toJSON() : object; object = new that.type(object); } object.parent = parent; object.bind(CHANGE, function (e) { that.trigger(CHANGE, { field: e.field, node: e.node, index: e.index, items: e.items || [this], action: e.node ? e.action || 'itemloaded' : 'itemchange' }); }); } return object; }, push: function () { var index = this.length, items = this.wrapAll(arguments), result; result = push.apply(this, items); this.trigger(CHANGE, { action: 'add', index: index, items: items }); return result; }, slice: slice, sort: [].sort, join: join, pop: function () { var length = this.length, result = pop.apply(this); if (length) { this.trigger(CHANGE, { action: 'remove', index: length - 1, items: [result] }); } return result; }, splice: function (index, howMany, item) { var items = this.wrapAll(slice.call(arguments, 2)), result, i, len; result = splice.apply(this, [ index, howMany ].concat(items)); if (result.length) { this.trigger(CHANGE, { action: 'remove', index: index, items: result }); for (i = 0, len = result.length; i < len; i++) { if (result[i] && result[i].children) { result[i].unbind(CHANGE); } } } if (item) { this.trigger(CHANGE, { action: 'add', index: index, items: items }); } return result; }, shift: function () { var length = this.length, result = shift.apply(this); if (length) { this.trigger(CHANGE, { action: 'remove', index: 0, items: [result] }); } return result; }, unshift: function () { var items = this.wrapAll(arguments), result; result = unshift.apply(this, items); this.trigger(CHANGE, { action: 'add', index: 0, items: items }); return result; }, indexOf: function (item) { var that = this, idx, length; for (idx = 0, length = that.length; idx < length; idx++) { if (that[idx] === item) { return idx; } } return -1; }, forEach: function (callback) { var idx = 0, length = this.length; for (; idx < length; idx++) { callback(this[idx], idx, this); } }, map: function (callback) { var idx = 0, result = [], length = this.length; for (; idx < length; idx++) { result[idx] = callback(this[idx], idx, this); } return result; }, reduce: function (callback) { var idx = 0, result, length = this.length; if (arguments.length == 2) { result = arguments[1]; } else if (idx < length) { result = this[idx++]; } for (; idx < length; idx++) { result = callback(result, this[idx], idx, this); } return result; }, reduceRight: function (callback) { var idx = this.length - 1, result; if (arguments.length == 2) { result = arguments[1]; } else if (idx > 0) { result = this[idx--]; } for (; idx >= 0; idx--) { result = callback(result, this[idx], idx, this); } return result; }, filter: function (callback) { var idx = 0, result = [], item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (callback(item, idx, this)) { result[result.length] = item; } } return result; }, find: function (callback) { var idx = 0, item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (callback(item, idx, this)) { return item; } } }, every: function (callback) { var idx = 0, item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (!callback(item, idx, this)) { return false; } } return true; }, some: function (callback) { var idx = 0, item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (callback(item, idx, this)) { return true; } } return false; }, remove: function (item) { var idx = this.indexOf(item); if (idx !== -1) { this.splice(idx, 1); } }, empty: function () { this.splice(0, this.length); } }); if (typeof Symbol !== 'undefined' && Symbol.iterator && !ObservableArray.prototype[Symbol.iterator]) { ObservableArray.prototype[Symbol.iterator] = [][Symbol.iterator]; } var LazyObservableArray = ObservableArray.extend({ init: function (data, type) { Observable.fn.init.call(this); this.type = type || ObservableObject; for (var idx = 0; idx < data.length; idx++) { this[idx] = data[idx]; } this.length = idx; this._parent = proxy(function () { return this; }, this); }, at: function (index) { var item = this[index]; if (!(item instanceof this.type)) { item = this[index] = this.wrap(item, this._parent); } else { item.parent = this._parent; } return item; } }); function eventHandler(context, type, field, prefix) { return function (e) { var event = {}, key; for (key in e) { event[key] = e[key]; } if (prefix) { event.field = field + '.' + e.field; } else { event.field = field; } if (type == CHANGE && context._notifyChange) { context._notifyChange(event); } context.trigger(type, event); }; } var ObservableObject = Observable.extend({ init: function (value) { var that = this, member, field, parent = function () { return that; }; Observable.fn.init.call(this); this._handlers = {}; for (field in value) { member = value[field]; if (typeof member === 'object' && member && !member.getTime && field.charAt(0) != '_') { member = that.wrap(member, field, parent); } that[field] = member; } that.uid = kendo.guid(); }, shouldSerialize: function (field) { return this.hasOwnProperty(field) && field !== '_handlers' && field !== '_events' && typeof this[field] !== FUNCTION && field !== 'uid'; }, forEach: function (f) { for (var i in this) { if (this.shouldSerialize(i)) { f(this[i], i); } } }, toJSON: function () { var result = {}, value, field; for (field in this) { if (this.shouldSerialize(field)) { value = this[field]; if (value instanceof ObservableObject || value instanceof ObservableArray) { value = value.toJSON(); } result[field] = value; } } return result; }, get: function (field) { var that = this, result; that.trigger(GET, { field: field }); if (field === 'this') { result = that; } else { result = kendo.getter(field, true)(that); } return result; }, _set: function (field, value) { var that = this; var composite = field.indexOf('.') >= 0; if (composite) { var paths = field.split('.'), path = ''; while (paths.length > 1) { path += paths.shift(); var obj = kendo.getter(path, true)(that); if (obj instanceof ObservableObject) { obj.set(paths.join('.'), value); return composite; } path += '.'; } } kendo.setter(field)(that, value); return composite; }, set: function (field, value) { var that = this, isSetPrevented = false, composite = field.indexOf('.') >= 0, current = kendo.getter(field, true)(that); if (current !== value) { if (current instanceof Observable && this._handlers[field]) { if (this._handlers[field].get) { current.unbind(GET, this._handlers[field].get); } current.unbind(CHANGE, this._handlers[field].change); } isSetPrevented = that.trigger('set', { field: field, value: value }); if (!isSetPrevented) { if (!composite) { value = that.wrap(value, field, function () { return that; }); } if (!that._set(field, value) || field.indexOf('(') >= 0 || field.indexOf('[') >= 0) { that.trigger(CHANGE, { field: field }); } } } return isSetPrevented; }, parent: noop, wrap: function (object, field, parent) { var that = this; var get; var change; var type = toString.call(object); if (object != null && (type === '[object Object]' || type === '[object Array]')) { var isObservableArray = object instanceof ObservableArray; var isDataSource = object instanceof DataSource; if (type === '[object Object]' && !isDataSource && !isObservableArray) { if (!(object instanceof ObservableObject)) { object = new ObservableObject(object); } get = eventHandler(that, GET, field, true); object.bind(GET, get); change = eventHandler(that, CHANGE, field, true); object.bind(CHANGE, change); that._handlers[field] = { get: get, change: change }; } else if (type === '[object Array]' || isObservableArray || isDataSource) { if (!isObservableArray && !isDataSource) { object = new ObservableArray(object); } change = eventHandler(that, CHANGE, field, false); object.bind(CHANGE, change); that._handlers[field] = { change: change }; } object.parent = parent; } return object; } }); function equal(x, y) { if (x === y) { return true; } var xtype = $.type(x), ytype = $.type(y), field; if (xtype !== ytype) { return false; } if (xtype === 'date') { return x.getTime() === y.getTime(); } if (xtype !== 'object' && xtype !== 'array') { return false; } for (field in x) { if (!equal(x[field], y[field])) { return false; } } return true; } var parsers = { 'number': function (value) { return kendo.parseFloat(value); }, 'date': function (value) { return kendo.parseDate(value); }, 'boolean': function (value) { if (typeof value === STRING) { return value.toLowerCase() === 'true'; } return value != null ? !!value : value; }, 'string': function (value) { return value != null ? value + '' : value; }, 'default': function (value) { return value; } }; var defaultValues = { 'string': '', 'number': 0, 'date': new Date(), 'boolean': false, 'default': '' }; function getFieldByName(obj, name) { var field, fieldName; for (fieldName in obj) { field = obj[fieldName]; if (isPlainObject(field) && field.field && field.field === name) { return field; } else if (field === name) { return field; } } return null; } var Model = ObservableObject.extend({ init: function (data) { var that = this; if (!data || $.isEmptyObject(data)) { data = $.extend({}, that.defaults, data); if (that._initializers) { for (var idx = 0; idx < that._initializers.length; idx++) { var name = that._initializers[idx]; data[name] = that.defaults[name](); } } } ObservableObject.fn.init.call(that, data); that.dirty = false; if (that.idField) { that.id = that.get(that.idField); if (that.id === undefined) { that.id = that._defaultId; } } }, shouldSerialize: function (field) { return ObservableObject.fn.shouldSerialize.call(this, field) && field !== 'uid' && !(this.idField !== 'id' && field === 'id') && field !== 'dirty' && field !== '_accessors'; }, _parse: function (field, value) { var that = this, fieldName = field, fields = that.fields || {}, parse; field = fields[field]; if (!field) { field = getFieldByName(fields, fieldName); } if (field) { parse = field.parse; if (!parse && field.type) { parse = parsers[field.type.toLowerCase()]; } } return parse ? parse(value) : value; }, _notifyChange: function (e) { var action = e.action; if (action == 'add' || action == 'remove') { this.dirty = true; } }, editable: function (field) { field = (this.fields || {})[field]; return field ? field.editable !== false : true; }, set: function (field, value, initiator) { var that = this; var dirty = that.dirty; if (that.editable(field)) { value = that._parse(field, value); if (!equal(value, that.get(field))) { that.dirty = true; if (ObservableObject.fn.set.call(that, field, value, initiator) && !dirty) { that.dirty = dirty; } } } }, accept: function (data) { var that = this, parent = function () { return that; }, field; for (field in data) { var value = data[field]; if (field.charAt(0) != '_') { value = that.wrap(data[field], field, parent); } that._set(field, value); } if (that.idField) { that.id = that.get(that.idField); } that.dirty = false; }, isNew: function () { return this.id === this._defaultId; } }); Model.define = function (base, options) { if (options === undefined) { options = base; base = Model; } var model, proto = extend({ defaults: {} }, options), name, field, type, value, idx, length, fields = {}, originalName, id = proto.id, functionFields = []; if (id) { proto.idField = id; } if (proto.id) { delete proto.id; } if (id) { proto.defaults[id] = proto._defaultId = ''; } if (toString.call(proto.fields) === '[object Array]') { for (idx = 0, length = proto.fields.length; idx < length; idx++) { field = proto.fields[idx]; if (typeof field === STRING) { fields[field] = {}; } else if (field.field) { fields[field.field] = field; } } proto.fields = fields; } for (name in proto.fields) { field = proto.fields[name]; type = field.type || 'default'; value = null; originalName = name; name = typeof field.field === STRING ? field.field : name; if (!field.nullable) { value = proto.defaults[originalName !== name ? originalName : name] = field.defaultValue !== undefined ? field.defaultValue : defaultValues[type.toLowerCase()]; if (typeof value === 'function') { functionFields.push(name); } } if (options.id === name) { proto._defaultId = value; } proto.defaults[originalName !== name ? originalName : name] = value; field.parse = field.parse || parsers[type]; } if (functionFields.length > 0) { proto._initializers = functionFields; } model = base.extend(proto); model.define = function (options) { return Model.define(model, options); }; if (proto.fields) { model.fields = proto.fields; model.idField = proto.idField; } return model; }; var Comparer = { selector: function (field) { return isFunction(field) ? field : getter(field); }, compare: function (field) { var selector = this.selector(field); return function (a, b) { a = selector(a); b = selector(b); if (a == null && b == null) { return 0; } if (a == null) { return -1; } if (b == null) { return 1; } if (a.localeCompare) { return a.localeCompare(b); } return a > b ? 1 : a < b ? -1 : 0; }; }, create: function (sort) { var compare = sort.compare || this.compare(sort.field); if (sort.dir == 'desc') { return function (a, b) { return compare(b, a, true); }; } return compare; }, combine: function (comparers) { return function (a, b) { var result = comparers[0](a, b), idx, length; for (idx = 1, length = comparers.length; idx < length; idx++) { result = result || comparers[idx](a, b); } return result; }; } }; var StableComparer = extend({}, Comparer, { asc: function (field) { var selector = this.selector(field); return function (a, b) { var valueA = selector(a); var valueB = selector(b); if (valueA && valueA.getTime && valueB && valueB.getTime) { valueA = valueA.getTime(); valueB = valueB.getTime(); } if (valueA === valueB) { return a.__position - b.__position; } if (valueA == null) { return -1; } if (valueB == null) { return 1; } if (valueA.localeCompare) { return valueA.localeCompare(valueB); } return valueA > valueB ? 1 : -1; }; }, desc: function (field) { var selector = this.selector(field); return function (a, b) { var valueA = selector(a); var valueB = selector(b); if (valueA && valueA.getTime && valueB && valueB.getTime) { valueA = valueA.getTime(); valueB = valueB.getTime(); } if (valueA === valueB) { return a.__position - b.__position; } if (valueA == null) { return 1; } if (valueB == null) { return -1; } if (valueB.localeCompare) { return valueB.localeCompare(valueA); } return valueA < valueB ? 1 : -1; }; }, create: function (sort) { return this[sort.dir](sort.field); } }); map = function (array, callback) { var idx, length = array.length, result = new Array(length); for (idx = 0; idx < length; idx++) { result[idx] = callback(array[idx], idx, array); } return result; }; var operators = function () { function quote(value) { return value.replace(quoteRegExp, '\\').replace(newLineRegExp, ''); } function operator(op, a, b, ignore) { var date; if (b != null) { if (typeof b === STRING) { b = quote(b); date = dateRegExp.exec(b); if (date) { b = new Date(+date[1]); } else if (ignore) { b = '\'' + b.toLowerCase() + '\''; a = '((' + a + ' || \'\')+\'\').toLowerCase()'; } else { b = '\'' + b + '\''; } } if (b.getTime) { a = '(' + a + '&&' + a + '.getTime?' + a + '.getTime():' + a + ')'; b = b.getTime(); } } return a + ' ' + op + ' ' + b; } return { quote: function (value) { if (value && value.getTime) { return 'new Date(' + value.getTime() + ')'; } if (typeof value == 'string') { return '\'' + quote(value) + '\''; } return '' + value; }, eq: function (a, b, ignore) { return operator('==', a, b, ignore); }, neq: function (a, b, ignore) { return operator('!=', a, b, ignore); }, gt: function (a, b, ignore) { return operator('>', a, b, ignore); }, gte: function (a, b, ignore) { return operator('>=', a, b, ignore); }, lt: function (a, b, ignore) { return operator('<', a, b, ignore); }, lte: function (a, b, ignore) { return operator('<=', a, b, ignore); }, startswith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.lastIndexOf(\'' + b + '\', 0) == 0'; }, doesnotstartwith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.lastIndexOf(\'' + b + '\', 0) == -1'; }, endswith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\', ' + a + '.length - ' + (b || '').length + ') >= 0'; }, doesnotendwith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\', ' + a + '.length - ' + (b || '').length + ') < 0'; }, contains: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\') >= 0'; }, doesnotcontain: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\') == -1'; }, isempty: function (a) { return a + ' === \'\''; }, isnotempty: function (a) { return a + ' !== \'\''; }, isnull: function (a) { return '(' + a + ' === null || ' + a + ' === undefined)'; }, isnotnull: function (a) { return '(' + a + ' !== null && ' + a + ' !== undefined)'; } }; }(); function Query(data) { this.data = data || []; } Query.filterExpr = function (expression) { var expressions = [], logic = { and: ' && ', or: ' || ' }, idx, length, filter, expr, fieldFunctions = [], operatorFunctions = [], field, operator, filters = expression.filters; for (idx = 0, length = filters.length; idx < length; idx++) { filter = filters[idx]; field = filter.field; operator = filter.operator; if (filter.filters) { expr = Query.filterExpr(filter); filter = expr.expression.replace(/__o\[(\d+)\]/g, function (match, index) { index = +index; return '__o[' + (operatorFunctions.length + index) + ']'; }).replace(/__f\[(\d+)\]/g, function (match, index) { index = +index; return '__f[' + (fieldFunctions.length + index) + ']'; }); operatorFunctions.push.apply(operatorFunctions, expr.operators); fieldFunctions.push.apply(fieldFunctions, expr.fields); } else { if (typeof field === FUNCTION) { expr = '__f[' + fieldFunctions.length + '](d)'; fieldFunctions.push(field); } else { expr = kendo.expr(field); } if (typeof operator === FUNCTION) { filter = '__o[' + operatorFunctions.length + '](' + expr + ', ' + operators.quote(filter.value) + ')'; operatorFunctions.push(operator); } else { filter = operators[(operator || 'eq').toLowerCase()](expr, filter.value, filter.ignoreCase !== undefined ? filter.ignoreCase : true); } } expressions.push(filter); } return { expression: '(' + expressions.join(logic[expression.logic]) + ')', fields: fieldFunctions, operators: operatorFunctions }; }; function normalizeSort(field, dir) { if (field) { var descriptor = typeof field === STRING ? { field: field, dir: dir } : field, descriptors = isArray(descriptor) ? descriptor : descriptor !== undefined ? [descriptor] : []; return grep(descriptors, function (d) { return !!d.dir; }); } } var operatorMap = { '==': 'eq', equals: 'eq', isequalto: 'eq', equalto: 'eq', equal: 'eq', '!=': 'neq', ne: 'neq', notequals: 'neq', isnotequalto: 'neq', notequalto: 'neq', notequal: 'neq', '<': 'lt', islessthan: 'lt', lessthan: 'lt', less: 'lt', '<=': 'lte', le: 'lte', islessthanorequalto: 'lte', lessthanequal: 'lte', '>': 'gt', isgreaterthan: 'gt', greaterthan: 'gt', greater: 'gt', '>=': 'gte', isgreaterthanorequalto: 'gte', greaterthanequal: 'gte', ge: 'gte', notsubstringof: 'doesnotcontain', isnull: 'isnull', isempty: 'isempty', isnotempty: 'isnotempty' }; function normalizeOperator(expression) { var idx, length, filter, operator, filters = expression.filters; if (filters) { for (idx = 0, length = filters.length; idx < length; idx++) { filter = filters[idx]; operator = filter.operator; if (operator && typeof operator === STRING) { filter.operator = operatorMap[operator.toLowerCase()] || operator; } normalizeOperator(filter); } } } function normalizeFilter(expression) { if (expression && !isEmptyObject(expression)) { if (isArray(expression) || !expression.filters) { expression = { logic: 'and', filters: isArray(expression) ? expression : [expression] }; } normalizeOperator(expression); return expression; } } Query.normalizeFilter = normalizeFilter; function compareDescriptor(f1, f2) { if (f1.logic || f2.logic) { return false; } return f1.field === f2.field && f1.value === f2.value && f1.operator === f2.operator; } function normalizeDescriptor(filter) { filter = filter || {}; if (isEmptyObject(filter)) { return { logic: 'and', filters: [] }; } return normalizeFilter(filter); } function fieldComparer(a, b) { if (b.logic || a.field > b.field) { return 1; } else if (a.field < b.field) { return -1; } else { return 0; } } function compareFilters(expr1, expr2) { expr1 = normalizeDescriptor(expr1); expr2 = normalizeDescriptor(expr2); if (expr1.logic !== expr2.logic) { return false; } var f1, f2; var filters1 = (expr1.filters || []).slice(); var filters2 = (expr2.filters || []).slice(); if (filters1.length !== filters2.length) { return false; } filters1 = filters1.sort(fieldComparer); filters2 = filters2.sort(fieldComparer); for (var idx = 0; idx < filters1.length; idx++) { f1 = filters1[idx]; f2 = filters2[idx]; if (f1.logic && f2.logic) { if (!compareFilters(f1, f2)) { return false; } } else if (!compareDescriptor(f1, f2)) { return false; } } return true; } Query.compareFilters = compareFilters; function normalizeAggregate(expressions) { return isArray(expressions) ? expressions : [expressions]; } function normalizeGroup(field, dir) { var descriptor = typeof field === STRING ? { field: field, dir: dir } : field, descriptors = isArray(descriptor) ? descriptor : descriptor !== undefined ? [descriptor] : []; return map(descriptors, function (d) { return { field: d.field, dir: d.dir || 'asc', aggregates: d.aggregates }; }); } Query.prototype = { toArray: function () { return this.data; }, range: function (index, count) { return new Query(this.data.slice(index, index + count)); }, skip: function (count) { return new Query(this.data.slice(count)); }, take: function (count) { return new Query(this.data.slice(0, count)); }, select: function (selector) { return new Query(map(this.data, selector)); }, order: function (selector, dir) { var sort = { dir: dir }; if (selector) { if (selector.compare) { sort.compare = selector.compare; } else { sort.field = selector; } } return new Query(this.data.slice(0).sort(Comparer.create(sort))); }, orderBy: function (selector) { return this.order(selector, 'asc'); }, orderByDescending: function (selector) { return this.order(selector, 'desc'); }, sort: function (field, dir, comparer) { var idx, length, descriptors = normalizeSort(field, dir), comparers = []; comparer = comparer || Comparer; if (descriptors.length) { for (idx = 0, length = descriptors.length; idx < length; idx++) { comparers.push(comparer.create(descriptors[idx])); } return this.orderBy({ compare: comparer.combine(comparers) }); } return this; }, filter: function (expressions) { var idx, current, length, compiled, predicate, data = this.data, fields, operators, result = [], filter; expressions = normalizeFilter(expressions); if (!expressions || expressions.filters.length === 0) { return this; } compiled = Query.filterExpr(expressions); fields = compiled.fields; operators = compiled.operators; predicate = filter = new Function('d, __f, __o', 'return ' + compiled.expression); if (fields.length || operators.length) { filter = function (d) { return predicate(d, fields, operators); }; } for (idx = 0, length = data.length; idx < length; idx++) { current = data[idx]; if (filter(current)) { result.push(current); } } return new Query(result); }, group: function (descriptors, allData) { descriptors = normalizeGroup(descriptors || []); allData = allData || this.data; var that = this, result = new Query(that.data), descriptor; if (descriptors.length > 0) { descriptor = descriptors[0]; result = result.groupBy(descriptor).select(function (group) { var data = new Query(allData).filter([{ field: group.field, operator: 'eq', value: group.value, ignoreCase: false }]); return { field: group.field, value: group.value, items: descriptors.length > 1 ? new Query(group.items).group(descriptors.slice(1), data.toArray()).toArray() : group.items, hasSubgroups: descriptors.length > 1, aggregates: data.aggregate(descriptor.aggregates) }; }); } return result; }, groupBy: function (descriptor) { if (isEmptyObject(descriptor) || !this.data.length) { return new Query([]); } var field = descriptor.field, sorted = this._sortForGrouping(field, descriptor.dir || 'asc'), accessor = kendo.accessor(field), item, groupValue = accessor.get(sorted[0], field), group = { field: field, value: groupValue, items: [] }, currentValue, idx, len, result = [group]; for (idx = 0, len = sorted.length; idx < len; idx++) { item = sorted[idx]; currentValue = accessor.get(item, field); if (!groupValueComparer(groupValue, currentValue)) { groupValue = currentValue; group = { field: field, value: groupValue, items: [] }; result.push(group); } group.items.push(item); } return new Query(result); }, _sortForGrouping: function (field, dir) { var idx, length, data = this.data; if (!stableSort) { for (idx = 0, length = data.length; idx < length; idx++) { data[idx].__position = idx; } data = new Query(data).sort(field, dir, StableComparer).toArray(); for (idx = 0, length = data.length; idx < length; idx++) { delete data[idx].__position; } return data; } return this.sort(field, dir).toArray(); }, aggregate: function (aggregates) { var idx, len, result = {}, state = {}; if (aggregates && aggregates.length) { for (idx = 0, len = this.data.length; idx < len; idx++) { calculateAggregate(result, aggregates, this.data[idx], idx, len, state); } } return result; } }; function groupValueComparer(a, b) { if (a && a.getTime && b && b.getTime) { return a.getTime() === b.getTime(); } return a === b; } function calculateAggregate(accumulator, aggregates, item, index, length, state) { aggregates = aggregates || []; var idx, aggr, functionName, len = aggregates.length; for (idx = 0; idx < len; idx++) { aggr = aggregates[idx]; functionName = aggr.aggregate; var field = aggr.field; accumulator[field] = accumulator[field] || {}; state[field] = state[field] || {}; state[field][functionName] = state[field][functionName] || {}; accumulator[field][functionName] = functions[functionName.toLowerCase()](accumulator[field][functionName], item, kendo.accessor(field), index, length, state[field][functionName]); } } var functions = { sum: function (accumulator, item, accessor) { var value = accessor.get(item); if (!isNumber(accumulator)) { accumulator = value; } else if (isNumber(value)) { accumulator += value; } return accumulator; }, count: function (accumulator) { return (accumulator || 0) + 1; }, average: function (accumulator, item, accessor, index, length, state) { var value = accessor.get(item); if (state.count === undefined) { state.count = 0; } if (!isNumber(accumulator)) { accumulator = value; } else if (isNumber(value)) { accumulator += value; } if (isNumber(value)) { state.count++; } if (index == length - 1 && isNumber(accumulator)) { accumulator = accumulator / state.count; } return accumulator; }, max: function (accumulator, item, accessor) { var value = accessor.get(item); if (!isNumber(accumulator) && !isDate(accumulator)) { accumulator = value; } if (accumulator < value && (isNumber(value) || isDate(value))) { accumulator = value; } return accumulator; }, min: function (accumulator, item, accessor) { var value = accessor.get(item); if (!isNumber(accumulator) && !isDate(accumulator)) { accumulator = value; } if (accumulator > value && (isNumber(value) || isDate(value))) { accumulator = value; } return accumulator; } }; function isNumber(val) { return typeof val === 'number' && !isNaN(val); } function isDate(val) { return val && val.getTime; } function toJSON(array) { var idx, length = array.length, result = new Array(length); for (idx = 0; idx < length; idx++) { result[idx] = array[idx].toJSON(); } return result; } Query.process = function (data, options) { options = options || {}; var query = new Query(data), group = options.group, sort = normalizeGroup(group || []).concat(normalizeSort(options.sort || [])), total, filterCallback = options.filterCallback, filter = options.filter, skip = options.skip, take = options.take; if (filter) { query = query.filter(filter); if (filterCallback) { query = filterCallback(query); } total = query.toArray().length; } if (sort) { query = query.sort(sort); if (group) { data = query.toArray(); } } if (skip !== undefined && take !== undefined) { query = query.range(skip, take); } if (group) { query = query.group(group, data); } return { total: total, data: query.toArray() }; }; var LocalTransport = Class.extend({ init: function (options) { this.data = options.data; }, read: function (options) { options.success(this.data); }, update: function (options) { options.success(options.data); }, create: function (options) { options.success(options.data); }, destroy: function (options) { options.success(options.data); } }); var RemoteTransport = Class.extend({ init: function (options) { var that = this, parameterMap; options = that.options = extend({}, that.options, options); each(crud, function (index, type) { if (typeof options[type] === STRING) { options[type] = { url: options[type] }; } }); that.cache = options.cache ? Cache.create(options.cache) : { find: noop, add: noop }; parameterMap = options.parameterMap; if (isFunction(options.push)) { that.push = options.push; } if (!that.push) { that.push = identity; } that.parameterMap = isFunction(parameterMap) ? parameterMap : function (options) { var result = {}; each(options, function (option, value) { if (option in parameterMap) { option = parameterMap[option]; if (isPlainObject(option)) { value = option.value(value); option = option.key; } } result[option] = value; }); return result; }; }, options: { parameterMap: identity }, create: function (options) { return ajax(this.setup(options, CREATE)); }, read: function (options) { var that = this, success, error, result, cache = that.cache; options = that.setup(options, READ); success = options.success || noop; error = options.error || noop; result = cache.find(options.data); if (result !== undefined) { success(result); } else { options.success = function (result) { cache.add(options.data, result); success(result); }; $.ajax(options); } }, update: function (options) { return ajax(this.setup(options, UPDATE)); }, destroy: function (options) { return ajax(this.setup(options, DESTROY)); }, setup: function (options, type) { options = options || {}; var that = this, parameters, operation = that.options[type], data = isFunction(operation.data) ? operation.data(options.data) : operation.data; options = extend(true, {}, operation, options); parameters = extend(true, {}, data, options.data); options.data = that.parameterMap(parameters, type); if (isFunction(options.url)) { options.url = options.url(parameters); } return options; } }); var Cache = Class.extend({ init: function () { this._store = {}; }, add: function (key, data) { if (key !== undefined) { this._store[stringify(key)] = data; } }, find: function (key) { return this._store[stringify(key)]; }, clear: function () { this._store = {}; }, remove: function (key) { delete this._store[stringify(key)]; } }); Cache.create = function (options) { var store = { 'inmemory': function () { return new Cache(); } }; if (isPlainObject(options) && isFunction(options.find)) { return options; } if (options === true) { return new Cache(); } return store[options](); }; function serializeRecords(data, getters, modelInstance, originalFieldNames, fieldNames) { var record, getter, originalName, idx, setters = {}, length; for (idx = 0, length = data.length; idx < length; idx++) { record = data[idx]; for (getter in getters) { originalName = fieldNames[getter]; if (originalName && originalName !== getter) { if (!setters[originalName]) { setters[originalName] = kendo.setter(originalName); } setters[originalName](record, getters[getter](record)); delete record[getter]; } } } } function convertRecords(data, getters, modelInstance, originalFieldNames, fieldNames) { var record, getter, originalName, idx, length; for (idx = 0, length = data.length; idx < length; idx++) { record = data[idx]; for (getter in getters) { record[getter] = modelInstance._parse(getter, getters[getter](record)); originalName = fieldNames[getter]; if (originalName && originalName !== getter) { delete record[originalName]; } } } } function convertGroup(data, getters, modelInstance, originalFieldNames, fieldNames) { var record, idx, fieldName, length; for (idx = 0, length = data.length; idx < length; idx++) { record = data[idx]; fieldName = originalFieldNames[record.field]; if (fieldName && fieldName != record.field) { record.field = fieldName; } record.value = modelInstance._parse(record.field, record.value); if (record.hasSubgroups) { convertGroup(record.items, getters, modelInstance, originalFieldNames, fieldNames); } else { convertRecords(record.items, getters, modelInstance, originalFieldNames, fieldNames); } } } function wrapDataAccess(originalFunction, model, converter, getters, originalFieldNames, fieldNames) { return function (data) { data = originalFunction(data); if (data && !isEmptyObject(getters)) { if (toString.call(data) !== '[object Array]' && !(data instanceof ObservableArray)) { data = [data]; } converter(data, getters, new model(), originalFieldNames, fieldNames); } return data || []; }; } var DataReader = Class.extend({ init: function (schema) { var that = this, member, get, model, base; schema = schema || {}; for (member in schema) { get = schema[member]; that[member] = typeof get === STRING ? getter(get) : get; } base = schema.modelBase || Model; if (isPlainObject(that.model)) { that.model = model = base.define(that.model); } var dataFunction = proxy(that.data, that); that._dataAccessFunction = dataFunction; if (that.model) { var groupsFunction = proxy(that.groups, that), serializeFunction = proxy(that.serialize, that), originalFieldNames = {}, getters = {}, serializeGetters = {}, fieldNames = {}, shouldSerialize = false, fieldName; model = that.model; if (model.fields) { each(model.fields, function (field, value) { var fromName; fieldName = field; if (isPlainObject(value) && value.field) { fieldName = value.field; } else if (typeof value === STRING) { fieldName = value; } if (isPlainObject(value) && value.from) { fromName = value.from; } shouldSerialize = shouldSerialize || fromName && fromName !== field || fieldName !== field; getters[field] = getter(fromName || fieldName); serializeGetters[field] = getter(field); originalFieldNames[fromName || fieldName] = field; fieldNames[field] = fromName || fieldName; }); if (!schema.serialize && shouldSerialize) { that.serialize = wrapDataAccess(serializeFunction, model, serializeRecords, serializeGetters, originalFieldNames, fieldNames); } } that._dataAccessFunction = dataFunction; that.data = wrapDataAccess(dataFunction, model, convertRecords, getters, originalFieldNames, fieldNames); that.groups = wrapDataAccess(groupsFunction, model, convertGroup, getters, originalFieldNames, fieldNames); } }, errors: function (data) { return data ? data.errors : null; }, parse: identity, data: identity, total: function (data) { return data.length; }, groups: identity, aggregates: function () { return {}; }, serialize: function (data) { return data; } }); function mergeGroups(target, dest, skip, take) { var group, idx = 0, items; while (dest.length && take) { group = dest[idx]; items = group.items; var length = items.length; if (target && target.field === group.field && target.value === group.value) { if (target.hasSubgroups && target.items.length) { mergeGroups(target.items[target.items.length - 1], group.items, skip, take); } else { items = items.slice(skip, skip + take); target.items = target.items.concat(items); } dest.splice(idx--, 1); } else if (group.hasSubgroups && items.length) { mergeGroups(group, items, skip, take); if (!group.items.length) { dest.splice(idx--, 1); } } else { items = items.slice(skip, skip + take); group.items = items; if (!group.items.length) { dest.splice(idx--, 1); } } if (items.length === 0) { skip -= length; } else { skip = 0; take -= items.length; } if (++idx >= dest.length) { break; } } if (idx < dest.length) { dest.splice(idx, dest.length - idx); } } function flattenGroups(data) { var idx, result = [], length, items, itemIndex; for (idx = 0, length = data.length; idx < length; idx++) { var group = data.at(idx); if (group.hasSubgroups) { result = result.concat(flattenGroups(group.items)); } else { items = group.items; for (itemIndex = 0; itemIndex < items.length; itemIndex++) { result.push(items.at(itemIndex)); } } } return result; } function wrapGroupItems(data, model) { var idx, length, group; if (model) { for (idx = 0, length = data.length; idx < length; idx++) { group = data.at(idx); if (group.hasSubgroups) { wrapGroupItems(group.items, model); } else { group.items = new LazyObservableArray(group.items, model); } } } } function eachGroupItems(data, func) { for (var idx = 0, length = data.length; idx < length; idx++) { if (data[idx].hasSubgroups) { if (eachGroupItems(data[idx].items, func)) { return true; } } else if (func(data[idx].items, data[idx])) { return true; } } } function replaceInRanges(ranges, data, item, observable) { for (var idx = 0; idx < ranges.length; idx++) { if (ranges[idx].data === data) { break; } if (replaceInRange(ranges[idx].data, item, observable)) { break; } } } function replaceInRange(items, item, observable) { for (var idx = 0, length = items.length; idx < length; idx++) { if (items[idx] && items[idx].hasSubgroups) { return replaceInRange(items[idx].items, item, observable); } else if (items[idx] === item || items[idx] === observable) { items[idx] = observable; return true; } } } function replaceWithObservable(view, data, ranges, type, serverGrouping) { for (var viewIndex = 0, length = view.length; viewIndex < length; viewIndex++) { var item = view[viewIndex]; if (!item || item instanceof type) { continue; } if (item.hasSubgroups !== undefined && !serverGrouping) { replaceWithObservable(item.items, data, ranges, type, serverGrouping); } else { for (var idx = 0; idx < data.length; idx++) { if (data[idx] === item) { view[viewIndex] = data.at(idx); replaceInRanges(ranges, data, item, view[viewIndex]); break; } } } } } function removeModel(data, model) { var idx, length; for (idx = 0, length = data.length; idx < length; idx++) { var dataItem = data.at(idx); if (dataItem.uid == model.uid) { data.splice(idx, 1); return dataItem; } } } function indexOfPristineModel(data, model) { if (model) { return indexOf(data, function (item) { return item.uid && item.uid == model.uid || item[model.idField] === model.id && model.id !== model._defaultId; }); } return -1; } function indexOfModel(data, model) { if (model) { return indexOf(data, function (item) { return item.uid == model.uid; }); } return -1; } function indexOf(data, comparer) { var idx, length; for (idx = 0, length = data.length; idx < length; idx++) { if (comparer(data[idx])) { return idx; } } return -1; } function fieldNameFromModel(fields, name) { if (fields && !isEmptyObject(fields)) { var descriptor = fields[name]; var fieldName; if (isPlainObject(descriptor)) { fieldName = descriptor.from || descriptor.field || name; } else { fieldName = fields[name] || name; } if (isFunction(fieldName)) { return name; } return fieldName; } return name; } function convertFilterDescriptorsField(descriptor, model) { var idx, length, target = {}; for (var field in descriptor) { if (field !== 'filters') { target[field] = descriptor[field]; } } if (descriptor.filters) { target.filters = []; for (idx = 0, length = descriptor.filters.length; idx < length; idx++) { target.filters[idx] = convertFilterDescriptorsField(descriptor.filters[idx], model); } } else { target.field = fieldNameFromModel(model.fields, target.field); } return target; } function convertDescriptorsField(descriptors, model) { var idx, length, result = [], target, descriptor; for (idx = 0, length = descriptors.length; idx < length; idx++) { target = {}; descriptor = descriptors[idx]; for (var field in descriptor) { target[field] = descriptor[field]; } target.field = fieldNameFromModel(model.fields, target.field); if (target.aggregates && isArray(target.aggregates)) { target.aggregates = convertDescriptorsField(target.aggregates, model); } result.push(target); } return result; } var DataSource = Observable.extend({ init: function (options) { var that = this, model, data; if (options) { data = options.data; } options = that.options = extend({}, that.options, options); that._map = {}; that._prefetch = {}; that._data = []; that._pristineData = []; that._ranges = []; that._view = []; that._pristineTotal = 0; that._destroyed = []; that._pageSize = options.pageSize; that._page = options.page || (options.pageSize ? 1 : undefined); that._sort = normalizeSort(options.sort); that._filter = normalizeFilter(options.filter); that._group = normalizeGroup(options.group); that._aggregate = options.aggregate; that._total = options.total; that._shouldDetachObservableParents = true; Observable.fn.init.call(that); that.transport = Transport.create(options, data, that); if (isFunction(that.transport.push)) { that.transport.push({ pushCreate: proxy(that._pushCreate, that), pushUpdate: proxy(that._pushUpdate, that), pushDestroy: proxy(that._pushDestroy, that) }); } if (options.offlineStorage != null) { if (typeof options.offlineStorage == 'string') { var key = options.offlineStorage; that._storage = { getItem: function () { return JSON.parse(localStorage.getItem(key)); }, setItem: function (item) { localStorage.setItem(key, stringify(that.reader.serialize(item))); } }; } else { that._storage = options.offlineStorage; } } that.reader = new kendo.data.readers[options.schema.type || 'json'](options.schema); model = that.reader.model || {}; that._detachObservableParents(); that._data = that._observe(that._data); that._online = true; that.bind([ 'push', ERROR, CHANGE, REQUESTSTART, SYNC, REQUESTEND, PROGRESS ], options); }, options: { data: null, schema: { modelBase: Model }, offlineStorage: null, serverSorting: false, serverPaging: false, serverFiltering: false, serverGrouping: false, serverAggregates: false, batch: false }, clone: function () { return this; }, online: function (value) { if (value !== undefined) { if (this._online != value) { this._online = value; if (value) { return this.sync(); } } return $.Deferred().resolve().promise(); } else { return this._online; } }, offlineData: function (state) { if (this.options.offlineStorage == null) { return null; } if (state !== undefined) { return this._storage.setItem(state); } return this._storage.getItem() || []; }, _isServerGrouped: function () { var group = this.group() || []; return this.options.serverGrouping && group.length; }, _pushCreate: function (result) { this._push(result, 'pushCreate'); }, _pushUpdate: function (result) { this._push(result, 'pushUpdate'); }, _pushDestroy: function (result) { this._push(result, 'pushDestroy'); }, _push: function (result, operation) { var data = this._readData(result); if (!data) { data = result; } this[operation](data); }, _flatData: function (data, skip) { if (data) { if (this._isServerGrouped()) { return flattenGroups(data); } if (!skip) { for (var idx = 0; idx < data.length; idx++) { data.at(idx); } } } return data; }, parent: noop, get: function (id) { var idx, length, data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].id == id) { return data[idx]; } } }, getByUid: function (id) { var idx, length, data = this._flatData(this._data); if (!data) { return; } for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].uid == id) { return data[idx]; } } }, indexOf: function (model) { return indexOfModel(this._data, model); }, at: function (index) { return this._data.at(index); }, data: function (value) { var that = this; if (value !== undefined) { that._detachObservableParents(); that._data = this._observe(value); that._pristineData = value.slice(0); that._storeData(); that._ranges = []; that.trigger('reset'); that._addRange(that._data); that._total = that._data.length; that._pristineTotal = that._total; that._process(that._data); } else { if (that._data) { for (var idx = 0; idx < that._data.length; idx++) { that._data.at(idx); } } return that._data; } }, view: function (value) { if (value === undefined) { return this._view; } else { this._view = this._observeView(value); } }, _observeView: function (data) { var that = this; replaceWithObservable(data, that._data, that._ranges, that.reader.model || ObservableObject, that._isServerGrouped()); var view = new LazyObservableArray(data, that.reader.model); view.parent = function () { return that.parent(); }; return view; }, flatView: function () { var groups = this.group() || []; if (groups.length) { return flattenGroups(this._view); } else { return this._view; } }, add: function (model) { return this.insert(this._data.length, model); }, _createNewModel: function (model) { if (this.reader.model) { return new this.reader.model(model); } if (model instanceof ObservableObject) { return model; } return new ObservableObject(model); }, insert: function (index, model) { if (!model) { model = index; index = 0; } if (!(model instanceof Model)) { model = this._createNewModel(model); } if (this._isServerGrouped()) { this._data.splice(index, 0, this._wrapInEmptyGroup(model)); } else { this._data.splice(index, 0, model); } return model; }, pushCreate: function (items) { if (!isArray(items)) { items = [items]; } var pushed = []; var autoSync = this.options.autoSync; this.options.autoSync = false; try { for (var idx = 0; idx < items.length; idx++) { var item = items[idx]; var result = this.add(item); pushed.push(result); var pristine = result.toJSON(); if (this._isServerGrouped()) { pristine = this._wrapInEmptyGroup(pristine); } this._pristineData.push(pristine); } } finally { this.options.autoSync = autoSync; } if (pushed.length) { this.trigger('push', { type: 'create', items: pushed }); } }, pushUpdate: function (items) { if (!isArray(items)) { items = [items]; } var pushed = []; for (var idx = 0; idx < items.length; idx++) { var item = items[idx]; var model = this._createNewModel(item); var target = this.get(model.id); if (target) { pushed.push(target); target.accept(item); target.trigger(CHANGE); this._updatePristineForModel(target, item); } else { this.pushCreate(item); } } if (pushed.length) { this.trigger('push', { type: 'update', items: pushed }); } }, pushDestroy: function (items) { var pushed = this._removeItems(items); if (pushed.length) { this.trigger('push', { type: 'destroy', items: pushed }); } }, _removeItems: function (items) { if (!isArray(items)) { items = [items]; } var destroyed = []; var autoSync = this.options.autoSync; this.options.autoSync = false; try { for (var idx = 0; idx < items.length; idx++) { var item = items[idx]; var model = this._createNewModel(item); var found = false; this._eachItem(this._data, function (items) { for (var idx = 0; idx < items.length; idx++) { var item = items.at(idx); if (item.id === model.id) { destroyed.push(item); items.splice(idx, 1); found = true; break; } } }); if (found) { this._removePristineForModel(model); this._destroyed.pop(); } } } finally { this.options.autoSync = autoSync; } return destroyed; }, remove: function (model) { var result, that = this, hasGroups = that._isServerGrouped(); this._eachItem(that._data, function (items) { result = removeModel(items, model); if (result && hasGroups) { if (!result.isNew || !result.isNew()) { that._destroyed.push(result); } return true; } }); this._removeModelFromRanges(model); this._updateRangesLength(); return model; }, destroyed: function () { return this._destroyed; }, created: function () { var idx, length, result = [], data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].isNew && data[idx].isNew()) { result.push(data[idx]); } } return result; }, updated: function () { var idx, length, result = [], data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].isNew && !data[idx].isNew() && data[idx].dirty) { result.push(data[idx]); } } return result; }, sync: function () { var that = this, created = [], updated = [], destroyed = that._destroyed; var promise = $.Deferred().resolve().promise(); if (that.online()) { if (!that.reader.model) { return promise; } created = that.created(); updated = that.updated(); var promises = []; if (that.options.batch && that.transport.submit) { promises = that._sendSubmit(created, updated, destroyed); } else { promises.push.apply(promises, that._send('create', created)); promises.push.apply(promises, that._send('update', updated)); promises.push.apply(promises, that._send('destroy', destroyed)); } promise = $.when.apply(null, promises).then(function () { var idx, length; for (idx = 0, length = arguments.length; idx < length; idx++) { that._accept(arguments[idx]); } that._storeData(true); that._change({ action: 'sync' }); that.trigger(SYNC); }); } else { that._storeData(true); that._change({ action: 'sync' }); } return promise; }, cancelChanges: function (model) { var that = this; if (model instanceof kendo.data.Model) { that._cancelModel(model); } else { that._destroyed = []; that._detachObservableParents(); that._data = that._observe(that._pristineData); if (that.options.serverPaging) { that._total = that._pristineTotal; } that._ranges = []; that._addRange(that._data); that._change(); that._markOfflineUpdatesAsDirty(); } }, _markOfflineUpdatesAsDirty: function () { var that = this; if (that.options.offlineStorage != null) { that._eachItem(that._data, function (items) { for (var idx = 0; idx < items.length; idx++) { var item = items.at(idx); if (item.__state__ == 'update' || item.__state__ == 'create') { item.dirty = true; } } }); } }, hasChanges: function () { var idx, length, data = this._flatData(this._data); if (this._destroyed.length) { return true; } for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].isNew && data[idx].isNew() || data[idx].dirty) { return true; } } return false; }, _accept: function (result) { var that = this, models = result.models, response = result.response, idx = 0, serverGroup = that._isServerGrouped(), pristine = that._pristineData, type = result.type, length; that.trigger(REQUESTEND, { response: response, type: type }); if (response && !isEmptyObject(response)) { response = that.reader.parse(response); if (that._handleCustomErrors(response)) { return; } response = that.reader.data(response); if (!isArray(response)) { response = [response]; } } else { response = $.map(models, function (model) { return model.toJSON(); }); } if (type === 'destroy') { that._destroyed = []; } for (idx = 0, length = models.length; idx < length; idx++) { if (type !== 'destroy') { models[idx].accept(response[idx]); if (type === 'create') { pristine.push(serverGroup ? that._wrapInEmptyGroup(models[idx]) : response[idx]); } else if (type === 'update') { that._updatePristineForModel(models[idx], response[idx]); } } else { that._removePristineForModel(models[idx]); } } }, _updatePristineForModel: function (model, values) { this._executeOnPristineForModel(model, function (index, items) { kendo.deepExtend(items[index], values); }); }, _executeOnPristineForModel: function (model, callback) { this._eachPristineItem(function (items) { var index = indexOfPristineModel(items, model); if (index > -1) { callback(index, items); return true; } }); }, _removePristineForModel: function (model) { this._executeOnPristineForModel(model, function (index, items) { items.splice(index, 1); }); }, _readData: function (data) { var read = !this._isServerGrouped() ? this.reader.data : this.reader.groups; return read.call(this.reader, data); }, _eachPristineItem: function (callback) { this._eachItem(this._pristineData, callback); }, _eachItem: function (data, callback) { if (data && data.length) { if (this._isServerGrouped()) { eachGroupItems(data, callback); } else { callback(data); } } }, _pristineForModel: function (model) { var pristine, idx, callback = function (items) { idx = indexOfPristineModel(items, model); if (idx > -1) { pristine = items[idx]; return true; } }; this._eachPristineItem(callback); return pristine; }, _cancelModel: function (model) { var pristine = this._pristineForModel(model); this._eachItem(this._data, function (items) { var idx = indexOfModel(items, model); if (idx >= 0) { if (pristine && (!model.isNew() || pristine.__state__)) { items[idx].accept(pristine); if (pristine.__state__ == 'update') { items[idx].dirty = true; } } else { items.splice(idx, 1); } } }); }, _submit: function (promises, data) { var that = this; that.trigger(REQUESTSTART, { type: 'submit' }); that.transport.submit(extend({ success: function (response, type) { var promise = $.grep(promises, function (x) { return x.type == type; })[0]; if (promise) { promise.resolve({ response: response, models: promise.models, type: type }); } }, error: function (response, status, error) { for (var idx = 0; idx < promises.length; idx++) { promises[idx].reject(response); } that.error(response, status, error); } }, data)); }, _sendSubmit: function (created, updated, destroyed) { var that = this, promises = []; if (that.options.batch) { if (created.length) { promises.push($.Deferred(function (deferred) { deferred.type = 'create'; deferred.models = created; })); } if (updated.length) { promises.push($.Deferred(function (deferred) { deferred.type = 'update'; deferred.models = updated; })); } if (destroyed.length) { promises.push($.Deferred(function (deferred) { deferred.type = 'destroy'; deferred.models = destroyed; })); } that._submit(promises, { data: { created: that.reader.serialize(toJSON(created)), updated: that.reader.serialize(toJSON(updated)), destroyed: that.reader.serialize(toJSON(destroyed)) } }); } return promises; }, _promise: function (data, models, type) { var that = this; return $.Deferred(function (deferred) { that.trigger(REQUESTSTART, { type: type }); that.transport[type].call(that.transport, extend({ success: function (response) { deferred.resolve({ response: response, models: models, type: type }); }, error: function (response, status, error) { deferred.reject(response); that.error(response, status, error); } }, data)); }).promise(); }, _send: function (method, data) { var that = this, idx, length, promises = [], converted = that.reader.serialize(toJSON(data)); if (that.options.batch) { if (data.length) { promises.push(that._promise({ data: { models: converted } }, data, method)); } } else { for (idx = 0, length = data.length; idx < length; idx++) { promises.push(that._promise({ data: converted[idx] }, [data[idx]], method)); } } return promises; }, read: function (data) { var that = this, params = that._params(data); var deferred = $.Deferred(); that._queueRequest(params, function () { var isPrevented = that.trigger(REQUESTSTART, { type: 'read' }); if (!isPrevented) { that.trigger(PROGRESS); that._ranges = []; that.trigger('reset'); if (that.online()) { that.transport.read({ data: params, success: function (data) { that._ranges = []; that.success(data, params); deferred.resolve(); }, error: function () { var args = slice.call(arguments); that.error.apply(that, args); deferred.reject.apply(deferred, args); } }); } else if (that.options.offlineStorage != null) { that.success(that.offlineData(), params); deferred.resolve(); } } else { that._dequeueRequest(); deferred.resolve(isPrevented); } }); return deferred.promise(); }, _readAggregates: function (data) { return this.reader.aggregates(data); }, success: function (data) { var that = this, options = that.options; that.trigger(REQUESTEND, { response: data, type: 'read' }); if (that.online()) { data = that.reader.parse(data); if (that._handleCustomErrors(data)) { that._dequeueRequest(); return; } that._total = that.reader.total(data); if (that._aggregate && options.serverAggregates) { that._aggregateResult = that._readAggregates(data); } data = that._readData(data); that._destroyed = []; } else { data = that._readData(data); var items = []; var itemIds = {}; var model = that.reader.model; var idField = model ? model.idField : 'id'; var idx; for (idx = 0; idx < this._destroyed.length; idx++) { var id = this._destroyed[idx][idField]; itemIds[id] = id; } for (idx = 0; idx < data.length; idx++) { var item = data[idx]; var state = item.__state__; if (state == 'destroy') { if (!itemIds[item[idField]]) { this._destroyed.push(this._createNewModel(item)); } } else { items.push(item); } } data = items; that._total = data.length; } that._pristineTotal = that._total; that._pristineData = data.slice(0); that._detachObservableParents(); that._data = that._observe(data); that._markOfflineUpdatesAsDirty(); that._storeData(); that._addRange(that._data); that._process(that._data); that._dequeueRequest(); }, _detachObservableParents: function () { if (this._data && this._shouldDetachObservableParents) { for (var idx = 0; idx < this._data.length; idx++) { if (this._data[idx].parent) { this._data[idx].parent = noop; } } } }, _storeData: function (updatePristine) { var serverGrouping = this._isServerGrouped(); var model = this.reader.model; function items(data) { var state = []; for (var idx = 0; idx < data.length; idx++) { var dataItem = data.at(idx); var item = dataItem.toJSON(); if (serverGrouping && dataItem.items) { item.items = items(dataItem.items); } else { item.uid = dataItem.uid; if (model) { if (dataItem.isNew()) { item.__state__ = 'create'; } else if (dataItem.dirty) { item.__state__ = 'update'; } } } state.push(item); } return state; } if (this.options.offlineStorage != null) { var state = items(this._data); var destroyed = []; for (var idx = 0; idx < this._destroyed.length; idx++) { var item = this._destroyed[idx].toJSON(); item.__state__ = 'destroy'; destroyed.push(item); } this.offlineData(state.concat(destroyed)); if (updatePristine) { this._pristineData = this._readData(state); } } }, _addRange: function (data) { var that = this, start = that._skip || 0, end = start + that._flatData(data, true).length; that._ranges.push({ start: start, end: end, data: data, timestamp: new Date().getTime() }); that._ranges.sort(function (x, y) { return x.start - y.start; }); }, error: function (xhr, status, errorThrown) { this._dequeueRequest(); this.trigger(REQUESTEND, {}); this.trigger(ERROR, { xhr: xhr, status: status, errorThrown: errorThrown }); }, _params: function (data) { var that = this, options = extend({ take: that.take(), skip: that.skip(), page: that.page(), pageSize: that.pageSize(), sort: that._sort, filter: that._filter, group: that._group, aggregate: that._aggregate }, data); if (!that.options.serverPaging) { delete options.take; delete options.skip; delete options.page; delete options.pageSize; } if (!that.options.serverGrouping) { delete options.group; } else if (that.reader.model && options.group) { options.group = convertDescriptorsField(options.group, that.reader.model); } if (!that.options.serverFiltering) { delete options.filter; } else if (that.reader.model && options.filter) { options.filter = convertFilterDescriptorsField(options.filter, that.reader.model); } if (!that.options.serverSorting) { delete options.sort; } else if (that.reader.model && options.sort) { options.sort = convertDescriptorsField(options.sort, that.reader.model); } if (!that.options.serverAggregates) { delete options.aggregate; } else if (that.reader.model && options.aggregate) { options.aggregate = convertDescriptorsField(options.aggregate, that.reader.model); } return options; }, _queueRequest: function (options, callback) { var that = this; if (!that._requestInProgress) { that._requestInProgress = true; that._pending = undefined; callback(); } else { that._pending = { callback: proxy(callback, that), options: options }; } }, _dequeueRequest: function () { var that = this; that._requestInProgress = false; if (that._pending) { that._queueRequest(that._pending.options, that._pending.callback); } }, _handleCustomErrors: function (response) { if (this.reader.errors) { var errors = this.reader.errors(response); if (errors) { this.trigger(ERROR, { xhr: null, status: 'customerror', errorThrown: 'custom error', errors: errors }); return true; } } return false; }, _shouldWrap: function (data) { var model = this.reader.model; if (model && data.length) { return !(data[0] instanceof model); } return false; }, _observe: function (data) { var that = this, model = that.reader.model; that._shouldDetachObservableParents = true; if (data instanceof ObservableArray) { that._shouldDetachObservableParents = false; if (that._shouldWrap(data)) { data.type = that.reader.model; data.wrapAll(data, data); } } else { var arrayType = that.pageSize() && !that.options.serverPaging ? LazyObservableArray : ObservableArray; data = new arrayType(data, that.reader.model); data.parent = function () { return that.parent(); }; } if (that._isServerGrouped()) { wrapGroupItems(data, model); } if (that._changeHandler && that._data && that._data instanceof ObservableArray) { that._data.unbind(CHANGE, that._changeHandler); } else { that._changeHandler = proxy(that._change, that); } return data.bind(CHANGE, that._changeHandler); }, _updateTotalForAction: function (action, items) { var that = this; var total = parseInt(that._total, 10); if (!isNumber(that._total)) { total = parseInt(that._pristineTotal, 10); } if (action === 'add') { total += items.length; } else if (action === 'remove') { total -= items.length; } else if (action !== 'itemchange' && action !== 'sync' && !that.options.serverPaging) { total = that._pristineTotal; } else if (action === 'sync') { total = that._pristineTotal = parseInt(that._total, 10); } that._total = total; }, _change: function (e) { var that = this, idx, length, action = e ? e.action : ''; if (action === 'remove') { for (idx = 0, length = e.items.length; idx < length; idx++) { if (!e.items[idx].isNew || !e.items[idx].isNew()) { that._destroyed.push(e.items[idx]); } } } if (that.options.autoSync && (action === 'add' || action === 'remove' || action === 'itemchange')) { var handler = function (args) { if (args.action === 'sync') { that.unbind('change', handler); that._updateTotalForAction(action, e.items); } }; that.first('change', handler); that.sync(); } else { that._updateTotalForAction(action, e ? e.items : []); that._process(that._data, e); } }, _calculateAggregates: function (data, options) { options = options || {}; var query = new Query(data), aggregates = options.aggregate, filter = options.filter; if (filter) { query = query.filter(filter); } return query.aggregate(aggregates); }, _process: function (data, e) { var that = this, options = {}, result; if (that.options.serverPaging !== true) { options.skip = that._skip; options.take = that._take || that._pageSize; if (options.skip === undefined && that._page !== undefined && that._pageSize !== undefined) { options.skip = (that._page - 1) * that._pageSize; } } if (that.options.serverSorting !== true) { options.sort = that._sort; } if (that.options.serverFiltering !== true) { options.filter = that._filter; } if (that.options.serverGrouping !== true) { options.group = that._group; } if (that.options.serverAggregates !== true) { options.aggregate = that._aggregate; that._aggregateResult = that._calculateAggregates(data, options); } result = that._queryProcess(data, options); that.view(result.data); if (result.total !== undefined && !that.options.serverFiltering) { that._total = result.total; } e = e || {}; e.items = e.items || that._view; that.trigger(CHANGE, e); }, _queryProcess: function (data, options) { return Query.process(data, options); }, _mergeState: function (options) { var that = this; if (options !== undefined) { that._pageSize = options.pageSize; that._page = options.page; that._sort = options.sort; that._filter = options.filter; that._group = options.group; that._aggregate = options.aggregate; that._skip = that._currentRangeStart = options.skip; that._take = options.take; if (that._skip === undefined) { that._skip = that._currentRangeStart = that.skip(); options.skip = that.skip(); } if (that._take === undefined && that._pageSize !== undefined) { that._take = that._pageSize; options.take = that._take; } if (options.sort) { that._sort = options.sort = normalizeSort(options.sort); } if (options.filter) { that._filter = options.filter = normalizeFilter(options.filter); } if (options.group) { that._group = options.group = normalizeGroup(options.group); } if (options.aggregate) { that._aggregate = options.aggregate = normalizeAggregate(options.aggregate); } } return options; }, query: function (options) { var result; var remote = this.options.serverSorting || this.options.serverPaging || this.options.serverFiltering || this.options.serverGrouping || this.options.serverAggregates; if (remote || (this._data === undefined || this._data.length === 0) && !this._destroyed.length) { return this.read(this._mergeState(options)); } var isPrevented = this.trigger(REQUESTSTART, { type: 'read' }); if (!isPrevented) { this.trigger(PROGRESS); result = this._queryProcess(this._data, this._mergeState(options)); if (!this.options.serverFiltering) { if (result.total !== undefined) { this._total = result.total; } else { this._total = this._data.length; } } this._aggregateResult = this._calculateAggregates(this._data, options); this.view(result.data); this.trigger(REQUESTEND, { type: 'read' }); this.trigger(CHANGE, { items: result.data }); } return $.Deferred().resolve(isPrevented).promise(); }, fetch: function (callback) { var that = this; var fn = function (isPrevented) { if (isPrevented !== true && isFunction(callback)) { callback.call(that); } }; return this._query().then(fn); }, _query: function (options) { var that = this; return that.query(extend({}, { page: that.page(), pageSize: that.pageSize(), sort: that.sort(), filter: that.filter(), group: that.group(), aggregate: that.aggregate() }, options)); }, next: function (options) { var that = this, page = that.page(), total = that.total(); options = options || {}; if (!page || total && page + 1 > that.totalPages()) { return; } that._skip = that._currentRangeStart = page * that.take(); page += 1; options.page = page; that._query(options); return page; }, prev: function (options) { var that = this, page = that.page(); options = options || {}; if (!page || page === 1) { return; } that._skip = that._currentRangeStart = that._skip - that.take(); page -= 1; options.page = page; that._query(options); return page; }, page: function (val) { var that = this, skip; if (val !== undefined) { val = math.max(math.min(math.max(val, 1), that.totalPages()), 1); that._query({ page: val }); return; } skip = that.skip(); return skip !== undefined ? math.round((skip || 0) / (that.take() || 1)) + 1 : undefined; }, pageSize: function (val) { var that = this; if (val !== undefined) { that._query({ pageSize: val, page: 1 }); return; } return that.take(); }, sort: function (val) { var that = this; if (val !== undefined) { that._query({ sort: val }); return; } return that._sort; }, filter: function (val) { var that = this; if (val === undefined) { return that._filter; } that.trigger('reset'); that._query({ filter: val, page: 1 }); }, group: function (val) { var that = this; if (val !== undefined) { that._query({ group: val }); return; } return that._group; }, total: function () { return parseInt(this._total || 0, 10); }, aggregate: function (val) { var that = this; if (val !== undefined) { that._query({ aggregate: val }); return; } return that._aggregate; }, aggregates: function () { var result = this._aggregateResult; if (isEmptyObject(result)) { result = this._emptyAggregates(this.aggregate()); } return result; }, _emptyAggregates: function (aggregates) { var result = {}; if (!isEmptyObject(aggregates)) { var aggregate = {}; if (!isArray(aggregates)) { aggregates = [aggregates]; } for (var idx = 0; idx < aggregates.length; idx++) { aggregate[aggregates[idx].aggregate] = 0; result[aggregates[idx].field] = aggregate; } } return result; }, _wrapInEmptyGroup: function (model) { var groups = this.group(), parent, group, idx, length; for (idx = groups.length - 1, length = 0; idx >= length; idx--) { group = groups[idx]; parent = { value: model.get(group.field), field: group.field, items: parent ? [parent] : [model], hasSubgroups: !!parent, aggregates: this._emptyAggregates(group.aggregates) }; } return parent; }, totalPages: function () { var that = this, pageSize = that.pageSize() || that.total(); return math.ceil((that.total() || 0) / pageSize); }, inRange: function (skip, take) { var that = this, end = math.min(skip + take, that.total()); if (!that.options.serverPaging && that._data.length > 0) { return true; } return that._findRange(skip, end).length > 0; }, lastRange: function () { var ranges = this._ranges; return ranges[ranges.length - 1] || { start: 0, end: 0, data: [] }; }, firstItemUid: function () { var ranges = this._ranges; return ranges.length && ranges[0].data.length && ranges[0].data[0].uid; }, enableRequestsInProgress: function () { this._skipRequestsInProgress = false; }, _timeStamp: function () { return new Date().getTime(); }, range: function (skip, take) { this._currentRequestTimeStamp = this._timeStamp(); this._skipRequestsInProgress = true; skip = math.min(skip || 0, this.total()); var that = this, pageSkip = math.max(math.floor(skip / take), 0) * take, size = math.min(pageSkip + take, that.total()), data; data = that._findRange(skip, math.min(skip + take, that.total())); if (data.length) { that._pending = undefined; that._skip = skip > that.skip() ? math.min(size, (that.totalPages() - 1) * that.take()) : pageSkip; that._currentRangeStart = skip; that._take = take; var paging = that.options.serverPaging; var sorting = that.options.serverSorting; var filtering = that.options.serverFiltering; var aggregates = that.options.serverAggregates; try { that.options.serverPaging = true; if (!that._isServerGrouped() && !(that.group() && that.group().length)) { that.options.serverSorting = true; } that.options.serverFiltering = true; that.options.serverPaging = true; that.options.serverAggregates = true; if (paging) { that._detachObservableParents(); that._data = data = that._observe(data); } that._process(data); } finally { that.options.serverPaging = paging; that.options.serverSorting = sorting; that.options.serverFiltering = filtering; that.options.serverAggregates = aggregates; } return; } if (take !== undefined) { if (!that._rangeExists(pageSkip, size)) { that.prefetch(pageSkip, take, function () { if (skip > pageSkip && size < that.total() && !that._rangeExists(size, math.min(size + take, that.total()))) { that.prefetch(size, take, function () { that.range(skip, take); }); } else { that.range(skip, take); } }); } else if (pageSkip < skip) { that.prefetch(size, take, function () { that.range(skip, take); }); } } }, _findRange: function (start, end) { var that = this, ranges = that._ranges, range, data = [], skipIdx, takeIdx, startIndex, endIndex, rangeData, rangeEnd, processed, options = that.options, remote = options.serverSorting || options.serverPaging || options.serverFiltering || options.serverGrouping || options.serverAggregates, flatData, count, length; for (skipIdx = 0, length = ranges.length; skipIdx < length; skipIdx++) { range = ranges[skipIdx]; if (start >= range.start && start <= range.end) { count = 0; for (takeIdx = skipIdx; takeIdx < length; takeIdx++) { range = ranges[takeIdx]; flatData = that._flatData(range.data, true); if (flatData.length && start + count >= range.start) { rangeData = range.data; rangeEnd = range.end; if (!remote) { var sort = normalizeGroup(that.group() || []).concat(normalizeSort(that.sort() || [])); processed = that._queryProcess(range.data, { sort: sort, filter: that.filter() }); flatData = rangeData = processed.data; if (processed.total !== undefined) { rangeEnd = processed.total; } } startIndex = 0; if (start + count > range.start) { startIndex = start + count - range.start; } endIndex = flatData.length; if (rangeEnd > end) { endIndex = endIndex - (rangeEnd - end); } count += endIndex - startIndex; data = that._mergeGroups(data, rangeData, startIndex, endIndex); if (end <= range.end && count == end - start) { return data; } } } break; } } return []; }, _mergeGroups: function (data, range, skip, take) { if (this._isServerGrouped()) { var temp = range.toJSON(), prevGroup; if (data.length) { prevGroup = data[data.length - 1]; } mergeGroups(prevGroup, temp, skip, take); return data.concat(temp); } return data.concat(range.slice(skip, take)); }, skip: function () { var that = this; if (that._skip === undefined) { return that._page !== undefined ? (that._page - 1) * (that.take() || 1) : undefined; } return that._skip; }, currentRangeStart: function () { return this._currentRangeStart || 0; }, take: function () { return this._take || this._pageSize; }, _prefetchSuccessHandler: function (skip, size, callback, force) { var that = this; var timestamp = that._timeStamp(); return function (data) { var found = false, range = { start: skip, end: size, data: [], timestamp: that._timeStamp() }, idx, length, temp; that._dequeueRequest(); that.trigger(REQUESTEND, { response: data, type: 'read' }); data = that.reader.parse(data); temp = that._readData(data); if (temp.length) { for (idx = 0, length = that._ranges.length; idx < length; idx++) { if (that._ranges[idx].start === skip) { found = true; range = that._ranges[idx]; break; } } if (!found) { that._ranges.push(range); } } range.data = that._observe(temp); range.end = range.start + that._flatData(range.data, true).length; that._ranges.sort(function (x, y) { return x.start - y.start; }); that._total = that.reader.total(data); if (force || (timestamp >= that._currentRequestTimeStamp || !that._skipRequestsInProgress)) { if (callback && temp.length) { callback(); } else { that.trigger(CHANGE, {}); } } }; }, prefetch: function (skip, take, callback) { var that = this, size = math.min(skip + take, that.total()), options = { take: take, skip: skip, page: skip / take + 1, pageSize: take, sort: that._sort, filter: that._filter, group: that._group, aggregate: that._aggregate }; if (!that._rangeExists(skip, size)) { clearTimeout(that._timeout); that._timeout = setTimeout(function () { that._queueRequest(options, function () { if (!that.trigger(REQUESTSTART, { type: 'read' })) { that.transport.read({ data: that._params(options), success: that._prefetchSuccessHandler(skip, size, callback), error: function () { var args = slice.call(arguments); that.error.apply(that, args); } }); } else { that._dequeueRequest(); } }); }, 100); } else if (callback) { callback(); } }, _multiplePrefetch: function (skip, take, callback) { var that = this, size = math.min(skip + take, that.total()), options = { take: take, skip: skip, page: skip / take + 1, pageSize: take, sort: that._sort, filter: that._filter, group: that._group, aggregate: that._aggregate }; if (!that._rangeExists(skip, size)) { if (!that.trigger(REQUESTSTART, { type: 'read' })) { that.transport.read({ data: that._params(options), success: that._prefetchSuccessHandler(skip, size, callback, true) }); } } else if (callback) { callback(); } }, _rangeExists: function (start, end) { var that = this, ranges = that._ranges, idx, length; for (idx = 0, length = ranges.length; idx < length; idx++) { if (ranges[idx].start <= start && ranges[idx].end >= end) { return true; } } return false; }, _removeModelFromRanges: function (model) { var result, found, range; for (var idx = 0, length = this._ranges.length; idx < length; idx++) { range = this._ranges[idx]; this._eachItem(range.data, function (items) { result = removeModel(items, model); if (result) { found = true; } }); if (found) { break; } } }, _updateRangesLength: function () { var startOffset = 0, range, rangeLength; for (var idx = 0, length = this._ranges.length; idx < length; idx++) { range = this._ranges[idx]; range.start = range.start - startOffset; rangeLength = this._flatData(range.data, true).length; startOffset = range.end - rangeLength; range.end = range.start + rangeLength; } } }); var Transport = {}; Transport.create = function (options, data, dataSource) { var transport, transportOptions = options.transport ? $.extend({}, options.transport) : null; if (transportOptions) { transportOptions.read = typeof transportOptions.read === STRING ? { url: transportOptions.read } : transportOptions.read; if (options.type === 'jsdo') { transportOptions.dataSource = dataSource; } if (options.type) { kendo.data.transports = kendo.data.transports || {}; kendo.data.schemas = kendo.data.schemas || {}; if (!kendo.data.transports[options.type]) { kendo.logToConsole('Unknown DataSource transport type \'' + options.type + '\'.\nVerify that registration scripts for this type are included after Kendo UI on the page.', 'warn'); } else if (!isPlainObject(kendo.data.transports[options.type])) { transport = new kendo.data.transports[options.type](extend(transportOptions, { data: data })); } else { transportOptions = extend(true, {}, kendo.data.transports[options.type], transportOptions); } options.schema = extend(true, {}, kendo.data.schemas[options.type], options.schema); } if (!transport) { transport = isFunction(transportOptions.read) ? transportOptions : new RemoteTransport(transportOptions); } } else { transport = new LocalTransport({ data: options.data || [] }); } return transport; }; DataSource.create = function (options) { if (isArray(options) || options instanceof ObservableArray) { options = { data: options }; } var dataSource = options || {}, data = dataSource.data, fields = dataSource.fields, table = dataSource.table, select = dataSource.select, idx, length, model = {}, field; if (!data && fields && !dataSource.transport) { if (table) { data = inferTable(table, fields); } else if (select) { data = inferSelect(select, fields); if (dataSource.group === undefined && data[0] && data[0].optgroup !== undefined) { dataSource.group = 'optgroup'; } } } if (kendo.data.Model && fields && (!dataSource.schema || !dataSource.schema.model)) { for (idx = 0, length = fields.length; idx < length; idx++) { field = fields[idx]; if (field.type) { model[field.field] = field; } } if (!isEmptyObject(model)) { dataSource.schema = extend(true, dataSource.schema, { model: { fields: model } }); } } dataSource.data = data; select = null; dataSource.select = null; table = null; dataSource.table = null; return dataSource instanceof DataSource ? dataSource : new DataSource(dataSource); }; function inferSelect(select, fields) { select = $(select)[0]; var options = select.options; var firstField = fields[0]; var secondField = fields[1]; var data = []; var idx, length; var optgroup; var option; var record; var value; for (idx = 0, length = options.length; idx < length; idx++) { record = {}; option = options[idx]; optgroup = option.parentNode; if (optgroup === select) { optgroup = null; } if (option.disabled || optgroup && optgroup.disabled) { continue; } if (optgroup) { record.optgroup = optgroup.label; } record[firstField.field] = option.text; value = option.attributes.value; if (value && value.specified) { value = option.value; } else { value = option.text; } record[secondField.field] = value; data.push(record); } return data; } function inferTable(table, fields) { var tbody = $(table)[0].tBodies[0], rows = tbody ? tbody.rows : [], idx, length, fieldIndex, fieldCount = fields.length, data = [], cells, record, cell, empty; for (idx = 0, length = rows.length; idx < length; idx++) { record = {}; empty = true; cells = rows[idx].cells; for (fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { cell = cells[fieldIndex]; if (cell.nodeName.toLowerCase() !== 'th') { empty = false; record[fields[fieldIndex].field] = cell.innerHTML; } } if (!empty) { data.push(record); } } return data; } var Node = Model.define({ idField: 'id', init: function (value) { var that = this, hasChildren = that.hasChildren || value && value.hasChildren, childrenField = 'items', childrenOptions = {}; kendo.data.Model.fn.init.call(that, value); if (typeof that.children === STRING) { childrenField = that.children; } childrenOptions = { schema: { data: childrenField, model: { hasChildren: hasChildren, id: that.idField, fields: that.fields } } }; if (typeof that.children !== STRING) { extend(childrenOptions, that.children); } childrenOptions.data = value; if (!hasChildren) { hasChildren = childrenOptions.schema.data; } if (typeof hasChildren === STRING) { hasChildren = kendo.getter(hasChildren); } if (isFunction(hasChildren)) { that.hasChildren = !!hasChildren.call(that, that); } that._childrenOptions = childrenOptions; if (that.hasChildren) { that._initChildren(); } that._loaded = !!(value && value._loaded); }, _initChildren: function () { var that = this; var children, transport, parameterMap; if (!(that.children instanceof HierarchicalDataSource)) { children = that.children = new HierarchicalDataSource(that._childrenOptions); transport = children.transport; parameterMap = transport.parameterMap; transport.parameterMap = function (data, type) { data[that.idField || 'id'] = that.id; if (parameterMap) { data = parameterMap(data, type); } return data; }; children.parent = function () { return that; }; children.bind(CHANGE, function (e) { e.node = e.node || that; that.trigger(CHANGE, e); }); children.bind(ERROR, function (e) { var collection = that.parent(); if (collection) { e.node = e.node || that; collection.trigger(ERROR, e); } }); that._updateChildrenField(); } }, append: function (model) { this._initChildren(); this.loaded(true); this.children.add(model); }, hasChildren: false, level: function () { var parentNode = this.parentNode(), level = 0; while (parentNode && parentNode.parentNode) { level++; parentNode = parentNode.parentNode ? parentNode.parentNode() : null; } return level; }, _updateChildrenField: function () { var fieldName = this._childrenOptions.schema.data; this[fieldName || 'items'] = this.children.data(); }, _childrenLoaded: function () { this._loaded = true; this._updateChildrenField(); }, load: function () { var options = {}; var method = '_query'; var children, promise; if (this.hasChildren) { this._initChildren(); children = this.children; options[this.idField || 'id'] = this.id; if (!this._loaded) { children._data = undefined; method = 'read'; } children.one(CHANGE, proxy(this._childrenLoaded, this)); promise = children[method](options); } else { this.loaded(true); } return promise || $.Deferred().resolve().promise(); }, parentNode: function () { var array = this.parent(); return array.parent(); }, loaded: function (value) { if (value !== undefined) { this._loaded = value; } else { return this._loaded; } }, shouldSerialize: function (field) { return Model.fn.shouldSerialize.call(this, field) && field !== 'children' && field !== '_loaded' && field !== 'hasChildren' && field !== '_childrenOptions'; } }); function dataMethod(name) { return function () { var data = this._data, result = DataSource.fn[name].apply(this, slice.call(arguments)); if (this._data != data) { this._attachBubbleHandlers(); } return result; }; } var HierarchicalDataSource = DataSource.extend({ init: function (options) { var node = Node.define({ children: options }); DataSource.fn.init.call(this, extend(true, {}, { schema: { modelBase: node, model: node } }, options)); this._attachBubbleHandlers(); }, _attachBubbleHandlers: function () { var that = this; that._data.bind(ERROR, function (e) { that.trigger(ERROR, e); }); }, remove: function (node) { var parentNode = node.parentNode(), dataSource = this, result; if (parentNode && parentNode._initChildren) { dataSource = parentNode.children; } result = DataSource.fn.remove.call(dataSource, node); if (parentNode && !dataSource.data().length) { parentNode.hasChildren = false; } return result; }, success: dataMethod('success'), data: dataMethod('data'), insert: function (index, model) { var parentNode = this.parent(); if (parentNode && parentNode._initChildren) { parentNode.hasChildren = true; parentNode._initChildren(); } return DataSource.fn.insert.call(this, index, model); }, _find: function (method, value) { var idx, length, node, children; var data = this._data; if (!data) { return; } node = DataSource.fn[method].call(this, value); if (node) { return node; } data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { children = data[idx].children; if (!(children instanceof HierarchicalDataSource)) { continue; } node = children[method](value); if (node) { return node; } } }, get: function (id) { return this._find('get', id); }, getByUid: function (uid) { return this._find('getByUid', uid); } }); function inferList(list, fields) { var items = $(list).children(), idx, length, data = [], record, textField = fields[0].field, urlField = fields[1] && fields[1].field, spriteCssClassField = fields[2] && fields[2].field, imageUrlField = fields[3] && fields[3].field, item, id, textChild, className, children; function elements(collection, tagName) { return collection.filter(tagName).add(collection.find(tagName)); } for (idx = 0, length = items.length; idx < length; idx++) { record = { _loaded: true }; item = items.eq(idx); textChild = item[0].firstChild; children = item.children(); list = children.filter('ul'); children = children.filter(':not(ul)'); id = item.attr('data-id'); if (id) { record.id = id; } if (textChild) { record[textField] = textChild.nodeType == 3 ? textChild.nodeValue : children.text(); } if (urlField) { record[urlField] = elements(children, 'a').attr('href'); } if (imageUrlField) { record[imageUrlField] = elements(children, 'img').attr('src'); } if (spriteCssClassField) { className = elements(children, '.k-sprite').prop('className'); record[spriteCssClassField] = className && $.trim(className.replace('k-sprite', '')); } if (list.length) { record.items = inferList(list.eq(0), fields); } if (item.attr('data-hasChildren') == 'true') { record.hasChildren = true; } data.push(record); } return data; } HierarchicalDataSource.create = function (options) { options = options && options.push ? { data: options } : options; var dataSource = options || {}, data = dataSource.data, fields = dataSource.fields, list = dataSource.list; if (data && data._dataSource) { return data._dataSource; } if (!data && fields && !dataSource.transport) { if (list) { data = inferList(list, fields); } } dataSource.data = data; return dataSource instanceof HierarchicalDataSource ? dataSource : new HierarchicalDataSource(dataSource); }; var Buffer = kendo.Observable.extend({ init: function (dataSource, viewSize, disablePrefetch) { kendo.Observable.fn.init.call(this); this._prefetching = false; this.dataSource = dataSource; this.prefetch = !disablePrefetch; var buffer = this; dataSource.bind('change', function () { buffer._change(); }); dataSource.bind('reset', function () { buffer._reset(); }); this._syncWithDataSource(); this.setViewSize(viewSize); }, setViewSize: function (viewSize) { this.viewSize = viewSize; this._recalculate(); }, at: function (index) { var pageSize = this.pageSize, itemPresent = true; if (index >= this.total()) { this.trigger('endreached', { index: index }); return null; } if (!this.useRanges) { return this.dataSource.view()[index]; } if (this.useRanges) { if (index < this.dataOffset || index >= this.skip + pageSize) { itemPresent = this.range(Math.floor(index / pageSize) * pageSize); } if (index === this.prefetchThreshold) { this._prefetch(); } if (index === this.midPageThreshold) { this.range(this.nextMidRange, true); } else if (index === this.nextPageThreshold) { this.range(this.nextFullRange); } else if (index === this.pullBackThreshold) { if (this.offset === this.skip) { this.range(this.previousMidRange); } else { this.range(this.previousFullRange); } } if (itemPresent) { return this.dataSource.at(index - this.dataOffset); } else { this.trigger('endreached', { index: index }); return null; } } }, indexOf: function (item) { return this.dataSource.data().indexOf(item) + this.dataOffset; }, total: function () { return parseInt(this.dataSource.total(), 10); }, next: function () { var buffer = this, pageSize = buffer.pageSize, offset = buffer.skip - buffer.viewSize + pageSize, pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize; this.offset = offset; this.dataSource.prefetch(pageSkip, pageSize, function () { buffer._goToRange(offset, true); }); }, range: function (offset, nextRange) { if (this.offset === offset) { return true; } var buffer = this, pageSize = this.pageSize, pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize, dataSource = this.dataSource; if (nextRange) { pageSkip += pageSize; } if (dataSource.inRange(offset, pageSize)) { this.offset = offset; this._recalculate(); this._goToRange(offset); return true; } else if (this.prefetch) { dataSource.prefetch(pageSkip, pageSize, function () { buffer.offset = offset; buffer._recalculate(); buffer._goToRange(offset, true); }); return false; } return true; }, syncDataSource: function () { var offset = this.offset; this.offset = null; this.range(offset); }, destroy: function () { this.unbind(); }, _prefetch: function () { var buffer = this, pageSize = this.pageSize, prefetchOffset = this.skip + pageSize, dataSource = this.dataSource; if (!dataSource.inRange(prefetchOffset, pageSize) && !this._prefetching && this.prefetch) { this._prefetching = true; this.trigger('prefetching', { skip: prefetchOffset, take: pageSize }); dataSource.prefetch(prefetchOffset, pageSize, function () { buffer._prefetching = false; buffer.trigger('prefetched', { skip: prefetchOffset, take: pageSize }); }); } }, _goToRange: function (offset, expanding) { if (this.offset !== offset) { return; } this.dataOffset = offset; this._expanding = expanding; this.dataSource.range(offset, this.pageSize); this.dataSource.enableRequestsInProgress(); }, _reset: function () { this._syncPending = true; }, _change: function () { var dataSource = this.dataSource; this.length = this.useRanges ? dataSource.lastRange().end : dataSource.view().length; if (this._syncPending) { this._syncWithDataSource(); this._recalculate(); this._syncPending = false; this.trigger('reset', { offset: this.offset }); } this.trigger('resize'); if (this._expanding) { this.trigger('expand'); } delete this._expanding; }, _syncWithDataSource: function () { var dataSource = this.dataSource; this._firstItemUid = dataSource.firstItemUid(); this.dataOffset = this.offset = dataSource.skip() || 0; this.pageSize = dataSource.pageSize(); this.useRanges = dataSource.options.serverPaging; }, _recalculate: function () { var pageSize = this.pageSize, offset = this.offset, viewSize = this.viewSize, skip = Math.ceil(offset / pageSize) * pageSize; this.skip = skip; this.midPageThreshold = skip + pageSize - 1; this.nextPageThreshold = skip + viewSize - 1; this.prefetchThreshold = skip + Math.floor(pageSize / 3 * 2); this.pullBackThreshold = this.offset - 1; this.nextMidRange = skip + pageSize - viewSize; this.nextFullRange = skip; this.previousMidRange = offset - viewSize; this.previousFullRange = skip - pageSize; } }); var BatchBuffer = kendo.Observable.extend({ init: function (dataSource, batchSize) { var batchBuffer = this; kendo.Observable.fn.init.call(batchBuffer); this.dataSource = dataSource; this.batchSize = batchSize; this._total = 0; this.buffer = new Buffer(dataSource, batchSize * 3); this.buffer.bind({ 'endreached': function (e) { batchBuffer.trigger('endreached', { index: e.index }); }, 'prefetching': function (e) { batchBuffer.trigger('prefetching', { skip: e.skip, take: e.take }); }, 'prefetched': function (e) { batchBuffer.trigger('prefetched', { skip: e.skip, take: e.take }); }, 'reset': function () { batchBuffer._total = 0; batchBuffer.trigger('reset'); }, 'resize': function () { batchBuffer._total = Math.ceil(this.length / batchBuffer.batchSize); batchBuffer.trigger('resize', { total: batchBuffer.total(), offset: this.offset }); } }); }, syncDataSource: function () { this.buffer.syncDataSource(); }, at: function (index) { var buffer = this.buffer, skip = index * this.batchSize, take = this.batchSize, view = [], item; if (buffer.offset > skip) { buffer.at(buffer.offset - 1); } for (var i = 0; i < take; i++) { item = buffer.at(skip + i); if (item === null) { break; } view.push(item); } return view; }, total: function () { return this._total; }, destroy: function () { this.buffer.destroy(); this.unbind(); } }); extend(true, kendo.data, { readers: { json: DataReader }, Query: Query, DataSource: DataSource, HierarchicalDataSource: HierarchicalDataSource, Node: Node, ObservableObject: ObservableObject, ObservableArray: ObservableArray, LazyObservableArray: LazyObservableArray, LocalTransport: LocalTransport, RemoteTransport: RemoteTransport, Cache: Cache, DataReader: DataReader, Model: Model, Buffer: Buffer, BatchBuffer: BatchBuffer }); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.calendar', ['kendo.core'], f); }(function () { var __meta__ = { id: 'calendar', name: 'Calendar', category: 'web', description: 'The Calendar widget renders a graphical calendar that supports navigation and selection.', depends: ['core'] }; (function ($, undefined) { var kendo = window.kendo, support = kendo.support, ui = kendo.ui, Widget = ui.Widget, keys = kendo.keys, parse = kendo.parseDate, adjustDST = kendo.date.adjustDST, extractFormat = kendo._extractFormat, template = kendo.template, getCulture = kendo.getCulture, transitions = kendo.support.transitions, transitionOrigin = transitions ? transitions.css + 'transform-origin' : '', cellTemplate = template('<td#=data.cssClass# role="gridcell"><a tabindex="-1" class="k-link" href="\\#" data-#=data.ns#value="#=data.dateString#">#=data.value#</a></td>', { useWithBlock: false }), emptyCellTemplate = template('<td role="gridcell"> </td>', { useWithBlock: false }), browser = kendo.support.browser, isIE8 = browser.msie && browser.version < 9, ns = '.kendoCalendar', CLICK = 'click' + ns, KEYDOWN_NS = 'keydown' + ns, ID = 'id', MIN = 'min', LEFT = 'left', SLIDE = 'slideIn', MONTH = 'month', CENTURY = 'century', CHANGE = 'change', NAVIGATE = 'navigate', VALUE = 'value', HOVER = 'k-state-hover', DISABLED = 'k-state-disabled', FOCUSED = 'k-state-focused', OTHERMONTH = 'k-other-month', OTHERMONTHCLASS = ' class="' + OTHERMONTH + '"', TODAY = 'k-nav-today', CELLSELECTOR = 'td:has(.k-link)', BLUR = 'blur' + ns, FOCUS = 'focus', FOCUS_WITH_NS = FOCUS + ns, MOUSEENTER = support.touch ? 'touchstart' : 'mouseenter', MOUSEENTER_WITH_NS = support.touch ? 'touchstart' + ns : 'mouseenter' + ns, MOUSELEAVE = support.touch ? 'touchend' + ns + ' touchmove' + ns : 'mouseleave' + ns, MS_PER_MINUTE = 60000, MS_PER_DAY = 86400000, PREVARROW = '_prevArrow', NEXTARROW = '_nextArrow', ARIA_DISABLED = 'aria-disabled', ARIA_SELECTED = 'aria-selected', proxy = $.proxy, extend = $.extend, DATE = Date, views = { month: 0, year: 1, decade: 2, century: 3 }; var Calendar = Widget.extend({ init: function (element, options) { var that = this, value, id; Widget.fn.init.call(that, element, options); element = that.wrapper = that.element; options = that.options; options.url = window.unescape(options.url); that.options.disableDates = getDisabledExpr(that.options.disableDates); that._templates(); that._header(); that._footer(that.footer); id = element.addClass('k-widget k-calendar').on(MOUSEENTER_WITH_NS + ' ' + MOUSELEAVE, CELLSELECTOR, mousetoggle).on(KEYDOWN_NS, 'table.k-content', proxy(that._move, that)).on(CLICK, CELLSELECTOR, function (e) { var link = e.currentTarget.firstChild, value = that._toDateObject(link); if (link.href.indexOf('#') != -1) { e.preventDefault(); } if (that.options.disableDates(value) && that._view.name == 'month') { return; } that._click($(link)); }).on('mouseup' + ns, 'table.k-content, .k-footer', function () { that._focusView(that.options.focusOnNav !== false); }).attr(ID); if (id) { that._cellID = id + '_cell_selected'; } normalize(options); value = parse(options.value, options.format, options.culture); that._index = views[options.start]; that._current = new DATE(+restrictValue(value, options.min, options.max)); that._addClassProxy = function () { that._active = true; if (that._cell.hasClass(DISABLED)) { var todayString = that._view.toDateString(getToday()); that._cell = that._cellByDate(todayString); } that._cell.addClass(FOCUSED); }; that._removeClassProxy = function () { that._active = false; that._cell.removeClass(FOCUSED); }; that.value(value); kendo.notify(that); }, options: { name: 'Calendar', value: null, min: new DATE(1900, 0, 1), max: new DATE(2099, 11, 31), dates: [], url: '', culture: '', footer: '', format: '', month: {}, start: MONTH, depth: MONTH, animation: { horizontal: { effects: SLIDE, reverse: true, duration: 500, divisor: 2 }, vertical: { effects: 'zoomIn', duration: 400 } } }, events: [ CHANGE, NAVIGATE ], setOptions: function (options) { var that = this; normalize(options); options.disableDates = getDisabledExpr(options.disableDates); Widget.fn.setOptions.call(that, options); that._templates(); that._footer(that.footer); that._index = views[that.options.start]; that.navigate(); }, destroy: function () { var that = this, today = that._today; that.element.off(ns); that._title.off(ns); that[PREVARROW].off(ns); that[NEXTARROW].off(ns); kendo.destroy(that._table); if (today) { kendo.destroy(today.off(ns)); } Widget.fn.destroy.call(that); }, current: function () { return this._current; }, view: function () { return this._view; }, focus: function (table) { table = table || this._table; this._bindTable(table); table.focus(); }, min: function (value) { return this._option(MIN, value); }, max: function (value) { return this._option('max', value); }, navigateToPast: function () { this._navigate(PREVARROW, -1); }, navigateToFuture: function () { this._navigate(NEXTARROW, 1); }, navigateUp: function () { var that = this, index = that._index; if (that._title.hasClass(DISABLED)) { return; } that.navigate(that._current, ++index); }, navigateDown: function (value) { var that = this, index = that._index, depth = that.options.depth; if (!value) { return; } if (index === views[depth]) { if (!isEqualDate(that._value, that._current) || !isEqualDate(that._value, value)) { that.value(value); that.trigger(CHANGE); } return; } that.navigate(value, --index); }, navigate: function (value, view) { view = isNaN(view) ? views[view] : view; var that = this, options = that.options, culture = options.culture, min = options.min, max = options.max, title = that._title, from = that._table, old = that._oldTable, selectedValue = that._value, currentValue = that._current, future = value && +value > +currentValue, vertical = view !== undefined && view !== that._index, to, currentView, compare, disabled; if (!value) { value = currentValue; } that._current = value = new DATE(+restrictValue(value, min, max)); if (view === undefined) { view = that._index; } else { that._index = view; } that._view = currentView = calendar.views[view]; compare = currentView.compare; disabled = view === views[CENTURY]; title.toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled); disabled = compare(value, min) < 1; that[PREVARROW].toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled); disabled = compare(value, max) > -1; that[NEXTARROW].toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled); if (from && old && old.data('animating')) { old.kendoStop(true, true); from.kendoStop(true, true); } that._oldTable = from; if (!from || that._changeView) { title.html(currentView.title(value, min, max, culture)); that._table = to = $(currentView.content(extend({ min: min, max: max, date: value, url: options.url, dates: options.dates, format: options.format, culture: culture, disableDates: options.disableDates }, that[currentView.name]))); makeUnselectable(to); var replace = from && from.data('start') === to.data('start'); that._animate({ from: from, to: to, vertical: vertical, future: future, replace: replace }); that.trigger(NAVIGATE); that._focus(value); } if (view === views[options.depth] && selectedValue && !that.options.disableDates(selectedValue)) { that._class('k-state-selected', selectedValue); } that._class(FOCUSED, value); if (!from && that._cell) { that._cell.removeClass(FOCUSED); } that._changeView = true; }, value: function (value) { var that = this, view = that._view, options = that.options, old = that._view, min = options.min, max = options.max; if (value === undefined) { return that._value; } if (value === null) { that._current = new Date(that._current.getFullYear(), that._current.getMonth(), that._current.getDate()); } value = parse(value, options.format, options.culture); if (value !== null) { value = new DATE(+value); if (!isInRange(value, min, max)) { value = null; } } if (value === null || !that.options.disableDates(value)) { that._value = value; } else if (that._value === undefined) { that._value = null; } if (old && value === null && that._cell) { that._cell.removeClass('k-state-selected'); } else { that._changeView = !value || view && view.compare(value, that._current) !== 0; that.navigate(value); } }, _move: function (e) { var that = this, options = that.options, key = e.keyCode, view = that._view, index = that._index, min = that.options.min, max = that.options.max, currentValue = new DATE(+that._current), isRtl = kendo.support.isRtl(that.wrapper), isDisabled = that.options.disableDates, value, prevent, method, temp; if (e.target === that._table[0]) { that._active = true; } if (e.ctrlKey) { if (key == keys.RIGHT && !isRtl || key == keys.LEFT && isRtl) { that.navigateToFuture(); prevent = true; } else if (key == keys.LEFT && !isRtl || key == keys.RIGHT && isRtl) { that.navigateToPast(); prevent = true; } else if (key == keys.UP) { that.navigateUp(); prevent = true; } else if (key == keys.DOWN) { that._click($(that._cell[0].firstChild)); prevent = true; } } else { if (key == keys.RIGHT && !isRtl || key == keys.LEFT && isRtl) { value = 1; prevent = true; } else if (key == keys.LEFT && !isRtl || key == keys.RIGHT && isRtl) { value = -1; prevent = true; } else if (key == keys.UP) { value = index === 0 ? -7 : -4; prevent = true; } else if (key == keys.DOWN) { value = index === 0 ? 7 : 4; prevent = true; } else if (key == keys.ENTER) { that._click($(that._cell[0].firstChild)); prevent = true; } else if (key == keys.HOME || key == keys.END) { method = key == keys.HOME ? 'first' : 'last'; temp = view[method](currentValue); currentValue = new DATE(temp.getFullYear(), temp.getMonth(), temp.getDate(), currentValue.getHours(), currentValue.getMinutes(), currentValue.getSeconds(), currentValue.getMilliseconds()); prevent = true; } else if (key == keys.PAGEUP) { prevent = true; that.navigateToPast(); } else if (key == keys.PAGEDOWN) { prevent = true; that.navigateToFuture(); } if (value || method) { if (!method) { view.setDate(currentValue, value); } if (isDisabled(currentValue)) { currentValue = that._nextNavigatable(currentValue, value); } if (isInRange(currentValue, min, max)) { that._focus(restrictValue(currentValue, options.min, options.max)); } } } if (prevent) { e.preventDefault(); } return that._current; }, _nextNavigatable: function (currentValue, value) { var that = this, disabled = true, view = that._view, min = that.options.min, max = that.options.max, isDisabled = that.options.disableDates, navigatableDate = new Date(currentValue.getTime()); view.setDate(navigatableDate, -value); while (disabled) { view.setDate(currentValue, value); if (!isInRange(currentValue, min, max)) { currentValue = navigatableDate; break; } disabled = isDisabled(currentValue); } return currentValue; }, _animate: function (options) { var that = this, from = options.from, to = options.to, active = that._active; if (!from) { to.insertAfter(that.element[0].firstChild); that._bindTable(to); } else if (from.parent().data('animating')) { from.off(ns); from.parent().kendoStop(true, true).remove(); from.remove(); to.insertAfter(that.element[0].firstChild); that._focusView(active); } else if (!from.is(':visible') || that.options.animation === false || options.replace) { to.insertAfter(from); from.off(ns).remove(); that._focusView(active); } else { that[options.vertical ? '_vertical' : '_horizontal'](from, to, options.future); } }, _horizontal: function (from, to, future) { var that = this, active = that._active, horizontal = that.options.animation.horizontal, effects = horizontal.effects, viewWidth = from.outerWidth(); if (effects && effects.indexOf(SLIDE) != -1) { from.add(to).css({ width: viewWidth }); from.wrap('<div/>'); that._focusView(active, from); from.parent().css({ position: 'relative', width: viewWidth * 2, 'float': LEFT, 'margin-left': future ? 0 : -viewWidth }); to[future ? 'insertAfter' : 'insertBefore'](from); extend(horizontal, { effects: SLIDE + ':' + (future ? 'right' : LEFT), complete: function () { from.off(ns).remove(); that._oldTable = null; to.unwrap(); that._focusView(active); } }); from.parent().kendoStop(true, true).kendoAnimate(horizontal); } }, _vertical: function (from, to) { var that = this, vertical = that.options.animation.vertical, effects = vertical.effects, active = that._active, cell, position; if (effects && effects.indexOf('zoom') != -1) { to.css({ position: 'absolute', top: from.prev().outerHeight(), left: 0 }).insertBefore(from); if (transitionOrigin) { cell = that._cellByDate(that._view.toDateString(that._current)); position = cell.position(); position = position.left + parseInt(cell.width() / 2, 10) + 'px' + ' ' + (position.top + parseInt(cell.height() / 2, 10) + 'px'); to.css(transitionOrigin, position); } from.kendoStop(true, true).kendoAnimate({ effects: 'fadeOut', duration: 600, complete: function () { from.off(ns).remove(); that._oldTable = null; to.css({ position: 'static', top: 0, left: 0 }); that._focusView(active); } }); to.kendoStop(true, true).kendoAnimate(vertical); } }, _cellByDate: function (value) { return this._table.find('td:not(.' + OTHERMONTH + ')').filter(function () { return $(this.firstChild).attr(kendo.attr(VALUE)) === value; }); }, _class: function (className, date) { var that = this, id = that._cellID, cell = that._cell, value = that._view.toDateString(date), disabledDate; if (cell) { cell.removeAttr(ARIA_SELECTED).removeAttr('aria-label').removeAttr(ID); } if (date) { disabledDate = that.options.disableDates(date); } cell = that._table.find('td:not(.' + OTHERMONTH + ')').removeClass(className).filter(function () { return $(this.firstChild).attr(kendo.attr(VALUE)) === value; }).attr(ARIA_SELECTED, true); if (className === FOCUSED && !that._active && that.options.focusOnNav !== false || disabledDate) { className = ''; } cell.addClass(className); if (cell[0]) { that._cell = cell; } if (id) { cell.attr(ID, id); that._table.removeAttr('aria-activedescendant').attr('aria-activedescendant', id); } }, _bindTable: function (table) { table.on(FOCUS_WITH_NS, this._addClassProxy).on(BLUR, this._removeClassProxy); }, _click: function (link) { var that = this, options = that.options, currentValue = new Date(+that._current), value = that._toDateObject(link); adjustDST(value, 0); if (that.options.disableDates(value) && that._view.name == 'month') { value = that._value; } that._view.setDate(currentValue, value); that.navigateDown(restrictValue(currentValue, options.min, options.max)); }, _focus: function (value) { var that = this, view = that._view; if (view.compare(value, that._current) !== 0) { that.navigate(value); } else { that._current = value; that._class(FOCUSED, value); } }, _focusView: function (active, table) { if (active) { this.focus(table); } }, _footer: function (template) { var that = this, today = getToday(), element = that.element, footer = element.find('.k-footer'); if (!template) { that._toggle(false); footer.hide(); return; } if (!footer[0]) { footer = $('<div class="k-footer"><a href="#" class="k-link k-nav-today"></a></div>').appendTo(element); } that._today = footer.show().find('.k-link').html(template(today)).attr('title', kendo.toString(today, 'D', that.options.culture)); that._toggle(); }, _header: function () { var that = this, element = that.element, links; if (!element.find('.k-header')[0]) { element.html('<div class="k-header">' + '<a href="#" role="button" class="k-link k-nav-prev"><span class="k-icon k-i-arrow-w"></span></a>' + '<a href="#" role="button" aria-live="assertive" aria-atomic="true" class="k-link k-nav-fast"></a>' + '<a href="#" role="button" class="k-link k-nav-next"><span class="k-icon k-i-arrow-e"></span></a>' + '</div>'); } links = element.find('.k-link').on(MOUSEENTER_WITH_NS + ' ' + MOUSELEAVE + ' ' + FOCUS_WITH_NS + ' ' + BLUR, mousetoggle).click(false); that._title = links.eq(1).on(CLICK, function () { that._active = that.options.focusOnNav !== false; that.navigateUp(); }); that[PREVARROW] = links.eq(0).on(CLICK, function () { that._active = that.options.focusOnNav !== false; that.navigateToPast(); }); that[NEXTARROW] = links.eq(2).on(CLICK, function () { that._active = that.options.focusOnNav !== false; that.navigateToFuture(); }); }, _navigate: function (arrow, modifier) { var that = this, index = that._index + 1, currentValue = new DATE(+that._current); arrow = that[arrow]; if (!arrow.hasClass(DISABLED)) { if (index > 3) { currentValue.setFullYear(currentValue.getFullYear() + 100 * modifier); } else { calendar.views[index].setDate(currentValue, modifier); } that.navigate(currentValue); } }, _option: function (option, value) { var that = this, options = that.options, currentValue = that._value || that._current, isBigger; if (value === undefined) { return options[option]; } value = parse(value, options.format, options.culture); if (!value) { return; } options[option] = new DATE(+value); if (option === MIN) { isBigger = value > currentValue; } else { isBigger = currentValue > value; } if (isBigger || isEqualMonth(currentValue, value)) { if (isBigger) { that._value = null; } that._changeView = true; } if (!that._changeView) { that._changeView = !!(options.month.content || options.month.empty); } that.navigate(that._value); that._toggle(); }, _toggle: function (toggle) { var that = this, options = that.options, isTodayDisabled = that.options.disableDates(getToday()), link = that._today; if (toggle === undefined) { toggle = isInRange(getToday(), options.min, options.max); } if (link) { link.off(CLICK); if (toggle && !isTodayDisabled) { link.addClass(TODAY).removeClass(DISABLED).on(CLICK, proxy(that._todayClick, that)); } else { link.removeClass(TODAY).addClass(DISABLED).on(CLICK, prevent); } } }, _todayClick: function (e) { var that = this, depth = views[that.options.depth], disabled = that.options.disableDates, today = getToday(); e.preventDefault(); if (disabled(today)) { return; } if (that._view.compare(that._current, today) === 0 && that._index == depth) { that._changeView = false; } that._value = today; that.navigate(today, depth); that.trigger(CHANGE); }, _toDateObject: function (link) { var value = $(link).attr(kendo.attr(VALUE)).split('/'); value = new DATE(value[0], value[1], value[2]); return value; }, _templates: function () { var that = this, options = that.options, footer = options.footer, month = options.month, content = month.content, empty = month.empty; that.month = { content: template('<td#=data.cssClass# role="gridcell"><a tabindex="-1" class="k-link#=data.linkClass#" href="#=data.url#" ' + kendo.attr('value') + '="#=data.dateString#" title="#=data.title#">' + (content || '#=data.value#') + '</a></td>', { useWithBlock: !!content }), empty: template('<td role="gridcell">' + (empty || ' ') + '</td>', { useWithBlock: !!empty }) }; that.footer = footer !== false ? template(footer || '#= kendo.toString(data,"D","' + options.culture + '") #', { useWithBlock: false }) : null; } }); ui.plugin(Calendar); var calendar = { firstDayOfMonth: function (date) { return new DATE(date.getFullYear(), date.getMonth(), 1); }, firstVisibleDay: function (date, calendarInfo) { calendarInfo = calendarInfo || kendo.culture().calendar; var firstDay = calendarInfo.firstDay, firstVisibleDay = new DATE(date.getFullYear(), date.getMonth(), 0, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); while (firstVisibleDay.getDay() != firstDay) { calendar.setTime(firstVisibleDay, -1 * MS_PER_DAY); } return firstVisibleDay; }, setTime: function (date, time) { var tzOffsetBefore = date.getTimezoneOffset(), resultDATE = new DATE(date.getTime() + time), tzOffsetDiff = resultDATE.getTimezoneOffset() - tzOffsetBefore; date.setTime(resultDATE.getTime() + tzOffsetDiff * MS_PER_MINUTE); }, views: [ { name: MONTH, title: function (date, min, max, culture) { return getCalendarInfo(culture).months.names[date.getMonth()] + ' ' + date.getFullYear(); }, content: function (options) { var that = this, idx = 0, min = options.min, max = options.max, date = options.date, dates = options.dates, format = options.format, culture = options.culture, navigateUrl = options.url, hasUrl = navigateUrl && dates[0], currentCalendar = getCalendarInfo(culture), firstDayIdx = currentCalendar.firstDay, days = currentCalendar.days, names = shiftArray(days.names, firstDayIdx), shortNames = shiftArray(days.namesShort, firstDayIdx), start = calendar.firstVisibleDay(date, currentCalendar), firstDayOfMonth = that.first(date), lastDayOfMonth = that.last(date), toDateString = that.toDateString, today = new DATE(), html = '<table tabindex="0" role="grid" class="k-content" cellspacing="0" data-start="' + toDateString(start) + '"><thead><tr role="row">'; for (; idx < 7; idx++) { html += '<th scope="col" title="' + names[idx] + '">' + shortNames[idx] + '</th>'; } today = new DATE(today.getFullYear(), today.getMonth(), today.getDate()); adjustDST(today, 0); today = +today; return view({ cells: 42, perRow: 7, html: html += '</tr></thead><tbody><tr role="row">', start: start, min: new DATE(min.getFullYear(), min.getMonth(), min.getDate()), max: new DATE(max.getFullYear(), max.getMonth(), max.getDate()), content: options.content, empty: options.empty, setter: that.setDate, disableDates: options.disableDates, build: function (date, idx, disableDates) { var cssClass = [], day = date.getDay(), linkClass = '', url = '#'; if (date < firstDayOfMonth || date > lastDayOfMonth) { cssClass.push(OTHERMONTH); } if (disableDates(date)) { cssClass.push(DISABLED); } if (+date === today) { cssClass.push('k-today'); } if (day === 0 || day === 6) { cssClass.push('k-weekend'); } if (hasUrl && inArray(+date, dates)) { url = navigateUrl.replace('{0}', kendo.toString(date, format, culture)); linkClass = ' k-action-link'; } return { date: date, dates: dates, ns: kendo.ns, title: kendo.toString(date, 'D', culture), value: date.getDate(), dateString: toDateString(date), cssClass: cssClass[0] ? ' class="' + cssClass.join(' ') + '"' : '', linkClass: linkClass, url: url }; } }); }, first: function (date) { return calendar.firstDayOfMonth(date); }, last: function (date) { var last = new DATE(date.getFullYear(), date.getMonth() + 1, 0), first = calendar.firstDayOfMonth(date), timeOffset = Math.abs(last.getTimezoneOffset() - first.getTimezoneOffset()); if (timeOffset) { last.setHours(first.getHours() + timeOffset / 60); } return last; }, compare: function (date1, date2) { var result, month1 = date1.getMonth(), year1 = date1.getFullYear(), month2 = date2.getMonth(), year2 = date2.getFullYear(); if (year1 > year2) { result = 1; } else if (year1 < year2) { result = -1; } else { result = month1 == month2 ? 0 : month1 > month2 ? 1 : -1; } return result; }, setDate: function (date, value) { var hours = date.getHours(); if (value instanceof DATE) { date.setFullYear(value.getFullYear(), value.getMonth(), value.getDate()); } else { calendar.setTime(date, value * MS_PER_DAY); } adjustDST(date, hours); }, toDateString: function (date) { return date.getFullYear() + '/' + date.getMonth() + '/' + date.getDate(); } }, { name: 'year', title: function (date) { return date.getFullYear(); }, content: function (options) { var namesAbbr = getCalendarInfo(options.culture).months.namesAbbr, toDateString = this.toDateString, min = options.min, max = options.max; return view({ min: new DATE(min.getFullYear(), min.getMonth(), 1), max: new DATE(max.getFullYear(), max.getMonth(), 1), start: new DATE(options.date.getFullYear(), 0, 1), setter: this.setDate, build: function (date) { return { value: namesAbbr[date.getMonth()], ns: kendo.ns, dateString: toDateString(date), cssClass: '' }; } }); }, first: function (date) { return new DATE(date.getFullYear(), 0, date.getDate()); }, last: function (date) { return new DATE(date.getFullYear(), 11, date.getDate()); }, compare: function (date1, date2) { return compare(date1, date2); }, setDate: function (date, value) { var month, hours = date.getHours(); if (value instanceof DATE) { month = value.getMonth(); date.setFullYear(value.getFullYear(), month, date.getDate()); if (month !== date.getMonth()) { date.setDate(0); } } else { month = date.getMonth() + value; date.setMonth(month); if (month > 11) { month -= 12; } if (month > 0 && date.getMonth() != month) { date.setDate(0); } } adjustDST(date, hours); }, toDateString: function (date) { return date.getFullYear() + '/' + date.getMonth() + '/1'; } }, { name: 'decade', title: function (date, min, max) { return title(date, min, max, 10); }, content: function (options) { var year = options.date.getFullYear(), toDateString = this.toDateString; return view({ start: new DATE(year - year % 10 - 1, 0, 1), min: new DATE(options.min.getFullYear(), 0, 1), max: new DATE(options.max.getFullYear(), 0, 1), setter: this.setDate, build: function (date, idx) { return { value: date.getFullYear(), ns: kendo.ns, dateString: toDateString(date), cssClass: idx === 0 || idx == 11 ? OTHERMONTHCLASS : '' }; } }); }, first: function (date) { var year = date.getFullYear(); return new DATE(year - year % 10, date.getMonth(), date.getDate()); }, last: function (date) { var year = date.getFullYear(); return new DATE(year - year % 10 + 9, date.getMonth(), date.getDate()); }, compare: function (date1, date2) { return compare(date1, date2, 10); }, setDate: function (date, value) { setDate(date, value, 1); }, toDateString: function (date) { return date.getFullYear() + '/0/1'; } }, { name: CENTURY, title: function (date, min, max) { return title(date, min, max, 100); }, content: function (options) { var year = options.date.getFullYear(), min = options.min.getFullYear(), max = options.max.getFullYear(), toDateString = this.toDateString, minYear = min, maxYear = max; minYear = minYear - minYear % 10; maxYear = maxYear - maxYear % 10; if (maxYear - minYear < 10) { maxYear = minYear + 9; } return view({ start: new DATE(year - year % 100 - 10, 0, 1), min: new DATE(minYear, 0, 1), max: new DATE(maxYear, 0, 1), setter: this.setDate, build: function (date, idx) { var start = date.getFullYear(), end = start + 9; if (start < min) { start = min; } if (end > max) { end = max; } return { ns: kendo.ns, value: start + ' - ' + end, dateString: toDateString(date), cssClass: idx === 0 || idx == 11 ? OTHERMONTHCLASS : '' }; } }); }, first: function (date) { var year = date.getFullYear(); return new DATE(year - year % 100, date.getMonth(), date.getDate()); }, last: function (date) { var year = date.getFullYear(); return new DATE(year - year % 100 + 99, date.getMonth(), date.getDate()); }, compare: function (date1, date2) { return compare(date1, date2, 100); }, setDate: function (date, value) { setDate(date, value, 10); }, toDateString: function (date) { var year = date.getFullYear(); return year - year % 10 + '/0/1'; } } ] }; function title(date, min, max, modular) { var start = date.getFullYear(), minYear = min.getFullYear(), maxYear = max.getFullYear(), end; start = start - start % modular; end = start + (modular - 1); if (start < minYear) { start = minYear; } if (end > maxYear) { end = maxYear; } return start + '-' + end; } function view(options) { var idx = 0, data, min = options.min, max = options.max, start = options.start, setter = options.setter, build = options.build, length = options.cells || 12, cellsPerRow = options.perRow || 4, content = options.content || cellTemplate, empty = options.empty || emptyCellTemplate, html = options.html || '<table tabindex="0" role="grid" class="k-content k-meta-view" cellspacing="0"><tbody><tr role="row">'; for (; idx < length; idx++) { if (idx > 0 && idx % cellsPerRow === 0) { html += '</tr><tr role="row">'; } start = new DATE(start.getFullYear(), start.getMonth(), start.getDate(), 0, 0, 0); adjustDST(start, 0); data = build(start, idx, options.disableDates); html += isInRange(start, min, max) ? content(data) : empty(data); setter(start, 1); } return html + '</tr></tbody></table>'; } function compare(date1, date2, modifier) { var year1 = date1.getFullYear(), start = date2.getFullYear(), end = start, result = 0; if (modifier) { start = start - start % modifier; end = start - start % modifier + modifier - 1; } if (year1 > end) { result = 1; } else if (year1 < start) { result = -1; } return result; } function getToday() { var today = new DATE(); return new DATE(today.getFullYear(), today.getMonth(), today.getDate()); } function restrictValue(value, min, max) { var today = getToday(); if (value) { today = new DATE(+value); } if (min > today) { today = new DATE(+min); } else if (max < today) { today = new DATE(+max); } return today; } function isInRange(date, min, max) { return +date >= +min && +date <= +max; } function shiftArray(array, idx) { return array.slice(idx).concat(array.slice(0, idx)); } function setDate(date, value, multiplier) { value = value instanceof DATE ? value.getFullYear() : date.getFullYear() + multiplier * value; date.setFullYear(value); } function mousetoggle(e) { var disabled = $(this).hasClass('k-state-disabled'); if (!disabled) { $(this).toggleClass(HOVER, MOUSEENTER.indexOf(e.type) > -1 || e.type == FOCUS); } } function prevent(e) { e.preventDefault(); } function getCalendarInfo(culture) { return getCulture(culture).calendars.standard; } function normalize(options) { var start = views[options.start], depth = views[options.depth], culture = getCulture(options.culture); options.format = extractFormat(options.format || culture.calendars.standard.patterns.d); if (isNaN(start)) { start = 0; options.start = MONTH; } if (depth === undefined || depth > start) { options.depth = MONTH; } if (options.dates === null) { options.dates = []; } } function makeUnselectable(element) { if (isIE8) { element.find('*').attr('unselectable', 'on'); } } function inArray(date, dates) { for (var i = 0, length = dates.length; i < length; i++) { if (date === +dates[i]) { return true; } } return false; } function isEqualDatePart(value1, value2) { if (value1) { return value1.getFullYear() === value2.getFullYear() && value1.getMonth() === value2.getMonth() && value1.getDate() === value2.getDate(); } return false; } function isEqualMonth(value1, value2) { if (value1) { return value1.getFullYear() === value2.getFullYear() && value1.getMonth() === value2.getMonth(); } return false; } function getDisabledExpr(option) { if (kendo.isFunction(option)) { return option; } if ($.isArray(option)) { return createDisabledExpr(option); } return $.noop; } function convertDatesArray(dates) { var result = []; for (var i = 0; i < dates.length; i++) { result.push(dates[i].setHours(0, 0, 0, 0)); } return result; } function createDisabledExpr(dates) { var body, callback, disabledDates = [], days = [ 'su', 'mo', 'tu', 'we', 'th', 'fr', 'sa' ], searchExpression = 'if (found) {' + ' return true ' + '} else {' + 'return false' + '}'; if (dates[0] instanceof DATE) { disabledDates = convertDatesArray(dates); body = 'var found = date && $.inArray(date.setHours(0, 0, 0, 0),[' + disabledDates + ']) > -1;' + searchExpression; } else { for (var i = 0; i < dates.length; i++) { var day = dates[i].slice(0, 2).toLowerCase(); var index = $.inArray(day, days); if (index > -1) { disabledDates.push(index); } } body = 'var found = date && $.inArray(date.getDay(),[' + disabledDates + ']) > -1;' + searchExpression; } callback = new Function('date', body); return callback; } function isEqualDate(oldValue, newValue) { if (oldValue instanceof Date && newValue instanceof Date) { oldValue = oldValue.getTime(); newValue = newValue.getTime(); } return oldValue === newValue; } calendar.isEqualDatePart = isEqualDatePart; calendar.makeUnselectable = makeUnselectable; calendar.restrictValue = restrictValue; calendar.isInRange = isInRange; calendar.normalize = normalize; calendar.viewsEnum = views; calendar.disabled = getDisabledExpr; kendo.calendar = calendar; }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.popup', ['kendo.core'], f); }(function () { var __meta__ = { id: 'popup', name: 'Pop-up', category: 'framework', depends: ['core'], advanced: true }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, support = kendo.support, getOffset = kendo.getOffset, OPEN = 'open', CLOSE = 'close', DEACTIVATE = 'deactivate', ACTIVATE = 'activate', CENTER = 'center', LEFT = 'left', RIGHT = 'right', TOP = 'top', BOTTOM = 'bottom', ABSOLUTE = 'absolute', HIDDEN = 'hidden', BODY = 'body', LOCATION = 'location', POSITION = 'position', VISIBLE = 'visible', EFFECTS = 'effects', ACTIVE = 'k-state-active', ACTIVEBORDER = 'k-state-border', ACTIVEBORDERREGEXP = /k-state-border-(\w+)/, ACTIVECHILDREN = '.k-picker-wrap, .k-dropdown-wrap, .k-link', MOUSEDOWN = 'down', DOCUMENT_ELEMENT = $(document.documentElement), WINDOW = $(window), SCROLL = 'scroll', cssPrefix = support.transitions.css, TRANSFORM = cssPrefix + 'transform', extend = $.extend, NS = '.kendoPopup', styles = [ 'font-size', 'font-family', 'font-stretch', 'font-style', 'font-weight', 'line-height' ]; function contains(container, target) { return container === target || $.contains(container, target); } var Popup = Widget.extend({ init: function (element, options) { var that = this, parentPopup; options = options || {}; if (options.isRtl) { options.origin = options.origin || BOTTOM + ' ' + RIGHT; options.position = options.position || TOP + ' ' + RIGHT; } Widget.fn.init.call(that, element, options); element = that.element; options = that.options; that.collisions = options.collision ? options.collision.split(' ') : []; that.downEvent = kendo.applyEventMap(MOUSEDOWN, kendo.guid()); if (that.collisions.length === 1) { that.collisions.push(that.collisions[0]); } parentPopup = $(that.options.anchor).closest('.k-popup,.k-group').filter(':not([class^=km-])'); options.appendTo = $($(options.appendTo)[0] || parentPopup[0] || BODY); that.element.hide().addClass('k-popup k-group k-reset').toggleClass('k-rtl', !!options.isRtl).css({ position: ABSOLUTE }).appendTo(options.appendTo).on('mouseenter' + NS, function () { that._hovered = true; }).on('mouseleave' + NS, function () { that._hovered = false; }); that.wrapper = $(); if (options.animation === false) { options.animation = { open: { effects: {} }, close: { hide: true, effects: {} } }; } extend(options.animation.open, { complete: function () { that.wrapper.css({ overflow: VISIBLE }); that._activated = true; that._trigger(ACTIVATE); } }); extend(options.animation.close, { complete: function () { that._animationClose(); } }); that._mousedownProxy = function (e) { that._mousedown(e); }; if (support.mobileOS.android) { that._resizeProxy = function (e) { setTimeout(function () { that._resize(e); }, 600); }; } else { that._resizeProxy = function (e) { that._resize(e); }; } if (options.toggleTarget) { $(options.toggleTarget).on(options.toggleEvent + NS, $.proxy(that.toggle, that)); } }, events: [ OPEN, ACTIVATE, CLOSE, DEACTIVATE ], options: { name: 'Popup', toggleEvent: 'click', origin: BOTTOM + ' ' + LEFT, position: TOP + ' ' + LEFT, anchor: BODY, appendTo: null, collision: 'flip fit', viewport: window, copyAnchorStyles: true, autosize: false, modal: false, adjustSize: { width: 0, height: 0 }, animation: { open: { effects: 'slideIn:down', transition: true, duration: 200 }, close: { duration: 100, hide: true } } }, _animationClose: function () { var that = this; var location = that.wrapper.data(LOCATION); that.wrapper.hide(); if (location) { that.wrapper.css(location); } if (that.options.anchor != BODY) { that._hideDirClass(); } that._closing = false; that._trigger(DEACTIVATE); }, destroy: function () { var that = this, options = that.options, element = that.element.off(NS), parent; Widget.fn.destroy.call(that); if (options.toggleTarget) { $(options.toggleTarget).off(NS); } if (!options.modal) { DOCUMENT_ELEMENT.unbind(that.downEvent, that._mousedownProxy); that._toggleResize(false); } kendo.destroy(that.element.children()); element.removeData(); if (options.appendTo[0] === document.body) { parent = element.parent('.k-animation-container'); if (parent[0]) { parent.remove(); } else { element.remove(); } } }, open: function (x, y) { var that = this, fixed = { isFixed: !isNaN(parseInt(y, 10)), x: x, y: y }, element = that.element, options = that.options, animation, wrapper, anchor = $(options.anchor), mobile = element[0] && element.hasClass('km-widget'); if (!that.visible()) { if (options.copyAnchorStyles) { if (mobile && styles[0] == 'font-size') { styles.shift(); } element.css(kendo.getComputedStyles(anchor[0], styles)); } if (element.data('animating') || that._trigger(OPEN)) { return; } that._activated = false; if (!options.modal) { DOCUMENT_ELEMENT.unbind(that.downEvent, that._mousedownProxy).bind(that.downEvent, that._mousedownProxy); that._toggleResize(false); that._toggleResize(true); } that.wrapper = wrapper = kendo.wrap(element, options.autosize).css({ overflow: HIDDEN, display: 'block', position: ABSOLUTE }); if (support.mobileOS.android) { wrapper.css(TRANSFORM, 'translatez(0)'); } wrapper.css(POSITION); if ($(options.appendTo)[0] == document.body) { wrapper.css(TOP, '-10000px'); } that.flipped = that._position(fixed); animation = that._openAnimation(); if (options.anchor != BODY) { that._showDirClass(animation); } element.data(EFFECTS, animation.effects).kendoStop(true).kendoAnimate(animation); } }, _openAnimation: function () { var animation = extend(true, {}, this.options.animation.open); animation.effects = kendo.parseEffects(animation.effects, this.flipped); return animation; }, _hideDirClass: function () { var anchor = $(this.options.anchor); var direction = ((anchor.attr('class') || '').match(ACTIVEBORDERREGEXP) || [ '', 'down' ])[1]; var dirClass = ACTIVEBORDER + '-' + direction; anchor.removeClass(dirClass).children(ACTIVECHILDREN).removeClass(ACTIVE).removeClass(dirClass); this.element.removeClass(ACTIVEBORDER + '-' + kendo.directions[direction].reverse); }, _showDirClass: function (animation) { var direction = animation.effects.slideIn ? animation.effects.slideIn.direction : 'down'; var dirClass = ACTIVEBORDER + '-' + direction; $(this.options.anchor).addClass(dirClass).children(ACTIVECHILDREN).addClass(ACTIVE).addClass(dirClass); this.element.addClass(ACTIVEBORDER + '-' + kendo.directions[direction].reverse); }, position: function () { if (this.visible()) { this.flipped = this._position(); } }, toggle: function () { var that = this; that[that.visible() ? CLOSE : OPEN](); }, visible: function () { return this.element.is(':' + VISIBLE); }, close: function (skipEffects) { var that = this, options = that.options, wrap, animation, openEffects, closeEffects; if (that.visible()) { wrap = that.wrapper[0] ? that.wrapper : kendo.wrap(that.element).hide(); that._toggleResize(false); if (that._closing || that._trigger(CLOSE)) { that._toggleResize(true); return; } that.element.find('.k-popup').each(function () { var that = $(this), popup = that.data('kendoPopup'); if (popup) { popup.close(skipEffects); } }); DOCUMENT_ELEMENT.unbind(that.downEvent, that._mousedownProxy); if (skipEffects) { animation = { hide: true, effects: {} }; } else { animation = extend(true, {}, options.animation.close); openEffects = that.element.data(EFFECTS); closeEffects = animation.effects; if (!closeEffects && !kendo.size(closeEffects) && openEffects && kendo.size(openEffects)) { animation.effects = openEffects; animation.reverse = true; } that._closing = true; } that.element.kendoStop(true); wrap.css({ overflow: HIDDEN }); that.element.kendoAnimate(animation); if (skipEffects) { that._animationClose(); } } }, _trigger: function (ev) { return this.trigger(ev, { type: ev }); }, _resize: function (e) { var that = this; if (support.resize.indexOf(e.type) !== -1) { clearTimeout(that._resizeTimeout); that._resizeTimeout = setTimeout(function () { that._position(); that._resizeTimeout = null; }, 50); } else { if (!that._hovered || that._activated && that.element.hasClass('k-list-container')) { that.close(); } } }, _toggleResize: function (toggle) { var method = toggle ? 'on' : 'off'; var eventNames = support.resize; if (!(support.mobileOS.ios || support.mobileOS.android)) { eventNames += ' ' + SCROLL; } this._scrollableParents()[method](SCROLL, this._resizeProxy); WINDOW[method](eventNames, this._resizeProxy); }, _mousedown: function (e) { var that = this, container = that.element[0], options = that.options, anchor = $(options.anchor)[0], toggleTarget = options.toggleTarget, target = kendo.eventTarget(e), popup = $(target).closest('.k-popup'), mobile = popup.parent().parent('.km-shim').length; popup = popup[0]; if (!mobile && popup && popup !== that.element[0]) { return; } if ($(e.target).closest('a').data('rel') === 'popover') { return; } if (!contains(container, target) && !contains(anchor, target) && !(toggleTarget && contains($(toggleTarget)[0], target))) { that.close(); } }, _fit: function (position, size, viewPortSize) { var output = 0; if (position + size > viewPortSize) { output = viewPortSize - (position + size); } if (position < 0) { output = -position; } return output; }, _flip: function (offset, size, anchorSize, viewPortSize, origin, position, boxSize) { var output = 0; boxSize = boxSize || size; if (position !== origin && position !== CENTER && origin !== CENTER) { if (offset + boxSize > viewPortSize) { output += -(anchorSize + size); } if (offset + output < 0) { output += anchorSize + size; } } return output; }, _scrollableParents: function () { return $(this.options.anchor).parentsUntil('body').filter(function (index, element) { return kendo.isScrollable(element); }); }, _position: function (fixed) { var that = this, element = that.element, wrapper = that.wrapper, options = that.options, viewport = $(options.viewport), zoomLevel = support.zoomLevel(), isWindow = !!(viewport[0] == window && window.innerWidth && zoomLevel <= 1.02), anchor = $(options.anchor), origins = options.origin.toLowerCase().split(' '), positions = options.position.toLowerCase().split(' '), collisions = that.collisions, siblingContainer, parents, parentZIndex, zIndex = 10002, idx = 0, docEl = document.documentElement, length, viewportOffset, viewportWidth, viewportHeight; if (isWindow) { viewportWidth = window.innerWidth; viewportHeight = window.innerHeight; viewportOffset = { top: window.pageYOffset || document.documentElement.scrollTop || 0, left: window.pageXOffset || document.documentElement.scrollLeft || 0 }; } else { viewportWidth = viewport.width(); viewportHeight = viewport.height(); viewportOffset = viewport.offset(); } if (isWindow && docEl.scrollHeight - docEl.clientHeight > 0) { viewportWidth -= kendo.support.scrollbar(); } siblingContainer = anchor.parents().filter(wrapper.siblings()); if (siblingContainer[0]) { parentZIndex = Math.max(Number(siblingContainer.css('zIndex')), 0); if (parentZIndex) { zIndex = parentZIndex + 10; } else { parents = anchor.parentsUntil(siblingContainer); for (length = parents.length; idx < length; idx++) { parentZIndex = Number($(parents[idx]).css('zIndex')); if (parentZIndex && zIndex < parentZIndex) { zIndex = parentZIndex + 10; } } } } wrapper.css('zIndex', zIndex); if (fixed && fixed.isFixed) { wrapper.css({ left: fixed.x, top: fixed.y }); } else { wrapper.css(that._align(origins, positions)); } var pos = getOffset(wrapper, POSITION, anchor[0] === wrapper.offsetParent()[0]), offset = getOffset(wrapper), anchorParent = anchor.offsetParent().parent('.k-animation-container,.k-popup,.k-group'); if (anchorParent.length) { pos = getOffset(wrapper, POSITION, true); offset = getOffset(wrapper); } offset.top -= viewportOffset.top; offset.left -= viewportOffset.left; if (!that.wrapper.data(LOCATION)) { wrapper.data(LOCATION, extend({}, pos)); } var offsets = extend({}, offset), location = extend({}, pos), adjustSize = options.adjustSize; if (collisions[0] === 'fit') { location.top += that._fit(offsets.top, wrapper.outerHeight() + adjustSize.height, viewportHeight / zoomLevel); } if (collisions[1] === 'fit') { location.left += that._fit(offsets.left, wrapper.outerWidth() + adjustSize.width, viewportWidth / zoomLevel); } var flipPos = extend({}, location); var elementHeight = element.outerHeight(); var wrapperHeight = wrapper.outerHeight(); if (!wrapper.height() && elementHeight) { wrapperHeight = wrapperHeight + elementHeight; } if (collisions[0] === 'flip') { location.top += that._flip(offsets.top, elementHeight, anchor.outerHeight(), viewportHeight / zoomLevel, origins[0], positions[0], wrapperHeight); } if (collisions[1] === 'flip') { location.left += that._flip(offsets.left, element.outerWidth(), anchor.outerWidth(), viewportWidth / zoomLevel, origins[1], positions[1], wrapper.outerWidth()); } element.css(POSITION, ABSOLUTE); wrapper.css(location); return location.left != flipPos.left || location.top != flipPos.top; }, _align: function (origin, position) { var that = this, element = that.wrapper, anchor = $(that.options.anchor), verticalOrigin = origin[0], horizontalOrigin = origin[1], verticalPosition = position[0], horizontalPosition = position[1], anchorOffset = getOffset(anchor), appendTo = $(that.options.appendTo), appendToOffset, width = element.outerWidth(), height = element.outerHeight(), anchorWidth = anchor.outerWidth(), anchorHeight = anchor.outerHeight(), top = anchorOffset.top, left = anchorOffset.left, round = Math.round; if (appendTo[0] != document.body) { appendToOffset = getOffset(appendTo); top -= appendToOffset.top; left -= appendToOffset.left; } if (verticalOrigin === BOTTOM) { top += anchorHeight; } if (verticalOrigin === CENTER) { top += round(anchorHeight / 2); } if (verticalPosition === BOTTOM) { top -= height; } if (verticalPosition === CENTER) { top -= round(height / 2); } if (horizontalOrigin === RIGHT) { left += anchorWidth; } if (horizontalOrigin === CENTER) { left += round(anchorWidth / 2); } if (horizontalPosition === RIGHT) { left -= width; } if (horizontalPosition === CENTER) { left -= round(width / 2); } return { top: top, left: left }; } }); ui.plugin(Popup); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.datepicker', [ 'kendo.calendar', 'kendo.popup' ], f); }(function () { var __meta__ = { id: 'datepicker', name: 'DatePicker', category: 'web', description: 'The DatePicker widget allows the user to select a date from a calendar or by direct input.', depends: [ 'calendar', 'popup' ] }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, parse = kendo.parseDate, keys = kendo.keys, template = kendo.template, activeElement = kendo._activeElement, DIV = '<div />', SPAN = '<span />', ns = '.kendoDatePicker', CLICK = 'click' + ns, OPEN = 'open', CLOSE = 'close', CHANGE = 'change', DISABLED = 'disabled', READONLY = 'readonly', DEFAULT = 'k-state-default', FOCUSED = 'k-state-focused', SELECTED = 'k-state-selected', STATEDISABLED = 'k-state-disabled', HOVER = 'k-state-hover', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, MOUSEDOWN = 'mousedown' + ns, ID = 'id', MIN = 'min', MAX = 'max', MONTH = 'month', ARIA_DISABLED = 'aria-disabled', ARIA_EXPANDED = 'aria-expanded', ARIA_HIDDEN = 'aria-hidden', calendar = kendo.calendar, isInRange = calendar.isInRange, restrictValue = calendar.restrictValue, isEqualDatePart = calendar.isEqualDatePart, extend = $.extend, proxy = $.proxy, DATE = Date; function normalize(options) { var parseFormats = options.parseFormats, format = options.format; calendar.normalize(options); parseFormats = $.isArray(parseFormats) ? parseFormats : [parseFormats]; if (!parseFormats.length) { parseFormats.push('yyyy-MM-dd'); } if ($.inArray(format, parseFormats) === -1) { parseFormats.splice(0, 0, options.format); } options.parseFormats = parseFormats; } function preventDefault(e) { e.preventDefault(); } var DateView = function (options) { var that = this, id, body = document.body, div = $(DIV).attr(ARIA_HIDDEN, 'true').addClass('k-calendar-container').appendTo(body); that.options = options = options || {}; id = options.id; if (id) { id += '_dateview'; div.attr(ID, id); that._dateViewID = id; } that.popup = new ui.Popup(div, extend(options.popup, options, { name: 'Popup', isRtl: kendo.support.isRtl(options.anchor) })); that.div = div; that.value(options.value); }; DateView.prototype = { _calendar: function () { var that = this; var calendar = that.calendar; var options = that.options; var div; if (!calendar) { div = $(DIV).attr(ID, kendo.guid()).appendTo(that.popup.element).on(MOUSEDOWN, preventDefault).on(CLICK, 'td:has(.k-link)', proxy(that._click, that)); that.calendar = calendar = new ui.Calendar(div); that._setOptions(options); kendo.calendar.makeUnselectable(calendar.element); calendar.navigate(that._value || that._current, options.start); that.value(that._value); } }, _setOptions: function (options) { this.calendar.setOptions({ focusOnNav: false, change: options.change, culture: options.culture, dates: options.dates, depth: options.depth, footer: options.footer, format: options.format, max: options.max, min: options.min, month: options.month, start: options.start, disableDates: options.disableDates }); }, setOptions: function (options) { var old = this.options; var disableDates = options.disableDates; if (disableDates) { options.disableDates = calendar.disabled(disableDates); } this.options = extend(old, options, { change: old.change, close: old.close, open: old.open }); if (this.calendar) { this._setOptions(this.options); } }, destroy: function () { this.popup.destroy(); }, open: function () { var that = this; that._calendar(); that.popup.open(); }, close: function () { this.popup.close(); }, min: function (value) { this._option(MIN, value); }, max: function (value) { this._option(MAX, value); }, toggle: function () { var that = this; that[that.popup.visible() ? CLOSE : OPEN](); }, move: function (e) { var that = this, key = e.keyCode, calendar = that.calendar, selectIsClicked = e.ctrlKey && key == keys.DOWN || key == keys.ENTER, handled = false; if (e.altKey) { if (key == keys.DOWN) { that.open(); e.preventDefault(); handled = true; } else if (key == keys.UP) { that.close(); e.preventDefault(); handled = true; } } else if (that.popup.visible()) { if (key == keys.ESC || selectIsClicked && calendar._cell.hasClass(SELECTED)) { that.close(); e.preventDefault(); return true; } that._current = calendar._move(e); handled = true; } return handled; }, current: function (date) { this._current = date; this.calendar._focus(date); }, value: function (value) { var that = this, calendar = that.calendar, options = that.options, disabledDate = options.disableDates; if (disabledDate && disabledDate(value)) { value = null; } that._value = value; that._current = new DATE(+restrictValue(value, options.min, options.max)); if (calendar) { calendar.value(value); } }, _click: function (e) { if (e.currentTarget.className.indexOf(SELECTED) !== -1) { this.close(); } }, _option: function (option, value) { var that = this; var calendar = that.calendar; that.options[option] = value; if (calendar) { calendar[option](value); } } }; DateView.normalize = normalize; kendo.DateView = DateView; var DatePicker = Widget.extend({ init: function (element, options) { var that = this, disabled, div; Widget.fn.init.call(that, element, options); element = that.element; options = that.options; options.disableDates = kendo.calendar.disabled(options.disableDates); options.min = parse(element.attr('min')) || parse(options.min); options.max = parse(element.attr('max')) || parse(options.max); normalize(options); that._initialOptions = extend({}, options); that._wrapper(); that.dateView = new DateView(extend({}, options, { id: element.attr(ID), anchor: that.wrapper, change: function () { that._change(this.value()); that.close(); }, close: function (e) { if (that.trigger(CLOSE)) { e.preventDefault(); } else { element.attr(ARIA_EXPANDED, false); div.attr(ARIA_HIDDEN, true); } }, open: function (e) { var options = that.options, date; if (that.trigger(OPEN)) { e.preventDefault(); } else { if (that.element.val() !== that._oldText) { date = parse(element.val(), options.parseFormats, options.culture); that.dateView[date ? 'current' : 'value'](date); } element.attr(ARIA_EXPANDED, true); div.attr(ARIA_HIDDEN, false); that._updateARIA(date); } } })); div = that.dateView.div; that._icon(); try { element[0].setAttribute('type', 'text'); } catch (e) { element[0].type = 'text'; } element.addClass('k-input').attr({ role: 'combobox', 'aria-expanded': false, 'aria-owns': that.dateView._dateViewID }); that._reset(); that._template(); disabled = element.is('[disabled]') || $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } else { that.readonly(element.is('[readonly]')); } that._old = that._update(options.value || that.element.val()); that._oldText = element.val(); kendo.notify(that); }, events: [ OPEN, CLOSE, CHANGE ], options: { name: 'DatePicker', value: null, footer: '', format: '', culture: '', parseFormats: [], min: new Date(1900, 0, 1), max: new Date(2099, 11, 31), start: MONTH, depth: MONTH, animation: {}, month: {}, dates: [], ARIATemplate: 'Current focused date is #=kendo.toString(data.current, "D")#' }, setOptions: function (options) { var that = this; var value = that._value; Widget.fn.setOptions.call(that, options); options = that.options; options.min = parse(options.min); options.max = parse(options.max); normalize(options); that.dateView.setOptions(options); if (value) { that.element.val(kendo.toString(value, options.format, options.culture)); that._updateARIA(value); } }, _editable: function (options) { var that = this, icon = that._dateIcon.off(ns), element = that.element.off(ns), wrapper = that._inputWrapper.off(ns), readonly = options.readonly, disable = options.disable; if (!readonly && !disable) { wrapper.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); element.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false).on('keydown' + ns, proxy(that._keydown, that)).on('focusout' + ns, proxy(that._blur, that)).on('focus' + ns, function () { that._inputWrapper.addClass(FOCUSED); }); icon.on(CLICK, proxy(that._click, that)).on(MOUSEDOWN, preventDefault); } else { wrapper.addClass(disable ? STATEDISABLED : DEFAULT).removeClass(disable ? DEFAULT : STATEDISABLED); element.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable); } }, readonly: function (readonly) { this._editable({ readonly: readonly === undefined ? true : readonly, disable: false }); }, enable: function (enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined ? true : enable) }); }, destroy: function () { var that = this; Widget.fn.destroy.call(that); that.dateView.destroy(); that.element.off(ns); that._dateIcon.off(ns); that._inputWrapper.off(ns); if (that._form) { that._form.off('reset', that._resetHandler); } }, open: function () { this.dateView.open(); }, close: function () { this.dateView.close(); }, min: function (value) { return this._option(MIN, value); }, max: function (value) { return this._option(MAX, value); }, value: function (value) { var that = this; if (value === undefined) { return that._value; } that._old = that._update(value); if (that._old === null) { that.element.val(''); } that._oldText = that.element.val(); }, _toggleHover: function (e) { $(e.currentTarget).toggleClass(HOVER, e.type === 'mouseenter'); }, _blur: function () { var that = this, value = that.element.val(); that.close(); if (value !== that._oldText) { that._change(value); } that._inputWrapper.removeClass(FOCUSED); }, _click: function () { var that = this, element = that.element; that.dateView.toggle(); if (!kendo.support.touch && element[0] !== activeElement()) { element.focus(); } }, _change: function (value) { var that = this, oldValue = that.element.val(), dateChanged; value = that._update(value); dateChanged = +that._old != +value; var valueUpdated = dateChanged && !that._typing; var textFormatted = oldValue !== that.element.val(); if (valueUpdated || textFormatted) { that.element.trigger(CHANGE); } if (dateChanged) { that._old = value; that._oldText = that.element.val(); that.trigger(CHANGE); } that._typing = false; }, _keydown: function (e) { var that = this, dateView = that.dateView, value = that.element.val(), handled = false; if (!dateView.popup.visible() && e.keyCode == keys.ENTER && value !== that._oldText) { that._change(value); } else { handled = dateView.move(e); that._updateARIA(dateView._current); if (!handled) { that._typing = true; } } }, _icon: function () { var that = this, element = that.element, icon; icon = element.next('span.k-select'); if (!icon[0]) { icon = $('<span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-calendar">select</span></span>').insertAfter(element); } that._dateIcon = icon.attr({ 'role': 'button', 'aria-controls': that.dateView._dateViewID }); }, _option: function (option, value) { var that = this, options = that.options; if (value === undefined) { return options[option]; } value = parse(value, options.parseFormats, options.culture); if (!value) { return; } options[option] = new DATE(+value); that.dateView[option](value); }, _update: function (value) { var that = this, options = that.options, min = options.min, max = options.max, current = that._value, date = parse(value, options.parseFormats, options.culture), isSameType = date === null && current === null || date instanceof Date && current instanceof Date, formattedValue; if (options.disableDates(date)) { date = null; if (!that._old && !that.element.val()) { value = null; } } if (+date === +current && isSameType) { formattedValue = kendo.toString(date, options.format, options.culture); if (formattedValue !== value) { that.element.val(date === null ? value : formattedValue); } return date; } if (date !== null && isEqualDatePart(date, min)) { date = restrictValue(date, min, max); } else if (!isInRange(date, min, max)) { date = null; } that._value = date; that.dateView.value(date); that.element.val(kendo.toString(date || value, options.format, options.culture)); that._updateARIA(date); return date; }, _wrapper: function () { var that = this, element = that.element, wrapper; wrapper = element.parents('.k-datepicker'); if (!wrapper[0]) { wrapper = element.wrap(SPAN).parent().addClass('k-picker-wrap k-state-default'); wrapper = wrapper.wrap(SPAN).parent(); } wrapper[0].style.cssText = element[0].style.cssText; element.css({ width: '100%', height: element[0].style.height }); that.wrapper = wrapper.addClass('k-widget k-datepicker k-header').addClass(element[0].className); that._inputWrapper = $(wrapper[0].firstChild); }, _reset: function () { var that = this, element = that.element, formId = element.attr('form'), form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._resetHandler = function () { that.value(element[0].defaultValue); that.max(that._initialOptions.max); that.min(that._initialOptions.min); }; that._form = form.on('reset', that._resetHandler); } }, _template: function () { this._ariaTemplate = template(this.options.ARIATemplate); }, _updateARIA: function (date) { var cell; var that = this; var calendar = that.dateView.calendar; that.element.removeAttr('aria-activedescendant'); if (calendar) { cell = calendar._cell; cell.attr('aria-label', that._ariaTemplate({ current: date || calendar.current() })); that.element.attr('aria-activedescendant', cell.attr('id')); } } }); ui.plugin(DatePicker); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.timepicker', ['kendo.popup'], f); }(function () { var __meta__ = { id: 'timepicker', name: 'TimePicker', category: 'web', description: 'The TimePicker widget allows the end user to select a value from a list of predefined values or to type a new value.', depends: ['popup'] }; (function ($, undefined) { var kendo = window.kendo, keys = kendo.keys, parse = kendo.parseDate, activeElement = kendo._activeElement, extractFormat = kendo._extractFormat, support = kendo.support, browser = support.browser, ui = kendo.ui, Widget = ui.Widget, OPEN = 'open', CLOSE = 'close', CHANGE = 'change', ns = '.kendoTimePicker', CLICK = 'click' + ns, DEFAULT = 'k-state-default', DISABLED = 'disabled', READONLY = 'readonly', LI = 'li', SPAN = '<span/>', FOCUSED = 'k-state-focused', HOVER = 'k-state-hover', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, MOUSEDOWN = 'mousedown' + ns, MS_PER_MINUTE = 60000, MS_PER_DAY = 86400000, SELECTED = 'k-state-selected', STATEDISABLED = 'k-state-disabled', ARIA_SELECTED = 'aria-selected', ARIA_EXPANDED = 'aria-expanded', ARIA_HIDDEN = 'aria-hidden', ARIA_DISABLED = 'aria-disabled', ARIA_ACTIVEDESCENDANT = 'aria-activedescendant', ID = 'id', isArray = $.isArray, extend = $.extend, proxy = $.proxy, DATE = Date, TODAY = new DATE(); TODAY = new DATE(TODAY.getFullYear(), TODAY.getMonth(), TODAY.getDate(), 0, 0, 0); var TimeView = function (options) { var that = this, id = options.id; that.options = options; that._dates = []; that.ul = $('<ul tabindex="-1" role="listbox" aria-hidden="true" unselectable="on" class="k-list k-reset"/>').css({ overflow: support.kineticScrollNeeded ? '' : 'auto' }).on(CLICK, LI, proxy(that._click, that)).on('mouseenter' + ns, LI, function () { $(this).addClass(HOVER); }).on('mouseleave' + ns, LI, function () { $(this).removeClass(HOVER); }); that.list = $('<div class=\'k-list-container k-list-scroller\' unselectable=\'on\'/>').append(that.ul).on(MOUSEDOWN, preventDefault); if (id) { that._timeViewID = id + '_timeview'; that._optionID = id + '_option_selected'; that.ul.attr(ID, that._timeViewID); } that._popup(); that._heightHandler = proxy(that._height, that); that.template = kendo.template('<li tabindex="-1" role="option" class="k-item" unselectable="on">#=data#</li>', { useWithBlock: false }); }; TimeView.prototype = { current: function (candidate) { var that = this, active = that.options.active; if (candidate !== undefined) { if (that._current) { that._current.removeClass(SELECTED).removeAttr(ARIA_SELECTED).removeAttr(ID); } if (candidate) { candidate = $(candidate).addClass(SELECTED).attr(ID, that._optionID).attr(ARIA_SELECTED, true); that.scroll(candidate[0]); } that._current = candidate; if (active) { active(candidate); } } else { return that._current; } }, close: function () { this.popup.close(); }, destroy: function () { var that = this; that.ul.off(ns); that.list.off(ns); that.popup.destroy(); }, open: function () { var that = this; if (!that.ul[0].firstChild) { that.bind(); } that.popup.open(); if (that._current) { that.scroll(that._current[0]); } }, dataBind: function (dates) { var that = this, options = that.options, format = options.format, toString = kendo.toString, template = that.template, length = dates.length, idx = 0, date, html = ''; for (; idx < length; idx++) { date = dates[idx]; if (isInRange(date, options.min, options.max)) { html += template(toString(date, format, options.culture)); } } that._html(html); }, refresh: function () { var that = this, options = that.options, format = options.format, offset = dst(), ignoreDST = offset < 0, min = options.min, max = options.max, msMin = getMilliseconds(min), msMax = getMilliseconds(max), msInterval = options.interval * MS_PER_MINUTE, toString = kendo.toString, template = that.template, start = new DATE(+min), startDay = start.getDate(), msStart, lastIdx, idx = 0, length, html = ''; if (ignoreDST) { length = (MS_PER_DAY + offset * MS_PER_MINUTE) / msInterval; } else { length = MS_PER_DAY / msInterval; } if (msMin != msMax) { if (msMin > msMax) { msMax += MS_PER_DAY; } length = (msMax - msMin) / msInterval + 1; } lastIdx = parseInt(length, 10); for (; idx < length; idx++) { if (idx) { setTime(start, msInterval, ignoreDST); } if (msMax && lastIdx == idx) { msStart = getMilliseconds(start); if (startDay < start.getDate()) { msStart += MS_PER_DAY; } if (msStart > msMax) { start = new DATE(+max); } } that._dates.push(getMilliseconds(start)); html += template(toString(start, format, options.culture)); } that._html(html); }, bind: function () { var that = this, dates = that.options.dates; if (dates && dates[0]) { that.dataBind(dates); } else { that.refresh(); } }, _html: function (html) { var that = this; that.ul[0].innerHTML = html; that.popup.unbind(OPEN, that._heightHandler); that.popup.one(OPEN, that._heightHandler); that.current(null); that.select(that._value); }, scroll: function (item) { if (!item) { return; } var content = this.list[0], itemOffsetTop = item.offsetTop, itemOffsetHeight = item.offsetHeight, contentScrollTop = content.scrollTop, contentOffsetHeight = content.clientHeight, bottomDistance = itemOffsetTop + itemOffsetHeight; if (contentScrollTop > itemOffsetTop) { contentScrollTop = itemOffsetTop; } else if (bottomDistance > contentScrollTop + contentOffsetHeight) { contentScrollTop = bottomDistance - contentOffsetHeight; } content.scrollTop = contentScrollTop; }, select: function (li) { var that = this, options = that.options, current = that._current, selection; if (li instanceof Date) { li = kendo.toString(li, options.format, options.culture); } if (typeof li === 'string') { if (!current || current.text() !== li) { li = $.grep(that.ul[0].childNodes, function (node) { return (node.textContent || node.innerText) == li; }); li = li[0] ? li : null; } else { li = current; } } selection = that._distinctSelection(li); that.current(selection); }, _distinctSelection: function (selection) { var that = this, currentValue, selectionIndex; if (selection && selection.length > 1) { currentValue = getMilliseconds(that._value); selectionIndex = $.inArray(currentValue, that._dates); selection = that.ul.children()[selectionIndex]; } return selection; }, setOptions: function (options) { var old = this.options; options.min = parse(options.min); options.max = parse(options.max); this.options = extend(old, options, { active: old.active, change: old.change, close: old.close, open: old.open }); this.bind(); }, toggle: function () { var that = this; if (that.popup.visible()) { that.close(); } else { that.open(); } }, value: function (value) { var that = this; that._value = value; if (that.ul[0].firstChild) { that.select(value); } }, _click: function (e) { var that = this, li = $(e.currentTarget), date = li.text(), dates = that.options.dates; if (dates && dates.length > 0) { date = dates[li.index()]; } if (!e.isDefaultPrevented()) { that.select(li); that.options.change(date, true); that.close(); } }, _height: function () { var that = this; var list = that.list; var parent = list.parent('.k-animation-container'); var height = that.options.height; if (that.ul[0].children.length) { list.add(parent).show().height(that.ul[0].scrollHeight > height ? height : 'auto').hide(); } }, _parse: function (value) { var that = this, options = that.options, current = that._value || TODAY; if (value instanceof DATE) { return value; } value = parse(value, options.parseFormats, options.culture); if (value) { value = new DATE(current.getFullYear(), current.getMonth(), current.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds()); } return value; }, _adjustListWidth: function () { var list = this.list, width = list[0].style.width, wrapper = this.options.anchor, computedStyle, computedWidth; if (!list.data('width') && width) { return; } computedStyle = window.getComputedStyle ? window.getComputedStyle(wrapper[0], null) : 0; computedWidth = computedStyle ? parseFloat(computedStyle.width) : wrapper.outerWidth(); if (computedStyle && (browser.mozilla || browser.msie)) { computedWidth += parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight) + parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth); } width = computedWidth - (list.outerWidth() - list.width()); list.css({ fontFamily: wrapper.css('font-family'), width: width }).data('width', width); }, _popup: function () { var that = this, list = that.list, options = that.options, anchor = options.anchor; that.popup = new ui.Popup(list, extend(options.popup, { anchor: anchor, open: options.open, close: options.close, animation: options.animation, isRtl: support.isRtl(options.anchor) })); }, move: function (e) { var that = this, key = e.keyCode, ul = that.ul[0], current = that._current, down = key === keys.DOWN; if (key === keys.UP || down) { if (e.altKey) { that.toggle(down); return; } else if (down) { current = current ? current[0].nextSibling : ul.firstChild; } else { current = current ? current[0].previousSibling : ul.lastChild; } if (current) { that.select(current); } that.options.change(that._current.text()); e.preventDefault(); } else if (key === keys.ENTER || key === keys.TAB || key === keys.ESC) { e.preventDefault(); if (current) { that.options.change(current.text(), true); } that.close(); } } }; function setTime(date, time, ignoreDST) { var offset = date.getTimezoneOffset(), offsetDiff; date.setTime(date.getTime() + time); if (!ignoreDST) { offsetDiff = date.getTimezoneOffset() - offset; date.setTime(date.getTime() + offsetDiff * MS_PER_MINUTE); } } function dst() { var today = new DATE(), midnight = new DATE(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0), noon = new DATE(today.getFullYear(), today.getMonth(), today.getDate(), 12, 0, 0); return -1 * (midnight.getTimezoneOffset() - noon.getTimezoneOffset()); } function getMilliseconds(date) { return date.getHours() * 60 * MS_PER_MINUTE + date.getMinutes() * MS_PER_MINUTE + date.getSeconds() * 1000 + date.getMilliseconds(); } function isInRange(value, min, max) { var msMin = getMilliseconds(min), msMax = getMilliseconds(max), msValue; if (!value || msMin == msMax) { return true; } msValue = getMilliseconds(value); if (msMin > msValue) { msValue += MS_PER_DAY; } if (msMax < msMin) { msMax += MS_PER_DAY; } return msValue >= msMin && msValue <= msMax; } TimeView.getMilliseconds = getMilliseconds; kendo.TimeView = TimeView; var TimePicker = Widget.extend({ init: function (element, options) { var that = this, ul, timeView, disabled; Widget.fn.init.call(that, element, options); element = that.element; options = that.options; options.min = parse(element.attr('min')) || parse(options.min); options.max = parse(element.attr('max')) || parse(options.max); normalize(options); that._initialOptions = extend({}, options); that._wrapper(); that.timeView = timeView = new TimeView(extend({}, options, { id: element.attr(ID), anchor: that.wrapper, format: options.format, change: function (value, trigger) { if (trigger) { that._change(value); } else { element.val(value); } }, open: function (e) { that.timeView._adjustListWidth(); if (that.trigger(OPEN)) { e.preventDefault(); } else { element.attr(ARIA_EXPANDED, true); ul.attr(ARIA_HIDDEN, false); } }, close: function (e) { if (that.trigger(CLOSE)) { e.preventDefault(); } else { element.attr(ARIA_EXPANDED, false); ul.attr(ARIA_HIDDEN, true); } }, active: function (current) { element.removeAttr(ARIA_ACTIVEDESCENDANT); if (current) { element.attr(ARIA_ACTIVEDESCENDANT, timeView._optionID); } } })); ul = timeView.ul; that._icon(); that._reset(); try { element[0].setAttribute('type', 'text'); } catch (e) { element[0].type = 'text'; } element.addClass('k-input').attr({ 'role': 'combobox', 'aria-expanded': false, 'aria-owns': timeView._timeViewID }); disabled = element.is('[disabled]') || $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } else { that.readonly(element.is('[readonly]')); } that._old = that._update(options.value || that.element.val()); that._oldText = element.val(); kendo.notify(that); }, options: { name: 'TimePicker', min: TODAY, max: TODAY, format: '', dates: [], parseFormats: [], value: null, interval: 30, height: 200, animation: {} }, events: [ OPEN, CLOSE, CHANGE ], setOptions: function (options) { var that = this; var value = that._value; Widget.fn.setOptions.call(that, options); options = that.options; normalize(options); that.timeView.setOptions(options); if (value) { that.element.val(kendo.toString(value, options.format, options.culture)); } }, dataBind: function (dates) { if (isArray(dates)) { this.timeView.dataBind(dates); } }, _editable: function (options) { var that = this, disable = options.disable, readonly = options.readonly, arrow = that._arrow.off(ns), element = that.element.off(ns), wrapper = that._inputWrapper.off(ns); if (!readonly && !disable) { wrapper.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); element.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false).on('keydown' + ns, proxy(that._keydown, that)).on('focusout' + ns, proxy(that._blur, that)).on('focus' + ns, function () { that._inputWrapper.addClass(FOCUSED); }); arrow.on(CLICK, proxy(that._click, that)).on(MOUSEDOWN, preventDefault); } else { wrapper.addClass(disable ? STATEDISABLED : DEFAULT).removeClass(disable ? DEFAULT : STATEDISABLED); element.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable); } }, readonly: function (readonly) { this._editable({ readonly: readonly === undefined ? true : readonly, disable: false }); }, enable: function (enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined ? true : enable) }); }, destroy: function () { var that = this; Widget.fn.destroy.call(that); that.timeView.destroy(); that.element.off(ns); that._arrow.off(ns); that._inputWrapper.off(ns); if (that._form) { that._form.off('reset', that._resetHandler); } }, close: function () { this.timeView.close(); }, open: function () { this.timeView.open(); }, min: function (value) { return this._option('min', value); }, max: function (value) { return this._option('max', value); }, value: function (value) { var that = this; if (value === undefined) { return that._value; } that._old = that._update(value); if (that._old === null) { that.element.val(''); } that._oldText = that.element.val(); }, _blur: function () { var that = this, value = that.element.val(); that.close(); if (value !== that._oldText) { that._change(value); } that._inputWrapper.removeClass(FOCUSED); }, _click: function () { var that = this, element = that.element; that.timeView.toggle(); if (!support.touch && element[0] !== activeElement()) { element.focus(); } }, _change: function (value) { var that = this; value = that._update(value); if (+that._old != +value) { that._old = value; that._oldText = that.element.val(); if (!that._typing) { that.element.trigger(CHANGE); } that.trigger(CHANGE); } that._typing = false; }, _icon: function () { var that = this, element = that.element, arrow; arrow = element.next('span.k-select'); if (!arrow[0]) { arrow = $('<span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-clock">select</span></span>').insertAfter(element); } that._arrow = arrow.attr({ 'role': 'button', 'aria-controls': that.timeView._timeViewID }); }, _keydown: function (e) { var that = this, key = e.keyCode, timeView = that.timeView, value = that.element.val(); if (timeView.popup.visible() || e.altKey) { timeView.move(e); } else if (key === keys.ENTER && value !== that._oldText) { that._change(value); } else { that._typing = true; } }, _option: function (option, value) { var that = this, options = that.options; if (value === undefined) { return options[option]; } value = that.timeView._parse(value); if (!value) { return; } value = new DATE(+value); options[option] = value; that.timeView.options[option] = value; that.timeView.bind(); }, _toggleHover: function (e) { $(e.currentTarget).toggleClass(HOVER, e.type === 'mouseenter'); }, _update: function (value) { var that = this, options = that.options, timeView = that.timeView, date = timeView._parse(value); if (!isInRange(date, options.min, options.max)) { date = null; } that._value = date; that.element.val(kendo.toString(date || value, options.format, options.culture)); timeView.value(date); return date; }, _wrapper: function () { var that = this, element = that.element, wrapper; wrapper = element.parents('.k-timepicker'); if (!wrapper[0]) { wrapper = element.wrap(SPAN).parent().addClass('k-picker-wrap k-state-default'); wrapper = wrapper.wrap(SPAN).parent(); } wrapper[0].style.cssText = element[0].style.cssText; that.wrapper = wrapper.addClass('k-widget k-timepicker k-header').addClass(element[0].className); element.css({ width: '100%', height: element[0].style.height }); that._inputWrapper = $(wrapper[0].firstChild); }, _reset: function () { var that = this, element = that.element, formId = element.attr('form'), form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._resetHandler = function () { that.value(element[0].defaultValue); that.max(that._initialOptions.max); that.min(that._initialOptions.min); }; that._form = form.on('reset', that._resetHandler); } } }); function normalize(options) { var parseFormats = options.parseFormats; options.format = extractFormat(options.format || kendo.getCulture(options.culture).calendars.standard.patterns.t); parseFormats = isArray(parseFormats) ? parseFormats : [parseFormats]; parseFormats.splice(0, 0, options.format); options.parseFormats = parseFormats; } function preventDefault(e) { e.preventDefault(); } ui.plugin(TimePicker); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.datetimepicker', [ 'kendo.datepicker', 'kendo.timepicker' ], f); }(function () { var __meta__ = { id: 'datetimepicker', name: 'DateTimePicker', category: 'web', description: 'The DateTimePicker allows the end user to select a value from a calendar or a time drop-down list.', depends: [ 'datepicker', 'timepicker' ] }; (function ($, undefined) { var kendo = window.kendo, TimeView = kendo.TimeView, parse = kendo.parseDate, activeElement = kendo._activeElement, extractFormat = kendo._extractFormat, calendar = kendo.calendar, isInRange = calendar.isInRange, restrictValue = calendar.restrictValue, isEqualDatePart = calendar.isEqualDatePart, getMilliseconds = TimeView.getMilliseconds, ui = kendo.ui, Widget = ui.Widget, OPEN = 'open', CLOSE = 'close', CHANGE = 'change', ns = '.kendoDateTimePicker', CLICK = 'click' + ns, DISABLED = 'disabled', READONLY = 'readonly', DEFAULT = 'k-state-default', FOCUSED = 'k-state-focused', HOVER = 'k-state-hover', STATEDISABLED = 'k-state-disabled', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, MOUSEDOWN = 'mousedown' + ns, MONTH = 'month', SPAN = '<span/>', ARIA_ACTIVEDESCENDANT = 'aria-activedescendant', ARIA_EXPANDED = 'aria-expanded', ARIA_HIDDEN = 'aria-hidden', ARIA_OWNS = 'aria-owns', ARIA_DISABLED = 'aria-disabled', DATE = Date, MIN = new DATE(1800, 0, 1), MAX = new DATE(2099, 11, 31), dateViewParams = { view: 'date' }, timeViewParams = { view: 'time' }, extend = $.extend; var DateTimePicker = Widget.extend({ init: function (element, options) { var that = this, disabled; Widget.fn.init.call(that, element, options); element = that.element; options = that.options; options.disableDates = kendo.calendar.disabled(options.disableDates); options.min = parse(element.attr('min')) || parse(options.min); options.max = parse(element.attr('max')) || parse(options.max); normalize(options); that._initialOptions = extend({}, options); that._wrapper(); that._views(); that._icons(); that._reset(); that._template(); try { element[0].setAttribute('type', 'text'); } catch (e) { element[0].type = 'text'; } element.addClass('k-input').attr({ 'role': 'combobox', 'aria-expanded': false }); that._midnight = that._calculateMidnight(options.min, options.max); disabled = element.is('[disabled]') || $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } else { that.readonly(element.is('[readonly]')); } that._old = that._update(options.value || that.element.val()); that._oldText = element.val(); kendo.notify(that); }, options: { name: 'DateTimePicker', value: null, format: '', timeFormat: '', culture: '', parseFormats: [], dates: [], min: new DATE(MIN), max: new DATE(MAX), interval: 30, height: 200, footer: '', start: MONTH, depth: MONTH, animation: {}, month: {}, ARIATemplate: 'Current focused date is #=kendo.toString(data.current, "d")#' }, events: [ OPEN, CLOSE, CHANGE ], setOptions: function (options) { var that = this, value = that._value, min, max, currentValue; Widget.fn.setOptions.call(that, options); options = that.options; options.min = min = parse(options.min); options.max = max = parse(options.max); normalize(options); that._midnight = that._calculateMidnight(options.min, options.max); currentValue = options.value || that._value || that.dateView._current; if (min && !isEqualDatePart(min, currentValue)) { min = new DATE(MIN); } if (max && !isEqualDatePart(max, currentValue)) { max = new DATE(MAX); } that.dateView.setOptions(options); that.timeView.setOptions(extend({}, options, { format: options.timeFormat, min: min, max: max })); if (value) { that.element.val(kendo.toString(value, options.format, options.culture)); that._updateARIA(value); } }, _editable: function (options) { var that = this, element = that.element.off(ns), dateIcon = that._dateIcon.off(ns), timeIcon = that._timeIcon.off(ns), wrapper = that._inputWrapper.off(ns), readonly = options.readonly, disable = options.disable; if (!readonly && !disable) { wrapper.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); element.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false).on('keydown' + ns, $.proxy(that._keydown, that)).on('focus' + ns, function () { that._inputWrapper.addClass(FOCUSED); }).on('focusout' + ns, function () { that._inputWrapper.removeClass(FOCUSED); if (element.val() !== that._oldText) { that._change(element.val()); } that.close('date'); that.close('time'); }); dateIcon.on(MOUSEDOWN, preventDefault).on(CLICK, function () { that.toggle('date'); if (!kendo.support.touch && element[0] !== activeElement()) { element.focus(); } }); timeIcon.on(MOUSEDOWN, preventDefault).on(CLICK, function () { that.toggle('time'); if (!kendo.support.touch && element[0] !== activeElement()) { element.focus(); } }); } else { wrapper.addClass(disable ? STATEDISABLED : DEFAULT).removeClass(disable ? DEFAULT : STATEDISABLED); element.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable); } }, readonly: function (readonly) { this._editable({ readonly: readonly === undefined ? true : readonly, disable: false }); }, enable: function (enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined ? true : enable) }); }, destroy: function () { var that = this; Widget.fn.destroy.call(that); that.dateView.destroy(); that.timeView.destroy(); that.element.off(ns); that._dateIcon.off(ns); that._timeIcon.off(ns); that._inputWrapper.off(ns); if (that._form) { that._form.off('reset', that._resetHandler); } }, close: function (view) { if (view !== 'time') { view = 'date'; } this[view + 'View'].close(); }, open: function (view) { if (view !== 'time') { view = 'date'; } this[view + 'View'].open(); }, min: function (value) { return this._option('min', value); }, max: function (value) { return this._option('max', value); }, toggle: function (view) { var secondView = 'timeView'; if (view !== 'time') { view = 'date'; } else { secondView = 'dateView'; } this[view + 'View'].toggle(); this[secondView].close(); }, value: function (value) { var that = this; if (value === undefined) { return that._value; } that._old = that._update(value); if (that._old === null) { that.element.val(''); } that._oldText = that.element.val(); }, _change: function (value) { var that = this, oldValue = that.element.val(), dateChanged; value = that._update(value); dateChanged = +that._old != +value; var valueUpdated = dateChanged && !that._typing; var textFormatted = oldValue !== that.element.val(); if (valueUpdated || textFormatted) { that.element.trigger(CHANGE); } if (dateChanged) { that._old = value; that._oldText = that.element.val(); that.trigger(CHANGE); } that._typing = false; }, _option: function (option, value) { var that = this; var options = that.options; var timeView = that.timeView; var timeViewOptions = timeView.options; var current = that._value || that._old; var minDateEqual; var maxDateEqual; if (value === undefined) { return options[option]; } value = parse(value, options.parseFormats, options.culture); if (!value) { return; } if (options.min.getTime() === options.max.getTime()) { timeViewOptions.dates = []; } options[option] = new DATE(value.getTime()); that.dateView[option](value); that._midnight = that._calculateMidnight(options.min, options.max); if (current) { minDateEqual = isEqualDatePart(options.min, current); maxDateEqual = isEqualDatePart(options.max, current); } if (minDateEqual || maxDateEqual) { timeViewOptions[option] = value; if (minDateEqual && !maxDateEqual) { timeViewOptions.max = lastTimeOption(options.interval); } if (maxDateEqual) { if (that._midnight) { timeView.dataBind([MAX]); return; } else if (!minDateEqual) { timeViewOptions.min = MIN; } } } else { timeViewOptions.max = MAX; timeViewOptions.min = MIN; } timeView.bind(); }, _toggleHover: function (e) { $(e.currentTarget).toggleClass(HOVER, e.type === 'mouseenter'); }, _update: function (value) { var that = this, options = that.options, min = options.min, max = options.max, dates = options.dates, timeView = that.timeView, current = that._value, date = parse(value, options.parseFormats, options.culture), isSameType = date === null && current === null || date instanceof Date && current instanceof Date, rebind, timeViewOptions, old, skip, formattedValue; if (options.disableDates && options.disableDates(date)) { date = null; if (!that._old && !that.element.val()) { value = null; } } if (+date === +current && isSameType) { formattedValue = kendo.toString(date, options.format, options.culture); if (formattedValue !== value) { that.element.val(date === null ? value : formattedValue); if (value instanceof String) { that.element.trigger(CHANGE); } } return date; } if (date !== null && isEqualDatePart(date, min)) { date = restrictValue(date, min, max); } else if (!isInRange(date, min, max)) { date = null; } that._value = date; timeView.value(date); that.dateView.value(date); if (date) { old = that._old; timeViewOptions = timeView.options; if (dates[0]) { dates = $.grep(dates, function (d) { return isEqualDatePart(date, d); }); if (dates[0]) { timeView.dataBind(dates); skip = true; } } if (!skip) { if (isEqualDatePart(date, min)) { timeViewOptions.min = min; timeViewOptions.max = lastTimeOption(options.interval); rebind = true; } if (isEqualDatePart(date, max)) { if (that._midnight) { timeView.dataBind([MAX]); skip = true; } else { timeViewOptions.max = max; if (!rebind) { timeViewOptions.min = MIN; } rebind = true; } } } if (!skip && (!old && rebind || old && !isEqualDatePart(old, date))) { if (!rebind) { timeViewOptions.max = MAX; timeViewOptions.min = MIN; } timeView.bind(); } } that.element.val(kendo.toString(date || value, options.format, options.culture)); that._updateARIA(date); return date; }, _keydown: function (e) { var that = this, dateView = that.dateView, timeView = that.timeView, value = that.element.val(), isDateViewVisible = dateView.popup.visible(); if (e.altKey && e.keyCode === kendo.keys.DOWN) { that.toggle(isDateViewVisible ? 'time' : 'date'); } else if (isDateViewVisible) { dateView.move(e); that._updateARIA(dateView._current); } else if (timeView.popup.visible()) { timeView.move(e); } else if (e.keyCode === kendo.keys.ENTER && value !== that._oldText) { that._change(value); } else { that._typing = true; } }, _views: function () { var that = this, element = that.element, options = that.options, id = element.attr('id'), dateView, timeView, div, ul, msMin, date; that.dateView = dateView = new kendo.DateView(extend({}, options, { id: id, anchor: that.wrapper, change: function () { var value = dateView.calendar.value(), msValue = +value, msMin = +options.min, msMax = +options.max, current, adjustedDate; if (msValue === msMin || msValue === msMax) { current = msValue === msMin ? msMin : msMax; current = new DATE(that._value || current); current.setFullYear(value.getFullYear(), value.getMonth(), value.getDate()); if (isInRange(current, msMin, msMax)) { value = current; } } if (that._value) { adjustedDate = kendo.date.setHours(new Date(value), that._value); if (isInRange(adjustedDate, msMin, msMax)) { value = adjustedDate; } } that._change(value); that.close('date'); }, close: function (e) { if (that.trigger(CLOSE, dateViewParams)) { e.preventDefault(); } else { element.attr(ARIA_EXPANDED, false); div.attr(ARIA_HIDDEN, true); if (!timeView.popup.visible()) { element.removeAttr(ARIA_OWNS); } } }, open: function (e) { if (that.trigger(OPEN, dateViewParams)) { e.preventDefault(); } else { if (element.val() !== that._oldText) { date = parse(element.val(), options.parseFormats, options.culture); that.dateView[date ? 'current' : 'value'](date); } div.attr(ARIA_HIDDEN, false); element.attr(ARIA_EXPANDED, true).attr(ARIA_OWNS, dateView._dateViewID); that._updateARIA(date); } } })); div = dateView.div; msMin = options.min.getTime(); that.timeView = timeView = new TimeView({ id: id, value: options.value, anchor: that.wrapper, animation: options.animation, format: options.timeFormat, culture: options.culture, height: options.height, interval: options.interval, min: new DATE(MIN), max: new DATE(MAX), dates: msMin === options.max.getTime() ? [new Date(msMin)] : [], parseFormats: options.parseFormats, change: function (value, trigger) { value = timeView._parse(value); if (value < options.min) { value = new DATE(+options.min); timeView.options.min = value; } else if (value > options.max) { value = new DATE(+options.max); timeView.options.max = value; } if (trigger) { that._timeSelected = true; that._change(value); } else { element.val(kendo.toString(value, options.format, options.culture)); dateView.value(value); that._updateARIA(value); } }, close: function (e) { if (that.trigger(CLOSE, timeViewParams)) { e.preventDefault(); } else { ul.attr(ARIA_HIDDEN, true); element.attr(ARIA_EXPANDED, false); if (!dateView.popup.visible()) { element.removeAttr(ARIA_OWNS); } } }, open: function (e) { timeView._adjustListWidth(); if (that.trigger(OPEN, timeViewParams)) { e.preventDefault(); } else { if (element.val() !== that._oldText) { date = parse(element.val(), options.parseFormats, options.culture); that.timeView.value(date); } ul.attr(ARIA_HIDDEN, false); element.attr(ARIA_EXPANDED, true).attr(ARIA_OWNS, timeView._timeViewID); timeView.options.active(timeView.current()); } }, active: function (current) { element.removeAttr(ARIA_ACTIVEDESCENDANT); if (current) { element.attr(ARIA_ACTIVEDESCENDANT, timeView._optionID); } } }); ul = timeView.ul; }, _icons: function () { var that = this, element = that.element, icons; icons = element.next('span.k-select'); if (!icons[0]) { icons = $('<span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-calendar">select</span><span unselectable="on" class="k-icon k-i-clock">select</span></span>').insertAfter(element); } icons = icons.children(); that._dateIcon = icons.eq(0).attr({ 'role': 'button', 'aria-controls': that.dateView._dateViewID }); that._timeIcon = icons.eq(1).attr({ 'role': 'button', 'aria-controls': that.timeView._timeViewID }); }, _wrapper: function () { var that = this, element = that.element, wrapper; wrapper = element.parents('.k-datetimepicker'); if (!wrapper[0]) { wrapper = element.wrap(SPAN).parent().addClass('k-picker-wrap k-state-default'); wrapper = wrapper.wrap(SPAN).parent(); } wrapper[0].style.cssText = element[0].style.cssText; element.css({ width: '100%', height: element[0].style.height }); that.wrapper = wrapper.addClass('k-widget k-datetimepicker k-header').addClass(element[0].className); that._inputWrapper = $(wrapper[0].firstChild); }, _reset: function () { var that = this, element = that.element, formId = element.attr('form'), form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._resetHandler = function () { that.value(element[0].defaultValue); that.max(that._initialOptions.max); that.min(that._initialOptions.min); }; that._form = form.on('reset', that._resetHandler); } }, _template: function () { this._ariaTemplate = kendo.template(this.options.ARIATemplate); }, _calculateMidnight: function (min, max) { return getMilliseconds(min) + getMilliseconds(max) === 0; }, _updateARIA: function (date) { var cell; var that = this; var calendar = that.dateView.calendar; that.element.removeAttr(ARIA_ACTIVEDESCENDANT); if (calendar) { cell = calendar._cell; cell.attr('aria-label', that._ariaTemplate({ current: date || calendar.current() })); that.element.attr(ARIA_ACTIVEDESCENDANT, cell.attr('id')); } } }); function lastTimeOption(interval) { var date = new Date(2100, 0, 1); date.setMinutes(-interval); return date; } function preventDefault(e) { e.preventDefault(); } function normalize(options) { var patterns = kendo.getCulture(options.culture).calendars.standard.patterns, parseFormats = !options.parseFormats.length, timeFormat; options.format = extractFormat(options.format || patterns.g); options.timeFormat = timeFormat = extractFormat(options.timeFormat || patterns.t); kendo.DateView.normalize(options); if (parseFormats) { options.parseFormats.unshift('yyyy-MM-ddTHH:mm:ss'); } if ($.inArray(timeFormat, options.parseFormats) === -1) { options.parseFormats.splice(1, 0, timeFormat); } } ui.plugin(DateTimePicker); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.list', [ 'kendo.data', 'kendo.popup' ], f); }(function () { var __meta__ = { id: 'list', name: 'List', category: 'framework', depends: [ 'data', 'popup' ], hidden: true }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, keys = kendo.keys, support = kendo.support, htmlEncode = kendo.htmlEncode, activeElement = kendo._activeElement, ObservableArray = kendo.data.ObservableArray, ID = 'id', CHANGE = 'change', FOCUSED = 'k-state-focused', HOVER = 'k-state-hover', LOADING = 'k-loading', OPEN = 'open', CLOSE = 'close', CASCADE = 'cascade', SELECT = 'select', SELECTED = 'selected', REQUESTSTART = 'requestStart', REQUESTEND = 'requestEnd', WIDTH = 'width', extend = $.extend, proxy = $.proxy, isArray = $.isArray, browser = support.browser, isIE8 = browser.msie && browser.version < 9, quotRegExp = /"/g, alternativeNames = { 'ComboBox': 'DropDownList', 'DropDownList': 'ComboBox' }; var List = kendo.ui.DataBoundWidget.extend({ init: function (element, options) { var that = this, ns = that.ns, id; Widget.fn.init.call(that, element, options); element = that.element; options = that.options; that._isSelect = element.is(SELECT); if (that._isSelect && that.element[0].length) { if (!options.dataSource) { options.dataTextField = options.dataTextField || 'text'; options.dataValueField = options.dataValueField || 'value'; } } that.ul = $('<ul unselectable="on" class="k-list k-reset"/>').attr({ tabIndex: -1, 'aria-hidden': true }); that.list = $('<div class=\'k-list-container\'/>').append(that.ul).on('mousedown' + ns, proxy(that._listMousedown, that)); id = element.attr(ID); if (id) { that.list.attr(ID, id + '-list'); that.ul.attr(ID, id + '_listbox'); } that._header(); that._accessors(); that._initValue(); }, options: { valuePrimitive: false, headerTemplate: '' }, setOptions: function (options) { Widget.fn.setOptions.call(this, options); if (options && options.enable !== undefined) { options.enabled = options.enable; } }, focus: function () { this._focused.focus(); }, readonly: function (readonly) { this._editable({ readonly: readonly === undefined ? true : readonly, disable: false }); }, enable: function (enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined ? true : enable) }); }, _listOptions: function (options) { var that = this; var currentOptions = that.options; var virtual = currentOptions.virtual; var listBoundHandler = proxy(that._listBound, that); virtual = typeof virtual === 'object' ? virtual : {}; options = $.extend({ autoBind: false, selectable: true, dataSource: that.dataSource, click: proxy(that._click, that), change: proxy(that._listChange, that), activate: proxy(that._activateItem, that), deactivate: proxy(that._deactivateItem, that), dataBinding: function () { that.trigger('dataBinding'); }, dataBound: listBoundHandler, height: currentOptions.height, dataValueField: currentOptions.dataValueField, dataTextField: currentOptions.dataTextField, groupTemplate: currentOptions.groupTemplate, fixedGroupTemplate: currentOptions.fixedGroupTemplate, template: currentOptions.template }, options, virtual); if (!options.template) { options.template = '#:' + kendo.expr(options.dataTextField, 'data') + '#'; } if (currentOptions.$angular) { options.$angular = currentOptions.$angular; } return options; }, _initList: function () { var that = this; var listOptions = that._listOptions({ selectedItemChange: proxy(that._listChange, that) }); if (!that.options.virtual) { that.listView = new kendo.ui.StaticList(that.ul, listOptions); } else { that.listView = new kendo.ui.VirtualList(that.ul, listOptions); } that.listView.bind('listBound', proxy(that._listBound, that)); that._setListValue(); }, _setListValue: function (value) { value = value || this.options.value; if (value !== undefined) { this.listView.value(value).done(proxy(this._updateSelectionState, this)); } }, _updateSelectionState: $.noop, _listMousedown: function (e) { if (!this.filterInput || this.filterInput[0] !== e.target) { e.preventDefault(); } }, _isFilterEnabled: function () { var filter = this.options.filter; return filter && filter !== 'none'; }, _clearFilter: function () { if (!this.options.virtual) { this.listView.bound(false); } this._filterSource(); }, _filterSource: function (filter, force) { var that = this; var options = that.options; var dataSource = that.dataSource; var expression = extend({}, dataSource.filter() || {}); var removed = removeFiltersForField(expression, options.dataTextField); if ((filter || removed) && that.trigger('filtering', { filter: filter })) { return; } expression = { filters: expression.filters || [], logic: 'and' }; if (filter) { expression.filters.push(filter); } if (that._cascading) { this.listView.setDSFilter(expression); } if (!force) { dataSource.filter(expression); } else { dataSource.read(dataSource._mergeState({ filter: expression })); } }, _header: function () { var that = this; var template = that.options.headerTemplate; var header; if ($.isFunction(template)) { template = template({}); } if (template) { that.list.prepend(template); header = that.ul.prev(); that.header = header[0] ? header : null; if (that.header) { that.angular('compile', function () { return { elements: that.header }; }); } } }, _initValue: function () { var that = this, value = that.options.value; if (value !== null) { that.element.val(value); } else { value = that._accessor(); that.options.value = value; } that._old = value; }, _ignoreCase: function () { var that = this, model = that.dataSource.reader.model, field; if (model && model.fields) { field = model.fields[that.options.dataTextField]; if (field && field.type && field.type !== 'string') { that.options.ignoreCase = false; } } }, _focus: function (candidate) { return this.listView.focus(candidate); }, current: function (candidate) { return this._focus(candidate); }, items: function () { return this.ul[0].children; }, destroy: function () { var that = this; var ns = that.ns; Widget.fn.destroy.call(that); that._unbindDataSource(); that.listView.destroy(); that.list.off(ns); that.popup.destroy(); if (that._form) { that._form.off('reset', that._resetHandler); } }, dataItem: function (index) { var that = this; if (index === undefined) { return that.listView.selectedDataItems()[0]; } if (typeof index !== 'number') { if (that.options.virtual) { return that.dataSource.getByUid($(index).data('uid')); } index = $(that.items()).index(index); } return that.dataSource.flatView()[index]; }, _activateItem: function () { var current = this.listView.focus(); if (current) { this._focused.add(this.filterInput).attr('aria-activedescendant', current.attr('id')); } }, _deactivateItem: function () { this._focused.add(this.filterInput).removeAttr('aria-activedescendant'); }, _accessors: function () { var that = this; var element = that.element; var options = that.options; var getter = kendo.getter; var textField = element.attr(kendo.attr('text-field')); var valueField = element.attr(kendo.attr('value-field')); if (!options.dataTextField && textField) { options.dataTextField = textField; } if (!options.dataValueField && valueField) { options.dataValueField = valueField; } that._text = getter(options.dataTextField); that._value = getter(options.dataValueField); }, _aria: function (id) { var that = this, options = that.options, element = that._focused.add(that.filterInput); if (options.suggest !== undefined) { element.attr('aria-autocomplete', options.suggest ? 'both' : 'list'); } id = id ? id + ' ' + that.ul[0].id : that.ul[0].id; element.attr('aria-owns', id); that.ul.attr('aria-live', !that._isFilterEnabled() ? 'off' : 'polite'); }, _blur: function () { var that = this; that._change(); that.close(); }, _change: function () { var that = this; var index = that.selectedIndex; var optionValue = that.options.value; var value = that.value(); var trigger; if (that._isSelect && !that.listView.bound() && optionValue) { value = optionValue; } if (value !== unifyType(that._old, typeof value)) { trigger = true; } else if (index !== undefined && index !== that._oldIndex) { trigger = true; } if (trigger) { that._old = value; that._oldIndex = index; if (!that._typing) { that.element.trigger(CHANGE); } that.trigger(CHANGE); } that.typing = false; }, _data: function () { return this.dataSource.view(); }, _enable: function () { var that = this, options = that.options, disabled = that.element.is('[disabled]'); if (options.enable !== undefined) { options.enabled = options.enable; } if (!options.enabled || disabled) { that.enable(false); } else { that.readonly(that.element.is('[readonly]')); } }, _dataValue: function (dataItem) { var value = this._value(dataItem); if (value === undefined) { value = this._text(dataItem); } return value; }, _offsetHeight: function () { var offsetHeight = 0; var siblings = this.listView.content.prevAll(':visible'); siblings.each(function () { var element = $(this); if (element.hasClass('k-list-filter')) { offsetHeight += element.children().outerHeight(); } else { offsetHeight += element.outerHeight(); } }); return offsetHeight; }, _height: function (length) { var that = this; var list = that.list; var height = that.options.height; var visible = that.popup.visible(); var offsetTop; var popups; if (length) { popups = list.add(list.parent('.k-animation-container')).show(); if (!list.is(':visible')) { popups.hide(); return; } height = that.listView.content[0].scrollHeight > height ? height : 'auto'; popups.height(height); if (height !== 'auto') { offsetTop = that._offsetHeight(); if (offsetTop) { height -= offsetTop; } } that.listView.content.height(height); if (!visible) { popups.hide(); } } return height; }, _adjustListWidth: function () { var list = this.list, width = list[0].style.width, wrapper = this.wrapper, computedStyle, computedWidth; if (!list.data(WIDTH) && width) { return; } computedStyle = window.getComputedStyle ? window.getComputedStyle(wrapper[0], null) : 0; computedWidth = parseFloat(computedStyle && computedStyle.width) || wrapper.outerWidth(); if (computedStyle && browser.msie) { computedWidth += parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight) + parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth); } if (list.css('box-sizing') !== 'border-box') { width = computedWidth - (list.outerWidth() - list.width()); } else { width = computedWidth; } list.css({ fontFamily: wrapper.css('font-family'), width: width }).data(WIDTH, width); return true; }, _openHandler: function (e) { this._adjustListWidth(); if (this.trigger(OPEN)) { e.preventDefault(); } else { this._focused.attr('aria-expanded', true); this.ul.attr('aria-hidden', false); } }, _closeHandler: function (e) { if (this.trigger(CLOSE)) { e.preventDefault(); } else { this._focused.attr('aria-expanded', false); this.ul.attr('aria-hidden', true); } }, _focusItem: function () { var listView = this.listView; var focusedItem = listView.focus(); var index = listView.select(); index = index[index.length - 1]; if (index === undefined && this.options.highlightFirst && !focusedItem) { index = 0; } if (index !== undefined) { listView.focus(index); } else { listView.scrollToIndex(0); } }, _calculateGroupPadding: function (height) { var li = this.ul.children('.k-first:first'); var groupHeader = this.listView.content.prev('.k-group-header'); var padding = 0; if (groupHeader[0] && groupHeader[0].style.display !== 'none') { if (height !== 'auto') { padding = kendo.support.scrollbar(); } padding += parseFloat(li.css('border-right-width'), 10) + parseFloat(li.children('.k-group').css('padding-right'), 10); groupHeader.css('padding-right', padding); } }, _calculatePopupHeight: function (force) { var height = this._height(this.dataSource.flatView().length || force); this._calculateGroupPadding(height); }, _resizePopup: function (force) { if (this.options.virtual) { return; } if (!this.popup.element.is(':visible')) { this.popup.one('open', function (force) { return proxy(function () { this._calculatePopupHeight(force); }, this); }.call(this, force)); } else { this._calculatePopupHeight(force); } }, _popup: function () { var that = this; that.popup = new ui.Popup(that.list, extend({}, that.options.popup, { anchor: that.wrapper, open: proxy(that._openHandler, that), close: proxy(that._closeHandler, that), animation: that.options.animation, isRtl: support.isRtl(that.wrapper) })); }, _makeUnselectable: function () { if (isIE8) { this.list.find('*').not('.k-textbox').attr('unselectable', 'on'); } }, _toggleHover: function (e) { $(e.currentTarget).toggleClass(HOVER, e.type === 'mouseenter'); }, _toggle: function (open, preventFocus) { var that = this; var touchEnabled = support.mobileOS && (support.touch || support.MSPointers || support.pointers); open = open !== undefined ? open : !that.popup.visible(); if (!preventFocus && !touchEnabled && that._focused[0] !== activeElement()) { that._prevent = true; that._focused.focus(); that._prevent = false; } that[open ? OPEN : CLOSE](); }, _triggerCascade: function () { var that = this; if (!that._cascadeTriggered || that._old !== that.value() || that._oldIndex !== that.selectedIndex) { that._cascadeTriggered = true; that.trigger(CASCADE, { userTriggered: that._userTriggered }); } }, _triggerChange: function () { if (this._valueBeforeCascade !== this.value()) { this.trigger(CHANGE); } }, _unbindDataSource: function () { var that = this; that.dataSource.unbind(REQUESTSTART, that._requestStartHandler).unbind(REQUESTEND, that._requestEndHandler).unbind('error', that._errorHandler); } }); function unifyType(value, type) { if (value !== undefined && value !== '' && value !== null) { if (type === 'boolean') { value = Boolean(value); } else if (type === 'number') { value = Number(value); } else if (type === 'string') { value = value.toString(); } } return value; } extend(List, { inArray: function (node, parentNode) { var idx, length, siblings = parentNode.children; if (!node || node.parentNode !== parentNode) { return -1; } for (idx = 0, length = siblings.length; idx < length; idx++) { if (node === siblings[idx]) { return idx; } } return -1; }, unifyType: unifyType }); kendo.ui.List = List; ui.Select = List.extend({ init: function (element, options) { List.fn.init.call(this, element, options); this._initial = this.element.val(); }, setDataSource: function (dataSource) { var that = this; var parent; that.options.dataSource = dataSource; that._dataSource(); if (that.listView.bound()) { that._initialIndex = null; } that.listView.setDataSource(that.dataSource); if (that.options.autoBind) { that.dataSource.fetch(); } parent = that._parentWidget(); if (parent) { that._cascadeSelect(parent); } }, close: function () { this.popup.close(); }, select: function (candidate) { var that = this; if (candidate === undefined) { return that.selectedIndex; } else { that._select(candidate); that._old = that._accessor(); that._oldIndex = that.selectedIndex; } }, search: function (word) { word = typeof word === 'string' ? word : this.text(); var that = this; var length = word.length; var options = that.options; var ignoreCase = options.ignoreCase; var field = options.dataTextField; clearTimeout(that._typingTimeout); if (!length || length >= options.minLength) { that._state = 'filter'; if (!that._isFilterEnabled()) { that._filter(word); } else { that._open = true; that._filterSource({ value: ignoreCase ? word.toLowerCase() : word, field: field, operator: options.filter, ignoreCase: ignoreCase }); } } }, _accessor: function (value, idx) { return this[this._isSelect ? '_accessorSelect' : '_accessorInput'](value, idx); }, _accessorInput: function (value) { var element = this.element[0]; if (value === undefined) { return element.value; } else { if (value === null) { value = ''; } element.value = value; } }, _accessorSelect: function (value, idx) { var element = this.element[0]; var selectedIndex = element.selectedIndex; var option; if (value === undefined) { if (selectedIndex > -1) { option = element.options[selectedIndex]; } if (option) { value = option.value; } return value || ''; } else { if (selectedIndex > -1) { element.options[selectedIndex].removeAttribute(SELECTED); element.options[selectedIndex].selected = false; } if (idx === undefined) { idx = -1; } if (value !== null && value !== '' && idx == -1) { this._custom(value); } else { if (value) { element.value = value; } else { element.selectedIndex = idx; } if (element.selectedIndex > -1) { option = element.options[element.selectedIndex]; } if (option) { option.setAttribute(SELECTED, SELECTED); } } } }, _custom: function (value) { var that = this; var element = that.element; var custom = that._customOption; if (!custom) { custom = $('<option/>'); that._customOption = custom; element.append(custom); } custom.text(value); custom[0].setAttribute(SELECTED, SELECTED); custom[0].selected = true; }, _hideBusy: function () { var that = this; clearTimeout(that._busy); that._arrow.removeClass(LOADING); that._focused.attr('aria-busy', false); that._busy = null; }, _showBusy: function () { var that = this; that._request = true; if (that._busy) { return; } that._busy = setTimeout(function () { if (that._arrow) { that._focused.attr('aria-busy', true); that._arrow.addClass(LOADING); } }, 100); }, _requestEnd: function () { this._request = false; this._hideBusy(); }, _dataSource: function () { var that = this, element = that.element, options = that.options, dataSource = options.dataSource || {}, idx; dataSource = $.isArray(dataSource) ? { data: dataSource } : dataSource; if (that._isSelect) { idx = element[0].selectedIndex; if (idx > -1) { options.index = idx; } dataSource.select = element; dataSource.fields = [ { field: options.dataTextField }, { field: options.dataValueField } ]; } if (that.dataSource) { that._unbindDataSource(); } else { that._requestStartHandler = proxy(that._showBusy, that); that._requestEndHandler = proxy(that._requestEnd, that); that._errorHandler = proxy(that._hideBusy, that); } that.dataSource = kendo.data.DataSource.create(dataSource).bind(REQUESTSTART, that._requestStartHandler).bind(REQUESTEND, that._requestEndHandler).bind('error', that._errorHandler); }, _firstItem: function () { this.listView.focusFirst(); }, _lastItem: function () { this.listView.focusLast(); }, _nextItem: function () { this.listView.focusNext(); }, _prevItem: function () { this.listView.focusPrev(); }, _move: function (e) { var that = this; var key = e.keyCode; var down = key === keys.DOWN; var dataItem; var pressed; var current; if (key === keys.UP || down) { if (e.altKey) { that.toggle(down); } else { if (!that.listView.bound()) { if (!that._fetch) { that.dataSource.one(CHANGE, function () { that._fetch = false; that._move(e); }); that._fetch = true; that._filterSource(); } e.preventDefault(); return true; } current = that._focus(); if (!that._fetch && (!current || current.hasClass('k-state-selected'))) { if (down) { that._nextItem(); if (!that._focus()) { that._lastItem(); } } else { that._prevItem(); if (!that._focus()) { that._firstItem(); } } } if (that.trigger(SELECT, { item: that._focus() })) { that._focus(current); return; } that._select(that._focus(), true); if (!that.popup.visible()) { that._blur(); } } e.preventDefault(); pressed = true; } else if (key === keys.ENTER || key === keys.TAB) { if (that.popup.visible()) { e.preventDefault(); } current = that._focus(); dataItem = that.dataItem(); if (!that.popup.visible() && (!dataItem || that.text() !== that._text(dataItem))) { current = null; } var activeFilter = that.filterInput && that.filterInput[0] === activeElement(); if (current) { if (that.trigger(SELECT, { item: current })) { return; } that._select(current); } else if (that.input) { that._accessor(that.input.val()); that.listView.value(that.input.val()); } if (that._focusElement) { that._focusElement(that.wrapper); } if (activeFilter && key === keys.TAB) { that.wrapper.focusout(); } else { that._blur(); } that.close(); pressed = true; } else if (key === keys.ESC) { if (that.popup.visible()) { e.preventDefault(); } that.close(); pressed = true; } return pressed; }, _fetchData: function () { var that = this; var hasItems = !!that.dataSource.view().length; if (that._request || that.options.cascadeFrom) { return; } if (!that.listView.bound() && !that._fetch && !hasItems) { that._fetch = true; that.dataSource.fetch().done(function () { that._fetch = false; }); } }, _options: function (data, optionLabel, value) { var that = this, element = that.element, length = data.length, options = '', option, dataItem, dataText, dataValue, idx = 0; if (optionLabel) { options = optionLabel; } for (; idx < length; idx++) { option = '<option'; dataItem = data[idx]; dataText = that._text(dataItem); dataValue = that._value(dataItem); if (dataValue !== undefined) { dataValue += ''; if (dataValue.indexOf('"') !== -1) { dataValue = dataValue.replace(quotRegExp, '"'); } option += ' value="' + dataValue + '"'; } option += '>'; if (dataText !== undefined) { option += htmlEncode(dataText); } option += '</option>'; options += option; } element.html(options); if (value !== undefined) { element[0].value = value; if (element[0].value && !value) { element[0].selectedIndex = -1; } } }, _reset: function () { var that = this, element = that.element, formId = element.attr('form'), form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._resetHandler = function () { setTimeout(function () { that.value(that._initial); }); }; that._form = form.on('reset', that._resetHandler); } }, _parentWidget: function () { var name = this.options.name; var parentElement = $('#' + this.options.cascadeFrom); var parent = parentElement.data('kendo' + name); if (!parent) { parent = parentElement.data('kendo' + alternativeNames[name]); } return parent; }, _cascade: function () { var that = this; var options = that.options; var cascade = options.cascadeFrom; var parent; if (cascade) { parent = that._parentWidget(); that._cascadeHandlerProxy = proxy(that._cascadeHandler, that); if (!parent) { return; } options.autoBind = false; parent.bind('set', function () { that.one('set', function (e) { that._selectedValue = e.value; }); }); parent.first(CASCADE, that._cascadeHandlerProxy); if (parent.listView.bound()) { that._toggleCascadeOnFocus(); that._cascadeSelect(parent); } else { parent.one('dataBound', function () { that._toggleCascadeOnFocus(); }); if (!parent.value()) { that.enable(false); } } } }, _toggleCascadeOnFocus: function () { var that = this; var parent = that._parentWidget(); parent._focused.add(parent.filterInput).bind('focus', function () { parent.unbind(CASCADE, that._cascadeHandlerProxy); parent.first(CHANGE, that._cascadeHandlerProxy); }); parent._focused.add(parent.filterInput).bind('focusout', function () { parent.unbind(CHANGE, that._cascadeHandlerProxy); parent.first(CASCADE, that._cascadeHandlerProxy); }); }, _cascadeHandler: function (e) { var parent = this._parentWidget(); var valueBeforeCascade = this.value(); this._userTriggered = e.userTriggered; if (this.listView.bound()) { this._clearSelection(parent, true); } this._cascadeSelect(parent, valueBeforeCascade); }, _cascadeChange: function (parent) { var that = this; var value = that._accessor() || that._selectedValue; that._selectedValue = null; if (that._userTriggered) { that._clearSelection(parent, true); } else if (value) { if (value !== that.listView.value()[0]) { that.value(value); } if (!that.dataSource.view()[0] || that.selectedIndex === -1) { that._clearSelection(parent, true); } } else if (that.dataSource.flatView().length) { that.select(that.options.index); } that.enable(); that._triggerCascade(); that._triggerChange(); that._userTriggered = false; }, _cascadeSelect: function (parent, valueBeforeCascade) { var that = this; var dataItem = parent.dataItem(); var filterValue = dataItem ? parent._value(dataItem) : null; var valueField = that.options.cascadeFromField || parent.options.dataValueField; var expressions; that._valueBeforeCascade = valueBeforeCascade !== undefined ? valueBeforeCascade : that.value(); if (filterValue || filterValue === 0) { expressions = that.dataSource.filter() || {}; removeFiltersForField(expressions, valueField); var handler = function () { that.unbind('dataBound', handler); that._cascadeChange(parent); }; that.first('dataBound', handler); that._cascading = true; that._filterSource({ field: valueField, operator: 'eq', value: filterValue }); that._cascading = false; } else { that.enable(false); that._clearSelection(parent); that._triggerCascade(); that._triggerChange(); that._userTriggered = false; } } }); var STATIC_LIST_NS = '.StaticList'; var StaticList = kendo.ui.DataBoundWidget.extend({ init: function (element, options) { Widget.fn.init.call(this, element, options); this.element.attr('role', 'listbox').on('click' + STATIC_LIST_NS, 'li', proxy(this._click, this)).on('mouseenter' + STATIC_LIST_NS, 'li', function () { $(this).addClass(HOVER); }).on('mouseleave' + STATIC_LIST_NS, 'li', function () { $(this).removeClass(HOVER); }); this.content = this.element.wrap('<div class=\'k-list-scroller\' unselectable=\'on\'></div>').parent(); this.header = this.content.before('<div class="k-group-header" style="display:none"></div>').prev(); this.bound(false); this._optionID = kendo.guid(); this._selectedIndices = []; this._view = []; this._dataItems = []; this._values = []; var value = this.options.value; if (value) { this._values = $.isArray(value) ? value.slice(0) : [value]; } this._getter(); this._templates(); this.setDataSource(this.options.dataSource); this._onScroll = proxy(function () { var that = this; clearTimeout(that._scrollId); that._scrollId = setTimeout(function () { that._renderHeader(); }, 50); }, this); }, options: { name: 'StaticList', dataValueField: null, valuePrimitive: false, selectable: true, template: null, groupTemplate: null, fixedGroupTemplate: null }, events: [ 'click', CHANGE, 'activate', 'deactivate', 'dataBinding', 'dataBound', 'selectedItemChange' ], setDataSource: function (source) { var that = this; var dataSource = source || {}; var value; dataSource = $.isArray(dataSource) ? { data: dataSource } : dataSource; dataSource = kendo.data.DataSource.create(dataSource); if (that.dataSource) { that.dataSource.unbind(CHANGE, that._refreshHandler); value = that.value(); that.value([]); that.bound(false); that.value(value); } else { that._refreshHandler = proxy(that.refresh, that); } that.setDSFilter(dataSource.filter()); that.dataSource = dataSource.bind(CHANGE, that._refreshHandler); that._fixedHeader(); }, skip: function () { return this.dataSource.skip(); }, setOptions: function (options) { Widget.fn.setOptions.call(this, options); this._getter(); this._templates(); this._render(); }, destroy: function () { this.element.off(STATIC_LIST_NS); if (this._refreshHandler) { this.dataSource.unbind(CHANGE, this._refreshHandler); } clearTimeout(this._scrollId); Widget.fn.destroy.call(this); }, scrollToIndex: function (index) { var item = this.element[0].children[index]; if (item) { this.scroll(item); } }, scroll: function (item) { if (!item) { return; } if (item[0]) { item = item[0]; } var content = this.content[0], itemOffsetTop = item.offsetTop, itemOffsetHeight = item.offsetHeight, contentScrollTop = content.scrollTop, contentOffsetHeight = content.clientHeight, bottomDistance = itemOffsetTop + itemOffsetHeight; if (contentScrollTop > itemOffsetTop) { contentScrollTop = itemOffsetTop; } else if (bottomDistance > contentScrollTop + contentOffsetHeight) { contentScrollTop = bottomDistance - contentOffsetHeight; } content.scrollTop = contentScrollTop; }, selectedDataItems: function (dataItems) { if (dataItems === undefined) { return this._dataItems.slice(); } this._dataItems = dataItems; this._values = this._getValues(dataItems); }, _getValues: function (dataItems) { var getter = this._valueGetter; return $.map(dataItems, function (dataItem) { return getter(dataItem); }); }, focusNext: function () { var current = this.focus(); if (!current) { current = 0; } else { current = current.next(); } this.focus(current); }, focusPrev: function () { var current = this.focus(); if (!current) { current = this.element[0].children.length - 1; } else { current = current.prev(); } this.focus(current); }, focusFirst: function () { this.focus(this.element[0].children[0]); }, focusLast: function () { this.focus(this.element[0].children[this.element[0].children.length - 1]); }, focus: function (candidate) { var that = this; var id = that._optionID; var hasCandidate; if (candidate === undefined) { return that._current; } candidate = that._get(candidate); candidate = candidate[candidate.length - 1]; candidate = $(this.element[0].children[candidate]); if (that._current) { that._current.removeClass(FOCUSED).removeAttr('aria-selected').removeAttr(ID); that.trigger('deactivate'); } hasCandidate = !!candidate[0]; if (hasCandidate) { candidate.addClass(FOCUSED); that.scroll(candidate); candidate.attr('id', id); } that._current = hasCandidate ? candidate : null; that.trigger('activate'); }, focusIndex: function () { return this.focus() ? this.focus().index() : undefined; }, skipUpdate: function (skipUpdate) { this._skipUpdate = skipUpdate; }, select: function (indices) { var that = this; var selectable = that.options.selectable; var singleSelection = selectable !== 'multiple' && selectable !== false; var selectedIndices = that._selectedIndices; var added = []; var removed = []; var result; if (indices === undefined) { return selectedIndices.slice(); } indices = that._get(indices); if (indices.length === 1 && indices[0] === -1) { indices = []; } var filtered = that.isFiltered(); if (filtered && !singleSelection && that._deselectFiltered(indices)) { return; } if (singleSelection && !filtered && $.inArray(indices[indices.length - 1], selectedIndices) !== -1) { if (that._dataItems.length && that._view.length) { that._dataItems = [that._view[selectedIndices[0]].item]; } return; } result = that._deselect(indices); removed = result.removed; indices = result.indices; if (indices.length) { if (singleSelection) { indices = [indices[indices.length - 1]]; } added = that._select(indices); } if (added.length || removed.length) { that._valueComparer = null; that.trigger(CHANGE, { added: added, removed: removed }); } }, removeAt: function (position) { this._selectedIndices.splice(position, 1); this._values.splice(position, 1); this._valueComparer = null; return { position: position, dataItem: this._dataItems.splice(position, 1)[0] }; }, setValue: function (value) { value = $.isArray(value) || value instanceof ObservableArray ? value.slice(0) : [value]; this._values = value; this._valueComparer = null; }, value: function (value) { var that = this; var deferred = that._valueDeferred; var indices; if (value === undefined) { return that._values.slice(); } that.setValue(value); if (!deferred || deferred.state() === 'resolved') { that._valueDeferred = deferred = $.Deferred(); } if (that.bound()) { indices = that._valueIndices(that._values); if (that.options.selectable === 'multiple') { that.select(-1); } that.select(indices); deferred.resolve(); } that._skipUpdate = false; return deferred; }, items: function () { return this.element.children('.k-item'); }, _click: function (e) { if (!e.isDefaultPrevented()) { if (!this.trigger('click', { item: $(e.currentTarget) })) { this.select(e.currentTarget); } } }, _valueExpr: function (type, values) { var that = this; var idx = 0; var body; var comparer; var normalized = []; if (!that._valueComparer || that._valueType !== type) { that._valueType = type; for (; idx < values.length; idx++) { normalized.push(unifyType(values[idx], type)); } body = 'for (var idx = 0; idx < ' + normalized.length + '; idx++) {' + ' if (current === values[idx]) {' + ' return idx;' + ' }' + '} ' + 'return -1;'; comparer = new Function('current', 'values', body); that._valueComparer = function (current) { return comparer(current, normalized); }; } return that._valueComparer; }, _dataItemPosition: function (dataItem, values) { var value = this._valueGetter(dataItem); var valueExpr = this._valueExpr(typeof value, values); return valueExpr(value); }, _getter: function () { this._valueGetter = kendo.getter(this.options.dataValueField); }, _deselect: function (indices) { var that = this; var children = that.element[0].children; var selectable = that.options.selectable; var selectedIndices = that._selectedIndices; var dataItems = that._dataItems; var values = that._values; var removed = []; var i = 0; var j; var index, selectedIndex; var removedIndices = 0; indices = indices.slice(); if (selectable === true || !indices.length) { for (; i < selectedIndices.length; i++) { $(children[selectedIndices[i]]).removeClass('k-state-selected'); removed.push({ position: i, dataItem: dataItems[i] }); } that._values = []; that._dataItems = []; that._selectedIndices = []; } else if (selectable === 'multiple') { for (; i < indices.length; i++) { index = indices[i]; if (!$(children[index]).hasClass('k-state-selected')) { continue; } for (j = 0; j < selectedIndices.length; j++) { selectedIndex = selectedIndices[j]; if (selectedIndex === index) { $(children[selectedIndex]).removeClass('k-state-selected'); removed.push({ position: j + removedIndices, dataItem: dataItems.splice(j, 1)[0] }); selectedIndices.splice(j, 1); indices.splice(i, 1); values.splice(j, 1); removedIndices += 1; i -= 1; j -= 1; break; } } } } return { indices: indices, removed: removed }; }, _deselectFiltered: function (indices) { var children = this.element[0].children; var dataItem, index, position; var removed = []; var idx = 0; for (; idx < indices.length; idx++) { index = indices[idx]; dataItem = this._view[index].item; position = this._dataItemPosition(dataItem, this._values); if (position > -1) { removed.push(this.removeAt(position)); $(children[index]).removeClass('k-state-selected'); } } if (removed.length) { this.trigger(CHANGE, { added: [], removed: removed }); return true; } return false; }, _select: function (indices) { var that = this; var children = that.element[0].children; var data = that._view; var dataItem, index; var added = []; var idx = 0; if (indices[indices.length - 1] !== -1) { that.focus(indices); } for (; idx < indices.length; idx++) { index = indices[idx]; dataItem = data[index]; if (index === -1 || !dataItem) { continue; } dataItem = dataItem.item; that._selectedIndices.push(index); that._dataItems.push(dataItem); that._values.push(that._valueGetter(dataItem)); $(children[index]).addClass('k-state-selected').attr('aria-selected', true); added.push({ dataItem: dataItem }); } return added; }, _get: function (candidate) { if (typeof candidate === 'number') { candidate = [candidate]; } else if (!isArray(candidate)) { candidate = $(candidate).data('offset-index'); if (candidate === undefined) { candidate = -1; } candidate = [candidate]; } return candidate; }, _template: function () { var that = this; var options = that.options; var template = options.template; if (!template) { template = kendo.template('<li tabindex="-1" role="option" unselectable="on" class="k-item">${' + kendo.expr(options.dataTextField, 'data') + '}</li>', { useWithBlock: false }); } else { template = kendo.template(template); template = function (data) { return '<li tabindex="-1" role="option" unselectable="on" class="k-item">' + template(data) + '</li>'; }; } return template; }, _templates: function () { var template; var templates = { template: this.options.template, groupTemplate: this.options.groupTemplate, fixedGroupTemplate: this.options.fixedGroupTemplate }; for (var key in templates) { template = templates[key]; if (template && typeof template !== 'function') { templates[key] = kendo.template(template); } } this.templates = templates; }, _normalizeIndices: function (indices) { var newIndices = []; var idx = 0; for (; idx < indices.length; idx++) { if (indices[idx] !== undefined) { newIndices.push(indices[idx]); } } return newIndices; }, _valueIndices: function (values, indices) { var data = this._view; var idx = 0; var index; indices = indices ? indices.slice() : []; if (!values.length) { return []; } for (; idx < data.length; idx++) { index = this._dataItemPosition(data[idx].item, values); if (index !== -1) { indices[index] = idx; } } return this._normalizeIndices(indices); }, _firstVisibleItem: function () { var element = this.element[0]; var content = this.content[0]; var scrollTop = content.scrollTop; var itemHeight = $(element.children[0]).height(); var itemIndex = Math.floor(scrollTop / itemHeight) || 0; var item = element.children[itemIndex] || element.lastChild; var forward = item.offsetTop < scrollTop; while (item) { if (forward) { if (item.offsetTop + itemHeight > scrollTop || !item.nextSibling) { break; } item = item.nextSibling; } else { if (item.offsetTop <= scrollTop || !item.previousSibling) { break; } item = item.previousSibling; } } return this._view[$(item).data('offset-index')]; }, _fixedHeader: function () { if (this.isGrouped() && this.templates.fixedGroupTemplate) { this.header.show(); this.content.scroll(this._onScroll); } else { this.header.hide(); this.content.off('scroll', this._onScroll); } }, _renderHeader: function () { var template = this.templates.fixedGroupTemplate; if (!template) { return; } var visibleItem = this._firstVisibleItem(); if (visibleItem) { this.header.html(template(visibleItem.group)); } }, _renderItem: function (context) { var item = '<li tabindex="-1" role="option" unselectable="on" class="k-item'; var dataItem = context.item; var notFirstItem = context.index !== 0; var selected = context.selected; if (notFirstItem && context.newGroup) { item += ' k-first'; } if (selected) { item += ' k-state-selected'; } item += '"' + (selected ? ' aria-selected="true"' : '') + ' data-offset-index="' + context.index + '">'; item += this.templates.template(dataItem); if (notFirstItem && context.newGroup) { item += '<div class="k-group">' + this.templates.groupTemplate(context.group) + '</div>'; } return item + '</li>'; }, _render: function () { var html = ''; var i = 0; var idx = 0; var context; var dataContext = []; var view = this.dataSource.view(); var values = this.value(); var group, newGroup, j; var isGrouped = this.isGrouped(); if (isGrouped) { for (i = 0; i < view.length; i++) { group = view[i]; newGroup = true; for (j = 0; j < group.items.length; j++) { context = { selected: this._selected(group.items[j], values), item: group.items[j], group: group.value, newGroup: newGroup, index: idx }; dataContext[idx] = context; idx += 1; html += this._renderItem(context); newGroup = false; } } } else { for (i = 0; i < view.length; i++) { context = { selected: this._selected(view[i], values), item: view[i], index: i }; dataContext[i] = context; html += this._renderItem(context); } } this._view = dataContext; this.element[0].innerHTML = html; if (isGrouped && dataContext.length) { this._renderHeader(); } }, _selected: function (dataItem, values) { var select = !this.isFiltered() || this.options.selectable === 'multiple'; return select && this._dataItemPosition(dataItem, values) !== -1; }, setDSFilter: function (filter) { this._lastDSFilter = extend({}, filter); }, isFiltered: function () { if (!this._lastDSFilter) { this.setDSFilter(this.dataSource.filter()); } return !kendo.data.Query.compareFilters(this.dataSource.filter(), this._lastDSFilter); }, refresh: function (e) { var that = this; var action = e && e.action; var skipUpdateOnBind = that.options.skipUpdateOnBind; var isItemChange = action === 'itemchange'; var result; that.trigger('dataBinding'); this._angularItems('cleanup'); that._fixedHeader(); that._render(); that.bound(true); if (isItemChange || action === 'remove') { result = mapChangedItems(that._dataItems, e.items); if (result.changed.length) { if (isItemChange) { that.trigger('selectedItemChange', { items: result.changed }); } else { that.value(that._getValues(result.unchanged)); } } } else if (that.isFiltered() || that._skipUpdate) { that.focus(0); if (that._skipUpdate) { that._skipUpdate = false; that._selectedIndices = that._valueIndices(that._values, that._selectedIndices); } } else if (!skipUpdateOnBind && (!action || action === 'add')) { that.value(that._values); } if (that._valueDeferred) { that._valueDeferred.resolve(); } that._angularItems('compile'); that.trigger('dataBound'); }, bound: function (bound) { if (bound === undefined) { return this._bound; } this._bound = bound; }, isGrouped: function () { return (this.dataSource.group() || []).length; } }); ui.plugin(StaticList); function mapChangedItems(selected, itemsToMatch) { var itemsLength = itemsToMatch.length; var selectedLength = selected.length; var dataItem; var found; var i, j; var changed = []; var unchanged = []; if (selectedLength) { for (i = 0; i < selectedLength; i++) { dataItem = selected[i]; found = false; for (j = 0; j < itemsLength; j++) { if (dataItem === itemsToMatch[j]) { found = true; changed.push({ index: i, item: dataItem }); break; } } if (!found) { unchanged.push(dataItem); } } } return { changed: changed, unchanged: unchanged }; } function removeFiltersForField(expression, field) { var filters; var found = false; if (expression.filters) { filters = $.grep(expression.filters, function (filter) { found = removeFiltersForField(filter, field); if (filter.filters) { return filter.filters.length; } else { return filter.field != field; } }); if (!found && expression.filters.length !== filters.length) { found = true; } expression.filters = filters; } return found; } }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.fx', ['kendo.core'], f); }(function () { var __meta__ = { id: 'fx', name: 'Effects', category: 'framework', description: 'Required for animation effects in all Kendo UI widgets.', depends: ['core'] }; (function ($, undefined) { var kendo = window.kendo, fx = kendo.effects, each = $.each, extend = $.extend, proxy = $.proxy, support = kendo.support, browser = support.browser, transforms = support.transforms, transitions = support.transitions, scaleProperties = { scale: 0, scalex: 0, scaley: 0, scale3d: 0 }, translateProperties = { translate: 0, translatex: 0, translatey: 0, translate3d: 0 }, hasZoom = typeof document.documentElement.style.zoom !== 'undefined' && !transforms, matrix3dRegExp = /matrix3?d?\s*\(.*,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?/i, cssParamsRegExp = /^(-?[\d\.\-]+)?[\w\s]*,?\s*(-?[\d\.\-]+)?[\w\s]*/i, translateXRegExp = /translatex?$/i, oldEffectsRegExp = /(zoom|fade|expand)(\w+)/, singleEffectRegExp = /(zoom|fade|expand)/, unitRegExp = /[xy]$/i, transformProps = [ 'perspective', 'rotate', 'rotatex', 'rotatey', 'rotatez', 'rotate3d', 'scale', 'scalex', 'scaley', 'scalez', 'scale3d', 'skew', 'skewx', 'skewy', 'translate', 'translatex', 'translatey', 'translatez', 'translate3d', 'matrix', 'matrix3d' ], transform2d = [ 'rotate', 'scale', 'scalex', 'scaley', 'skew', 'skewx', 'skewy', 'translate', 'translatex', 'translatey', 'matrix' ], transform2units = { 'rotate': 'deg', scale: '', skew: 'px', translate: 'px' }, cssPrefix = transforms.css, round = Math.round, BLANK = '', PX = 'px', NONE = 'none', AUTO = 'auto', WIDTH = 'width', HEIGHT = 'height', HIDDEN = 'hidden', ORIGIN = 'origin', ABORT_ID = 'abortId', OVERFLOW = 'overflow', TRANSLATE = 'translate', POSITION = 'position', COMPLETE_CALLBACK = 'completeCallback', TRANSITION = cssPrefix + 'transition', TRANSFORM = cssPrefix + 'transform', BACKFACE = cssPrefix + 'backface-visibility', PERSPECTIVE = cssPrefix + 'perspective', DEFAULT_PERSPECTIVE = '1500px', TRANSFORM_PERSPECTIVE = 'perspective(' + DEFAULT_PERSPECTIVE + ')', directions = { left: { reverse: 'right', property: 'left', transition: 'translatex', vertical: false, modifier: -1 }, right: { reverse: 'left', property: 'left', transition: 'translatex', vertical: false, modifier: 1 }, down: { reverse: 'up', property: 'top', transition: 'translatey', vertical: true, modifier: 1 }, up: { reverse: 'down', property: 'top', transition: 'translatey', vertical: true, modifier: -1 }, top: { reverse: 'bottom' }, bottom: { reverse: 'top' }, 'in': { reverse: 'out', modifier: -1 }, out: { reverse: 'in', modifier: 1 }, vertical: { reverse: 'vertical' }, horizontal: { reverse: 'horizontal' } }; kendo.directions = directions; extend($.fn, { kendoStop: function (clearQueue, gotoEnd) { if (transitions) { return fx.stopQueue(this, clearQueue || false, gotoEnd || false); } else { return this.stop(clearQueue, gotoEnd); } } }); if (transforms && !transitions) { each(transform2d, function (idx, value) { $.fn[value] = function (val) { if (typeof val == 'undefined') { return animationProperty(this, value); } else { var that = $(this)[0], transformValue = value + '(' + val + transform2units[value.replace(unitRegExp, '')] + ')'; if (that.style.cssText.indexOf(TRANSFORM) == -1) { $(this).css(TRANSFORM, transformValue); } else { that.style.cssText = that.style.cssText.replace(new RegExp(value + '\\(.*?\\)', 'i'), transformValue); } } return this; }; $.fx.step[value] = function (fx) { $(fx.elem)[value](fx.now); }; }); var curProxy = $.fx.prototype.cur; $.fx.prototype.cur = function () { if (transform2d.indexOf(this.prop) != -1) { return parseFloat($(this.elem)[this.prop]()); } return curProxy.apply(this, arguments); }; } kendo.toggleClass = function (element, classes, options, add) { if (classes) { classes = classes.split(' '); if (transitions) { options = extend({ exclusive: 'all', duration: 400, ease: 'ease-out' }, options); element.css(TRANSITION, options.exclusive + ' ' + options.duration + 'ms ' + options.ease); setTimeout(function () { element.css(TRANSITION, '').css(HEIGHT); }, options.duration); } each(classes, function (idx, value) { element.toggleClass(value, add); }); } return element; }; kendo.parseEffects = function (input, mirror) { var effects = {}; if (typeof input === 'string') { each(input.split(' '), function (idx, value) { var redirectedEffect = !singleEffectRegExp.test(value), resolved = value.replace(oldEffectsRegExp, function (match, $1, $2) { return $1 + ':' + $2.toLowerCase(); }), effect = resolved.split(':'), direction = effect[1], effectBody = {}; if (effect.length > 1) { effectBody.direction = mirror && redirectedEffect ? directions[direction].reverse : direction; } effects[effect[0]] = effectBody; }); } else { each(input, function (idx) { var direction = this.direction; if (direction && mirror && !singleEffectRegExp.test(idx)) { this.direction = directions[direction].reverse; } effects[idx] = this; }); } return effects; }; function parseInteger(value) { return parseInt(value, 10); } function parseCSS(element, property) { return parseInteger(element.css(property)); } function keys(obj) { var acc = []; for (var propertyName in obj) { acc.push(propertyName); } return acc; } function strip3DTransforms(properties) { for (var key in properties) { if (transformProps.indexOf(key) != -1 && transform2d.indexOf(key) == -1) { delete properties[key]; } } return properties; } function normalizeCSS(element, properties) { var transformation = [], cssValues = {}, lowerKey, key, value, isTransformed; for (key in properties) { lowerKey = key.toLowerCase(); isTransformed = transforms && transformProps.indexOf(lowerKey) != -1; if (!support.hasHW3D && isTransformed && transform2d.indexOf(lowerKey) == -1) { delete properties[key]; } else { value = properties[key]; if (isTransformed) { transformation.push(key + '(' + value + ')'); } else { cssValues[key] = value; } } } if (transformation.length) { cssValues[TRANSFORM] = transformation.join(' '); } return cssValues; } if (transitions) { extend(fx, { transition: function (element, properties, options) { var css, delay = 0, oldKeys = element.data('keys') || [], timeoutID; options = extend({ duration: 200, ease: 'ease-out', complete: null, exclusive: 'all' }, options); var stopTransitionCalled = false; var stopTransition = function () { if (!stopTransitionCalled) { stopTransitionCalled = true; if (timeoutID) { clearTimeout(timeoutID); timeoutID = null; } element.removeData(ABORT_ID).dequeue().css(TRANSITION, '').css(TRANSITION); options.complete.call(element); } }; options.duration = $.fx ? $.fx.speeds[options.duration] || options.duration : options.duration; css = normalizeCSS(element, properties); $.merge(oldKeys, keys(css)); element.data('keys', $.unique(oldKeys)).height(); element.css(TRANSITION, options.exclusive + ' ' + options.duration + 'ms ' + options.ease).css(TRANSITION); element.css(css).css(TRANSFORM); if (transitions.event) { element.one(transitions.event, stopTransition); if (options.duration !== 0) { delay = 500; } } timeoutID = setTimeout(stopTransition, options.duration + delay); element.data(ABORT_ID, timeoutID); element.data(COMPLETE_CALLBACK, stopTransition); }, stopQueue: function (element, clearQueue, gotoEnd) { var cssValues, taskKeys = element.data('keys'), retainPosition = !gotoEnd && taskKeys, completeCallback = element.data(COMPLETE_CALLBACK); if (retainPosition) { cssValues = kendo.getComputedStyles(element[0], taskKeys); } if (completeCallback) { completeCallback(); } if (retainPosition) { element.css(cssValues); } return element.removeData('keys').stop(clearQueue); } }); } function animationProperty(element, property) { if (transforms) { var transform = element.css(TRANSFORM); if (transform == NONE) { return property == 'scale' ? 1 : 0; } var match = transform.match(new RegExp(property + '\\s*\\(([\\d\\w\\.]+)')), computed = 0; if (match) { computed = parseInteger(match[1]); } else { match = transform.match(matrix3dRegExp) || [ 0, 0, 0, 0, 0 ]; property = property.toLowerCase(); if (translateXRegExp.test(property)) { computed = parseFloat(match[3] / match[2]); } else if (property == 'translatey') { computed = parseFloat(match[4] / match[2]); } else if (property == 'scale') { computed = parseFloat(match[2]); } else if (property == 'rotate') { computed = parseFloat(Math.atan2(match[2], match[1])); } } return computed; } else { return parseFloat(element.css(property)); } } var EffectSet = kendo.Class.extend({ init: function (element, options) { var that = this; that.element = element; that.effects = []; that.options = options; that.restore = []; }, run: function (effects) { var that = this, effect, idx, jdx, length = effects.length, element = that.element, options = that.options, deferred = $.Deferred(), start = {}, end = {}, target, children, childrenLength; that.effects = effects; deferred.then($.proxy(that, 'complete')); element.data('animating', true); for (idx = 0; idx < length; idx++) { effect = effects[idx]; effect.setReverse(options.reverse); effect.setOptions(options); that.addRestoreProperties(effect.restore); effect.prepare(start, end); children = effect.children(); for (jdx = 0, childrenLength = children.length; jdx < childrenLength; jdx++) { children[jdx].duration(options.duration).run(); } } for (var effectName in options.effects) { extend(end, options.effects[effectName].properties); } if (!element.is(':visible')) { extend(start, { display: element.data('olddisplay') || 'block' }); } if (transforms && !options.reset) { target = element.data('targetTransform'); if (target) { start = extend(target, start); } } start = normalizeCSS(element, start); if (transforms && !transitions) { start = strip3DTransforms(start); } element.css(start).css(TRANSFORM); for (idx = 0; idx < length; idx++) { effects[idx].setup(); } if (options.init) { options.init(); } element.data('targetTransform', end); fx.animate(element, end, extend({}, options, { complete: deferred.resolve })); return deferred.promise(); }, stop: function () { $(this.element).kendoStop(true, true); }, addRestoreProperties: function (restore) { var element = this.element, value, i = 0, length = restore.length; for (; i < length; i++) { value = restore[i]; this.restore.push(value); if (!element.data(value)) { element.data(value, element.css(value)); } } }, restoreCallback: function () { var element = this.element; for (var i = 0, length = this.restore.length; i < length; i++) { var value = this.restore[i]; element.css(value, element.data(value)); } }, complete: function () { var that = this, idx = 0, element = that.element, options = that.options, effects = that.effects, length = effects.length; element.removeData('animating').dequeue(); if (options.hide) { element.data('olddisplay', element.css('display')).hide(); } this.restoreCallback(); if (hasZoom && !transforms) { setTimeout($.proxy(this, 'restoreCallback'), 0); } for (; idx < length; idx++) { effects[idx].teardown(); } if (options.completeCallback) { options.completeCallback(element); } } }); fx.promise = function (element, options) { var effects = [], effectClass, effectSet = new EffectSet(element, options), parsedEffects = kendo.parseEffects(options.effects), effect; options.effects = parsedEffects; for (var effectName in parsedEffects) { effectClass = fx[capitalize(effectName)]; if (effectClass) { effect = new effectClass(element, parsedEffects[effectName].direction); effects.push(effect); } } if (effects[0]) { effectSet.run(effects); } else { if (!element.is(':visible')) { element.css({ display: element.data('olddisplay') || 'block' }).css('display'); } if (options.init) { options.init(); } element.dequeue(); effectSet.complete(); } }; extend(fx, { animate: function (elements, properties, options) { var useTransition = options.transition !== false; delete options.transition; if (transitions && 'transition' in fx && useTransition) { fx.transition(elements, properties, options); } else { if (transforms) { elements.animate(strip3DTransforms(properties), { queue: false, show: false, hide: false, duration: options.duration, complete: options.complete }); } else { elements.each(function () { var element = $(this), multiple = {}; each(transformProps, function (idx, value) { var params, currentValue = properties ? properties[value] + ' ' : null; if (currentValue) { var single = properties; if (value in scaleProperties && properties[value] !== undefined) { params = currentValue.match(cssParamsRegExp); if (transforms) { extend(single, { scale: +params[0] }); } } else { if (value in translateProperties && properties[value] !== undefined) { var position = element.css(POSITION), isFixed = position == 'absolute' || position == 'fixed'; if (!element.data(TRANSLATE)) { if (isFixed) { element.data(TRANSLATE, { top: parseCSS(element, 'top') || 0, left: parseCSS(element, 'left') || 0, bottom: parseCSS(element, 'bottom'), right: parseCSS(element, 'right') }); } else { element.data(TRANSLATE, { top: parseCSS(element, 'marginTop') || 0, left: parseCSS(element, 'marginLeft') || 0 }); } } var originalPosition = element.data(TRANSLATE); params = currentValue.match(cssParamsRegExp); if (params) { var dX = value == TRANSLATE + 'y' ? +null : +params[1], dY = value == TRANSLATE + 'y' ? +params[1] : +params[2]; if (isFixed) { if (!isNaN(originalPosition.right)) { if (!isNaN(dX)) { extend(single, { right: originalPosition.right - dX }); } } else { if (!isNaN(dX)) { extend(single, { left: originalPosition.left + dX }); } } if (!isNaN(originalPosition.bottom)) { if (!isNaN(dY)) { extend(single, { bottom: originalPosition.bottom - dY }); } } else { if (!isNaN(dY)) { extend(single, { top: originalPosition.top + dY }); } } } else { if (!isNaN(dX)) { extend(single, { marginLeft: originalPosition.left + dX }); } if (!isNaN(dY)) { extend(single, { marginTop: originalPosition.top + dY }); } } } } } if (!transforms && value != 'scale' && value in single) { delete single[value]; } if (single) { extend(multiple, single); } } }); if (browser.msie) { delete multiple.scale; } element.animate(multiple, { queue: false, show: false, hide: false, duration: options.duration, complete: options.complete }); }); } } } }); fx.animatedPromise = fx.promise; var Effect = kendo.Class.extend({ init: function (element, direction) { var that = this; that.element = element; that._direction = direction; that.options = {}; that._additionalEffects = []; if (!that.restore) { that.restore = []; } }, reverse: function () { this._reverse = true; return this.run(); }, play: function () { this._reverse = false; return this.run(); }, add: function (additional) { this._additionalEffects.push(additional); return this; }, direction: function (value) { this._direction = value; return this; }, duration: function (duration) { this._duration = duration; return this; }, compositeRun: function () { var that = this, effectSet = new EffectSet(that.element, { reverse: that._reverse, duration: that._duration }), effects = that._additionalEffects.concat([that]); return effectSet.run(effects); }, run: function () { if (this._additionalEffects && this._additionalEffects[0]) { return this.compositeRun(); } var that = this, element = that.element, idx = 0, restore = that.restore, length = restore.length, value, deferred = $.Deferred(), start = {}, end = {}, target, children = that.children(), childrenLength = children.length; deferred.then($.proxy(that, '_complete')); element.data('animating', true); for (idx = 0; idx < length; idx++) { value = restore[idx]; if (!element.data(value)) { element.data(value, element.css(value)); } } for (idx = 0; idx < childrenLength; idx++) { children[idx].duration(that._duration).run(); } that.prepare(start, end); if (!element.is(':visible')) { extend(start, { display: element.data('olddisplay') || 'block' }); } if (transforms) { target = element.data('targetTransform'); if (target) { start = extend(target, start); } } start = normalizeCSS(element, start); if (transforms && !transitions) { start = strip3DTransforms(start); } element.css(start).css(TRANSFORM); that.setup(); element.data('targetTransform', end); fx.animate(element, end, { duration: that._duration, complete: deferred.resolve }); return deferred.promise(); }, stop: function () { var idx = 0, children = this.children(), childrenLength = children.length; for (idx = 0; idx < childrenLength; idx++) { children[idx].stop(); } $(this.element).kendoStop(true, true); return this; }, restoreCallback: function () { var element = this.element; for (var i = 0, length = this.restore.length; i < length; i++) { var value = this.restore[i]; element.css(value, element.data(value)); } }, _complete: function () { var that = this, element = that.element; element.removeData('animating').dequeue(); that.restoreCallback(); if (that.shouldHide()) { element.data('olddisplay', element.css('display')).hide(); } if (hasZoom && !transforms) { setTimeout($.proxy(that, 'restoreCallback'), 0); } that.teardown(); }, setOptions: function (options) { extend(true, this.options, options); }, children: function () { return []; }, shouldHide: $.noop, setup: $.noop, prepare: $.noop, teardown: $.noop, directions: [], setReverse: function (reverse) { this._reverse = reverse; return this; } }); function capitalize(word) { return word.charAt(0).toUpperCase() + word.substring(1); } function createEffect(name, definition) { var effectClass = Effect.extend(definition), directions = effectClass.prototype.directions; fx[capitalize(name)] = effectClass; fx.Element.prototype[name] = function (direction, opt1, opt2, opt3) { return new effectClass(this.element, direction, opt1, opt2, opt3); }; each(directions, function (idx, theDirection) { fx.Element.prototype[name + capitalize(theDirection)] = function (opt1, opt2, opt3) { return new effectClass(this.element, theDirection, opt1, opt2, opt3); }; }); } var FOUR_DIRECTIONS = [ 'left', 'right', 'up', 'down' ], IN_OUT = [ 'in', 'out' ]; createEffect('slideIn', { directions: FOUR_DIRECTIONS, divisor: function (value) { this.options.divisor = value; return this; }, prepare: function (start, end) { var that = this, tmp, element = that.element, direction = directions[that._direction], offset = -direction.modifier * (direction.vertical ? element.outerHeight() : element.outerWidth()), startValue = offset / (that.options && that.options.divisor || 1) + PX, endValue = '0px'; if (that._reverse) { tmp = start; start = end; end = tmp; } if (transforms) { start[direction.transition] = startValue; end[direction.transition] = endValue; } else { start[direction.property] = startValue; end[direction.property] = endValue; } } }); createEffect('tile', { directions: FOUR_DIRECTIONS, init: function (element, direction, previous) { Effect.prototype.init.call(this, element, direction); this.options = { previous: previous }; }, previousDivisor: function (value) { this.options.previousDivisor = value; return this; }, children: function () { var that = this, reverse = that._reverse, previous = that.options.previous, divisor = that.options.previousDivisor || 1, dir = that._direction; var children = [kendo.fx(that.element).slideIn(dir).setReverse(reverse)]; if (previous) { children.push(kendo.fx(previous).slideIn(directions[dir].reverse).divisor(divisor).setReverse(!reverse)); } return children; } }); function createToggleEffect(name, property, defaultStart, defaultEnd) { createEffect(name, { directions: IN_OUT, startValue: function (value) { this._startValue = value; return this; }, endValue: function (value) { this._endValue = value; return this; }, shouldHide: function () { return this._shouldHide; }, prepare: function (start, end) { var that = this, startValue, endValue, out = this._direction === 'out', startDataValue = that.element.data(property), startDataValueIsSet = !(isNaN(startDataValue) || startDataValue == defaultStart); if (startDataValueIsSet) { startValue = startDataValue; } else if (typeof this._startValue !== 'undefined') { startValue = this._startValue; } else { startValue = out ? defaultStart : defaultEnd; } if (typeof this._endValue !== 'undefined') { endValue = this._endValue; } else { endValue = out ? defaultEnd : defaultStart; } if (this._reverse) { start[property] = endValue; end[property] = startValue; } else { start[property] = startValue; end[property] = endValue; } that._shouldHide = end[property] === defaultEnd; } }); } createToggleEffect('fade', 'opacity', 1, 0); createToggleEffect('zoom', 'scale', 1, 0.01); createEffect('slideMargin', { prepare: function (start, end) { var that = this, element = that.element, options = that.options, origin = element.data(ORIGIN), offset = options.offset, margin, reverse = that._reverse; if (!reverse && origin === null) { element.data(ORIGIN, parseFloat(element.css('margin-' + options.axis))); } margin = element.data(ORIGIN) || 0; end['margin-' + options.axis] = !reverse ? margin + offset : margin; } }); createEffect('slideTo', { prepare: function (start, end) { var that = this, element = that.element, options = that.options, offset = options.offset.split(','), reverse = that._reverse; if (transforms) { end.translatex = !reverse ? offset[0] : 0; end.translatey = !reverse ? offset[1] : 0; } else { end.left = !reverse ? offset[0] : 0; end.top = !reverse ? offset[1] : 0; } element.css('left'); } }); createEffect('expand', { directions: [ 'horizontal', 'vertical' ], restore: [OVERFLOW], prepare: function (start, end) { var that = this, element = that.element, options = that.options, reverse = that._reverse, property = that._direction === 'vertical' ? HEIGHT : WIDTH, setLength = element[0].style[property], oldLength = element.data(property), length = parseFloat(oldLength || setLength), realLength = round(element.css(property, AUTO)[property]()); start.overflow = HIDDEN; length = options && options.reset ? realLength || length : length || realLength; end[property] = (reverse ? 0 : length) + PX; start[property] = (reverse ? length : 0) + PX; if (oldLength === undefined) { element.data(property, setLength); } }, shouldHide: function () { return this._reverse; }, teardown: function () { var that = this, element = that.element, property = that._direction === 'vertical' ? HEIGHT : WIDTH, length = element.data(property); if (length == AUTO || length === BLANK) { setTimeout(function () { element.css(property, AUTO).css(property); }, 0); } } }); var TRANSFER_START_STATE = { position: 'absolute', marginLeft: 0, marginTop: 0, scale: 1 }; createEffect('transfer', { init: function (element, target) { this.element = element; this.options = { target: target }; this.restore = []; }, setup: function () { this.element.appendTo(document.body); }, prepare: function (start, end) { var that = this, element = that.element, outerBox = fx.box(element), innerBox = fx.box(that.options.target), currentScale = animationProperty(element, 'scale'), scale = fx.fillScale(innerBox, outerBox), transformOrigin = fx.transformOrigin(innerBox, outerBox); extend(start, TRANSFER_START_STATE); end.scale = 1; element.css(TRANSFORM, 'scale(1)').css(TRANSFORM); element.css(TRANSFORM, 'scale(' + currentScale + ')'); start.top = outerBox.top; start.left = outerBox.left; start.transformOrigin = transformOrigin.x + PX + ' ' + transformOrigin.y + PX; if (that._reverse) { start.scale = scale; } else { end.scale = scale; } } }); var CLIPS = { top: 'rect(auto auto $size auto)', bottom: 'rect($size auto auto auto)', left: 'rect(auto $size auto auto)', right: 'rect(auto auto auto $size)' }; var ROTATIONS = { top: { start: 'rotatex(0deg)', end: 'rotatex(180deg)' }, bottom: { start: 'rotatex(-180deg)', end: 'rotatex(0deg)' }, left: { start: 'rotatey(0deg)', end: 'rotatey(-180deg)' }, right: { start: 'rotatey(180deg)', end: 'rotatey(0deg)' } }; function clipInHalf(container, direction) { var vertical = kendo.directions[direction].vertical, size = container[vertical ? HEIGHT : WIDTH]() / 2 + 'px'; return CLIPS[direction].replace('$size', size); } createEffect('turningPage', { directions: FOUR_DIRECTIONS, init: function (element, direction, container) { Effect.prototype.init.call(this, element, direction); this._container = container; }, prepare: function (start, end) { var that = this, reverse = that._reverse, direction = reverse ? directions[that._direction].reverse : that._direction, rotation = ROTATIONS[direction]; start.zIndex = 1; if (that._clipInHalf) { start.clip = clipInHalf(that._container, kendo.directions[direction].reverse); } start[BACKFACE] = HIDDEN; end[TRANSFORM] = TRANSFORM_PERSPECTIVE + (reverse ? rotation.start : rotation.end); start[TRANSFORM] = TRANSFORM_PERSPECTIVE + (reverse ? rotation.end : rotation.start); }, setup: function () { this._container.append(this.element); }, face: function (value) { this._face = value; return this; }, shouldHide: function () { var that = this, reverse = that._reverse, face = that._face; return reverse && !face || !reverse && face; }, clipInHalf: function (value) { this._clipInHalf = value; return this; }, temporary: function () { this.element.addClass('temp-page'); return this; } }); createEffect('staticPage', { directions: FOUR_DIRECTIONS, init: function (element, direction, container) { Effect.prototype.init.call(this, element, direction); this._container = container; }, restore: ['clip'], prepare: function (start, end) { var that = this, direction = that._reverse ? directions[that._direction].reverse : that._direction; start.clip = clipInHalf(that._container, direction); start.opacity = 0.999; end.opacity = 1; }, shouldHide: function () { var that = this, reverse = that._reverse, face = that._face; return reverse && !face || !reverse && face; }, face: function (value) { this._face = value; return this; } }); createEffect('pageturn', { directions: [ 'horizontal', 'vertical' ], init: function (element, direction, face, back) { Effect.prototype.init.call(this, element, direction); this.options = {}; this.options.face = face; this.options.back = back; }, children: function () { var that = this, options = that.options, direction = that._direction === 'horizontal' ? 'left' : 'top', reverseDirection = kendo.directions[direction].reverse, reverse = that._reverse, temp, faceClone = options.face.clone(true).removeAttr('id'), backClone = options.back.clone(true).removeAttr('id'), element = that.element; if (reverse) { temp = direction; direction = reverseDirection; reverseDirection = temp; } return [ kendo.fx(options.face).staticPage(direction, element).face(true).setReverse(reverse), kendo.fx(options.back).staticPage(reverseDirection, element).setReverse(reverse), kendo.fx(faceClone).turningPage(direction, element).face(true).clipInHalf(true).temporary().setReverse(reverse), kendo.fx(backClone).turningPage(reverseDirection, element).clipInHalf(true).temporary().setReverse(reverse) ]; }, prepare: function (start, end) { start[PERSPECTIVE] = DEFAULT_PERSPECTIVE; start.transformStyle = 'preserve-3d'; start.opacity = 0.999; end.opacity = 1; }, teardown: function () { this.element.find('.temp-page').remove(); } }); createEffect('flip', { directions: [ 'horizontal', 'vertical' ], init: function (element, direction, face, back) { Effect.prototype.init.call(this, element, direction); this.options = {}; this.options.face = face; this.options.back = back; }, children: function () { var that = this, options = that.options, direction = that._direction === 'horizontal' ? 'left' : 'top', reverseDirection = kendo.directions[direction].reverse, reverse = that._reverse, temp, element = that.element; if (reverse) { temp = direction; direction = reverseDirection; reverseDirection = temp; } return [ kendo.fx(options.face).turningPage(direction, element).face(true).setReverse(reverse), kendo.fx(options.back).turningPage(reverseDirection, element).setReverse(reverse) ]; }, prepare: function (start) { start[PERSPECTIVE] = DEFAULT_PERSPECTIVE; start.transformStyle = 'preserve-3d'; } }); var RESTORE_OVERFLOW = !support.mobileOS.android; var IGNORE_TRANSITION_EVENT_SELECTOR = '.km-touch-scrollbar, .km-actionsheet-wrapper'; createEffect('replace', { _before: $.noop, _after: $.noop, init: function (element, previous, transitionClass) { Effect.prototype.init.call(this, element); this._previous = $(previous); this._transitionClass = transitionClass; }, duration: function () { throw new Error('The replace effect does not support duration setting; the effect duration may be customized through the transition class rule'); }, beforeTransition: function (callback) { this._before = callback; return this; }, afterTransition: function (callback) { this._after = callback; return this; }, _both: function () { return $().add(this._element).add(this._previous); }, _containerClass: function () { var direction = this._direction, containerClass = 'k-fx k-fx-start k-fx-' + this._transitionClass; if (direction) { containerClass += ' k-fx-' + direction; } if (this._reverse) { containerClass += ' k-fx-reverse'; } return containerClass; }, complete: function (e) { if (!this.deferred || e && $(e.target).is(IGNORE_TRANSITION_EVENT_SELECTOR)) { return; } var container = this.container; container.removeClass('k-fx-end').removeClass(this._containerClass()).off(transitions.event, this.completeProxy); this._previous.hide().removeClass('k-fx-current'); this.element.removeClass('k-fx-next'); if (RESTORE_OVERFLOW) { container.css(OVERFLOW, ''); } if (!this.isAbsolute) { this._both().css(POSITION, ''); } this.deferred.resolve(); delete this.deferred; }, run: function () { if (this._additionalEffects && this._additionalEffects[0]) { return this.compositeRun(); } var that = this, element = that.element, previous = that._previous, container = element.parents().filter(previous.parents()).first(), both = that._both(), deferred = $.Deferred(), originalPosition = element.css(POSITION), originalOverflow; if (!container.length) { container = element.parent(); } this.container = container; this.deferred = deferred; this.isAbsolute = originalPosition == 'absolute'; if (!this.isAbsolute) { both.css(POSITION, 'absolute'); } if (RESTORE_OVERFLOW) { originalOverflow = container.css(OVERFLOW); container.css(OVERFLOW, 'hidden'); } if (!transitions) { this.complete(); } else { element.addClass('k-fx-hidden'); container.addClass(this._containerClass()); this.completeProxy = $.proxy(this, 'complete'); container.on(transitions.event, this.completeProxy); kendo.animationFrame(function () { element.removeClass('k-fx-hidden').addClass('k-fx-next'); previous.css('display', '').addClass('k-fx-current'); that._before(previous, element); kendo.animationFrame(function () { container.removeClass('k-fx-start').addClass('k-fx-end'); that._after(previous, element); }); }); } return deferred.promise(); }, stop: function () { this.complete(); } }); var Animation = kendo.Class.extend({ init: function () { var that = this; that._tickProxy = proxy(that._tick, that); that._started = false; }, tick: $.noop, done: $.noop, onEnd: $.noop, onCancel: $.noop, start: function () { if (!this.enabled()) { return; } if (!this.done()) { this._started = true; kendo.animationFrame(this._tickProxy); } else { this.onEnd(); } }, enabled: function () { return true; }, cancel: function () { this._started = false; this.onCancel(); }, _tick: function () { var that = this; if (!that._started) { return; } that.tick(); if (!that.done()) { kendo.animationFrame(that._tickProxy); } else { that._started = false; that.onEnd(); } } }); var Transition = Animation.extend({ init: function (options) { var that = this; extend(that, options); Animation.fn.init.call(that); }, done: function () { return this.timePassed() >= this.duration; }, timePassed: function () { return Math.min(this.duration, new Date() - this.startDate); }, moveTo: function (options) { var that = this, movable = that.movable; that.initial = movable[that.axis]; that.delta = options.location - that.initial; that.duration = typeof options.duration == 'number' ? options.duration : 300; that.tick = that._easeProxy(options.ease); that.startDate = new Date(); that.start(); }, _easeProxy: function (ease) { var that = this; return function () { that.movable.moveAxis(that.axis, ease(that.timePassed(), that.initial, that.delta, that.duration)); }; } }); extend(Transition, { easeOutExpo: function (t, b, c, d) { return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; }, easeOutBack: function (t, b, c, d, s) { s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; } }); fx.Animation = Animation; fx.Transition = Transition; fx.createEffect = createEffect; fx.box = function (element) { element = $(element); var result = element.offset(); result.width = element.outerWidth(); result.height = element.outerHeight(); return result; }; fx.transformOrigin = function (inner, outer) { var x = (inner.left - outer.left) * outer.width / (outer.width - inner.width), y = (inner.top - outer.top) * outer.height / (outer.height - inner.height); return { x: isNaN(x) ? 0 : x, y: isNaN(y) ? 0 : y }; }; fx.fillScale = function (inner, outer) { return Math.min(inner.width / outer.width, inner.height / outer.height); }; fx.fitScale = function (inner, outer) { return Math.max(inner.width / outer.width, inner.height / outer.height); }; }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.userevents', ['kendo.core'], f); }(function () { var __meta__ = { id: 'userevents', name: 'User Events', category: 'framework', depends: ['core'], hidden: true }; (function ($, undefined) { var kendo = window.kendo, support = kendo.support, document = window.document, Class = kendo.Class, Observable = kendo.Observable, now = $.now, extend = $.extend, OS = support.mobileOS, invalidZeroEvents = OS && OS.android, DEFAULT_MIN_HOLD = 800, DEFAULT_THRESHOLD = support.browser.msie ? 5 : 0, PRESS = 'press', HOLD = 'hold', SELECT = 'select', START = 'start', MOVE = 'move', END = 'end', CANCEL = 'cancel', TAP = 'tap', RELEASE = 'release', GESTURESTART = 'gesturestart', GESTURECHANGE = 'gesturechange', GESTUREEND = 'gestureend', GESTURETAP = 'gesturetap'; var THRESHOLD = { 'api': 0, 'touch': 0, 'mouse': 9, 'pointer': 9 }; var ENABLE_GLOBAL_SURFACE = !support.touch || support.mouseAndTouchPresent; function touchDelta(touch1, touch2) { var x1 = touch1.x.location, y1 = touch1.y.location, x2 = touch2.x.location, y2 = touch2.y.location, dx = x1 - x2, dy = y1 - y2; return { center: { x: (x1 + x2) / 2, y: (y1 + y2) / 2 }, distance: Math.sqrt(dx * dx + dy * dy) }; } function getTouches(e) { var touches = [], originalEvent = e.originalEvent, currentTarget = e.currentTarget, idx = 0, length, changedTouches, touch; if (e.api) { touches.push({ id: 2, event: e, target: e.target, currentTarget: e.target, location: e, type: 'api' }); } else if (e.type.match(/touch/)) { changedTouches = originalEvent ? originalEvent.changedTouches : []; for (length = changedTouches.length; idx < length; idx++) { touch = changedTouches[idx]; touches.push({ location: touch, event: e, target: touch.target, currentTarget: currentTarget, id: touch.identifier, type: 'touch' }); } } else if (support.pointers || support.msPointers) { touches.push({ location: originalEvent, event: e, target: e.target, currentTarget: currentTarget, id: originalEvent.pointerId, type: 'pointer' }); } else { touches.push({ id: 1, event: e, target: e.target, currentTarget: currentTarget, location: e, type: 'mouse' }); } return touches; } var TouchAxis = Class.extend({ init: function (axis, location) { var that = this; that.axis = axis; that._updateLocationData(location); that.startLocation = that.location; that.velocity = that.delta = 0; that.timeStamp = now(); }, move: function (location) { var that = this, offset = location['page' + that.axis], timeStamp = now(), timeDelta = timeStamp - that.timeStamp || 1; if (!offset && invalidZeroEvents) { return; } that.delta = offset - that.location; that._updateLocationData(location); that.initialDelta = offset - that.startLocation; that.velocity = that.delta / timeDelta; that.timeStamp = timeStamp; }, _updateLocationData: function (location) { var that = this, axis = that.axis; that.location = location['page' + axis]; that.client = location['client' + axis]; that.screen = location['screen' + axis]; } }); var Touch = Class.extend({ init: function (userEvents, target, touchInfo) { extend(this, { x: new TouchAxis('X', touchInfo.location), y: new TouchAxis('Y', touchInfo.location), type: touchInfo.type, useClickAsTap: userEvents.useClickAsTap, threshold: userEvents.threshold || THRESHOLD[touchInfo.type], userEvents: userEvents, target: target, currentTarget: touchInfo.currentTarget, initialTouch: touchInfo.target, id: touchInfo.id, pressEvent: touchInfo, _moved: false, _finished: false }); }, press: function () { this._holdTimeout = setTimeout($.proxy(this, '_hold'), this.userEvents.minHold); this._trigger(PRESS, this.pressEvent); }, _hold: function () { this._trigger(HOLD, this.pressEvent); }, move: function (touchInfo) { var that = this; if (that._finished) { return; } that.x.move(touchInfo.location); that.y.move(touchInfo.location); if (!that._moved) { if (that._withinIgnoreThreshold()) { return; } if (!UserEvents.current || UserEvents.current === that.userEvents) { that._start(touchInfo); } else { return that.dispose(); } } if (!that._finished) { that._trigger(MOVE, touchInfo); } }, end: function (touchInfo) { this.endTime = now(); if (this._finished) { return; } this._finished = true; this._trigger(RELEASE, touchInfo); if (this._moved) { this._trigger(END, touchInfo); } else { if (!this.useClickAsTap) { this._trigger(TAP, touchInfo); } } clearTimeout(this._holdTimeout); this.dispose(); }, dispose: function () { var userEvents = this.userEvents, activeTouches = userEvents.touches; this._finished = true; this.pressEvent = null; clearTimeout(this._holdTimeout); activeTouches.splice($.inArray(this, activeTouches), 1); }, skip: function () { this.dispose(); }, cancel: function () { this.dispose(); }, isMoved: function () { return this._moved; }, _start: function (touchInfo) { clearTimeout(this._holdTimeout); this.startTime = now(); this._moved = true; this._trigger(START, touchInfo); }, _trigger: function (name, touchInfo) { var that = this, jQueryEvent = touchInfo.event, data = { touch: that, x: that.x, y: that.y, target: that.target, event: jQueryEvent }; if (that.userEvents.notify(name, data)) { jQueryEvent.preventDefault(); } }, _withinIgnoreThreshold: function () { var xDelta = this.x.initialDelta, yDelta = this.y.initialDelta; return Math.sqrt(xDelta * xDelta + yDelta * yDelta) <= this.threshold; } }); function withEachUpEvent(callback) { var downEvents = kendo.eventMap.up.split(' '), idx = 0, length = downEvents.length; for (; idx < length; idx++) { callback(downEvents[idx]); } } var UserEvents = Observable.extend({ init: function (element, options) { var that = this, filter, ns = kendo.guid(); options = options || {}; filter = that.filter = options.filter; that.threshold = options.threshold || DEFAULT_THRESHOLD; that.minHold = options.minHold || DEFAULT_MIN_HOLD; that.touches = []; that._maxTouches = options.multiTouch ? 2 : 1; that.allowSelection = options.allowSelection; that.captureUpIfMoved = options.captureUpIfMoved; that.useClickAsTap = !options.fastTap && !support.delayedClick(); that.eventNS = ns; element = $(element).handler(that); Observable.fn.init.call(that); extend(that, { element: element, surface: options.global && ENABLE_GLOBAL_SURFACE ? $(document.documentElement) : $(options.surface || element), stopPropagation: options.stopPropagation, pressed: false }); that.surface.handler(that).on(kendo.applyEventMap('move', ns), '_move').on(kendo.applyEventMap('up cancel', ns), '_end'); element.on(kendo.applyEventMap('down', ns), filter, '_start'); if (that.useClickAsTap) { element.on(kendo.applyEventMap('click', ns), filter, '_click'); } if (support.pointers || support.msPointers) { if (support.browser.version < 11) { element.css('-ms-touch-action', 'pinch-zoom double-tap-zoom'); } else { element.css('touch-action', options.touchAction || 'none'); } } if (options.preventDragEvent) { element.on(kendo.applyEventMap('dragstart', ns), kendo.preventDefault); } element.on(kendo.applyEventMap('mousedown', ns), filter, { root: element }, '_select'); if (that.captureUpIfMoved && support.eventCapture) { var surfaceElement = that.surface[0], preventIfMovingProxy = $.proxy(that.preventIfMoving, that); withEachUpEvent(function (eventName) { surfaceElement.addEventListener(eventName, preventIfMovingProxy, true); }); } that.bind([ PRESS, HOLD, TAP, START, MOVE, END, RELEASE, CANCEL, GESTURESTART, GESTURECHANGE, GESTUREEND, GESTURETAP, SELECT ], options); }, preventIfMoving: function (e) { if (this._isMoved()) { e.preventDefault(); } }, destroy: function () { var that = this; if (that._destroyed) { return; } that._destroyed = true; if (that.captureUpIfMoved && support.eventCapture) { var surfaceElement = that.surface[0]; withEachUpEvent(function (eventName) { surfaceElement.removeEventListener(eventName, that.preventIfMoving); }); } that.element.kendoDestroy(that.eventNS); that.surface.kendoDestroy(that.eventNS); that.element.removeData('handler'); that.surface.removeData('handler'); that._disposeAll(); that.unbind(); delete that.surface; delete that.element; delete that.currentTarget; }, capture: function () { UserEvents.current = this; }, cancel: function () { this._disposeAll(); this.trigger(CANCEL); }, notify: function (eventName, data) { var that = this, touches = that.touches; if (this._isMultiTouch()) { switch (eventName) { case MOVE: eventName = GESTURECHANGE; break; case END: eventName = GESTUREEND; break; case TAP: eventName = GESTURETAP; break; } extend(data, { touches: touches }, touchDelta(touches[0], touches[1])); } return this.trigger(eventName, extend(data, { type: eventName })); }, press: function (x, y, target) { this._apiCall('_start', x, y, target); }, move: function (x, y) { this._apiCall('_move', x, y); }, end: function (x, y) { this._apiCall('_end', x, y); }, _isMultiTouch: function () { return this.touches.length > 1; }, _maxTouchesReached: function () { return this.touches.length >= this._maxTouches; }, _disposeAll: function () { var touches = this.touches; while (touches.length > 0) { touches.pop().dispose(); } }, _isMoved: function () { return $.grep(this.touches, function (touch) { return touch.isMoved(); }).length; }, _select: function (e) { if (!this.allowSelection || this.trigger(SELECT, { event: e })) { e.preventDefault(); } }, _start: function (e) { var that = this, idx = 0, filter = that.filter, target, touches = getTouches(e), length = touches.length, touch, which = e.which; if (which && which > 1 || that._maxTouchesReached()) { return; } UserEvents.current = null; that.currentTarget = e.currentTarget; if (that.stopPropagation) { e.stopPropagation(); } for (; idx < length; idx++) { if (that._maxTouchesReached()) { break; } touch = touches[idx]; if (filter) { target = $(touch.currentTarget); } else { target = that.element; } if (!target.length) { continue; } touch = new Touch(that, target, touch); that.touches.push(touch); touch.press(); if (that._isMultiTouch()) { that.notify('gesturestart', {}); } } }, _move: function (e) { this._eachTouch('move', e); }, _end: function (e) { this._eachTouch('end', e); }, _click: function (e) { var data = { touch: { initialTouch: e.target, target: $(e.currentTarget), endTime: now(), x: { location: e.pageX, client: e.clientX }, y: { location: e.pageY, client: e.clientY } }, x: e.pageX, y: e.pageY, target: $(e.currentTarget), event: e, type: 'tap' }; if (this.trigger('tap', data)) { e.preventDefault(); } }, _eachTouch: function (methodName, e) { var that = this, dict = {}, touches = getTouches(e), activeTouches = that.touches, idx, touch, touchInfo, matchingTouch; for (idx = 0; idx < activeTouches.length; idx++) { touch = activeTouches[idx]; dict[touch.id] = touch; } for (idx = 0; idx < touches.length; idx++) { touchInfo = touches[idx]; matchingTouch = dict[touchInfo.id]; if (matchingTouch) { matchingTouch[methodName](touchInfo); } } }, _apiCall: function (type, x, y, target) { this[type]({ api: true, pageX: x, pageY: y, clientX: x, clientY: y, target: $(target || this.element)[0], stopPropagation: $.noop, preventDefault: $.noop }); } }); UserEvents.defaultThreshold = function (value) { DEFAULT_THRESHOLD = value; }; UserEvents.minHold = function (value) { DEFAULT_MIN_HOLD = value; }; kendo.getTouches = getTouches; kendo.touchDelta = touchDelta; kendo.UserEvents = UserEvents; }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.menu', ['kendo.popup'], f); }(function () { var __meta__ = { id: 'menu', name: 'Menu', category: 'web', description: 'The Menu widget displays hierarchical data as a multi-level menu.', depends: ['popup'] }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, activeElement = kendo._activeElement, touch = kendo.support.touch && kendo.support.mobileOS, MOUSEDOWN = 'mousedown', CLICK = 'click', extend = $.extend, proxy = $.proxy, each = $.each, template = kendo.template, keys = kendo.keys, Widget = ui.Widget, excludedNodesRegExp = /^(ul|a|div)$/i, NS = '.kendoMenu', IMG = 'img', OPEN = 'open', MENU = 'k-menu', LINK = 'k-link', LAST = 'k-last', CLOSE = 'close', TIMER = 'timer', FIRST = 'k-first', IMAGE = 'k-image', SELECT = 'select', ZINDEX = 'zIndex', ACTIVATE = 'activate', DEACTIVATE = 'deactivate', POINTERDOWN = 'touchstart' + NS + ' MSPointerDown' + NS + ' pointerdown' + NS, pointers = kendo.support.pointers, msPointers = kendo.support.msPointers, allPointers = msPointers || pointers, MOUSEENTER = pointers ? 'pointerover' : msPointers ? 'MSPointerOver' : 'mouseenter', MOUSELEAVE = pointers ? 'pointerout' : msPointers ? 'MSPointerOut' : 'mouseleave', mobile = touch || allPointers, DOCUMENT_ELEMENT = $(document.documentElement), KENDOPOPUP = 'kendoPopup', DEFAULTSTATE = 'k-state-default', HOVERSTATE = 'k-state-hover', FOCUSEDSTATE = 'k-state-focused', DISABLEDSTATE = 'k-state-disabled', SELECTEDSTATE = 'k-state-selected', menuSelector = '.k-menu', groupSelector = '.k-menu-group', popupSelector = groupSelector + ',.k-animation-container', allItemsSelector = ':not(.k-list) > .k-item', disabledSelector = '.k-item.k-state-disabled', itemSelector = '.k-item:not(.k-state-disabled)', linkSelector = '.k-item:not(.k-state-disabled) > .k-link', exclusionSelector = ':not(.k-item.k-separator)', nextSelector = exclusionSelector + ':eq(0)', lastSelector = exclusionSelector + ':last', templateSelector = '> div:not(.k-animation-container,.k-list-container)', touchPointerTypes = { '2': 1, 'touch': 1 }, templates = { content: template('<div #= contentCssAttributes(item) # tabindex=\'-1\'>#= content(item) #</div>'), group: template('<ul class=\'#= groupCssClass(group) #\'#= groupAttributes(group) # role=\'menu\' aria-hidden=\'true\'>' + '#= renderItems(data) #' + '</ul>'), itemWrapper: template('<#= tag(item) # class=\'#= textClass(item) #\'#= textAttributes(item) #>' + '#= image(data) ##= sprite(item) ##= text(item) #' + '#= arrow(data) #' + '</#= tag(item) #>'), item: template('<li class=\'#= wrapperCssClass(group, item) #\' #= itemCssAttributes(item) # role=\'menuitem\' #=item.items ? "aria-haspopup=\'true\'": ""#' + '#=item.enabled === false ? "aria-disabled=\'true\'" : \'\'#>' + '#= itemWrapper(data) #' + '# if (item.items) { #' + '#= subGroup({ items: item.items, menu: menu, group: { expanded: item.expanded } }) #' + '# } else if (item.content || item.contentUrl) { #' + '#= renderContent(data) #' + '# } #' + '</li>'), image: template('<img #= imageCssAttributes(item) # alt=\'\' src=\'#= item.imageUrl #\' />'), arrow: template('<span class=\'#= arrowClass(item, group) #\'></span>'), sprite: template('<span class=\'k-sprite #= spriteCssClass #\'></span>'), empty: template('') }, rendering = { wrapperCssClass: function (group, item) { var result = 'k-item', index = item.index; if (item.enabled === false) { result += ' k-state-disabled'; } else { result += ' k-state-default'; } if (group.firstLevel && index === 0) { result += ' k-first'; } if (index == group.length - 1) { result += ' k-last'; } if (item.cssClass) { result += ' ' + item.cssClass; } if (item.attr && item.attr.hasOwnProperty('class')) { result += ' ' + item.attr['class']; } if (item.selected) { result += ' ' + SELECTEDSTATE; } return result; }, itemCssAttributes: function (item) { var result = ''; var attributes = item.attr || {}; for (var attr in attributes) { if (attributes.hasOwnProperty(attr) && attr !== 'class') { result += attr + '="' + attributes[attr] + '" '; } } return result; }, imageCssAttributes: function (item) { var result = ''; var attributes = item.imageAttr || {}; if (!attributes['class']) { attributes['class'] = IMAGE; } else { attributes['class'] += ' ' + IMAGE; } for (var attr in attributes) { if (attributes.hasOwnProperty(attr)) { result += attr + '="' + attributes[attr] + '" '; } } return result; }, contentCssAttributes: function (item) { var result = ''; var attributes = item.contentAttr || {}; var defaultClasses = 'k-content k-group k-menu-group'; if (!attributes['class']) { attributes['class'] = defaultClasses; } else { attributes['class'] += ' ' + defaultClasses; } for (var attr in attributes) { if (attributes.hasOwnProperty(attr)) { result += attr + '="' + attributes[attr] + '" '; } } return result; }, textClass: function () { return LINK; }, textAttributes: function (item) { return item.url ? ' href=\'' + item.url + '\'' : ''; }, arrowClass: function (item, group) { var result = 'k-icon'; if (group.horizontal) { result += ' k-i-arrow-s'; } else { result += ' k-i-arrow-e'; } return result; }, text: function (item) { return item.encoded === false ? item.text : kendo.htmlEncode(item.text); }, tag: function (item) { return item.url ? 'a' : 'span'; }, groupAttributes: function (group) { return group.expanded !== true ? ' style=\'display:none\'' : ''; }, groupCssClass: function () { return 'k-group k-menu-group'; }, content: function (item) { return item.content ? item.content : ' '; } }; function getEffectDirection(direction, root) { direction = direction.split(' ')[!root + 0] || direction; return direction.replace('top', 'up').replace('bottom', 'down'); } function parseDirection(direction, root, isRtl) { direction = direction.split(' ')[!root + 0] || direction; var output = { origin: [ 'bottom', isRtl ? 'right' : 'left' ], position: [ 'top', isRtl ? 'right' : 'left' ] }, horizontal = /left|right/.test(direction); if (horizontal) { output.origin = [ 'top', direction ]; output.position[1] = kendo.directions[direction].reverse; } else { output.origin[0] = direction; output.position[0] = kendo.directions[direction].reverse; } output.origin = output.origin.join(' '); output.position = output.position.join(' '); return output; } function contains(parent, child) { try { return $.contains(parent, child); } catch (e) { return false; } } function updateItemClasses(item) { item = $(item); item.addClass('k-item').children(IMG).addClass(IMAGE); item.children('a').addClass(LINK).children(IMG).addClass(IMAGE); item.filter(':not([disabled])').addClass(DEFAULTSTATE); item.filter('.k-separator').empty().append(' '); item.filter('li[disabled]').addClass(DISABLEDSTATE).removeAttr('disabled').attr('aria-disabled', true); if (!item.filter('[role]').length) { item.attr('role', 'menuitem'); } if (!item.children('.' + LINK).length) { item.contents().filter(function () { return !this.nodeName.match(excludedNodesRegExp) && !(this.nodeType == 3 && !$.trim(this.nodeValue)); }).wrapAll('<span class=\'' + LINK + '\'/>'); } updateArrow(item); updateFirstLast(item); } function updateArrow(item) { item = $(item); item.find('> .k-link > [class*=k-i-arrow]:not(.k-sprite)').remove(); item.filter(':has(.k-menu-group)').children('.k-link:not(:has([class*=k-i-arrow]:not(.k-sprite)))').each(function () { var item = $(this), parent = item.parent().parent(); item.append('<span class=\'k-icon ' + (parent.hasClass(MENU + '-horizontal') ? 'k-i-arrow-s' : 'k-i-arrow-e') + '\'/>'); }); } function updateFirstLast(item) { item = $(item); item.filter('.k-first:not(:first-child)').removeClass(FIRST); item.filter('.k-last:not(:last-child)').removeClass(LAST); item.filter(':first-child').addClass(FIRST); item.filter(':last-child').addClass(LAST); } var Menu = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); element = that.wrapper = that.element; options = that.options; that._initData(options); that._updateClasses(); that._animations(options); that.nextItemZIndex = 100; that._tabindex(); that._focusProxy = proxy(that._focusHandler, that); element.on(POINTERDOWN, itemSelector, that._focusProxy).on(CLICK + NS, disabledSelector, false).on(CLICK + NS, itemSelector, proxy(that._click, that)).on('keydown' + NS, proxy(that._keydown, that)).on('focus' + NS, proxy(that._focus, that)).on('focus' + NS, '.k-content', proxy(that._focus, that)).on(POINTERDOWN + ' ' + MOUSEDOWN + NS, '.k-content', proxy(that._preventClose, that)).on('blur' + NS, proxy(that._removeHoverItem, that)).on('blur' + NS, '[tabindex]', proxy(that._checkActiveElement, that)).on(MOUSEENTER + NS, itemSelector, proxy(that._mouseenter, that)).on(MOUSELEAVE + NS, itemSelector, proxy(that._mouseleave, that)).on(MOUSEENTER + NS + ' ' + MOUSELEAVE + NS + ' ' + MOUSEDOWN + NS + ' ' + CLICK + NS, linkSelector, proxy(that._toggleHover, that)); if (options.openOnClick) { that.clicked = false; that._documentClickHandler = proxy(that._documentClick, that); $(document).click(that._documentClickHandler); } element.attr('role', 'menubar'); if (element[0].id) { that._ariaId = kendo.format('{0}_mn_active', element[0].id); } kendo.notify(that); }, events: [ OPEN, CLOSE, ACTIVATE, DEACTIVATE, SELECT ], options: { name: 'Menu', animation: { open: { duration: 200 }, close: { duration: 100 } }, orientation: 'horizontal', direction: 'default', openOnClick: false, closeOnClick: true, hoverDelay: 100, popupCollision: undefined }, _initData: function (options) { var that = this; if (options.dataSource) { that.angular('cleanup', function () { return { elements: that.element.children() }; }); that.element.empty(); that.append(options.dataSource, that.element); that.angular('compile', function () { return { elements: that.element.children() }; }); } }, setOptions: function (options) { var animation = this.options.animation; this._animations(options); options.animation = extend(true, animation, options.animation); if ('dataSource' in options) { this._initData(options); } this._updateClasses(); Widget.fn.setOptions.call(this, options); }, destroy: function () { var that = this; Widget.fn.destroy.call(that); that.element.off(NS); if (that._documentClickHandler) { $(document).unbind('click', that._documentClickHandler); } kendo.destroy(that.element); }, enable: function (element, enable) { this._toggleDisabled(element, enable !== false); return this; }, disable: function (element) { this._toggleDisabled(element, false); return this; }, append: function (item, referenceItem) { referenceItem = this.element.find(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.length ? referenceItem.find('> .k-menu-group, > .k-animation-container > .k-menu-group') : null); each(inserted.items, function () { inserted.group.append(this); updateArrow(this); }); updateArrow(referenceItem); updateFirstLast(inserted.group.find('.k-first, .k-last').add(inserted.items)); return this; }, insertBefore: function (item, referenceItem) { referenceItem = this.element.find(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.parent()); each(inserted.items, function () { referenceItem.before(this); updateArrow(this); updateFirstLast(this); }); updateFirstLast(referenceItem); return this; }, insertAfter: function (item, referenceItem) { referenceItem = this.element.find(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.parent()); each(inserted.items, function () { referenceItem.after(this); updateArrow(this); updateFirstLast(this); }); updateFirstLast(referenceItem); return this; }, _insert: function (item, referenceItem, parent) { var that = this, items, groups; if (!referenceItem || !referenceItem.length) { parent = that.element; } var plain = $.isPlainObject(item), groupData = { firstLevel: parent.hasClass(MENU), horizontal: parent.hasClass(MENU + '-horizontal'), expanded: true, length: parent.children().length }; if (referenceItem && !parent.length) { parent = $(Menu.renderGroup({ group: groupData })).appendTo(referenceItem); } if (plain || $.isArray(item)) { items = $($.map(plain ? [item] : item, function (value, idx) { if (typeof value === 'string') { return $(value).get(); } else { return $(Menu.renderItem({ group: groupData, item: extend(value, { index: idx }) })).get(); } })); } else { if (typeof item == 'string' && item.charAt(0) != '<') { items = that.element.find(item); } else { items = $(item); } groups = items.find('> ul').addClass('k-menu-group').attr('role', 'menu'); items = items.filter('li'); items.add(groups.find('> li')).each(function () { updateItemClasses(this); }); } return { items: items, group: parent }; }, remove: function (element) { element = this.element.find(element); var that = this, parent = element.parentsUntil(that.element, allItemsSelector), group = element.parent('ul:not(.k-menu)'); element.remove(); if (group && !group.children(allItemsSelector).length) { var container = group.parent('.k-animation-container'); if (container.length) { container.remove(); } else { group.remove(); } } if (parent.length) { parent = parent.eq(0); updateArrow(parent); updateFirstLast(parent); } return that; }, open: function (element) { var that = this, options = that.options, horizontal = options.orientation == 'horizontal', direction = options.direction, isRtl = kendo.support.isRtl(that.wrapper); element = that.element.find(element); if (/^(top|bottom|default)$/.test(direction)) { if (isRtl) { direction = horizontal ? (direction + ' left').replace('default', 'bottom') : 'left'; } else { direction = horizontal ? (direction + ' right').replace('default', 'bottom') : 'right'; } } element.siblings().find('>.k-popup:visible,>.k-animation-container>.k-popup:visible').each(function () { var popup = $(this).data('kendoPopup'); if (popup) { popup.close(); } }); element.each(function () { var li = $(this); clearTimeout(li.data(TIMER)); li.data(TIMER, setTimeout(function () { var ul = li.find('.k-menu-group:first:hidden'), popup; if (ul[0] && that._triggerEvent({ item: li[0], type: OPEN }) === false) { if (!ul.find('.k-menu-group')[0] && ul.children('.k-item').length > 1) { var windowHeight = $(window).height(), setScrolling = function () { ul.css({ maxHeight: windowHeight - (ul.outerHeight() - ul.height()) - kendo.getShadows(ul).bottom, overflow: 'auto' }); }; if (kendo.support.browser.msie && kendo.support.browser.version <= 7) { setTimeout(setScrolling, 0); } else { setScrolling(); } } else { ul.css({ maxHeight: '', overflow: '' }); } li.data(ZINDEX, li.css(ZINDEX)); li.css(ZINDEX, that.nextItemZIndex++); popup = ul.data(KENDOPOPUP); var root = li.parent().hasClass(MENU), parentHorizontal = root && horizontal, directions = parseDirection(direction, root, isRtl), effects = options.animation.open.effects, openEffects = effects !== undefined ? effects : 'slideIn:' + getEffectDirection(direction, root); if (!popup) { popup = ul.kendoPopup({ activate: function () { that._triggerEvent({ item: this.wrapper.parent(), type: ACTIVATE }); }, deactivate: function (e) { e.sender.element.removeData('targetTransform').css({ opacity: '' }); that._triggerEvent({ item: this.wrapper.parent(), type: DEACTIVATE }); }, origin: directions.origin, position: directions.position, collision: options.popupCollision !== undefined ? options.popupCollision : parentHorizontal ? 'fit' : 'fit flip', anchor: li, appendTo: li, animation: { open: extend(true, { effects: openEffects }, options.animation.open), close: options.animation.close }, close: function (e) { var li = e.sender.wrapper.parent(); if (!that._triggerEvent({ item: li[0], type: CLOSE })) { li.css(ZINDEX, li.data(ZINDEX)); li.removeData(ZINDEX); if (touch) { li.removeClass(HOVERSTATE); that._removeHoverItem(); } } else { e.preventDefault(); } } }).data(KENDOPOPUP); } else { popup = ul.data(KENDOPOPUP); popup.options.origin = directions.origin; popup.options.position = directions.position; popup.options.animation.open.effects = openEffects; } ul.removeAttr('aria-hidden'); popup.open(); } }, that.options.hoverDelay)); }); return that; }, close: function (items, dontClearClose) { var that = this, element = that.element; items = element.find(items); if (!items.length) { items = element.find('>.k-item'); } items.each(function () { var li = $(this); if (!dontClearClose && that._isRootItem(li)) { that.clicked = false; } clearTimeout(li.data(TIMER)); li.data(TIMER, setTimeout(function () { var popup = li.find('.k-menu-group:not(.k-list-container):not(.k-calendar-container):first:visible').data(KENDOPOPUP); if (popup) { popup.close(); popup.element.attr('aria-hidden', true); } }, that.options.hoverDelay)); }); return that; }, _toggleDisabled: function (items, enable) { this.element.find(items).each(function () { $(this).toggleClass(DEFAULTSTATE, enable).toggleClass(DISABLEDSTATE, !enable).attr('aria-disabled', !enable); }); }, _toggleHover: function (e) { var target = $(kendo.eventTarget(e) || e.target).closest(allItemsSelector), isEnter = e.type == MOUSEENTER || MOUSEDOWN.indexOf(e.type) !== -1; if (!target.parents('li.' + DISABLEDSTATE).length) { target.toggleClass(HOVERSTATE, isEnter || e.type == 'mousedown' || e.type == 'click'); } this._removeHoverItem(); }, _preventClose: function () { if (!this.options.closeOnClick) { this._closurePrevented = true; } }, _checkActiveElement: function (e) { var that = this, hoverItem = $(e ? e.currentTarget : this._hoverItem()), target = that._findRootParent(hoverItem)[0]; if (!this._closurePrevented) { setTimeout(function () { if (!document.hasFocus() || !contains(target, kendo._activeElement()) && e && !contains(target, e.currentTarget)) { that.close(target); } }, 0); } this._closurePrevented = false; }, _removeHoverItem: function () { var oldHoverItem = this._hoverItem(); if (oldHoverItem && oldHoverItem.hasClass(FOCUSEDSTATE)) { oldHoverItem.removeClass(FOCUSEDSTATE); this._oldHoverItem = null; } }, _updateClasses: function () { var element = this.element, nonContentGroupsSelector = '.k-menu-init div ul', items; element.removeClass('k-menu-horizontal k-menu-vertical'); element.addClass('k-widget k-reset k-header k-menu-init ' + MENU).addClass(MENU + '-' + this.options.orientation); element.find('li > ul').filter(function () { return !kendo.support.matchesSelector.call(this, nonContentGroupsSelector); }).addClass('k-group k-menu-group').attr('role', 'menu').attr('aria-hidden', element.is(':visible')).end().find('li > div').addClass('k-content').attr('tabindex', '-1'); items = element.find('> li,.k-menu-group > li'); element.removeClass('k-menu-init'); items.each(function () { updateItemClasses(this); }); }, _mouseenter: function (e) { var that = this, element = $(e.currentTarget), hasChildren = element.children('.k-animation-container').length || element.children(groupSelector).length; if (e.delegateTarget != element.parents(menuSelector)[0]) { return; } if ((!that.options.openOnClick || that.clicked) && !touch && !((pointers || msPointers) && e.originalEvent.pointerType in touchPointerTypes && that._isRootItem(element.closest(allItemsSelector)))) { if (!contains(e.currentTarget, e.relatedTarget) && hasChildren) { that.open(element); } } if (that.options.openOnClick && that.clicked || mobile) { element.siblings().each(proxy(function (_, sibling) { that.close(sibling, true); }, that)); } }, _mouseleave: function (e) { var that = this, element = $(e.currentTarget), hasChildren = element.children('.k-animation-container').length || element.children(groupSelector).length; if (element.parentsUntil('.k-animation-container', '.k-list-container,.k-calendar-container')[0]) { e.stopImmediatePropagation(); return; } if (!that.options.openOnClick && !touch && !((pointers || msPointers) && e.originalEvent.pointerType in touchPointerTypes) && !contains(e.currentTarget, e.relatedTarget || e.target) && hasChildren && !contains(e.currentTarget, kendo._activeElement())) { that.close(element); } }, _click: function (e) { var that = this, openHandle, options = that.options, target = $(kendo.eventTarget(e)), nodeName = target[0] ? target[0].nodeName.toUpperCase() : '', formNode = nodeName == 'INPUT' || nodeName == 'SELECT' || nodeName == 'BUTTON' || nodeName == 'LABEL', link = target.closest('.' + LINK), element = target.closest(allItemsSelector), href = link.attr('href'), childGroup, childGroupVisible, targetHref = target.attr('href'), sampleHref = $('<a href=\'#\' />').attr('href'), isLink = !!href && href !== sampleHref, isLocalLink = isLink && !!href.match(/^#/), isTargetLink = !!targetHref && targetHref !== sampleHref, shouldCloseTheRootItem = options.openOnClick && childGroupVisible && that._isRootItem(element); if (target.closest(templateSelector, element[0]).length) { return; } if (element.hasClass(DISABLEDSTATE)) { e.preventDefault(); return; } if (!e.handled && that._triggerEvent({ item: element[0], type: SELECT }) && !formNode) { e.preventDefault(); } e.handled = true; childGroup = element.children(popupSelector); childGroupVisible = childGroup.is(':visible'); if (options.closeOnClick && (!isLink || isLocalLink) && (!childGroup.length || shouldCloseTheRootItem)) { element.removeClass(HOVERSTATE).css('height'); that._oldHoverItem = that._findRootParent(element); that.close(link.parentsUntil(that.element, allItemsSelector)); that.clicked = false; if ('MSPointerUp'.indexOf(e.type) != -1) { e.preventDefault(); } return; } if (isLink && e.enterKey) { link[0].click(); } if ((!that._isRootItem(element) || !options.openOnClick) && !kendo.support.touch && !((pointers || msPointers) && that._isRootItem(element.closest(allItemsSelector)))) { return; } if (!isLink && !formNode && !isTargetLink) { e.preventDefault(); } that.clicked = true; openHandle = childGroup.is(':visible') ? CLOSE : OPEN; if (!options.closeOnClick && openHandle == CLOSE) { return; } that[openHandle](element); }, _documentClick: function (e) { if (contains(this.element[0], e.target)) { return; } this.clicked = false; }, _focus: function (e) { var that = this, target = e.target, hoverItem = that._hoverItem(), active = activeElement(); if (target != that.wrapper[0] && !$(target).is(':kendoFocusable')) { e.stopPropagation(); $(target).closest('.k-content').closest('.k-menu-group').closest('.k-item').addClass(FOCUSEDSTATE); that.wrapper.focus(); return; } if (active === e.currentTarget) { if (hoverItem.length) { that._moveHover([], hoverItem); } else if (!that._oldHoverItem) { that._moveHover([], that.wrapper.children().first()); } } }, _keydown: function (e) { var that = this, key = e.keyCode, hoverItem = that._oldHoverItem, target, belongsToVertical, hasChildren, isRtl = kendo.support.isRtl(that.wrapper); if (e.target != e.currentTarget && key != keys.ESC) { return; } if (!hoverItem) { hoverItem = that._oldHoverItem = that._hoverItem(); } belongsToVertical = that._itemBelongsToVertival(hoverItem); hasChildren = that._itemHasChildren(hoverItem); if (key == keys.RIGHT) { target = that[isRtl ? '_itemLeft' : '_itemRight'](hoverItem, belongsToVertical, hasChildren); } else if (key == keys.LEFT) { target = that[isRtl ? '_itemRight' : '_itemLeft'](hoverItem, belongsToVertical, hasChildren); } else if (key == keys.DOWN) { target = that._itemDown(hoverItem, belongsToVertical, hasChildren); } else if (key == keys.UP) { target = that._itemUp(hoverItem, belongsToVertical, hasChildren); } else if (key == keys.ESC) { target = that._itemEsc(hoverItem, belongsToVertical); } else if (key == keys.ENTER || key == keys.SPACEBAR) { target = hoverItem.children('.k-link'); if (target.length > 0) { that._click({ target: target[0], preventDefault: function () { }, enterKey: true }); that._moveHover(hoverItem, that._findRootParent(hoverItem)); } } else if (key == keys.TAB) { target = that._findRootParent(hoverItem); that._moveHover(hoverItem, target); that._checkActiveElement(); return; } if (target && target[0]) { e.preventDefault(); e.stopPropagation(); } }, _hoverItem: function () { return this.wrapper.find('.k-item.k-state-hover,.k-item.k-state-focused').filter(':visible'); }, _itemBelongsToVertival: function (item) { var menuIsVertical = this.wrapper.hasClass('k-menu-vertical'); if (!item.length) { return menuIsVertical; } return item.parent().hasClass('k-menu-group') || menuIsVertical; }, _itemHasChildren: function (item) { if (!item.length) { return false; } return item.children('ul.k-menu-group, div.k-animation-container').length > 0; }, _moveHover: function (item, nextItem) { var that = this, id = that._ariaId; if (item.length && nextItem.length) { item.removeClass(FOCUSEDSTATE); } if (nextItem.length) { if (nextItem[0].id) { id = nextItem[0].id; } nextItem.addClass(FOCUSEDSTATE); that._oldHoverItem = nextItem; if (id) { that.element.removeAttr('aria-activedescendant'); $('#' + id).removeAttr('id'); nextItem.attr('id', id); that.element.attr('aria-activedescendant', id); } } }, _findRootParent: function (item) { if (this._isRootItem(item)) { return item; } else { return item.parentsUntil(menuSelector, 'li.k-item').last(); } }, _isRootItem: function (item) { return item.parent().hasClass(MENU); }, _itemRight: function (item, belongsToVertical, hasChildren) { var that = this, nextItem, parentItem; if (item.hasClass(DISABLEDSTATE)) { return; } if (!belongsToVertical) { nextItem = item.nextAll(nextSelector); if (!nextItem.length) { nextItem = item.prevAll(lastSelector); } } else if (hasChildren) { that.open(item); nextItem = item.find('.k-menu-group').children().first(); } else if (that.options.orientation == 'horizontal') { parentItem = that._findRootParent(item); that.close(parentItem); nextItem = parentItem.nextAll(nextSelector); } if (nextItem && !nextItem.length) { nextItem = that.wrapper.children('.k-item').first(); } else if (!nextItem) { nextItem = []; } that._moveHover(item, nextItem); return nextItem; }, _itemLeft: function (item, belongsToVertical) { var that = this, nextItem; if (!belongsToVertical) { nextItem = item.prevAll(nextSelector); if (!nextItem.length) { nextItem = item.nextAll(lastSelector); } } else { nextItem = item.parent().closest('.k-item'); that.close(nextItem); if (that._isRootItem(nextItem) && that.options.orientation == 'horizontal') { nextItem = nextItem.prevAll(nextSelector); } } if (!nextItem.length) { nextItem = that.wrapper.children('.k-item').last(); } that._moveHover(item, nextItem); return nextItem; }, _itemDown: function (item, belongsToVertical, hasChildren) { var that = this, nextItem; if (!belongsToVertical) { if (!hasChildren || item.hasClass(DISABLEDSTATE)) { return; } else { that.open(item); nextItem = item.find('.k-menu-group').children().first(); } } else { nextItem = item.nextAll(nextSelector); } if (!nextItem.length && item.length) { nextItem = item.parent().children().first(); } else if (!item.length) { nextItem = that.wrapper.children('.k-item').first(); } that._moveHover(item, nextItem); return nextItem; }, _itemUp: function (item, belongsToVertical) { var that = this, nextItem; if (!belongsToVertical) { return; } else { nextItem = item.prevAll(nextSelector); } if (!nextItem.length && item.length) { nextItem = item.parent().children().last(); } else if (!item.length) { nextItem = that.wrapper.children('.k-item').last(); } that._moveHover(item, nextItem); return nextItem; }, _itemEsc: function (item, belongsToVertical) { var that = this, nextItem; if (!belongsToVertical) { return item; } else { nextItem = item.parent().closest('.k-item'); that.close(nextItem); that._moveHover(item, nextItem); } return nextItem; }, _triggerEvent: function (e) { var that = this; return that.trigger(e.type, { type: e.type, item: e.item }); }, _focusHandler: function (e) { var that = this, item = $(kendo.eventTarget(e)).closest(allItemsSelector); setTimeout(function () { that._moveHover([], item); if (item.children('.k-content')[0]) { item.parent().closest('.k-item').removeClass(FOCUSEDSTATE); } }, 200); }, _animations: function (options) { if (options && 'animation' in options && !options.animation) { options.animation = { open: { effects: {} }, close: { hide: true, effects: {} } }; } } }); extend(Menu, { renderItem: function (options) { options = extend({ menu: {}, group: {} }, options); var empty = templates.empty, item = options.item; return templates.item(extend(options, { image: item.imageUrl ? templates.image : empty, sprite: item.spriteCssClass ? templates.sprite : empty, itemWrapper: templates.itemWrapper, renderContent: Menu.renderContent, arrow: item.items || item.content ? templates.arrow : empty, subGroup: Menu.renderGroup }, rendering)); }, renderGroup: function (options) { return templates.group(extend({ renderItems: function (options) { var html = '', i = 0, items = options.items, len = items ? items.length : 0, group = extend({ length: len }, options.group); for (; i < len; i++) { html += Menu.renderItem(extend(options, { group: group, item: extend({ index: i }, items[i]) })); } return html; } }, options, rendering)); }, renderContent: function (options) { return templates.content(extend(options, rendering)); } }); var ContextMenu = Menu.extend({ init: function (element, options) { var that = this; Menu.fn.init.call(that, element, options); that._marker = kendo.guid().substring(0, 8); that.target = $(that.options.target); that._popup(); that._wire(); }, options: { name: 'ContextMenu', filter: null, showOn: 'contextmenu', orientation: 'vertical', alignToAnchor: false, target: 'body' }, events: [ OPEN, CLOSE, ACTIVATE, DEACTIVATE, SELECT ], setOptions: function (options) { var that = this; Menu.fn.setOptions.call(that, options); that.target.off(that.showOn + NS + that._marker, that._showProxy); if (that.userEvents) { that.userEvents.destroy(); } that.target = $(that.options.target); if (options.orientation && that.popup.wrapper[0]) { that.popup.element.unwrap(); } that._wire(); Menu.fn.setOptions.call(this, options); }, destroy: function () { var that = this; that.target.off(that.options.showOn + NS + that._marker); DOCUMENT_ELEMENT.off(kendo.support.mousedown + NS + that._marker, that._closeProxy); if (that.userEvents) { that.userEvents.destroy(); } Menu.fn.destroy.call(that); }, open: function (x, y) { var that = this; x = $(x)[0]; if (contains(that.element[0], $(x)[0])) { Menu.fn.open.call(that, x); } else { if (that._triggerEvent({ item: that.element, type: OPEN }) === false) { if (that.popup.visible() && that.options.filter) { that.popup.close(true); that.popup.element.kendoStop(true); } if (y !== undefined) { that.popup.wrapper.hide(); that.popup.open(x, y); } else { that.popup.options.anchor = (x ? x : that.popup.anchor) || that.target; that.popup.element.kendoStop(true); that.popup.open(); } DOCUMENT_ELEMENT.off(that.popup.downEvent, that.popup._mousedownProxy); DOCUMENT_ELEMENT.on(kendo.support.mousedown + NS + that._marker, that._closeProxy); } } return that; }, close: function () { var that = this; if (contains(that.element[0], $(arguments[0])[0])) { Menu.fn.close.call(that, arguments[0]); } else { if (that.popup.visible()) { if (that._triggerEvent({ item: that.element, type: CLOSE }) === false) { that.popup.close(); DOCUMENT_ELEMENT.off(kendo.support.mousedown + NS, that._closeProxy); that.unbind(SELECT, that._closeTimeoutProxy); } } } }, _showHandler: function (e) { var ev = e, offset, that = this, options = that.options; if (e.event) { ev = e.event; ev.pageX = e.x.location; ev.pageY = e.y.location; } if (contains(that.element[0], e.relatedTarget || e.target)) { return; } that._eventOrigin = ev; ev.preventDefault(); ev.stopImmediatePropagation(); that.element.find('.' + FOCUSEDSTATE).removeClass(FOCUSEDSTATE); if (options.filter && kendo.support.matchesSelector.call(ev.currentTarget, options.filter) || !options.filter) { if (options.alignToAnchor) { that.popup.options.anchor = ev.currentTarget; that.open(ev.currentTarget); } else { that.popup.options.anchor = ev.currentTarget; if (that._targetChild) { offset = that.target.offset(); that.open(ev.pageX - offset.left, ev.pageY - offset.top); } else { that.open(ev.pageX, ev.pageY); } } } }, _closeHandler: function (e) { var that = this, target = $(e.relatedTarget || e.target), sameTarget = target.closest(that.target.selector)[0] == that.target[0], children = target.closest(itemSelector).children(popupSelector), containment = contains(that.element[0], target[0]); that._eventOrigin = e; var normalClick = e.which !== 3; if (that.popup.visible() && (normalClick && sameTarget || !sameTarget) && (that.options.closeOnClick && !children[0] && containment || !containment)) { if (containment) { this.unbind(SELECT, this._closeTimeoutProxy); that.bind(SELECT, that._closeTimeoutProxy); } else { that.close(); } } }, _wire: function () { var that = this, options = that.options, target = that.target; that._showProxy = proxy(that._showHandler, that); that._closeProxy = proxy(that._closeHandler, that); that._closeTimeoutProxy = proxy(that.close, that); if (target[0]) { if (kendo.support.mobileOS && options.showOn == 'contextmenu') { that.userEvents = new kendo.UserEvents(target, { filter: options.filter, allowSelection: false }); target.on(options.showOn + NS + that._marker, false); that.userEvents.bind('hold', that._showProxy); } else { if (options.filter) { target.on(options.showOn + NS + that._marker, options.filter, that._showProxy); } else { target.on(options.showOn + NS + that._marker, that._showProxy); } } } }, _triggerEvent: function (e) { var that = this, anchor = $(that.popup.options.anchor)[0], origin = that._eventOrigin; that._eventOrigin = undefined; return that.trigger(e.type, extend({ type: e.type, item: e.item || this.element[0], target: anchor }, origin ? { event: origin } : {})); }, _popup: function () { var that = this; that._triggerProxy = proxy(that._triggerEvent, that); that.popup = that.element.addClass('k-context-menu').kendoPopup({ anchor: that.target || 'body', copyAnchorStyles: that.options.copyAnchorStyles, collision: that.options.popupCollision || 'fit', animation: that.options.animation, activate: that._triggerProxy, deactivate: that._triggerProxy }).data('kendoPopup'); that._targetChild = contains(that.target[0], that.popup.element[0]); } }); ui.plugin(Menu); ui.plugin(ContextMenu); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.draganddrop', [ 'kendo.core', 'kendo.userevents' ], f); }(function () { var __meta__ = { id: 'draganddrop', name: 'Drag & drop', category: 'framework', description: 'Drag & drop functionality for any DOM element.', depends: [ 'core', 'userevents' ] }; (function ($, undefined) { var kendo = window.kendo, support = kendo.support, document = window.document, $window = $(window), Class = kendo.Class, Widget = kendo.ui.Widget, Observable = kendo.Observable, UserEvents = kendo.UserEvents, proxy = $.proxy, extend = $.extend, getOffset = kendo.getOffset, draggables = {}, dropTargets = {}, dropAreas = {}, lastDropTarget, elementUnderCursor = kendo.elementUnderCursor, KEYUP = 'keyup', CHANGE = 'change', DRAGSTART = 'dragstart', HOLD = 'hold', DRAG = 'drag', DRAGEND = 'dragend', DRAGCANCEL = 'dragcancel', HINTDESTROYED = 'hintDestroyed', DRAGENTER = 'dragenter', DRAGLEAVE = 'dragleave', DROP = 'drop'; function contains(parent, child) { try { return $.contains(parent, child) || parent == child; } catch (e) { return false; } } function numericCssPropery(element, property) { return parseInt(element.css(property), 10) || 0; } function within(value, range) { return Math.min(Math.max(value, range.min), range.max); } function containerBoundaries(container, element) { var offset = getOffset(container), minX = offset.left + numericCssPropery(container, 'borderLeftWidth') + numericCssPropery(container, 'paddingLeft'), minY = offset.top + numericCssPropery(container, 'borderTopWidth') + numericCssPropery(container, 'paddingTop'), maxX = minX + container.width() - element.outerWidth(true), maxY = minY + container.height() - element.outerHeight(true); return { x: { min: minX, max: maxX }, y: { min: minY, max: maxY } }; } function checkTarget(target, targets, areas) { var theTarget, theFilter, i = 0, targetLen = targets && targets.length, areaLen = areas && areas.length; while (target && target.parentNode) { for (i = 0; i < targetLen; i++) { theTarget = targets[i]; if (theTarget.element[0] === target) { return { target: theTarget, targetElement: target }; } } for (i = 0; i < areaLen; i++) { theFilter = areas[i]; if ($.contains(theFilter.element[0], target) && support.matchesSelector.call(target, theFilter.options.filter)) { return { target: theFilter, targetElement: target }; } } target = target.parentNode; } return undefined; } var TapCapture = Observable.extend({ init: function (element, options) { var that = this, domElement = element[0]; that.capture = false; if (domElement.addEventListener) { $.each(kendo.eventMap.down.split(' '), function () { domElement.addEventListener(this, proxy(that._press, that), true); }); $.each(kendo.eventMap.up.split(' '), function () { domElement.addEventListener(this, proxy(that._release, that), true); }); } else { $.each(kendo.eventMap.down.split(' '), function () { domElement.attachEvent(this, proxy(that._press, that)); }); $.each(kendo.eventMap.up.split(' '), function () { domElement.attachEvent(this, proxy(that._release, that)); }); } Observable.fn.init.call(that); that.bind([ 'press', 'release' ], options || {}); }, captureNext: function () { this.capture = true; }, cancelCapture: function () { this.capture = false; }, _press: function (e) { var that = this; that.trigger('press'); if (that.capture) { e.preventDefault(); } }, _release: function (e) { var that = this; that.trigger('release'); if (that.capture) { e.preventDefault(); that.cancelCapture(); } } }); var PaneDimension = Observable.extend({ init: function (options) { var that = this; Observable.fn.init.call(that); that.forcedEnabled = false; $.extend(that, options); that.scale = 1; if (that.horizontal) { that.measure = 'offsetWidth'; that.scrollSize = 'scrollWidth'; that.axis = 'x'; } else { that.measure = 'offsetHeight'; that.scrollSize = 'scrollHeight'; that.axis = 'y'; } }, makeVirtual: function () { $.extend(this, { virtual: true, forcedEnabled: true, _virtualMin: 0, _virtualMax: 0 }); }, virtualSize: function (min, max) { if (this._virtualMin !== min || this._virtualMax !== max) { this._virtualMin = min; this._virtualMax = max; this.update(); } }, outOfBounds: function (offset) { return offset > this.max || offset < this.min; }, forceEnabled: function () { this.forcedEnabled = true; }, getSize: function () { return this.container[0][this.measure]; }, getTotal: function () { return this.element[0][this.scrollSize]; }, rescale: function (scale) { this.scale = scale; }, update: function (silent) { var that = this, total = that.virtual ? that._virtualMax : that.getTotal(), scaledTotal = total * that.scale, size = that.getSize(); if (total === 0 && !that.forcedEnabled) { return; } that.max = that.virtual ? -that._virtualMin : 0; that.size = size; that.total = scaledTotal; that.min = Math.min(that.max, size - scaledTotal); that.minScale = size / total; that.centerOffset = (scaledTotal - size) / 2; that.enabled = that.forcedEnabled || scaledTotal > size; if (!silent) { that.trigger(CHANGE, that); } } }); var PaneDimensions = Observable.extend({ init: function (options) { var that = this; Observable.fn.init.call(that); that.x = new PaneDimension(extend({ horizontal: true }, options)); that.y = new PaneDimension(extend({ horizontal: false }, options)); that.container = options.container; that.forcedMinScale = options.minScale; that.maxScale = options.maxScale || 100; that.bind(CHANGE, options); }, rescale: function (newScale) { this.x.rescale(newScale); this.y.rescale(newScale); this.refresh(); }, centerCoordinates: function () { return { x: Math.min(0, -this.x.centerOffset), y: Math.min(0, -this.y.centerOffset) }; }, refresh: function () { var that = this; that.x.update(); that.y.update(); that.enabled = that.x.enabled || that.y.enabled; that.minScale = that.forcedMinScale || Math.min(that.x.minScale, that.y.minScale); that.fitScale = Math.max(that.x.minScale, that.y.minScale); that.trigger(CHANGE); } }); var PaneAxis = Observable.extend({ init: function (options) { var that = this; extend(that, options); Observable.fn.init.call(that); }, outOfBounds: function () { return this.dimension.outOfBounds(this.movable[this.axis]); }, dragMove: function (delta) { var that = this, dimension = that.dimension, axis = that.axis, movable = that.movable, position = movable[axis] + delta; if (!dimension.enabled) { return; } if (position < dimension.min && delta < 0 || position > dimension.max && delta > 0) { delta *= that.resistance; } movable.translateAxis(axis, delta); that.trigger(CHANGE, that); } }); var Pane = Class.extend({ init: function (options) { var that = this, x, y, resistance, movable; extend(that, { elastic: true }, options); resistance = that.elastic ? 0.5 : 0; movable = that.movable; that.x = x = new PaneAxis({ axis: 'x', dimension: that.dimensions.x, resistance: resistance, movable: movable }); that.y = y = new PaneAxis({ axis: 'y', dimension: that.dimensions.y, resistance: resistance, movable: movable }); that.userEvents.bind([ 'press', 'move', 'end', 'gesturestart', 'gesturechange' ], { gesturestart: function (e) { that.gesture = e; that.offset = that.dimensions.container.offset(); }, press: function (e) { if ($(e.event.target).closest('a').is('[data-navigate-on-press=true]')) { e.sender.cancel(); } }, gesturechange: function (e) { var previousGesture = that.gesture, previousCenter = previousGesture.center, center = e.center, scaleDelta = e.distance / previousGesture.distance, minScale = that.dimensions.minScale, maxScale = that.dimensions.maxScale, coordinates; if (movable.scale <= minScale && scaleDelta < 1) { scaleDelta += (1 - scaleDelta) * 0.8; } if (movable.scale * scaleDelta >= maxScale) { scaleDelta = maxScale / movable.scale; } var offsetX = movable.x + that.offset.left, offsetY = movable.y + that.offset.top; coordinates = { x: (offsetX - previousCenter.x) * scaleDelta + center.x - offsetX, y: (offsetY - previousCenter.y) * scaleDelta + center.y - offsetY }; movable.scaleWith(scaleDelta); x.dragMove(coordinates.x); y.dragMove(coordinates.y); that.dimensions.rescale(movable.scale); that.gesture = e; e.preventDefault(); }, move: function (e) { if (e.event.target.tagName.match(/textarea|input/i)) { return; } if (x.dimension.enabled || y.dimension.enabled) { x.dragMove(e.x.delta); y.dragMove(e.y.delta); e.preventDefault(); } else { e.touch.skip(); } }, end: function (e) { e.preventDefault(); } }); } }); var TRANSFORM_STYLE = support.transitions.prefix + 'Transform', translate; if (support.hasHW3D) { translate = function (x, y, scale) { return 'translate3d(' + x + 'px,' + y + 'px,0) scale(' + scale + ')'; }; } else { translate = function (x, y, scale) { return 'translate(' + x + 'px,' + y + 'px) scale(' + scale + ')'; }; } var Movable = Observable.extend({ init: function (element) { var that = this; Observable.fn.init.call(that); that.element = $(element); that.element[0].style.webkitTransformOrigin = 'left top'; that.x = 0; that.y = 0; that.scale = 1; that._saveCoordinates(translate(that.x, that.y, that.scale)); }, translateAxis: function (axis, by) { this[axis] += by; this.refresh(); }, scaleTo: function (scale) { this.scale = scale; this.refresh(); }, scaleWith: function (scaleDelta) { this.scale *= scaleDelta; this.refresh(); }, translate: function (coordinates) { this.x += coordinates.x; this.y += coordinates.y; this.refresh(); }, moveAxis: function (axis, value) { this[axis] = value; this.refresh(); }, moveTo: function (coordinates) { extend(this, coordinates); this.refresh(); }, refresh: function () { var that = this, x = that.x, y = that.y, newCoordinates; if (that.round) { x = Math.round(x); y = Math.round(y); } newCoordinates = translate(x, y, that.scale); if (newCoordinates != that.coordinates) { if (kendo.support.browser.msie && kendo.support.browser.version < 10) { that.element[0].style.position = 'absolute'; that.element[0].style.left = that.x + 'px'; that.element[0].style.top = that.y + 'px'; } else { that.element[0].style[TRANSFORM_STYLE] = newCoordinates; } that._saveCoordinates(newCoordinates); that.trigger(CHANGE); } }, _saveCoordinates: function (coordinates) { this.coordinates = coordinates; } }); function destroyDroppable(collection, widget) { var groupName = widget.options.group, droppables = collection[groupName], i; Widget.fn.destroy.call(widget); if (droppables.length > 1) { for (i = 0; i < droppables.length; i++) { if (droppables[i] == widget) { droppables.splice(i, 1); break; } } } else { droppables.length = 0; delete collection[groupName]; } } var DropTarget = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); var group = that.options.group; if (!(group in dropTargets)) { dropTargets[group] = [that]; } else { dropTargets[group].push(that); } }, events: [ DRAGENTER, DRAGLEAVE, DROP ], options: { name: 'DropTarget', group: 'default' }, destroy: function () { destroyDroppable(dropTargets, this); }, _trigger: function (eventName, e) { var that = this, draggable = draggables[that.options.group]; if (draggable) { return that.trigger(eventName, extend({}, e.event, { draggable: draggable, dropTarget: e.dropTarget })); } }, _over: function (e) { this._trigger(DRAGENTER, e); }, _out: function (e) { this._trigger(DRAGLEAVE, e); }, _drop: function (e) { var that = this, draggable = draggables[that.options.group]; if (draggable) { draggable.dropped = !that._trigger(DROP, e); } } }); DropTarget.destroyGroup = function (groupName) { var group = dropTargets[groupName] || dropAreas[groupName], i; if (group) { for (i = 0; i < group.length; i++) { Widget.fn.destroy.call(group[i]); } group.length = 0; delete dropTargets[groupName]; delete dropAreas[groupName]; } }; DropTarget._cache = dropTargets; var DropTargetArea = DropTarget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); var group = that.options.group; if (!(group in dropAreas)) { dropAreas[group] = [that]; } else { dropAreas[group].push(that); } }, destroy: function () { destroyDroppable(dropAreas, this); }, options: { name: 'DropTargetArea', group: 'default', filter: null } }); var Draggable = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); that._activated = false; that.userEvents = new UserEvents(that.element, { global: true, allowSelection: true, filter: that.options.filter, threshold: that.options.distance, start: proxy(that._start, that), hold: proxy(that._hold, that), move: proxy(that._drag, that), end: proxy(that._end, that), cancel: proxy(that._cancel, that), select: proxy(that._select, that) }); that._afterEndHandler = proxy(that._afterEnd, that); that._captureEscape = proxy(that._captureEscape, that); }, events: [ HOLD, DRAGSTART, DRAG, DRAGEND, DRAGCANCEL, HINTDESTROYED ], options: { name: 'Draggable', distance: kendo.support.touch ? 0 : 5, group: 'default', cursorOffset: null, axis: null, container: null, filter: null, ignore: null, holdToDrag: false, autoScroll: false, dropped: false }, cancelHold: function () { this._activated = false; }, _captureEscape: function (e) { var that = this; if (e.keyCode === kendo.keys.ESC) { that._trigger(DRAGCANCEL, { event: e }); that.userEvents.cancel(); } }, _updateHint: function (e) { var that = this, coordinates, options = that.options, boundaries = that.boundaries, axis = options.axis, cursorOffset = that.options.cursorOffset; if (cursorOffset) { coordinates = { left: e.x.location + cursorOffset.left, top: e.y.location + cursorOffset.top }; } else { that.hintOffset.left += e.x.delta; that.hintOffset.top += e.y.delta; coordinates = $.extend({}, that.hintOffset); } if (boundaries) { coordinates.top = within(coordinates.top, boundaries.y); coordinates.left = within(coordinates.left, boundaries.x); } if (axis === 'x') { delete coordinates.top; } else if (axis === 'y') { delete coordinates.left; } that.hint.css(coordinates); }, _shouldIgnoreTarget: function (target) { var ignoreSelector = this.options.ignore; return ignoreSelector && $(target).is(ignoreSelector); }, _select: function (e) { if (!this._shouldIgnoreTarget(e.event.target)) { e.preventDefault(); } }, _start: function (e) { var that = this, options = that.options, container = options.container, hint = options.hint; if (this._shouldIgnoreTarget(e.touch.initialTouch) || options.holdToDrag && !that._activated) { that.userEvents.cancel(); return; } that.currentTarget = e.target; that.currentTargetOffset = getOffset(that.currentTarget); if (hint) { if (that.hint) { that.hint.stop(true, true).remove(); } that.hint = kendo.isFunction(hint) ? $(hint.call(that, that.currentTarget)) : hint; var offset = getOffset(that.currentTarget); that.hintOffset = offset; that.hint.css({ position: 'absolute', zIndex: 20000, left: offset.left, top: offset.top }).appendTo(document.body); that.angular('compile', function () { that.hint.removeAttr('ng-repeat'); var scopeTarget = $(e.target); while (!scopeTarget.data('$$kendoScope') && scopeTarget.length) { scopeTarget = scopeTarget.parent(); } return { elements: that.hint.get(), scopeFrom: scopeTarget.data('$$kendoScope') }; }); } draggables[options.group] = that; that.dropped = false; if (container) { that.boundaries = containerBoundaries(container, that.hint); } $(document).on(KEYUP, that._captureEscape); if (that._trigger(DRAGSTART, e)) { that.userEvents.cancel(); that._afterEnd(); } that.userEvents.capture(); }, _hold: function (e) { this.currentTarget = e.target; if (this._trigger(HOLD, e)) { this.userEvents.cancel(); } else { this._activated = true; } }, _drag: function (e) { e.preventDefault(); var cursorElement = this._elementUnderCursor(e); if (this.options.autoScroll && this._cursorElement !== cursorElement) { this._scrollableParent = findScrollableParent(cursorElement); this._cursorElement = cursorElement; } this._lastEvent = e; this._processMovement(e, cursorElement); if (this.options.autoScroll) { if (this._scrollableParent[0]) { var velocity = autoScrollVelocity(e.x.location, e.y.location, scrollableViewPort(this._scrollableParent)); this._scrollCompenstation = $.extend({}, this.hintOffset); this._scrollVelocity = velocity; if (velocity.y === 0 && velocity.x === 0) { clearInterval(this._scrollInterval); this._scrollInterval = null; } else if (!this._scrollInterval) { this._scrollInterval = setInterval($.proxy(this, '_autoScroll'), 50); } } } if (this.hint) { this._updateHint(e); } }, _processMovement: function (e, cursorElement) { this._withDropTarget(cursorElement, function (target, targetElement) { if (!target) { if (lastDropTarget) { lastDropTarget._trigger(DRAGLEAVE, extend(e, { dropTarget: $(lastDropTarget.targetElement) })); lastDropTarget = null; } return; } if (lastDropTarget) { if (targetElement === lastDropTarget.targetElement) { return; } lastDropTarget._trigger(DRAGLEAVE, extend(e, { dropTarget: $(lastDropTarget.targetElement) })); } target._trigger(DRAGENTER, extend(e, { dropTarget: $(targetElement) })); lastDropTarget = extend(target, { targetElement: targetElement }); }); this._trigger(DRAG, extend(e, { dropTarget: lastDropTarget, elementUnderCursor: cursorElement })); }, _autoScroll: function () { var parent = this._scrollableParent[0], velocity = this._scrollVelocity, compensation = this._scrollCompenstation; if (!parent) { return; } var cursorElement = this._elementUnderCursor(this._lastEvent); this._processMovement(this._lastEvent, cursorElement); var yIsScrollable, xIsScrollable; var isRootNode = parent === scrollableRoot()[0]; if (isRootNode) { yIsScrollable = document.body.scrollHeight > $window.height(); xIsScrollable = document.body.scrollWidth > $window.width(); } else { yIsScrollable = parent.offsetHeight <= parent.scrollHeight; xIsScrollable = parent.offsetWidth <= parent.scrollWidth; } var yDelta = parent.scrollTop + velocity.y; var yInBounds = yIsScrollable && yDelta > 0 && yDelta < parent.scrollHeight; var xDelta = parent.scrollLeft + velocity.x; var xInBounds = xIsScrollable && xDelta > 0 && xDelta < parent.scrollWidth; if (yInBounds) { parent.scrollTop += velocity.y; } if (xInBounds) { parent.scrollLeft += velocity.x; } if (isRootNode && (xInBounds || yInBounds)) { if (yInBounds) { compensation.top += velocity.y; } if (xInBounds) { compensation.left += velocity.x; } this.hint.css(compensation); } }, _end: function (e) { this._withDropTarget(this._elementUnderCursor(e), function (target, targetElement) { if (target) { target._drop(extend({}, e, { dropTarget: $(targetElement) })); lastDropTarget = null; } }); this._cancel(this._trigger(DRAGEND, e)); }, _cancel: function (isDefaultPrevented) { var that = this; that._scrollableParent = null; this._cursorElement = null; clearInterval(this._scrollInterval); that._activated = false; if (that.hint && !that.dropped) { setTimeout(function () { that.hint.stop(true, true); if (isDefaultPrevented) { that._afterEndHandler(); } else { that.hint.animate(that.currentTargetOffset, 'fast', that._afterEndHandler); } }, 0); } else { that._afterEnd(); } }, _trigger: function (eventName, e) { var that = this; return that.trigger(eventName, extend({}, e.event, { x: e.x, y: e.y, currentTarget: that.currentTarget, initialTarget: e.touch ? e.touch.initialTouch : null, dropTarget: e.dropTarget, elementUnderCursor: e.elementUnderCursor })); }, _elementUnderCursor: function (e) { var target = elementUnderCursor(e), hint = this.hint; if (hint && contains(hint[0], target)) { hint.hide(); target = elementUnderCursor(e); if (!target) { target = elementUnderCursor(e); } hint.show(); } return target; }, _withDropTarget: function (element, callback) { var result, group = this.options.group, targets = dropTargets[group], areas = dropAreas[group]; if (targets && targets.length || areas && areas.length) { result = checkTarget(element, targets, areas); if (result) { callback(result.target, result.targetElement); } else { callback(); } } }, destroy: function () { var that = this; Widget.fn.destroy.call(that); that._afterEnd(); that.userEvents.destroy(); this._scrollableParent = null; this._cursorElement = null; clearInterval(this._scrollInterval); that.currentTarget = null; }, _afterEnd: function () { var that = this; if (that.hint) { that.hint.remove(); } delete draggables[that.options.group]; that.trigger('destroy'); that.trigger(HINTDESTROYED); $(document).off(KEYUP, that._captureEscape); } }); kendo.ui.plugin(DropTarget); kendo.ui.plugin(DropTargetArea); kendo.ui.plugin(Draggable); kendo.TapCapture = TapCapture; kendo.containerBoundaries = containerBoundaries; extend(kendo.ui, { Pane: Pane, PaneDimensions: PaneDimensions, Movable: Movable }); function scrollableViewPort(element) { var root = scrollableRoot()[0], offset, top, left; if (element[0] === root) { top = root.scrollTop; left = root.scrollLeft; return { top: top, left: left, bottom: top + $window.height(), right: left + $window.width() }; } else { offset = element.offset(); offset.bottom = offset.top + element.height(); offset.right = offset.left + element.width(); return offset; } } function scrollableRoot() { return $(kendo.support.browser.chrome ? document.body : document.documentElement); } function findScrollableParent(element) { var root = scrollableRoot(); if (!element || element === document.body || element === document.documentElement) { return root; } var parent = $(element)[0]; while (parent && !kendo.isScrollable(parent) && parent !== document.body) { parent = parent.parentNode; } if (parent === document.body) { return root; } return $(parent); } function autoScrollVelocity(mouseX, mouseY, rect) { var velocity = { x: 0, y: 0 }; var AUTO_SCROLL_AREA = 50; if (mouseX - rect.left < AUTO_SCROLL_AREA) { velocity.x = -(AUTO_SCROLL_AREA - (mouseX - rect.left)); } else if (rect.right - mouseX < AUTO_SCROLL_AREA) { velocity.x = AUTO_SCROLL_AREA - (rect.right - mouseX); } if (mouseY - rect.top < AUTO_SCROLL_AREA) { velocity.y = -(AUTO_SCROLL_AREA - (mouseY - rect.top)); } else if (rect.bottom - mouseY < AUTO_SCROLL_AREA) { velocity.y = AUTO_SCROLL_AREA - (rect.bottom - mouseY); } return velocity; } kendo.ui.Draggable.utils = { autoScrollVelocity: autoScrollVelocity, scrollableViewPort: scrollableViewPort, findScrollableParent: findScrollableParent }; }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.slider', ['kendo.draganddrop'], f); }(function () { var __meta__ = { id: 'slider', name: 'Slider', category: 'web', description: 'The Slider widget provides a rich input for selecting values or ranges of values.', depends: ['draganddrop'] }; (function ($, undefined) { var kendo = window.kendo, Widget = kendo.ui.Widget, Draggable = kendo.ui.Draggable, extend = $.extend, format = kendo.format, parse = kendo.parseFloat, proxy = $.proxy, isArray = $.isArray, math = Math, support = kendo.support, pointers = support.pointers, msPointers = support.msPointers, CHANGE = 'change', SLIDE = 'slide', NS = '.slider', MOUSE_DOWN = 'touchstart' + NS + ' mousedown' + NS, TRACK_MOUSE_DOWN = pointers ? 'pointerdown' + NS : msPointers ? 'MSPointerDown' + NS : MOUSE_DOWN, MOUSE_UP = 'touchend' + NS + ' mouseup' + NS, TRACK_MOUSE_UP = pointers ? 'pointerup' : msPointers ? 'MSPointerUp' + NS : MOUSE_UP, MOVE_SELECTION = 'moveSelection', KEY_DOWN = 'keydown' + NS, CLICK = 'click' + NS, MOUSE_OVER = 'mouseover' + NS, FOCUS = 'focus' + NS, BLUR = 'blur' + NS, DRAG_HANDLE = '.k-draghandle', TRACK_SELECTOR = '.k-slider-track', TICK_SELECTOR = '.k-tick', STATE_SELECTED = 'k-state-selected', STATE_FOCUSED = 'k-state-focused', STATE_DEFAULT = 'k-state-default', STATE_DISABLED = 'k-state-disabled', DISABLED = 'disabled', UNDEFINED = 'undefined', TABINDEX = 'tabindex', getTouches = kendo.getTouches; var SliderBase = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); options = that.options; that._distance = round(options.max - options.min); that._isHorizontal = options.orientation == 'horizontal'; that._isRtl = that._isHorizontal && kendo.support.isRtl(element); that._position = that._isHorizontal ? 'left' : 'bottom'; that._sizeFn = that._isHorizontal ? 'width' : 'height'; that._outerSize = that._isHorizontal ? 'outerWidth' : 'outerHeight'; options.tooltip.format = options.tooltip.enabled ? options.tooltip.format || '{0}' : '{0}'; if (options.smallStep <= 0) { throw new Error('Kendo UI Slider smallStep must be a positive number.'); } that._createHtml(); that.wrapper = that.element.closest('.k-slider'); that._trackDiv = that.wrapper.find(TRACK_SELECTOR); that._setTrackDivWidth(); that._maxSelection = that._trackDiv[that._sizeFn](); that._sliderItemsInit(); that._reset(); that._tabindex(that.wrapper.find(DRAG_HANDLE)); that[options.enabled ? 'enable' : 'disable'](); var rtlDirectionSign = kendo.support.isRtl(that.wrapper) ? -1 : 1; that._keyMap = { 37: step(-1 * rtlDirectionSign * options.smallStep), 40: step(-options.smallStep), 39: step(+1 * rtlDirectionSign * options.smallStep), 38: step(+options.smallStep), 35: setValue(options.max), 36: setValue(options.min), 33: step(+options.largeStep), 34: step(-options.largeStep) }; kendo.notify(that); }, events: [ CHANGE, SLIDE ], options: { enabled: true, min: 0, max: 10, smallStep: 1, largeStep: 5, orientation: 'horizontal', tickPlacement: 'both', tooltip: { enabled: true, format: '{0}' } }, _resize: function () { this._setTrackDivWidth(); this.wrapper.find('.k-slider-items').remove(); this._maxSelection = this._trackDiv[this._sizeFn](); this._sliderItemsInit(); this._refresh(); if (this.options.enabled) { this.enable(true); } }, _sliderItemsInit: function () { var that = this, options = that.options; var sizeBetweenTicks = that._maxSelection / ((options.max - options.min) / options.smallStep); var pixelWidths = that._calculateItemsWidth(math.floor(that._distance / options.smallStep)); if (options.tickPlacement != 'none' && sizeBetweenTicks >= 2) { that._trackDiv.before(createSliderItems(options, that._distance)); that._setItemsWidth(pixelWidths); that._setItemsTitle(); } that._calculateSteps(pixelWidths); if (options.tickPlacement != 'none' && sizeBetweenTicks >= 2 && options.largeStep >= options.smallStep) { that._setItemsLargeTick(); } }, getSize: function () { return kendo.dimensions(this.wrapper); }, _setTrackDivWidth: function () { var that = this, trackDivPosition = parseFloat(that._trackDiv.css(that._isRtl ? 'right' : that._position), 10) * 2; that._trackDiv[that._sizeFn](that.wrapper[that._sizeFn]() - 2 - trackDivPosition); }, _setItemsWidth: function (pixelWidths) { var that = this, options = that.options, first = 0, last = pixelWidths.length - 1, items = that.wrapper.find(TICK_SELECTOR), i, paddingTop = 0, bordersWidth = 2, count = items.length, selection = 0; for (i = 0; i < count - 2; i++) { $(items[i + 1])[that._sizeFn](pixelWidths[i]); } if (that._isHorizontal) { $(items[first]).addClass('k-first')[that._sizeFn](pixelWidths[last - 1]); $(items[last]).addClass('k-last')[that._sizeFn](pixelWidths[last]); } else { $(items[last]).addClass('k-first')[that._sizeFn](pixelWidths[last]); $(items[first]).addClass('k-last')[that._sizeFn](pixelWidths[last - 1]); } if (that._distance % options.smallStep !== 0 && !that._isHorizontal) { for (i = 0; i < pixelWidths.length; i++) { selection += pixelWidths[i]; } paddingTop = that._maxSelection - selection; paddingTop += parseFloat(that._trackDiv.css(that._position), 10) + bordersWidth; that.wrapper.find('.k-slider-items').css('padding-top', paddingTop); } }, _setItemsTitle: function () { var that = this, options = that.options, items = that.wrapper.find(TICK_SELECTOR), titleNumber = options.min, count = items.length, i = that._isHorizontal && !that._isRtl ? 0 : count - 1, limit = that._isHorizontal && !that._isRtl ? count : -1, increment = that._isHorizontal && !that._isRtl ? 1 : -1; for (; i - limit !== 0; i += increment) { $(items[i]).attr('title', format(options.tooltip.format, round(titleNumber))); titleNumber += options.smallStep; } }, _setItemsLargeTick: function () { var that = this, options = that.options, items = that.wrapper.find(TICK_SELECTOR), i = 0, item, value; if (removeFraction(options.largeStep) % removeFraction(options.smallStep) === 0 || that._distance / options.largeStep >= 3) { if (!that._isHorizontal && !that._isRtl) { items = $.makeArray(items).reverse(); } for (i = 0; i < items.length; i++) { item = $(items[i]); value = that._values[i]; var valueWithoutFraction = round(removeFraction(value - this.options.min)); if (valueWithoutFraction % removeFraction(options.smallStep) === 0 && valueWithoutFraction % removeFraction(options.largeStep) === 0) { item.addClass('k-tick-large').html('<span class=\'k-label\'>' + item.attr('title') + '</span>'); if (i !== 0 && i !== items.length - 1) { item.css('line-height', item[that._sizeFn]() + 'px'); } } } } }, _calculateItemsWidth: function (itemsCount) { var that = this, options = that.options, trackDivSize = parseFloat(that._trackDiv.css(that._sizeFn)) + 1, pixelStep = trackDivSize / that._distance, itemWidth, pixelWidths, i; if (that._distance / options.smallStep - math.floor(that._distance / options.smallStep) > 0) { trackDivSize -= that._distance % options.smallStep * pixelStep; } itemWidth = trackDivSize / itemsCount; pixelWidths = []; for (i = 0; i < itemsCount - 1; i++) { pixelWidths[i] = itemWidth; } pixelWidths[itemsCount - 1] = pixelWidths[itemsCount] = itemWidth / 2; return that._roundWidths(pixelWidths); }, _roundWidths: function (pixelWidthsArray) { var balance = 0, count = pixelWidthsArray.length, i; for (i = 0; i < count; i++) { balance += pixelWidthsArray[i] - math.floor(pixelWidthsArray[i]); pixelWidthsArray[i] = math.floor(pixelWidthsArray[i]); } balance = math.round(balance); return this._addAdditionalSize(balance, pixelWidthsArray); }, _addAdditionalSize: function (additionalSize, pixelWidthsArray) { if (additionalSize === 0) { return pixelWidthsArray; } var step = parseFloat(pixelWidthsArray.length - 1) / parseFloat(additionalSize == 1 ? additionalSize : additionalSize - 1), i; for (i = 0; i < additionalSize; i++) { pixelWidthsArray[parseInt(math.round(step * i), 10)] += 1; } return pixelWidthsArray; }, _calculateSteps: function (pixelWidths) { var that = this, options = that.options, val = options.min, selection = 0, itemsCount = math.ceil(that._distance / options.smallStep), i = 1, lastItem; itemsCount += that._distance / options.smallStep % 1 === 0 ? 1 : 0; pixelWidths.splice(0, 0, pixelWidths[itemsCount - 2] * 2); pixelWidths.splice(itemsCount - 1, 1, pixelWidths.pop() * 2); that._pixelSteps = [selection]; that._values = [val]; if (itemsCount === 0) { return; } while (i < itemsCount) { selection += (pixelWidths[i - 1] + pixelWidths[i]) / 2; that._pixelSteps[i] = selection; val += options.smallStep; that._values[i] = round(val); i++; } lastItem = that._distance % options.smallStep === 0 ? itemsCount - 1 : itemsCount; that._pixelSteps[lastItem] = that._maxSelection; that._values[lastItem] = options.max; if (that._isRtl) { that._pixelSteps.reverse(); that._values.reverse(); } }, _getValueFromPosition: function (mousePosition, dragableArea) { var that = this, options = that.options, step = math.max(options.smallStep * (that._maxSelection / that._distance), 0), position = 0, halfStep = step / 2, i; if (that._isHorizontal) { position = mousePosition - dragableArea.startPoint; if (that._isRtl) { position = that._maxSelection - position; } } else { position = dragableArea.startPoint - mousePosition; } if (that._maxSelection - (parseInt(that._maxSelection % step, 10) - 3) / 2 < position) { return options.max; } for (i = 0; i < that._pixelSteps.length; i++) { if (math.abs(that._pixelSteps[i] - position) - 1 <= halfStep) { return round(that._values[i]); } } }, _getFormattedValue: function (val, drag) { var that = this, html = '', tooltip = that.options.tooltip, tooltipTemplate, selectionStart, selectionEnd; if (isArray(val)) { selectionStart = val[0]; selectionEnd = val[1]; } else if (drag && drag.type) { selectionStart = drag.selectionStart; selectionEnd = drag.selectionEnd; } if (drag) { tooltipTemplate = drag.tooltipTemplate; } if (!tooltipTemplate && tooltip.template) { tooltipTemplate = kendo.template(tooltip.template); } if (isArray(val) || drag && drag.type) { if (tooltipTemplate) { html = tooltipTemplate({ selectionStart: selectionStart, selectionEnd: selectionEnd }); } else { selectionStart = format(tooltip.format, selectionStart); selectionEnd = format(tooltip.format, selectionEnd); html = selectionStart + ' - ' + selectionEnd; } } else { if (drag) { drag.val = val; } if (tooltipTemplate) { html = tooltipTemplate({ value: val }); } else { html = format(tooltip.format, val); } } return html; }, _getDraggableArea: function () { var that = this, offset = kendo.getOffset(that._trackDiv); return { startPoint: that._isHorizontal ? offset.left : offset.top + that._maxSelection, endPoint: that._isHorizontal ? offset.left + that._maxSelection : offset.top }; }, _createHtml: function () { var that = this, element = that.element, options = that.options, inputs = element.find('input'); if (inputs.length == 2) { inputs.eq(0).prop('value', formatValue(options.selectionStart)); inputs.eq(1).prop('value', formatValue(options.selectionEnd)); } else { element.prop('value', formatValue(options.value)); } element.wrap(createWrapper(options, element, that._isHorizontal)).hide(); if (options.showButtons) { element.before(createButton(options, 'increase', that._isHorizontal)).before(createButton(options, 'decrease', that._isHorizontal)); } element.before(createTrack(options, element)); }, _focus: function (e) { var that = this, target = e.target, val = that.value(), drag = that._drag; if (!drag) { if (target == that.wrapper.find(DRAG_HANDLE).eq(0)[0]) { drag = that._firstHandleDrag; that._activeHandle = 0; } else { drag = that._lastHandleDrag; that._activeHandle = 1; } val = val[that._activeHandle]; } $(target).addClass(STATE_FOCUSED + ' ' + STATE_SELECTED); if (drag) { that._activeHandleDrag = drag; drag.selectionStart = that.options.selectionStart; drag.selectionEnd = that.options.selectionEnd; drag._updateTooltip(val); } }, _focusWithMouse: function (target) { target = $(target); var that = this, idx = target.is(DRAG_HANDLE) ? target.index() : 0; window.setTimeout(function () { that.wrapper.find(DRAG_HANDLE)[idx == 2 ? 1 : 0].focus(); }, 1); that._setTooltipTimeout(); }, _blur: function (e) { var that = this, drag = that._activeHandleDrag; $(e.target).removeClass(STATE_FOCUSED + ' ' + STATE_SELECTED); if (drag) { drag._removeTooltip(); delete that._activeHandleDrag; delete that._activeHandle; } }, _setTooltipTimeout: function () { var that = this; that._tooltipTimeout = window.setTimeout(function () { var drag = that._drag || that._activeHandleDrag; if (drag) { drag._removeTooltip(); } }, 300); }, _clearTooltipTimeout: function () { var that = this; window.clearTimeout(this._tooltipTimeout); var drag = that._drag || that._activeHandleDrag; if (drag && drag.tooltipDiv) { drag.tooltipDiv.stop(true, false).css('opacity', 1); } }, _reset: function () { var that = this, element = that.element, formId = element.attr('form'), form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._form = form.on('reset', proxy(that._formResetHandler, that)); } }, destroy: function () { if (this._form) { this._form.off('reset', this._formResetHandler); } Widget.fn.destroy.call(this); } }); function createWrapper(options, element, isHorizontal) { var orientationCssClass = isHorizontal ? ' k-slider-horizontal' : ' k-slider-vertical', style = options.style ? options.style : element.attr('style'), cssClasses = element.attr('class') ? ' ' + element.attr('class') : '', tickPlacementCssClass = ''; if (options.tickPlacement == 'bottomRight') { tickPlacementCssClass = ' k-slider-bottomright'; } else if (options.tickPlacement == 'topLeft') { tickPlacementCssClass = ' k-slider-topleft'; } style = style ? ' style=\'' + style + '\'' : ''; return '<div class=\'k-widget k-slider' + orientationCssClass + cssClasses + '\'' + style + '>' + '<div class=\'k-slider-wrap' + (options.showButtons ? ' k-slider-buttons' : '') + tickPlacementCssClass + '\'></div></div>'; } function createButton(options, type, isHorizontal) { var buttonCssClass = ''; if (type == 'increase') { buttonCssClass = isHorizontal ? 'k-i-arrow-e' : 'k-i-arrow-n'; } else { buttonCssClass = isHorizontal ? 'k-i-arrow-w' : 'k-i-arrow-s'; } return '<a class=\'k-button k-button-' + type + '\'><span class=\'k-icon ' + buttonCssClass + '\' title=\'' + options[type + 'ButtonTitle'] + '\'>' + options[type + 'ButtonTitle'] + '</span></a>'; } function createSliderItems(options, distance) { var result = '<ul class=\'k-reset k-slider-items\'>', count = math.floor(round(distance / options.smallStep)) + 1, i; for (i = 0; i < count; i++) { result += '<li class=\'k-tick\' role=\'presentation\'> </li>'; } result += '</ul>'; return result; } function createTrack(options, element) { var dragHandleCount = element.is('input') ? 1 : 2, firstDragHandleTitle = dragHandleCount == 2 ? options.leftDragHandleTitle : options.dragHandleTitle; return '<div class=\'k-slider-track\'><div class=\'k-slider-selection\'><!-- --></div>' + '<a href=\'#\' class=\'k-draghandle\' title=\'' + firstDragHandleTitle + '\' role=\'slider\' aria-valuemin=\'' + options.min + '\' aria-valuemax=\'' + options.max + '\' aria-valuenow=\'' + (dragHandleCount > 1 ? options.selectionStart || options.min : options.value || options.min) + '\'>Drag</a>' + (dragHandleCount > 1 ? '<a href=\'#\' class=\'k-draghandle\' title=\'' + options.rightDragHandleTitle + '\'role=\'slider\' aria-valuemin=\'' + options.min + '\' aria-valuemax=\'' + options.max + '\' aria-valuenow=\'' + (options.selectionEnd || options.max) + '\'>Drag</a>' : '') + '</div>'; } function step(stepValue) { return function (value) { return value + stepValue; }; } function setValue(value) { return function () { return value; }; } function formatValue(value) { return (value + '').replace('.', kendo.cultures.current.numberFormat['.']); } function calculatePrecision(value) { var number = value.toString(); var precision = 0; number = number.split('.'); if (number[1]) { precision = number[1].length; } precision = precision > 10 ? 10 : precision; return precision; } function round(value) { var precision, power; value = parseFloat(value, 10); precision = calculatePrecision(value); power = math.pow(10, precision || 0); return math.round(value * power) / power; } function parseAttr(element, name) { var value = parse(element.getAttribute(name)); if (value === null) { value = undefined; } return value; } function defined(value) { return typeof value !== UNDEFINED; } function removeFraction(value) { return value * 10000; } var Slider = SliderBase.extend({ init: function (element, options) { var that = this, dragHandle; element.type = 'text'; options = extend({}, { value: parseAttr(element, 'value'), min: parseAttr(element, 'min'), max: parseAttr(element, 'max'), smallStep: parseAttr(element, 'step') }, options); element = $(element); if (options && options.enabled === undefined) { options.enabled = !element.is('[disabled]'); } SliderBase.fn.init.call(that, element, options); options = that.options; if (!defined(options.value) || options.value === null) { options.value = options.min; element.prop('value', formatValue(options.min)); } options.value = math.max(math.min(options.value, options.max), options.min); dragHandle = that.wrapper.find(DRAG_HANDLE); this._selection = new Slider.Selection(dragHandle, that, options); that._drag = new Slider.Drag(dragHandle, '', that, options); }, options: { name: 'Slider', showButtons: true, increaseButtonTitle: 'Increase', decreaseButtonTitle: 'Decrease', dragHandleTitle: 'drag', tooltip: { format: '{0:#,#.##}' }, value: null }, enable: function (enable) { var that = this, options = that.options, clickHandler, move; that.disable(); if (enable === false) { return; } that.wrapper.removeClass(STATE_DISABLED).addClass(STATE_DEFAULT); that.wrapper.find('input').removeAttr(DISABLED); clickHandler = function (e) { var touch = getTouches(e)[0]; if (!touch) { return; } var mousePosition = that._isHorizontal ? touch.location.pageX : touch.location.pageY, dragableArea = that._getDraggableArea(), target = $(e.target); if (target.hasClass('k-draghandle')) { target.addClass(STATE_FOCUSED + ' ' + STATE_SELECTED); return; } that._update(that._getValueFromPosition(mousePosition, dragableArea)); that._focusWithMouse(e.target); that._drag.dragstart(e); e.preventDefault(); }; that.wrapper.find(TICK_SELECTOR + ', ' + TRACK_SELECTOR).on(TRACK_MOUSE_DOWN, clickHandler).end().on(TRACK_MOUSE_DOWN, function () { $(document.documentElement).one('selectstart', kendo.preventDefault); }).on(TRACK_MOUSE_UP, function () { that._drag._end(); }); that.wrapper.find(DRAG_HANDLE).attr(TABINDEX, 0).on(MOUSE_UP, function () { that._setTooltipTimeout(); }).on(CLICK, function (e) { that._focusWithMouse(e.target); e.preventDefault(); }).on(FOCUS, proxy(that._focus, that)).on(BLUR, proxy(that._blur, that)); move = proxy(function (sign) { var newVal = that._nextValueByIndex(that._valueIndex + sign * 1); that._setValueInRange(newVal); that._drag._updateTooltip(newVal); }, that); if (options.showButtons) { var mouseDownHandler = proxy(function (e, sign) { this._clearTooltipTimeout(); if (e.which === 1 || support.touch && e.which === 0) { move(sign); this.timeout = setTimeout(proxy(function () { this.timer = setInterval(function () { move(sign); }, 60); }, this), 200); } }, that); that.wrapper.find('.k-button').on(MOUSE_UP, proxy(function (e) { this._clearTimer(); that._focusWithMouse(e.target); }, that)).on(MOUSE_OVER, function (e) { $(e.currentTarget).addClass('k-state-hover'); }).on('mouseout' + NS, proxy(function (e) { $(e.currentTarget).removeClass('k-state-hover'); this._clearTimer(); }, that)).eq(0).on(MOUSE_DOWN, proxy(function (e) { mouseDownHandler(e, 1); }, that)).click(false).end().eq(1).on(MOUSE_DOWN, proxy(function (e) { mouseDownHandler(e, -1); }, that)).click(kendo.preventDefault); } that.wrapper.find(DRAG_HANDLE).off(KEY_DOWN, false).on(KEY_DOWN, proxy(this._keydown, that)); options.enabled = true; }, disable: function () { var that = this; that.wrapper.removeClass(STATE_DEFAULT).addClass(STATE_DISABLED); $(that.element).prop(DISABLED, DISABLED); that.wrapper.find('.k-button').off(MOUSE_DOWN).on(MOUSE_DOWN, kendo.preventDefault).off(MOUSE_UP).on(MOUSE_UP, kendo.preventDefault).off('mouseleave' + NS).on('mouseleave' + NS, kendo.preventDefault).off(MOUSE_OVER).on(MOUSE_OVER, kendo.preventDefault); that.wrapper.find(TICK_SELECTOR + ', ' + TRACK_SELECTOR).off(TRACK_MOUSE_DOWN).off(TRACK_MOUSE_UP); that.wrapper.find(DRAG_HANDLE).attr(TABINDEX, -1).off(MOUSE_UP).off(KEY_DOWN).off(CLICK).off(FOCUS).off(BLUR); that.options.enabled = false; }, _update: function (val) { var that = this, change = that.value() != val; that.value(val); if (change) { that.trigger(CHANGE, { value: that.options.value }); } }, value: function (value) { var that = this, options = that.options; value = round(value); if (isNaN(value)) { return options.value; } if (value >= options.min && value <= options.max) { if (options.value != value) { that.element.prop('value', formatValue(value)); options.value = value; that._refreshAriaAttr(value); that._refresh(); } } }, _refresh: function () { this.trigger(MOVE_SELECTION, { value: this.options.value }); }, _refreshAriaAttr: function (value) { var that = this, drag = that._drag, formattedValue; if (drag && drag._tooltipDiv) { formattedValue = drag._tooltipDiv.text(); } else { formattedValue = that._getFormattedValue(value, null); } this.wrapper.find(DRAG_HANDLE).attr('aria-valuenow', value).attr('aria-valuetext', formattedValue); }, _clearTimer: function () { clearTimeout(this.timeout); clearInterval(this.timer); }, _keydown: function (e) { var that = this; if (e.keyCode in that._keyMap) { that._clearTooltipTimeout(); that._setValueInRange(that._keyMap[e.keyCode](that.options.value)); that._drag._updateTooltip(that.value()); e.preventDefault(); } }, _setValueInRange: function (val) { var that = this, options = that.options; val = round(val); if (isNaN(val)) { that._update(options.min); return; } val = math.max(math.min(val, options.max), options.min); that._update(val); }, _nextValueByIndex: function (index) { var count = this._values.length; if (this._isRtl) { index = count - 1 - index; } return this._values[math.max(0, math.min(index, count - 1))]; }, _formResetHandler: function () { var that = this, min = that.options.min; setTimeout(function () { var value = that.element[0].value; that.value(value === '' || isNaN(value) ? min : value); }); }, destroy: function () { var that = this; SliderBase.fn.destroy.call(that); that.wrapper.off(NS).find('.k-button').off(NS).end().find(DRAG_HANDLE).off(NS).end().find(TICK_SELECTOR + ', ' + TRACK_SELECTOR).off(NS).end(); that._drag.draggable.destroy(); that._drag._removeTooltip(true); } }); Slider.Selection = function (dragHandle, that, options) { function moveSelection(val) { var selectionValue = val - options.min, index = that._valueIndex = math.ceil(round(selectionValue / options.smallStep)), selection = parseInt(that._pixelSteps[index], 10), selectionDiv = that._trackDiv.find('.k-slider-selection'), halfDragHanndle = parseInt(dragHandle[that._outerSize]() / 2, 10), rtlCorrection = that._isRtl ? 2 : 0; selectionDiv[that._sizeFn](that._isRtl ? that._maxSelection - selection : selection); dragHandle.css(that._position, selection - halfDragHanndle - rtlCorrection); } moveSelection(options.value); that.bind([ CHANGE, SLIDE, MOVE_SELECTION ], function (e) { moveSelection(parseFloat(e.value, 10)); }); }; Slider.Drag = function (element, type, owner, options) { var that = this; that.owner = owner; that.options = options; that.element = element; that.type = type; that.draggable = new Draggable(element, { distance: 0, dragstart: proxy(that._dragstart, that), drag: proxy(that.drag, that), dragend: proxy(that.dragend, that), dragcancel: proxy(that.dragcancel, that) }); element.click(false); }; Slider.Drag.prototype = { dragstart: function (e) { this.owner._activeDragHandle = this; this.draggable.userEvents.cancel(); this._dragstart(e); this.dragend(); }, _dragstart: function (e) { var that = this, owner = that.owner, options = that.options; if (!options.enabled) { e.preventDefault(); return; } this.owner._activeDragHandle = this; owner.element.off(MOUSE_OVER); owner.wrapper.find('.' + STATE_FOCUSED).removeClass(STATE_FOCUSED + ' ' + STATE_SELECTED); that.element.addClass(STATE_FOCUSED + ' ' + STATE_SELECTED); $(document.documentElement).css('cursor', 'pointer'); that.dragableArea = owner._getDraggableArea(); that.step = math.max(options.smallStep * (owner._maxSelection / owner._distance), 0); if (that.type) { that.selectionStart = options.selectionStart; that.selectionEnd = options.selectionEnd; owner._setZIndex(that.type); } else { that.oldVal = that.val = options.value; } that._removeTooltip(true); that._createTooltip(); }, _createTooltip: function () { var that = this, owner = that.owner, tooltip = that.options.tooltip, html = '', wnd = $(window), tooltipTemplate, colloutCssClass; if (!tooltip.enabled) { return; } if (tooltip.template) { tooltipTemplate = that.tooltipTemplate = kendo.template(tooltip.template); } $('.k-slider-tooltip').remove(); that.tooltipDiv = $('<div class=\'k-widget k-tooltip k-slider-tooltip\'><!-- --></div>').appendTo(document.body); html = owner._getFormattedValue(that.val || owner.value(), that); if (!that.type) { colloutCssClass = 'k-callout-' + (owner._isHorizontal ? 's' : 'e'); that.tooltipInnerDiv = '<div class=\'k-callout ' + colloutCssClass + '\'><!-- --></div>'; html += that.tooltipInnerDiv; } that.tooltipDiv.html(html); that._scrollOffset = { top: wnd.scrollTop(), left: wnd.scrollLeft() }; that.moveTooltip(); }, drag: function (e) { var that = this, owner = that.owner, x = e.x.location, y = e.y.location, startPoint = that.dragableArea.startPoint, endPoint = that.dragableArea.endPoint, slideParams; e.preventDefault(); if (owner._isHorizontal) { if (owner._isRtl) { that.val = that.constrainValue(x, startPoint, endPoint, x < endPoint); } else { that.val = that.constrainValue(x, startPoint, endPoint, x >= endPoint); } } else { that.val = that.constrainValue(y, endPoint, startPoint, y <= endPoint); } if (that.oldVal != that.val) { that.oldVal = that.val; if (that.type) { if (that.type == 'firstHandle') { if (that.val < that.selectionEnd) { that.selectionStart = that.val; } else { that.selectionStart = that.selectionEnd = that.val; } } else { if (that.val > that.selectionStart) { that.selectionEnd = that.val; } else { that.selectionStart = that.selectionEnd = that.val; } } slideParams = { values: [ that.selectionStart, that.selectionEnd ], value: [ that.selectionStart, that.selectionEnd ] }; } else { slideParams = { value: that.val }; } owner.trigger(SLIDE, slideParams); } that._updateTooltip(that.val); }, _updateTooltip: function (val) { var that = this, options = that.options, tooltip = options.tooltip, html = ''; if (!tooltip.enabled) { return; } if (!that.tooltipDiv) { that._createTooltip(); } html = that.owner._getFormattedValue(round(val), that); if (!that.type) { html += that.tooltipInnerDiv; } that.tooltipDiv.html(html); that.moveTooltip(); }, dragcancel: function () { this.owner._refresh(); $(document.documentElement).css('cursor', ''); return this._end(); }, dragend: function () { var that = this, owner = that.owner; $(document.documentElement).css('cursor', ''); if (that.type) { owner._update(that.selectionStart, that.selectionEnd); } else { owner._update(that.val); that.draggable.userEvents._disposeAll(); } that.draggable.userEvents.cancel(); return that._end(); }, _end: function () { var that = this, owner = that.owner; owner._focusWithMouse(that.element); owner.element.on(MOUSE_OVER); return false; }, _removeTooltip: function (noAnimation) { var that = this, owner = that.owner; if (that.tooltipDiv && owner.options.tooltip.enabled && owner.options.enabled) { if (noAnimation) { that.tooltipDiv.remove(); that.tooltipDiv = null; } else { that.tooltipDiv.fadeOut('slow', function () { $(this).remove(); that.tooltipDiv = null; }); } } }, moveTooltip: function () { var that = this, owner = that.owner, top = 0, left = 0, element = that.element, offset = kendo.getOffset(element), margin = 8, viewport = $(window), callout = that.tooltipDiv.find('.k-callout'), width = that.tooltipDiv.outerWidth(), height = that.tooltipDiv.outerHeight(), dragHandles, sdhOffset, diff, anchorSize; if (that.type) { dragHandles = owner.wrapper.find(DRAG_HANDLE); offset = kendo.getOffset(dragHandles.eq(0)); sdhOffset = kendo.getOffset(dragHandles.eq(1)); if (owner._isHorizontal) { top = sdhOffset.top; left = offset.left + (sdhOffset.left - offset.left) / 2; } else { top = offset.top + (sdhOffset.top - offset.top) / 2; left = sdhOffset.left; } anchorSize = dragHandles.eq(0).outerWidth() + 2 * margin; } else { top = offset.top; left = offset.left; anchorSize = element.outerWidth() + 2 * margin; } if (owner._isHorizontal) { left -= parseInt((width - element[owner._outerSize]()) / 2, 10); top -= height + callout.height() + margin; } else { top -= parseInt((height - element[owner._outerSize]()) / 2, 10); left -= width + callout.width() + margin; } if (owner._isHorizontal) { diff = that._flip(top, height, anchorSize, viewport.outerHeight() + that._scrollOffset.top); top += diff; left += that._fit(left, width, viewport.outerWidth() + that._scrollOffset.left); } else { diff = that._flip(left, width, anchorSize, viewport.outerWidth() + that._scrollOffset.left); top += that._fit(top, height, viewport.outerHeight() + that._scrollOffset.top); left += diff; } if (diff > 0 && callout) { callout.removeClass(); callout.addClass('k-callout k-callout-' + (owner._isHorizontal ? 'n' : 'w')); } that.tooltipDiv.css({ top: top, left: left }); }, _fit: function (position, size, viewPortEnd) { var output = 0; if (position + size > viewPortEnd) { output = viewPortEnd - (position + size); } if (position < 0) { output = -position; } return output; }, _flip: function (offset, size, anchorSize, viewPortEnd) { var output = 0; if (offset + size > viewPortEnd) { output += -(anchorSize + size); } if (offset + output < 0) { output += anchorSize + size; } return output; }, constrainValue: function (position, min, max, maxOverflow) { var that = this, val = 0; if (min < position && position < max) { val = that.owner._getValueFromPosition(position, that.dragableArea); } else { if (maxOverflow) { val = that.options.max; } else { val = that.options.min; } } return val; } }; kendo.ui.plugin(Slider); var RangeSlider = SliderBase.extend({ init: function (element, options) { var that = this, inputs = $(element).find('input'), firstInput = inputs.eq(0)[0], secondInput = inputs.eq(1)[0]; firstInput.type = 'text'; secondInput.type = 'text'; if (options && options.showButtons) { if (window.console) { window.console.warn('showbuttons option is not supported for the range slider, ignoring'); } options.showButtons = false; } options = extend({}, { selectionStart: parseAttr(firstInput, 'value'), min: parseAttr(firstInput, 'min'), max: parseAttr(firstInput, 'max'), smallStep: parseAttr(firstInput, 'step') }, { selectionEnd: parseAttr(secondInput, 'value'), min: parseAttr(secondInput, 'min'), max: parseAttr(secondInput, 'max'), smallStep: parseAttr(secondInput, 'step') }, options); if (options && options.enabled === undefined) { options.enabled = !inputs.is('[disabled]'); } SliderBase.fn.init.call(that, element, options); options = that.options; if (!defined(options.selectionStart) || options.selectionStart === null) { options.selectionStart = options.min; inputs.eq(0).prop('value', formatValue(options.min)); } if (!defined(options.selectionEnd) || options.selectionEnd === null) { options.selectionEnd = options.max; inputs.eq(1).prop('value', formatValue(options.max)); } var dragHandles = that.wrapper.find(DRAG_HANDLE); this._selection = new RangeSlider.Selection(dragHandles, that, options); that._firstHandleDrag = new Slider.Drag(dragHandles.eq(0), 'firstHandle', that, options); that._lastHandleDrag = new Slider.Drag(dragHandles.eq(1), 'lastHandle', that, options); }, options: { name: 'RangeSlider', leftDragHandleTitle: 'drag', rightDragHandleTitle: 'drag', tooltip: { format: '{0:#,#.##}' }, selectionStart: null, selectionEnd: null }, enable: function (enable) { var that = this, options = that.options, clickHandler; that.disable(); if (enable === false) { return; } that.wrapper.removeClass(STATE_DISABLED).addClass(STATE_DEFAULT); that.wrapper.find('input').removeAttr(DISABLED); clickHandler = function (e) { var touch = getTouches(e)[0]; if (!touch) { return; } var mousePosition = that._isHorizontal ? touch.location.pageX : touch.location.pageY, dragableArea = that._getDraggableArea(), val = that._getValueFromPosition(mousePosition, dragableArea), target = $(e.target), from, to, drag; if (target.hasClass('k-draghandle')) { that.wrapper.find('.' + STATE_FOCUSED).removeClass(STATE_FOCUSED + ' ' + STATE_SELECTED); target.addClass(STATE_FOCUSED + ' ' + STATE_SELECTED); return; } if (val < options.selectionStart) { from = val; to = options.selectionEnd; drag = that._firstHandleDrag; } else if (val > that.selectionEnd) { from = options.selectionStart; to = val; drag = that._lastHandleDrag; } else { if (val - options.selectionStart <= options.selectionEnd - val) { from = val; to = options.selectionEnd; drag = that._firstHandleDrag; } else { from = options.selectionStart; to = val; drag = that._lastHandleDrag; } } drag.dragstart(e); that._setValueInRange(from, to); that._focusWithMouse(drag.element); }; that.wrapper.find(TICK_SELECTOR + ', ' + TRACK_SELECTOR).on(TRACK_MOUSE_DOWN, clickHandler).end().on(TRACK_MOUSE_DOWN, function () { $(document.documentElement).one('selectstart', kendo.preventDefault); }).on(TRACK_MOUSE_UP, function () { if (that._activeDragHandle) { that._activeDragHandle._end(); } }); that.wrapper.find(DRAG_HANDLE).attr(TABINDEX, 0).on(MOUSE_UP, function () { that._setTooltipTimeout(); }).on(CLICK, function (e) { that._focusWithMouse(e.target); e.preventDefault(); }).on(FOCUS, proxy(that._focus, that)).on(BLUR, proxy(that._blur, that)); that.wrapper.find(DRAG_HANDLE).off(KEY_DOWN, kendo.preventDefault).eq(0).on(KEY_DOWN, proxy(function (e) { this._keydown(e, 'firstHandle'); }, that)).end().eq(1).on(KEY_DOWN, proxy(function (e) { this._keydown(e, 'lastHandle'); }, that)); that.options.enabled = true; }, disable: function () { var that = this; that.wrapper.removeClass(STATE_DEFAULT).addClass(STATE_DISABLED); that.wrapper.find('input').prop(DISABLED, DISABLED); that.wrapper.find(TICK_SELECTOR + ', ' + TRACK_SELECTOR).off(TRACK_MOUSE_DOWN).off(TRACK_MOUSE_UP); that.wrapper.find(DRAG_HANDLE).attr(TABINDEX, -1).off(MOUSE_UP).off(KEY_DOWN).off(CLICK).off(FOCUS).off(BLUR); that.options.enabled = false; }, _keydown: function (e, handle) { var that = this, selectionStartValue = that.options.selectionStart, selectionEndValue = that.options.selectionEnd, dragSelectionStart, dragSelectionEnd, activeHandleDrag; if (e.keyCode in that._keyMap) { that._clearTooltipTimeout(); if (handle == 'firstHandle') { activeHandleDrag = that._activeHandleDrag = that._firstHandleDrag; selectionStartValue = that._keyMap[e.keyCode](selectionStartValue); if (selectionStartValue > selectionEndValue) { selectionEndValue = selectionStartValue; } } else { activeHandleDrag = that._activeHandleDrag = that._lastHandleDrag; selectionEndValue = that._keyMap[e.keyCode](selectionEndValue); if (selectionStartValue > selectionEndValue) { selectionStartValue = selectionEndValue; } } that._setValueInRange(round(selectionStartValue), round(selectionEndValue)); dragSelectionStart = Math.max(selectionStartValue, that.options.selectionStart); dragSelectionEnd = Math.min(selectionEndValue, that.options.selectionEnd); activeHandleDrag.selectionEnd = Math.max(dragSelectionEnd, that.options.selectionStart); activeHandleDrag.selectionStart = Math.min(dragSelectionStart, that.options.selectionEnd); activeHandleDrag._updateTooltip(that.value()[that._activeHandle]); e.preventDefault(); } }, _update: function (selectionStart, selectionEnd) { var that = this, values = that.value(); var change = values[0] != selectionStart || values[1] != selectionEnd; that.value([ selectionStart, selectionEnd ]); if (change) { that.trigger(CHANGE, { values: [ selectionStart, selectionEnd ], value: [ selectionStart, selectionEnd ] }); } }, value: function (value) { if (value && value.length) { return this._value(value[0], value[1]); } else { return this._value(); } }, _value: function (start, end) { var that = this, options = that.options, selectionStart = options.selectionStart, selectionEnd = options.selectionEnd; if (isNaN(start) && isNaN(end)) { return [ selectionStart, selectionEnd ]; } else { start = round(start); end = round(end); } if (start >= options.min && start <= options.max && end >= options.min && end <= options.max && start <= end) { if (selectionStart != start || selectionEnd != end) { that.element.find('input').eq(0).prop('value', formatValue(start)).end().eq(1).prop('value', formatValue(end)); options.selectionStart = start; options.selectionEnd = end; that._refresh(); that._refreshAriaAttr(start, end); } } }, values: function (start, end) { if (isArray(start)) { return this._value(start[0], start[1]); } else { return this._value(start, end); } }, _refresh: function () { var that = this, options = that.options; that.trigger(MOVE_SELECTION, { values: [ options.selectionStart, options.selectionEnd ], value: [ options.selectionStart, options.selectionEnd ] }); if (options.selectionStart == options.max && options.selectionEnd == options.max) { that._setZIndex('firstHandle'); } }, _refreshAriaAttr: function (start, end) { var that = this, dragHandles = that.wrapper.find(DRAG_HANDLE), drag = that._activeHandleDrag, formattedValue; formattedValue = that._getFormattedValue([ start, end ], drag); dragHandles.eq(0).attr('aria-valuenow', start); dragHandles.eq(1).attr('aria-valuenow', end); dragHandles.attr('aria-valuetext', formattedValue); }, _setValueInRange: function (selectionStart, selectionEnd) { var options = this.options; selectionStart = math.max(math.min(selectionStart, options.max), options.min); selectionEnd = math.max(math.min(selectionEnd, options.max), options.min); if (selectionStart == options.max && selectionEnd == options.max) { this._setZIndex('firstHandle'); } this._update(math.min(selectionStart, selectionEnd), math.max(selectionStart, selectionEnd)); }, _setZIndex: function (type) { this.wrapper.find(DRAG_HANDLE).each(function (index) { $(this).css('z-index', type == 'firstHandle' ? 1 - index : index); }); }, _formResetHandler: function () { var that = this, options = that.options; setTimeout(function () { var inputs = that.element.find('input'); var start = inputs[0].value; var end = inputs[1].value; that.values(start === '' || isNaN(start) ? options.min : start, end === '' || isNaN(end) ? options.max : end); }); }, destroy: function () { var that = this; SliderBase.fn.destroy.call(that); that.wrapper.off(NS).find(TICK_SELECTOR + ', ' + TRACK_SELECTOR).off(NS).end().find(DRAG_HANDLE).off(NS); that._firstHandleDrag.draggable.destroy(); that._lastHandleDrag.draggable.destroy(); } }); RangeSlider.Selection = function (dragHandles, that, options) { function moveSelection(value) { value = value || []; var selectionStartValue = value[0] - options.min, selectionEndValue = value[1] - options.min, selectionStartIndex = math.ceil(round(selectionStartValue / options.smallStep)), selectionEndIndex = math.ceil(round(selectionEndValue / options.smallStep)), selectionStart = that._pixelSteps[selectionStartIndex], selectionEnd = that._pixelSteps[selectionEndIndex], halfHandle = parseInt(dragHandles.eq(0)[that._outerSize]() / 2, 10), rtlCorrection = that._isRtl ? 2 : 0; dragHandles.eq(0).css(that._position, selectionStart - halfHandle - rtlCorrection).end().eq(1).css(that._position, selectionEnd - halfHandle - rtlCorrection); makeSelection(selectionStart, selectionEnd); } function makeSelection(selectionStart, selectionEnd) { var selection, selectionPosition, selectionDiv = that._trackDiv.find('.k-slider-selection'); selection = math.abs(selectionStart - selectionEnd); selectionDiv[that._sizeFn](selection); if (that._isRtl) { selectionPosition = math.max(selectionStart, selectionEnd); selectionDiv.css('right', that._maxSelection - selectionPosition - 1); } else { selectionPosition = math.min(selectionStart, selectionEnd); selectionDiv.css(that._position, selectionPosition - 1); } } moveSelection(that.value()); that.bind([ CHANGE, SLIDE, MOVE_SELECTION ], function (e) { moveSelection(e.values); }); }; kendo.ui.plugin(RangeSlider); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.mobile.scroller', [ 'kendo.fx', 'kendo.draganddrop' ], f); }(function () { var __meta__ = { id: 'mobile.scroller', name: 'Scroller', category: 'mobile', description: 'The Kendo Mobile Scroller widget enables touch friendly kinetic scrolling for the contents of a given DOM element.', depends: [ 'fx', 'draganddrop' ] }; (function ($, undefined) { var kendo = window.kendo, mobile = kendo.mobile, fx = kendo.effects, ui = mobile.ui, proxy = $.proxy, extend = $.extend, Widget = ui.Widget, Class = kendo.Class, Movable = kendo.ui.Movable, Pane = kendo.ui.Pane, PaneDimensions = kendo.ui.PaneDimensions, Transition = fx.Transition, Animation = fx.Animation, abs = Math.abs, SNAPBACK_DURATION = 500, SCROLLBAR_OPACITY = 0.7, FRICTION = 0.96, VELOCITY_MULTIPLIER = 10, MAX_VELOCITY = 55, OUT_OF_BOUNDS_FRICTION = 0.5, ANIMATED_SCROLLER_PRECISION = 5, RELEASECLASS = 'km-scroller-release', REFRESHCLASS = 'km-scroller-refresh', PULL = 'pull', CHANGE = 'change', RESIZE = 'resize', SCROLL = 'scroll', MOUSE_WHEEL_ID = 2; var ZoomSnapBack = Animation.extend({ init: function (options) { var that = this; Animation.fn.init.call(that); extend(that, options); that.userEvents.bind('gestureend', proxy(that.start, that)); that.tapCapture.bind('press', proxy(that.cancel, that)); }, enabled: function () { return this.movable.scale < this.dimensions.minScale; }, done: function () { return this.dimensions.minScale - this.movable.scale < 0.01; }, tick: function () { var movable = this.movable; movable.scaleWith(1.1); this.dimensions.rescale(movable.scale); }, onEnd: function () { var movable = this.movable; movable.scaleTo(this.dimensions.minScale); this.dimensions.rescale(movable.scale); } }); var DragInertia = Animation.extend({ init: function (options) { var that = this; Animation.fn.init.call(that); extend(that, options, { transition: new Transition({ axis: options.axis, movable: options.movable, onEnd: function () { that._end(); } }) }); that.tapCapture.bind('press', function () { that.cancel(); }); that.userEvents.bind('end', proxy(that.start, that)); that.userEvents.bind('gestureend', proxy(that.start, that)); that.userEvents.bind('tap', proxy(that.onEnd, that)); }, onCancel: function () { this.transition.cancel(); }, freeze: function (location) { var that = this; that.cancel(); that._moveTo(location); }, onEnd: function () { var that = this; if (that.paneAxis.outOfBounds()) { that._snapBack(); } else { that._end(); } }, done: function () { return abs(this.velocity) < 1; }, start: function (e) { var that = this, velocity; if (!that.dimension.enabled) { return; } if (that.paneAxis.outOfBounds()) { that._snapBack(); } else { velocity = e.touch.id === MOUSE_WHEEL_ID ? 0 : e.touch[that.axis].velocity; that.velocity = Math.max(Math.min(velocity * that.velocityMultiplier, MAX_VELOCITY), -MAX_VELOCITY); that.tapCapture.captureNext(); Animation.fn.start.call(that); } }, tick: function () { var that = this, dimension = that.dimension, friction = that.paneAxis.outOfBounds() ? OUT_OF_BOUNDS_FRICTION : that.friction, delta = that.velocity *= friction, location = that.movable[that.axis] + delta; if (!that.elastic && dimension.outOfBounds(location)) { location = Math.max(Math.min(location, dimension.max), dimension.min); that.velocity = 0; } that.movable.moveAxis(that.axis, location); }, _end: function () { this.tapCapture.cancelCapture(); this.end(); }, _snapBack: function () { var that = this, dimension = that.dimension, snapBack = that.movable[that.axis] > dimension.max ? dimension.max : dimension.min; that._moveTo(snapBack); }, _moveTo: function (location) { this.transition.moveTo({ location: location, duration: SNAPBACK_DURATION, ease: Transition.easeOutExpo }); } }); var AnimatedScroller = Animation.extend({ init: function (options) { var that = this; kendo.effects.Animation.fn.init.call(this); extend(that, options, { origin: {}, destination: {}, offset: {} }); }, tick: function () { this._updateCoordinates(); this.moveTo(this.origin); }, done: function () { return abs(this.offset.y) < ANIMATED_SCROLLER_PRECISION && abs(this.offset.x) < ANIMATED_SCROLLER_PRECISION; }, onEnd: function () { this.moveTo(this.destination); if (this.callback) { this.callback.call(); } }, setCoordinates: function (from, to) { this.offset = {}; this.origin = from; this.destination = to; }, setCallback: function (callback) { if (callback && kendo.isFunction(callback)) { this.callback = callback; } else { callback = undefined; } }, _updateCoordinates: function () { this.offset = { x: (this.destination.x - this.origin.x) / 4, y: (this.destination.y - this.origin.y) / 4 }; this.origin = { y: this.origin.y + this.offset.y, x: this.origin.x + this.offset.x }; } }); var ScrollBar = Class.extend({ init: function (options) { var that = this, horizontal = options.axis === 'x', element = $('<div class="km-touch-scrollbar km-' + (horizontal ? 'horizontal' : 'vertical') + '-scrollbar" />'); extend(that, options, { element: element, elementSize: 0, movable: new Movable(element), scrollMovable: options.movable, alwaysVisible: options.alwaysVisible, size: horizontal ? 'width' : 'height' }); that.scrollMovable.bind(CHANGE, proxy(that.refresh, that)); that.container.append(element); if (options.alwaysVisible) { that.show(); } }, refresh: function () { var that = this, axis = that.axis, dimension = that.dimension, paneSize = dimension.size, scrollMovable = that.scrollMovable, sizeRatio = paneSize / dimension.total, position = Math.round(-scrollMovable[axis] * sizeRatio), size = Math.round(paneSize * sizeRatio); if (sizeRatio >= 1) { this.element.css('display', 'none'); } else { this.element.css('display', ''); } if (position + size > paneSize) { size = paneSize - position; } else if (position < 0) { size += position; position = 0; } if (that.elementSize != size) { that.element.css(that.size, size + 'px'); that.elementSize = size; } that.movable.moveAxis(axis, position); }, show: function () { this.element.css({ opacity: SCROLLBAR_OPACITY, visibility: 'visible' }); }, hide: function () { if (!this.alwaysVisible) { this.element.css({ opacity: 0 }); } } }); var Scroller = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); element = that.element; that._native = that.options.useNative && kendo.support.hasNativeScrolling; if (that._native) { element.addClass('km-native-scroller').prepend('<div class="km-scroll-header"/>'); extend(that, { scrollElement: element, fixedContainer: element.children().first() }); return; } element.css('overflow', 'hidden').addClass('km-scroll-wrapper').wrapInner('<div class="km-scroll-container"/>').prepend('<div class="km-scroll-header"/>'); var inner = element.children().eq(1), tapCapture = new kendo.TapCapture(element), movable = new Movable(inner), dimensions = new PaneDimensions({ element: inner, container: element, forcedEnabled: that.options.zoom }), avoidScrolling = this.options.avoidScrolling, userEvents = new kendo.UserEvents(element, { touchAction: 'pan-y', fastTap: true, allowSelection: true, preventDragEvent: true, captureUpIfMoved: true, multiTouch: that.options.zoom, start: function (e) { dimensions.refresh(); var velocityX = abs(e.x.velocity), velocityY = abs(e.y.velocity), horizontalSwipe = velocityX * 2 >= velocityY, originatedFromFixedContainer = $.contains(that.fixedContainer[0], e.event.target), verticalSwipe = velocityY * 2 >= velocityX; if (!originatedFromFixedContainer && !avoidScrolling(e) && that.enabled && (dimensions.x.enabled && horizontalSwipe || dimensions.y.enabled && verticalSwipe)) { userEvents.capture(); } else { userEvents.cancel(); } } }), pane = new Pane({ movable: movable, dimensions: dimensions, userEvents: userEvents, elastic: that.options.elastic }), zoomSnapBack = new ZoomSnapBack({ movable: movable, dimensions: dimensions, userEvents: userEvents, tapCapture: tapCapture }), animatedScroller = new AnimatedScroller({ moveTo: function (coordinates) { that.scrollTo(coordinates.x, coordinates.y); } }); movable.bind(CHANGE, function () { that.scrollTop = -movable.y; that.scrollLeft = -movable.x; that.trigger(SCROLL, { scrollTop: that.scrollTop, scrollLeft: that.scrollLeft }); }); if (that.options.mousewheelScrolling) { element.on('DOMMouseScroll mousewheel', proxy(this, '_wheelScroll')); } extend(that, { movable: movable, dimensions: dimensions, zoomSnapBack: zoomSnapBack, animatedScroller: animatedScroller, userEvents: userEvents, pane: pane, tapCapture: tapCapture, pulled: false, enabled: true, scrollElement: inner, scrollTop: 0, scrollLeft: 0, fixedContainer: element.children().first() }); that._initAxis('x'); that._initAxis('y'); that._wheelEnd = function () { that._wheel = false; that.userEvents.end(0, that._wheelY); }; dimensions.refresh(); if (that.options.pullToRefresh) { that._initPullToRefresh(); } }, _wheelScroll: function (e) { if (!this._wheel) { this._wheel = true; this._wheelY = 0; this.userEvents.press(0, this._wheelY); } clearTimeout(this._wheelTimeout); this._wheelTimeout = setTimeout(this._wheelEnd, 50); var delta = kendo.wheelDeltaY(e); if (delta) { this._wheelY += delta; this.userEvents.move(0, this._wheelY); } e.preventDefault(); }, makeVirtual: function () { this.dimensions.y.makeVirtual(); }, virtualSize: function (min, max) { this.dimensions.y.virtualSize(min, max); }, height: function () { return this.dimensions.y.size; }, scrollHeight: function () { return this.scrollElement[0].scrollHeight; }, scrollWidth: function () { return this.scrollElement[0].scrollWidth; }, options: { name: 'Scroller', zoom: false, pullOffset: 140, visibleScrollHints: false, elastic: true, useNative: false, mousewheelScrolling: true, avoidScrolling: function () { return false; }, pullToRefresh: false, messages: { pullTemplate: 'Pull to refresh', releaseTemplate: 'Release to refresh', refreshTemplate: 'Refreshing' } }, events: [ PULL, SCROLL, RESIZE ], _resize: function () { if (!this._native) { this.contentResized(); } }, setOptions: function (options) { var that = this; Widget.fn.setOptions.call(that, options); if (options.pullToRefresh) { that._initPullToRefresh(); } }, reset: function () { if (this._native) { this.scrollElement.scrollTop(0); } else { this.movable.moveTo({ x: 0, y: 0 }); this._scale(1); } }, contentResized: function () { this.dimensions.refresh(); if (this.pane.x.outOfBounds()) { this.movable.moveAxis('x', this.dimensions.x.min); } if (this.pane.y.outOfBounds()) { this.movable.moveAxis('y', this.dimensions.y.min); } }, zoomOut: function () { var dimensions = this.dimensions; dimensions.refresh(); this._scale(dimensions.fitScale); this.movable.moveTo(dimensions.centerCoordinates()); }, enable: function () { this.enabled = true; }, disable: function () { this.enabled = false; }, scrollTo: function (x, y) { if (this._native) { this.scrollElement.scrollLeft(abs(x)); this.scrollElement.scrollTop(abs(y)); } else { this.dimensions.refresh(); this.movable.moveTo({ x: x, y: y }); } }, animatedScrollTo: function (x, y, callback) { var from, to; if (this._native) { this.scrollTo(x, y); } else { from = { x: this.movable.x, y: this.movable.y }; to = { x: x, y: y }; this.animatedScroller.setCoordinates(from, to); this.animatedScroller.setCallback(callback); this.animatedScroller.start(); } }, pullHandled: function () { var that = this; that.refreshHint.removeClass(REFRESHCLASS); that.hintContainer.html(that.pullTemplate({})); that.yinertia.onEnd(); that.xinertia.onEnd(); that.userEvents.cancel(); }, destroy: function () { Widget.fn.destroy.call(this); if (this.userEvents) { this.userEvents.destroy(); } }, _scale: function (scale) { this.dimensions.rescale(scale); this.movable.scaleTo(scale); }, _initPullToRefresh: function () { var that = this; that.dimensions.y.forceEnabled(); that.pullTemplate = kendo.template(that.options.messages.pullTemplate); that.releaseTemplate = kendo.template(that.options.messages.releaseTemplate); that.refreshTemplate = kendo.template(that.options.messages.refreshTemplate); that.scrollElement.prepend('<span class="km-scroller-pull"><span class="km-icon"></span><span class="km-loading-left"></span><span class="km-loading-right"></span><span class="km-template">' + that.pullTemplate({}) + '</span></span>'); that.refreshHint = that.scrollElement.children().first(); that.hintContainer = that.refreshHint.children('.km-template'); that.pane.y.bind('change', proxy(that._paneChange, that)); that.userEvents.bind('end', proxy(that._dragEnd, that)); }, _dragEnd: function () { var that = this; if (!that.pulled) { return; } that.pulled = false; that.refreshHint.removeClass(RELEASECLASS).addClass(REFRESHCLASS); that.hintContainer.html(that.refreshTemplate({})); that.yinertia.freeze(that.options.pullOffset / 2); that.trigger('pull'); }, _paneChange: function () { var that = this; if (that.movable.y / OUT_OF_BOUNDS_FRICTION > that.options.pullOffset) { if (!that.pulled) { that.pulled = true; that.refreshHint.removeClass(REFRESHCLASS).addClass(RELEASECLASS); that.hintContainer.html(that.releaseTemplate({})); } } else if (that.pulled) { that.pulled = false; that.refreshHint.removeClass(RELEASECLASS); that.hintContainer.html(that.pullTemplate({})); } }, _initAxis: function (axis) { var that = this, movable = that.movable, dimension = that.dimensions[axis], tapCapture = that.tapCapture, paneAxis = that.pane[axis], scrollBar = new ScrollBar({ axis: axis, movable: movable, dimension: dimension, container: that.element, alwaysVisible: that.options.visibleScrollHints }); dimension.bind(CHANGE, function () { scrollBar.refresh(); }); paneAxis.bind(CHANGE, function () { scrollBar.show(); }); that[axis + 'inertia'] = new DragInertia({ axis: axis, paneAxis: paneAxis, movable: movable, tapCapture: tapCapture, userEvents: that.userEvents, dimension: dimension, elastic: that.options.elastic, friction: that.options.friction || FRICTION, velocityMultiplier: that.options.velocityMultiplier || VELOCITY_MULTIPLIER, end: function () { scrollBar.hide(); that.trigger('scrollEnd', { axis: axis, scrollTop: that.scrollTop, scrollLeft: that.scrollLeft }); } }); } }); ui.plugin(Scroller); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.autocomplete', [ 'kendo.list', 'kendo.mobile.scroller' ], f); }(function () { var __meta__ = { id: 'autocomplete', name: 'AutoComplete', category: 'web', description: 'The AutoComplete widget provides suggestions depending on the typed text.It also allows multiple value entries.', depends: ['list'], features: [ { id: 'mobile-scroller', name: 'Mobile scroller', description: 'Support for kinetic scrolling in mobile device', depends: ['mobile.scroller'] }, { id: 'virtualization', name: 'VirtualList', description: 'Support for virtualization', depends: ['virtuallist'] } ] }; (function ($, undefined) { var kendo = window.kendo, support = kendo.support, caret = kendo.caret, activeElement = kendo._activeElement, placeholderSupported = support.placeholder, ui = kendo.ui, List = ui.List, keys = kendo.keys, DataSource = kendo.data.DataSource, ARIA_DISABLED = 'aria-disabled', ARIA_READONLY = 'aria-readonly', CHANGE = 'change', DEFAULT = 'k-state-default', DISABLED = 'disabled', READONLY = 'readonly', FOCUSED = 'k-state-focused', SELECTED = 'k-state-selected', STATEDISABLED = 'k-state-disabled', HOVER = 'k-state-hover', ns = '.kendoAutoComplete', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, proxy = $.proxy; function indexOfWordAtCaret(caretIdx, text, separator) { return separator ? text.substring(0, caretIdx).split(separator).length - 1 : 0; } function wordAtCaret(caretIdx, text, separator) { return text.split(separator)[indexOfWordAtCaret(caretIdx, text, separator)]; } function replaceWordAtCaret(caretIdx, text, word, separator) { var words = text.split(separator); words.splice(indexOfWordAtCaret(caretIdx, text, separator), 1, word); if (separator && words[words.length - 1] !== '') { words.push(''); } return words.join(separator); } var AutoComplete = List.extend({ init: function (element, options) { var that = this, wrapper, disabled; that.ns = ns; options = $.isArray(options) ? { dataSource: options } : options; List.fn.init.call(that, element, options); element = that.element; options = that.options; options.placeholder = options.placeholder || element.attr('placeholder'); if (placeholderSupported) { element.attr('placeholder', options.placeholder); } that._wrapper(); that._loader(); that._dataSource(); that._ignoreCase(); element[0].type = 'text'; wrapper = that.wrapper; that._popup(); element.addClass('k-input').on('keydown' + ns, proxy(that._keydown, that)).on('keypress' + ns, proxy(that._keypress, that)).on('paste' + ns, proxy(that._search, that)).on('focus' + ns, function () { that._prev = that._accessor(); that._oldText = that._prev; that._placeholder(false); wrapper.addClass(FOCUSED); }).on('focusout' + ns, function () { that._change(); that._placeholder(); wrapper.removeClass(FOCUSED); }).attr({ autocomplete: 'off', role: 'textbox', 'aria-haspopup': true }); that._enable(); that._old = that._accessor(); if (element[0].id) { element.attr('aria-owns', that.ul[0].id); } that._aria(); that._placeholder(); that._initList(); disabled = $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } that.listView.bind('click', function (e) { e.preventDefault(); }); that._resetFocusItemHandler = $.proxy(that._resetFocusItem, that); kendo.notify(that); }, options: { name: 'AutoComplete', enabled: true, suggest: false, template: '', groupTemplate: '#:data#', fixedGroupTemplate: '#:data#', dataTextField: '', minLength: 1, delay: 200, height: 200, filter: 'startswith', ignoreCase: true, highlightFirst: false, separator: null, placeholder: '', animation: {}, virtual: false, value: null }, _dataSource: function () { var that = this; if (that.dataSource && that._refreshHandler) { that._unbindDataSource(); } else { that._progressHandler = proxy(that._showBusy, that); that._errorHandler = proxy(that._hideBusy, that); } that.dataSource = DataSource.create(that.options.dataSource).bind('progress', that._progressHandler).bind('error', that._errorHandler); }, setDataSource: function (dataSource) { this.options.dataSource = dataSource; this._dataSource(); this.listView.setDataSource(this.dataSource); }, events: [ 'open', 'close', CHANGE, 'select', 'filtering', 'dataBinding', 'dataBound' ], setOptions: function (options) { var listOptions = this._listOptions(options); List.fn.setOptions.call(this, options); this.listView.setOptions(listOptions); this._accessors(); this._aria(); }, _listOptions: function (options) { var listOptions = List.fn._listOptions.call(this, $.extend(options, { skipUpdateOnBind: true })); listOptions.dataValueField = listOptions.dataTextField; listOptions.selectedItemChange = null; return listOptions; }, _editable: function (options) { var that = this, element = that.element, wrapper = that.wrapper.off(ns), readonly = options.readonly, disable = options.disable; if (!readonly && !disable) { wrapper.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); element.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false).attr(ARIA_READONLY, false); } else { wrapper.addClass(disable ? STATEDISABLED : DEFAULT).removeClass(disable ? DEFAULT : STATEDISABLED); element.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable).attr(ARIA_READONLY, readonly); } }, close: function () { var that = this; var current = that.listView.focus(); if (current) { current.removeClass(SELECTED); } that.popup.close(); }, destroy: function () { var that = this; that.element.off(ns); that.wrapper.off(ns); List.fn.destroy.call(that); }, refresh: function () { this.listView.refresh(); }, select: function (li) { this._select(li); }, search: function (word) { var that = this, options = that.options, ignoreCase = options.ignoreCase, separator = options.separator, length; word = word || that._accessor(); clearTimeout(that._typingTimeout); if (separator) { word = wordAtCaret(caret(that.element)[0], word, separator); } length = word.length; if (!length || length >= options.minLength) { that._open = true; that._mute(function () { this.listView.value([]); }); that._filterSource({ value: ignoreCase ? word.toLowerCase() : word, operator: options.filter, field: options.dataTextField, ignoreCase: ignoreCase }); } }, suggest: function (word) { var that = this, key = that._last, value = that._accessor(), element = that.element[0], caretIdx = caret(element)[0], separator = that.options.separator, words = value.split(separator), wordIndex = indexOfWordAtCaret(caretIdx, value, separator), selectionEnd = caretIdx, idx; if (key == keys.BACKSPACE || key == keys.DELETE) { that._last = undefined; return; } word = word || ''; if (typeof word !== 'string') { if (word[0]) { word = that.dataSource.view()[List.inArray(word[0], that.ul[0])]; } word = word ? that._text(word) : ''; } if (caretIdx <= 0) { caretIdx = value.toLowerCase().indexOf(word.toLowerCase()) + 1; } idx = value.substring(0, caretIdx).lastIndexOf(separator); idx = idx > -1 ? caretIdx - (idx + separator.length) : caretIdx; value = words[wordIndex].substring(0, idx); if (word) { word = word.toString(); idx = word.toLowerCase().indexOf(value.toLowerCase()); if (idx > -1) { word = word.substring(idx + value.length); selectionEnd = caretIdx + word.length; value += word; } if (separator && words[words.length - 1] !== '') { words.push(''); } } words[wordIndex] = value; that._accessor(words.join(separator || '')); if (element === activeElement()) { caret(element, caretIdx, selectionEnd); } }, value: function (value) { if (value !== undefined) { this.listView.value(value); this._accessor(value); this._old = this._accessor(); this._oldText = this._accessor(); } else { return this._accessor(); } }, _click: function (e) { var item = e.item; var element = this.element; e.preventDefault(); this._active = true; if (this.trigger('select', { item: item })) { this.close(); return; } this._oldText = element.val(); this._select(item); this._blur(); caret(element, element.val().length); }, _resetFocusItem: function () { var index = this.options.highlightFirst ? 0 : -1; if (this.options.virtual) { this.listView.scrollTo(0); } this.listView.focus(index); }, _listBound: function () { var that = this; var popup = that.popup; var options = that.options; var data = that.dataSource.flatView(); var length = data.length; var isActive = that.element[0] === activeElement(); var action; that._resizePopup(); popup.position(); if (length) { if (options.suggest && isActive) { that.suggest(data[0]); } } if (that._open) { that._open = false; action = length ? 'open' : 'close'; if (that._typingTimeout && !isActive) { action = 'close'; } if (length) { that._resetFocusItem(); if (options.virtual) { that.popup.unbind('activate', that._resetFocusItemHandler).one('activate', that._resetFocusItemHandler); } } popup[action](); that._typingTimeout = undefined; } if (that._touchScroller) { that._touchScroller.reset(); } that._hideBusy(); that._makeUnselectable(); that.trigger('dataBound'); }, _mute: function (callback) { this._muted = true; callback.call(this); this._muted = false; }, _listChange: function () { var isActive = this._active || this.element[0] === activeElement(); if (isActive && !this._muted) { this._selectValue(this.listView.selectedDataItems()[0]); } }, _selectValue: function (dataItem) { var separator = this.options.separator; var text = ''; if (dataItem) { text = this._text(dataItem); } if (text === null) { text = ''; } if (separator) { text = replaceWordAtCaret(caret(this.element)[0], this._accessor(), text, separator); } this._prev = text; this._accessor(text); this._placeholder(); }, _change: function () { var that = this; var value = that.value(); var trigger = value !== List.unifyType(that._old, typeof value); var valueUpdated = trigger && !that._typing; var itemSelected = that._oldText !== value; if (valueUpdated || itemSelected) { that.element.trigger(CHANGE); } if (trigger) { that._old = value; that.trigger(CHANGE); } that.typing = false; }, _accessor: function (value) { var that = this, element = that.element[0]; if (value !== undefined) { element.value = value === null ? '' : value; that._placeholder(); } else { value = element.value; if (element.className.indexOf('k-readonly') > -1) { if (value === that.options.placeholder) { return ''; } else { return value; } } return value; } }, _keydown: function (e) { var that = this; var key = e.keyCode; var visible = that.popup.visible(); var current = this.listView.focus(); that._last = key; if (key === keys.DOWN) { if (visible) { this._move(current ? 'focusNext' : 'focusFirst'); } e.preventDefault(); } else if (key === keys.UP) { if (visible) { this._move(current ? 'focusPrev' : 'focusLast'); } e.preventDefault(); } else if (key === keys.ENTER || key === keys.TAB) { if (key === keys.ENTER && visible) { e.preventDefault(); } if (visible && current) { if (that.trigger('select', { item: current })) { return; } this._select(current); } this._blur(); } else if (key === keys.ESC) { if (visible) { e.preventDefault(); } that.close(); } else { that._search(); } }, _keypress: function () { this._oldText = this.element.val(); this._typing = true; }, _move: function (action) { this.listView[action](); if (this.options.suggest) { this.suggest(this.listView.focus()); } }, _hideBusy: function () { var that = this; clearTimeout(that._busy); that._loading.hide(); that.element.attr('aria-busy', false); that._busy = null; }, _showBusy: function () { var that = this; if (that._busy) { return; } that._busy = setTimeout(function () { that.element.attr('aria-busy', true); that._loading.show(); }, 100); }, _placeholder: function (show) { if (placeholderSupported) { return; } var that = this, element = that.element, placeholder = that.options.placeholder, value; if (placeholder) { value = element.val(); if (show === undefined) { show = !value; } if (!show) { if (value !== placeholder) { placeholder = value; } else { placeholder = ''; } } if (value === that._old && !show) { return; } element.toggleClass('k-readonly', show).val(placeholder); if (!placeholder && element[0] === document.activeElement) { caret(element[0], 0, 0); } } }, _search: function () { var that = this; clearTimeout(that._typingTimeout); that._typingTimeout = setTimeout(function () { if (that._prev !== that._accessor()) { that._prev = that._accessor(); that.search(); } }, that.options.delay); }, _select: function (candidate) { this._active = true; this.listView.select(candidate); this._active = false; }, _loader: function () { this._loading = $('<span class="k-icon k-loading" style="display:none"></span>').insertAfter(this.element); }, _toggleHover: function (e) { $(e.currentTarget).toggleClass(HOVER, e.type === 'mouseenter'); }, _wrapper: function () { var that = this, element = that.element, DOMelement = element[0], wrapper; wrapper = element.parent(); if (!wrapper.is('span.k-widget')) { wrapper = element.wrap('<span />').parent(); } wrapper.attr('tabindex', -1); wrapper.attr('role', 'presentation'); wrapper[0].style.cssText = DOMelement.style.cssText; element.css({ width: '100%', height: DOMelement.style.height }); that._focused = that.element; that.wrapper = wrapper.addClass('k-widget k-autocomplete k-header').addClass(DOMelement.className); } }); ui.plugin(AutoComplete); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.combobox', [ 'kendo.list', 'kendo.mobile.scroller' ], f); }(function () { var __meta__ = { id: 'combobox', name: 'ComboBox', category: 'web', description: 'The ComboBox widget allows the selection from pre-defined values or entering a new value.', depends: ['list'], features: [ { id: 'mobile-scroller', name: 'Mobile scroller', description: 'Support for kinetic scrolling in mobile device', depends: ['mobile.scroller'] }, { id: 'virtualization', name: 'VirtualList', description: 'Support for virtualization', depends: ['virtuallist'] } ] }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, List = ui.List, Select = ui.Select, caret = kendo.caret, support = kendo.support, placeholderSupported = support.placeholder, activeElement = kendo._activeElement, keys = kendo.keys, ns = '.kendoComboBox', CLICK = 'click' + ns, MOUSEDOWN = 'mousedown' + ns, DISABLED = 'disabled', READONLY = 'readonly', CHANGE = 'change', DEFAULT = 'k-state-default', FOCUSED = 'k-state-focused', STATEDISABLED = 'k-state-disabled', ARIA_DISABLED = 'aria-disabled', STATE_FILTER = 'filter', STATE_ACCEPT = 'accept', STATE_REBIND = 'rebind', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, proxy = $.proxy; var ComboBox = Select.extend({ init: function (element, options) { var that = this, text, disabled; that.ns = ns; options = $.isArray(options) ? { dataSource: options } : options; Select.fn.init.call(that, element, options); options = that.options; element = that.element.on('focus' + ns, proxy(that._focusHandler, that)); options.placeholder = options.placeholder || element.attr('placeholder'); that._reset(); that._wrapper(); that._input(); that._tabindex(that.input); that._popup(); that._dataSource(); that._ignoreCase(); that._enable(); that._oldIndex = that.selectedIndex = -1; that._aria(); that._initialIndex = options.index; that._initList(); that._cascade(); if (options.autoBind) { that._filterSource(); } else { text = options.text; if (!text && that._isSelect) { text = element.children(':selected').text(); } if (text) { that._setText(text); } } if (!text) { that._placeholder(); } disabled = $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } kendo.notify(that); }, options: { name: 'ComboBox', enabled: true, index: -1, text: null, value: null, autoBind: true, delay: 200, dataTextField: '', dataValueField: '', minLength: 0, height: 200, highlightFirst: true, filter: 'none', placeholder: '', suggest: false, cascadeFrom: '', cascadeFromField: '', ignoreCase: true, animation: {}, virtual: false, template: null, groupTemplate: '#:data#', fixedGroupTemplate: '#:data#' }, events: [ 'open', 'close', CHANGE, 'select', 'filtering', 'dataBinding', 'dataBound', 'cascade', 'set' ], setOptions: function (options) { Select.fn.setOptions.call(this, options); this.listView.setOptions(options); this._accessors(); this._aria(); }, destroy: function () { var that = this; that.input.off(ns); that.element.off(ns); that._inputWrapper.off(ns); clearTimeout(that._pasteTimeout); that._arrow.parent().off(CLICK + ' ' + MOUSEDOWN); Select.fn.destroy.call(that); }, _focusHandler: function () { this.input.focus(); }, _arrowClick: function () { this._toggle(); }, _inputFocus: function () { this._inputWrapper.addClass(FOCUSED); this._placeholder(false); }, _inputFocusout: function () { var that = this; var value = that.value(); that._inputWrapper.removeClass(FOCUSED); clearTimeout(that._typingTimeout); that._typingTimeout = null; that.text(that.text()); if (value !== that.value() && that.trigger('select', { item: that._focus() })) { that.value(value); return; } that._placeholder(); that._blur(); that.element.blur(); }, _inputPaste: function () { var that = this; clearTimeout(that._pasteTimeout); that._pasteTimeout = null; that._pasteTimeout = setTimeout(function () { that.search(); }); }, _editable: function (options) { var that = this, disable = options.disable, readonly = options.readonly, wrapper = that._inputWrapper.off(ns), input = that.element.add(that.input.off(ns)), arrow = that._arrow.parent().off(CLICK + ' ' + MOUSEDOWN); if (!readonly && !disable) { wrapper.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); input.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false); arrow.on(CLICK, proxy(that._arrowClick, that)).on(MOUSEDOWN, function (e) { e.preventDefault(); }); that.input.on('keydown' + ns, proxy(that._keydown, that)).on('focus' + ns, proxy(that._inputFocus, that)).on('focusout' + ns, proxy(that._inputFocusout, that)).on('paste' + ns, proxy(that._inputPaste, that)); } else { wrapper.addClass(disable ? STATEDISABLED : DEFAULT).removeClass(disable ? DEFAULT : STATEDISABLED); input.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable); } }, open: function () { var that = this; var state = that._state; if (that.popup.visible()) { return; } if (!that.listView.bound() && state !== STATE_FILTER || state === STATE_ACCEPT) { that._open = true; that._state = STATE_REBIND; that._filterSource(); } else { that.popup.open(); that._focusItem(); } }, _updateSelectionState: function () { var that = this; var text = that.options.text; var value = that.options.value; if (that.listView.isFiltered()) { return; } if (that.selectedIndex === -1) { if (text === undefined || text === null) { text = value; } that._accessor(value); that.input.val(text || that.input.val()); that._placeholder(); } else if (that._oldIndex === -1) { that._oldIndex = that.selectedIndex; } }, _buildOptions: function (data) { var that = this; if (!that._isSelect) { return; } var custom = that._customOption; if (that._state === STATE_REBIND) { that._state = ''; } that._customOption = undefined; that._options(data, '', that.value()); if (custom && custom[0].selected) { that._custom(custom.val()); } }, _updateSelection: function () { var that = this; var listView = that.listView; var initialIndex = that._initialIndex; var hasInitialIndex = initialIndex !== null && initialIndex > -1; var filtered = that._state === STATE_FILTER; if (filtered) { $(listView.focus()).removeClass('k-state-selected'); return; } if (that._fetch) { return; } if (!listView.value().length) { if (hasInitialIndex) { that.select(initialIndex); } else if (that._accessor()) { listView.value(that._accessor()); } } that._initialIndex = null; var dataItem = listView.selectedDataItems()[0]; if (!dataItem) { return; } if (that._value(dataItem) !== that.value()) { that._custom(that._value(dataItem)); } if (that.text() && that.text() !== that._text(dataItem)) { that._selectValue(dataItem); } }, _updateItemFocus: function () { var listView = this.listView; if (!this.options.highlightFirst) { listView.focus(-1); } else if (!listView.focus() && !listView.focusIndex()) { listView.focus(0); } }, _listBound: function () { var that = this; var isActive = that.input[0] === activeElement(); var data = that.dataSource.flatView(); var skip = that.listView.skip(); var isFirstPage = skip === undefined || skip === 0; that._presetValue = false; that._resizePopup(); that.popup.position(); that._buildOptions(data); that._makeUnselectable(); that._updateSelection(); if (data.length && isFirstPage) { that._updateItemFocus(); if (that.options.suggest && isActive && that.input.val()) { that.suggest(data[0]); } } if (that._open) { that._open = false; if (that._typingTimeout && !isActive) { that.popup.close(); } else { that.toggle(!!data.length); } that._typingTimeout = null; } that._hideBusy(); that.trigger('dataBound'); }, _listChange: function () { this._selectValue(this.listView.selectedDataItems()[0]); if (this._presetValue) { this._oldIndex = this.selectedIndex; } }, _get: function (candidate) { var data, found, idx; if (typeof candidate === 'function') { data = this.dataSource.flatView(); for (idx = 0; idx < data.length; idx++) { if (candidate(data[idx])) { candidate = idx; found = true; break; } } if (!found) { candidate = -1; } } return candidate; }, _select: function (candidate, keepState) { candidate = this._get(candidate); if (candidate === -1) { this.input[0].value = ''; this._accessor(''); } this.listView.select(candidate); if (!keepState && this._state === STATE_FILTER) { this._state = STATE_ACCEPT; } }, _selectValue: function (dataItem) { var idx = this.listView.select(); var value = ''; var text = ''; idx = idx[idx.length - 1]; if (idx === undefined) { idx = -1; } this.selectedIndex = idx; if (idx === -1) { value = text = this.input[0].value; this.listView.focus(-1); } else { if (dataItem) { value = this._dataValue(dataItem); text = this._text(dataItem); } if (value === null) { value = ''; } } this._prev = this.input[0].value = text; this._accessor(value !== undefined ? value : text, idx); this._placeholder(); this._triggerCascade(); }, refresh: function () { this.listView.refresh(); }, suggest: function (word) { var that = this; var element = that.input[0]; var value = that.text(); var caretIdx = caret(element)[0]; var key = that._last; var idx; if (key == keys.BACKSPACE || key == keys.DELETE) { that._last = undefined; return; } word = word || ''; if (typeof word !== 'string') { if (word[0]) { word = that.dataSource.view()[List.inArray(word[0], that.ul[0])]; } word = word ? that._text(word) : ''; } if (caretIdx <= 0) { caretIdx = value.toLowerCase().indexOf(word.toLowerCase()) + 1; } if (word) { word = word.toString(); idx = word.toLowerCase().indexOf(value.toLowerCase()); if (idx > -1) { value += word.substring(idx + value.length); } } else { value = value.substring(0, caretIdx); } if (value.length !== caretIdx || !word) { element.value = value; if (element === activeElement()) { caret(element, caretIdx, value.length); } } }, text: function (text) { text = text === null ? '' : text; var that = this; var input = that.input[0]; var ignoreCase = that.options.ignoreCase; var loweredText = text; var dataItem; var value; if (text === undefined) { return input.value; } if (that.options.autoBind === false && !that.listView.bound()) { that._setText(text); return; } dataItem = that.dataItem(); if (dataItem && that._text(dataItem) === text) { value = that._value(dataItem); if (value === List.unifyType(that._old, typeof value)) { that._triggerCascade(); return; } } if (ignoreCase) { loweredText = loweredText.toLowerCase(); } that._select(function (data) { data = that._text(data); if (ignoreCase) { data = (data + '').toLowerCase(); } return data === loweredText; }); if (that.selectedIndex < 0) { that._accessor(text); input.value = text; that._triggerCascade(); } that._prev = input.value; }, toggle: function (toggle) { this._toggle(toggle, true); }, value: function (value) { var that = this; var options = that.options; var listView = that.listView; if (value === undefined) { value = that._accessor() || that.listView.value()[0]; return value === undefined || value === null ? '' : value; } that.trigger('set', { value: value }); if (value === options.value && that.input.val() === options.text) { return; } that._accessor(value); if (that._isFilterEnabled() && listView.bound() && listView.isFiltered()) { that._clearFilter(); } else { that._fetchData(); } listView.value(value).done(function () { if (that.selectedIndex === -1) { that._accessor(value); that.input.val(value); that._placeholder(true); } that._old = that._accessor(); that._oldIndex = that.selectedIndex; that._prev = that.input.val(); if (that._state === STATE_FILTER) { that._state = STATE_ACCEPT; } }); }, _click: function (e) { var item = e.item; e.preventDefault(); if (this.trigger('select', { item: item })) { this.close(); return; } this._userTriggered = true; this._select(item); this._blur(); }, _filter: function (word) { var that = this; var options = that.options; var dataSource = that.dataSource; var ignoreCase = options.ignoreCase; var predicate = function (dataItem) { var text = that._text(dataItem); if (text !== undefined) { text = text + ''; if (text !== '' && word === '') { return false; } if (ignoreCase) { text = text.toLowerCase(); } return text.indexOf(word) === 0; } }; if (ignoreCase) { word = word.toLowerCase(); } if (!that.ul[0].firstChild) { dataSource.one(CHANGE, function () { if (dataSource.view()[0]) { that.search(word); } }).fetch(); return; } this.listView.focus(this._get(predicate)); var current = this.listView.focus(); if (current) { if (options.suggest) { that.suggest(current); } this.open(); } if (this.options.highlightFirst && !word) { this.listView.focusFirst(); } }, _input: function () { var that = this, element = that.element.removeClass('k-input')[0], accessKey = element.accessKey, wrapper = that.wrapper, SELECTOR = 'input.k-input', name = element.name || '', input, maxLength; if (name) { name = 'name="' + name + '_input" '; } input = wrapper.find(SELECTOR); if (!input[0]) { wrapper.append('<span tabindex="-1" unselectable="on" class="k-dropdown-wrap k-state-default"><input ' + name + 'class="k-input" type="text" autocomplete="off"/><span tabindex="-1" unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-arrow-s">select</span></span></span>').append(that.element); input = wrapper.find(SELECTOR); } input[0].style.cssText = element.style.cssText; input[0].title = element.title; maxLength = parseInt(this.element.prop('maxlength') || this.element.attr('maxlength'), 10); if (maxLength > -1) { input[0].maxLength = maxLength; } input.addClass(element.className).val(this.options.text || element.value).css({ width: '100%', height: element.style.height }).attr({ 'role': 'combobox', 'aria-expanded': false }).show(); if (placeholderSupported) { input.attr('placeholder', that.options.placeholder); } if (accessKey) { element.accessKey = ''; input[0].accessKey = accessKey; } that._focused = that.input = input; that._inputWrapper = $(wrapper[0].firstChild); that._arrow = wrapper.find('.k-icon').attr({ 'role': 'button', 'tabIndex': -1 }); if (element.id) { that._arrow.attr('aria-controls', that.ul[0].id); } }, _keydown: function (e) { var that = this, key = e.keyCode; that._last = key; clearTimeout(that._typingTimeout); that._typingTimeout = null; if (key != keys.TAB && !that._move(e)) { that._search(); } }, _placeholder: function (show) { if (placeholderSupported) { return; } var that = this, input = that.input, placeholder = that.options.placeholder, value; if (placeholder) { value = that.value(); if (show === undefined) { show = !value; } input.toggleClass('k-readonly', show); if (!show) { if (!value) { placeholder = ''; } else { return; } } input.val(placeholder); if (!placeholder && input[0] === activeElement()) { caret(input[0], 0, 0); } } }, _search: function () { var that = this; that._typingTimeout = setTimeout(function () { var value = that.text(); if (that._prev !== value) { that._prev = value; if (that.options.filter === 'none') { that.listView.select(-1); } that.search(value); } that._typingTimeout = null; }, that.options.delay); }, _setText: function (text) { this.input.val(text); this._prev = text; }, _wrapper: function () { var that = this, element = that.element, wrapper = element.parent(); if (!wrapper.is('span.k-widget')) { wrapper = element.hide().wrap('<span />').parent(); wrapper[0].style.cssText = element[0].style.cssText; } that.wrapper = wrapper.addClass('k-widget k-combobox k-header').addClass(element[0].className).css('display', ''); }, _clearSelection: function (parent, isFiltered) { var that = this; var hasValue = parent.value(); var custom = hasValue && parent.selectedIndex === -1; if (this.selectedIndex == -1 && this.value()) { return; } if (isFiltered || !hasValue || custom) { that.options.value = ''; that.value(''); } }, _preselect: function (value, text) { this.input.val(text); this._accessor(value); this._old = this._accessor(); this._oldIndex = this.selectedIndex; this.listView.setValue(value); this._placeholder(); this._initialIndex = null; this._presetValue = true; } }); ui.plugin(ComboBox); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.dropdownlist', [ 'kendo.list', 'kendo.mobile.scroller' ], f); }(function () { var __meta__ = { id: 'dropdownlist', name: 'DropDownList', category: 'web', description: 'The DropDownList widget displays a list of values and allows the selection of a single value from the list.', depends: ['list'], features: [ { id: 'mobile-scroller', name: 'Mobile scroller', description: 'Support for kinetic scrolling in mobile device', depends: ['mobile.scroller'] }, { id: 'virtualization', name: 'VirtualList', description: 'Support for virtualization', depends: ['virtuallist'] } ] }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, List = ui.List, Select = ui.Select, support = kendo.support, activeElement = kendo._activeElement, ObservableObject = kendo.data.ObservableObject, keys = kendo.keys, ns = '.kendoDropDownList', DISABLED = 'disabled', READONLY = 'readonly', CHANGE = 'change', FOCUSED = 'k-state-focused', DEFAULT = 'k-state-default', STATEDISABLED = 'k-state-disabled', ARIA_DISABLED = 'aria-disabled', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, TABINDEX = 'tabindex', STATE_FILTER = 'filter', STATE_ACCEPT = 'accept', MSG_INVALID_OPTION_LABEL = 'The `optionLabel` option is not valid due to missing fields. Define a custom optionLabel as shown here http://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist#configuration-optionLabel', proxy = $.proxy; var DropDownList = Select.extend({ init: function (element, options) { var that = this; var index = options && options.index; var optionLabel, text, disabled; that.ns = ns; options = $.isArray(options) ? { dataSource: options } : options; Select.fn.init.call(that, element, options); options = that.options; element = that.element.on('focus' + ns, proxy(that._focusHandler, that)); that._focusInputHandler = $.proxy(that._focusInput, that); that.optionLabel = $(); that._optionLabel(); that._inputTemplate(); that._reset(); that._prev = ''; that._word = ''; that._wrapper(); that._tabindex(); that.wrapper.data(TABINDEX, that.wrapper.attr(TABINDEX)); that._span(); that._popup(); that._mobile(); that._dataSource(); that._ignoreCase(); that._filterHeader(); that._aria(); that._enable(); that._oldIndex = that.selectedIndex = -1; if (index !== undefined) { options.index = index; } that._initialIndex = options.index; that._initList(); that._cascade(); if (options.autoBind) { that.dataSource.fetch(); } else if (that.selectedIndex === -1) { text = options.text || ''; if (!text) { optionLabel = options.optionLabel; if (optionLabel && options.index === 0) { text = optionLabel; } else if (that._isSelect) { text = element.children(':selected').text(); } } that._textAccessor(text); } disabled = $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } that.listView.bind('click', function (e) { e.preventDefault(); }); kendo.notify(that); }, options: { name: 'DropDownList', enabled: true, autoBind: true, index: 0, text: null, value: null, delay: 500, height: 200, dataTextField: '', dataValueField: '', optionLabel: '', cascadeFrom: '', cascadeFromField: '', ignoreCase: true, animation: {}, filter: 'none', minLength: 1, virtual: false, template: null, valueTemplate: null, optionLabelTemplate: null, groupTemplate: '#:data#', fixedGroupTemplate: '#:data#' }, events: [ 'open', 'close', CHANGE, 'select', 'filtering', 'dataBinding', 'dataBound', 'cascade', 'set' ], setOptions: function (options) { Select.fn.setOptions.call(this, options); this.listView.setOptions(this._listOptions(options)); this._optionLabel(); this._inputTemplate(); this._accessors(); this._filterHeader(); this._enable(); this._aria(); if (!this.value() && this.hasOptionLabel()) { this.select(0); } }, destroy: function () { var that = this; Select.fn.destroy.call(that); that.wrapper.off(ns); that.element.off(ns); that._inputWrapper.off(ns); that._arrow.off(); that._arrow = null; that.optionLabel.off(); }, open: function () { var that = this; if (that.popup.visible()) { return; } if (!that.listView.bound() || that._state === STATE_ACCEPT) { that._open = true; that._state = 'rebind'; if (that.filterInput) { that.filterInput.val(''); that._prev = ''; } that._filterSource(); } else if (that._allowOpening()) { that.popup.one('activate', that._focusInputHandler); that.popup.open(); that._focusItem(); } }, _focusInput: function () { this._focusElement(this.filterInput); }, _allowOpening: function () { return this.hasOptionLabel() || this.filterInput || this.dataSource.view().length; }, toggle: function (toggle) { this._toggle(toggle, true); }, current: function (candidate) { var current; if (candidate === undefined) { current = this.listView.focus(); if (!current && this.selectedIndex === 0 && this.hasOptionLabel()) { return this.optionLabel; } return current; } this._focus(candidate); }, dataItem: function (index) { var that = this; var dataItem = null; if (index === null) { return index; } if (index === undefined) { dataItem = that.listView.selectedDataItems()[0]; } else { if (typeof index !== 'number') { if (that.options.virtual) { return that.dataSource.getByUid($(index).data('uid')); } if (index.hasClass('k-list-optionlabel')) { index = -1; } else { index = $(that.items()).index(index); } } else if (that.hasOptionLabel()) { index -= 1; } dataItem = that.dataSource.flatView()[index]; } if (!dataItem) { dataItem = that._optionLabelDataItem(); } return dataItem; }, refresh: function () { this.listView.refresh(); }, text: function (text) { var that = this; var dataItem, loweredText; var ignoreCase = that.options.ignoreCase; text = text === null ? '' : text; if (text !== undefined) { if (typeof text === 'string') { loweredText = ignoreCase ? text.toLowerCase() : text; that._select(function (data) { data = that._text(data); if (ignoreCase) { data = (data + '').toLowerCase(); } return data === loweredText; }); dataItem = that.dataItem(); if (dataItem) { text = dataItem; } } that._textAccessor(text); } else { return that._textAccessor(); } }, value: function (value) { var that = this; var listView = that.listView; var dataSource = that.dataSource; if (value === undefined) { value = that._accessor() || that.listView.value()[0]; return value === undefined || value === null ? '' : value; } if (value || !that.hasOptionLabel()) { that._initialIndex = null; } this.trigger('set', { value: value }); if (that._request && that.options.cascadeFrom && that.listView.bound()) { if (that._valueSetter) { dataSource.unbind(CHANGE, that._valueSetter); } that._valueSetter = proxy(function () { that.value(value); }, that); dataSource.one(CHANGE, that._valueSetter); return; } if (that._isFilterEnabled() && listView.bound() && listView.isFiltered()) { that._clearFilter(); } else { that._fetchData(); } listView.value(value).done(function () { if (that.selectedIndex === -1 && that.text()) { that.text(''); that._accessor('', -1); } that._old = that._accessor(); that._oldIndex = that.selectedIndex; }); }, hasOptionLabel: function () { return this.optionLabel && !!this.optionLabel[0]; }, _optionLabel: function () { var that = this; var options = that.options; var optionLabel = options.optionLabel; var template = options.optionLabelTemplate; if (!optionLabel) { that.optionLabel.off().remove(); that.optionLabel = $(); return; } if (!template) { template = '#:'; if (typeof optionLabel === 'string') { template += 'data'; } else { template += kendo.expr(options.dataTextField, 'data'); } template += '#'; } if (typeof template !== 'function') { template = kendo.template(template); } that.optionLabelTemplate = template; if (!that.hasOptionLabel()) { that.optionLabel = $('<div class="k-list-optionlabel"></div>').prependTo(that.list); } that.optionLabel.html(template(optionLabel)).off().click(proxy(that._click, that)).on(HOVEREVENTS, that._toggleHover); that.angular('compile', function () { return { elements: that.optionLabel, data: [{ dataItem: that._optionLabelDataItem() }] }; }); }, _optionLabelText: function () { var optionLabel = this.options.optionLabel; return typeof optionLabel === 'string' ? optionLabel : this._text(optionLabel); }, _optionLabelDataItem: function () { var that = this; var optionLabel = that.options.optionLabel; if (that.hasOptionLabel()) { return $.isPlainObject(optionLabel) ? new ObservableObject(optionLabel) : that._assignInstance(that._optionLabelText(), ''); } return null; }, _buildOptions: function (data) { var that = this; if (!that._isSelect) { return; } var value = that.listView.value()[0]; var optionLabel = that._optionLabelDataItem(); var optionLabelValue = optionLabel && that._value(optionLabel); if (value === undefined || value === null) { value = ''; } if (optionLabel) { if (optionLabelValue === undefined || optionLabelValue === null) { optionLabelValue = ''; } optionLabel = '<option value="' + optionLabelValue + '">' + that._text(optionLabel) + '</option>'; } that._options(data, optionLabel, value); if (value !== List.unifyType(that._accessor(), typeof value)) { that._customOption = null; that._custom(value); } }, _listBound: function () { var that = this; var initialIndex = that._initialIndex; var filtered = that._state === STATE_FILTER; var data = that.dataSource.flatView(); var dataItem; that._presetValue = false; that._resizePopup(true); that.popup.position(); that._buildOptions(data); that._makeUnselectable(); if (!filtered) { if (that._open) { that.toggle(that._allowOpening()); } that._open = false; if (!that._fetch) { if (data.length) { if (!that.listView.value().length && initialIndex > -1 && initialIndex !== null) { that.select(initialIndex); } that._initialIndex = null; dataItem = that.listView.selectedDataItems()[0]; if (dataItem && that.text() !== that._text(dataItem)) { that._selectValue(dataItem); } } else if (that._textAccessor() !== that._optionLabelText()) { that.listView.value(''); that._selectValue(null); that._oldIndex = that.selectedIndex; } } } that._hideBusy(); that.trigger('dataBound'); }, _listChange: function () { this._selectValue(this.listView.selectedDataItems()[0]); if (this._presetValue || this._old && this._oldIndex === -1) { this._oldIndex = this.selectedIndex; } }, _filterPaste: function () { this._search(); }, _focusHandler: function () { this.wrapper.focus(); }, _focusinHandler: function () { this._inputWrapper.addClass(FOCUSED); this._prevent = false; }, _focusoutHandler: function () { var that = this; var filtered = that._state === STATE_FILTER; var isIFrame = window.self !== window.top; var focusedItem = that._focus(); if (!that._prevent) { clearTimeout(that._typingTimeout); if (filtered && focusedItem && !that.trigger('select', { item: focusedItem })) { that._select(focusedItem, !that.dataSource.view().length); } if (support.mobileOS.ios && isIFrame) { that._change(); } else { that._blur(); } that._inputWrapper.removeClass(FOCUSED); that._prevent = true; that._open = false; that.element.blur(); } }, _wrapperMousedown: function () { this._prevent = !!this.filterInput; }, _wrapperClick: function (e) { e.preventDefault(); this.popup.unbind('activate', this._focusInputHandler); this._focused = this.wrapper; this._toggle(); }, _editable: function (options) { var that = this; var element = that.element; var disable = options.disable; var readonly = options.readonly; var wrapper = that.wrapper.add(that.filterInput).off(ns); var dropDownWrapper = that._inputWrapper.off(HOVEREVENTS); if (!readonly && !disable) { element.removeAttr(DISABLED).removeAttr(READONLY); dropDownWrapper.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); wrapper.attr(TABINDEX, wrapper.data(TABINDEX)).attr(ARIA_DISABLED, false).on('keydown' + ns, proxy(that._keydown, that)).on('focusin' + ns, proxy(that._focusinHandler, that)).on('focusout' + ns, proxy(that._focusoutHandler, that)).on('mousedown' + ns, proxy(that._wrapperMousedown, that)).on('paste' + ns, proxy(that._filterPaste, that)); that.wrapper.on('click' + ns, proxy(that._wrapperClick, that)); if (!that.filterInput) { wrapper.on('keypress' + ns, proxy(that._keypress, that)); } } else if (disable) { wrapper.removeAttr(TABINDEX); dropDownWrapper.addClass(STATEDISABLED).removeClass(DEFAULT); } else { dropDownWrapper.addClass(DEFAULT).removeClass(STATEDISABLED); wrapper.on('focusin' + ns, proxy(that._focusinHandler, that)).on('focusout' + ns, proxy(that._focusoutHandler, that)); } element.attr(DISABLED, disable).attr(READONLY, readonly); wrapper.attr(ARIA_DISABLED, disable); }, _keydown: function (e) { var that = this; var key = e.keyCode; var altKey = e.altKey; var isInputActive; var handled; var isPopupVisible = that.popup.visible(); if (that.filterInput) { isInputActive = that.filterInput[0] === activeElement(); } if (key === keys.LEFT) { key = keys.UP; handled = true; } else if (key === keys.RIGHT) { key = keys.DOWN; handled = true; } if (handled && isInputActive) { return; } e.keyCode = key; if (altKey && key === keys.UP || key === keys.ESC) { that._focusElement(that.wrapper); } if (key === keys.ENTER && that._typingTimeout && that.filterInput && isPopupVisible) { e.preventDefault(); return; } handled = that._move(e); if (handled) { return; } if (!isPopupVisible || !that.filterInput) { var current = that._focus(); if (key === keys.HOME) { handled = true; that._firstItem(); } else if (key === keys.END) { handled = true; that._lastItem(); } if (handled) { if (that.trigger('select', { item: that._focus() })) { that._focus(current); return; } that._select(that._focus(), true); if (!isPopupVisible) { that._blur(); } } } if (!altKey && !handled && that.filterInput) { that._search(); } }, _matchText: function (text, word) { var ignoreCase = this.options.ignoreCase; if (text === undefined || text === null) { return false; } text = text + ''; if (ignoreCase) { text = text.toLowerCase(); } return text.indexOf(word) === 0; }, _shuffleData: function (data, splitIndex) { var optionDataItem = this._optionLabelDataItem(); if (optionDataItem) { data = [optionDataItem].concat(data); } return data.slice(splitIndex).concat(data.slice(0, splitIndex)); }, _selectNext: function () { var that = this; var data = that.dataSource.flatView(); var dataLength = data.length + (that.hasOptionLabel() ? 1 : 0); var isInLoop = sameCharsOnly(that._word, that._last); var startIndex = that.selectedIndex; var oldFocusedItem; var text; if (startIndex === -1) { startIndex = 0; } else { startIndex += isInLoop ? 1 : 0; startIndex = normalizeIndex(startIndex, dataLength); } data = data.toJSON ? data.toJSON() : data.slice(); data = that._shuffleData(data, startIndex); for (var idx = 0; idx < dataLength; idx++) { text = that._text(data[idx]); if (isInLoop && that._matchText(text, that._last)) { break; } else if (that._matchText(text, that._word)) { break; } } if (idx !== dataLength) { oldFocusedItem = that._focus(); that._select(normalizeIndex(startIndex + idx, dataLength)); if (that.trigger('select', { item: that._focus() })) { that._select(oldFocusedItem); } if (!that.popup.visible()) { that._change(); } } }, _keypress: function (e) { var that = this; if (e.which === 0 || e.keyCode === kendo.keys.ENTER) { return; } var character = String.fromCharCode(e.charCode || e.keyCode); if (that.options.ignoreCase) { character = character.toLowerCase(); } if (character === ' ') { e.preventDefault(); } that._word += character; that._last = character; that._search(); }, _popupOpen: function () { var popup = this.popup; popup.wrapper = kendo.wrap(popup.element); if (popup.element.closest('.km-root')[0]) { popup.wrapper.addClass('km-popup km-widget'); this.wrapper.addClass('km-widget'); } }, _popup: function () { Select.fn._popup.call(this); this.popup.one('open', proxy(this._popupOpen, this)); }, _click: function (e) { var item = e.item || $(e.currentTarget); e.preventDefault(); if (this.trigger('select', { item: item })) { this.close(); return; } this._userTriggered = true; this._select(item); this._focusElement(this.wrapper); this._blur(); }, _focusElement: function (element) { var active = activeElement(); var wrapper = this.wrapper; var filterInput = this.filterInput; var compareElement = element === filterInput ? wrapper : filterInput; var touchEnabled = support.mobileOS && (support.touch || support.MSPointers || support.pointers); if (filterInput && filterInput[0] === element[0] && touchEnabled) { return; } if (filterInput && compareElement[0] === active) { this._prevent = true; this._focused = element.focus(); } }, _filter: function (word) { if (word) { var that = this; var ignoreCase = that.options.ignoreCase; if (ignoreCase) { word = word.toLowerCase(); } that._select(function (dataItem) { return that._matchText(that._text(dataItem), word); }); } }, _search: function () { var that = this; var dataSource = that.dataSource; clearTimeout(that._typingTimeout); if (that._isFilterEnabled()) { that._typingTimeout = setTimeout(function () { var value = that.filterInput.val(); if (that._prev !== value) { that._prev = value; that.search(value); } that._typingTimeout = null; }, that.options.delay); } else { that._typingTimeout = setTimeout(function () { that._word = ''; }, that.options.delay); if (!that.listView.bound()) { dataSource.fetch().done(function () { that._selectNext(); }); return; } that._selectNext(); } }, _get: function (candidate) { var data, found, idx; var isFunction = typeof candidate === 'function'; var jQueryCandidate = !isFunction ? $(candidate) : $(); if (this.hasOptionLabel()) { if (typeof candidate === 'number') { if (candidate > -1) { candidate -= 1; } } else if (jQueryCandidate.hasClass('k-list-optionlabel')) { candidate = -1; } } if (isFunction) { data = this.dataSource.flatView(); for (idx = 0; idx < data.length; idx++) { if (candidate(data[idx])) { candidate = idx; found = true; break; } } if (!found) { candidate = -1; } } return candidate; }, _firstItem: function () { if (this.hasOptionLabel()) { this._focus(this.optionLabel); } else { this.listView.focusFirst(); } }, _lastItem: function () { this._resetOptionLabel(); this.listView.focusLast(); }, _nextItem: function () { if (this.optionLabel.hasClass('k-state-focused')) { this._resetOptionLabel(); this.listView.focusFirst(); } else { this.listView.focusNext(); } }, _prevItem: function () { if (this.optionLabel.hasClass('k-state-focused')) { return; } this.listView.focusPrev(); if (!this.listView.focus()) { this._focus(this.optionLabel); } }, _focusItem: function () { var listView = this.listView; var focusedItem = listView.focus(); var index = listView.select(); index = index[index.length - 1]; if (index === undefined && this.options.highlightFirst && !focusedItem) { index = 0; } if (index !== undefined) { listView.focus(index); } else { if (this.options.optionLabel) { this._focus(this.optionLabel); this._select(this.optionLabel); } else { listView.scrollToIndex(0); } } }, _resetOptionLabel: function (additionalClass) { this.optionLabel.removeClass('k-state-focused' + (additionalClass || '')).removeAttr('id'); }, _focus: function (candidate) { var listView = this.listView; var optionLabel = this.optionLabel; if (candidate === undefined) { candidate = listView.focus(); if (!candidate && optionLabel.hasClass('k-state-focused')) { candidate = optionLabel; } return candidate; } this._resetOptionLabel(); candidate = this._get(candidate); listView.focus(candidate); if (candidate === -1) { optionLabel.addClass('k-state-focused').attr('id', listView._optionID); this._focused.add(this.filterInput).removeAttr('aria-activedescendant').attr('aria-activedescendant', listView._optionID); } }, _select: function (candidate, keepState) { var that = this; candidate = that._get(candidate); that.listView.select(candidate); if (!keepState && that._state === STATE_FILTER) { that._state = STATE_ACCEPT; } if (candidate === -1) { that._selectValue(null); } }, _selectValue: function (dataItem) { var that = this; var optionLabel = that.options.optionLabel; var idx = that.listView.select(); var value = ''; var text = ''; idx = idx[idx.length - 1]; if (idx === undefined) { idx = -1; } this._resetOptionLabel(' k-state-selected'); if (dataItem) { text = dataItem; value = that._dataValue(dataItem); if (optionLabel) { idx += 1; } } else if (optionLabel) { that._focus(that.optionLabel.addClass('k-state-selected')); text = that._optionLabelText(); if (typeof optionLabel === 'string') { value = ''; } else { value = that._value(optionLabel); } idx = 0; } that.selectedIndex = idx; if (value === null) { value = ''; } that._textAccessor(text); that._accessor(value, idx); that._triggerCascade(); }, _mobile: function () { var that = this, popup = that.popup, mobileOS = support.mobileOS, root = popup.element.parents('.km-root').eq(0); if (root.length && mobileOS) { popup.options.animation.open.effects = mobileOS.android || mobileOS.meego ? 'fadeIn' : mobileOS.ios || mobileOS.wp ? 'slideIn:up' : popup.options.animation.open.effects; } }, _filterHeader: function () { var icon; if (this.filterInput) { this.filterInput.off(ns).parent().remove(); this.filterInput = null; } if (this._isFilterEnabled()) { icon = '<span unselectable="on" class="k-icon k-i-search">select</span>'; this.filterInput = $('<input class="k-textbox"/>').attr({ placeholder: this.element.attr('placeholder'), title: this.element.attr('title'), role: 'listbox', 'aria-haspopup': true, 'aria-expanded': false }); this.list.prepend($('<span class="k-list-filter" />').append(this.filterInput.add(icon))); } }, _span: function () { var that = this, wrapper = that.wrapper, SELECTOR = 'span.k-input', span; span = wrapper.find(SELECTOR); if (!span[0]) { wrapper.append('<span unselectable="on" class="k-dropdown-wrap k-state-default"><span unselectable="on" class="k-input"> </span><span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-arrow-s">select</span></span></span>').append(that.element); span = wrapper.find(SELECTOR); } that.span = span; that._inputWrapper = $(wrapper[0].firstChild); that._arrow = wrapper.find('.k-icon'); }, _wrapper: function () { var that = this, element = that.element, DOMelement = element[0], wrapper; wrapper = element.parent(); if (!wrapper.is('span.k-widget')) { wrapper = element.wrap('<span />').parent(); wrapper[0].style.cssText = DOMelement.style.cssText; wrapper[0].title = DOMelement.title; } element.hide(); that._focused = that.wrapper = wrapper.addClass('k-widget k-dropdown k-header').addClass(DOMelement.className).css('display', '').attr({ accesskey: element.attr('accesskey'), unselectable: 'on', role: 'listbox', 'aria-haspopup': true, 'aria-expanded': false }); }, _clearSelection: function (parent) { this.select(parent.value() ? 0 : -1); }, _inputTemplate: function () { var that = this, template = that.options.valueTemplate; if (!template) { template = $.proxy(kendo.template('#:this._text(data)#', { useWithBlock: false }), that); } else { template = kendo.template(template); } that.valueTemplate = template; if (that.hasOptionLabel() && !that.options.optionLabelTemplate) { try { that.valueTemplate(that._optionLabelDataItem()); } catch (e) { throw new Error(MSG_INVALID_OPTION_LABEL); } } }, _textAccessor: function (text) { var dataItem = null; var template = this.valueTemplate; var optionLabelText = this._optionLabelText(); var span = this.span; if (text === undefined) { return span.text(); } if ($.isPlainObject(text) || text instanceof ObservableObject) { dataItem = text; } else if (optionLabelText && optionLabelText === text) { dataItem = this.options.optionLabel; } if (!dataItem) { dataItem = this._assignInstance(text, this._accessor()); } if (dataItem === optionLabelText || this._text(dataItem) === optionLabelText) { template = this.optionLabelTemplate; } var getElements = function () { return { elements: span.get(), data: [{ dataItem: dataItem }] }; }; this.angular('cleanup', getElements); try { span.html(template(dataItem)); } catch (e) { span.html(''); } this.angular('compile', getElements); }, _preselect: function (value, text) { if (!value && !text) { text = this._optionLabelText(); } this._accessor(value); this._textAccessor(text); this._old = this._accessor(); this._oldIndex = this.selectedIndex; this.listView.setValue(value); this._initialIndex = null; this._presetValue = true; }, _assignInstance: function (text, value) { var dataTextField = this.options.dataTextField; var dataItem = {}; if (dataTextField) { assign(dataItem, dataTextField.split('.'), text); assign(dataItem, this.options.dataValueField.split('.'), value); dataItem = new ObservableObject(dataItem); } else { dataItem = text; } return dataItem; } }); function assign(instance, fields, value) { var idx = 0, lastIndex = fields.length - 1, field; for (; idx < lastIndex; ++idx) { field = fields[idx]; if (!(field in instance)) { instance[field] = {}; } instance = instance[field]; } instance[fields[lastIndex]] = value; } function normalizeIndex(index, length) { if (index >= length) { index -= length; } return index; } function sameCharsOnly(word, character) { for (var idx = 0; idx < word.length; idx++) { if (word.charAt(idx) !== character) { return false; } } return true; } ui.plugin(DropDownList); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.colorpicker', [ 'kendo.core', 'kendo.color', 'kendo.popup', 'kendo.slider', 'kendo.userevents' ], f); }(function () { var __meta__ = { id: 'colorpicker', name: 'Color tools', category: 'web', description: 'Color selection widgets', depends: [ 'core', 'color', 'popup', 'slider', 'userevents' ] }; (function ($, parseInt, undefined) { var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, parseColor = kendo.parseColor, Color = kendo.Color, KEYS = kendo.keys, BACKGROUNDCOLOR = 'background-color', ITEMSELECTEDCLASS = 'k-state-selected', SIMPLEPALETTE = '000000,7f7f7f,880015,ed1c24,ff7f27,fff200,22b14c,00a2e8,3f48cc,a349a4,ffffff,c3c3c3,b97a57,ffaec9,ffc90e,efe4b0,b5e61d,99d9ea,7092be,c8bfe7', WEBPALETTE = 'FFFFFF,FFCCFF,FF99FF,FF66FF,FF33FF,FF00FF,CCFFFF,CCCCFF,CC99FF,CC66FF,CC33FF,CC00FF,99FFFF,99CCFF,9999FF,9966FF,9933FF,9900FF,FFFFCC,FFCCCC,FF99CC,FF66CC,FF33CC,FF00CC,CCFFCC,CCCCCC,CC99CC,CC66CC,CC33CC,CC00CC,99FFCC,99CCCC,9999CC,9966CC,9933CC,9900CC,FFFF99,FFCC99,FF9999,FF6699,FF3399,FF0099,CCFF99,CCCC99,CC9999,CC6699,CC3399,CC0099,99FF99,99CC99,999999,996699,993399,990099,FFFF66,FFCC66,FF9966,FF6666,FF3366,FF0066,CCFF66,CCCC66,CC9966,CC6666,CC3366,CC0066,99FF66,99CC66,999966,996666,993366,990066,FFFF33,FFCC33,FF9933,FF6633,FF3333,FF0033,CCFF33,CCCC33,CC9933,CC6633,CC3333,CC0033,99FF33,99CC33,999933,996633,993333,990033,FFFF00,FFCC00,FF9900,FF6600,FF3300,FF0000,CCFF00,CCCC00,CC9900,CC6600,CC3300,CC0000,99FF00,99CC00,999900,996600,993300,990000,66FFFF,66CCFF,6699FF,6666FF,6633FF,6600FF,33FFFF,33CCFF,3399FF,3366FF,3333FF,3300FF,00FFFF,00CCFF,0099FF,0066FF,0033FF,0000FF,66FFCC,66CCCC,6699CC,6666CC,6633CC,6600CC,33FFCC,33CCCC,3399CC,3366CC,3333CC,3300CC,00FFCC,00CCCC,0099CC,0066CC,0033CC,0000CC,66FF99,66CC99,669999,666699,663399,660099,33FF99,33CC99,339999,336699,333399,330099,00FF99,00CC99,009999,006699,003399,000099,66FF66,66CC66,669966,666666,663366,660066,33FF66,33CC66,339966,336666,333366,330066,00FF66,00CC66,009966,006666,003366,000066,66FF33,66CC33,669933,666633,663333,660033,33FF33,33CC33,339933,336633,333333,330033,00FF33,00CC33,009933,006633,003333,000033,66FF00,66CC00,669900,666600,663300,660000,33FF00,33CC00,339900,336600,333300,330000,00FF00,00CC00,009900,006600,003300,000000', APPLY_CANCEL = { apply: 'Apply', cancel: 'Cancel' }, NS = '.kendoColorTools', CLICK_NS = 'click' + NS, KEYDOWN_NS = 'keydown' + NS, browser = kendo.support.browser, isIE8 = browser.msie && browser.version < 9; var ColorSelector = Widget.extend({ init: function (element, options) { var that = this, ariaId; Widget.fn.init.call(that, element, options); element = that.element; options = that.options; that._value = options.value = parseColor(options.value); that._tabIndex = element.attr('tabIndex') || 0; ariaId = that._ariaId = options.ariaId; if (ariaId) { element.attr('aria-labelledby', ariaId); } if (options._standalone) { that._triggerSelect = that._triggerChange; } }, options: { name: 'ColorSelector', value: null, _standalone: true }, events: [ 'change', 'select', 'cancel' ], color: function (value) { if (value !== undefined) { this._value = parseColor(value); this._updateUI(this._value); } return this._value; }, value: function (color) { color = this.color(color); if (color) { if (this.options.opacity) { color = color.toCssRgba(); } else { color = color.toCss(); } } return color || null; }, enable: function (enable) { if (arguments.length === 0) { enable = true; } $('.k-disabled-overlay', this.wrapper).remove(); if (!enable) { this.wrapper.append('<div class=\'k-disabled-overlay\'></div>'); } this._onEnable(enable); }, _select: function (color, nohooks) { var prev = this._value; color = this.color(color); if (!nohooks) { this.element.trigger('change'); if (!color.equals(prev)) { this.trigger('change', { value: this.value() }); } else if (!this._standalone) { this.trigger('cancel'); } } }, _triggerSelect: function (color) { triggerEvent(this, 'select', color); }, _triggerChange: function (color) { triggerEvent(this, 'change', color); }, destroy: function () { if (this.element) { this.element.off(NS); } if (this.wrapper) { this.wrapper.off(NS).find('*').off(NS); } this.wrapper = null; Widget.fn.destroy.call(this); }, _updateUI: $.noop, _selectOnHide: function () { return null; }, _cancel: function () { this.trigger('cancel'); } }); function triggerEvent(self, type, color) { color = parseColor(color); if (color && !color.equals(self.color())) { if (type == 'change') { self._value = color; } if (color.a != 1) { color = color.toCssRgba(); } else { color = color.toCss(); } self.trigger(type, { value: color }); } } var ColorPalette = ColorSelector.extend({ init: function (element, options) { var that = this; ColorSelector.fn.init.call(that, element, options); element = that.wrapper = that.element; options = that.options; var colors = options.palette; if (colors == 'websafe') { colors = WEBPALETTE; options.columns = 18; } else if (colors == 'basic') { colors = SIMPLEPALETTE; } if (typeof colors == 'string') { colors = colors.split(','); } if ($.isArray(colors)) { colors = $.map(colors, function (x) { return parseColor(x); }); } that._selectedID = (options.ariaId || kendo.guid()) + '_selected'; element.addClass('k-widget k-colorpalette').attr('role', 'grid').attr('aria-readonly', 'true').append($(that._template({ colors: colors, columns: options.columns, tileSize: options.tileSize, value: that._value, id: options.ariaId }))).on(CLICK_NS, '.k-item', function (ev) { that._select($(ev.currentTarget).css(BACKGROUNDCOLOR)); }).attr('tabIndex', that._tabIndex).on(KEYDOWN_NS, bind(that._keydown, that)); var tileSize = options.tileSize, width, height; if (tileSize) { if (/number|string/.test(typeof tileSize)) { width = height = parseFloat(tileSize); } else if (typeof tileSize == 'object') { width = parseFloat(tileSize.width); height = parseFloat(tileSize.height); } else { throw new Error('Unsupported value for the \'tileSize\' argument'); } element.find('.k-item').css({ width: width, height: height }); } }, focus: function () { this.wrapper.focus(); }, options: { name: 'ColorPalette', columns: 10, tileSize: null, palette: 'basic' }, _onEnable: function (enable) { if (enable) { this.wrapper.attr('tabIndex', this._tabIndex); } else { this.wrapper.removeAttr('tabIndex'); } }, _keydown: function (e) { var selected, wrapper = this.wrapper, items = wrapper.find('.k-item'), current = items.filter('.' + ITEMSELECTEDCLASS).get(0), keyCode = e.keyCode; if (keyCode == KEYS.LEFT) { selected = relative(items, current, -1); } else if (keyCode == KEYS.RIGHT) { selected = relative(items, current, 1); } else if (keyCode == KEYS.DOWN) { selected = relative(items, current, this.options.columns); } else if (keyCode == KEYS.UP) { selected = relative(items, current, -this.options.columns); } else if (keyCode == KEYS.ENTER) { preventDefault(e); if (current) { this._select($(current).css(BACKGROUNDCOLOR)); } } else if (keyCode == KEYS.ESC) { this._cancel(); } if (selected) { preventDefault(e); this._current(selected); try { var color = parseColor(selected.css(BACKGROUNDCOLOR)); this._triggerSelect(color); } catch (ex) { } } }, _current: function (item) { this.wrapper.find('.' + ITEMSELECTEDCLASS).removeClass(ITEMSELECTEDCLASS).attr('aria-selected', false).removeAttr('id'); $(item).addClass(ITEMSELECTEDCLASS).attr('aria-selected', true).attr('id', this._selectedID); this.element.removeAttr('aria-activedescendant').attr('aria-activedescendant', this._selectedID); }, _updateUI: function (color) { var item = null; this.wrapper.find('.k-item').each(function () { var c = parseColor($(this).css(BACKGROUNDCOLOR)); if (c && c.equals(color)) { item = this; return false; } }); this._current(item); }, _template: kendo.template('<table class="k-palette k-reset" role="presentation"><tr role="row">' + '# for (var i = 0; i < colors.length; ++i) { #' + '# var selected = colors[i].equals(value); #' + '# if (i && i % columns == 0) { # </tr><tr role="row"> # } #' + '<td role="gridcell" unselectable="on" style="background-color:#= colors[i].toCss() #"' + '#= selected ? " aria-selected=true" : "" # ' + '#=(id && i === 0) ? "id=\\""+id+"\\" " : "" # ' + 'class="k-item#= selected ? " ' + ITEMSELECTEDCLASS + '" : "" #" ' + 'aria-label="#= colors[i].toCss() #"></td>' + '# } #' + '</tr></table>') }); var FlatColorPicker = ColorSelector.extend({ init: function (element, options) { var that = this; ColorSelector.fn.init.call(that, element, options); options = that.options; element = that.element; that.wrapper = element.addClass('k-widget k-flatcolorpicker').append(that._template(options)); that._hueElements = $('.k-hsv-rectangle, .k-transparency-slider .k-slider-track', element); that._selectedColor = $('.k-selected-color-display', element); that._colorAsText = $('input.k-color-value', element); that._sliders(); that._hsvArea(); that._updateUI(that._value || parseColor('#f00')); element.find('input.k-color-value').on(KEYDOWN_NS, function (ev) { var input = this; if (ev.keyCode == KEYS.ENTER) { try { var color = parseColor(input.value); var val = that.color(); that._select(color, color.equals(val)); } catch (ex) { $(input).addClass('k-state-error'); } } else if (that.options.autoupdate) { setTimeout(function () { var color = parseColor(input.value, true); if (color) { that._updateUI(color, true); } }, 10); } }).end().on(CLICK_NS, '.k-controls button.apply', function () { that._select(that._getHSV()); }).on(CLICK_NS, '.k-controls button.cancel', function () { that._updateUI(that.color()); that._cancel(); }); if (isIE8) { that._applyIEFilter(); } }, destroy: function () { this._hueSlider.destroy(); if (this._opacitySlider) { this._opacitySlider.destroy(); } this._hueSlider = this._opacitySlider = this._hsvRect = this._hsvHandle = this._hueElements = this._selectedColor = this._colorAsText = null; ColorSelector.fn.destroy.call(this); }, options: { name: 'FlatColorPicker', opacity: false, buttons: false, input: true, preview: true, autoupdate: true, messages: APPLY_CANCEL }, _applyIEFilter: function () { var track = this.element.find('.k-hue-slider .k-slider-track')[0], url = track.currentStyle.backgroundImage; url = url.replace(/^url\([\'\"]?|[\'\"]?\)$/g, ''); track.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + url + '\', sizingMethod=\'scale\')'; }, _sliders: function () { var that = this, element = that.element; function hueChange(e) { that._updateUI(that._getHSV(e.value, null, null, null)); } that._hueSlider = element.find('.k-hue-slider').kendoSlider({ min: 0, max: 359, tickPlacement: 'none', showButtons: false, slide: hueChange, change: hueChange }).data('kendoSlider'); function opacityChange(e) { that._updateUI(that._getHSV(null, null, null, e.value / 100)); } that._opacitySlider = element.find('.k-transparency-slider').kendoSlider({ min: 0, max: 100, tickPlacement: 'none', showButtons: false, slide: opacityChange, change: opacityChange }).data('kendoSlider'); }, _hsvArea: function () { var that = this, element = that.element, hsvRect = element.find('.k-hsv-rectangle'), hsvHandle = hsvRect.find('.k-draghandle').attr('tabIndex', 0).on(KEYDOWN_NS, bind(that._keydown, that)); function update(x, y) { var offset = this.offset, dx = x - offset.left, dy = y - offset.top, rw = this.width, rh = this.height; dx = dx < 0 ? 0 : dx > rw ? rw : dx; dy = dy < 0 ? 0 : dy > rh ? rh : dy; that._svChange(dx / rw, 1 - dy / rh); } that._hsvEvents = new kendo.UserEvents(hsvRect, { global: true, press: function (e) { this.offset = kendo.getOffset(hsvRect); this.width = hsvRect.width(); this.height = hsvRect.height(); hsvHandle.focus(); update.call(this, e.x.location, e.y.location); }, start: function () { hsvRect.addClass('k-dragging'); hsvHandle.focus(); }, move: function (e) { e.preventDefault(); update.call(this, e.x.location, e.y.location); }, end: function () { hsvRect.removeClass('k-dragging'); } }); that._hsvRect = hsvRect; that._hsvHandle = hsvHandle; }, _onEnable: function (enable) { this._hueSlider.enable(enable); if (this._opacitySlider) { this._opacitySlider.enable(enable); } this.wrapper.find('input').attr('disabled', !enable); var handle = this._hsvRect.find('.k-draghandle'); if (enable) { handle.attr('tabIndex', this._tabIndex); } else { handle.removeAttr('tabIndex'); } }, _keydown: function (ev) { var that = this; function move(prop, d) { var c = that._getHSV(); c[prop] += d * (ev.shiftKey ? 0.01 : 0.05); if (c[prop] < 0) { c[prop] = 0; } if (c[prop] > 1) { c[prop] = 1; } that._updateUI(c); preventDefault(ev); } function hue(d) { var c = that._getHSV(); c.h += d * (ev.shiftKey ? 1 : 5); if (c.h < 0) { c.h = 0; } if (c.h > 359) { c.h = 359; } that._updateUI(c); preventDefault(ev); } switch (ev.keyCode) { case KEYS.LEFT: if (ev.ctrlKey) { hue(-1); } else { move('s', -1); } break; case KEYS.RIGHT: if (ev.ctrlKey) { hue(1); } else { move('s', 1); } break; case KEYS.UP: move(ev.ctrlKey && that._opacitySlider ? 'a' : 'v', 1); break; case KEYS.DOWN: move(ev.ctrlKey && that._opacitySlider ? 'a' : 'v', -1); break; case KEYS.ENTER: that._select(that._getHSV()); break; case KEYS.F2: that.wrapper.find('input.k-color-value').focus().select(); break; case KEYS.ESC: that._cancel(); break; } }, focus: function () { this._hsvHandle.focus(); }, _getHSV: function (h, s, v, a) { var rect = this._hsvRect, width = rect.width(), height = rect.height(), handlePosition = this._hsvHandle.position(); if (h == null) { h = this._hueSlider.value(); } if (s == null) { s = handlePosition.left / width; } if (v == null) { v = 1 - handlePosition.top / height; } if (a == null) { a = this._opacitySlider ? this._opacitySlider.value() / 100 : 1; } return Color.fromHSV(h, s, v, a); }, _svChange: function (s, v) { var color = this._getHSV(null, s, v, null); this._updateUI(color); }, _updateUI: function (color, dontChangeInput) { var that = this, rect = that._hsvRect; if (!color) { return; } this._colorAsText.removeClass('k-state-error'); that._selectedColor.css(BACKGROUNDCOLOR, color.toDisplay()); if (!dontChangeInput) { that._colorAsText.val(that._opacitySlider ? color.toCssRgba() : color.toCss()); } that._triggerSelect(color); color = color.toHSV(); that._hsvHandle.css({ left: color.s * rect.width() + 'px', top: (1 - color.v) * rect.height() + 'px' }); that._hueElements.css(BACKGROUNDCOLOR, Color.fromHSV(color.h, 1, 1, 1).toCss()); that._hueSlider.value(color.h); if (that._opacitySlider) { that._opacitySlider.value(100 * color.a); } }, _selectOnHide: function () { return this.options.buttons ? null : this._getHSV(); }, _template: kendo.template('# if (preview) { #' + '<div class="k-selected-color"><div class="k-selected-color-display"><input class="k-color-value" #= !data.input ? \'style="visibility: hidden;"\' : "" #></div></div>' + '# } #' + '<div class="k-hsv-rectangle"><div class="k-hsv-gradient"></div><div class="k-draghandle"></div></div>' + '<input class="k-hue-slider" />' + '# if (opacity) { #' + '<input class="k-transparency-slider" />' + '# } #' + '# if (buttons) { #' + '<div unselectable="on" class="k-controls"><button class="k-button k-primary apply">#: messages.apply #</button> <button class="k-button cancel">#: messages.cancel #</button></div>' + '# } #') }); function relative(array, element, delta) { array = Array.prototype.slice.call(array); var n = array.length; var pos = array.indexOf(element); if (pos < 0) { return delta < 0 ? array[n - 1] : array[0]; } pos += delta; if (pos < 0) { pos += n; } else { pos %= n; } return array[pos]; } var ColorPicker = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); options = that.options; element = that.element; var value = element.attr('value') || element.val(); if (value) { value = parseColor(value, true); } else { value = parseColor(options.value, true); } that._value = options.value = value; var content = that.wrapper = $(that._template(options)); element.hide().after(content); if (element.is('input')) { element.appendTo(content); var label = element.closest('label'); var id = element.attr('id'); if (id) { label = label.add('label[for="' + id + '"]'); } label.click(function (ev) { that.open(); ev.preventDefault(); }); } that._tabIndex = element.attr('tabIndex') || 0; that.enable(!element.attr('disabled')); var accesskey = element.attr('accesskey'); if (accesskey) { element.attr('accesskey', null); content.attr('accesskey', accesskey); } that.bind('activate', function (ev) { if (!ev.isDefaultPrevented()) { that.toggle(); } }); that._updateUI(value); }, destroy: function () { this.wrapper.off(NS).find('*').off(NS); if (this._popup) { this._selector.destroy(); this._popup.destroy(); } this._selector = this._popup = this.wrapper = null; Widget.fn.destroy.call(this); }, enable: function (enable) { var that = this, wrapper = that.wrapper, innerWrapper = wrapper.children('.k-picker-wrap'), icon = innerWrapper.find('.k-select'); if (arguments.length === 0) { enable = true; } that.element.attr('disabled', !enable); wrapper.attr('aria-disabled', !enable); icon.off(NS).on('mousedown' + NS, preventDefault); wrapper.addClass('k-state-disabled').removeAttr('tabIndex').add('*', wrapper).off(NS); if (enable) { wrapper.removeClass('k-state-disabled').attr('tabIndex', that._tabIndex).on('mouseenter' + NS, function () { innerWrapper.addClass('k-state-hover'); }).on('mouseleave' + NS, function () { innerWrapper.removeClass('k-state-hover'); }).on('focus' + NS, function () { innerWrapper.addClass('k-state-focused'); }).on('blur' + NS, function () { innerWrapper.removeClass('k-state-focused'); }).on(KEYDOWN_NS, bind(that._keydown, that)).on(CLICK_NS, '.k-select', bind(that.toggle, that)).on(CLICK_NS, that.options.toolIcon ? '.k-tool-icon' : '.k-selected-color', function () { that.trigger('activate'); }); } else { that.close(); } }, _template: kendo.template('<span role="textbox" aria-haspopup="true" class="k-widget k-colorpicker k-header">' + '<span class="k-picker-wrap k-state-default">' + '# if (toolIcon) { #' + '<span class="k-tool-icon #= toolIcon #">' + '<span class="k-selected-color"></span>' + '</span>' + '# } else { #' + '<span class="k-selected-color"></span>' + '# } #' + '<span class="k-select" unselectable="on">' + '<span class="k-icon k-i-arrow-s" unselectable="on"></span>' + '</span>' + '</span>' + '</span>'), options: { name: 'ColorPicker', palette: null, columns: 10, toolIcon: null, value: null, messages: APPLY_CANCEL, opacity: false, buttons: true, preview: true, ARIATemplate: 'Current selected color is #=data || ""#' }, events: [ 'activate', 'change', 'select', 'open', 'close' ], open: function () { if (!this.element.prop('disabled')) { this._getPopup().open(); } }, close: function () { this._getPopup().close(); }, toggle: function () { if (!this.element.prop('disabled')) { this._getPopup().toggle(); } }, color: ColorSelector.fn.color, value: ColorSelector.fn.value, _select: ColorSelector.fn._select, _triggerSelect: ColorSelector.fn._triggerSelect, _isInputTypeColor: function () { var el = this.element[0]; return /^input$/i.test(el.tagName) && /^color$/i.test(el.type); }, _updateUI: function (value) { var formattedValue = ''; if (value) { if (this._isInputTypeColor() || value.a == 1) { formattedValue = value.toCss(); } else { formattedValue = value.toCssRgba(); } this.element.val(formattedValue); } if (!this._ariaTemplate) { this._ariaTemplate = kendo.template(this.options.ARIATemplate); } this.wrapper.attr('aria-label', this._ariaTemplate(formattedValue)); this._triggerSelect(value); this.wrapper.find('.k-selected-color').css(BACKGROUNDCOLOR, value ? value.toDisplay() : 'transparent'); }, _keydown: function (ev) { var key = ev.keyCode; if (this._getPopup().visible()) { if (key == KEYS.ESC) { this._selector._cancel(); } else { this._selector._keydown(ev); } preventDefault(ev); } else if (key == KEYS.ENTER || key == KEYS.DOWN) { this.open(); preventDefault(ev); } }, _getPopup: function () { var that = this, popup = that._popup; if (!popup) { var options = that.options; var selectorType; if (options.palette) { selectorType = ColorPalette; } else { selectorType = FlatColorPicker; } options._standalone = false; delete options.select; delete options.change; delete options.cancel; var id = kendo.guid(); var selector = that._selector = new selectorType($('<div id="' + id + '"/>').appendTo(document.body), options); that.wrapper.attr('aria-owns', id); that._popup = popup = selector.wrapper.kendoPopup({ anchor: that.wrapper, adjustSize: { width: 5, height: 0 } }).data('kendoPopup'); selector.bind({ select: function (ev) { that._updateUI(parseColor(ev.value)); }, change: function () { that._select(selector.color()); that.close(); }, cancel: function () { that.close(); } }); popup.bind({ close: function (ev) { if (that.trigger('close')) { ev.preventDefault(); return; } that.wrapper.children('.k-picker-wrap').removeClass('k-state-focused'); var color = selector._selectOnHide(); if (!color) { setTimeout(function () { if (that.wrapper) { that.wrapper.focus(); } }); that._updateUI(that.color()); } else { that._select(color); } }, open: function (ev) { if (that.trigger('open')) { ev.preventDefault(); } else { that.wrapper.children('.k-picker-wrap').addClass('k-state-focused'); } }, activate: function () { selector._select(that.color(), true); selector.focus(); that.wrapper.children('.k-picker-wrap').addClass('k-state-focused'); } }); } return popup; } }); function preventDefault(ev) { ev.preventDefault(); } function bind(callback, obj) { return function () { return callback.apply(obj, arguments); }; } ui.plugin(ColorPalette); ui.plugin(FlatColorPicker); ui.plugin(ColorPicker); }(jQuery, parseInt)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.maskedtextbox', ['kendo.core'], f); }(function () { var __meta__ = { id: 'maskedtextbox', name: 'MaskedTextBox', category: 'web', description: 'The MaskedTextBox widget allows to specify a mask type on an input field.', depends: ['core'] }; (function ($, undefined) { var kendo = window.kendo; var caret = kendo.caret; var keys = kendo.keys; var ui = kendo.ui; var Widget = ui.Widget; var ns = '.kendoMaskedTextBox'; var proxy = $.proxy; var INPUT_EVENT_NAME = (kendo.support.propertyChangeEvent ? 'propertychange' : 'input') + ns; var STATEDISABLED = 'k-state-disabled'; var DISABLED = 'disabled'; var READONLY = 'readonly'; var CHANGE = 'change'; var MaskedTextBox = Widget.extend({ init: function (element, options) { var that = this; var DOMElement; Widget.fn.init.call(that, element, options); that._rules = $.extend({}, that.rules, that.options.rules); element = that.element; DOMElement = element[0]; that.wrapper = element; that._tokenize(); that._form(); that.element.addClass('k-textbox').attr('autocomplete', 'off').on('focus' + ns, function () { var value = DOMElement.value; if (!value) { DOMElement.value = that._old = that._emptyMask; } else { that._togglePrompt(true); } that._oldValue = value; that._timeoutId = setTimeout(function () { caret(element, 0, value ? that._maskLength : 0); }); }).on('focusout' + ns, function () { var value = element.val(); clearTimeout(that._timeoutId); DOMElement.value = that._old = ''; if (value !== that._emptyMask) { DOMElement.value = that._old = value; } that._change(); that._togglePrompt(); }); var disabled = element.is('[disabled]') || $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } else { that.readonly(element.is('[readonly]')); } that.value(that.options.value || element.val()); kendo.notify(that); }, options: { name: 'MaskedTextBox', clearPromptChar: false, unmaskOnPost: false, promptChar: '_', culture: '', rules: {}, value: '', mask: '' }, events: [CHANGE], rules: { '0': /\d/, '9': /\d|\s/, '#': /\d|\s|\+|\-/, 'L': /[a-zA-Z]/, '?': /[a-zA-Z]|\s/, '&': /\S/, 'C': /./, 'A': /[a-zA-Z0-9]/, 'a': /[a-zA-Z0-9]|\s/ }, setOptions: function (options) { var that = this; Widget.fn.setOptions.call(that, options); that._rules = $.extend({}, that.rules, that.options.rules); that._tokenize(); this._unbindInput(); this._bindInput(); that.value(that.element.val()); }, destroy: function () { var that = this; that.element.off(ns); if (that._formElement) { that._formElement.off('reset', that._resetHandler); that._formElement.off('submit', that._submitHandler); } Widget.fn.destroy.call(that); }, raw: function () { var unmasked = this._unmask(this.element.val(), 0); return unmasked.replace(new RegExp(this.options.promptChar, 'g'), ''); }, value: function (value) { var element = this.element; var emptyMask = this._emptyMask; if (value === undefined) { return this.element.val(); } if (value === null) { value = ''; } if (!emptyMask) { element.val(value); return; } value = this._unmask(value + ''); element.val(value ? emptyMask : ''); this._mask(0, this._maskLength, value); value = element.val(); this._oldValue = value; if (kendo._activeElement() !== element) { if (value === emptyMask) { element.val(''); } else { this._togglePrompt(); } } }, _togglePrompt: function (show) { var DOMElement = this.element[0]; var value = DOMElement.value; if (this.options.clearPromptChar) { if (!show) { value = value.replace(new RegExp(this.options.promptChar, 'g'), ' '); } else { value = this._oldValue; } DOMElement.value = this._old = value; } }, readonly: function (readonly) { this._editable({ readonly: readonly === undefined ? true : readonly, disable: false }); }, enable: function (enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined ? true : enable) }); }, _bindInput: function () { var that = this; if (that._maskLength) { that.element.on('keydown' + ns, proxy(that._keydown, that)).on('keypress' + ns, proxy(that._keypress, that)).on('paste' + ns, proxy(that._paste, that)).on(INPUT_EVENT_NAME, proxy(that._propertyChange, that)); } }, _unbindInput: function () { this.element.off('keydown' + ns).off('keypress' + ns).off('paste' + ns).off(INPUT_EVENT_NAME); }, _editable: function (options) { var that = this; var element = that.element; var disable = options.disable; var readonly = options.readonly; that._unbindInput(); if (!readonly && !disable) { element.removeAttr(DISABLED).removeAttr(READONLY).removeClass(STATEDISABLED); that._bindInput(); } else { element.attr(DISABLED, disable).attr(READONLY, readonly).toggleClass(STATEDISABLED, disable); } }, _change: function () { var that = this; var value = that.value(); if (value !== that._oldValue) { that._oldValue = value; that.trigger(CHANGE); that.element.trigger(CHANGE); } }, _propertyChange: function () { var that = this; var element = that.element[0]; var value = element.value; var unmasked; var start; if (kendo._activeElement() !== element) { return; } if (value !== that._old && !that._pasting) { start = caret(element)[0]; unmasked = that._unmask(value.substring(start), start); element.value = that._old = value.substring(0, start) + that._emptyMask.substring(start); that._mask(start, start, unmasked); caret(element, start); } }, _paste: function (e) { var that = this; var element = e.target; var position = caret(element); var start = position[0]; var end = position[1]; var unmasked = that._unmask(element.value.substring(end), end); that._pasting = true; setTimeout(function () { var value = element.value; var pasted = value.substring(start, caret(element)[0]); element.value = that._old = value.substring(0, start) + that._emptyMask.substring(start); that._mask(start, start, pasted); start = caret(element)[0]; that._mask(start, start, unmasked); caret(element, start); that._pasting = false; }); }, _form: function () { var that = this; var element = that.element; var formId = element.attr('form'); var form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._resetHandler = function () { setTimeout(function () { that.value(element[0].value); }); }; that._submitHandler = function () { that.element[0].value = that._old = that.raw(); }; if (that.options.unmaskOnPost) { form.on('submit', that._submitHandler); } that._formElement = form.on('reset', that._resetHandler); } }, _keydown: function (e) { var key = e.keyCode; var element = this.element[0]; var selection = caret(element); var start = selection[0]; var end = selection[1]; var placeholder; var backward = key === keys.BACKSPACE; if (backward || key === keys.DELETE) { if (start === end) { if (backward) { start -= 1; } else { end += 1; } placeholder = this._find(start, backward); } if (placeholder !== undefined && placeholder !== start) { if (backward) { placeholder += 1; } caret(element, placeholder); } else if (start > -1) { this._mask(start, end, '', backward); } e.preventDefault(); } else if (key === keys.ENTER) { this._change(); } }, _keypress: function (e) { if (e.which === 0 || e.metaKey || e.ctrlKey || e.keyCode === keys.ENTER) { return; } var character = String.fromCharCode(e.which); var selection = caret(this.element); this._mask(selection[0], selection[1], character); if (e.keyCode === keys.BACKSPACE || character) { e.preventDefault(); } }, _find: function (idx, backward) { var value = this.element.val() || this._emptyMask; var step = 1; if (backward === true) { step = -1; } while (idx > -1 || idx <= this._maskLength) { if (value.charAt(idx) !== this.tokens[idx]) { return idx; } idx += step; } return -1; }, _mask: function (start, end, value, backward) { var element = this.element[0]; var current = element.value || this._emptyMask; var empty = this.options.promptChar; var valueLength; var chrIdx = 0; var unmasked; var chr; var idx; start = this._find(start, backward); if (start > end) { end = start; } unmasked = this._unmask(current.substring(end), end); value = this._unmask(value, start); valueLength = value.length; if (value) { unmasked = unmasked.replace(new RegExp('^_{0,' + valueLength + '}'), ''); } value += unmasked; current = current.split(''); chr = value.charAt(chrIdx); while (start < this._maskLength) { current[start] = chr || empty; chr = value.charAt(++chrIdx); if (idx === undefined && chrIdx > valueLength) { idx = start; } start = this._find(start + 1); } element.value = this._old = current.join(''); if (kendo._activeElement() === element) { if (idx === undefined) { idx = this._maskLength; } caret(element, idx); } }, _unmask: function (value, idx) { if (!value) { return ''; } value = (value + '').split(''); var chr; var token; var chrIdx = 0; var tokenIdx = idx || 0; var empty = this.options.promptChar; var valueLength = value.length; var tokensLength = this.tokens.length; var result = ''; while (tokenIdx < tokensLength) { chr = value[chrIdx]; token = this.tokens[tokenIdx]; if (chr === token || chr === empty) { result += chr === empty ? empty : ''; chrIdx += 1; tokenIdx += 1; } else if (typeof token !== 'string') { if (token.test && token.test(chr) || $.isFunction(token) && token(chr)) { result += chr; tokenIdx += 1; } chrIdx += 1; } else { tokenIdx += 1; } if (chrIdx >= valueLength) { break; } } return result; }, _tokenize: function () { var tokens = []; var tokenIdx = 0; var mask = this.options.mask || ''; var maskChars = mask.split(''); var length = maskChars.length; var idx = 0; var chr; var rule; var emptyMask = ''; var promptChar = this.options.promptChar; var numberFormat = kendo.getCulture(this.options.culture).numberFormat; var rules = this._rules; for (; idx < length; idx++) { chr = maskChars[idx]; rule = rules[chr]; if (rule) { tokens[tokenIdx] = rule; emptyMask += promptChar; tokenIdx += 1; } else { if (chr === '.' || chr === ',') { chr = numberFormat[chr]; } else if (chr === '$') { chr = numberFormat.currency.symbol; } else if (chr === '\\') { idx += 1; chr = maskChars[idx]; } chr = chr.split(''); for (var i = 0, l = chr.length; i < l; i++) { tokens[tokenIdx] = chr[i]; emptyMask += chr[i]; tokenIdx += 1; } } } this.tokens = tokens; this._emptyMask = emptyMask; this._maskLength = emptyMask.length; } }); ui.plugin(MaskedTextBox); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.multiselect', [ 'kendo.list', 'kendo.mobile.scroller' ], f); }(function () { var __meta__ = { id: 'multiselect', name: 'MultiSelect', category: 'web', description: 'The MultiSelect widget allows the selection from pre-defined values.', depends: ['list'], features: [ { id: 'mobile-scroller', name: 'Mobile scroller', description: 'Support for kinetic scrolling in mobile device', depends: ['mobile.scroller'] }, { id: 'virtualization', name: 'VirtualList', description: 'Support for virtualization', depends: ['virtuallist'] } ] }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, List = ui.List, keys = kendo.keys, activeElement = kendo._activeElement, ObservableArray = kendo.data.ObservableArray, proxy = $.proxy, ID = 'id', LI = 'li', ACCEPT = 'accept', FILTER = 'filter', REBIND = 'rebind', OPEN = 'open', CLOSE = 'close', CHANGE = 'change', PROGRESS = 'progress', SELECT = 'select', ARIA_DISABLED = 'aria-disabled', FOCUSEDCLASS = 'k-state-focused', HIDDENCLASS = 'k-loading-hidden', HOVERCLASS = 'k-state-hover', STATEDISABLED = 'k-state-disabled', DISABLED = 'disabled', READONLY = 'readonly', ns = '.kendoMultiSelect', CLICK = 'click' + ns, KEYDOWN = 'keydown' + ns, MOUSEENTER = 'mouseenter' + ns, MOUSELEAVE = 'mouseleave' + ns, HOVEREVENTS = MOUSEENTER + ' ' + MOUSELEAVE, quotRegExp = /"/g, isArray = $.isArray, styles = [ 'font-family', 'font-size', 'font-stretch', 'font-style', 'font-weight', 'letter-spacing', 'text-transform', 'line-height' ]; var MultiSelect = List.extend({ init: function (element, options) { var that = this, id, disabled; that.ns = ns; List.fn.init.call(that, element, options); that._optionsMap = {}; that._customOptions = {}; that._wrapper(); that._tagList(); that._input(); that._textContainer(); that._loader(); that._tabindex(that.input); element = that.element.attr('multiple', 'multiple').hide(); options = that.options; if (!options.placeholder) { options.placeholder = element.data('placeholder'); } id = element.attr(ID); if (id) { that._tagID = id + '_tag_active'; id = id + '_taglist'; that.tagList.attr(ID, id); } that._aria(id); that._dataSource(); that._ignoreCase(); that._popup(); that._tagTemplate(); that._initList(); that._reset(); that._enable(); that._placeholder(); if (options.autoBind) { that.dataSource.fetch(); } else if (options.value) { that._preselect(options.value); } disabled = $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } kendo.notify(that); }, options: { name: 'MultiSelect', tagMode: 'multiple', enabled: true, autoBind: true, autoClose: true, highlightFirst: true, dataTextField: '', dataValueField: '', filter: 'startswith', ignoreCase: true, minLength: 0, delay: 100, value: null, maxSelectedItems: null, placeholder: '', height: 200, animation: {}, virtual: false, itemTemplate: '', tagTemplate: '', groupTemplate: '#:data#', fixedGroupTemplate: '#:data#' }, events: [ OPEN, CLOSE, CHANGE, SELECT, 'filtering', 'dataBinding', 'dataBound' ], setDataSource: function (dataSource) { this.options.dataSource = dataSource; this._state = ''; this._dataSource(); this.listView.setDataSource(this.dataSource); if (this.options.autoBind) { this.dataSource.fetch(); } }, setOptions: function (options) { var listOptions = this._listOptions(options); List.fn.setOptions.call(this, options); this.listView.setOptions(listOptions); this._accessors(); this._aria(this.tagList.attr(ID)); this._tagTemplate(); }, currentTag: function (candidate) { var that = this; if (candidate !== undefined) { if (that._currentTag) { that._currentTag.removeClass(FOCUSEDCLASS).removeAttr(ID); that.input.removeAttr('aria-activedescendant'); } if (candidate) { candidate.addClass(FOCUSEDCLASS).attr(ID, that._tagID); that.input.attr('aria-activedescendant', that._tagID); } that._currentTag = candidate; } else { return that._currentTag; } }, dataItems: function () { return this.listView.selectedDataItems(); }, destroy: function () { var that = this, ns = that.ns; clearTimeout(that._busy); clearTimeout(that._typingTimeout); that.wrapper.off(ns); that.tagList.off(ns); that.input.off(ns); List.fn.destroy.call(that); }, _activateItem: function () { List.fn._activateItem.call(this); this.currentTag(null); }, _listOptions: function (options) { var that = this; var listOptions = List.fn._listOptions.call(that, $.extend(options, { selectedItemChange: proxy(that._selectedItemChange, that), selectable: 'multiple' })); var itemTemplate = this.options.itemTemplate || this.options.template; var template = listOptions.itemTemplate || itemTemplate || listOptions.template; if (!template) { template = '#:' + kendo.expr(listOptions.dataTextField, 'data') + '#'; } listOptions.template = template; return listOptions; }, _setListValue: function () { List.fn._setListValue.call(this, this._initialValues.slice(0)); }, _listChange: function (e) { var data = this.dataSource.flatView(); var optionsMap = this._optionsMap; var valueGetter = this._value; if (this._state === REBIND) { this._state = ''; } for (var i = 0; i < e.added.length; i++) { if (optionsMap[valueGetter(e.added[i])] === undefined) { this._render(data); break; } } this._selectValue(e.added, e.removed); }, _selectedItemChange: function (e) { var items = e.items; var context; var idx; for (idx = 0; idx < items.length; idx++) { context = items[idx]; this.tagList.children().eq(context.index).children('span:first').html(this.tagTextTemplate(context.item)); } }, _wrapperMousedown: function (e) { var that = this; var notInput = e.target.nodeName.toLowerCase() !== 'input'; var target = $(e.target); var closeButton = target.hasClass('k-select') || target.hasClass('k-icon'); if (closeButton) { closeButton = !target.closest('.k-select').children('.k-i-arrow-s').length; } if (notInput && !(closeButton && kendo.support.mobileOS)) { e.preventDefault(); } if (!closeButton) { if (that.input[0] !== activeElement() && notInput) { that.input.focus(); } if (that.options.minLength === 0) { that.open(); } } }, _inputFocus: function () { this._placeholder(false); this.wrapper.addClass(FOCUSEDCLASS); }, _inputFocusout: function () { var that = this; clearTimeout(that._typingTimeout); that.wrapper.removeClass(FOCUSEDCLASS); that._placeholder(!that.listView.selectedDataItems()[0], true); that.close(); if (that._state === FILTER) { that._state = ACCEPT; that.listView.skipUpdate(true); } that.element.blur(); }, _removeTag: function (tag) { var that = this; var state = that._state; var position = tag.index(); var listView = that.listView; var value = listView.value()[position]; var customIndex = that._customOptions[value]; var option; if (customIndex === undefined && (state === ACCEPT || state === FILTER)) { customIndex = that._optionsMap[value]; } if (customIndex !== undefined) { option = that.element[0].children[customIndex]; option.removeAttribute('selected'); option.selected = false; listView.removeAt(position); tag.remove(); } else { listView.select(listView.select()[position]); } that.currentTag(null); that._change(); that._close(); }, _tagListClick: function (e) { var target = $(e.currentTarget); if (!target.children('.k-i-arrow-s').length) { this._removeTag(target.closest(LI)); } }, _editable: function (options) { var that = this, disable = options.disable, readonly = options.readonly, wrapper = that.wrapper.off(ns), tagList = that.tagList.off(ns), input = that.element.add(that.input.off(ns)); if (!readonly && !disable) { wrapper.removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover).on('mousedown' + ns + ' touchend' + ns, proxy(that._wrapperMousedown, that)); that.input.on(KEYDOWN, proxy(that._keydown, that)).on('paste' + ns, proxy(that._search, that)).on('focus' + ns, proxy(that._inputFocus, that)).on('focusout' + ns, proxy(that._inputFocusout, that)); input.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false); tagList.on(MOUSEENTER, LI, function () { $(this).addClass(HOVERCLASS); }).on(MOUSELEAVE, LI, function () { $(this).removeClass(HOVERCLASS); }).on(CLICK, 'li.k-button .k-select', proxy(that._tagListClick, that)); } else { if (disable) { wrapper.addClass(STATEDISABLED); } else { wrapper.removeClass(STATEDISABLED); } input.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable); } }, _close: function () { var that = this; if (that.options.autoClose) { that.close(); } else { that.popup.position(); } }, _filterSource: function (filter, force) { if (!force) { force = this._retrieveData; } this._retrieveData = false; List.fn._filterSource.call(this, filter, force); }, close: function () { this.popup.close(); }, open: function () { var that = this; if (that._request) { that._retrieveData = false; } if (that._retrieveData || !that.listView.bound() || that._state === ACCEPT) { that._open = true; that._state = REBIND; that.listView.skipUpdate(true); that._filterSource(); } else if (that._allowSelection()) { that.popup.open(); that._focusItem(); } }, toggle: function (toggle) { toggle = toggle !== undefined ? toggle : !this.popup.visible(); this[toggle ? OPEN : CLOSE](); }, refresh: function () { this.listView.refresh(); }, _listBound: function () { var that = this; var data = that.dataSource.flatView(); var skip = that.listView.skip(); var length = data.length; that._render(data); that._resizePopup(); if (that._open) { that._open = false; that.toggle(length); } that.popup.position(); if (that.options.highlightFirst && (skip === undefined || skip === 0)) { that.listView.focusFirst(); } if (that._touchScroller) { that._touchScroller.reset(); } that._hideBusy(); that._makeUnselectable(); that.trigger('dataBound'); }, search: function (word) { var that = this; var options = that.options; var ignoreCase = options.ignoreCase; var field = options.dataTextField; var inputValue = that.input.val(); var expression; var length; if (options.placeholder === inputValue) { inputValue = ''; } clearTimeout(that._typingTimeout); word = typeof word === 'string' ? word : inputValue; length = word.length; if (!length || length >= options.minLength) { that._state = FILTER; that._open = true; expression = { value: ignoreCase ? word.toLowerCase() : word, field: field, operator: options.filter, ignoreCase: ignoreCase }; that._filterSource(expression); } }, value: function (value) { var that = this; var listView = that.listView; var oldValue = listView.value().slice(); var maxSelectedItems = that.options.maxSelectedItems; var clearFilters = listView.bound() && listView.isFiltered(); if (value === undefined) { return oldValue; } value = that._normalizeValues(value); if (maxSelectedItems !== null && value.length > maxSelectedItems) { value = value.slice(0, maxSelectedItems); } if (clearFilters) { that._clearFilter(); } listView.value(value); that._old = value; if (!clearFilters) { that._fetchData(); } }, _preselect: function (data, value) { var that = this; if (!isArray(data) && !(data instanceof kendo.data.ObservableArray)) { data = [data]; } if ($.isPlainObject(data[0]) || data[0] instanceof kendo.data.ObservableObject || !that.options.dataValueField) { that.dataSource.data(data); that.value(value || that._initialValues); that._retrieveData = true; } }, _setOption: function (value, selected) { var option = this.element[0].children[this._optionsMap[value]]; if (option) { if (selected) { option.setAttribute('selected', 'selected'); } else { option.removeAttribute('selected'); } option.selected = selected; } }, _fetchData: function () { var that = this; var hasItems = !!that.dataSource.view().length; var isEmptyArray = that.listView.value().length === 0; if (isEmptyArray || that._request) { return; } if (that._retrieveData || !that._fetch && !hasItems) { that._fetch = true; that._retrieveData = false; that.dataSource.read().done(function () { that._fetch = false; }); } }, _isBound: function () { return this.listView.bound() && !this._retrieveData; }, _dataSource: function () { var that = this, element = that.element, options = that.options, dataSource = options.dataSource || {}; dataSource = isArray(dataSource) ? { data: dataSource } : dataSource; dataSource.select = element; dataSource.fields = [ { field: options.dataTextField }, { field: options.dataValueField } ]; if (that.dataSource && that._refreshHandler) { that._unbindDataSource(); } else { that._progressHandler = proxy(that._showBusy, that); that._errorHandler = proxy(that._hideBusy, that); } that.dataSource = kendo.data.DataSource.create(dataSource).bind(PROGRESS, that._progressHandler).bind('error', that._errorHandler); }, _reset: function () { var that = this, element = that.element, formId = element.attr('form'), form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._resetHandler = function () { setTimeout(function () { that.value(that._initialValues); that._placeholder(); }); }; that._form = form.on('reset', that._resetHandler); } }, _initValue: function () { var value = this.options.value || this.element.val(); this._old = this._initialValues = this._normalizeValues(value); }, _normalizeValues: function (value) { var that = this; if (value === null) { value = []; } else if (value && $.isPlainObject(value)) { value = [that._value(value)]; } else if (value && $.isPlainObject(value[0])) { value = $.map(value, function (dataItem) { return that._value(dataItem); }); } else if (!isArray(value) && !(value instanceof ObservableArray)) { value = [value]; } return value; }, _change: function () { var that = this, value = that.value(); if (!compare(value, that._old)) { that._old = value.slice(); that.trigger(CHANGE); that.element.trigger(CHANGE); } }, _click: function (e) { var item = e.item; e.preventDefault(); if (this.trigger(SELECT, { item: item })) { this._close(); return; } this._select(item); this._change(); this._close(); }, _keydown: function (e) { var that = this; var key = e.keyCode; var tag = that._currentTag; var current = that.listView.focus(); var hasValue = that.input.val(); var isRtl = kendo.support.isRtl(that.wrapper); var visible = that.popup.visible(); if (key === keys.DOWN) { e.preventDefault(); if (!visible) { that.open(); if (!current) { this.listView.focusFirst(); } return; } if (current) { this.listView.focusNext(); if (!this.listView.focus()) { this.listView.focusLast(); } } else { this.listView.focusFirst(); } } else if (key === keys.UP) { if (visible) { if (current) { this.listView.focusPrev(); } if (!this.listView.focus()) { that.close(); } } e.preventDefault(); } else if (key === keys.LEFT && !isRtl || key === keys.RIGHT && isRtl) { if (!hasValue) { tag = tag ? tag.prev() : $(that.tagList[0].lastChild); if (tag[0]) { that.currentTag(tag); } } } else if (key === keys.RIGHT && !isRtl || key === keys.LEFT && isRtl) { if (!hasValue && tag) { tag = tag.next(); that.currentTag(tag[0] ? tag : null); } } else if (key === keys.ENTER && visible) { if (current) { if (that.trigger(SELECT, { item: current })) { that._close(); return; } that._select(current); } that._change(); that._close(); e.preventDefault(); } else if (key === keys.ESC) { if (visible) { e.preventDefault(); } else { that.currentTag(null); } that.close(); } else if (key === keys.HOME) { if (visible) { this.listView.focusFirst(); } else if (!hasValue) { tag = that.tagList[0].firstChild; if (tag) { that.currentTag($(tag)); } } } else if (key === keys.END) { if (visible) { this.listView.focusLast(); } else if (!hasValue) { tag = that.tagList[0].lastChild; if (tag) { that.currentTag($(tag)); } } } else if ((key === keys.DELETE || key === keys.BACKSPACE) && !hasValue) { if (key === keys.BACKSPACE && !tag) { tag = $(that.tagList[0].lastChild); } if (tag && tag[0]) { that._removeTag(tag); } } else { clearTimeout(that._typingTimeout); setTimeout(function () { that._scale(); }); that._search(); } }, _hideBusy: function () { var that = this; clearTimeout(that._busy); that.input.attr('aria-busy', false); that._loading.addClass(HIDDENCLASS); that._request = false; that._busy = null; }, _showBusyHandler: function () { this.input.attr('aria-busy', true); this._loading.removeClass(HIDDENCLASS); }, _showBusy: function () { var that = this; that._request = true; if (that._busy) { return; } that._busy = setTimeout(proxy(that._showBusyHandler, that), 100); }, _placeholder: function (show, skipCaret) { var that = this, input = that.input, active = activeElement(); if (show === undefined) { show = false; if (input[0] !== active) { show = !that.listView.selectedDataItems()[0]; } } that._prev = ''; input.toggleClass('k-readonly', show).val(show ? that.options.placeholder : ''); if (input[0] === active && !skipCaret) { kendo.caret(input[0], 0, 0); } that._scale(); }, _scale: function () { var that = this, wrapper = that.wrapper, wrapperWidth = wrapper.width(), span = that._span.text(that.input.val()), textWidth; if (!wrapper.is(':visible')) { span.appendTo(document.documentElement); wrapperWidth = textWidth = span.width() + 25; span.appendTo(wrapper); } else { textWidth = span.width() + 25; } that.input.width(textWidth > wrapperWidth ? wrapperWidth : textWidth); }, _option: function (dataValue, dataText, selected) { var option = '<option'; if (dataValue !== undefined) { dataValue += ''; if (dataValue.indexOf('"') !== -1) { dataValue = dataValue.replace(quotRegExp, '"'); } option += ' value="' + dataValue + '"'; } if (selected) { option += ' selected'; } option += '>'; if (dataText !== undefined) { option += kendo.htmlEncode(dataText); } return option += '</option>'; }, _render: function (data) { var selectedItems = this.listView.selectedDataItems(); var values = this.listView.value(); var length = data.length; var selectedIndex; var options = ''; var dataItem; var value; var idx; if (values.length !== selectedItems.length) { selectedItems = this._buildSelectedItems(values); } var custom = {}; var optionsMap = {}; for (idx = 0; idx < length; idx++) { dataItem = data[idx]; value = this._value(dataItem); selectedIndex = this._selectedItemIndex(value, selectedItems); if (selectedIndex !== -1) { selectedItems.splice(selectedIndex, 1); } optionsMap[value] = idx; options += this._option(value, this._text(dataItem), selectedIndex !== -1); } if (selectedItems.length) { for (idx = 0; idx < selectedItems.length; idx++) { dataItem = selectedItems[idx]; value = this._value(dataItem); custom[value] = length; optionsMap[value] = length; length += 1; options += this._option(value, this._text(dataItem), true); } } this._customOptions = custom; this._optionsMap = optionsMap; this.element.html(options); }, _buildSelectedItems: function (values) { var valueField = this.options.dataValueField; var textField = this.options.dataTextField; var result = []; var item; for (var idx = 0; idx < values.length; idx++) { item = {}; item[valueField] = values[idx]; item[textField] = values[idx]; result.push(item); } return result; }, _selectedItemIndex: function (value, selectedItems) { var valueGetter = this._value; var idx = 0; for (; idx < selectedItems.length; idx++) { if (value === valueGetter(selectedItems[idx])) { return idx; } } return -1; }, _search: function () { var that = this; that._typingTimeout = setTimeout(function () { var value = that.input.val(); if (that._prev !== value) { that._prev = value; that.search(value); } }, that.options.delay); }, _allowSelection: function () { var max = this.options.maxSelectedItems; return max === null || max > this.listView.value().length; }, _angularTagItems: function (cmd) { var that = this; that.angular(cmd, function () { return { elements: that.tagList[0].children, data: $.map(that.dataItems(), function (dataItem) { return { dataItem: dataItem }; }) }; }); }, _selectValue: function (added, removed) { var that = this; var values = that.value(); var total = that.dataSource.total(); var tagList = that.tagList; var getter = that._value; var removedItem; var addedItem; var idx; that._angularTagItems('cleanup'); if (that.options.tagMode === 'multiple') { for (idx = removed.length - 1; idx > -1; idx--) { removedItem = removed[idx]; tagList[0].removeChild(tagList[0].children[removedItem.position]); that._setOption(getter(removedItem.dataItem), false); } for (idx = 0; idx < added.length; idx++) { addedItem = added[idx]; tagList.append(that.tagTemplate(addedItem.dataItem)); that._setOption(getter(addedItem.dataItem), true); } } else { if (!that._maxTotal || that._maxTotal < total) { that._maxTotal = total; } tagList.html(''); if (values.length) { tagList.append(that.tagTemplate({ values: values, dataItems: that.dataItems(), maxTotal: that._maxTotal, currentTotal: total })); } for (idx = removed.length - 1; idx > -1; idx--) { that._setOption(getter(removed[idx].dataItem), false); } for (idx = 0; idx < added.length; idx++) { that._setOption(getter(added[idx].dataItem), true); } } that._angularTagItems('compile'); that._placeholder(); }, _select: function (candidate) { var that = this; if (that._state === REBIND) { that._state = ''; } if (!that._allowSelection()) { return; } this.listView.select(candidate); that._placeholder(); if (that._state === FILTER) { that._state = ACCEPT; that.listView.skipUpdate(true); } }, _input: function () { var that = this; var element = that.element; var accessKey = element[0].accessKey; var input = that._innerWrapper.children('input.k-input'); if (!input[0]) { input = $('<input class="k-input" style="width: 25px" />').appendTo(that._innerWrapper); } element.removeAttr('accesskey'); that._focused = that.input = input.attr({ 'accesskey': accessKey, 'autocomplete': 'off', 'role': 'listbox', 'title': element[0].title, 'aria-expanded': false }); }, _tagList: function () { var that = this, tagList = that._innerWrapper.children('ul'); if (!tagList[0]) { tagList = $('<ul role="listbox" unselectable="on" class="k-reset"/>').appendTo(that._innerWrapper); } that.tagList = tagList; }, _tagTemplate: function () { var that = this; var options = that.options; var tagTemplate = options.tagTemplate; var hasDataSource = options.dataSource; var isMultiple = options.tagMode === 'multiple'; var defaultTemplate; if (that.element[0].length && !hasDataSource) { options.dataTextField = options.dataTextField || 'text'; options.dataValueField = options.dataValueField || 'value'; } defaultTemplate = isMultiple ? kendo.template('#:' + kendo.expr(options.dataTextField, 'data') + '#', { useWithBlock: false }) : kendo.template('#:values.length# item(s) selected'); that.tagTextTemplate = tagTemplate = tagTemplate ? kendo.template(tagTemplate) : defaultTemplate; that.tagTemplate = function (data) { return '<li class="k-button" unselectable="on"><span unselectable="on">' + tagTemplate(data) + '</span><span unselectable="on" class="k-select"><span unselectable="on" class="k-icon ' + (isMultiple ? 'k-i-close' : 'k-i-arrow-s') + '">' + (isMultiple ? 'delete' : 'open') + '</span></span></li>'; }; }, _loader: function () { this._loading = $('<span class="k-icon k-loading ' + HIDDENCLASS + '"></span>').insertAfter(this.input); }, _textContainer: function () { var computedStyles = kendo.getComputedStyles(this.input[0], styles); computedStyles.position = 'absolute'; computedStyles.visibility = 'hidden'; computedStyles.top = -3333; computedStyles.left = -3333; this._span = $('<span/>').css(computedStyles).appendTo(this.wrapper); }, _wrapper: function () { var that = this, element = that.element, wrapper = element.parent('span.k-multiselect'); if (!wrapper[0]) { wrapper = element.wrap('<div class="k-widget k-multiselect k-header" unselectable="on" />').parent(); wrapper[0].style.cssText = element[0].style.cssText; wrapper[0].title = element[0].title; $('<div class="k-multiselect-wrap k-floatwrap" unselectable="on" />').insertBefore(element); } that.wrapper = wrapper.addClass(element[0].className).css('display', ''); that._innerWrapper = $(wrapper[0].firstChild); } }); function compare(a, b) { var length; if (a === null && b !== null || a !== null && b === null) { return false; } length = a.length; if (length !== b.length) { return false; } while (length--) { if (a[length] !== b[length]) { return false; } } return true; } ui.plugin(MultiSelect); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.numerictextbox', [ 'kendo.core', 'kendo.userevents' ], f); }(function () { var __meta__ = { id: 'numerictextbox', name: 'NumericTextBox', category: 'web', description: 'The NumericTextBox widget can format and display numeric, percentage or currency textbox.', depends: [ 'core', 'userevents' ] }; (function ($, undefined) { var kendo = window.kendo, caret = kendo.caret, keys = kendo.keys, ui = kendo.ui, Widget = ui.Widget, activeElement = kendo._activeElement, extractFormat = kendo._extractFormat, parse = kendo.parseFloat, placeholderSupported = kendo.support.placeholder, getCulture = kendo.getCulture, round = kendo._round, CHANGE = 'change', DISABLED = 'disabled', READONLY = 'readonly', INPUT = 'k-input', SPIN = 'spin', ns = '.kendoNumericTextBox', TOUCHEND = 'touchend', MOUSELEAVE = 'mouseleave' + ns, HOVEREVENTS = 'mouseenter' + ns + ' ' + MOUSELEAVE, DEFAULT = 'k-state-default', FOCUSED = 'k-state-focused', HOVER = 'k-state-hover', FOCUS = 'focus', POINT = '.', SELECTED = 'k-state-selected', STATEDISABLED = 'k-state-disabled', ARIA_DISABLED = 'aria-disabled', ARIA_READONLY = 'aria-readonly', INTEGER_REGEXP = /^(-)?(\d*)$/, NULL = null, proxy = $.proxy, extend = $.extend; var NumericTextBox = Widget.extend({ init: function (element, options) { var that = this, isStep = options && options.step !== undefined, min, max, step, value, disabled; Widget.fn.init.call(that, element, options); options = that.options; element = that.element.on('focusout' + ns, proxy(that._focusout, that)).attr('role', 'spinbutton'); options.placeholder = options.placeholder || element.attr('placeholder'); that._initialOptions = extend({}, options); that._reset(); that._wrapper(); that._arrows(); that._input(); if (!kendo.support.mobileOS) { that._text.on(FOCUS + ns, proxy(that._click, that)); } else { that._text.on(TOUCHEND + ns + ' ' + FOCUS + ns, function () { that._toggleText(false); element.focus(); }); } min = that.min(element.attr('min')); max = that.max(element.attr('max')); step = that._parse(element.attr('step')); if (options.min === NULL && min !== NULL) { options.min = min; } if (options.max === NULL && max !== NULL) { options.max = max; } if (!isStep && step !== NULL) { options.step = step; } element.attr('aria-valuemin', options.min).attr('aria-valuemax', options.max); options.format = extractFormat(options.format); value = options.value; that.value(value !== NULL ? value : element.val()); disabled = element.is('[disabled]') || $(that.element).parents('fieldset').is(':disabled'); if (disabled) { that.enable(false); } else { that.readonly(element.is('[readonly]')); } kendo.notify(that); }, options: { name: 'NumericTextBox', decimals: NULL, min: NULL, max: NULL, value: NULL, step: 1, culture: '', format: 'n', spinners: true, placeholder: '', upArrowText: 'Increase value', downArrowText: 'Decrease value' }, events: [ CHANGE, SPIN ], _editable: function (options) { var that = this, element = that.element, disable = options.disable, readonly = options.readonly, text = that._text.add(element), wrapper = that._inputWrapper.off(HOVEREVENTS); that._toggleText(true); that._upArrowEventHandler.unbind('press'); that._downArrowEventHandler.unbind('press'); element.off('keydown' + ns).off('keypress' + ns).off('paste' + ns); if (!readonly && !disable) { wrapper.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); text.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false).attr(ARIA_READONLY, false); that._upArrowEventHandler.bind('press', function (e) { e.preventDefault(); that._spin(1); that._upArrow.addClass(SELECTED); }); that._downArrowEventHandler.bind('press', function (e) { e.preventDefault(); that._spin(-1); that._downArrow.addClass(SELECTED); }); that.element.on('keydown' + ns, proxy(that._keydown, that)).on('keypress' + ns, proxy(that._keypress, that)).on('paste' + ns, proxy(that._paste, that)); } else { wrapper.addClass(disable ? STATEDISABLED : DEFAULT).removeClass(disable ? DEFAULT : STATEDISABLED); text.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable).attr(ARIA_READONLY, readonly); } }, readonly: function (readonly) { this._editable({ readonly: readonly === undefined ? true : readonly, disable: false }); }, enable: function (enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined ? true : enable) }); }, destroy: function () { var that = this; that.element.add(that._text).add(that._upArrow).add(that._downArrow).add(that._inputWrapper).off(ns); that._upArrowEventHandler.destroy(); that._downArrowEventHandler.destroy(); if (that._form) { that._form.off('reset', that._resetHandler); } Widget.fn.destroy.call(that); }, min: function (value) { return this._option('min', value); }, max: function (value) { return this._option('max', value); }, step: function (value) { return this._option('step', value); }, value: function (value) { var that = this, adjusted; if (value === undefined) { return that._value; } value = that._parse(value); adjusted = that._adjust(value); if (value !== adjusted) { return; } that._update(value); that._old = that._value; }, focus: function () { this._focusin(); }, _adjust: function (value) { var that = this, options = that.options, min = options.min, max = options.max; if (value === NULL) { return value; } if (min !== NULL && value < min) { value = min; } else if (max !== NULL && value > max) { value = max; } return value; }, _arrows: function () { var that = this, arrows, _release = function () { clearTimeout(that._spinning); arrows.removeClass(SELECTED); }, options = that.options, spinners = options.spinners, element = that.element; arrows = element.siblings('.k-icon'); if (!arrows[0]) { arrows = $(buttonHtml('n', options.upArrowText) + buttonHtml('s', options.downArrowText)).insertAfter(element); arrows.wrapAll('<span class="k-select"/>'); } if (!spinners) { arrows.parent().toggle(spinners); that._inputWrapper.addClass('k-expand-padding'); } that._upArrow = arrows.eq(0); that._upArrowEventHandler = new kendo.UserEvents(that._upArrow, { release: _release }); that._downArrow = arrows.eq(1); that._downArrowEventHandler = new kendo.UserEvents(that._downArrow, { release: _release }); }, _blur: function () { var that = this; that._toggleText(true); that._change(that.element.val()); }, _click: function (e) { var that = this; clearTimeout(that._focusing); that._focusing = setTimeout(function () { var input = e.target, idx = caret(input)[0], value = input.value.substring(0, idx), format = that._format(that.options.format), group = format[','], result, groupRegExp, extractRegExp, caretPosition = 0; if (group) { groupRegExp = new RegExp('\\' + group, 'g'); extractRegExp = new RegExp('([\\d\\' + group + ']+)(\\' + format[POINT] + ')?(\\d+)?'); } if (extractRegExp) { result = extractRegExp.exec(value); } if (result) { caretPosition = result[0].replace(groupRegExp, '').length; if (value.indexOf('(') != -1 && that._value < 0) { caretPosition++; } } that._focusin(); caret(that.element[0], caretPosition); }); }, _change: function (value) { var that = this; that._update(value); value = that._value; if (that._old != value) { that._old = value; if (!that._typing) { that.element.trigger(CHANGE); } that.trigger(CHANGE); } that._typing = false; }, _culture: function (culture) { return culture || getCulture(this.options.culture); }, _focusin: function () { var that = this; that._inputWrapper.addClass(FOCUSED); that._toggleText(false); that.element[0].focus(); }, _focusout: function () { var that = this; clearTimeout(that._focusing); that._inputWrapper.removeClass(FOCUSED).removeClass(HOVER); that._blur(); }, _format: function (format, culture) { var numberFormat = this._culture(culture).numberFormat; format = format.toLowerCase(); if (format.indexOf('c') > -1) { numberFormat = numberFormat.currency; } else if (format.indexOf('p') > -1) { numberFormat = numberFormat.percent; } return numberFormat; }, _input: function () { var that = this, CLASSNAME = 'k-formatted-value', element = that.element.addClass(INPUT).show()[0], accessKey = element.accessKey, wrapper = that.wrapper, text; text = wrapper.find(POINT + CLASSNAME); if (!text[0]) { text = $('<input type="text"/>').insertBefore(element).addClass(CLASSNAME); } try { element.setAttribute('type', 'text'); } catch (e) { element.type = 'text'; } text[0].tabIndex = element.tabIndex; text[0].style.cssText = element.style.cssText; text[0].title = element.title; text.prop('placeholder', that.options.placeholder); if (accessKey) { text.attr('accesskey', accessKey); element.accessKey = ''; } that._text = text.addClass(element.className); }, _keydown: function (e) { var that = this, key = e.keyCode; that._key = key; if (key == keys.DOWN) { that._step(-1); } else if (key == keys.UP) { that._step(1); } else if (key == keys.ENTER) { that._change(that.element.val()); } else { that._typing = true; } }, _keypress: function (e) { if (e.which === 0 || e.metaKey || e.ctrlKey || e.keyCode === keys.BACKSPACE || e.keyCode === keys.ENTER) { return; } var that = this; var min = that.options.min; var element = that.element; var selection = caret(element); var selectionStart = selection[0]; var selectionEnd = selection[1]; var character = String.fromCharCode(e.which); var numberFormat = that._format(that.options.format); var isNumPadDecimal = that._key === keys.NUMPAD_DOT; var value = element.val(); var isValid; if (isNumPadDecimal) { character = numberFormat[POINT]; } value = value.substring(0, selectionStart) + character + value.substring(selectionEnd); isValid = that._numericRegex(numberFormat).test(value); if (isValid && isNumPadDecimal) { element.val(value); caret(element, selectionStart + character.length); e.preventDefault(); } else if (min !== null && min >= 0 && value.charAt(0) === '-' || !isValid) { e.preventDefault(); } that._key = 0; }, _numericRegex: function (numberFormat) { var that = this; var separator = numberFormat[POINT]; var precision = that.options.decimals; if (separator === POINT) { separator = '\\' + separator; } if (precision === NULL) { precision = numberFormat.decimals; } if (precision === 0) { return INTEGER_REGEXP; } if (that._separator !== separator) { that._separator = separator; that._floatRegExp = new RegExp('^(-)?(((\\d+(' + separator + '\\d*)?)|(' + separator + '\\d*)))?$'); } return that._floatRegExp; }, _paste: function (e) { var that = this, element = e.target, value = element.value; setTimeout(function () { if (that._parse(element.value) === NULL) { that._update(value); } }); }, _option: function (option, value) { var that = this, options = that.options; if (value === undefined) { return options[option]; } value = that._parse(value); if (!value && option === 'step') { return; } options[option] = value; that.element.attr('aria-value' + option, value).attr(option, value); }, _spin: function (step, timeout) { var that = this; timeout = timeout || 500; clearTimeout(that._spinning); that._spinning = setTimeout(function () { that._spin(step, 50); }, timeout); that._step(step); }, _step: function (step) { var that = this, element = that.element, value = that._parse(element.val()) || 0; if (activeElement() != element[0]) { that._focusin(); } value += that.options.step * step; that._update(that._adjust(value)); that._typing = false; that.trigger(SPIN); }, _toggleHover: function (e) { $(e.currentTarget).toggleClass(HOVER, e.type === 'mouseenter'); }, _toggleText: function (toggle) { var that = this; that._text.toggle(toggle); that.element.toggle(!toggle); }, _parse: function (value, culture) { return parse(value, this._culture(culture), this.options.format); }, _update: function (value) { var that = this, options = that.options, format = options.format, decimals = options.decimals, culture = that._culture(), numberFormat = that._format(format, culture), isNotNull; if (decimals === NULL) { decimals = numberFormat.decimals; } value = that._parse(value, culture); isNotNull = value !== NULL; if (isNotNull) { value = parseFloat(round(value, decimals)); } that._value = value = that._adjust(value); that._placeholder(kendo.toString(value, format, culture)); if (isNotNull) { value = value.toString(); if (value.indexOf('e') !== -1) { value = round(+value, decimals); } value = value.replace(POINT, numberFormat[POINT]); } else { value = ''; } that.element.val(value).attr('aria-valuenow', value); }, _placeholder: function (value) { this._text.val(value); if (!placeholderSupported && !value) { this._text.val(this.options.placeholder); } }, _wrapper: function () { var that = this, element = that.element, DOMElement = element[0], wrapper; wrapper = element.parents('.k-numerictextbox'); if (!wrapper.is('span.k-numerictextbox')) { wrapper = element.hide().wrap('<span class="k-numeric-wrap k-state-default" />').parent(); wrapper = wrapper.wrap('<span/>').parent(); } wrapper[0].style.cssText = DOMElement.style.cssText; DOMElement.style.width = ''; that.wrapper = wrapper.addClass('k-widget k-numerictextbox').addClass(DOMElement.className).css('display', ''); that._inputWrapper = $(wrapper[0].firstChild); }, _reset: function () { var that = this, element = that.element, formId = element.attr('form'), form = formId ? $('#' + formId) : element.closest('form'); if (form[0]) { that._resetHandler = function () { setTimeout(function () { that.value(element[0].value); that.max(that._initialOptions.max); that.min(that._initialOptions.min); }); }; that._form = form.on('reset', that._resetHandler); } } }); function buttonHtml(className, text) { return '<span unselectable="on" class="k-link"><span unselectable="on" class="k-icon k-i-arrow-' + className + '" title="' + text + '">' + text + '</span></span>'; } ui.plugin(NumericTextBox); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.toolbar', [ 'kendo.core', 'kendo.userevents', 'kendo.popup' ], f); }(function () { var __meta__ = { id: 'toolbar', name: 'ToolBar', category: 'web', description: 'The ToolBar widget displays one or more command buttons divided into groups.', depends: ['core'] }; (function ($, undefined) { var kendo = window.kendo, Class = kendo.Class, Widget = kendo.ui.Widget, proxy = $.proxy, isFunction = kendo.isFunction, keys = kendo.keys, TOOLBAR = 'k-toolbar', BUTTON = 'k-button', OVERFLOW_BUTTON = 'k-overflow-button', TOGGLE_BUTTON = 'k-toggle-button', BUTTON_GROUP = 'k-button-group', SPLIT_BUTTON = 'k-split-button', SEPARATOR = 'k-separator', POPUP = 'k-popup', RESIZABLE_TOOLBAR = 'k-toolbar-resizable', STATE_ACTIVE = 'k-state-active', STATE_DISABLED = 'k-state-disabled', STATE_HIDDEN = 'k-state-hidden', GROUP_START = 'k-group-start', GROUP_END = 'k-group-end', PRIMARY = 'k-primary', ICON = 'k-icon', ICON_PREFIX = 'k-i-', BUTTON_ICON = 'k-button-icon', BUTTON_ICON_TEXT = 'k-button-icontext', LIST_CONTAINER = 'k-list-container k-split-container', SPLIT_BUTTON_ARROW = 'k-split-button-arrow', OVERFLOW_ANCHOR = 'k-overflow-anchor', OVERFLOW_CONTAINER = 'k-overflow-container', FIRST_TOOLBAR_VISIBLE = 'k-toolbar-first-visible', LAST_TOOLBAR_VISIBLE = 'k-toolbar-last-visible', CLICK = 'click', TOGGLE = 'toggle', OPEN = 'open', CLOSE = 'close', OVERFLOW_OPEN = 'overflowOpen', OVERFLOW_CLOSE = 'overflowClose', OVERFLOW_NEVER = 'never', OVERFLOW_AUTO = 'auto', OVERFLOW_ALWAYS = 'always', OVERFLOW_HIDDEN = 'k-overflow-hidden', KENDO_UID_ATTR = kendo.attr('uid'); kendo.toolbar = {}; var components = { overflowAnchor: '<div tabindex="0" class="k-overflow-anchor"></div>', overflowContainer: '<ul class="k-overflow-container k-list-container"></ul>' }; kendo.toolbar.registerComponent = function (name, toolbar, overflow) { components[name] = { toolbar: toolbar, overflow: overflow }; }; var Item = kendo.Class.extend({ addOverflowAttr: function () { this.element.attr(kendo.attr('overflow'), this.options.overflow || OVERFLOW_AUTO); }, addUidAttr: function () { this.element.attr(KENDO_UID_ATTR, this.options.uid); }, addIdAttr: function () { if (this.options.id) { this.element.attr('id', this.options.id); } }, addOverflowIdAttr: function () { if (this.options.id) { this.element.attr('id', this.options.id + '_overflow'); } }, attributes: function () { if (this.options.attributes) { this.element.attr(this.options.attributes); } }, show: function () { this.element.removeClass(STATE_HIDDEN).show(); this.options.hidden = false; }, hide: function () { this.element.addClass(STATE_HIDDEN).hide(); this.options.hidden = true; }, remove: function () { this.element.remove(); }, enable: function (isEnabled) { if (isEnabled === undefined) { isEnabled = true; } this.element.toggleClass(STATE_DISABLED, !isEnabled); this.options.enable = isEnabled; }, twin: function () { var uid = this.element.attr(KENDO_UID_ATTR); if (this.overflow) { return this.toolbar.element.find('[' + KENDO_UID_ATTR + '=\'' + uid + '\']').data(this.options.type); } else if (this.toolbar.options.resizable) { return this.toolbar.popup.element.find('[' + KENDO_UID_ATTR + '=\'' + uid + '\']').data(this.options.type); } } }); kendo.toolbar.Item = Item; var Button = Item.extend({ init: function (options, toolbar) { var element = options.useButtonTag ? $('<button tabindex="0"></button>') : $('<a href tabindex="0"></a>'); this.element = element; this.options = options; this.toolbar = toolbar; this.attributes(); if (options.primary) { element.addClass(PRIMARY); } if (options.togglable) { element.addClass(TOGGLE_BUTTON); this.toggle(options.selected); } if (options.url !== undefined && !options.useButtonTag) { element.attr('href', options.url); if (options.mobile) { element.attr(kendo.attr('role'), 'button'); } } if (options.group) { element.attr(kendo.attr('group'), options.group); this.group = this.toolbar.addToGroup(this, options.group); } if (!options.togglable && options.click && isFunction(options.click)) { this.clickHandler = options.click; } if (options.togglable && options.toggle && isFunction(options.toggle)) { this.toggleHandler = options.toggle; } }, toggle: function (state, propagate) { state = !!state; if (this.group && state) { this.group.select(this); } else if (!this.group) { this.select(state); } if (propagate && this.twin()) { this.twin().toggle(state); } }, getParentGroup: function () { if (this.options.isChild) { return this.element.closest('.' + BUTTON_GROUP).data('buttonGroup'); } }, _addGraphics: function () { var element = this.element, icon = this.options.icon, spriteCssClass = this.options.spriteCssClass, imageUrl = this.options.imageUrl, isEmpty, span, img; if (spriteCssClass || imageUrl || icon) { isEmpty = true; element.contents().not('span.k-sprite,span.' + ICON + ',img.k-image').each(function (idx, el) { if (el.nodeType == 1 || el.nodeType == 3 && $.trim(el.nodeValue).length > 0) { isEmpty = false; } }); if (isEmpty) { element.addClass(BUTTON_ICON); } else { element.addClass(BUTTON_ICON_TEXT); } } if (icon) { span = element.children('span.' + ICON).first(); if (!span[0]) { span = $('<span class="' + ICON + '"></span>').prependTo(element); } span.addClass(ICON_PREFIX + icon); } else if (spriteCssClass) { span = element.children('span.k-sprite').first(); if (!span[0]) { span = $('<span class="k-sprite"></span>').prependTo(element); } span.addClass(spriteCssClass); } else if (imageUrl) { img = element.children('img.k-image').first(); if (!img[0]) { img = $('<img alt="icon" class="k-image" />').prependTo(element); } img.attr('src', imageUrl); } } }); kendo.toolbar.Button = Button; var ToolBarButton = Button.extend({ init: function (options, toolbar) { Button.fn.init.call(this, options, toolbar); var element = this.element; element.addClass(BUTTON); this.addIdAttr(); if (options.align) { element.addClass('k-align-' + options.align); } if (options.showText != 'overflow' && options.text) { if (options.mobile) { element.html('<span class="km-text">' + options.text + '</span>'); } else { element.html(options.text); } } options.hasIcon = options.showIcon != 'overflow' && (options.icon || options.spriteCssClass || options.imageUrl); if (options.hasIcon) { this._addGraphics(); } this.addUidAttr(); this.addOverflowAttr(); this.enable(options.enable); if (options.hidden) { this.hide(); } this.element.data({ type: 'button', button: this }); }, select: function (selected) { if (selected === undefined) { selected = false; } this.element.toggleClass(STATE_ACTIVE, selected); this.options.selected = selected; } }); kendo.toolbar.ToolBarButton = ToolBarButton; var OverflowButton = Button.extend({ init: function (options, toolbar) { this.overflow = true; Button.fn.init.call(this, options, toolbar); var element = this.element; if (options.showText != 'toolbar' && options.text) { if (options.mobile) { element.html('<span class="km-text">' + options.text + '</span>'); } else { element.html('<span class="k-text">' + options.text + '</span>'); } } options.hasIcon = options.showIcon != 'toolbar' && (options.icon || options.spriteCssClass || options.imageUrl); if (options.hasIcon) { this._addGraphics(); } if (!options.isChild) { this._wrap(); } this.addOverflowIdAttr(); this.attributes(); this.addUidAttr(); this.addOverflowAttr(); this.enable(options.enable); element.addClass(OVERFLOW_BUTTON + ' ' + BUTTON); if (options.hidden) { this.hide(); } this.element.data({ type: 'button', button: this }); }, _wrap: function () { this.element = this.element.wrap('<li></li>').parent(); }, overflowHidden: function () { this.element.addClass(OVERFLOW_HIDDEN); }, select: function (selected) { if (selected === undefined) { selected = false; } if (this.options.isChild) { this.element.toggleClass(STATE_ACTIVE, selected); } else { this.element.find('.k-button').toggleClass(STATE_ACTIVE, selected); } this.options.selected = selected; } }); kendo.toolbar.OverflowButton = OverflowButton; kendo.toolbar.registerComponent('button', ToolBarButton, OverflowButton); var ButtonGroup = Item.extend({ createButtons: function (buttonConstructor) { var options = this.options; var items = options.buttons || []; var item; for (var i = 0; i < items.length; i++) { if (!items[i].uid) { items[i].uid = kendo.guid(); } item = new buttonConstructor($.extend({ mobile: options.mobile, isChild: true, type: 'button' }, items[i]), this.toolbar); item.element.appendTo(this.element); } }, refresh: function () { this.element.children().filter(':not(\'.' + STATE_HIDDEN + '\'):first').addClass(GROUP_START); this.element.children().filter(':not(\'.' + STATE_HIDDEN + '\'):last').addClass(GROUP_END); } }); kendo.toolbar.ButtonGroup = ButtonGroup; var ToolBarButtonGroup = ButtonGroup.extend({ init: function (options, toolbar) { var element = this.element = $('<div></div>'); this.options = options; this.toolbar = toolbar; this.addIdAttr(); if (options.align) { element.addClass('k-align-' + options.align); } this.createButtons(ToolBarButton); this.attributes(); this.addUidAttr(); this.addOverflowAttr(); this.refresh(); element.addClass(BUTTON_GROUP); this.element.data({ type: 'buttonGroup', buttonGroup: this }); } }); kendo.toolbar.ToolBarButtonGroup = ToolBarButtonGroup; var OverflowButtonGroup = ButtonGroup.extend({ init: function (options, toolbar) { var element = this.element = $('<li></li>'); this.options = options; this.toolbar = toolbar; this.overflow = true; this.addOverflowIdAttr(); this.createButtons(OverflowButton); this.attributes(); this.addUidAttr(); this.addOverflowAttr(); this.refresh(); element.addClass((options.mobile ? '' : BUTTON_GROUP) + ' k-overflow-group'); this.element.data({ type: 'buttonGroup', buttonGroup: this }); }, overflowHidden: function () { this.element.addClass(OVERFLOW_HIDDEN); } }); kendo.toolbar.OverflowButtonGroup = OverflowButtonGroup; kendo.toolbar.registerComponent('buttonGroup', ToolBarButtonGroup, OverflowButtonGroup); var ToolBarSplitButton = Item.extend({ init: function (options, toolbar) { var element = this.element = $('<div class="' + SPLIT_BUTTON + '" tabindex="0"></div>'); this.options = options; this.toolbar = toolbar; this.mainButton = new ToolBarButton($.extend({}, options, { hidden: false }), toolbar); this.arrowButton = $('<a class="' + BUTTON + ' ' + SPLIT_BUTTON_ARROW + '"><span class="' + (options.mobile ? 'km-icon km-arrowdown' : 'k-icon k-i-arrow-s') + '"></span></a>'); this.popupElement = $('<ul class="' + LIST_CONTAINER + '"></ul>'); this.mainButton.element.removeAttr('href tabindex').appendTo(element); this.arrowButton.appendTo(element); this.popupElement.appendTo(element); if (options.align) { element.addClass('k-align-' + options.align); } if (!options.id) { options.id = options.uid; } element.attr('id', options.id + '_wrapper'); this.addOverflowAttr(); this.addUidAttr(); this.createMenuButtons(); this.createPopup(); this._navigatable(); this.mainButton.main = true; this.enable(options.enable); if (options.hidden) { this.hide(); } element.data({ type: 'splitButton', splitButton: this, kendoPopup: this.popup }); }, _navigatable: function () { var that = this; that.popupElement.on('keydown', '.' + BUTTON, function (e) { var li = $(e.target).parent(); e.preventDefault(); if (e.keyCode === keys.ESC || e.keyCode === keys.TAB || e.altKey && e.keyCode === keys.UP) { that.toggle(); that.focus(); } else if (e.keyCode === keys.DOWN) { findFocusableSibling(li, 'next').focus(); } else if (e.keyCode === keys.UP) { findFocusableSibling(li, 'prev').focus(); } else if (e.keyCode === keys.SPACEBAR || e.keyCode === keys.ENTER) { that.toolbar.userEvents.trigger('tap', { target: $(e.target) }); } }); }, createMenuButtons: function () { var options = this.options; var items = options.menuButtons; var item; for (var i = 0; i < items.length; i++) { item = new ToolBarButton($.extend({ mobile: options.mobile, type: 'button', click: options.click }, items[i]), this.toolbar); item.element.wrap('<li></li>').parent().appendTo(this.popupElement); } }, createPopup: function () { var options = this.options; var element = this.element; this.popupElement.attr('id', options.id + '_optionlist').attr(KENDO_UID_ATTR, options.rootUid); if (options.mobile) { this.popupElement = actionSheetWrap(this.popupElement); } this.popup = this.popupElement.kendoPopup({ appendTo: options.mobile ? $(options.mobile).children('.km-pane') : null, anchor: element, isRtl: this.toolbar._isRtl, copyAnchorStyles: false, animation: options.animation, open: adjustPopupWidth, activate: function () { this.element.find(':kendoFocusable').first().focus(); }, close: function () { element.focus(); } }).data('kendoPopup'); this.popup.element.on(CLICK, 'a.k-button', preventClick); }, remove: function () { this.popup.element.off(CLICK, 'a.k-button'); this.popup.destroy(); this.element.remove(); }, toggle: function () { this.popup.toggle(); }, enable: function (isEnabled) { if (isEnabled === undefined) { isEnabled = true; } this.mainButton.enable(isEnabled); this.options.enable = isEnabled; }, focus: function () { this.element.focus(); }, hide: function () { if (this.popup) { this.popup.close(); } this.element.addClass(STATE_HIDDEN).hide(); this.options.hidden = true; }, show: function () { this.element.removeClass(STATE_HIDDEN).hide(); this.options.hidden = false; } }); kendo.toolbar.ToolBarSplitButton = ToolBarSplitButton; var OverflowSplitButton = Item.extend({ init: function (options, toolbar) { var element = this.element = $('<li class="' + SPLIT_BUTTON + '"></li>'), items = options.menuButtons, item; this.options = options; this.toolbar = toolbar; this.overflow = true; this.mainButton = new OverflowButton($.extend({ isChild: true }, options)); this.mainButton.element.appendTo(element); for (var i = 0; i < items.length; i++) { item = new OverflowButton($.extend({ mobile: options.mobile, isChild: true }, items[i]), this.toolbar); item.element.appendTo(element); } this.addUidAttr(); this.addOverflowAttr(); this.mainButton.main = true; element.data({ type: 'splitButton', splitButton: this }); }, overflowHidden: function () { this.element.addClass(OVERFLOW_HIDDEN); } }); kendo.toolbar.OverflowSplitButton = OverflowSplitButton; kendo.toolbar.registerComponent('splitButton', ToolBarSplitButton, OverflowSplitButton); var ToolBarSeparator = Item.extend({ init: function (options, toolbar) { var element = this.element = $('<div> </div>'); this.element = element; this.options = options; this.toolbar = toolbar; this.attributes(); this.addIdAttr(); this.addUidAttr(); this.addOverflowAttr(); element.addClass(SEPARATOR); element.data({ type: 'separator', separator: this }); } }); var OverflowSeparator = Item.extend({ init: function (options, toolbar) { var element = this.element = $('<li> </li>'); this.element = element; this.options = options; this.toolbar = toolbar; this.overflow = true; this.attributes(); this.addUidAttr(); this.addOverflowIdAttr(); element.addClass(SEPARATOR); element.data({ type: 'separator', separator: this }); }, overflowHidden: function () { this.element.addClass(OVERFLOW_HIDDEN); } }); kendo.toolbar.registerComponent('separator', ToolBarSeparator, OverflowSeparator); var TemplateItem = Item.extend({ init: function (template, options, toolbar) { var element = isFunction(template) ? template(options) : template; if (!(element instanceof jQuery)) { element = $('<div></div>').html(element); } else { element = element.wrap('<div></div>').parent(); } this.element = element; this.options = options; this.options.type = 'template'; this.toolbar = toolbar; this.attributes(); this.addUidAttr(); this.addIdAttr(); this.addOverflowAttr(); element.data({ type: 'template', template: this }); } }); kendo.toolbar.TemplateItem = TemplateItem; var OverflowTemplateItem = Item.extend({ init: function (template, options, toolbar) { var element = isFunction(template) ? $(template(options)) : $(template); if (!(element instanceof jQuery)) { element = $('<li></li>').html(element); } else { element = element.wrap('<li></li>').parent(); } this.element = element; this.options = options; this.options.type = 'template'; this.toolbar = toolbar; this.overflow = true; this.attributes(); this.addUidAttr(); this.addOverflowIdAttr(); this.addOverflowAttr(); element.data({ type: 'template', template: this }); }, overflowHidden: function () { this.element.addClass(OVERFLOW_HIDDEN); } }); kendo.toolbar.OverflowTemplateItem = OverflowTemplateItem; function adjustPopupWidth() { var anchor = this.options.anchor, computedWidth = anchor.outerWidth(), width; kendo.wrap(this.element).addClass('k-split-wrapper'); if (this.element.css('box-sizing') !== 'border-box') { width = computedWidth - (this.element.outerWidth() - this.element.width()); } else { width = computedWidth; } this.element.css({ fontFamily: anchor.css('font-family'), 'min-width': width }); } function toggleActive(e) { if (!e.target.is('.k-toggle-button')) { e.target.toggleClass(STATE_ACTIVE, e.type == 'press'); } } function actionSheetWrap(element) { element = $(element); return element.hasClass('km-actionsheet') ? element.closest('.km-popup-wrapper') : element.addClass('km-widget km-actionsheet').wrap('<div class="km-actionsheet-wrapper km-actionsheet-tablet km-widget km-popup"></div>').parent().wrap('<div class="km-popup-wrapper k-popup"></div>').parent(); } function preventClick(e) { e.preventDefault(); } function findFocusableSibling(element, dir) { var getSibling = dir === 'next' ? $.fn.next : $.fn.prev; var getter = dir === 'next' ? $.fn.first : $.fn.last; var candidate = getSibling.call(element); if (candidate.is(':kendoFocusable') || !candidate.length) { return candidate; } if (candidate.find(':kendoFocusable').length) { return getter.call(candidate.find(':kendoFocusable')); } return findFocusableSibling(candidate, dir); } var Group = Class.extend({ init: function (name) { this.name = name; this.buttons = []; }, add: function (button) { this.buttons[this.buttons.length] = button; }, remove: function (button) { var index = $.inArray(button, this.buttons); this.buttons.splice(index, 1); }, select: function (button) { var tmp; for (var i = 0; i < this.buttons.length; i++) { tmp = this.buttons[i]; tmp.select(false); } button.select(true); if (button.twin()) { button.twin().select(true); } } }); var ToolBar = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); options = that.options; element = that.wrapper = that.element; element.addClass(TOOLBAR + ' k-widget'); this.uid = kendo.guid(); this._isRtl = kendo.support.isRtl(element); this._groups = {}; element.attr(KENDO_UID_ATTR, this.uid); that.isMobile = typeof options.mobile === 'boolean' ? options.mobile : that.element.closest('.km-root')[0]; that.animation = that.isMobile ? { open: { effects: 'fade' } } : {}; if (that.isMobile) { element.addClass('km-widget'); ICON = 'km-icon'; ICON_PREFIX = 'km-'; BUTTON = 'km-button'; BUTTON_GROUP = 'km-buttongroup km-widget'; STATE_ACTIVE = 'km-state-active'; STATE_DISABLED = 'km-state-disabled'; } if (options.resizable) { that._renderOverflow(); element.addClass(RESIZABLE_TOOLBAR); that.overflowUserEvents = new kendo.UserEvents(that.element, { threshold: 5, allowSelection: true, filter: '.' + OVERFLOW_ANCHOR, tap: proxy(that._toggleOverflow, that) }); that._resizeHandler = kendo.onResize(function () { that.resize(); }); } else { that.popup = { element: $([]) }; } if (options.items && options.items.length) { for (var i = 0; i < options.items.length; i++) { that.add(options.items[i]); } } that.userEvents = new kendo.UserEvents(document, { threshold: 5, allowSelection: true, filter: '[' + KENDO_UID_ATTR + '=' + this.uid + '] a.' + BUTTON + ', ' + '[' + KENDO_UID_ATTR + '=' + this.uid + '] .' + OVERFLOW_BUTTON, tap: proxy(that._buttonClick, that), press: toggleActive, release: toggleActive }); that.element.on(CLICK, 'a.k-button', preventClick); that._navigatable(); if (options.resizable) { that.popup.element.on(CLICK, +'a.k-button', preventClick); } if (options.resizable) { this._toggleOverflowAnchor(); } kendo.notify(that); }, events: [ CLICK, TOGGLE, OPEN, CLOSE, OVERFLOW_OPEN, OVERFLOW_CLOSE ], options: { name: 'ToolBar', items: [], resizable: true, mobile: null }, addToGroup: function (button, groupName) { var group; if (!this._groups[groupName]) { group = this._groups[groupName] = new Group(); } else { group = this._groups[groupName]; } group.add(button); return group; }, destroy: function () { var that = this; that.element.find('.' + SPLIT_BUTTON).each(function (idx, element) { $(element).data('kendoPopup').destroy(); }); that.element.off(CLICK, 'a.k-button'); that.userEvents.destroy(); if (that.options.resizable) { kendo.unbindResize(that._resizeHandler); that.overflowUserEvents.destroy(); that.popup.element.off(CLICK, 'a.k-button'); that.popup.destroy(); } Widget.fn.destroy.call(that); }, add: function (options) { var component = components[options.type], template = options.template, tool, that = this, itemClasses = that.isMobile ? '' : 'k-item k-state-default', overflowTemplate = options.overflowTemplate, overflowTool; $.extend(options, { uid: kendo.guid(), animation: that.animation, mobile: that.isMobile, rootUid: that.uid }); if (options.menuButtons) { for (var i = 0; i < options.menuButtons.length; i++) { $.extend(options.menuButtons[i], { uid: kendo.guid() }); } } if (template && !overflowTemplate) { options.overflow = OVERFLOW_NEVER; } else if (!options.overflow) { options.overflow = OVERFLOW_AUTO; } if (options.overflow !== OVERFLOW_NEVER && that.options.resizable) { if (overflowTemplate) { overflowTool = new OverflowTemplateItem(overflowTemplate, options, that); } else if (component) { overflowTool = new component.overflow(options, that); overflowTool.element.addClass(itemClasses); } if (overflowTool) { if (options.overflow === OVERFLOW_AUTO) { overflowTool.overflowHidden(); } overflowTool.element.appendTo(that.popup.container); that.angular('compile', function () { return { elements: overflowTool.element.get() }; }); } } if (options.overflow !== OVERFLOW_ALWAYS) { if (template) { tool = new TemplateItem(template, options, that); } else if (component) { tool = new component.toolbar(options, that); } if (tool) { if (that.options.resizable) { tool.element.appendTo(that.element).css('visibility', 'hidden'); that._shrink(that.element.innerWidth()); tool.element.css('visibility', 'visible'); } else { tool.element.appendTo(that.element); } that.angular('compile', function () { return { elements: tool.element.get() }; }); } } }, _getItem: function (candidate) { var element, toolbarItem, overflowItem, isResizable = this.options.resizable, type; element = this.element.find(candidate); if (!element.length) { element = $('.k-split-container[data-uid=' + this.uid + ']').find(candidate); } type = element.length ? element.data('type') : ''; toolbarItem = element.data(type); if (toolbarItem) { if (toolbarItem.main) { element = element.parent('.' + SPLIT_BUTTON); type = 'splitButton'; toolbarItem = element.data(type); } if (isResizable) { overflowItem = toolbarItem.twin(); } } else if (isResizable) { element = this.popup.element.find(candidate); type = element.length ? element.data('type') : ''; overflowItem = element.data(type); if (overflowItem && overflowItem.main) { element = element.parent('.' + SPLIT_BUTTON); type = 'splitButton'; overflowItem = element.data(type); } } return { type: type, toolbar: toolbarItem, overflow: overflowItem }; }, remove: function (candidate) { var item = this._getItem(candidate); if (item.toolbar) { item.toolbar.remove(); } if (item.overflow) { item.overflow.remove(); } this.resize(true); }, hide: function (candidate) { var item = this._getItem(candidate); if (item.toolbar) { if (item.toolbar.options.type === 'button' && item.toolbar.options.isChild) { item.toolbar.hide(); item.toolbar.getParentGroup().refresh(); } else if (!item.toolbar.options.hidden) { item.toolbar.hide(); } } if (item.overflow) { if (item.overflow.options.type === 'button' && item.overflow.options.isChild) { item.overflow.hide(); item.overflow.getParentGroup().refresh(); } else if (!item.toolbar.options.hidden) { item.overflow.hide(); } } this.resize(true); }, show: function (candidate) { var item = this._getItem(candidate); if (item.toolbar) { if (item.toolbar.options.type === 'button' && item.toolbar.options.isChild) { item.toolbar.show(); item.toolbar.getParentGroup().refresh(); } else if (item.toolbar.options.hidden) { item.toolbar.show(); } } if (item.overflow) { if (item.overflow.options.type === 'button' && item.overflow.options.isChild) { item.toolbar.show(); item.overflow.getParentGroup().refresh(); } else if (item.overflow.options.hidden) { item.overflow.show(); } } this.resize(true); }, enable: function (element, enable) { var item = this._getItem(element); if (typeof enable == 'undefined') { enable = true; } if (item.toolbar) { item.toolbar.enable(enable); } if (item.overflow) { item.overflow.enable(enable); } }, getSelectedFromGroup: function (groupName) { return this.element.find('.' + TOGGLE_BUTTON + '[data-group=\'' + groupName + '\']').filter('.' + STATE_ACTIVE); }, toggle: function (button, checked) { var element = $(button), item = element.data('button'); if (item.options.togglable) { if (checked === undefined) { checked = true; } item.toggle(checked, true); } }, _renderOverflow: function () { var that = this, overflowContainer = components.overflowContainer, isRtl = that._isRtl, horizontalDirection = isRtl ? 'left' : 'right'; that.overflowAnchor = $(components.overflowAnchor).addClass(BUTTON); that.element.append(that.overflowAnchor); if (that.isMobile) { that.overflowAnchor.append('<span class="km-icon km-more"></span>'); overflowContainer = actionSheetWrap(overflowContainer); } else { that.overflowAnchor.append('<span class="k-icon k-i-arrow-s"></span>'); } that.popup = new kendo.ui.Popup(overflowContainer, { origin: 'bottom ' + horizontalDirection, position: 'top ' + horizontalDirection, anchor: that.overflowAnchor, isRtl: isRtl, animation: that.animation, appendTo: that.isMobile ? $(that.isMobile).children('.km-pane') : null, copyAnchorStyles: false, open: function (e) { var wrapper = kendo.wrap(that.popup.element).addClass('k-overflow-wrapper'); if (!that.isMobile) { wrapper.css('margin-left', (isRtl ? -1 : 1) * ((wrapper.outerWidth() - wrapper.width()) / 2 + 1)); } else { that.popup.container.css('max-height', parseFloat($('.km-content:visible').innerHeight()) - 15 + 'px'); } if (that.trigger(OVERFLOW_OPEN)) { e.preventDefault(); } }, activate: function () { this.element.find(':kendoFocusable').first().focus(); }, close: function (e) { if (that.trigger(OVERFLOW_CLOSE)) { e.preventDefault(); } this.element.focus(); } }); that.popup.element.on('keydown', '.' + BUTTON, function (e) { var target = $(e.target), li = target.parent(), isComplexTool = li.is('.' + BUTTON_GROUP) || li.is('.' + SPLIT_BUTTON), element; e.preventDefault(); if (e.keyCode === keys.ESC || e.keyCode === keys.TAB || e.altKey && e.keyCode === keys.UP) { that._toggleOverflow(); that.overflowAnchor.focus(); } else if (e.keyCode === keys.DOWN) { element = !isComplexTool || isComplexTool && target.is(':last-child') ? li : target; findFocusableSibling(element, 'next').focus(); } else if (e.keyCode === keys.UP) { element = !isComplexTool || isComplexTool && target.is(':first-child') ? li : target; findFocusableSibling(element, 'prev').focus(); } else if (e.keyCode === keys.SPACEBAR || e.keyCode === keys.ENTER) { that.userEvents.trigger('tap', { target: $(e.target) }); } }); if (that.isMobile) { that.popup.container = that.popup.element.find('.' + OVERFLOW_CONTAINER); } else { that.popup.container = that.popup.element; } that.popup.container.attr(KENDO_UID_ATTR, this.uid); }, _toggleOverflowAnchor: function () { var hasVisibleChildren = false; if (this.options.mobile) { hasVisibleChildren = this.popup.element.find('.' + OVERFLOW_CONTAINER).children(':not(.' + OVERFLOW_HIDDEN + ', .' + POPUP + ')').length > 0; } else { hasVisibleChildren = this.popup.element.children(':not(.' + OVERFLOW_HIDDEN + ', .' + POPUP + ')').length > 0; } if (hasVisibleChildren) { this.overflowAnchor.css({ visibility: 'visible', width: '' }); } else { this.overflowAnchor.css({ visibility: 'hidden', width: '1px' }); } }, _buttonClick: function (e) { var that = this, popup, target, item, splitContainer, isSplitButtonArrow = e.target.closest('.' + SPLIT_BUTTON_ARROW).length, handler, eventData, urlTarget; e.preventDefault(); if (isSplitButtonArrow) { that._toggle(e); return; } target = $(e.target).closest('.' + BUTTON, that.element); if (target.hasClass(OVERFLOW_ANCHOR)) { return; } item = target.data('button'); if (!item && that.popup) { target = $(e.target).closest('.' + OVERFLOW_BUTTON, that.popup.container); item = target.parent('li').data('button'); } if (!item || !item.options.enable) { return; } if (item.options.togglable) { handler = isFunction(item.toggleHandler) ? item.toggleHandler : null; item.toggle(!item.options.selected, true); eventData = { target: target, group: item.options.group, checked: item.options.selected, id: item.options.id }; if (handler) { handler.call(that, eventData); } that.trigger(TOGGLE, eventData); } else { handler = isFunction(item.clickHandler) ? item.clickHandler : null; eventData = { sender: that, target: target, id: item.options.id }; if (handler) { handler.call(that, eventData); } that.trigger(CLICK, eventData); } if (item.options.url) { if (item.options.attributes && item.options.attributes.target) { urlTarget = item.options.attributes.target; } window.open(item.options.url, urlTarget || '_self'); } if (target.hasClass(OVERFLOW_BUTTON)) { that.popup.close(); } splitContainer = target.closest('.k-split-container'); if (splitContainer[0]) { popup = splitContainer.data('kendoPopup'); (popup ? popup : splitContainer.parents('.km-popup-wrapper').data('kendoPopup')).close(); } }, _navigatable: function () { var that = this; that.element.attr('tabindex', 0).focus(function () { var element = $(this).find(':kendoFocusable:first'); if (element.is('.' + OVERFLOW_ANCHOR)) { element = findFocusableSibling(element, 'next'); } element[0].focus(); }).on('keydown', proxy(that._keydown, that)); }, _keydown: function (e) { var target = $(e.target), keyCode = e.keyCode, items = this.element.children(':not(.k-separator):visible'); if (keyCode === keys.TAB) { var element = target.parentsUntil(this.element).last(), lastHasFocus = false, firstHasFocus = false; if (!element.length) { element = target; } if (element.is('.' + OVERFLOW_ANCHOR)) { if (e.shiftKey) { e.preventDefault(); } if (items.last().is(':kendoFocusable')) { items.last().focus(); } else { items.last().find(':kendoFocusable').last().focus(); } } if (!e.shiftKey && items.index(element) === items.length - 1) { if (element.is('.' + BUTTON_GROUP)) { lastHasFocus = target.is(':last-child'); } else { lastHasFocus = true; } } if (e.shiftKey && items.index(element) === 1) { if (element.is('.' + BUTTON_GROUP)) { firstHasFocus = target.is(':first-child'); } else { firstHasFocus = true; } } if (lastHasFocus && this.overflowAnchor && this.overflowAnchor.css('visibility') !== 'hidden') { e.preventDefault(); this.overflowAnchor.focus(); } if (firstHasFocus) { e.preventDefault(); this.wrapper.prev(':kendoFocusable').focus(); } } if (e.altKey && keyCode === keys.DOWN) { var splitButton = $(document.activeElement).data('splitButton'); var isOverflowAnchor = $(document.activeElement).is('.' + OVERFLOW_ANCHOR); if (splitButton) { splitButton.toggle(); } else if (isOverflowAnchor) { this._toggleOverflow(); } return; } if ((keyCode === keys.SPACEBAR || keyCode === keys.ENTER) && !target.is('input, checkbox')) { e.preventDefault(); if (target.is('.' + SPLIT_BUTTON)) { target = target.children().first(); } this.userEvents.trigger('tap', { target: target }); return; } }, _toggle: function (e) { var splitButton = $(e.target).closest('.' + SPLIT_BUTTON).data('splitButton'), isDefaultPrevented; e.preventDefault(); if (!splitButton.options.enable) { return; } if (splitButton.popup.element.is(':visible')) { isDefaultPrevented = this.trigger(CLOSE, { target: splitButton.element }); } else { isDefaultPrevented = this.trigger(OPEN, { target: splitButton.element }); } if (!isDefaultPrevented) { splitButton.toggle(); } }, _toggleOverflow: function () { this.popup.toggle(); }, _resize: function (e) { var containerWidth = e.width; if (!this.options.resizable) { return; } this.popup.close(); this._shrink(containerWidth); this._stretch(containerWidth); this._markVisibles(); this._toggleOverflowAnchor(); }, _childrenWidth: function () { var childrenWidth = 0; this.element.children(':visible:not(\'.' + STATE_HIDDEN + '\')').each(function () { childrenWidth += $(this).outerWidth(true); }); return Math.ceil(childrenWidth); }, _shrink: function (containerWidth) { var commandElement, visibleCommands; if (containerWidth < this._childrenWidth()) { visibleCommands = this.element.children(':visible:not([data-overflow=\'never\'], .' + OVERFLOW_ANCHOR + ')'); for (var i = visibleCommands.length - 1; i >= 0; i--) { commandElement = visibleCommands.eq(i); if (containerWidth > this._childrenWidth()) { break; } else { this._hideItem(commandElement); } } } }, _stretch: function (containerWidth) { var commandElement, hiddenCommands; if (containerWidth > this._childrenWidth()) { hiddenCommands = this.element.children(':hidden:not(\'.' + STATE_HIDDEN + '\')'); for (var i = 0; i < hiddenCommands.length; i++) { commandElement = hiddenCommands.eq(i); if (containerWidth < this._childrenWidth() || !this._showItem(commandElement, containerWidth)) { break; } } } }, _hideItem: function (item) { item.hide(); if (this.popup) { this.popup.container.find('>li[data-uid=\'' + item.data('uid') + '\']').removeClass(OVERFLOW_HIDDEN); } }, _showItem: function (item, containerWidth) { if (item.length && containerWidth > this._childrenWidth() + item.outerWidth(true)) { item.show(); if (this.popup) { this.popup.container.find('>li[data-uid=\'' + item.data('uid') + '\']').addClass(OVERFLOW_HIDDEN); } return true; } return false; }, _markVisibles: function () { var overflowItems = this.popup.container.children(), toolbarItems = this.element.children(':not(.k-overflow-anchor)'), visibleOverflowItems = overflowItems.filter(':not(.k-overflow-hidden)'), visibleToolbarItems = toolbarItems.filter(':visible'); overflowItems.add(toolbarItems).removeClass(FIRST_TOOLBAR_VISIBLE + ' ' + LAST_TOOLBAR_VISIBLE); visibleOverflowItems.first().add(visibleToolbarItems.first()).addClass(FIRST_TOOLBAR_VISIBLE); visibleOverflowItems.last().add(visibleToolbarItems.last()).addClass(LAST_TOOLBAR_VISIBLE); } }); kendo.ui.plugin(ToolBar); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.panelbar', ['kendo.core'], f); }(function () { var __meta__ = { id: 'panelbar', name: 'PanelBar', category: 'web', description: 'The PanelBar widget displays hierarchical data as a multi-level expandable panel bar.', depends: ['core'] }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, keys = kendo.keys, extend = $.extend, each = $.each, template = kendo.template, Widget = ui.Widget, excludedNodesRegExp = /^(ul|a|div)$/i, NS = '.kendoPanelBar', IMG = 'img', HREF = 'href', LAST = 'k-last', LINK = 'k-link', LINKSELECTOR = '.' + LINK, ERROR = 'error', ITEM = '.k-item', GROUP = '.k-group', VISIBLEGROUP = GROUP + ':visible', IMAGE = 'k-image', FIRST = 'k-first', EXPAND = 'expand', SELECT = 'select', CONTENT = 'k-content', ACTIVATE = 'activate', COLLAPSE = 'collapse', MOUSEENTER = 'mouseenter', MOUSELEAVE = 'mouseleave', CONTENTLOAD = 'contentLoad', ACTIVECLASS = 'k-state-active', GROUPS = '> .k-panel', CONTENTS = '> .k-content', FOCUSEDCLASS = 'k-state-focused', DISABLEDCLASS = 'k-state-disabled', SELECTEDCLASS = 'k-state-selected', SELECTEDSELECTOR = '.' + SELECTEDCLASS, HIGHLIGHTCLASS = 'k-state-highlight', ACTIVEITEMSELECTOR = ITEM + ':not(.k-state-disabled)', clickableItems = '> ' + ACTIVEITEMSELECTOR + ' > ' + LINKSELECTOR + ', .k-panel > ' + ACTIVEITEMSELECTOR + ' > ' + LINKSELECTOR, disabledItems = ITEM + '.k-state-disabled > .k-link', selectableItems = '> li > ' + SELECTEDSELECTOR + ', .k-panel > li > ' + SELECTEDSELECTOR, defaultState = 'k-state-default', ARIA_DISABLED = 'aria-disabled', ARIA_EXPANDED = 'aria-expanded', ARIA_HIDDEN = 'aria-hidden', ARIA_SELECTED = 'aria-selected', VISIBLE = ':visible', EMPTY = ':empty', SINGLE = 'single', templates = { content: template('<div role=\'region\' class=\'k-content\'#= contentAttributes(data) #>#= content(item) #</div>'), group: template('<ul role=\'group\' aria-hidden=\'true\' class=\'#= groupCssClass(group) #\'#= groupAttributes(group) #>' + '#= renderItems(data) #' + '</ul>'), itemWrapper: template('<#= tag(item) # class=\'#= textClass(item, group) #\' #= contentUrl(item) ##= textAttributes(item) #>' + '#= image(item) ##= sprite(item) ##= text(item) #' + '#= arrow(data) #' + '</#= tag(item) #>'), item: template('<li role=\'menuitem\' #=aria(item)#class=\'#= wrapperCssClass(group, item) #\'>' + '#= itemWrapper(data) #' + '# if (item.items) { #' + '#= subGroup({ items: item.items, panelBar: panelBar, group: { expanded: item.expanded } }) #' + '# } else if (item.content || item.contentUrl) { #' + '#= renderContent(data) #' + '# } #' + '</li>'), image: template('<img class=\'k-image\' alt=\'\' src=\'#= imageUrl #\' />'), arrow: template('<span class=\'#= arrowClass(item) #\'></span>'), sprite: template('<span class=\'k-sprite #= spriteCssClass #\'></span>'), empty: template('') }, rendering = { aria: function (item) { var attr = ''; if (item.items || item.content || item.contentUrl) { attr += ARIA_EXPANDED + '=\'' + (item.expanded ? 'true' : 'false') + '\' '; } if (item.enabled === false) { attr += ARIA_DISABLED + '=\'true\''; } return attr; }, wrapperCssClass: function (group, item) { var result = 'k-item', index = item.index; if (item.enabled === false) { result += ' ' + DISABLEDCLASS; } else if (item.expanded === true) { result += ' ' + ACTIVECLASS; } else { result += ' k-state-default'; } if (index === 0) { result += ' k-first'; } if (index == group.length - 1) { result += ' k-last'; } if (item.cssClass) { result += ' ' + item.cssClass; } return result; }, textClass: function (item, group) { var result = LINK; if (group.firstLevel) { result += ' k-header'; } return result; }, textAttributes: function (item) { return item.url ? ' href=\'' + item.url + '\'' : ''; }, arrowClass: function (item) { var result = 'k-icon'; result += item.expanded ? ' k-i-arrow-n k-panelbar-collapse' : ' k-i-arrow-s k-panelbar-expand'; return result; }, text: function (item) { return item.encoded === false ? item.text : kendo.htmlEncode(item.text); }, tag: function (item) { return item.url || item.contentUrl ? 'a' : 'span'; }, groupAttributes: function (group) { return group.expanded !== true ? ' style=\'display:none\'' : ''; }, groupCssClass: function () { return 'k-group k-panel'; }, contentAttributes: function (content) { return content.item.expanded !== true ? ' style=\'display:none\'' : ''; }, content: function (item) { return item.content ? item.content : item.contentUrl ? '' : ' '; }, contentUrl: function (item) { return item.contentUrl ? 'href="' + item.contentUrl + '"' : ''; } }; function updateArrow(items) { items = $(items); items.children(LINKSELECTOR).children('.k-icon').remove(); items.filter(':has(.k-panel),:has(.k-content)').children('.k-link:not(:has([class*=k-i-arrow]))').each(function () { var item = $(this), parent = item.parent(); item.append('<span class=\'k-icon ' + (parent.hasClass(ACTIVECLASS) ? 'k-i-arrow-n k-panelbar-collapse' : 'k-i-arrow-s k-panelbar-expand') + '\'/>'); }); } function updateFirstLast(items) { items = $(items); items.filter('.k-first:not(:first-child)').removeClass(FIRST); items.filter('.k-last:not(:last-child)').removeClass(LAST); items.filter(':first-child').addClass(FIRST); items.filter(':last-child').addClass(LAST); } var PanelBar = Widget.extend({ init: function (element, options) { var that = this, content; Widget.fn.init.call(that, element, options); element = that.wrapper = that.element.addClass('k-widget k-reset k-header k-panelbar'); options = that.options; if (element[0].id) { that._itemId = element[0].id + '_pb_active'; } that._tabindex(); that._initData(options); that._updateClasses(); that._animations(options); element.on('click' + NS, clickableItems, function (e) { if (that._click($(e.currentTarget))) { e.preventDefault(); } }).on(MOUSEENTER + NS + ' ' + MOUSELEAVE + NS, clickableItems, that._toggleHover).on('click' + NS, disabledItems, false).on('keydown' + NS, $.proxy(that._keydown, that)).on('focus' + NS, function () { var item = that.select(); that._current(item[0] ? item : that._first()); }).on('blur' + NS, function () { that._current(null); }).attr('role', 'menu'); content = element.find('li.' + ACTIVECLASS + ' > .' + CONTENT); if (content[0]) { that.expand(content.parent(), false); } if (options.dataSource) { that._angularCompile(); } kendo.notify(that); }, events: [ EXPAND, COLLAPSE, SELECT, ACTIVATE, ERROR, CONTENTLOAD ], options: { name: 'PanelBar', animation: { expand: { effects: 'expand:vertical', duration: 200 }, collapse: { duration: 200 } }, expandMode: 'multiple' }, _angularCompile: function () { var that = this; that.angular('compile', function () { return { elements: that.element.children('li'), data: [{ dataItem: that.options.$angular }] }; }); }, _angularCleanup: function () { var that = this; that.angular('cleanup', function () { return { elements: that.element.children('li') }; }); }, destroy: function () { Widget.fn.destroy.call(this); this.element.off(NS); this._angularCleanup(); kendo.destroy(this.element); }, _initData: function (options) { var that = this; if (options.dataSource) { that.element.empty(); that.append(options.dataSource, that.element); } }, setOptions: function (options) { var animation = this.options.animation; this._animations(options); options.animation = extend(true, animation, options.animation); if ('dataSource' in options) { this._initData(options); } Widget.fn.setOptions.call(this, options); }, expand: function (element, useAnimation) { var that = this, animBackup = {}; element = this.element.find(element); if (that._animating && element.find('ul').is(':visible')) { that.one('complete', function () { setTimeout(function () { that.expand(element); }); }); return; } that._animating = true; useAnimation = useAnimation !== false; element.each(function (index, item) { item = $(item); var groups = item.find(GROUPS).add(item.find(CONTENTS)); if (!item.hasClass(DISABLEDCLASS) && groups.length > 0) { if (that.options.expandMode == SINGLE && that._collapseAllExpanded(item)) { return that; } element.find('.' + HIGHLIGHTCLASS).removeClass(HIGHLIGHTCLASS); item.addClass(HIGHLIGHTCLASS); if (!useAnimation) { animBackup = that.options.animation; that.options.animation = { expand: { effects: {} }, collapse: { hide: true, effects: {} } }; } if (!that._triggerEvent(EXPAND, item)) { that._toggleItem(item, false); } if (!useAnimation) { that.options.animation = animBackup; } } }); return that; }, collapse: function (element, useAnimation) { var that = this, animBackup = {}; that._animating = true; useAnimation = useAnimation !== false; element = that.element.find(element); element.each(function (index, item) { item = $(item); var groups = item.find(GROUPS).add(item.find(CONTENTS)); if (!item.hasClass(DISABLEDCLASS) && groups.is(VISIBLE)) { item.removeClass(HIGHLIGHTCLASS); if (!useAnimation) { animBackup = that.options.animation; that.options.animation = { expand: { effects: {} }, collapse: { hide: true, effects: {} } }; } if (!that._triggerEvent(COLLAPSE, item)) { that._toggleItem(item, true); } if (!useAnimation) { that.options.animation = animBackup; } } }); return that; }, _toggleDisabled: function (element, enable) { element = this.element.find(element); element.toggleClass(defaultState, enable).toggleClass(DISABLEDCLASS, !enable).attr(ARIA_DISABLED, !enable); }, select: function (element) { var that = this; if (element === undefined) { return that.element.find(selectableItems).parent(); } element = that.element.find(element); if (!element.length) { this._updateSelected(element); } else { element.each(function () { var item = $(this), link = item.children(LINKSELECTOR); if (item.hasClass(DISABLEDCLASS)) { return that; } if (!that._triggerEvent(SELECT, item)) { that._updateSelected(link); } }); } return that; }, clearSelection: function () { this.select($()); }, enable: function (element, state) { this._toggleDisabled(element, state !== false); return this; }, disable: function (element) { this._toggleDisabled(element, false); return this; }, append: function (item, referenceItem) { referenceItem = this.element.find(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.length ? referenceItem.find(GROUPS) : null); each(inserted.items, function () { inserted.group.append(this); updateFirstLast(this); }); updateArrow(referenceItem); updateFirstLast(inserted.group.find('.k-first, .k-last')); inserted.group.height('auto'); return this; }, insertBefore: function (item, referenceItem) { referenceItem = this.element.find(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.parent()); each(inserted.items, function () { referenceItem.before(this); updateFirstLast(this); }); updateFirstLast(referenceItem); inserted.group.height('auto'); return this; }, insertAfter: function (item, referenceItem) { referenceItem = this.element.find(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.parent()); each(inserted.items, function () { referenceItem.after(this); updateFirstLast(this); }); updateFirstLast(referenceItem); inserted.group.height('auto'); return this; }, remove: function (element) { element = this.element.find(element); var that = this, parent = element.parentsUntil(that.element, ITEM), group = element.parent('ul'); element.remove(); if (group && !group.hasClass('k-panelbar') && !group.children(ITEM).length) { group.remove(); } if (parent.length) { parent = parent.eq(0); updateArrow(parent); updateFirstLast(parent); } return that; }, reload: function (element) { var that = this; element = that.element.find(element); element.each(function () { var item = $(this); that._ajaxRequest(item, item.children('.' + CONTENT), !item.is(VISIBLE)); }); }, _first: function () { return this.element.children(ACTIVEITEMSELECTOR).first(); }, _last: function () { var item = this.element.children(ACTIVEITEMSELECTOR).last(), group = item.children(VISIBLEGROUP); if (group[0]) { return group.children(ACTIVEITEMSELECTOR).last(); } return item; }, _current: function (candidate) { var that = this, focused = that._focused, id = that._itemId; if (candidate === undefined) { return focused; } that.element.removeAttr('aria-activedescendant'); if (focused && focused.length) { if (focused[0].id === id) { focused.removeAttr('id'); } focused.children(LINKSELECTOR).removeClass(FOCUSEDCLASS); } if ($(candidate).length) { id = candidate[0].id || id; candidate.attr('id', id).children(LINKSELECTOR).addClass(FOCUSEDCLASS); that.element.attr('aria-activedescendant', id); } that._focused = candidate; }, _keydown: function (e) { var that = this, key = e.keyCode, current = that._current(); if (e.target != e.currentTarget) { return; } if (key == keys.DOWN || key == keys.RIGHT) { that._current(that._nextItem(current)); e.preventDefault(); } else if (key == keys.UP || key == keys.LEFT) { that._current(that._prevItem(current)); e.preventDefault(); } else if (key == keys.ENTER || key == keys.SPACEBAR) { that._click(current.children(LINKSELECTOR)); e.preventDefault(); } else if (key == keys.HOME) { that._current(that._first()); e.preventDefault(); } else if (key == keys.END) { that._current(that._last()); e.preventDefault(); } }, _nextItem: function (item) { if (!item) { return this._first(); } var group = item.children(VISIBLEGROUP), next = item.nextAll(':visible').first(); if (group[0]) { next = group.children('.' + FIRST); } if (!next[0]) { next = item.parent(VISIBLEGROUP).parent(ITEM).next(); } if (!next[0]) { next = this._first(); } if (next.hasClass(DISABLEDCLASS)) { next = this._nextItem(next); } return next; }, _prevItem: function (item) { if (!item) { return this._last(); } var prev = item.prevAll(':visible').first(), result; if (!prev[0]) { prev = item.parent(VISIBLEGROUP).parent(ITEM); if (!prev[0]) { prev = this._last(); } } else { result = prev; while (result[0]) { result = result.children(VISIBLEGROUP).children('.' + LAST); if (result[0]) { prev = result; } } } if (prev.hasClass(DISABLEDCLASS)) { prev = this._prevItem(prev); } return prev; }, _insert: function (item, referenceItem, parent) { var that = this, items, plain = $.isPlainObject(item), isReferenceItem = referenceItem && referenceItem[0], groupData; if (!isReferenceItem) { parent = that.element; } groupData = { firstLevel: parent.hasClass('k-panelbar'), expanded: parent.parent().hasClass(ACTIVECLASS), length: parent.children().length }; if (isReferenceItem && !parent.length) { parent = $(PanelBar.renderGroup({ group: groupData })).appendTo(referenceItem); } if (item instanceof kendo.Observable) { item = item.toJSON(); } if (plain || $.isArray(item)) { items = $.map(plain ? [item] : item, function (value, idx) { if (typeof value === 'string') { return $(value); } else { return $(PanelBar.renderItem({ group: groupData, item: extend(value, { index: idx }) })); } }); if (isReferenceItem) { referenceItem.attr(ARIA_EXPANDED, false); } } else { if (typeof item == 'string' && item.charAt(0) != '<') { items = that.element.find(item); } else { items = $(item); } that._updateItemsClasses(items); } return { items: items, group: parent }; }, _toggleHover: function (e) { var target = $(e.currentTarget); if (!target.parents('li.' + DISABLEDCLASS).length) { target.toggleClass('k-state-hover', e.type == MOUSEENTER); } }, _updateClasses: function () { var that = this, panels, items; panels = that.element.find('li > ul').not(function () { return $(this).parentsUntil('.k-panelbar', 'div').length; }).addClass('k-group k-panel').attr('role', 'group'); panels.parent().attr(ARIA_EXPANDED, false).not('.' + ACTIVECLASS).children('ul').attr(ARIA_HIDDEN, true).hide(); items = that.element.add(panels).children(); that._updateItemsClasses(items); updateArrow(items); updateFirstLast(items); }, _updateItemsClasses: function (items) { var length = items.length, idx = 0; for (; idx < length; idx++) { this._updateItemClasses(items[idx], idx); } }, _updateItemClasses: function (item, index) { var selected = this._selected, contentUrls = this.options.contentUrls, url = contentUrls && contentUrls[index], root = this.element[0], wrapElement, link; item = $(item).addClass('k-item').attr('role', 'menuitem'); if (kendo.support.browser.msie) { item.css('list-style-position', 'inside').css('list-style-position', ''); } item.children(IMG).addClass(IMAGE); link = item.children('a').addClass(LINK); if (link[0]) { link.attr('href', url); link.children(IMG).addClass(IMAGE); } item.filter(':not([disabled]):not([class*=k-state])').addClass('k-state-default'); item.filter('li[disabled]').addClass('k-state-disabled').attr(ARIA_DISABLED, true).removeAttr('disabled'); item.children('div').addClass(CONTENT).attr('role', 'region').attr(ARIA_HIDDEN, true).hide().parent().attr(ARIA_EXPANDED, false); link = item.children(SELECTEDSELECTOR); if (link[0]) { if (selected) { selected.removeAttr(ARIA_SELECTED).children(SELECTEDSELECTOR).removeClass(SELECTEDCLASS); } link.addClass(SELECTEDCLASS); this._selected = item.attr(ARIA_SELECTED, true); } if (!item.children(LINKSELECTOR)[0]) { wrapElement = '<span class=\'' + LINK + '\'/>'; if (contentUrls && contentUrls[index] && item[0].parentNode == root) { wrapElement = '<a class="k-link k-header" href="' + contentUrls[index] + '"/>'; } item.contents().filter(function () { return !this.nodeName.match(excludedNodesRegExp) && !(this.nodeType == 3 && !$.trim(this.nodeValue)); }).wrapAll(wrapElement); } if (item.parent('.k-panelbar')[0]) { item.children(LINKSELECTOR).addClass('k-header'); } }, _click: function (target) { var that = this, element = that.element, prevent, contents, href, isAnchor; if (target.parents('li.' + DISABLEDCLASS).length) { return; } if (target.closest('.k-widget')[0] != element[0]) { return; } var link = target.closest(LINKSELECTOR), item = link.closest(ITEM); that._updateSelected(link); contents = item.find(GROUPS).add(item.find(CONTENTS)); href = link.attr(HREF); isAnchor = href && (href.charAt(href.length - 1) == '#' || href.indexOf('#' + that.element[0].id + '-') != -1); prevent = !!(isAnchor || contents.length); if (contents.data('animating')) { return prevent; } if (that._triggerEvent(SELECT, item)) { prevent = true; } if (prevent === false) { return; } if (that.options.expandMode == SINGLE) { if (that._collapseAllExpanded(item)) { return prevent; } } if (contents.length) { var visibility = contents.is(VISIBLE); if (!that._triggerEvent(!visibility ? EXPAND : COLLAPSE, item)) { prevent = that._toggleItem(item, visibility); } } return prevent; }, _toggleItem: function (element, isVisible) { var that = this, childGroup = element.find(GROUPS), link = element.find(LINKSELECTOR), url = link.attr(HREF), prevent, content; if (childGroup.length) { this._toggleGroup(childGroup, isVisible); prevent = true; } else { content = element.children('.' + CONTENT); if (content.length) { prevent = true; if (!content.is(EMPTY) || url === undefined) { that._toggleGroup(content, isVisible); } else { that._ajaxRequest(element, content, isVisible); } } } return prevent; }, _toggleGroup: function (element, visibility) { var that = this, animationSettings = that.options.animation, animation = animationSettings.expand, collapse = extend({}, animationSettings.collapse), hasCollapseAnimation = collapse && 'effects' in collapse; if (element.is(VISIBLE) != visibility) { that._animating = false; return; } element.parent().attr(ARIA_EXPANDED, !visibility).attr(ARIA_HIDDEN, visibility).toggleClass(ACTIVECLASS, !visibility).find('> .k-link > .k-icon').toggleClass('k-i-arrow-n', !visibility).toggleClass('k-panelbar-collapse', !visibility).toggleClass('k-i-arrow-s', visibility).toggleClass('k-panelbar-expand', visibility); if (visibility) { animation = extend(hasCollapseAnimation ? collapse : extend({ reverse: true }, animation), { hide: true }); animation.complete = function () { that._animationCallback(); }; } else { animation = extend({ complete: function (element) { that._triggerEvent(ACTIVATE, element.closest(ITEM)); that._animationCallback(); } }, animation); } element.kendoStop(true, true).kendoAnimate(animation); }, _animationCallback: function () { var that = this; that.trigger('complete'); that._animating = false; }, _collapseAllExpanded: function (item) { var that = this, children, stopExpand = false; var groups = item.find(GROUPS).add(item.find(CONTENTS)); if (groups.is(VISIBLE)) { stopExpand = true; } if (!(groups.is(VISIBLE) || groups.length === 0)) { children = item.siblings(); children.find(GROUPS).add(children.find(CONTENTS)).filter(function () { return $(this).is(VISIBLE); }).each(function (index, content) { content = $(content); stopExpand = that._triggerEvent(COLLAPSE, content.closest(ITEM)); if (!stopExpand) { that._toggleGroup(content, true); } }); } return stopExpand; }, _ajaxRequest: function (element, contentElement, isVisible) { var that = this, statusIcon = element.find('.k-panelbar-collapse, .k-panelbar-expand'), link = element.find(LINKSELECTOR), loadingIconTimeout = setTimeout(function () { statusIcon.addClass('k-loading'); }, 100), data = {}, url = link.attr(HREF); $.ajax({ type: 'GET', cache: false, url: url, dataType: 'html', data: data, error: function (xhr, status) { statusIcon.removeClass('k-loading'); if (that.trigger(ERROR, { xhr: xhr, status: status })) { this.complete(); } }, complete: function () { clearTimeout(loadingIconTimeout); statusIcon.removeClass('k-loading'); }, success: function (data) { function getElements() { return { elements: contentElement.get() }; } try { that.angular('cleanup', getElements); contentElement.html(data); that.angular('compile', getElements); } catch (e) { var console = window.console; if (console && console.error) { console.error(e.name + ': ' + e.message + ' in ' + url); } this.error(this.xhr, 'error'); } that._toggleGroup(contentElement, isVisible); that.trigger(CONTENTLOAD, { item: element[0], contentElement: contentElement[0] }); } }); }, _triggerEvent: function (eventName, element) { var that = this; return that.trigger(eventName, { item: element[0] }); }, _updateSelected: function (link) { var that = this, element = that.element, item = link.parent(ITEM), selected = that._selected; if (selected) { selected.removeAttr(ARIA_SELECTED); } that._selected = item.attr(ARIA_SELECTED, true); element.find(selectableItems).removeClass(SELECTEDCLASS); element.find('> .' + HIGHLIGHTCLASS + ', .k-panel > .' + HIGHLIGHTCLASS).removeClass(HIGHLIGHTCLASS); link.addClass(SELECTEDCLASS); link.parentsUntil(element, ITEM).filter(':has(.k-header)').addClass(HIGHLIGHTCLASS); that._current(item[0] ? item : null); }, _animations: function (options) { if (options && 'animation' in options && !options.animation) { options.animation = { expand: { effects: {} }, collapse: { hide: true, effects: {} } }; } } }); extend(PanelBar, { renderItem: function (options) { options = extend({ panelBar: {}, group: {} }, options); var empty = templates.empty, item = options.item; return templates.item(extend(options, { image: item.imageUrl ? templates.image : empty, sprite: item.spriteCssClass ? templates.sprite : empty, itemWrapper: templates.itemWrapper, renderContent: PanelBar.renderContent, arrow: item.items || item.content || item.contentUrl ? templates.arrow : empty, subGroup: PanelBar.renderGroup }, rendering)); }, renderGroup: function (options) { return templates.group(extend({ renderItems: function (options) { var html = '', i = 0, items = options.items, len = items ? items.length : 0, group = extend({ length: len }, options.group); for (; i < len; i++) { html += PanelBar.renderItem(extend(options, { group: group, item: extend({ index: i }, items[i]) })); } return html; } }, options, rendering)); }, renderContent: function (options) { return templates.content(extend(options, rendering)); } }); kendo.ui.plugin(PanelBar); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); /** * Copyright 2016 Telerik AD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function (f, define) { define('kendo.window', ['kendo.draganddrop'], f); }(function () { var __meta__ = { id: 'window', name: 'Window', category: 'web', description: 'The Window widget displays content in a modal or non-modal HTML window.', depends: ['draganddrop'] }; (function ($, undefined) { var kendo = window.kendo, Widget = kendo.ui.Widget, Draggable = kendo.ui.Draggable, isPlainObject = $.isPlainObject, activeElement = kendo._activeElement, proxy = $.proxy, extend = $.extend, each = $.each, template = kendo.template, BODY = 'body', templates, NS = '.kendoWindow', KWINDOW = '.k-window', KWINDOWTITLE = '.k-window-title', KWINDOWTITLEBAR = KWINDOWTITLE + 'bar', KWINDOWCONTENT = '.k-window-content', KWINDOWRESIZEHANDLES = '.k-resize-handle', KOVERLAY = '.k-overlay', KCONTENTFRAME = 'k-content-frame', LOADING = 'k-loading', KHOVERSTATE = 'k-state-hover', KFOCUSEDSTATE = 'k-state-focused', MAXIMIZEDSTATE = 'k-window-maximized', VISIBLE = ':visible', HIDDEN = 'hidden', CURSOR = 'cursor', OPEN = 'open', ACTIVATE = 'activate', DEACTIVATE = 'deactivate', CLOSE = 'close', REFRESH = 'refresh', MINIMIZE = 'minimize', MAXIMIZE = 'maximize', RESIZE = 'resize', RESIZEEND = 'resizeEnd', DRAGSTART = 'dragstart', DRAGEND = 'dragend', ERROR = 'error', OVERFLOW = 'overflow', ZINDEX = 'zIndex', MINIMIZE_MAXIMIZE = '.k-window-actions .k-i-minimize,.k-window-actions .k-i-maximize', KPIN = '.k-i-pin', KUNPIN = '.k-i-unpin', PIN_UNPIN = KPIN + ',' + KUNPIN, TITLEBAR_BUTTONS = '.k-window-titlebar .k-window-action', REFRESHICON = '.k-window-titlebar .k-i-refresh', isLocalUrl = kendo.isLocalUrl; function defined(x) { return typeof x != 'undefined'; } function constrain(value, low, high) { return Math.max(Math.min(parseInt(value, 10), high === Infinity ? high : parseInt(high, 10)), parseInt(low, 10)); } function executableScript() { return !this.type || this.type.toLowerCase().indexOf('script') >= 0; } var Window = Widget.extend({ init: function (element, options) { var that = this, wrapper, offset = {}, visibility, display, position, isVisible = false, content, windowContent, suppressActions = options && options.actions && !options.actions.length, id; Widget.fn.init.call(that, element, options); options = that.options; position = options.position; element = that.element; content = options.content; if (suppressActions) { options.actions = []; } that.appendTo = $(options.appendTo); if (content && !isPlainObject(content)) { content = options.content = { url: content }; } element.find('script').filter(executableScript).remove(); if (!element.parent().is(that.appendTo) && (position.top === undefined || position.left === undefined)) { if (element.is(VISIBLE)) { offset = element.offset(); isVisible = true; } else { visibility = element.css('visibility'); display = element.css('display'); element.css({ visibility: HIDDEN, display: '' }); offset = element.offset(); element.css({ visibility: visibility, display: display }); } if (position.top === undefined) { position.top = offset.top; } if (position.left === undefined) { position.left = offset.left; } } if (!defined(options.visible) || options.visible === null) { options.visible = element.is(VISIBLE); } wrapper = that.wrapper = element.closest(KWINDOW); if (!element.is('.k-content') || !wrapper[0]) { element.addClass('k-window-content k-content'); that._createWindow(element, options); wrapper = that.wrapper = element.closest(KWINDOW); that._dimensions(); } that._position(); if (options.pinned) { that.pin(true); } if (content) { that.refresh(content); } if (options.visible) { that.toFront(); } windowContent = wrapper.children(KWINDOWCONTENT); that._tabindex(windowContent); if (options.visible && options.modal) { that._overlay(wrapper.is(VISIBLE)).css({ opacity: 0.5 }); } wrapper.on('mouseenter' + NS, TITLEBAR_BUTTONS, proxy(that._buttonEnter, that)).on('mouseleave' + NS, TITLEBAR_BUTTONS, proxy(that._buttonLeave, that)).on('click' + NS, '> ' + TITLEBAR_BUTTONS, proxy(that._windowActionHandler, that)); windowContent.on('keydown' + NS, proxy(that._keydown, that)).on('focus' + NS, proxy(that._focus, that)).on('blur' + NS, proxy(that._blur, that)); this._resizable(); this._draggable(); id = element.attr('id'); if (id) { id = id + '_wnd_title'; wrapper.children(KWINDOWTITLEBAR).children(KWINDOWTITLE).attr('id', id); windowContent.attr({ 'role': 'dialog', 'aria-labelledby': id }); } wrapper.add(wrapper.children('.k-resize-handle,' + KWINDOWTITLEBAR)).on('mousedown' + NS, proxy(that.toFront, that)); that.touchScroller = kendo.touchScroller(element); that._resizeHandler = proxy(that._onDocumentResize, that); that._marker = kendo.guid().substring(0, 8); $(window).on('resize' + NS + that._marker, that._resizeHandler); if (options.visible) { that.trigger(OPEN); that.trigger(ACTIVATE); } kendo.notify(that); }, _buttonEnter: function (e) { $(e.currentTarget).addClass(KHOVERSTATE); }, _buttonLeave: function (e) { $(e.currentTarget).removeClass(KHOVERSTATE); }, _focus: function () { this.wrapper.addClass(KFOCUSEDSTATE); }, _blur: function () { this.wrapper.removeClass(KFOCUSEDSTATE); }, _dimensions: function () { var wrapper = this.wrapper; var options = this.options; var width = options.width; var height = options.height; var maxHeight = options.maxHeight; var dimensions = [ 'minWidth', 'minHeight', 'maxWidth', 'maxHeight' ]; this.title(options.title); for (var i = 0; i < dimensions.length; i++) { var value = options[dimensions[i]] || ''; if (value != Infinity) { wrapper.css(dimensions[i], value); } } if (maxHeight != Infinity) { this.element.css('maxHeight', maxHeight); } if (width) { if (width.toString().indexOf('%') > 0) { wrapper.width(width); } else { wrapper.width(constrain(width, options.minWidth, options.maxWidth)); } } else { wrapper.width(''); } if (height) { if (height.toString().indexOf('%') > 0) { wrapper.height(height); } else { wrapper.height(constrain(height, options.minHeight, options.maxHeight)); } } else { wrapper.height(''); } if (!options.visible) { wrapper.hide(); } }, _position: function () { var wrapper = this.wrapper, position = this.options.position; if (position.top === 0) { position.top = position.top.toString(); } if (position.left === 0) { position.left = position.left.toString(); } wrapper.css({ top: position.top || '', left: position.left || '' }); }, _animationOptions: function (id) { var animation = this.options.animation; var basicAnimation = { open: { effects: {} }, close: { hide: true, effects: {} } }; return animation && animation[id] || basicAnimation[id]; }, _resize: function () { kendo.resize(this.element.children()); }, _resizable: function () { var resizable = this.options.resizable; var wrapper = this.wrapper; if (this.resizing) { wrapper.off('dblclick' + NS).children(KWINDOWRESIZEHANDLES).remove(); this.resizing.destroy(); this.resizing = null; } if (resizable) { wrapper.on('dblclick' + NS, KWINDOWTITLEBAR, proxy(function (e) { if (!$(e.target).closest('.k-window-action').length) { this.toggleMaximization(); } }, this)); each('n e s w se sw ne nw'.split(' '), function (index, handler) { wrapper.append(templates.resizeHandle(handler)); }); this.resizing = new WindowResizing(this); } wrapper = null; }, _draggable: function () { var draggable = this.options.draggable; if (this.dragging) { this.dragging.destroy(); this.dragging = null; } if (draggable) { this.dragging = new WindowDragging(this, draggable.dragHandle || KWINDOWTITLEBAR); } }, _actions: function () { var actions = this.options.actions; var titlebar = this.wrapper.children(KWINDOWTITLEBAR); var container = titlebar.find('.k-window-actions'); actions = $.map(actions, function (action) { return { name: action }; }); container.html(kendo.render(templates.action, actions)); }, setOptions: function (options) { Widget.fn.setOptions.call(this, options); var scrollable = this.options.scrollable !== false; this.restore(); this._dimensions(); this._position(); this._resizable(); this._draggable(); this._actions(); if (typeof options.modal !== 'undefined') { var visible = this.options.visible !== false; this._overlay(options.modal && visible); } this.element.css(OVERFLOW, scrollable ? '' : 'hidden'); }, events: [ OPEN, ACTIVATE, DEACTIVATE, CLOSE, MINIMIZE, MAXIMIZE, REFRESH, RESIZE, RESIZEEND, DRAGSTART, DRAGEND, ERROR ], options: { name: 'Window', animation: { open: { effects: { zoom: { direction: 'in' }, fade: { direction: 'in' } }, duration: 350 }, close: { effects: { zoom: { direction: 'out', properties: { scale: 0.7 } }, fade: { direction: 'out' } }, duration: 350, hide: true } }, title: '', actions: ['Close'], autoFocus: true, modal: false, resizable: true, draggable: true, minWidth: 90, minHeight: 50, maxWidth: Infinity, maxHeight: Infinity, pinned: false, scrollable: true, position: {}, content: null, visible: null, height: null, width: null, appendTo: 'body' }, _closable: function () { return $.inArray('close', $.map(this.options.actions, function (x) { return x.toLowerCase(); })) > -1; }, _keydown: function (e) { var that = this, options = that.options, keys = kendo.keys, keyCode = e.keyCode, wrapper = that.wrapper, offset, handled, distance = 10, isMaximized = that.options.isMaximized, newWidth, newHeight, w, h; if (e.target != e.currentTarget || that._closing) { return; } if (keyCode == keys.ESC && that._closable()) { that._close(false); } if (options.draggable && !e.ctrlKey && !isMaximized) { offset = kendo.getOffset(wrapper); if (keyCode == keys.UP) { handled = wrapper.css('top', offset.top - distance); } else if (keyCode == keys.DOWN) { handled = wrapper.css('top', offset.top + distance); } else if (keyCode == keys.LEFT) { handled = wrapper.css('left', offset.left - distance); } else if (keyCode == keys.RIGHT) { handled = wrapper.css('left', offset.left + distance); } } if (options.resizable && e.ctrlKey && !isMaximized) { if (keyCode == keys.UP) { handled = true; newHeight = wrapper.height() - distance; } else if (keyCode == keys.DOWN) { handled = true; newHeight = wrapper.height() + distance; } if (keyCode == keys.LEFT) { handled = true; newWidth = wrapper.width() - distance; } else if (keyCode == keys.RIGHT) { handled = true; newWidth = wrapper.width() + distance; } if (handled) { w = constrain(newWidth, options.minWidth, options.maxWidth); h = constrain(newHeight, options.minHeight, options.maxHeight); if (!isNaN(w)) { wrapper.width(w); that.options.width = w + 'px'; } if (!isNaN(h)) { wrapper.height(h); that.options.height = h + 'px'; } that.resize(); } } if (handled) { e.preventDefault(); } }, _overlay: function (visible) { var overlay = this.appendTo.children(KOVERLAY), wrapper = this.wrapper; if (!overlay.length) { overlay = $('<div class=\'k-overlay\' />'); } overlay.insertBefore(wrapper[0]).toggle(visible).css(ZINDEX, parseInt(wrapper.css(ZINDEX), 10) - 1); return overlay; }, _actionForIcon: function (icon) { var iconClass = /\bk-i-\w+\b/.exec(icon[0].className)[0]; return { 'k-i-close': '_close', 'k-i-maximize': 'maximize', 'k-i-minimize': 'minimize', 'k-i-restore': 'restore', 'k-i-refresh': 'refresh', 'k-i-pin': 'pin', 'k-i-unpin': 'unpin' }[iconClass]; }, _windowActionHandler: function (e) { if (this._closing) { return; } var icon = $(e.target).closest('.k-window-action').find('.k-icon'); var action = this._actionForIcon(icon); if (action) { e.preventDefault(); this[action](); return false; } }, _modals: function () { var that = this; var zStack = $(KWINDOW).filter(function () { var dom = $(this); var object = that._object(dom); var options = object && object.options; return options && options.modal && options.visible && options.appendTo === that.options.appendTo && dom.is(VISIBLE); }).sort(function (a, b) { return +$(a).css('zIndex') - +$(b).css('zIndex'); }); that = null; return zStack; }, _object: function (element) { var content = element.children(KWINDOWCONTENT); var widget = kendo.widgetInstance(content); if (widget instanceof Window) { return widget; } return undefined; }, center: function () { var that = this, position = that.options.position, wrapper = that.wrapper, documentWindow = $(window), scrollTop = 0, scrollLeft = 0, newTop, newLeft; if (that.options.isMaximized) { return that; } if (!that.options.pinned) { scrollTop = documentWindow.scrollTop(); scrollLeft = documentWindow.scrollLeft(); } newLeft = scrollLeft + Math.max(0, (documentWindow.width() - wrapper.width()) / 2); newTop = scrollTop + Math.max(0, (documentWindow.height() - wrapper.height() - parseInt(wrapper.css('paddingTop'), 10)) / 2); wrapper.css({ left: newLeft, top: newTop }); position.top = newTop; position.left = newLeft; return that; }, title: function (text) { var that = this, wrapper = that.wrapper, options = that.options, titleBar = wrapper.children(KWINDOWTITLEBAR), title = titleBar.children(KWINDOWTITLE), titleBarHeight; if (!arguments.length) { return title.html(); } if (text === false) { wrapper.addClass('k-window-titleless'); titleBar.remove(); } else { if (!titleBar.length) { wrapper.prepend(templates.titlebar(options)); that._actions(); titleBar = wrapper.children(KWINDOWTITLEBAR); } else { title.html(text); } titleBarHeight = titleBar.outerHeight(); wrapper.css('padding-top', titleBarHeight); titleBar.css('margin-top', -titleBarHeight); } that.options.title = text; return that; }, content: function (html, data) { var content = this.wrapper.children(KWINDOWCONTENT), scrollContainer = content.children('.km-scroll-container'); content = scrollContainer[0] ? scrollContainer : content; if (!defined(html)) { return content.html(); } this.angular('cleanup', function () { return { elements: content.children() }; }); kendo.destroy(this.element.children()); content.empty().html(html); this.angular('compile', function () { var a = []; for (var i = content.length; --i >= 0;) { a.push({ dataItem: data }); } return { elements: content.children(), data: a }; }); return this; }, open: function () { var that = this, wrapper = that.wrapper, options = that.options, showOptions = this._animationOptions('open'), contentElement = wrapper.children(KWINDOWCONTENT), overlay, otherModalsVisible, doc = $(document); if (!that.trigger(OPEN)) { if (that._closing) { wrapper.kendoStop(true, true); } that._closing = false; that.toFront(); if (options.autoFocus) { that.element.focus(); } options.visible = true; if (options.modal) { otherModalsVisible = !!that._modals().length; overlay = that._overlay(otherModalsVisible); overlay.kendoStop(true, true); if (showOptions.duration && kendo.effects.Fade && !otherModalsVisible) { var overlayFx = kendo.fx(overlay).fadeIn(); overlayFx.duration(showOptions.duration || 0); overlayFx.endValue(0.5); overlayFx.play(); } else { overlay.css('opacity', 0.5); } overlay.show(); } if (!wrapper.is(VISIBLE)) { contentElement.css(OVERFLOW, HIDDEN); wrapper.show().kendoStop().kendoAnimate({ effects: showOptions.effects, duration: showOptions.duration, complete: proxy(this._activate, this) }); } } if (options.isMaximized) { that._documentScrollTop = doc.scrollTop(); that._documentScrollLeft = doc.scrollLeft(); $('html, body').css(OVERFLOW, HIDDEN); } return that; }, _activate: function () { var scrollable = this.options.scrollable !== false; if (this.options.autoFocus) { this.element.focus(); } this.element.css(OVERFLOW, scrollable ? '' : 'hidden'); this.trigger(ACTIVATE); }, _removeOverlay: function (suppressAnimation) { var modals = this._modals(); var options = this.options; var hideOverlay = options.modal && !modals.length; var overlay = options.modal ? this._overlay(true) : $(undefined); var hideOptions = this._animationOptions('close'); if (hideOverlay) { if (!suppressAnimation && hideOptions.duration && kendo.effects.Fade) { var overlayFx = kendo.fx(overlay).fadeOut(); overlayFx.duration(hideOptions.duration || 0); overlayFx.startValue(0.5); overlayFx.play(); } else { this._overlay(false).remove(); } } else if (modals.length) { this._object(modals.last())._overlay(true); } }, _close: function (systemTriggered) { var that = this, wrapper = that.wrapper, options = that.options, showOptions = this._animationOptions('open'), hideOptions = this._animationOptions('close'), doc = $(document); if (wrapper.is(VISIBLE) && !that.trigger(CLOSE, { userTriggered: !systemTriggered })) { if (that._closing) { return; } that._closing = true; options.visible = false; $(KWINDOW).each(function (i, element) { var contentElement = $(element).children(KWINDOWCONTENT); if (element != wrapper && contentElement.find('> .' + KCONTENTFRAME).length > 0) { contentElement.children(KOVERLAY).remove(); } }); this._removeOverlay(); wrapper.kendoStop().kendoAnimate({ effects: hideOptions.effects || showOptions.effects, reverse: hideOptions.reverse === true, duration: hideOptions.duration, complete: proxy(this._deactivate, this) }); } if (that.options.isMaximized) { $('html, body').css(OVERFLOW, ''); if (that._documentScrollTop && that._documentScrollTop > 0) { doc.scrollTop(that._documentScrollTop); } if (that._documentScrollLeft && that._documentScrollLeft > 0) { doc.scrollLeft(that._documentScrollLeft); } } }, _deactivate: function () { var that = this; that.wrapper.hide().css('opacity', ''); that.trigger(DEACTIVATE); if (that.options.modal) { var lastModal = that._object(that._modals().last()); if (lastModal) { lastModal.toFront(); } } }, close: function () { this._close(true); return this; }, _actionable: function (element) { return $(element).is(TITLEBAR_BUTTONS + ',' + TITLEBAR_BUTTONS + ' .k-icon,:input,a'); }, _shouldFocus: function (target) { var active = activeElement(), element = this.element; return this.options.autoFocus && !$(active).is(element) && !this._actionable(target) && (!element.find(active).length || !element.find(target).length); }, toFront: function (e) { var that = this, wrapper = that.wrapper, currentWindow = wrapper[0], zIndex = +wrapper.css(ZINDEX), originalZIndex = zIndex, target = e && e.target || null; $(KWINDOW).each(function (i, element) { var windowObject = $(element), zIndexNew = windowObject.css(ZINDEX), contentElement = windowObject.children(KWINDOWCONTENT); if (!isNaN(zIndexNew)) { zIndex = Math.max(+zIndexNew, zIndex); } if (element != currentWindow && contentElement.find('> .' + KCONTENTFRAME).length > 0) { contentElement.append(templates.overlay); } }); if (!wrapper[0].style.zIndex || originalZIndex < zIndex) { wrapper.css(ZINDEX, zIndex + 2); } that.element.find('> .k-overlay').remove(); if (that._shouldFocus(target)) { that.element.focus(); var scrollTop = $(window).scrollTop(), windowTop = parseInt(wrapper.position().top, 10); if (windowTop > 0 && windowTop < scrollTop) { if (scrollTop > 0) { $(window).scrollTop(windowTop); } else { wrapper.css('top', scrollTop); } } } wrapper = null; return that; }, toggleMaximization: function () { if (this._closing) { return this; } return this[this.options.isMaximized ? 'restore' : 'maximize'](); }, restore: function () { var that = this; var options = that.options; var minHeight = options.minHeight; var restoreOptions = that.restoreOptions; var doc = $(document); if (!options.isMaximized && !options.isMinimized) { return that; } if (minHeight && minHeight != Infinity) { that.wrapper.css('min-height', minHeight); } that.wrapper.css({ position: options.pinned ? 'fixed' : 'absolute', left: restoreOptions.left, top: restoreOptions.top, width: restoreOptions.width, height: restoreOptions.height }).removeClass(MAXIMIZEDSTATE).find('.k-window-content,.k-resize-handle').show().end().find('.k-window-titlebar .k-i-restore').parent().remove().end().end().find(MINIMIZE_MAXIMIZE).parent().show().end().end().find(PIN_UNPIN).parent().show(); that.options.width = restoreOptions.width; that.options.height = restoreOptions.height; $('html, body').css(OVERFLOW, ''); if (this._documentScrollTop && this._documentScrollTop > 0) { doc.scrollTop(this._documentScrollTop); } if (this._documentScrollLeft && this._documentScrollLeft > 0) { doc.scrollLeft(this._documentScrollLeft); } options.isMaximized = options.isMinimized = false; that.resize(); return that; }, _sizingAction: function (actionId, callback) { var that = this, wrapper = that.wrapper, style = wrapper[0].style, options = that.options; if (options.isMaximized || options.isMinimized) { return that; } that.restoreOptions = { width: style.width, height: style.height }; wrapper.children(KWINDOWRESIZEHANDLES).hide().end().children(KWINDOWTITLEBAR).find(MINIMIZE_MAXIMIZE).parent().hide().eq(0).before(templates.action({ name: 'Restore' })); callback.call(that); that.wrapper.children(KWINDOWTITLEBAR).find(PIN_UNPIN).parent().toggle(actionId !== 'maximize'); that.trigger(actionId); return that; }, maximize: function () { this._sizingAction('maximize', function () { var that = this, wrapper = that.wrapper, position = wrapper.position(), doc = $(document); extend(that.restoreOptions, { left: position.left, top: position.top }); wrapper.css({ left: 0, top: 0, position: 'fixed' }).addClass(MAXIMIZEDSTATE); this._documentScrollTop = doc.scrollTop(); this._documentScrollLeft = doc.scrollLeft(); $('html, body').css(OVERFLOW, HIDDEN); that.options.isMaximized = true; that._onDocumentResize(); }); return this; }, minimize: function () { this._sizingAction('minimize', function () { var that = this; that.wrapper.css({ height: '', minHeight: '' }); that.element.hide(); that.options.isMinimized = true; }); return this; }, pin: function (force) { var that = this, win = $(window), wrapper = that.wrapper, top = parseInt(wrapper.css('top'), 10), left = parseInt(wrapper.css('left'), 10); if (force || !that.options.pinned && !that.options.isMaximized) { wrapper.css({ position: 'fixed', top: top - win.scrollTop(), left: left - win.scrollLeft() }); wrapper.children(KWINDOWTITLEBAR).find(KPIN).addClass('k-i-unpin').removeClass('k-i-pin'); that.options.pinned = true; } }, unpin: function () { var that = this, win = $(window), wrapper = that.wrapper, top = parseInt(wrapper.css('top'), 10), left = parseInt(wrapper.css('left'), 10); if (that.options.pinned && !that.options.isMaximized) { wrapper.css({ position: '', top: top + win.scrollTop(), left: left + win.scrollLeft() }); wrapper.children(KWINDOWTITLEBAR).find(KUNPIN).addClass('k-i-pin').removeClass('k-i-unpin'); that.options.pinned = false; } }, _onDocumentResize: function () { var that = this, wrapper = that.wrapper, wnd = $(window), zoomLevel = kendo.support.zoomLevel(), w, h; if (!that.options.isMaximized) { return; } w = wnd.width() / zoomLevel; h = wnd.height() / zoomLevel - parseInt(wrapper.css('padding-top'), 10); wrapper.css({ width: w, height: h }); that.options.width = w; that.options.height = h; that.resize(); }, refresh: function (options) { var that = this, initOptions = that.options, element = $(that.element), iframe, showIframe, url; if (!isPlainObject(options)) { options = { url: options }; } options = extend({}, initOptions.content, options); showIframe = defined(initOptions.iframe) ? initOptions.iframe : options.iframe; url = options.url; if (url) { if (!defined(showIframe)) { showIframe = !isLocalUrl(url); } if (!showIframe) { that._ajaxRequest(options); } else { iframe = element.find('.' + KCONTENTFRAME)[0]; if (iframe) { iframe.src = url || iframe.src; } else { element.html(templates.contentFrame(extend({}, initOptions, { content: options }))); } element.find('.' + KCONTENTFRAME).unbind('load' + NS).on('load' + NS, proxy(this._triggerRefresh, this)); } } else { if (options.template) { that.content(template(options.template)({})); } that.trigger(REFRESH); } element.toggleClass('k-window-iframecontent', !!showIframe); return that; }, _triggerRefresh: function () { this.trigger(REFRESH); }, _ajaxComplete: function () { clearTimeout(this._loadingIconTimeout); this.wrapper.find(REFRESHICON).removeClass(LOADING); }, _ajaxError: function (xhr, status) { this.trigger(ERROR, { status: status, xhr: xhr }); }, _ajaxSuccess: function (contentTemplate) { return function (data) { var html = data; if (contentTemplate) { html = template(contentTemplate)(data || {}); } this.content(html, data); this.element.prop('scrollTop', 0); this.trigger(REFRESH); }; }, _showLoading: function () { this.wrapper.find(REFRESHICON).addClass(LOADING); }, _ajaxRequest: function (options) { this._loadingIconTimeout = setTimeout(proxy(this._showLoading, this), 100); $.ajax(extend({ type: 'GET', dataType: 'html', cache: false, error: proxy(this._ajaxError, this), complete: proxy(this._ajaxComplete, this), success: proxy(this._ajaxSuccess(options.template), this) }, options)); }, _destroy: function () { if (this.resizing) { this.resizing.destroy(); } if (this.dragging) { this.dragging.destroy(); } this.wrapper.off(NS).children(KWINDOWCONTENT).off(NS).end().find('.k-resize-handle,.k-window-titlebar').off(NS); $(window).off('resize' + NS + this._marker); clearTimeout(this._loadingIconTimeout); Widget.fn.destroy.call(this); this.unbind(undefined); kendo.destroy(this.wrapper); this._removeOverlay(true); }, destroy: function () { this._destroy(); this.wrapper.empty().remove(); this.wrapper = this.appendTo = this.element = $(); }, _createWindow: function () { var contentHtml = this.element, options = this.options, iframeSrcAttributes, wrapper, isRtl = kendo.support.isRtl(contentHtml); if (options.scrollable === false) { contentHtml.attr('style', 'overflow:hidden;'); } wrapper = $(templates.wrapper(options)); iframeSrcAttributes = contentHtml.find('iframe:not(.k-content)').map(function () { var src = this.getAttribute('src'); this.src = ''; return src; }); wrapper.toggleClass('k-rtl', isRtl).appendTo(this.appendTo).append(contentHtml).find('iframe:not(.k-content)').each(function (index) { this.src = iframeSrcAttributes[index]; }); wrapper.find('.k-window-title').css(isRtl ? 'left' : 'right', wrapper.find('.k-window-actions').outerWidth() + 10); contentHtml.css('visibility', '').show(); contentHtml.find('[data-role=editor]').each(function () { var editor = $(this).data('kendoEditor'); if (editor) { editor.refresh(); } }); wrapper = contentHtml = null; } }); templates = { wrapper: template('<div class=\'k-widget k-window\' />'), action: template('<a role=\'button\' href=\'\\#\' class=\'k-window-action k-link\'>' + '<span role=\'presentation\' class=\'k-icon k-i-#= name.toLowerCase() #\'>#= name #</span>' + '</a>'), titlebar: template('<div class=\'k-window-titlebar k-header\'> ' + '<span class=\'k-window-title\'>#= title #</span>' + '<div class=\'k-window-actions\' />' + '</div>'), overlay: '<div class=\'k-overlay\' />', contentFrame: template('<iframe frameborder=\'0\' title=\'#= title #\' class=\'' + KCONTENTFRAME + '\' ' + 'src=\'#= content.url #\'>' + 'This page requires frames in order to show content' + '</iframe>'), resizeHandle: template('<div class=\'k-resize-handle k-resize-#= data #\'></div>') }; function WindowResizing(wnd) { var that = this; that.owner = wnd; that._draggable = new Draggable(wnd.wrapper, { filter: '>' + KWINDOWRESIZEHANDLES, group: wnd.wrapper.id + '-resizing', dragstart: proxy(that.dragstart, that), drag: proxy(that.drag, that), dragend: proxy(that.dragend, that) }); that._draggable.userEvents.bind('press', proxy(that.addOverlay, that)); that._draggable.userEvents.bind('release', proxy(that.removeOverlay, that)); } WindowResizing.prototype = { addOverlay: function () { this.owner.wrapper.append(templates.overlay); }, removeOverlay: function () { this.owner.wrapper.find(KOVERLAY).remove(); }, dragstart: function (e) { var that = this; var wnd = that.owner; var wrapper = wnd.wrapper; that.elementPadding = parseInt(wrapper.css('padding-top'), 10); that.initialPosition = kendo.getOffset(wrapper, 'position'); that.resizeDirection = e.currentTarget.prop('className').replace('k-resize-handle k-resize-', ''); that.initialSize = { width: wrapper.width(), height: wrapper.height() }; that.containerOffset = kendo.getOffset(wnd.appendTo, 'position'); wrapper.children(KWINDOWRESIZEHANDLES).not(e.currentTarget).hide(); $(BODY).css(CURSOR, e.currentTarget.css(CURSOR)); }, drag: function (e) { var that = this, wnd = that.owner, wrapper = wnd.wrapper, options = wnd.options, direction = that.resizeDirection, containerOffset = that.containerOffset, initialPosition = that.initialPosition, initialSize = that.initialSize, newWidth, newHeight, windowBottom, windowRight, x = Math.max(e.x.location, containerOffset.left), y = Math.max(e.y.location, containerOffset.top); if (direction.indexOf('e') >= 0) { newWidth = x - initialPosition.left; wrapper.width(constrain(newWidth, options.minWidth, options.maxWidth)); } else if (direction.indexOf('w') >= 0) { windowRight = initialPosition.left + initialSize.width; newWidth = constrain(windowRight - x, options.minWidth, options.maxWidth); wrapper.css({ left: windowRight - newWidth - containerOffset.left, width: newWidth }); } if (direction.indexOf('s') >= 0) { newHeight = y - initialPosition.top - that.elementPadding; wrapper.height(constrain(newHeight, options.minHeight, options.maxHeight)); } else if (direction.indexOf('n') >= 0) { windowBottom = initialPosition.top + initialSize.height; newHeight = constrain(windowBottom - y, options.minHeight, options.maxHeight); wrapper.css({ top: windowBottom - newHeight - containerOffset.top, height: newHeight }); } if (newWidth) { wnd.options.width = newWidth + 'px'; } if (newHeight) { wnd.options.height = newHeight + 'px'; } wnd.resize(); }, dragend: function (e) { var that = this, wnd = that.owner, wrapper = wnd.wrapper; wrapper.children(KWINDOWRESIZEHANDLES).not(e.currentTarget).show(); $(BODY).css(CURSOR, ''); if (wnd.touchScroller) { wnd.touchScroller.reset(); } if (e.keyCode == 27) { wrapper.css(that.initialPosition).css(that.initialSize); } wnd.trigger(RESIZEEND); return false; }, destroy: function () { if (this._draggable) { this._draggable.destroy(); } this._draggable = this.owner = null; } }; function WindowDragging(wnd, dragHandle) { var that = this; that.owner = wnd; that._draggable = new Draggable(wnd.wrapper, { filter: dragHandle, group: wnd.wrapper.id + '-moving', dragstart: proxy(that.dragstart, that), drag: proxy(that.drag, that), dragend: proxy(that.dragend, that), dragcancel: proxy(that.dragcancel, that) }); that._draggable.userEvents.stopPropagation = false; } WindowDragging.prototype = { dragstart: function (e) { var wnd = this.owner, element = wnd.element, actions = element.find('.k-window-actions'), containerOffset = kendo.getOffset(wnd.appendTo); wnd.trigger(DRAGSTART); wnd.initialWindowPosition = kendo.getOffset(wnd.wrapper, 'position'); wnd.initialPointerPosition = { left: e.x.client, top: e.y.client }; wnd.startPosition = { left: e.x.client - wnd.initialWindowPosition.left, top: e.y.client - wnd.initialWindowPosition.top }; if (actions.length > 0) { wnd.minLeftPosition = actions.outerWidth() + parseInt(actions.css('right'), 10) - element.outerWidth(); } else { wnd.minLeftPosition = 20 - element.outerWidth(); } wnd.minLeftPosition -= containerOffset.left; wnd.minTopPosition = -containerOffset.top; wnd.wrapper.append(templates.overlay).children(KWINDOWRESIZEHANDLES).hide(); $(BODY).css(CURSOR, e.currentTarget.css(CURSOR)); }, drag: function (e) { var wnd = this.owner; var position = wnd.options.position; position.top = Math.max(e.y.client - wnd.startPosition.top, wnd.minTopPosition); position.left = Math.max(e.x.client - wnd.startPosition.left, wnd.minLeftPosition); if (kendo.support.transforms) { $(wnd.wrapper).css('transform', 'translate(' + (e.x.client - wnd.initialPointerPosition.left) + 'px, ' + (e.y.client - wnd.initialPointerPosition.top) + 'px)'); } else { $(wnd.wrapper).css(position); } }, _finishDrag: function () { var wnd = this.owner; wnd.wrapper.children(KWINDOWRESIZEHANDLES).toggle(!wnd.options.isMinimized).end().find(KOVERLAY).remove(); $(BODY).css(CURSOR, ''); }, dragcancel: function (e) { this._finishDrag(); e.currentTarget.closest(KWINDOW).css(this.owner.initialWindowPosition); }, dragend: function () { $(this.owner.wrapper).css(this.owner.options.position).css('transform', ''); this._finishDrag(); this.owner.trigger(DRAGEND); return false; }, destroy: function () { if (this._draggable) { this._draggable.destroy(); } this._draggable = this.owner = null; } }; kendo.ui.plugin(Window); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); }));