").html(element).contents();
if ($element.length === 1 && $element.is("script"))
$element = normalizeTemplateElement(element.html());
return $element
};
var clearSelection = function() {
if (window.getSelection) {
if (window.getSelection().empty)
window.getSelection().empty();
else if (window.getSelection().removeAllRanges)
window.getSelection().removeAllRanges()
}
else if (document.selection)
document.selection.empty()
};
var closestCommonParent = function(startTarget, endTarget) {
var $startParents = $(startTarget).parents().addBack(),
$endParents = $(endTarget).parents().addBack(),
startingParent = Math.min($startParents.length, $endParents.length) - 1;
for (var i = startingParent; i >= 0; i--)
if ($startParents.eq(i).is($endParents.eq(i)))
return $startParents.get(i)
};
var toggleAttr = function($target, attr, value) {
value ? $target.attr(attr, value) : $target.removeAttr(attr)
};
var clipboardText = function(event, text) {
var clipboard = event.originalEvent && event.originalEvent.clipboardData || window.clipboardData;
if (arguments.length === 1)
return clipboard && clipboard.getData("Text");
clipboard && clipboard.setData("Text", text)
};
$.extend(DX.utils, {
windowResizeCallbacks: windowResizeCallbacks,
resetActiveElement: resetActiveElement,
createMarkupFromString: createMarkupFromString,
triggerShownEvent: triggerVisibilityChangeEvent("dxshown"),
triggerHidingEvent: triggerVisibilityChangeEvent("dxhiding"),
initMobileViewport: initMobileViewport,
getElementOptions: getElementOptions,
createComponents: createComponents,
normalizeTemplateElement: normalizeTemplateElement,
clearSelection: clearSelection,
uniqueId: uniqueId,
closestCommonParent: closestCommonParent,
clipboardText: clipboardText,
toggleAttr: toggleAttr
})
})(jQuery, DevExpress);
/*! Module core, file utils.caret.js */
(function($, DX, undefined) {
var getCaret = function(input) {
if (isObsoleteBrowser(input))
return getCaretForObsoleteBrowser(input);
return {
start: input.selectionStart,
end: input.selectionEnd
}
};
var setCaret = function(input, position) {
if (isObsoleteBrowser(input)) {
setCaretForObsoleteBrowser(input, position);
return
}
if (!$.contains(document, input))
return;
input.selectionStart = position.start;
input.selectionEnd = position.end
};
var isObsoleteBrowser = function(input) {
return !input.setSelectionRange
};
var getCaretForObsoleteBrowser = function(input) {
var range = document.selection.createRange();
var rangeCopy = range.duplicate();
range.move('character', -input.value.length);
range.setEndPoint('EndToStart', rangeCopy);
return {
start: range.text.length,
end: range.text.length + rangeCopy.text.length
}
};
var setCaretForObsoleteBrowser = function(input, position) {
var range = input.createTextRange();
range.collapse(true);
range.moveStart("character", position.start);
range.moveEnd("character", position.end - position.start);
range.select()
};
var caret = function(input, position) {
input = $(input).get(0);
if (!DX.utils.isDefined(position))
return getCaret(input);
setCaret(input, position)
};
$.extend(DX.utils, {caret: caret})
})(jQuery, DevExpress);
/*! Module core, file utils.graphics.js */
(function($, DX, undefined) {
var _utils = DX.utils,
isFunction = _utils.isFunction,
_inArray = $.inArray,
isDefined = _utils.isDefined;
var processSeriesTemplate = function(seriesTemplate, items) {
var customizeSeries = isFunction(seriesTemplate.customizeSeries) ? seriesTemplate.customizeSeries : $.noop,
nameField = seriesTemplate.nameField || 'series',
generatedSeries = {},
seriesOrder = [],
series;
for (var i = 0, length = items.length; i < length; i++) {
var data = items[i];
if (nameField in data) {
series = generatedSeries[data[nameField]];
if (!series) {
series = generatedSeries[data[nameField]] = {
name: data[nameField],
data: []
};
seriesOrder.push(series.name)
}
series.data.push(data)
}
}
return $.map(seriesOrder, function(orderedName) {
var group = generatedSeries[orderedName],
seriesOptions = customizeSeries.call(null, group.name);
return $.extend(group, seriesOptions)
})
};
var getCategoriesInfo = function(categories, startValue, endValue) {
if (!(categories && categories.length > 0))
return {};
startValue = isDefined(startValue) ? startValue : categories[0];
endValue = isDefined(endValue) ? endValue : categories[categories.length - 1];
var categoriesValue = $.map(categories, function(category) {
return category && category.valueOf()
}),
visibleCategories = [],
indexStartValue = isDefined(startValue) ? _inArray(startValue.valueOf(), categoriesValue) : 0,
indexEndValue = isDefined(endValue) ? _inArray(endValue.valueOf(), categoriesValue) : categories.length - 1,
swapBuf,
hasVisibleCategories,
inverted = false,
visibleCategoriesLen;
indexStartValue < 0 && (indexStartValue = 0);
indexEndValue < 0 && (indexEndValue = categories.length - 1);
if (indexEndValue < indexStartValue) {
swapBuf = indexEndValue;
indexEndValue = indexStartValue;
indexStartValue = swapBuf;
inverted = true
}
visibleCategories = categories.slice(indexStartValue, indexEndValue + 1);
visibleCategoriesLen = visibleCategories.length;
hasVisibleCategories = visibleCategoriesLen > 0;
return {
categories: hasVisibleCategories ? visibleCategories : null,
start: hasVisibleCategories ? visibleCategories[inverted ? visibleCategoriesLen - 1 : 0] : null,
end: hasVisibleCategories ? visibleCategories[inverted ? 0 : visibleCategoriesLen - 1] : null,
inverted: inverted
}
};
$.extend(_utils, {
processSeriesTemplate: processSeriesTemplate,
getCategoriesInfo: getCategoriesInfo
})
})(jQuery, DevExpress);
/*! Module core, file utils.arrays.js */
(function($, DX, undefined) {
var isEmptyArray = function(entity) {
return $.isArray(entity) && !entity.length
};
var wrapToArray = function(entity) {
return $.isArray(entity) ? entity : [entity]
};
var removeDublicates = function(from, what) {
if (!$.isArray(from) || from.length === 0)
return [];
if (!$.isArray(what) || what.length === 0)
return from.slice();
var result = [];
$.each(from, function(_, value) {
var bIndex = $.inArray(value, what);
if (bIndex === -1)
result.push(value)
});
return result
};
$.extend(DX.utils, {
isEmptyArray: isEmptyArray,
wrapToArray: wrapToArray,
removeDublicates: removeDublicates
})
})(jQuery, DevExpress);
/*! Module core, file devices.js */
(function($, DX, undefined) {
var KNOWN_UA_TABLE = {
iPhone: "iPhone",
iPhone5: "iPhone",
iPhone6: "iPhone",
iPhone6plus: "iPhone",
iPad: "iPad",
iPadMini: "iPad Mini",
androidPhone: "Android Mobile",
androidTablet: "Android",
win8: "MSAppHost",
win8Phone: "Windows Phone 8",
msSurface: "MSIE ARM Tablet PC",
desktop: "desktop"
};
var DEFAULT_DEVICE = {
deviceType: "",
platform: "",
version: [],
phone: false,
tablet: false,
android: false,
ios: false,
win8: false,
generic: false,
grade: "A",
mac: false
};
$.extend(DEFAULT_DEVICE, {
platform: "generic",
deviceType: "desktop",
generic: true
});
var uaParsers = {
win8: function(userAgent) {
var isPhone = /windows phone/i.test(userAgent) || userAgent.match(/WPDesktop/),
isTablet = !isPhone && /arm(.*)trident/i.test(userAgent),
isDesktop = !isPhone && !isTablet && /msapphost/i.test(userAgent);
if (!(isPhone || isTablet || isDesktop))
return;
var matches = userAgent.match(/windows phone (\d+).(\d+)/i) || userAgent.match(/windows nt (\d+).(\d+)/i),
version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10)] : [];
return {
deviceType: isPhone ? "phone" : isTablet ? "tablet" : "desktop",
platform: "win8",
version: version,
grade: "A"
}
},
ios: function(userAgent) {
if (!/ip(hone|od|ad)/i.test(userAgent))
return;
var isPhone = /ip(hone|od)/i.test(userAgent),
matches = userAgent.match(/os (\d+)_(\d+)_?(\d+)?/i),
version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],
isIPhone4 = window.screen.height === 960 / 2,
grade = isIPhone4 ? "B" : "A";
return {
deviceType: isPhone ? "phone" : "tablet",
platform: "ios",
version: version,
grade: grade
}
},
android: function(userAgent) {
if (!/android|htc_|silk/i.test(userAgent))
return;
var isPhone = /mobile/i.test(userAgent),
matches = userAgent.match(/android (\d+)\.(\d+)\.?(\d+)?/i),
version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],
worseThan4_4 = version.length > 1 && (version[0] < 4 || version[0] === 4 && version[1] < 4),
grade = worseThan4_4 ? "B" : "A";
return {
deviceType: isPhone ? "phone" : "tablet",
platform: "android",
version: version,
grade: grade
}
}
};
DX.Devices = DX.Class.inherit({
ctor: function(options) {
this._window = options && options.window || window;
this._realDevice = this._getDevice();
this._currentDevice = undefined;
this._currentOrientation = undefined;
this.orientationChanged = $.Callbacks();
this._callbacksToEvents("Devices", ["orientationChanged"]);
this._recalculateOrientation();
DX.utils.windowResizeCallbacks.add($.proxy(this._recalculateOrientation, this))
},
current: function(deviceOrName) {
if (deviceOrName) {
this._currentDevice = this._getDevice(deviceOrName);
this._forced = true;
DX.ui.themes.init({_autoInit: true})
}
else {
if (!this._currentDevice) {
deviceOrName = undefined;
try {
deviceOrName = this._getDeviceOrNameFromWindowScope()
}
catch(e) {
deviceOrName = this._getDeviceNameFromSessionStorage()
}
finally {
if (!deviceOrName)
deviceOrName = this._getDeviceNameFromSessionStorage();
if (deviceOrName)
this._forced = true
}
this._currentDevice = this._getDevice(deviceOrName)
}
return this._currentDevice
}
},
real: function() {
var forceDevice = arguments[0];
if ($.isPlainObject(forceDevice)) {
$.extend(this._realDevice, forceDevice);
return
}
return $.extend({}, this._realDevice)
},
orientation: function() {
return this._currentOrientation
},
isForced: function() {
return this._forced
},
isRippleEmulator: function() {
return !!this._window.tinyHippos
},
_getCssClasses: function(device) {
var result = [];
var realDevice = this._realDevice;
device = device || this.current();
if (device.deviceType) {
result.push("dx-device-" + device.deviceType);
if (device.deviceType !== "desktop")
result.push("dx-device-mobile")
}
result.push("dx-device-" + realDevice.platform);
if (realDevice.version && realDevice.version.length)
result.push("dx-device-" + realDevice.platform + "-" + realDevice.version[0]);
if (DX.devices.isSimulator())
result.push("dx-simulator");
if (DX.rtlEnabled)
result.push("dx-rtl");
return result
},
attachCssClasses: function(element, device) {
this._deviceClasses = this._getCssClasses(device).join(" ");
$(element).addClass(this._deviceClasses)
},
detachCssClasses: function(element) {
$(element).removeClass(this._deviceClasses)
},
isSimulator: function() {
try {
return this._isSimulator || this._window.top !== this._window.self && this._window.top["dx-force-device"] || this.isRippleEmulator()
}
catch(e) {
return false
}
},
forceSimulator: function() {
this._isSimulator = true
},
_getDevice: function(deviceName) {
if (deviceName === "genericPhone")
deviceName = {
deviceType: "phone",
platform: "generic",
generic: true
};
if ($.isPlainObject(deviceName))
return this._fromConfig(deviceName);
else {
var ua;
if (deviceName) {
ua = KNOWN_UA_TABLE[deviceName];
if (!ua)
throw DX.Error("E0005");
}
else
ua = navigator.userAgent;
return this._fromUA(ua)
}
},
_getDeviceOrNameFromWindowScope: function() {
var result;
if (this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"])
result = this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"];
return result
},
_getDeviceNameFromSessionStorage: function() {
var sessionStorage;
try {
sessionStorage = this._window.sessionStorage
}
catch(e) {}
if (!sessionStorage)
return;
var deviceOrName = sessionStorage.getItem("dx-force-device");
try {
return $.parseJSON(deviceOrName)
}
catch(ex) {
return deviceOrName
}
},
_fromConfig: function(config) {
var shortcuts = {
phone: config.deviceType === "phone",
tablet: config.deviceType === "tablet",
android: config.platform === "android",
ios: config.platform === "ios",
win8: config.platform === "win8",
generic: config.platform === "generic"
};
return $.extend({}, DEFAULT_DEVICE, this._currentDevice, shortcuts, config)
},
_fromUA: function(ua) {
var config;
$.each(uaParsers, function(platform, parser) {
config = parser(ua);
return !config
});
if (config)
return this._fromConfig(config);
var isMac = /(mac os)/.test(ua.toLowerCase()),
deviceWithOS = DEFAULT_DEVICE;
deviceWithOS.mac = isMac;
return deviceWithOS
},
_changeOrientation: function() {
var $window = $(this._window),
orientation = $window.height() > $window.width() ? "portrait" : "landscape";
if (this._currentOrientation === orientation)
return;
this._currentOrientation = orientation;
this.orientationChanged.fire({orientation: orientation})
},
_recalculateOrientation: function() {
var windowWidth = $(this._window).width();
if (this._currentWidth === windowWidth)
return;
this._currentWidth = windowWidth;
this._changeOrientation()
}
}).include(DX.EventsMixin);
DX.devices = new DX.Devices;
DX.viewPortChanged.add(function(viewPort, prevViewport) {
DX.devices.detachCssClasses(prevViewport);
DX.devices.attachCssClasses(viewPort)
})
})(jQuery, DevExpress);
/*! Module core, file browser.js */
(function($, DX, global, undefined) {
var webkitRegExp = /(webkit)[ \/]([\w.]+)/,
operaRegExp = /(opera)(?:.*version)?[ \/]([\w.]+)/,
ieRegExp = /(msie) (\d{1,2}\.\d)/,
ie11RegExp = /(trident).*rv:(\d{1,2}\.\d)/,
mozillaRegExp = /(mozilla)(?:.*? rv:([\w.]+))?/;
var ua = navigator.userAgent.toLowerCase();
var browser = function() {
var result = {},
matches = webkitRegExp.exec(ua) || operaRegExp.exec(ua) || ieRegExp.exec(ua) || ie11RegExp.exec(ua) || ua.indexOf("compatible") < 0 && mozillaRegExp.exec(ua) || [],
browserName = matches[1],
browserVersion = matches[2];
if (browserName === "trident")
browserName = "msie";
if (browserName) {
result[browserName] = true;
result.version = browserVersion
}
return result
}();
DX.browser = browser
})(jQuery, DevExpress, this);
/*! Module core, file support.js */
(function($, DX, window) {
var jsPrefixes = ["", "Webkit", "Moz", "O", "Ms"],
cssPrefixes = {
"": "",
Webkit: "-webkit-",
Moz: "-moz-",
O: "-o-",
ms: "-ms-"
},
styles = document.createElement("dx").style;
var transitionEndEventNames = {
webkitTransition: 'webkitTransitionEnd',
MozTransition: 'transitionend',
OTransition: 'oTransitionEnd',
msTransition: 'MsTransitionEnd',
transition: 'transitionend'
};
var forEachPrefixes = function(prop, callBack) {
prop = DX.inflector.camelize(prop, true);
var result;
for (var i = 0, cssPrefixesCount = jsPrefixes.length; i < cssPrefixesCount; i++) {
var jsPrefix = jsPrefixes[i];
var prefixedProp = jsPrefix + prop;
var lowerPrefixedProp = DX.inflector.camelize(prefixedProp);
result = callBack(lowerPrefixedProp, jsPrefix);
if (result === undefined)
result = callBack(prefixedProp, jsPrefix);
if (result !== undefined)
break
}
return result
};
var styleProp = function(prop) {
return forEachPrefixes(prop, function(specific) {
if (specific in styles)
return specific
})
};
var stylePropPrefix = function(prop) {
return forEachPrefixes(prop, function(specific, jsPrefix) {
if (specific in styles)
return cssPrefixes[jsPrefix]
})
};
var supportProp = function(prop) {
return !!styleProp(prop)
};
var isNativeScrollingSupported = function() {
var realDevice = DX.devices.real(),
realPlatform = realDevice.platform,
realVersion = realDevice.version,
isObsoleteAndroid = realVersion && realVersion[0] < 4 && realPlatform === "android",
isNativeScrollDevice = !isObsoleteAndroid && $.inArray(realPlatform, ["ios", "android", "win8"]) > -1 || realDevice.mac;
return isNativeScrollDevice
};
DX.support = {
touchEvents: "ontouchstart" in window,
touch: "ontouchstart" in window || !!window.navigator.msMaxTouchPoints,
pointer: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
transform: supportProp("transform"),
transition: supportProp("transition"),
transitionEndEventName: transitionEndEventNames[styleProp("transition")],
animation: supportProp("animation"),
nativeScrolling: isNativeScrollingSupported(),
winJS: "WinJS" in window,
styleProp: styleProp,
stylePropPrefix: stylePropPrefix,
supportProp: supportProp,
hasKo: !!window.ko,
hasNg: !window.ko && !!window.angular,
inputType: function(type) {
if (type === "text")
return true;
var input = document.createElement("input");
try {
input.setAttribute("type", type);
input.value = "wrongValue";
return !input.value
}
catch(e) {
return false
}
}
}
})(jQuery, DevExpress, this);
/*! Module core, file position.js */
(function($, DX, undefined) {
var horzRe = /left|right/,
vertRe = /top|bottom/,
collisionRe = /fit|flip|none/;
var normalizeAlign = function(raw) {
var result = {
h: "center",
v: "center"
};
var pair = DX.utils.splitPair(raw);
if (pair)
$.each(pair, function() {
var w = String(this).toLowerCase();
if (horzRe.test(w))
result.h = w;
else if (vertRe.test(w))
result.v = w
});
return result
};
var normalizeOffset = function(raw) {
return DX.utils.stringPairToObject(raw)
};
var normalizeCollision = function(raw) {
var pair = DX.utils.splitPair(raw),
h = String(pair && pair[0]).toLowerCase(),
v = String(pair && pair[1]).toLowerCase();
if (!collisionRe.test(h))
h = "none";
if (!collisionRe.test(v))
v = h;
return {
h: h,
v: v
}
};
var getAlignFactor = function(align) {
switch (align) {
case"center":
return 0.5;
case"right":
case"bottom":
return 1;
default:
return 0
}
};
var inverseAlign = function(align) {
switch (align) {
case"left":
return "right";
case"right":
return "left";
case"top":
return "bottom";
case"bottom":
return "top";
default:
return align
}
};
var calculateOversize = function(data, bounds) {
var oversize = 0;
if (data.myLocation < bounds.min)
oversize += bounds.min - data.myLocation;
if (data.myLocation > bounds.max)
oversize += data.myLocation - bounds.max;
return oversize
};
var initMyLocation = function(data) {
data.myLocation = data.atLocation + getAlignFactor(data.atAlign) * data.atSize - getAlignFactor(data.myAlign) * data.mySize + data.offset
};
var decolliders = {
fit: function(data, bounds) {
var result = false;
if (data.myLocation > bounds.max) {
data.myLocation = bounds.max;
result = true
}
if (data.myLocation < bounds.min) {
data.myLocation = bounds.min;
result = true
}
return result
},
flip: function(data, bounds) {
if (data.myAlign === "center" && data.atAlign === "center")
return false;
if (data.myLocation < bounds.min || data.myLocation > bounds.max) {
var inverseData = $.extend({}, data, {
myAlign: inverseAlign(data.myAlign),
atAlign: inverseAlign(data.atAlign),
offset: -data.offset
});
initMyLocation(inverseData);
inverseData.oversize = calculateOversize(inverseData, bounds);
if (inverseData.myLocation >= bounds.min && inverseData.myLocation <= bounds.max || inverseData.myLocation > data.myLocation || inverseData.oversize < data.oversize) {
data.myLocation = inverseData.myLocation;
data.oversize = inverseData.oversize;
return true
}
}
return false
}
};
var scrollbarWidth;
var defaultPositionResult = {
h: {
location: 0,
flip: false,
fit: false,
oversize: 0
},
v: {
location: 0,
flip: false,
fit: false,
oversize: 0
}
};
var calculatePosition = function(what, options) {
var $what = $(what),
currentOffset = $what.offset(),
result = $.extend(true, {}, defaultPositionResult, {
h: {location: currentOffset.left},
v: {location: currentOffset.top}
});
if (!options)
return result;
var my = normalizeAlign(options.my),
at = normalizeAlign(options.at),
of = options.of || window,
offset = normalizeOffset(options.offset),
collision = normalizeCollision(options.collision),
boundary = options.boundary,
boundaryOffset = normalizeOffset(options.boundaryOffset);
var h = {
mySize: $what.outerWidth(),
myAlign: my.h,
atAlign: at.h,
offset: offset.h,
collision: collision.h,
boundaryOffset: boundaryOffset.h
};
var v = {
mySize: $what.outerHeight(),
myAlign: my.v,
atAlign: at.v,
offset: offset.v,
collision: collision.v,
boundaryOffset: boundaryOffset.v
};
if (of.preventDefault) {
h.atLocation = of.pageX;
v.atLocation = of.pageY;
h.atSize = 0;
v.atSize = 0
}
else {
of = $(of);
if ($.isWindow(of[0])) {
h.atLocation = of.scrollLeft();
v.atLocation = of.scrollTop();
h.atSize = of.width();
v.atSize = of.height()
}
else if (of[0].nodeType === 9) {
h.atLocation = 0;
v.atLocation = 0;
h.atSize = of.width();
v.atSize = of.height()
}
else {
var o = of.offset();
h.atLocation = o.left;
v.atLocation = o.top;
h.atSize = of.outerWidth();
v.atSize = of.outerHeight()
}
}
initMyLocation(h);
initMyLocation(v);
var bounds = function() {
var win = $(window),
windowWidth = win.width(),
windowHeight = win.height(),
left = win.scrollLeft(),
top = win.scrollTop(),
hScrollbar = document.width > document.documentElement.clientWidth,
vScrollbar = document.height > document.documentElement.clientHeight,
hZoomLevel = DX.support.touch ? document.documentElement.clientWidth / (vScrollbar ? windowWidth - scrollbarWidth : windowWidth) : 1,
vZoomLevel = DX.support.touch ? document.documentElement.clientHeight / (hScrollbar ? windowHeight - scrollbarWidth : windowHeight) : 1;
if (scrollbarWidth === undefined)
scrollbarWidth = calculateScrollbarWidth();
var boundaryWidth = windowWidth,
boundaryHeight = windowHeight;
if (boundary) {
var $boundary = $(boundary),
boundaryPosition = $boundary.offset();
left = boundaryPosition.left;
top = boundaryPosition.top;
boundaryWidth = $boundary.width();
boundaryHeight = $boundary.height()
}
return {
h: {
min: left + h.boundaryOffset,
max: left + boundaryWidth / hZoomLevel - h.mySize - h.boundaryOffset
},
v: {
min: top + v.boundaryOffset,
max: top + boundaryHeight / vZoomLevel - v.mySize - v.boundaryOffset
}
}
}();
h.oversize = calculateOversize(h, bounds.h);
v.oversize = calculateOversize(v, bounds.v);
if (decolliders[h.collision])
result.h[h.collision] = decolliders[h.collision](h, bounds.h);
if (decolliders[v.collision])
result.v[v.collision] = decolliders[v.collision](v, bounds.v);
var preciser = function(number) {
return options.precise ? number : Math.round(number)
};
$.extend(true, result, {
h: {
location: preciser(h.myLocation),
oversize: preciser(h.oversize)
},
v: {
location: preciser(v.myLocation),
oversize: preciser(v.oversize)
},
precise: options.precise
});
return result
};
var position = function(what, options) {
var $what = $(what);
if (!options)
return $what.offset();
DX.translator.resetPosition($what);
var offset = $what.offset(),
targetPosition = options.h && options.v ? options : calculatePosition($what, options);
var preciser = function(number) {
return options.precise ? number : Math.round(number)
};
DX.translator.move($what, {
left: targetPosition.h.location - preciser(offset.left),
top: targetPosition.v.location - preciser(offset.top)
});
return targetPosition
};
$.extend(DX, {
calculatePosition: calculatePosition,
position: position
});
$.extend(DX.position, {
inverseAlign: inverseAlign,
normalizeAlign: normalizeAlign
});
var calculateScrollbarWidth = function() {
var $scrollDiv = $("
").css({
width: 100,
height: 100,
overflow: "scroll",
position: "absolute",
top: -9999
}).appendTo($("body")),
result = $scrollDiv.get(0).offsetWidth - $scrollDiv.get(0).clientWidth;
$scrollDiv.remove();
return result
}
})(jQuery, DevExpress);
/*! Module core, file action.js */
(function($, DX, undefined) {
var actionExecutors = {};
var registerExecutor = function(name, executor) {
if ($.isPlainObject(name)) {
$.each(name, registerExecutor);
return
}
actionExecutors[name] = executor
};
var unregisterExecutor = function() {
var args = $.makeArray(arguments);
$.each(args, function() {
delete actionExecutors[this]
})
};
registerExecutor({
func: {execute: function(e) {
if ($.isFunction(e.action)) {
e.result = e.action.apply(e.context, e.args);
e.handled = true
}
}},
url: {execute: function(e) {
if (typeof e.action === "string" && e.action.charAt(0) !== "#")
document.location = e.action
}},
hash: {execute: function(e) {
if (typeof e.action === "string" && e.action.charAt(0) === "#")
document.location.hash = e.action
}}
});
var Action = DX.Class.inherit({
ctor: function(action, config) {
config = config || {};
this._action = action || $.noop;
this._context = config.context || window;
this._beforeExecute = config.beforeExecute || $.noop;
this._afterExecute = config.afterExecute || $.noop;
this._component = config.component;
this._excludeValidators = config.excludeValidators;
this._validatingTargetName = config.validatingTargetName
},
execute: function() {
var e = {
action: this._action,
args: Array.prototype.slice.call(arguments),
context: this._context,
component: this._component,
validatingTargetName: this._validatingTargetName,
cancel: false,
handled: false
};
if (!this._validateAction(e))
return;
this._beforeExecute.call(this._context, e);
if (e.cancel)
return;
var result = this._executeAction(e);
this._afterExecute.call(this._context, e);
return result
},
_validateAction: function(e) {
var excludeValidators = this._excludeValidators;
$.each(actionExecutors, function(name, executor) {
if (excludeValidators && $.inArray(name, excludeValidators) > -1)
return;
if (executor.validate)
executor.validate(e);
if (e.cancel)
return false
});
return !e.cancel
},
_executeAction: function(e) {
var result;
$.each(actionExecutors, function(index, executor) {
if (executor.execute)
executor.execute(e);
if (e.handled) {
result = e.result;
return false
}
});
return result
}
});
$.extend(DX, {
registerActionExecutor: registerExecutor,
unregisterActionExecutor: unregisterExecutor,
Action: Action
});
DX.__internals = {actionExecutors: actionExecutors}
})(jQuery, DevExpress);
/*! Module core, file translator.js */
(function($, DX, undefined) {
var support = DX.support,
TRANSLATOR_DATA_KEY = "dxTranslator",
TRANSFORM_MATRIX_REGEX = /matrix(3d)?\((.+?)\)/,
TRANSLATE_REGEX = /translate(?:3d)?\((.+?)\)/;
var locate = function($element) {
var translate = support.transform ? getTranslate($element) : getTranslateFallback($element);
return {
left: translate.x,
top: translate.y
}
};
var move = function($element, position) {
if (!support.transform) {
$element.css(position);
return
}
var translate = getTranslate($element),
left = position.left,
top = position.top;
if (left !== undefined)
translate.x = left || 0;
if (top !== undefined)
translate.y = top || 0;
$element.css({transform: getTranslateCss(translate)});
if (isPersentValue(left) || isPersentValue(top))
clearCache($element)
};
var isPersentValue = function(value) {
return $.type(value) === "string" && value[value.length - 1] === "%"
};
var getTranslateFallback = function($element) {
var result;
try {
var originalTop = $element.css("top"),
originalLeft = $element.css("left");
var position = $element.position();
$element.css({
transform: "none",
top: 0,
left: 0
});
clearCache($element);
var finalPosition = $element.position();
result = {
x: position.left - finalPosition.left || parseInt(originalLeft) || 0,
y: position.top - finalPosition.top || parseInt(originalTop) || 0
};
$element.css({
top: originalTop,
left: originalLeft
})
}
catch(e) {
result = {
x: 0,
y: 0
}
}
return result
};
var getTranslate = function($element) {
var result = $element.data(TRANSLATOR_DATA_KEY);
if (!result) {
var transformValue = $element.css("transform") || getTranslateCss({
x: 0,
y: 0
}),
matrix = transformValue.match(TRANSFORM_MATRIX_REGEX),
is3D = matrix && matrix[1];
if (matrix) {
matrix = matrix[2].split(",");
if (is3D === "3d")
matrix = matrix.slice(12, 15);
else {
matrix.push(0);
matrix = matrix.slice(4, 7)
}
}
else
matrix = [0, 0, 0];
result = {
x: parseFloat(matrix[0]),
y: parseFloat(matrix[1]),
z: parseFloat(matrix[2])
};
cacheTranslate($element, result)
}
return result
};
var cacheTranslate = function($element, translate) {
$element.data(TRANSLATOR_DATA_KEY, translate)
};
var clearCache = function($element) {
$element.removeData(TRANSLATOR_DATA_KEY)
};
var resetPosition = function($element) {
$element.css({
left: 0,
top: 0,
transform: "none"
});
clearCache($element)
};
var parseTranslate = function(translateString) {
var result = translateString.match(TRANSLATE_REGEX);
if (!result || !result[1])
return;
result = result[1].split(",");
result = {
x: parseFloat(result[0]),
y: parseFloat(result[1]),
z: parseFloat(result[2])
};
return result
};
var getTranslateCss = function(translate) {
translate.x = translate.x || 0;
translate.y = translate.y || 0;
var xValueString = isPersentValue(translate.x) ? translate.x : translate.x + "px";
var yValueString = isPersentValue(translate.y) ? translate.y : translate.y + "px";
return "translate(" + xValueString + ", " + yValueString + ")"
};
DX.translator = {
move: move,
locate: locate,
clearCache: clearCache,
parseTranslate: parseTranslate,
getTranslate: getTranslate,
getTranslateCss: getTranslateCss,
resetPosition: resetPosition
}
})(jQuery, DevExpress);
/*! Module core, file animationFrame.js */
(function($, DX, undefined) {
var FRAME_ANIMATION_STEP_TIME = 1000 / 60,
requestAnimationFrame = function(callback) {
return this.setTimeout(callback, FRAME_ANIMATION_STEP_TIME)
},
cancelAnimationFrame = function(requestID) {
this.clearTimeout(requestID)
},
nativeRequestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame,
nativeCancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;
if (nativeRequestAnimationFrame && nativeCancelAnimationFrame) {
requestAnimationFrame = nativeRequestAnimationFrame;
cancelAnimationFrame = nativeCancelAnimationFrame
}
if (nativeRequestAnimationFrame && !nativeCancelAnimationFrame) {
var cancelledRequests = {};
requestAnimationFrame = function(callback) {
var requestId = nativeRequestAnimationFrame.call(window, function() {
try {
if (requestId in cancelledRequests)
return;
callback.apply(this, arguments)
}
finally {
delete cancelledRequests[requestId]
}
});
return requestId
};
cancelAnimationFrame = function(requestId) {
cancelledRequests[requestId] = true
}
}
requestAnimationFrame = $.proxy(requestAnimationFrame, window);
cancelAnimationFrame = $.proxy(cancelAnimationFrame, window);
$.extend(DX, {
requestAnimationFrame: requestAnimationFrame,
cancelAnimationFrame: cancelAnimationFrame
})
})(jQuery, DevExpress);
/*! Module core, file animator.js */
(function($, DX, undefined) {
DX.Animator = DX.Class.inherit({
ctor: function() {
this._finished = true;
this._stopped = false;
this._proxiedStepCore = $.proxy(this._stepCore, this)
},
start: function() {
this._stopped = false;
this._finished = false;
this._stepCore()
},
stop: function() {
this._stopped = true;
DX.cancelAnimationFrame(this._stepAnimationFrame)
},
_stepCore: function() {
if (this._isStopped()) {
this._stop();
return
}
if (this._isFinished()) {
this._finished = true;
this._complete();
return
}
this._step();
this._stepAnimationFrame = DX.requestAnimationFrame.call(window, this._proxiedStepCore)
},
_step: DX.abstract,
_isFinished: $.noop,
_stop: $.noop,
_complete: $.noop,
_isStopped: function() {
return this._stopped
},
inProgress: function() {
return !(this._stopped || this._finished)
}
})
})(jQuery, DevExpress);
/*! Module core, file fx.js */
(function($, DX, undefined) {
var translator = DX.translator,
support = DX.support,
transitionEndEventName = support.transitionEndEventName + ".dxFX",
removeEventName = "dxremove.dxFX";
var CSS_TRANSITION_EASING_REGEX = /cubic-bezier\((\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\)/,
RELATIVE_VALUE_REGEX = /^([+-])=(.*)/i,
ANIM_DATA_KEY = "dxAnimData",
ANIM_QUEUE_KEY = "dxAnimQueue",
TRANSFORM_PROP = "transform";
var TransitionAnimationStrategy = {
initAnimation: function($element, config) {
$element.css({transitionProperty: "none"});
if (typeof config.from === "string")
$element.addClass(config.from);
else
setProps($element, config.from)
},
animate: function($element, config) {
var that = this,
deferred = $.Deferred(),
cleanupWhen = config.cleanupWhen;
config.transitionAnimation = {finish: function() {
that._finishTransition($element, config);
if (cleanupWhen)
$.when(deferred, cleanupWhen).always(function() {
that._cleanup($element, config)
});
else
that._cleanup($element, config);
deferred.resolveWith($element, [config, $element])
}};
this._startAnimation($element, config);
this._completeAnimationCallback($element, config).done(function() {
config.transitionAnimation.finish()
});
if (!config.duration)
config.transitionAnimation.finish();
return deferred.promise()
},
_completeAnimationCallback: function($element, config) {
var startTime = $.now() + config.delay,
deferred = $.Deferred(),
transitionEndFired = $.Deferred(),
simulatedTransitionEndFired = $.Deferred(),
simulatedEndEventTimer,
waitForJSCompleteTimer;
config.transitionAnimation.cleanup = function() {
clearTimeout(simulatedEndEventTimer);
clearTimeout(waitForJSCompleteTimer)
};
$element.one(transitionEndEventName, function() {
if ($.now() - startTime >= config.duration)
transitionEndFired.reject()
}).off(removeEventName).on(removeEventName, function() {
config.transitionAnimation.cleanup()
});
waitForJSCompleteTimer = setTimeout(function() {
simulatedEndEventTimer = setTimeout(function() {
simulatedTransitionEndFired.reject()
}, config.duration + config.delay + DX.fx._simulatedTransitionEndDelay);
$.when(transitionEndFired, simulatedTransitionEndFired).fail($.proxy(function() {
deferred.resolve()
}, this))
});
return deferred.promise()
},
_startAnimation: function($element, config) {
$element.css("transform");
$element.css({
transitionProperty: "all",
transitionDelay: config.delay + "ms",
transitionDuration: config.duration + "ms",
transitionTimingFunction: config.easing
});
if (typeof config.to === "string")
$element.addClass(config.to);
else if (config.to)
setProps($element, config.to)
},
_finishTransition: function($element, config) {
$element.css("transition", "none")
},
_cleanup: function($element, config) {
$element.off(transitionEndEventName);
config.transitionAnimation.cleanup();
if (typeof config.from === "string") {
$element.removeClass(config.from);
$element.removeClass(config.to)
}
},
stop: function($element, config, jumpToEnd) {
if (!config)
return;
if (jumpToEnd)
config.transitionAnimation.finish();
else {
if ($.isPlainObject(config.to))
$.each(config.to, function(key) {
$element.css(key, $element.css(key))
});
this._finishTransition($element, config);
this._cleanup($element, config)
}
}
};
var FrameAnimationStrategy = {
initAnimation: function($element, config) {
setProps($element, config.from)
},
animate: function($element, config) {
var deferred = $.Deferred(),
that = this;
if (!config)
return deferred.reject().promise();
$.each(config.to, function(prop) {
if (config.from[prop] === undefined)
config.from[prop] = that._normalizeValue($element.css(prop))
});
if (config.to[TRANSFORM_PROP]) {
config.from[TRANSFORM_PROP] = that._parseTransform(config.from[TRANSFORM_PROP]);
config.to[TRANSFORM_PROP] = that._parseTransform(config.to[TRANSFORM_PROP])
}
config.frameAnimation = {
to: config.to,
from: config.from,
currentValue: config.from,
easing: convertTransitionTimingFuncToJQueryEasing(config.easing),
duration: config.duration,
startTime: (new Date).valueOf(),
finish: function() {
this.currentValue = this.to;
this.draw();
deferred.resolve()
},
draw: function() {
var currentValue = $.extend({}, this.currentValue);
if (currentValue[TRANSFORM_PROP])
currentValue[TRANSFORM_PROP] = $.map(currentValue[TRANSFORM_PROP], function(value, prop) {
if (prop === "translate")
return translator.getTranslateCss(value);
else if (prop === "scale")
return "scale(" + value + ")";
else if (prop.substr(0, prop.length - 1) === "rotate")
return prop + "(" + value + "deg)"
}).join(" ");
$element.css(currentValue)
}
};
if (config.delay) {
config.frameAnimation.startTime += config.delay;
config.frameAnimation.delayTimeout = setTimeout(function() {
that._animationStep($element, config)
}, config.delay)
}
else
that._animationStep($element, config);
return deferred.promise()
},
_parseTransform: function(transformString) {
var result = {};
$.each(transformString.match(/(\w|\d)+\([^\)]*\)\s*/g), function(i, part) {
var translateData = translator.parseTranslate(part),
scaleData = part.match(/scale\((.+?)\)/),
rotateData = part.match(/(rotate.)\((.+)deg\)/);
if (translateData)
result.translate = translateData;
if (scaleData && scaleData[1])
result.scale = parseFloat(scaleData[1]);
if (rotateData && rotateData[1])
result[rotateData[1]] = parseFloat(rotateData[2])
});
return result
},
stop: function($element, config, jumpToEnd) {
var frameAnimation = config && config.frameAnimation;
if (!frameAnimation)
return;
clearTimeout(frameAnimation.delayTimeout);
if (jumpToEnd)
frameAnimation.finish();
delete config.frameAnimation
},
_animationStep: function($element, config) {
var frameAnimation = config && config.frameAnimation;
if (!frameAnimation)
return;
var now = (new Date).valueOf();
if (now >= frameAnimation.startTime + frameAnimation.duration) {
frameAnimation.finish();
return
}
frameAnimation.currentValue = this._calcStepValue(frameAnimation, now - frameAnimation.startTime);
frameAnimation.draw();
DX.requestAnimationFrame($.proxy(function() {
this._animationStep($element, config)
}, this))
},
_calcStepValue: function(frameAnimation, currentDuration) {
var calcValueRecursively = function(from, to) {
var result = $.isArray(to) ? [] : {};
var calcEasedValue = function(propName) {
var x = currentDuration / frameAnimation.duration,
t = currentDuration,
b = 1 * from[propName],
c = to[propName] - from[propName],
d = frameAnimation.duration;
return $.easing[frameAnimation.easing](x, t, b, c, d)
};
$.each(to, function(propName, endPropValue) {
if (typeof endPropValue === "string" && parseFloat(endPropValue, 10) === false)
return true;
result[propName] = typeof endPropValue === "object" ? calcValueRecursively(from[propName], endPropValue) : calcEasedValue(propName)
});
return result
};
return calcValueRecursively(frameAnimation.from, frameAnimation.to)
},
_normalizeValue: function(value) {
var numericValue = parseFloat(value, 10);
if (numericValue === false)
return value;
return numericValue
}
};
var FallbackToNoAnimationStrategy = {
initAnimation: function($element, config){},
animate: function($element, config) {
return $.Deferred().resolve().promise()
}
};
var animationStrategies = {
transition: support.transition ? TransitionAnimationStrategy : FrameAnimationStrategy,
frame: FrameAnimationStrategy,
noAnimation: FallbackToNoAnimationStrategy
};
var getAnimationStrategy = function(config) {
config = config || {};
var strategy = config.strategy || "transition";
if (config.type === "css" && !support.transition)
strategy = "noAnimation";
return animationStrategies[strategy]
};
var TransitionTimingFuncMap = {
linear: "cubic-bezier(0, 0, 1, 1)",
ease: "cubic-bezier(0.25, 0.1, 0.25, 1)",
"ease-in": "cubic-bezier(0.42, 0, 1, 1)",
"ease-out": "cubic-bezier(0, 0, 0.58, 1)",
"ease-in-out": "cubic-bezier(0.42, 0, 0.58, 1)"
};
var convertTransitionTimingFuncToJQueryEasing = function(cssTransitionEasing) {
cssTransitionEasing = TransitionTimingFuncMap[cssTransitionEasing] || cssTransitionEasing;
var bezCoeffs = cssTransitionEasing.match(CSS_TRANSITION_EASING_REGEX);
if (!bezCoeffs)
return "linear";
bezCoeffs = bezCoeffs.slice(1, 5);
$.each(bezCoeffs, function(index, value) {
bezCoeffs[index] = parseFloat(value)
});
var easingName = "cubicbezier_" + bezCoeffs.join("_").replace(/\./g, "p");
if (!$.isFunction($.easing[easingName])) {
var polynomBezier = function(x1, y1, x2, y2) {
var Cx = 3 * x1,
Bx = 3 * (x2 - x1) - Cx,
Ax = 1 - Cx - Bx,
Cy = 3 * y1,
By = 3 * (y2 - y1) - Cy,
Ay = 1 - Cy - By;
var bezierX = function(t) {
return t * (Cx + t * (Bx + t * Ax))
};
var bezierY = function(t) {
return t * (Cy + t * (By + t * Ay))
};
var findXfor = function(t) {
var x = t,
i = 0,
z;
while (i < 14) {
z = bezierX(x) - t;
if (Math.abs(z) < 1e-3)
break;
x = x - z / derivativeX(x);
i++
}
return x
};
var derivativeX = function(t) {
return Cx + t * (2 * Bx + t * 3 * Ax)
};
return function(t) {
return bezierY(findXfor(t))
}
};
$.easing[easingName] = function(x, t, b, c, d) {
return c * polynomBezier(bezCoeffs[0], bezCoeffs[1], bezCoeffs[2], bezCoeffs[3])(t / d) + b
}
}
return easingName
};
var baseConfigValidator = function(config, animationType, validate, typeMessage) {
$.each(["from", "to"], function() {
if (!validate(config[this]))
throw DX.Error("E0010", animationType, this, typeMessage);
})
};
var isObjectConfigValidator = function(config, animationType) {
return baseConfigValidator(config, animationType, function(target) {
return $.isPlainObject(target)
}, "a plain object")
};
var isStringConfigValidator = function(config, animationType) {
return baseConfigValidator(config, animationType, function(target) {
return typeof target === "string"
}, "a string")
};
var CustomAnimationConfigurator = {setup: function($element, config){}};
var CssAnimationConfigurator = {
validateConfig: function(config) {
isStringConfigValidator(config, "css")
},
setup: function($element, config){}
};
var positionAliases = {
top: {
my: "bottom center",
at: "top center"
},
bottom: {
my: "top center",
at: "bottom center"
},
right: {
my: "left center",
at: "right center"
},
left: {
my: "right center",
at: "left center"
}
};
var SlideAnimationConfigurator = {
validateConfig: function(config) {
isObjectConfigValidator(config, "slide")
},
setup: function($element, config) {
var location = translator.locate($element);
if (config.type !== "slide") {
var positioningConfig = config.type === "slideIn" ? config.from : config.to;
positioningConfig.position = $.extend({of: window}, positionAliases[config.direction]);
setupPosition($element, positioningConfig)
}
this._setUpConfig(location, config.from);
this._setUpConfig(location, config.to);
translator.clearCache($element);
if (!support.transform && $element.css("position") === "static")
$element.css("position", "relative")
},
_setUpConfig: function(location, config) {
config.left = "left" in config ? config.left : "+=0";
config.top = "top" in config ? config.top : "+=0";
this._initNewPosition(location, config)
},
_initNewPosition: function(location, config) {
var position = {
left: config.left,
top: config.top
};
delete config.left;
delete config.top;
var relativeValue = this._getRelativeValue(position.left);
if (relativeValue !== undefined)
position.left = relativeValue + location.left;
else
config.left = 0;
relativeValue = this._getRelativeValue(position.top);
if (relativeValue !== undefined)
position.top = relativeValue + location.top;
else
config.top = 0;
var translate = {
x: 0,
y: 0
};
if (support.transform)
translate = {
x: position.left,
y: position.top
};
else {
config.left = position.left;
config.top = position.top
}
config[TRANSFORM_PROP] = translator.getTranslateCss(translate)
},
_getRelativeValue: function(value) {
var relativeValue;
if (typeof value === "string" && (relativeValue = RELATIVE_VALUE_REGEX.exec(value)))
return parseInt(relativeValue[1] + "1") * relativeValue[2]
}
};
var FadeAnimationConfigurator = {setup: function($element, config) {
var from = config.from,
fromOpacity = $.isPlainObject(from) ? config.skipElementInitialStyles ? 0 : $element.css("opacity") : String(from),
toOpacity;
switch (config.type) {
case"fadeIn":
toOpacity = 1;
break;
case"fadeOut":
toOpacity = 0;
break;
default:
toOpacity = String(config.to)
}
config.from = {
visibility: "visible",
opacity: fromOpacity
};
config.to = {opacity: toOpacity}
}};
var PopAnimationConfigurator = {
validateConfig: function(config) {
isObjectConfigValidator(config, "pop")
},
setup: function($element, config) {
var from = config.from,
to = config.to,
fromOpacity = "opacity" in from ? from.opacity : $element.css("opacity"),
toOpacity = "opacity" in to ? to.opacity : 1,
fromScale = "scale" in from ? from.scale : 0,
toScale = "scale" in to ? to.scale : 1;
config.from = {opacity: fromOpacity};
var translate = translator.getTranslate($element);
config.from[TRANSFORM_PROP] = this._getCssTransform(translate, fromScale);
config.to = {opacity: toOpacity};
config.to[TRANSFORM_PROP] = this._getCssTransform(translate, toScale)
},
_getCssTransform: function(translate, scale) {
return translator.getTranslateCss(translate) + "scale(" + scale + ")"
}
};
var animationConfigurators = {
custom: CustomAnimationConfigurator,
slide: SlideAnimationConfigurator,
slideIn: SlideAnimationConfigurator,
slideOut: SlideAnimationConfigurator,
fade: FadeAnimationConfigurator,
fadeIn: FadeAnimationConfigurator,
fadeOut: FadeAnimationConfigurator,
pop: PopAnimationConfigurator,
css: CssAnimationConfigurator
};
var getAnimationConfigurator = function(config) {
var result = animationConfigurators[config.type];
if (!result)
throw DX.Error("E0011", config.type);
return result
};
var defaultJSConfig = {
type: "custom",
from: {},
to: {},
duration: 400,
start: $.noop,
complete: $.noop,
easing: "ease",
delay: 0
},
defaultCssConfig = {
duration: 400,
easing: "ease",
delay: 0
};
var setupAnimationOnElement = function() {
var animation = this,
$element = animation.$element,
config = animation.config;
setupPosition($element, config.from);
setupPosition($element, config.to);
animation.configurator.setup($element, config);
$element.data(ANIM_DATA_KEY, animation);
if (DX.fx.off)
config.duration = 0;
animation.strategy.initAnimation($element, config);
if (config.start)
config.start.apply(this, [$element, config])
};
var startAnimationOnElement = function() {
var animation = this,
$element = animation.$element,
config = animation.config;
return animation.strategy.animate($element, config).done(function() {
$element.removeData(ANIM_DATA_KEY);
if (config.complete)
config.complete.apply(this, [$element, config]);
animation.deferred.resolveWith(this, [$element, config])
})
};
var createAnimation = function($element, initialConfig) {
var defaultConfig = initialConfig.type === "css" ? defaultCssConfig : defaultJSConfig,
config = $.extend(true, {}, defaultConfig, initialConfig),
configurator = getAnimationConfigurator(config),
strategy = getAnimationStrategy(config),
animation = {
$element: $element,
config: config,
configurator: configurator,
strategy: strategy,
setup: setupAnimationOnElement,
start: startAnimationOnElement,
deferred: $.Deferred()
};
if ($.isFunction(configurator.validateConfig))
configurator.validateConfig(config);
return animation
};
var animate = function(element, config) {
var $element = $(element);
if (!$element.length)
return $.Deferred().resolve().promise();
var animation = createAnimation($element, config);
pushInAnimationQueue($element, animation);
return animation.deferred.promise()
};
var pushInAnimationQueue = function($element, animation) {
var queueData = getAnimQueueData($element);
writeAnimQueueData($element, queueData);
queueData.push(animation);
if (!isAnimating($element))
shiftFromAnimationQueue($element, queueData)
};
var getAnimQueueData = function($element) {
return $element.data(ANIM_QUEUE_KEY) || []
};
var writeAnimQueueData = function($element, queueData) {
$element.data(ANIM_QUEUE_KEY, queueData)
};
var destroyAnimQueueData = function($element) {
$element.removeData(ANIM_QUEUE_KEY)
};
var isAnimating = function($element) {
return !!$element.data(ANIM_DATA_KEY)
};
var shiftFromAnimationQueue = function($element, queueData) {
queueData = getAnimQueueData($element);
if (!queueData.length)
return;
var animation = queueData.shift();
if (queueData.length === 0)
destroyAnimQueueData($element);
executeAnimation(animation).done(function() {
shiftFromAnimationQueue($element)
})
};
var executeAnimation = function(animation) {
animation.setup();
return animation.start()
};
var setupPosition = function($element, config) {
if (!config || !config.position)
return;
var position = DX.calculatePosition($element, config.position),
offset = $element.offset(),
currentPosition = $element.position();
$.extend(config, {
left: position.h.location - offset.left + currentPosition.left,
top: position.v.location - offset.top + currentPosition.top
});
delete config.position
};
var setProps = function($element, props) {
$.each(props, function(key, value) {
$element.css(key, value)
})
};
var stop = function(element, jumpToEnd) {
var $element = $(element),
queueData = getAnimQueueData($element);
$.each(queueData, function(_, animation) {
animation.config.duration = 0
});
if (!isAnimating($element))
shiftFromAnimationQueue($element, queueData);
var animation = $element.data(ANIM_DATA_KEY);
if (animation)
animation.strategy.stop($element, animation.config, jumpToEnd);
$element.removeData(ANIM_DATA_KEY);
destroyAnimQueueData($element)
};
DX.fx = {
off: false,
animationTypes: animationConfigurators,
animate: animate,
createAnimation: createAnimation,
isAnimating: isAnimating,
stop: stop,
_simulatedTransitionEndDelay: 100
};
DX.fx.__internals = {convertTransitionTimingFuncToJQueryEasing: convertTransitionTimingFuncToJQueryEasing}
})(jQuery, DevExpress);
/*! Module core, file dxProxyUrlFormatter.js */
(function($, DX, undefined) {
var location = window.location,
DXPROXY_HOST = "dxproxy.devexpress.com:8000",
IS_DXPROXY_ORIGIN = location.host === DXPROXY_HOST,
urlMapping = {};
var extractProxyAppId = function() {
return location.pathname.split("/")[1]
};
var urlFormatter = {
isProxyUsed: function() {
return IS_DXPROXY_ORIGIN
},
formatProxyUrl: function(localUrl) {
var urlData = DX.parseUrl(localUrl);
if (!/^(localhost$|127\.)/i.test(urlData.hostname))
return localUrl;
var proxyUrlPart = DXPROXY_HOST + "/" + extractProxyAppId() + "_" + urlData.port;
urlMapping[proxyUrlPart] = urlData.hostname + ":" + urlData.port;
var resultUrl = "http://" + proxyUrlPart + urlData.pathname + urlData.search;
return resultUrl
},
formatLocalUrl: function(proxyUrl) {
if (proxyUrl.indexOf(DXPROXY_HOST) < 0)
return proxyUrl;
var resultUrl = proxyUrl;
for (var proxyUrlPart in urlMapping)
if (urlMapping.hasOwnProperty(proxyUrlPart))
if (proxyUrl.indexOf(proxyUrlPart) >= 0) {
resultUrl = proxyUrl.replace(proxyUrlPart, urlMapping[proxyUrlPart]);
break
}
return resultUrl
}
};
DX._proxyUrlFormatter = urlFormatter
})(jQuery, DevExpress);
/*! Module core, file endpointSelector.js */
(function($, DX, undefined) {
var location = window.location,
IS_WINJS_ORIGIN = location.protocol === "ms-appx:",
IS_LOCAL_ORIGIN = isLocalHostName(location.hostname);
function isLocalHostName(url) {
return /^(localhost$|127\.)/i.test(url)
}
var EndpointSelector = DX.EndpointSelector = function(config) {
this.config = config
};
EndpointSelector.prototype = {urlFor: function(key) {
var bag = this.config[key];
if (!bag)
throw DX.Error("E0006");
if (DX._proxyUrlFormatter.isProxyUsed())
return DX._proxyUrlFormatter.formatProxyUrl(bag.local);
if (bag.production)
if (IS_WINJS_ORIGIN && !Debug.debuggerEnabled || !IS_WINJS_ORIGIN && !IS_LOCAL_ORIGIN)
return bag.production;
return bag.local
}}
})(jQuery, DevExpress);
/*! Module core, file formatHelper.js */
(function($, DX, undefined) {
var utils = DX.utils;
DX.NumericFormat = {
currency: 'C',
fixedpoint: 'N',
exponential: '',
percent: 'P',
decimal: 'D'
};
DX.LargeNumberFormatPostfixes = {
1: 'K',
2: 'M',
3: 'B',
4: 'T'
};
var MAX_LARGE_NUMBER_POWER = 4,
DECIMAL_BASE = 10;
DX.LargeNumberFormatPowers = {
largenumber: 'auto',
thousands: 1,
millions: 2,
billions: 3,
trillions: 4
};
DX.DateTimeFormat = {
longdate: 'D',
longtime: 'T',
monthandday: 'M',
monthandyear: 'Y',
quarterandyear: 'qq',
shortdate: 'd',
shorttime: 't',
millisecond: 'fff',
second: 'T',
minute: 't',
hour: 't',
day: 'dd',
week: 'dd',
month: 'MMMM',
quarter: 'qq',
year: 'yyyy',
longdatelongtime: 'D',
shortdateshorttime: 'd',
shortyear: 'yy'
};
DX.formatHelper = {
defaultQuarterFormat: 'Q{0}',
romanDigits: ['I', 'II', 'III', 'IV'],
_addFormatSeparator: function(format1, format2) {
var separator = ' ';
if (format2)
return format1 + separator + format2;
return format1
},
_getDateTimeFormatPattern: function(dateTimeFormat) {
return Globalize.findClosestCulture().calendar.patterns[DX.DateTimeFormat[dateTimeFormat.toLowerCase()]]
},
_isDateFormatContains: function(format) {
var result = false;
$.each(DX.DateTimeFormat, function(key) {
result = key === format.toLowerCase();
return !result
});
return result
},
getQuarter: function(month) {
return Math.floor(month / 3)
},
getFirstQuarterMonth: function(month) {
return this.getQuarter(month) * 3
},
_getQuarterString: function(date, format) {
var quarter = this.getQuarter(date.getMonth());
switch (format) {
case'q':
return this.romanDigits[quarter];
case'qq':
return utils.stringFormat(this.defaultQuarterFormat, this.romanDigits[quarter]);
case'Q':
return (quarter + 1).toString();
case'QQ':
return utils.stringFormat(this.defaultQuarterFormat, (quarter + 1).toString())
}
return ''
},
_formatCustomString: function(value, format) {
var regExp = /qq|q|QQ|Q/g,
quarterFormat,
result = '',
index = 0;
regExp.lastIndex = 0;
while (index < format.length) {
quarterFormat = regExp.exec(format);
if (!quarterFormat || quarterFormat.index > index)
result += Globalize.format(value, format.substring(index, quarterFormat ? quarterFormat.index : format.length));
if (quarterFormat) {
result += this._getQuarterString(value, quarterFormat[0]);
index = quarterFormat.index + quarterFormat[0].length
}
else
index = format.length
}
return result
},
_parseNumberFormatString: function(format) {
var formatList,
formatObject = {};
if (!format || typeof format !== 'string')
return;
formatList = format.toLowerCase().split(' ');
$.each(formatList, function(index, value) {
if (value in DX.NumericFormat)
formatObject.formatType = value;
else if (value in DX.LargeNumberFormatPowers)
formatObject.power = DX.LargeNumberFormatPowers[value]
});
if (formatObject.power && !formatObject.formatType)
formatObject.formatType = 'fixedpoint';
if (formatObject.formatType)
return formatObject
},
_calculateNumberPower: function(value, base, minPower, maxPower) {
var number = Math.abs(value);
var power = 0;
if (number > 1)
while (number && number >= base && (maxPower === undefined || power < maxPower)) {
power++;
number = number / base
}
else if (number > 0 && number < 1)
while (number < 1 && (minPower === undefined || power > minPower)) {
power--;
number = number * base
}
return power
},
_getNumberByPower: function(number, power, base) {
var result = number;
while (power > 0) {
result = result / base;
power--
}
while (power < 0) {
result = result * base;
power++
}
return result
},
_formatNumber: function(value, formatObject, precision) {
var powerPostfix;
if (formatObject.power === 'auto')
formatObject.power = this._calculateNumberPower(value, 1000, 0, MAX_LARGE_NUMBER_POWER);
if (formatObject.power)
value = this._getNumberByPower(value, formatObject.power, 1000);
powerPostfix = DX.LargeNumberFormatPostfixes[formatObject.power] || '';
return this._formatNumberCore(value, formatObject.formatType, precision) + powerPostfix
},
_formatNumberExponential: function(value, precision) {
var power = this._calculateNumberPower(value, DECIMAL_BASE),
number = this._getNumberByPower(value, power, DECIMAL_BASE),
powString;
precision = precision === undefined ? 1 : precision;
if (number.toFixed(precision || 0) >= DECIMAL_BASE) {
power++;
number = number / DECIMAL_BASE
}
powString = (power >= 0 ? '+' : '') + power.toString();
return this._formatNumberCore(number, 'fixedpoint', precision) + 'E' + powString
},
_formatNumberCore: function(value, format, precision) {
if (format === 'exponential')
return this._formatNumberExponential(value, precision);
else
return Globalize.format(value, DX.NumericFormat[format] + (utils.isNumber(precision) ? precision : 0))
},
_formatDate: function(date, format) {
var resultFormat = DX.DateTimeFormat[format.toLowerCase()];
format = format.toLowerCase();
if (format === 'quarterandyear')
resultFormat = this._getQuarterString(date, resultFormat) + ' yyyy';
if (format === 'quarter')
return this._getQuarterString(date, resultFormat);
if (format === 'longdatelongtime')
return this._formatDate(date, 'longdate') + ' ' + this._formatDate(date, 'longtime');
if (format === 'shortdateshorttime')
return this._formatDate(date, 'shortDate') + ' ' + this._formatDate(date, 'shortTime');
return Globalize.format(date, resultFormat)
},
format: function(value, format, precision) {
if ($.isPlainObject(format) && format.format)
if (format.dateType)
return this._formatDateEx(value, format);
else if (utils.isNumber(value) && isFinite(value))
return this._formatNumberEx(value, format);
return this._format(value, format, precision)
},
_format: function(value, format, precision) {
var numberFormatObject;
if (!utils.isString(format) || format === '' || !utils.isNumber(value) && !utils.isDate(value))
return utils.isDefined(value) ? value.toString() : '';
numberFormatObject = this._parseNumberFormatString(format);
if (utils.isNumber(value) && numberFormatObject)
return this._formatNumber(value, numberFormatObject, precision);
if (utils.isDate(value) && this._isDateFormatContains(format))
return this._formatDate(value, format);
if (!numberFormatObject && !this._isDateFormatContains(format))
return this._formatCustomString(value, format)
},
_formatNumberEx: function(value, formatInfo) {
var that = this,
numericFormatType = DX.NumericFormat[formatInfo.format.toLowerCase()],
numberFormat = Globalize.culture().numberFormat,
currencyFormat = formatInfo.currencyCulture && Globalize.cultures[formatInfo.currencyCulture] ? Globalize.cultures[formatInfo.currencyCulture].numberFormat.currency : numberFormat.currency,
percentFormat = numberFormat.percent,
formatSettings = that._getUnitFormatSettings(value, formatInfo),
unit = formatSettings.unit,
precision = formatSettings.precision,
showTrailingZeros = formatSettings.showTrailingZeros,
includeGroupSeparator = formatSettings.includeGroupSeparator,
groupSymbol = numberFormat[","],
floatingSymbol = numberFormat["."],
number,
isNegative,
pattern,
currentFormat,
regexParts = /n|\$|-|%/g,
result = "";
if (!utils.isDefined(value))
return '';
value = that._applyUnitToValue(value, unit);
number = Math.abs(value);
isNegative = value < 0;
switch (numericFormatType) {
case DX.NumericFormat.decimal:
pattern = "n";
number = Math[isNegative ? "ceil" : "floor"](number);
if (precision > 0) {
var str = "" + number;
for (var i = str.length; i < precision; i += 1)
str = "0" + str;
number = str
}
if (isNegative)
number = "-" + number;
break;
case DX.NumericFormat.fixedpoint:
currentFormat = numberFormat;
case DX.NumericFormat.currency:
currentFormat = currentFormat || currencyFormat;
case DX.NumericFormat.percent:
currentFormat = currentFormat || percentFormat;
pattern = isNegative ? currentFormat.pattern[0] : currentFormat.pattern[1] || "n";
number = Globalize.format(number * (numericFormatType === DX.NumericFormat.percent ? 100 : 1), "N" + precision);
if (!showTrailingZeros)
number = that._excludeTrailingZeros(number, floatingSymbol);
if (!includeGroupSeparator)
number = number.replace(new RegExp('\\' + groupSymbol, 'g'), '');
break;
case DX.NumericFormat.exponential:
return that._formatNumberExponential(value, precision);
default:
throw"Illegal numeric format: '" + numericFormatType + "'";
}
for (; ; ) {
var lastIndex = regexParts.lastIndex,
matches = regexParts.exec(pattern);
result += pattern.slice(lastIndex, matches ? matches.index : pattern.length);
if (matches)
switch (matches[0]) {
case"-":
if (/[1-9]/.test(number))
result += numberFormat["-"];
break;
case"$":
result += currencyFormat.symbol;
break;
case"%":
result += percentFormat.symbol;
break;
case"n":
result += number + unit;
break
}
else
break
}
return (formatInfo.plus && value > 0 ? "+" : '') + result
},
_excludeTrailingZeros: function(strValue, floatingSymbol) {
var floatingIndex = strValue.indexOf(floatingSymbol),
stopIndex,
i;
if (floatingIndex < 0)
return strValue;
stopIndex = strValue.length;
for (i = stopIndex - 1; i >= floatingIndex && (strValue[i] === '0' || i === floatingIndex); i--)
stopIndex--;
return strValue.substring(0, stopIndex)
},
_getUnitFormatSettings: function(value, formatInfo) {
var unit = formatInfo.unit || '',
precision = formatInfo.precision || 0,
includeGroupSeparator = formatInfo.includeGroupSeparator || false,
showTrailingZeros = formatInfo.showTrailingZeros === undefined ? true : formatInfo.showTrailingZeros,
significantDigits = formatInfo.significantDigits || 1,
absValue;
if (unit.toLowerCase() === 'auto') {
showTrailingZeros = false;
absValue = Math.abs(value);
if (significantDigits < 1)
significantDigits = 1;
if (absValue >= 1000000000) {
unit = 'B';
absValue /= 1000000000
}
else if (absValue >= 1000000) {
unit = 'M';
absValue /= 1000000
}
else if (absValue >= 1000) {
unit = 'K';
absValue /= 1000
}
else
unit = '';
if (absValue === 0)
precision = 0;
else if (absValue < 1) {
precision = significantDigits;
var smallValue = Math.pow(10, -significantDigits);
while (absValue < smallValue) {
smallValue /= 10;
precision++
}
}
else if (absValue >= 100)
precision = significantDigits - 3;
else if (absValue >= 10)
precision = significantDigits - 2;
else
precision = significantDigits - 1
}
if (precision < 0)
precision = 0;
return {
unit: unit,
precision: precision,
showTrailingZeros: showTrailingZeros,
includeGroupSeparator: includeGroupSeparator
}
},
_applyUnitToValue: function(value, unit) {
if (unit === 'B')
return value.toFixed(1) / 1000000000;
if (unit === 'M')
return value / 1000000;
if (unit === 'K')
return value / 1000;
return value
},
_formatDateEx: function(value, formatInfo) {
var that = this,
format = formatInfo.format,
dateType = formatInfo.dateType,
calendar = Globalize.culture().calendars.standard,
time,
index,
dateStr;
format = format.toLowerCase();
if (!utils.isDefined(value))
return '';
if (dateType !== 'num' || format === 'dayofweek')
switch (format) {
case'monthyear':
return that._formatDate(value, 'monthandyear');
case'quarteryear':
return that._getQuarterString(value, 'QQ') + ' ' + value.getFullYear();
case'daymonthyear':
return that._formatDate(value, dateType + 'Date');
case'datehour':
time = new Date(value.getTime());
time.setMinutes(0);
dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
return dateType === 'timeOnly' ? that._formatDate(time, 'shorttime') : dateStr + ' ' + that._formatDate(time, 'shorttime');
case'datehourminute':
dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
return dateType === 'timeOnly' ? that._formatDate(value, 'shorttime') : dateStr + ' ' + that._formatDate(value, 'shorttime');
case'datehourminutesecond':
dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
return dateType === 'timeOnly' ? that._formatDate(value, 'longtime') : dateStr + ' ' + that._formatDate(value, 'longtime');
case'year':
dateStr = value.toString();
return dateType === 'abbr' ? dateStr.slice(2, 4) : dateStr;
case'dateyear':
return dateType === 'abbr' ? that._formatDate(value, 'shortyear') : that._formatDate(value, 'year');
case'quarter':
return utils.stringFormat(that.defaultQuarterFormat, value.toString());
case'month':
index = value - 1;
return dateType === 'abbr' ? calendar.months.namesAbbr[index] : calendar.months.names[index];
case'hour':
if (dateType === 'long') {
time = new Date;
time.setHours(value);
time.setMinutes(0);
return that._formatDate(time, 'shorttime')
}
return value.toString();
case'dayofweek':
index = utils.isString(value) ? $.inArray(value, ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']) : value;
if (dateType !== 'num')
return dateType === 'abbr' ? calendar.days.namesAbbr[index] : calendar.days.names[index];
return ((index - calendar.firstDay + 1 + 7) % 8).toString();
default:
return value.toString()
}
else
return value.toString()
},
getTimeFormat: function(showSecond) {
if (showSecond)
return this._getDateTimeFormatPattern('longtime');
return this._getDateTimeFormatPattern('shorttime')
},
getDateFormatByDifferences: function(dateDifferences) {
var resultFormat = '';
if (dateDifferences.millisecond)
resultFormat = DX.DateTimeFormat.millisecond;
if (dateDifferences.hour || dateDifferences.minute || dateDifferences.second)
resultFormat = this._addFormatSeparator(this.getTimeFormat(dateDifferences.second), resultFormat);
if (dateDifferences.year && dateDifferences.month && dateDifferences.day)
return this._addFormatSeparator(this._getDateTimeFormatPattern('shortdate'), resultFormat);
if (dateDifferences.year && dateDifferences.month)
return DX.DateTimeFormat['monthandyear'];
if (dateDifferences.year)
return DX.DateTimeFormat['year'];
if (dateDifferences.month && dateDifferences.day)
return this._addFormatSeparator(this._getDateTimeFormatPattern('monthandday'), resultFormat);
if (dateDifferences.month)
return DX.DateTimeFormat['month'];
if (dateDifferences.day)
return this._addFormatSeparator('dddd, dd', resultFormat);
return resultFormat
},
getDateFormatByTicks: function(ticks) {
var resultFormat,
maxDif,
currentDif,
i;
if (ticks.length > 1) {
maxDif = utils.getDatesDifferences(ticks[0], ticks[1]);
for (i = 1; i < ticks.length - 1; i++) {
currentDif = utils.getDatesDifferences(ticks[i], ticks[i + 1]);
if (maxDif.count < currentDif.count)
maxDif = currentDif
}
}
else
maxDif = {
year: true,
month: true,
day: true,
hour: ticks[0].getHours() > 0,
minute: ticks[0].getMinutes() > 0,
second: ticks[0].getSeconds() > 0
};
resultFormat = this.getDateFormatByDifferences(maxDif);
return resultFormat
},
getDateFormatByTickInterval: function(startValue, endValue, tickInterval) {
var resultFormat,
dateDifferences,
dateUnitInterval,
dateDifferencesConverter = {
quarter: 'month',
week: 'day'
},
correctDateDifferences = function(dateDifferences, tickInterval, value) {
switch (tickInterval) {
case'year':
dateDifferences.month = value;
case'quarter':
case'month':
dateDifferences.day = value;
case'week':
case'day':
dateDifferences.hour = value;
case'hour':
dateDifferences.minute = value;
case'minute':
dateDifferences.second = value;
case'second':
dateDifferences.millisecond = value
}
},
correctDifferencesByMaxDate = function(differences, minDate, maxDate) {
if (!maxDate.getMilliseconds() && maxDate.getSeconds()) {
if (maxDate.getSeconds() - minDate.getSeconds() === 1) {
differences.millisecond = true;
differences.second = false
}
}
else if (!maxDate.getSeconds() && maxDate.getMinutes()) {
if (maxDate.getMinutes() - minDate.getMinutes() === 1) {
differences.second = true;
differences.minute = false
}
}
else if (!maxDate.getMinutes() && maxDate.getHours()) {
if (maxDate.getHours() - minDate.getHours() === 1) {
differences.minute = true;
differences.hour = false
}
}
else if (!maxDate.getHours() && maxDate.getDate() > 1) {
if (maxDate.getDate() - minDate.getDate() === 1) {
differences.hour = true;
differences.day = false
}
}
else if (maxDate.getDate() === 1 && maxDate.getMonth()) {
if (maxDate.getMonth() - minDate.getMonth() === 1) {
differences.day = true;
differences.month = false
}
}
else if (!maxDate.getMonth() && maxDate.getFullYear())
if (maxDate.getFullYear() - minDate.getFullYear() === 1) {
differences.month = true;
differences.year = false
}
};
tickInterval = utils.isString(tickInterval) ? tickInterval.toLowerCase() : tickInterval;
dateDifferences = utils.getDatesDifferences(startValue, endValue);
if (startValue !== endValue)
correctDifferencesByMaxDate(dateDifferences, startValue > endValue ? endValue : startValue, startValue > endValue ? startValue : endValue);
dateUnitInterval = utils.getDateUnitInterval(dateDifferences);
correctDateDifferences(dateDifferences, dateUnitInterval, true);
dateUnitInterval = utils.getDateUnitInterval(tickInterval || 'second');
correctDateDifferences(dateDifferences, dateUnitInterval, false);
dateDifferences[dateDifferencesConverter[dateUnitInterval] || dateUnitInterval] = true;
resultFormat = this.getDateFormatByDifferences(dateDifferences);
return resultFormat
}
}
})(jQuery, DevExpress);
/*! Module core, file color.js */
(function(DX, undefined) {
var standardColorNames = {
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',
darkgreen: '006400',
darkkhaki: 'bdb76b',
darkmagenta: '8b008b',
darkolivegreen: '556b2f',
darkorange: 'ff8c00',
darkorchid: '9932cc',
darkred: '8b0000',
darksalmon: 'e9967a',
darkseagreen: '8fbc8f',
darkslateblue: '483d8b',
darkslategray: '2f4f4f',
darkturquoise: '00ced1',
darkviolet: '9400d3',
deeppink: 'ff1493',
deepskyblue: '00bfff',
dimgray: '696969',
dodgerblue: '1e90ff',
feldspar: 'd19275',
firebrick: 'b22222',
floralwhite: 'fffaf0',
forestgreen: '228b22',
fuchsia: 'ff00ff',
gainsboro: 'dcdcdc',
ghostwhite: 'f8f8ff',
gold: 'ffd700',
goldenrod: 'daa520',
gray: '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',
lightgrey: 'd3d3d3',
lightgreen: '90ee90',
lightpink: 'ffb6c1',
lightsalmon: 'ffa07a',
lightseagreen: '20b2aa',
lightskyblue: '87cefa',
lightslateblue: '8470ff',
lightslategray: '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',
snow: 'fffafa',
springgreen: '00ff7f',
steelblue: '4682b4',
tan: 'd2b48c',
teal: '008080',
thistle: 'd8bfd8',
tomato: 'ff6347',
turquoise: '40e0d0',
violet: 'ee82ee',
violetred: 'd02090',
wheat: 'f5deb3',
white: 'ffffff',
whitesmoke: 'f5f5f5',
yellow: 'ffff00',
yellowgreen: '9acd32'
};
var standardColorTypes = [{
re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
process: function(colorString) {
return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10)]
}
}, {
re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*\.*\d+)\)$/,
process: function(colorString) {
return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10), parseFloat(colorString[4])]
}
}, {
re: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/,
process: function(colorString) {
return [parseInt(colorString[1], 16), parseInt(colorString[2], 16), parseInt(colorString[3], 16)]
}
}, {
re: /^#([a-f0-9]{1})([a-f0-9]{1})([a-f0-9]{1})$/,
process: function(colorString) {
return [parseInt(colorString[1] + colorString[1], 16), parseInt(colorString[2] + colorString[2], 16), parseInt(colorString[3] + colorString[3], 16)]
}
}, {
re: /^hsv\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
process: function(colorString) {
var h = parseInt(colorString[1], 10),
s = parseInt(colorString[2], 10),
v = parseInt(colorString[3], 10),
rgb = hsvToRgb(h, s, v);
return [rgb[0], rgb[1], rgb[2], 1, [h, s, v]]
}
}, {
re: /^hsl\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
process: function(colorString) {
var h = parseInt(colorString[1], 10),
s = parseInt(colorString[2], 10),
l = parseInt(colorString[3], 10),
rgb = hslToRgb(h, s, l);
return [rgb[0], rgb[1], rgb[2], 1, null, [h, s, l]]
}
}];
function Color(value) {
this.baseColor = value;
var color;
if (value) {
color = String(value).toLowerCase().replace(/ /g, '');
color = standardColorNames[color] ? '#' + standardColorNames[color] : color;
color = parseColor(color)
}
if (!color)
this.colorIsInvalid = true;
color = color || {};
this.r = normalize(color[0]);
this.g = normalize(color[1]);
this.b = normalize(color[2]);
this.a = normalize(color[3], 1, 1);
if (color[4])
this.hsv = {
h: color[4][0],
s: color[4][1],
v: color[4][2]
};
else
this.hsv = toHsvFromRgb(this.r, this.g, this.b);
if (color[5])
this.hsl = {
h: color[5][0],
s: color[5][1],
l: color[5][2]
};
else
this.hsl = toHslFromRgb(this.r, this.g, this.b)
}
function parseColor(color) {
if (color === "transparent")
return [0, 0, 0, 0];
var i = 0,
ii = standardColorTypes.length,
str;
for (; i < ii; ++i) {
str = standardColorTypes[i].re.exec(color);
if (str)
return standardColorTypes[i].process(str)
}
return null
}
function normalize(colorComponent, def, max) {
def = def || 0;
max = max || 255;
return colorComponent < 0 || isNaN(colorComponent) ? def : colorComponent > max ? max : colorComponent
}
function toHexFromRgb(r, g, b) {
return '#' + (0X01000000 | r << 16 | g << 8 | b).toString(16).slice(1)
}
function toHsvFromRgb(r, g, b) {
var max = Math.max(r, g, b),
min = Math.min(r, g, b),
delta = max - min,
H,
S,
V;
V = max;
S = max === 0 ? 0 : 1 - min / max;
if (max === min)
H = 0;
else
switch (max) {
case r:
H = 60 * ((g - b) / delta);
if (g < b)
H = H + 360;
break;
case g:
H = 60 * ((b - r) / delta) + 120;
break;
case b:
H = 60 * ((r - g) / delta) + 240;
break
}
S *= 100;
V *= 100 / 255;
return {
h: Math.round(H),
s: Math.round(S),
v: Math.round(V)
}
}
function hsvToRgb(h, s, v) {
var Vdec,
Vinc,
Vmin,
Hi,
a,
r,
g,
b;
Hi = Math.floor(h / 60);
Vmin = (100 - s) * v / 100;
a = (v - Vmin) * (h % 60 / 60);
Vinc = Vmin + a;
Vdec = v - a;
switch (Hi) {
case 0:
r = v;
g = Vinc;
b = Vmin;
break;
case 1:
r = Vdec;
g = v;
b = Vmin;
break;
case 2:
r = Vmin;
g = v;
b = Vinc;
break;
case 3:
r = Vmin;
g = Vdec;
b = v;
break;
case 4:
r = Vinc;
g = Vmin;
b = v;
break;
case 5:
r = v;
g = Vmin;
b = Vdec;
break
}
return [Math.round(r * 2.55), Math.round(g * 2.55), Math.round(b * 2.55)]
}
function calculateHue(r, g, b, delta) {
var max = Math.max(r, g, b);
switch (max) {
case r:
return (g - b) / delta + (g < b ? 6 : 0);
case g:
return (b - r) / delta + 2;
case b:
return (r - g) / delta + 4
}
}
function toHslFromRgb(r, g, b) {
r = convertTo01Bounds(r, 255);
g = convertTo01Bounds(g, 255);
b = convertTo01Bounds(b, 255);
var max = Math.max(r, g, b),
min = Math.min(r, g, b),
maxMinSumm = max + min,
h,
s,
l = maxMinSumm / 2;
if (max === min)
h = s = 0;
else {
var delta = max - min;
if (l > 0.5)
s = delta / (2 - maxMinSumm);
else
s = delta / maxMinSumm;
h = calculateHue(r, g, b, delta);
h /= 6
}
return {
h: _round(h * 360),
s: _round(s * 100),
l: _round(l * 100)
}
}
function makeTc(colorPart, h) {
var Tc = h;
if (colorPart === "r")
Tc = h + 1 / 3;
if (colorPart === "b")
Tc = h - 1 / 3;
return Tc
}
function modifyTc(Tc) {
if (Tc < 0)
Tc += 1;
if (Tc > 1)
Tc -= 1;
return Tc
}
function hueToRgb(p, q, Tc) {
Tc = modifyTc(Tc);
if (Tc < 1 / 6)
return p + (q - p) * 6 * Tc;
if (Tc < 1 / 2)
return q;
if (Tc < 2 / 3)
return p + (q - p) * (2 / 3 - Tc) * 6;
return p
}
function hslToRgb(h, s, l) {
var r,
g,
b;
h = convertTo01Bounds(h, 360),
s = convertTo01Bounds(s, 100),
l = convertTo01Bounds(l, 100);
if (s === 0)
r = g = b = l;
else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
p = 2 * l - q;
r = hueToRgb(p, q, makeTc("r", h));
g = hueToRgb(p, q, makeTc("g", h));
b = hueToRgb(p, q, makeTc("b", h))
}
return [_round(r * 255), _round(g * 255), _round(b * 255)]
}
function convertTo01Bounds(n, max) {
n = Math.min(max, Math.max(0, parseFloat(n)));
if (Math.abs(n - max) < 0.000001)
return 1;
return n % max / parseFloat(max)
}
function isIntegerBtwMinAndMax(number, min, max) {
min = min || 0;
max = max || 255;
if (number % 1 !== 0 || number < min || number > max || typeof number !== 'number' || isNaN(number))
return false;
return true
}
var _round = Math.round;
Color.prototype = {
constructor: Color,
highlight: function(step) {
step = step || 10;
return this.alter(step).toHex()
},
darken: function(step) {
step = step || 10;
return this.alter(-step).toHex()
},
alter: function(step) {
var result = new Color;
result.r = normalize(this.r + step);
result.g = normalize(this.g + step);
result.b = normalize(this.b + step);
return result
},
blend: function(blendColor, opacity) {
var other = blendColor instanceof Color ? blendColor : new Color(blendColor),
result = new Color;
result.r = normalize(_round(this.r * (1 - opacity) + other.r * opacity));
result.g = normalize(_round(this.g * (1 - opacity) + other.g * opacity));
result.b = normalize(_round(this.b * (1 - opacity) + other.b * opacity));
return result
},
toHex: function() {
return toHexFromRgb(this.r, this.g, this.b)
},
getPureColor: function() {
var rgb = hsvToRgb(this.hsv.h, 100, 100);
return new Color("rgb(" + rgb.join(",") + ")")
},
isValidHex: function(hex) {
return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex)
},
isValidRGB: function(r, g, b) {
if (!isIntegerBtwMinAndMax(r) || !isIntegerBtwMinAndMax(g) || !isIntegerBtwMinAndMax(b))
return false;
return true
},
isValidAlpha: function(a) {
if (isNaN(a) || a < 0 || a > 1 || typeof a !== 'number')
return false;
return true
},
colorIsInvalid: false
};
DX.Color = Color
})(DevExpress);
/*! Module core, file localization.js */
(function($, DX, undefined) {
Globalize.localize = function(key, cultureSelector) {
var neutral = (cultureSelector || this.cultureSelector || "").substring(0, 2);
return this.findClosestCulture(cultureSelector).messages[key] || this.findClosestCulture(neutral).messages[key] || this.cultures["default"].messages[key]
};
var localization = function() {
var newMessages = {};
return {
setup: function(localizablePrefix) {
this.localizeString = function(text) {
var regex = new RegExp("(^|[^a-zA-Z_0-9" + localizablePrefix + "-]+)(" + localizablePrefix + "{1,2})([a-zA-Z_0-9-]+)", "g"),
escapeString = localizablePrefix + localizablePrefix;
return text.replace(regex, function(str, prefix, escape, localizationKey) {
var result = prefix + localizablePrefix + localizationKey;
if (escape !== escapeString)
if (Globalize.cultures["default"].messages[localizationKey])
result = prefix + Globalize.localize(localizationKey);
else
newMessages[localizationKey] = DX.inflector.humanize(localizationKey);
return result
})
}
},
localizeNode: function(node) {
var that = this;
$(node).each(function(index, nodeItem) {
if (!nodeItem.nodeType)
return;
if (nodeItem.nodeType === 3)
nodeItem.nodeValue = that.localizeString(nodeItem.nodeValue);
else if (!$(nodeItem).is("iframe")) {
$.each(nodeItem.attributes || [], function(index, attr) {
if (typeof attr.value === "string") {
var localizedValue = that.localizeString(attr.value);
if (attr.value !== localizedValue)
attr.value = localizedValue
}
});
$(nodeItem).contents().each(function(index, node) {
that.localizeNode(node)
})
}
})
},
getDictionary: function(onlyNew) {
if (onlyNew)
return newMessages;
return $.extend({}, newMessages, Globalize.cultures["default"].messages)
}
}
}();
localization.setup("@");
DX.localization = localization
})(jQuery, DevExpress);
/*! Module core, file core.en.js */
Globalize.addCultureInfo("default", {messages: {
Yes: "Yes",
No: "No",
Cancel: "Cancel",
Clear: "Clear",
Done: "Done",
Loading: "Loading...",
Select: "Select...",
Search: "Search",
Back: "Back",
OK: "OK",
"dxCollectionWidget-noDataText": "No data to display",
"validation-required": "Required",
"validation-required-formatted": "{0} is required",
"validation-numeric": "Value must be a number",
"validation-numeric-formatted": "{0} must be a number",
"validation-range": "Value is out of range",
"validation-range-formatted": "{0} is out of range",
"validation-stringLength": "The length of the value is not correct",
"validation-stringLength-formatted": "The length of {0} is not correct",
"validation-custom": "Value is invalid",
"validation-custom-formatted": "{0} is invalid",
"validation-compare": "Values do not match",
"validation-compare-formatted": "{0} does not match",
"validation-pattern": "Value does not match pattern",
"validation-pattern-formatted": "{0} does not match pattern",
"validation-email": "Email is invalid",
"validation-email-formatted": "{0} is invalid",
"validation-mask": "Value is invalid"
}});
/*! Module core, file widgets-base.en.js */
Globalize.addCultureInfo("default", {messages: {
"dxLookup-searchPlaceholder": "Minimum character number: {0}",
"dxList-pullingDownText": "Pull down to refresh...",
"dxList-pulledDownText": "Release to refresh...",
"dxList-refreshingText": "Refreshing...",
"dxList-pageLoadingText": "Loading...",
"dxList-nextButtonText": "More",
"dxList-selectAll": "Select All",
"dxListEditDecorator-delete": "Delete",
"dxListEditDecorator-more": "More",
"dxScrollView-pullingDownText": "Pull down to refresh...",
"dxScrollView-pulledDownText": "Release to refresh...",
"dxScrollView-refreshingText": "Refreshing...",
"dxScrollView-reachBottomText": "Loading...",
"dxDateBox-simulatedDataPickerTitleTime": "Select time",
"dxDateBox-simulatedDataPickerTitleDate": "Select date",
"dxDateBox-simulatedDataPickerTitleDateTime": "Select date and time",
"dxDateBox-validation-datetime": "Value must be a date or time",
"dxFileUploader-selectFile": "Select file",
"dxFileUploader-dropFile": "or Drop file here",
"dxFileUploader-bytes": "bytes",
"dxFileUploader-kb": "kb",
"dxFileUploader-Mb": "Mb",
"dxFileUploader-Gb": "Gb",
"dxFileUploader-upload": "Upload",
"dxFileUploader-uploaded": "Uploaded",
"dxFileUploader-readyToUpload": "Ready to upload",
"dxFileUploader-uploadFailedMessage": "Upload failed",
"dxRangeSlider-ariaFrom": "From {0}",
"dxRangeSlider-ariaTill": "Till {0}",
"dxSwitch-onText": "ON",
"dxSwitch-offText": "OFF"
}});
/*! Module core, file widgets-mobile.en.js */
/*! Module core, file widgets-web.en.js */
Globalize.addCultureInfo("default", {messages: {
"dxDataGrid-columnChooserTitle": "Column Chooser",
"dxDataGrid-columnChooserEmptyText": "Drag a column here to hide it",
"dxDataGrid-groupContinuesMessage": "Continues on the next page",
"dxDataGrid-groupContinuedMessage": "Continued from the previous page",
"dxDataGrid-editingEditRow": "Edit",
"dxDataGrid-editingSaveRowChanges": "Save",
"dxDataGrid-editingCancelRowChanges": "Cancel",
"dxDataGrid-editingDeleteRow": "Delete",
"dxDataGrid-editingUndeleteRow": "Undelete",
"dxDataGrid-editingConfirmDeleteMessage": "Are you sure you want to delete this record?",
"dxDataGrid-editingConfirmDeleteTitle": "",
"dxDataGrid-groupPanelEmptyText": "Drag a column header here to group by that column",
"dxDataGrid-noDataText": "No data",
"dxDataGrid-searchPanelPlaceholder": "Search...",
"dxDataGrid-filterRowShowAllText": "(All)",
"dxDataGrid-filterRowResetOperationText": "Reset",
"dxDataGrid-filterRowOperationEquals": "Equals",
"dxDataGrid-filterRowOperationNotEquals": "Does not equal",
"dxDataGrid-filterRowOperationLess": "Less than",
"dxDataGrid-filterRowOperationLessOrEquals": "Less than or equal to",
"dxDataGrid-filterRowOperationGreater": "Greater than",
"dxDataGrid-filterRowOperationGreaterOrEquals": "Greater than or equal to",
"dxDataGrid-filterRowOperationStartsWith": "Starts with",
"dxDataGrid-filterRowOperationContains": "Contains",
"dxDataGrid-filterRowOperationNotContains": "Does not contain",
"dxDataGrid-filterRowOperationEndsWith": "Ends with",
"dxDataGrid-applyFilterText": "Apply filter",
"dxDataGrid-trueText": "true",
"dxDataGrid-falseText": "false",
"dxDataGrid-sortingAscendingText": "Sort Ascending",
"dxDataGrid-sortingDescendingText": "Sort Descending",
"dxDataGrid-sortingClearText": "Clear Sorting",
"dxDataGrid-editingSaveAllChanges": "Save changes",
"dxDataGrid-editingCancelAllChanges": "Discard changes",
"dxDataGrid-editingAddRow": "Add a row",
"dxDataGrid-summaryMin": "Min: {0}",
"dxDataGrid-summaryMinOtherColumn": "Min of {1} is {0}",
"dxDataGrid-summaryMax": "Max: {0}",
"dxDataGrid-summaryMaxOtherColumn": "Max of {1} is {0}",
"dxDataGrid-summaryAvg": "Avg: {0}",
"dxDataGrid-summaryAvgOtherColumn": "Avg of {1} is {0}",
"dxDataGrid-summarySum": "Sum: {0}",
"dxDataGrid-summarySumOtherColumn": "Sum of {1} is {0}",
"dxDataGrid-summaryCount": "Count: {0}",
"dxDataGrid-columnFixingFix": "Fix",
"dxDataGrid-columnFixingUnfix": "Unfix",
"dxDataGrid-columnFixingLeftPosition": "To the left",
"dxDataGrid-columnFixingRightPosition": "To the right",
"dxDataGrid-exportTo": "Export to",
"dxDataGrid-exportToExcel": "Export to Excel file",
"dxDataGrid-excelFormat": "Excel file",
"dxDataGrid-selectedRows": "Selected rows",
"dxDataGrid-headerFilterEmptyValue": "(Blanks)",
"dxDataGrid-headerFilterOK": "OK",
"dxDataGrid-headerFilterCancel": "Cancel",
"dxDataGrid-ariaColumn": "Column",
"dxDataGrid-ariaValue": "Value",
"dxDataGrid-ariaFilterCell": "Filter cell",
"dxDataGrid-ariaCollapse": "Collapse",
"dxDataGrid-ariaExpand": "Expand",
"dxDataGrid-ariaDataGrid": "Data grid",
"dxDataGrid-ariaSearchInGrid": "Search in data grid",
"dxDataGrid-ariaSelectAll": "Select all",
"dxDataGrid-ariaSelectRow": "Select row",
"dxPager-infoText": "Page {0} of {1}",
"dxPivotGrid-grandTotal": "Grand Total",
"dxPivotGrid-total": "{0} Total",
"dxPivotGrid-fieldChooserTitle": "Field Chooser",
"dxPivotGrid-showFieldChooser": "Show Field Chooser",
"dxPivotGrid-expandAll": "Expand All",
"dxPivotGrid-collapseAll": "Collapse All",
"dxPivotGrid-sortColumnBySummary": "Sort \"{0}\" by This Column",
"dxPivotGrid-sortRowBySummary": "Sort \"{0}\" by This Row",
"dxPivotGrid-removeAllSorting": "Remove All Sorting",
"dxPivotGrid-rowFields": "Row Fields",
"dxPivotGrid-columnFields": "Column Fields",
"dxPivotGrid-dataFields": "Data Fields",
"dxPivotGrid-filterFields": "Filter Fields",
"dxPivotGrid-allFields": "All Fields",
"dxScheduler-editorLabelTitle": "Subject",
"dxScheduler-editorLabelStartDate": "Start Date",
"dxScheduler-editorLabelEndDate": "End Date",
"dxScheduler-editorLabelDescription": "Description",
"dxScheduler-editorLabelRecurrence": "Repeat",
"dxScheduler-openAppointment": "Open appointment",
"dxScheduler-recurrenceNever": "Never",
"dxScheduler-recurrenceDaily": "Daily",
"dxScheduler-recurrenceWeekly": "Weekly",
"dxScheduler-recurrenceMonthly": "Monthly",
"dxScheduler-recurrenceYearly": "Yearly",
"dxScheduler-recurrenceEvery": "Every",
"dxScheduler-recurrenceEnd": "End repeat",
"dxScheduler-recurrenceAfter": "After",
"dxScheduler-recurrenceOn": "On",
"dxScheduler-recurrenceRepeatDaily": "day(s)",
"dxScheduler-recurrenceRepeatWeekly": "week(s)",
"dxScheduler-recurrenceRepeatMonthly": "month(s)",
"dxScheduler-recurrenceRepeatYearly": "year(s)",
"dxScheduler-switcherDay": "Day",
"dxScheduler-switcherWeek": "Week",
"dxScheduler-switcherWorkWeek": "Work week",
"dxScheduler-switcherMonth": "Month",
"dxScheduler-recurrenceRepeatOnDate": "on date",
"dxScheduler-recurrenceRepeatCount": "occurrence(s)",
"dxScheduler-allDay": "All day",
"dxCalendar-todayButtonText": "Today",
"dxCalendar-ariaWidgetName": "Calendar",
"dxColorView-ariaRed": "Red",
"dxColorView-ariaGreen": "Green",
"dxColorView-ariaBlue": "Blue",
"dxColorView-ariaAlpha": "Transparency",
"dxColorView-ariaHex": "Color code"
}});
/*! Module core, file validationEngine.js */
(function($, DX, undefined) {
var utils = DX.utils;
var rulesValidators = {
required: {
validate: function(value, rule) {
if (!utils.isDefined(value))
return false;
if (value === false)
return false;
value = String(value);
if (rule.trim || !utils.isDefined(rule.trim))
value = $.trim(value);
return value !== ""
},
defaultMessage: function() {
return Globalize.localize("validation-required")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-required-formatted")
}
},
numeric: {
validate: function(value, rule) {
if (!rulesValidators.required.validate(value, {}))
return true;
if (rule.useCultureSettings && utils.isString(value))
return !isNaN(Globalize.parseFloat(value));
else
return $.isNumeric(value)
},
defaultMessage: function() {
return Globalize.localize("validation-numeric")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-numeric-formatted")
}
},
range: {
validate: function(value, rule) {
if (!rulesValidators.required.validate(value, {}))
return true;
var validNumber = rulesValidators["numeric"].validate(value, rule),
validValue = utils.isDefined(value),
number = validNumber ? parseFloat(value) : validValue && value.valueOf(),
min = rule.min,
max = rule.max;
if (!(validNumber || utils.isDate(value)) && !validValue)
return false;
if (utils.isDefined(min)) {
if (utils.isDefined(max))
return number >= min && number <= max;
return number >= min
}
else if (utils.isDefined(max))
return number <= max;
else
throw DX.Error("E0101");
return false
},
defaultMessage: function() {
return Globalize.localize("validation-range")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-range-formatted")
}
},
stringLength: {
validate: function(value, rule) {
value = String(value);
if (rule.trim || !utils.isDefined(rule.trim))
value = $.trim(value);
return rulesValidators.range.validate(value.length, $.extend({}, rule))
},
defaultMessage: function() {
return Globalize.localize("validation-stringLength")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-stringLength-formatted")
}
},
custom: {
validate: function(value, rule) {
return rule.validationCallback({
value: value,
validator: rule.validator,
rule: rule
})
},
defaultMessage: function() {
return Globalize.localize("validation-custom")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-custom-formatted")
}
},
compare: {
validate: function(value, rule) {
if (!rule.comparisonTarget)
throw DX.Error("E0102");
$.extend(rule, {reevaluate: true});
var otherValue = rule.comparisonTarget(),
type = rule.comparisonType || "==";
switch (type) {
case"==":
return value == otherValue;
case"!=":
return value != otherValue;
case"===":
return value === otherValue;
case"!==":
return value !== otherValue;
case">":
return value > otherValue;
case">=":
return value >= otherValue;
case"<":
return value < otherValue;
case"<=":
return value <= otherValue
}
},
defaultMessage: function() {
return Globalize.localize("validation-compare")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-compare-formatted")
}
},
pattern: {
validate: function(value, rule) {
if (!rulesValidators.required.validate(value, {}))
return true;
var pattern = rule.pattern;
if (utils.isString(pattern))
pattern = new RegExp(pattern);
return pattern.test(value)
},
defaultMessage: function() {
return Globalize.localize("validation-pattern")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-pattern-formatted")
}
},
email: {
validate: function(value, rule) {
if (!rulesValidators.required.validate(value, {}))
return true;
return rulesValidators.pattern.validate(value, $.extend({}, rule, {pattern: /^[\d\w\._\-]+@([\d\w\._\-]+\.)+[\w]+$/i}))
},
defaultMessage: function() {
return Globalize.localize("validation-email")
},
defaultFormattedMessage: function() {
return Globalize.localize("validation-email-formatted")
}
}
};
var GroupConfig = DX.Class.inherit({
ctor: function(group) {
this.group = group;
this.validators = []
},
validate: function() {
var result = {
isValid: true,
brokenRules: [],
validators: []
};
$.each(this.validators, function(_, validator) {
var validatorResult = validator.validate();
result.isValid = result.isValid && validatorResult.isValid;
if (validatorResult.brokenRule)
result.brokenRules.push(validatorResult.brokenRule);
result.validators.push(validator)
});
this.fireEvent("validated", [{
validators: result.validators,
brokenRules: result.brokenRules,
isValid: result.isValid
}]);
return result
},
reset: function() {
$.each(this.validators, function(_, validator) {
validator.reset()
})
}
}).include(DX.EventsMixin);
DX.validationEngine = {
groups: [],
getGroupConfig: function(group) {
var result = $.grep(this.groups, function(config) {
return config.group === group
});
if (result.length)
return result[0]
},
initGroups: function() {
this.groups = [];
this.addGroup()
},
addGroup: function(group) {
var config = this.getGroupConfig(group);
if (!config) {
config = new GroupConfig(group);
this.groups.push(config)
}
return config
},
removeGroup: function(group) {
var config = this.getGroupConfig(group),
index = $.inArray(config, this.groups);
if (index > -1)
this.groups.splice(index, 1);
return config
},
_setDefaultMessage: function(rule, validator, name) {
if (!utils.isDefined(rule.message))
if (validator.defaultFormattedMessage && utils.isDefined(name))
rule.message = validator.defaultFormattedMessage().replace(/\{0\}/, name);
else
rule.message = validator.defaultMessage()
},
validate: function validate(value, rules, name) {
var result = {
name: name,
value: value,
brokenRule: null,
isValid: true,
validationRules: rules
},
that = this;
$.each(rules || [], function(_, rule) {
var ruleValidator = rulesValidators[rule.type],
ruleValidationResult;
if (ruleValidator) {
if (utils.isDefined(rule.isValid) && rule.value === value && !rule.reevaluate) {
if (!rule.isValid) {
result.isValid = false;
result.brokenRule = rule;
return false
}
return true
}
rule.value = value;
ruleValidationResult = ruleValidator.validate(value, rule);
rule.isValid = ruleValidationResult;
if (!ruleValidationResult) {
result.isValid = false;
that._setDefaultMessage(rule, ruleValidator, name);
result.brokenRule = rule
}
if (!rule.isValid)
return false
}
else
throw DX.Error("E0100");
});
return result
},
registerValidatorInGroup: function(group, validator) {
var groupConfig = DX.validationEngine.addGroup(group);
if ($.inArray(validator, groupConfig.validators) < 0)
groupConfig.validators.push(validator)
},
removeRegistredValidator: function(group, validator) {
var config = DX.validationEngine.getGroupConfig(group),
validatorsInGroup = config && config.validators;
var index = $.inArray(validator, validatorsInGroup);
if (index > -1)
validatorsInGroup.splice(index, 1)
},
validateGroup: function(group) {
var groupConfig = DX.validationEngine.getGroupConfig(group);
if (!groupConfig)
throw DX.Error("E0110");
return groupConfig.validate()
},
resetGroup: function(group) {
var groupConfig = DX.validationEngine.getGroupConfig(group);
if (!groupConfig)
throw DX.Error("E0110");
return groupConfig.reset()
}
};
DX.validationEngine.initGroups()
})(jQuery, DevExpress);
/*! Module core, file data.errors.js */
(function($, DX) {
$.extend(DX.ERROR_MESSAGES, {
E4000: "[DevExpress.data]: {0}",
E4001: "Unknown aggregating function is detected: '{0}'",
E4002: "Unsupported OData protocol version is used",
E4003: "Unknown filter operation is used: {0}",
E4004: "The thenby() method is called before the sortby() method",
E4005: "Store requires a key expression for this operation",
E4006: "ArrayStore 'data' option must be an array",
E4007: "Compound keys cannot be auto-generated",
E4008: "Attempt to insert an item with the a duplicated key",
E4009: "Data item with specified key value cannot be found",
E4010: "CustomStore does not support creating queries",
E4011: "Custom Store method is not implemented or is not a function: {0}",
E4012: "Custom Store method returns an invalid value: {0}",
E4013: "Local Store requires the 'name' configuration option is specified",
E4014: "Unknown key type is detected: {0}",
E4015: "Unknown entity name or alias is used: {0}",
E4016: "The compileSetter(expr) method is called with 'self' passed as a parameter",
E4017: "Keys cannot be modified"
})
})(jQuery, DevExpress);
/*! Module core, file data.js */
(function($, DX, undefined) {
var bracketsToDots = function(expr) {
return expr.replace(/\[/g, ".").replace(/\]/g, "")
};
var unwrapObservable = DX.utils.unwrapObservable;
var isObservable = function(value) {
return DX.support.hasKo && ko.isObservable(value)
};
var readPropValue = function(obj, propName) {
if (propName === "this")
return obj;
return obj[propName]
};
var assignPropValue = function(obj, propName, value, options) {
if (propName === "this")
throw new DX.Error("E4016");
var propValue = obj[propName];
if (options.unwrapObservables && isObservable(propValue))
propValue(value);
else
obj[propName] = value
};
var prepareOptions = function(options) {
options = options || {};
options.unwrapObservables = options.unwrapObservables !== undefined ? options.unwrapObservables : true;
return options
};
var unwrap = function(value, options) {
return options.unwrapObservables ? unwrapObservable(value) : value
};
var compileGetter = function(expr) {
if (arguments.length > 1)
expr = $.makeArray(arguments);
if (!expr || expr === "this")
return function(obj) {
return obj
};
if ($.isFunction(expr))
return expr;
if ($.isArray(expr))
return combineGetters(expr);
expr = bracketsToDots(expr);
var path = expr.split(".");
return function(obj, options) {
options = prepareOptions(options);
var current = unwrap(obj, options);
$.each(path, function() {
if (!current)
return false;
var next = unwrap(current[this], options);
if ($.isFunction(next) && !options.functionsAsIs)
next = next.call(current);
current = next
});
return current
}
};
var combineGetters = function(getters) {
var compiledGetters = {};
$.each(getters, function() {
compiledGetters[this] = compileGetter(this)
});
return function(obj, options) {
var result = {};
$.each(compiledGetters, function(name) {
var value = this(obj, options),
current,
path,
last,
i;
if (value === undefined)
return;
current = result;
path = name.split(".");
last = path.length - 1;
for (i = 0; i < last; i++)
current = current[path[i]] = {};
current[path[i]] = value
});
return result
}
};
var compileSetter = function(expr) {
expr = expr || "this";
expr = bracketsToDots(expr);
var pos = expr.lastIndexOf("."),
targetGetter = compileGetter(expr.substr(0, pos)),
targetPropName = expr.substr(1 + pos);
return function(obj, value, options) {
options = prepareOptions(options);
var target = targetGetter(obj, {
functionsAsIs: options.functionsAsIs,
unwrapObservables: options.unwrapObservables
}),
prevTargetValue = readPropValue(target, targetPropName);
if (!options.functionsAsIs && $.isFunction(prevTargetValue) && !isObservable(prevTargetValue))
target[targetPropName](value);
else {
prevTargetValue = unwrap(prevTargetValue, options);
if (options.merge && $.isPlainObject(value) && (prevTargetValue === undefined || $.isPlainObject(prevTargetValue)) && !(value instanceof $.Event)) {
if (!prevTargetValue)
assignPropValue(target, targetPropName, {}, options);
DX.utils.deepExtendArraySafe(unwrap(readPropValue(target, targetPropName), options), value)
}
else
assignPropValue(target, targetPropName, value, options)
}
}
};
var normalizeBinaryCriterion = function(crit) {
return [crit[0], crit.length < 3 ? "=" : String(crit[1]).toLowerCase(), crit.length < 2 ? true : crit[crit.length - 1]]
};
var normalizeSortingInfo = function(info) {
if (!$.isArray(info))
info = [info];
return $.map(info, function(i) {
return {
selector: $.isFunction(i) || typeof i === "string" ? i : i.getter || i.field || i.selector,
desc: !!(i.desc || String(i.dir).charAt(0).toLowerCase() === "d")
}
})
};
var Guid = DX.Class.inherit({
ctor: function(value) {
if (value)
value = String(value);
this._value = this._normalize(value || this._generate())
},
_normalize: function(value) {
value = value.replace(/[^a-f0-9]/ig, "").toLowerCase();
while (value.length < 32)
value += "0";
return [value.substr(0, 8), value.substr(8, 4), value.substr(12, 4), value.substr(16, 4), value.substr(20, 12)].join("-")
},
_generate: function() {
var value = "";
for (var i = 0; i < 32; i++)
value += Math.round(Math.random() * 15).toString(16);
return value
},
toString: function() {
return this._value
},
valueOf: function() {
return this._value
},
toJSON: function() {
return this._value
}
});
var toComparable = function(value, caseSensitive) {
if (value instanceof Date)
return value.getTime();
if (value instanceof Guid)
return value.valueOf();
if (!caseSensitive && typeof value === "string")
return value.toLowerCase();
return value
};
var keysEqual = function(keyExpr, key1, key2) {
if ($.isArray(keyExpr)) {
var names = $.map(key1, function(v, k) {
return k
}),
name;
for (var i = 0; i < names.length; i++) {
name = names[i];
if (toComparable(key1[name], true) != toComparable(key2[name], true))
return false
}
return true
}
return toComparable(key1, true) == toComparable(key2, true)
};
var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var base64_encode = function(input) {
if (!$.isArray(input))
input = stringToByteArray(String(input));
var result = "";
function getBase64Char(index) {
return BASE64_CHARS.charAt(index)
}
for (var i = 0; i < input.length; i += 3) {
var octet1 = input[i],
octet2 = input[i + 1],
octet3 = input[i + 2];
result += $.map([octet1 >> 2, (octet1 & 3) << 4 | octet2 >> 4, isNaN(octet2) ? 64 : (octet2 & 15) << 2 | octet3 >> 6, isNaN(octet3) ? 64 : octet3 & 63], getBase64Char).join("")
}
return result
};
var stringToByteArray = function(str) {
var bytes = [],
code,
i;
for (i = 0; i < str.length; i++) {
code = str.charCodeAt(i);
if (code < 128)
bytes.push(code);
else if (code < 2048)
bytes.push(192 + (code >> 6), 128 + (code & 63));
else if (code < 65536)
bytes.push(224 + (code >> 12), 128 + (code >> 6 & 63), 128 + (code & 63));
else if (code < 2097152)
bytes.push(240 + (code >> 18), 128 + (code >> 12 & 63), 128 + (code >> 6 & 63), 128 + (code & 63))
}
return bytes
};
var errorMessageFromXhr = function() {
var textStatusMessages = {
timeout: "Network connection timeout",
error: "Unspecified network error",
parsererror: "Unexpected server response"
};
var textStatusDetails = {
timeout: "possible causes: the remote host is not accessible, overloaded or is not included into the domain white-list when being run in the native container",
error: "if the remote host is located on another domain, make sure it properly supports cross-origin resource sharing (CORS), or use the JSONP approach instead",
parsererror: "the remote host did not respond with valid JSON data"
};
var explainTextStatus = function(textStatus) {
var result = textStatusMessages[textStatus];
if (!result)
return textStatus;
result += " (" + textStatusDetails[textStatus] + ")";
return result
};
return function(xhr, textStatus) {
if (xhr.status < 400)
return explainTextStatus(textStatus);
return xhr.statusText
}
}();
var aggregators = {
count: {
seed: 0,
step: function(count) {
return 1 + count
}
},
sum: {
seed: 0,
step: function(sum, item) {
return sum + item
}
},
min: {step: function(min, item) {
return item < min ? item : min
}},
max: {step: function(max, item) {
return item > max ? item : max
}},
avg: {
seed: [0, 0],
step: function(pair, value) {
return [pair[0] + value, pair[1] + 1]
},
finalize: function(pair) {
return pair[1] ? pair[0] / pair[1] : NaN
}
}
};
function handleError(error) {
var id = "E4000";
if (error && "__id" in error)
id = error.__id;
DX.log(id, error)
}
function multiLevelSearch(options) {
var itemsGetter = options.itemsGetter,
itemsSetter = options.itemsSetter,
criteria = options.criteria,
data = options.data;
function selector(x) {
var hash,
items = itemsGetter(x);
if (isNotAnEmptyArray(items)) {
hash = {};
itemsSetter(hash, multiLevelSearch({
data: items,
criteria: criteria,
itemsGetter: itemsGetter,
itemsSetter: itemsSetter
}));
return $.extend({}, x, hash)
}
return x
}
function criterion(x) {
return isNotAnEmptyArray(itemsGetter(x))
}
function isNotAnEmptyArray(x) {
return $.isArray(x) && x.length > 0
}
return DX.data.query(data).select(selector).filter([[criterion], "or", criteria]).toArray()
}
var data = DX.data = {
utils: {
compileGetter: compileGetter,
compileSetter: compileSetter,
normalizeBinaryCriterion: normalizeBinaryCriterion,
normalizeSortingInfo: normalizeSortingInfo,
toComparable: toComparable,
keysEqual: keysEqual,
errorMessageFromXhr: errorMessageFromXhr,
aggregators: aggregators,
multiLevelSearch: multiLevelSearch
},
Guid: Guid,
base64_encode: base64_encode,
queryImpl: {},
queryAdapters: {},
query: function() {
var impl = $.isArray(arguments[0]) ? "array" : "remote";
return data.queryImpl[impl].apply(this, arguments)
},
errorHandler: null,
_errorHandler: function(error) {
handleError(error);
if (data.errorHandler)
data.errorHandler(error)
}
}
})(jQuery, DevExpress);
/*! Module core, file data.aggregateCalculator.js */
(function($, DX, undefined) {
var data = DX.data,
utils = data.utils;
function isCount(aggregator) {
return aggregator === utils.aggregators.count
}
function normalizeAggregate(aggregate) {
var selector = utils.compileGetter(aggregate.selector),
aggregator = aggregate.aggregator;
if (typeof aggregator === "string") {
aggregator = data.utils.aggregators[aggregator];
if (!aggregator)
throw DX.Error("E4001", aggregate.aggregator);
}
return {
selector: selector,
aggregator: aggregator
}
}
data.AggregateCalculator = DX.Class.inherit({
ctor: function(options) {
this._data = options.data;
this._groupLevel = options.groupLevel || 0;
this._totalAggregates = $.map(options.totalAggregates || [], normalizeAggregate);
this._groupAggregates = $.map(options.groupAggregates || [], normalizeAggregate);
this._totals = []
},
calculate: function() {
if (this._totalAggregates.length)
this._calculateTotals(0, {items: this._data});
if (this._groupAggregates.length && this._groupLevel > 0)
this._calculateGroups(0, {items: this._data})
},
totalAggregates: function() {
return this._totals
},
_aggregate: function(data, aggregates, container) {
var i,
j;
for (i = 0; i < aggregates.length; i++) {
if (isCount(aggregates[i].aggregator)) {
container[i] = (container[i] || 0) + data.items.length;
continue
}
for (j = 0; j < data.items.length; j++)
this._accumulate(i, aggregates[i], container, data.items[j])
}
},
_calculateTotals: function(level, data) {
var i;
if (level === 0)
this._totals = this._seed(this._totalAggregates);
if (level === this._groupLevel)
this._aggregate(data, this._totalAggregates, this._totals);
else
for (i = 0; i < data.items.length; i++)
this._calculateTotals(level + 1, data.items[i]);
if (level === 0)
this._totals = this._finalize(this._totalAggregates, this._totals)
},
_calculateGroups: function(level, data, outerAggregates) {
var i,
innerAggregates;
if (level === this._groupLevel)
this._aggregate(data, this._groupAggregates, outerAggregates);
else
for (i = 0; i < data.items.length; i++) {
innerAggregates = this._seed(this._groupAggregates);
this._calculateGroups(level + 1, data.items[i], innerAggregates);
data.items[i].aggregates = this._finalize(this._groupAggregates, innerAggregates);
if (level > 0) {
outerAggregates = outerAggregates || this._seed(this._groupAggregates);
this._calculateGroups(level + 1, data.items[i], outerAggregates)
}
}
},
_seed: function(aggregates) {
return $.map(aggregates, function(aggregate) {
var aggregator = aggregate.aggregator,
seed = "seed" in aggregator ? aggregator.seed : NaN;
return $.isArray(seed) ? [seed] : seed
})
},
_accumulate: function(aggregateIndex, aggregate, results, item) {
var value = aggregate.selector(item),
aggregator = aggregate.aggregator;
results[aggregateIndex] = results[aggregateIndex] !== results[aggregateIndex] ? value : aggregator.step(results[aggregateIndex], value)
},
_finalize: function(aggregates, results) {
return $.map(aggregates, function(aggregate, index) {
var fin = aggregate.aggregator.finalize;
return fin ? fin(results[index]) : results[index]
})
}
})
})(jQuery, DevExpress);
/*! Module core, file data.query.array.js */
(function($, DX, undefined) {
var Class = DX.Class,
data = DX.data,
queryImpl = data.queryImpl,
compileGetter = data.utils.compileGetter,
toComparable = data.utils.toComparable;
var Iterator = Class.inherit({
toArray: function() {
var result = [];
this.reset();
while (this.next())
result.push(this.current());
return result
},
countable: function() {
return false
}
});
var ArrayIterator = Iterator.inherit({
ctor: function(array) {
this.array = array;
this.index = -1
},
next: function() {
if (this.index + 1 < this.array.length) {
this.index++;
return true
}
return false
},
current: function() {
return this.array[this.index]
},
reset: function() {
this.index = -1
},
toArray: function() {
return this.array.slice(0)
},
countable: function() {
return true
},
count: function() {
return this.array.length
}
});
var WrappedIterator = Iterator.inherit({
ctor: function(iter) {
this.iter = iter
},
next: function() {
return this.iter.next()
},
current: function() {
return this.iter.current()
},
reset: function() {
return this.iter.reset()
}
});
var MapIterator = WrappedIterator.inherit({
ctor: function(iter, mapper) {
this.callBase(iter);
this.index = -1;
this.mapper = mapper
},
current: function() {
return this.mapper(this.callBase(), this.index)
},
next: function() {
var hasNext = this.callBase();
if (hasNext)
this.index++;
return hasNext
}
});
var SortIterator = Iterator.inherit({
ctor: function(iter, getter, desc) {
if (!(iter instanceof MapIterator))
iter = new MapIterator(iter, this._wrap);
this.iter = iter;
this.rules = [{
getter: getter,
desc: desc
}]
},
thenBy: function(getter, desc) {
var result = new SortIterator(this.sortedIter || this.iter, getter, desc);
if (!this.sortedIter)
result.rules = this.rules.concat(result.rules);
return result
},
next: function() {
this._ensureSorted();
return this.sortedIter.next()
},
current: function() {
this._ensureSorted();
return this.sortedIter.current()
},
reset: function() {
delete this.sortedIter
},
countable: function() {
return this.sortedIter || this.iter.countable()
},
count: function() {
if (this.sortedIter)
return this.sortedIter.count();
return this.iter.count()
},
_ensureSorted: function() {
if (this.sortedIter)
return;
$.each(this.rules, function() {
this.getter = compileGetter(this.getter)
});
this.sortedIter = new MapIterator(new ArrayIterator(this.iter.toArray().sort($.proxy(this._compare, this))), this._unwrap)
},
_wrap: function(record, index) {
return {
index: index,
value: record
}
},
_unwrap: function(wrappedItem) {
return wrappedItem.value
},
_compare: function(x, y) {
var xIndex = x.index,
yIndex = y.index;
x = x.value;
y = y.value;
if (x === y)
return xIndex - yIndex;
for (var i = 0, rulesCount = this.rules.length; i < rulesCount; i++) {
var rule = this.rules[i],
xValue = toComparable(rule.getter(x)),
yValue = toComparable(rule.getter(y)),
factor = rule.desc ? -1 : 1;
if (xValue < yValue)
return -factor;
if (xValue > yValue)
return factor;
if (xValue !== yValue)
return !xValue ? -factor : factor
}
return xIndex - yIndex
}
});
var compileCriteria = function() {
var compileGroup = function(crit) {
var operands = [],
bag = ["return function(d) { return "],
index = 0,
pushAnd = false;
$.each(crit, function() {
if ($.isArray(this) || $.isFunction(this)) {
if (pushAnd)
bag.push(" && ");
operands.push(compileCriteria(this));
bag.push("op[", index, "](d)");
index++;
pushAnd = true
}
else {
bag.push(/and|&/i.test(this) ? " && " : " || ");
pushAnd = false
}
});
bag.push(" }");
return new Function("op", bag.join(""))(operands)
};
var toString = function(value) {
return DX.utils.isDefined(value) ? value.toString() : ''
};
var compileBinary = function(crit) {
crit = data.utils.normalizeBinaryCriterion(crit);
var getter = compileGetter(crit[0]),
op = crit[1],
value = crit[2];
value = toComparable(value);
switch (op.toLowerCase()) {
case"=":
return compileEquals(getter, value);
case"<>":
return compileEquals(getter, value, true);
case">":
return function(obj) {
return toComparable(getter(obj)) > value
};
case"<":
return function(obj) {
return toComparable(getter(obj)) < value
};
case">=":
return function(obj) {
return toComparable(getter(obj)) >= value
};
case"<=":
return function(obj) {
return toComparable(getter(obj)) <= value
};
case"startswith":
return function(obj) {
return toComparable(toString(getter(obj))).indexOf(value) === 0
};
case"endswith":
return function(obj) {
var getterValue = toComparable(toString(getter(obj))),
searchValue = toString(value);
if (getterValue.length < searchValue.length)
return false;
return getterValue.lastIndexOf(value) === getterValue.length - value.length
};
case"contains":
return function(obj) {
return toComparable(toString(getter(obj))).indexOf(value) > -1
};
case"notcontains":
return function(obj) {
return toComparable(toString(getter(obj))).indexOf(value) === -1
}
}
throw DX.Error("E4003", op);
};
function compileEquals(getter, value, negate) {
return function(obj) {
obj = toComparable(getter(obj));
var result = useStrictComparison(value) ? obj === value : obj == value;
if (negate)
result = !result;
return result
}
}
function useStrictComparison(value) {
return value === "" || value === 0 || value === null || value === false || value === undefined
}
return function(crit) {
if ($.isFunction(crit))
return crit;
if ($.isArray(crit[0]))
return compileGroup(crit);
return compileBinary(crit)
}
}();
var FilterIterator = WrappedIterator.inherit({
ctor: function(iter, criteria) {
this.callBase(iter);
this.criteria = compileCriteria(criteria)
},
next: function() {
while (this.iter.next())
if (this.criteria(this.current()))
return true;
return false
}
});
var GroupIterator = Iterator.inherit({
ctor: function(iter, getter) {
this.iter = iter;
this.getter = getter
},
next: function() {
this._ensureGrouped();
return this.groupedIter.next()
},
current: function() {
this._ensureGrouped();
return this.groupedIter.current()
},
reset: function() {
delete this.groupedIter
},
countable: function() {
return !!this.groupedIter
},
count: function() {
return this.groupedIter.count()
},
_ensureGrouped: function() {
if (this.groupedIter)
return;
var hash = {},
keys = [],
iter = this.iter,
getter = compileGetter(this.getter);
iter.reset();
while (iter.next()) {
var current = iter.current(),
key = getter(current);
if (key in hash)
hash[key].push(current);
else {
hash[key] = [current];
keys.push(key)
}
}
this.groupedIter = new ArrayIterator($.map(keys, function(key) {
return {
key: key,
items: hash[key]
}
}))
}
});
var SelectIterator = WrappedIterator.inherit({
ctor: function(iter, getter) {
this.callBase(iter);
this.getter = compileGetter(getter)
},
current: function() {
return this.getter(this.callBase())
},
countable: function() {
return this.iter.countable()
},
count: function() {
return this.iter.count()
}
});
var SliceIterator = WrappedIterator.inherit({
ctor: function(iter, skip, take) {
this.callBase(iter);
this.skip = Math.max(0, skip);
this.take = Math.max(0, take);
this.pos = 0
},
next: function() {
if (this.pos >= this.skip + this.take)
return false;
while (this.pos < this.skip && this.iter.next())
this.pos++;
this.pos++;
return this.iter.next()
},
reset: function() {
this.callBase();
this.pos = 0
},
countable: function() {
return this.iter.countable()
},
count: function() {
return Math.min(this.iter.count() - this.skip, this.take)
}
});
queryImpl.array = function(iter, queryOptions) {
queryOptions = queryOptions || {};
if (!(iter instanceof Iterator))
iter = new ArrayIterator(iter);
var handleError = function(error) {
var handler = queryOptions.errorHandler;
if (handler)
handler(error);
data._errorHandler(error)
};
var aggregateCore = function(aggregator) {
var d = $.Deferred().fail(handleError),
seed,
step = aggregator.step,
finalize = aggregator.finalize;
try {
iter.reset();
if ("seed" in aggregator)
seed = aggregator.seed;
else
seed = iter.next() ? iter.current() : NaN;
var accumulator = seed;
while (iter.next())
accumulator = step(accumulator, iter.current());
d.resolve(finalize ? finalize(accumulator) : accumulator)
}
catch(x) {
d.reject(x)
}
return d.promise()
};
var aggregate = function(seed, step, finalize) {
if (arguments.length < 2)
return aggregateCore({step: arguments[0]});
return aggregateCore({
seed: seed,
step: step,
finalize: finalize
})
};
var standardAggregate = function(name) {
return aggregateCore(data.utils.aggregators[name])
};
var select = function(getter) {
if (!$.isFunction(getter) && !$.isArray(getter))
getter = $.makeArray(arguments);
return chainQuery(new SelectIterator(iter, getter))
};
var selectProp = function(name) {
return select(compileGetter(name))
};
var chainQuery = function(iter) {
return queryImpl.array(iter, queryOptions)
};
return {
toArray: function() {
return iter.toArray()
},
enumerate: function() {
var d = $.Deferred().fail(handleError);
try {
d.resolve(iter.toArray())
}
catch(x) {
d.reject(x)
}
return d.promise()
},
sortBy: function(getter, desc) {
return chainQuery(new SortIterator(iter, getter, desc))
},
thenBy: function(getter, desc) {
if (iter instanceof SortIterator)
return chainQuery(iter.thenBy(getter, desc));
throw DX.Error("E4004");
},
filter: function(criteria) {
if (!$.isArray(criteria))
criteria = $.makeArray(arguments);
return chainQuery(new FilterIterator(iter, criteria))
},
slice: function(skip, take) {
if (take === undefined)
take = Number.MAX_VALUE;
return chainQuery(new SliceIterator(iter, skip, take))
},
select: select,
groupBy: function(getter) {
return chainQuery(new GroupIterator(iter, getter))
},
aggregate: aggregate,
count: function() {
if (iter.countable()) {
var d = $.Deferred().fail(handleError);
try {
d.resolve(iter.count())
}
catch(x) {
d.reject(x)
}
return d.promise()
}
return standardAggregate("count")
},
sum: function(getter) {
if (getter)
return selectProp(getter).sum();
return standardAggregate("sum")
},
min: function(getter) {
if (getter)
return selectProp(getter).min();
return standardAggregate("min")
},
max: function(getter) {
if (getter)
return selectProp(getter).max();
return standardAggregate("max")
},
avg: function(getter) {
if (getter)
return selectProp(getter).avg();
return standardAggregate("avg")
}
}
}
})(jQuery, DevExpress);
/*! Module core, file data.query.remote.js */
(function($, DX, undefined) {
var data = DX.data,
queryImpl = data.queryImpl;
queryImpl.remote = function(url, queryOptions, tasks) {
tasks = tasks || [];
queryOptions = queryOptions || {};
var createTask = function(name, args) {
return {
name: name,
args: args
}
};
var exec = function(executorTask) {
var d = $.Deferred(),
_adapterFactory,
_adapter,
_taskQueue,
_currentTask,
_mergedSortArgs;
var rejectWithNotify = function(error) {
var handler = queryOptions.errorHandler;
if (handler)
handler(error);
data._errorHandler(error);
d.reject(error)
};
function mergeSortTask(task) {
switch (task.name) {
case"sortBy":
_mergedSortArgs = [task.args];
return true;
case"thenBy":
if (!_mergedSortArgs)
throw DX.Error("E4004");
_mergedSortArgs.push(task.args);
return true
}
return false
}
function unmergeSortTasks() {
var head = _taskQueue[0],
unmergedTasks = [];
if (head && head.name === "multiSort") {
_taskQueue.shift();
$.each(head.args[0], function() {
unmergedTasks.push(createTask(unmergedTasks.length ? "thenBy" : "sortBy", this))
})
}
_taskQueue = unmergedTasks.concat(_taskQueue)
}
try {
_adapterFactory = queryOptions.adapter || "odata";
if (!$.isFunction(_adapterFactory))
_adapterFactory = data.queryAdapters[_adapterFactory];
_adapter = _adapterFactory(queryOptions);
_taskQueue = [].concat(tasks).concat(executorTask);
while (_taskQueue.length) {
_currentTask = _taskQueue[0];
if (!mergeSortTask(_currentTask)) {
if (_mergedSortArgs) {
_taskQueue.unshift(createTask("multiSort", [_mergedSortArgs]));
_mergedSortArgs = null;
continue
}
if (String(_currentTask.name) !== "enumerate")
if (!_adapter[_currentTask.name] || _adapter[_currentTask.name].apply(_adapter, _currentTask.args) === false)
break
}
_taskQueue.shift()
}
unmergeSortTasks();
_adapter.exec(url).done(function(result, extra) {
if (!_taskQueue.length)
d.resolve(result, extra);
else {
var clientChain = queryImpl.array(result, {errorHandler: queryOptions.errorHandler});
$.each(_taskQueue, function() {
clientChain = clientChain[this.name].apply(clientChain, this.args)
});
clientChain.done(d.resolve).fail(d.reject)
}
}).fail(rejectWithNotify)
}
catch(x) {
rejectWithNotify(x)
}
return d.promise()
};
var query = {};
$.each(["sortBy", "thenBy", "filter", "slice", "select", "groupBy"], function() {
var name = String(this);
query[name] = function() {
return queryImpl.remote(url, queryOptions, tasks.concat(createTask(name, arguments)))
}
});
$.each(["count", "min", "max", "sum", "avg", "aggregate", "enumerate"], function() {
var name = String(this);
query[name] = function() {
return exec.call(this, createTask(name, arguments))
}
});
return query
}
})(jQuery, DevExpress);
/*! Module core, file data.odata.js */
(function($, DX, undefined) {
var data = DX.data,
utils = DX.utils,
Guid = data.Guid,
isDefined = utils.isDefined;
var DEFAULT_PROTOCOL_VERSION = 2;
var GUID_REGEX = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/;
var VERBOSE_DATE_REGEX = /^\/Date\((-?\d+)((\+|-)?(\d+)?)\)\/$/;
var ISO8601_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[-+]{1}\d{2}(:?)(\d{2})?)?$/;
var JSON_VERBOSE_MIME_TYPE = "application/json;odata=verbose";
function formatISO8601(date, skipZeroTime, skipTimezone) {
var ret = [];
var pad = function(n) {
if (n < 10)
return "0".concat(n);
return String(n)
};
var isZeroTime = function() {
return date.getHours() + date.getMinutes() + date.getSeconds() + date.getMilliseconds() < 1
};
ret.push(date.getFullYear());
ret.push("-");
ret.push(pad(date.getMonth() + 1));
ret.push("-");
ret.push(pad(date.getDate()));
if (!(skipZeroTime && isZeroTime())) {
ret.push("T");
ret.push(pad(date.getHours()));
ret.push(":");
ret.push(pad(date.getMinutes()));
ret.push(":");
ret.push(pad(date.getSeconds()));
if (date.getMilliseconds()) {
ret.push(".");
ret.push(date.getMilliseconds())
}
if (!skipTimezone)
ret.push("Z")
}
return ret.join("")
}
function parseISO8601(isoString) {
var result = new Date(0);
var chunks = isoString.replace("Z", "").split("T"),
date = /(\d{4})-(\d{2})-(\d{2})/.exec(chunks[0]),
time = /(\d{2}):(\d{2}):(\d{2})\.?(\d{0,7})?/.exec(chunks[1]);
result.setDate(Number(date[3]));
result.setMonth(Number(date[2]) - 1);
result.setFullYear(Number(date[1]));
if ($.isArray(time) && time.length) {
result.setHours(Number(time[1]));
result.setMinutes(Number(time[2]));
result.setSeconds(Number(time[3]));
result.setMilliseconds(Number(String(time[4]).substr(0, 3)) || 0)
}
return result
}
function isAbsoluteUrl(url) {
return /^(?:[a-z]+:)?\/\//i.test(url)
}
function toAbsoluteUrl(basePath, relativePath) {
var part,
baseParts = basePath.split("/"),
relativeParts = relativePath.split("/");
baseParts.pop();
while (relativeParts.length) {
part = relativeParts.shift();
if (part === "..")
baseParts.pop();
else
baseParts.push(part)
}
return baseParts.join("/")
}
var ajaxOptionsForRequest = function(protocolVersion, request, requestOptions) {
request = $.extend({
method: "get",
url: "",
params: {},
payload: null,
headers: {},
timeout: 30000
}, request);
requestOptions = requestOptions || {};
var beforeSend = requestOptions.beforeSend;
if (beforeSend)
beforeSend(request);
var method = (request.method || "get").toLowerCase(),
isGet = method === "get",
useJsonp = isGet && requestOptions.jsonp,
params = $.extend({}, request.params),
ajaxData = isGet ? params : formatPayload(request.payload),
qs = !isGet && $.param(params),
url = request.url,
contentType = !isGet && JSON_VERBOSE_MIME_TYPE;
if (qs)
url += (url.indexOf("?") > -1 ? "&" : "?") + qs;
if (useJsonp)
ajaxData["$format"] = "json";
return {
url: url,
data: ajaxData,
dataType: useJsonp ? "jsonp" : "json",
jsonp: useJsonp && "$callback",
type: method,
timeout: request.timeout,
headers: request.headers,
contentType: contentType,
accepts: {json: [JSON_VERBOSE_MIME_TYPE, "text/plain"].join()},
xhrFields: {withCredentials: requestOptions.withCredentials}
};
function formatPayload(payload) {
return JSON.stringify(payload, function(key, value) {
if (!(this[key] instanceof Date))
return value;
value = formatISO8601(this[key]);
switch (protocolVersion) {
case 2:
return value.substr(0, value.length - 1);
case 3:
case 4:
return value;
default:
throw DX.Error("E4002");
}
})
}
};
var sendRequest = function(protocolVersion, request, requestOptions) {
var d = $.Deferred();
var options = ajaxOptionsForRequest(protocolVersion, request, requestOptions);
$.ajax(options).always(function(obj, textStatus) {
var tuplet = interpretJsonFormat(obj, textStatus),
error = tuplet.error,
data = tuplet.data,
nextUrl = tuplet.nextUrl,
extra;
if (error)
d.reject(error);
else if (requestOptions.countOnly)
d.resolve(tuplet.count);
else if (nextUrl) {
if (!isAbsoluteUrl(nextUrl))
nextUrl = toAbsoluteUrl(options.url, nextUrl);
sendRequest(protocolVersion, {url: nextUrl}, requestOptions).fail(d.reject).done(function(nextData) {
d.resolve(data.concat(nextData))
})
}
else {
if (isFinite(tuplet.count))
extra = {totalCount: tuplet.count};
d.resolve(data, extra)
}
});
return d.promise()
};
var formatDotNetError = function(errorObj) {
var message,
currentError = errorObj;
if ("message" in errorObj)
if (errorObj.message.value)
message = errorObj.message.value;
else
message = errorObj.message;
while (currentError = currentError.innererror || currentError.internalexception) {
message = currentError.message;
if (currentError.internalexception && message.indexOf("inner exception") === -1)
break
}
return message
};
var errorFromResponse = function(obj, textStatus) {
if (textStatus === "nocontent")
return null;
var httpStatus = 200,
message = "Unknown error",
response = obj;
if (textStatus !== "success") {
httpStatus = obj.status;
message = data.utils.errorMessageFromXhr(obj, textStatus);
try {
response = $.parseJSON(obj.responseText)
}
catch(x) {}
}
var errorObj = response && (response.error || response["@odata.error"]);
if (errorObj) {
message = formatDotNetError(errorObj) || message;
if (httpStatus === 200)
httpStatus = 500;
if (errorObj.code)
httpStatus = Number(errorObj.code);
return $.extend(Error(message), {
httpStatus: httpStatus,
errorDetails: errorObj
})
}
else if (httpStatus !== 200)
return $.extend(Error(message), {httpStatus: httpStatus})
};
var interpretJsonFormat = function(obj, textStatus) {
var error = errorFromResponse(obj, textStatus),
value;
if (error)
return {error: error};
if (!$.isPlainObject(obj))
return {data: obj};
if ("d" in obj && (utils.isArray(obj.d) || utils.isObject(obj.d)))
value = interpretVerboseJsonFormat(obj, textStatus);
else
value = interpretLightJsonFormat(obj, textStatus);
transformTypes(value);
return value
};
var interpretVerboseJsonFormat = function(obj) {
var data = obj.d;
if (!isDefined(data))
return {error: Error("Malformed or unsupported JSON response received")};
data = data;
if (isDefined(data.results))
data = data.results;
return {
data: data,
nextUrl: obj.d.__next,
count: parseInt(obj.d.__count, 10)
}
};
var interpretLightJsonFormat = function(obj) {
var data = obj;
if (isDefined(data.value))
data = data.value;
return {
data: data,
nextUrl: obj["@odata.nextLink"],
count: parseInt(obj["@odata.count"], 10)
}
};
var EdmLiteral = DX.Class.inherit({
ctor: function(value) {
this._value = value
},
valueOf: function() {
return this._value
}
});
var transformTypes = function(obj) {
$.each(obj, function(key, value) {
if (value !== null && typeof value === "object") {
if ("results" in value)
obj[key] = value.results;
transformTypes(obj[key])
}
else if (typeof value === "string")
if (GUID_REGEX.test(value))
obj[key] = new Guid(value);
else if (value.match(VERBOSE_DATE_REGEX)) {
var date = new Date(Number(RegExp.$1) + RegExp.$2 * 60 * 1000);
obj[key] = new Date(date.valueOf() + date.getTimezoneOffset() * 60 * 1000)
}
else if (ISO8601_DATE_REGEX.test(value))
obj[key] = new Date(parseISO8601(obj[key]).valueOf())
})
};
var serializeDate = function(date) {
return "datetime'" + formatISO8601(date, true, true) + "'"
};
var serializeString = function(value) {
return "'" + value.replace(/'/g, "''") + "'"
};
var serializePropName = function(propName) {
if (propName instanceof EdmLiteral)
return propName.valueOf();
return propName.replace(/\./g, "/")
};
var serializeValueV4 = function(value) {
if (value instanceof Date)
return formatISO8601(value, false, false);
if (value instanceof Guid)
return value.valueOf();
return serializeValueV2(value)
};
var serializeValueV2 = function(value) {
if (value instanceof Date)
return serializeDate(value);
if (value instanceof Guid)
return "guid'" + value + "'";
if (value instanceof EdmLiteral)
return value.valueOf();
if (typeof value === "string")
return serializeString(value);
return String(value)
};
var serializeValue = function(value, protocolVersion) {
switch (protocolVersion) {
case 2:
case 3:
return serializeValueV2(value);
case 4:
return serializeValueV4(value);
default:
throw DX.Error("E4002");
}
};
var serializeKey = function(key, protocolVersion) {
if ($.isPlainObject(key)) {
var parts = [];
$.each(key, function(k, v) {
parts.push(serializePropName(k) + "=" + serializeValue(v, protocolVersion))
});
return parts.join()
}
return serializeValue(key, protocolVersion)
};
var keyConverters = {
String: function(value) {
return value + ""
},
Int32: function(value) {
return Math.floor(value)
},
Int64: function(value) {
if (value instanceof EdmLiteral)
return value;
return new EdmLiteral(value + "L")
},
Guid: function(value) {
if (value instanceof Guid)
return value;
return new Guid(value)
},
Boolean: function(value) {
return !!value
},
Single: function(value) {
if (value instanceof EdmLiteral)
return value;
return new EdmLiteral(value + "f")
},
Decimal: function(value) {
if (value instanceof EdmLiteral)
return value;
return new EdmLiteral(value + "m")
}
};
var compileCriteria = function() {
var createBinaryOperationFormatter = function(op) {
return function(prop, val, bag) {
bag.push(prop, " ", op, " ", val)
}
};
var createStringFuncFormatter = function(op, reverse) {
return function(prop, val, bag) {
if (reverse)
bag.push(op, "(", val, ",", prop, ")");
else
bag.push(op, "(", prop, ",", val, ")")
}
};
var formatters = {
"=": createBinaryOperationFormatter("eq"),
"<>": createBinaryOperationFormatter("ne"),
">": createBinaryOperationFormatter("gt"),
">=": createBinaryOperationFormatter("ge"),
"<": createBinaryOperationFormatter("lt"),
"<=": createBinaryOperationFormatter("le"),
startswith: createStringFuncFormatter("startswith"),
endswith: createStringFuncFormatter("endswith")
};
var formattersV2 = $.extend({}, formatters, {
contains: createStringFuncFormatter("substringof", true),
notcontains: createStringFuncFormatter("not substringof", true)
});
var formattersV4 = $.extend({}, formatters, {
contains: createStringFuncFormatter("contains"),
notcontains: createStringFuncFormatter("not contains")
});
var compileBinary = function(criteria, bag, protocolVersion) {
criteria = data.utils.normalizeBinaryCriterion(criteria);
var op = criteria[1],
formatters = protocolVersion === 4 ? formattersV4 : formattersV2,
formatter = formatters[op.toLowerCase()];
if (!formatter)
throw DX.Error("E4003", op);
formatter(serializePropName(criteria[0]), serializeValue(criteria[2], protocolVersion), bag)
};
var compileGroup = function(criteria, bag, protocolVersion) {
var pushAnd = false;
$.each(criteria, function() {
if ($.isArray(this)) {
if (pushAnd)
bag.push(" and ");
bag.push("(");
compileCore(this, bag, protocolVersion);
bag.push(")");
pushAnd = true
}
else {
bag.push(/and|&/i.test(this) ? " and " : " or ");
pushAnd = false
}
})
};
var compileCore = function(criteria, bag, protocolVersion) {
if ($.isArray(criteria[0]))
compileGroup(criteria, bag, protocolVersion);
else
compileBinary(criteria, bag, protocolVersion)
};
return function(criteria, protocolVersion) {
var bag = [];
compileCore(criteria, bag, protocolVersion);
return bag.join("")
}
}();
var createODataQueryAdapter = function(queryOptions) {
var _sorting = [],
_criteria = [],
_select,
_skip,
_take,
_countQuery;
var hasSlice = function() {
return _skip || _take !== undefined
};
var hasFunction = function(criterion) {
for (var i = 0; i < criterion.length; i++) {
if ($.isFunction(criterion[i]))
return true;
if ($.isArray(criterion[i]) && hasFunction(criterion[i]))
return true
}
return false
};
var generateExpand = function() {
var hash = {};
if (queryOptions.expand)
$.each($.makeArray(queryOptions.expand), function() {
hash[serializePropName(this)] = 1
});
if (_select)
$.each(_select, function() {
var path = this.split(".");
if (path.length < 2)
return;
path.pop();
hash[serializePropName(path.join("."))] = 1
});
return $.map(hash, function(k, v) {
return v
}).join() || undefined
};
var requestData = function() {
var result = {};
if (!_countQuery) {
if (_sorting.length)
result["$orderby"] = _sorting.join(",");
if (_skip)
result["$skip"] = _skip;
if (_take !== undefined)
result["$top"] = _take;
if (_select)
result["$select"] = serializePropName(_select.join());
result["$expand"] = generateExpand()
}
if (_criteria.length)
result["$filter"] = compileCriteria(_criteria.length < 2 ? _criteria[0] : _criteria, queryOptions.version);
if (_countQuery)
result["$top"] = 0;
if (queryOptions.requireTotalCount || _countQuery)
if (queryOptions.version !== 4)
result["$inlinecount"] = "allpages";
else
result["$count"] = "true";
return result
};
queryOptions.version = queryOptions.version || DEFAULT_PROTOCOL_VERSION;
return {
exec: function(url) {
return sendRequest(queryOptions.version, {
url: url,
params: $.extend(requestData(), queryOptions && queryOptions.params)
}, {
beforeSend: queryOptions.beforeSend,
jsonp: queryOptions.jsonp,
withCredentials: queryOptions.withCredentials,
countOnly: _countQuery
})
},
multiSort: function(args) {
var rules;
if (hasSlice())
return false;
for (var i = 0; i < args.length; i++) {
var getter = args[i][0],
desc = !!args[i][1],
rule;
if (typeof getter !== "string")
return false;
rule = serializePropName(getter);
if (desc)
rule += " desc";
rules = rules || [];
rules.push(rule)
}
_sorting = rules
},
slice: function(skipCount, takeCount) {
if (hasSlice())
return false;
_skip = skipCount;
_take = takeCount
},
filter: function(criterion) {
if (hasSlice() || $.isFunction(criterion))
return false;
if (!$.isArray(criterion))
criterion = $.makeArray(arguments);
if (hasFunction(criterion))
return false;
if (_criteria.length)
_criteria.push("and");
_criteria.push(criterion)
},
select: function(expr) {
if (_select || $.isFunction(expr))
return false;
if (!$.isArray(expr))
expr = $.makeArray(arguments);
_select = expr
},
count: function() {
_countQuery = true
}
}
};
$.extend(true, data, {
EdmLiteral: EdmLiteral,
utils: {odata: {
sendRequest: sendRequest,
serializePropName: serializePropName,
serializeValue: serializeValue,
serializeKey: serializeKey,
keyConverters: keyConverters
}},
queryAdapters: {odata: createODataQueryAdapter}
});
data.OData__internals = {interpretJsonFormat: interpretJsonFormat}
})(jQuery, DevExpress);
/*! Module core, file data.store.abstract.js */
(function($, DX, undefined) {
var Class = DX.Class,
abstract = DX.abstract,
data = DX.data,
normalizeSortingInfo = data.utils.normalizeSortingInfo;
var STORE_CALLBACK_NAMES = ["loading", "loaded", "modifying", "modified", "inserting", "inserted", "updating", "updated", "removing", "removed"];
function multiLevelGroup(query, groupInfo) {
query = query.groupBy(groupInfo[0].selector);
if (groupInfo.length > 1)
query = query.select(function(g) {
return $.extend({}, g, {items: multiLevelGroup(data.query(g.items), groupInfo.slice(1)).toArray()})
});
return query
}
data.utils.multiLevelGroup = multiLevelGroup;
function arrangeSortingInfo(groupInfo, sortInfo) {
var filteredGroup = [];
$.each(groupInfo, function(_, group) {
var collision = $.grep(sortInfo, function(sort) {
return group.selector === sort.selector
});
if (collision.length < 1)
filteredGroup.push(group)
});
return filteredGroup.concat(sortInfo)
}
data.utils.arrangeSortingInfo = arrangeSortingInfo;
data.Store = Class.inherit({
ctor: function(options) {
var that = this;
options = options || {};
$.each(STORE_CALLBACK_NAMES, function() {
var eventName = this;
var callbacks = that[eventName] = $.Callbacks();
var originalAdd = callbacks.add;
callbacks.add = function() {
DX.log("W0003", "Store", eventName, "14.2", "Use the '" + eventName + "' event instead");
return originalAdd.apply(eventName, arguments)
};
if (eventName in options)
callbacks.add(options[eventName]);
var propertyName = "on" + eventName.charAt(0).toUpperCase() + eventName.slice(1);
if (propertyName in options)
that.on(eventName, options[propertyName])
});
this._key = options.key;
this._errorHandler = options.errorHandler;
this._useDefaultSearch = true
},
_customLoadOptions: function() {
return null
},
key: function() {
return this._key
},
keyOf: function(obj) {
if (!this._keyGetter)
this._keyGetter = data.utils.compileGetter(this.key());
return this._keyGetter(obj)
},
_requireKey: function() {
if (!this.key())
throw DX.Error("E4005");
},
load: function(options) {
var that = this;
options = options || {};
this.fireEvent("loading", [options]);
this.loading.fire(options);
return this._loadImpl(options).done(function(result, extra) {
that.fireEvent("loaded", [result, options]);
that.loaded.fire(result, extra)
})
},
_loadImpl: function(options) {
var filter = options.filter,
sort = options.sort,
select = options.select,
group = options.group,
skip = options.skip,
take = options.take,
q = this.createQuery(options);
if (filter)
q = q.filter(filter);
if (group)
group = normalizeSortingInfo(group);
if (sort || group) {
sort = normalizeSortingInfo(sort || []);
if (group)
sort = arrangeSortingInfo(group, sort);
$.each(sort, function(index) {
q = q[index ? "thenBy" : "sortBy"](this.selector, this.desc)
})
}
if (select)
q = q.select(select);
if (group)
q = multiLevelGroup(q, group);
if (take || skip)
q = q.slice(skip || 0, take);
return q.enumerate()
},
createQuery: abstract,
totalCount: function(options) {
return this._addFailHandlers(this._totalCountImpl(options))
},
_totalCountImpl: function(options) {
options = options || {};
var q = this.createQuery(),
group = options.group,
filter = options.filter;
if (filter)
q = q.filter(filter);
if (group) {
group = normalizeSortingInfo(group);
q = multiLevelGroup(q, group)
}
return q.count()
},
byKey: function(key, extraOptions) {
return this._addFailHandlers(this._byKeyImpl(key, extraOptions))
},
_byKeyImpl: abstract,
insert: function(values) {
var that = this;
that.fireEvent("modifying");
that.fireEvent("inserting", [values]);
that.modifying.fire();
that.inserting.fire(values);
return that._addFailHandlers(that._insertImpl(values).done(function(callbackValues, callbackKey) {
that.fireEvent("inserted", [callbackValues, callbackKey]);
that.fireEvent("modified");
that.inserted.fire(callbackValues, callbackKey);
that.modified.fire()
}))
},
_insertImpl: abstract,
update: function(key, values) {
var that = this;
that.fireEvent("modifying");
that.fireEvent("updating", [key, values]);
that.modifying.fire();
that.updating.fire(key, values);
return that._addFailHandlers(that._updateImpl(key, values).done(function(callbackKey, callbackValues) {
that.fireEvent("updated", [callbackKey, callbackValues]);
that.fireEvent("modified");
that.updated.fire(callbackKey, callbackValues);
that.modified.fire()
}))
},
_updateImpl: abstract,
remove: function(key) {
var that = this;
that.fireEvent("modifying");
that.fireEvent("removing", [key]);
that.modifying.fire();
that.removing.fire(key);
return that._addFailHandlers(that._removeImpl(key).done(function(callbackKey) {
that.fireEvent("removed", [callbackKey]);
that.fireEvent("modified");
that.removed.fire(callbackKey);
that.modified.fire()
}))
},
_removeImpl: abstract,
_addFailHandlers: function(deferred) {
return deferred.fail(this._errorHandler, data._errorHandler)
}
}).include(DX.EventsMixin)
})(jQuery, DevExpress);
/*! Module core, file data.store.array.js */
(function($, DX, undefined) {
var data = DX.data,
Guid = data.Guid;
var trivialPromise = function() {
var d = $.Deferred();
return d.resolve.apply(d, arguments).promise()
};
var rejectedPromise = function() {
var d = $.Deferred();
return d.reject.apply(d, arguments).promise()
};
data.ArrayStore = data.Store.inherit({
ctor: function(options) {
if ($.isArray(options))
options = {data: options};
else
options = options || {};
this.callBase(options);
var initialArray = options.data;
if (initialArray && !$.isArray(initialArray))
throw DX.Error("E4006");
this._array = initialArray || []
},
createQuery: function() {
return data.query(this._array, {errorHandler: this._errorHandler})
},
_byKeyImpl: function(key) {
var index = this._indexByKey(key);
if (index === -1)
return rejectedPromise(DX.Error("E4009"));
return trivialPromise(this._array[index])
},
_insertImpl: function(values) {
var keyExpr = this.key(),
keyValue,
obj;
if ($.isPlainObject(values))
obj = $.extend({}, values);
else
obj = values;
if (keyExpr) {
keyValue = this.keyOf(obj);
if (keyValue === undefined || typeof keyValue === "object" && $.isEmptyObject(keyValue)) {
if ($.isArray(keyExpr))
throw DX.Error("E4007");
keyValue = obj[keyExpr] = String(new Guid)
}
else if (this._array[this._indexByKey(keyValue)] !== undefined)
return rejectedPromise(DX.Error("E4008"))
}
else
keyValue = obj;
this._array.push(obj);
return trivialPromise(values, keyValue)
},
_updateImpl: function(key, values) {
var target,
index;
if (this.key()) {
if (this.keyOf(values))
if (!data.utils.keysEqual(this.key(), key, this.keyOf(values)))
return rejectedPromise(DX.Error("E4017"));
index = this._indexByKey(key);
if (index < 0)
return rejectedPromise(DX.Error("E4009"));
target = this._array[index]
}
else
target = key;
DX.utils.deepExtendArraySafe(target, values);
return trivialPromise(key, values)
},
_removeImpl: function(key) {
var index = this._indexByKey(key);
if (index > -1)
this._array.splice(index, 1);
return trivialPromise(key)
},
_indexByKey: function(key) {
for (var i = 0, arrayLength = this._array.length; i < arrayLength; i++)
if (data.utils.keysEqual(this.key(), this.keyOf(this._array[i]), key))
return i;
return -1
},
clear: function() {
this._array = []
}
})
})(jQuery, DevExpress);
/*! Module core, file data.store.local.js */
(function($, DX, undefined) {
var Class = DX.Class,
abstract = DX.abstract,
data = DX.data;
var LocalStoreBackend = Class.inherit({
ctor: function(store, storeOptions) {
this._store = store;
this._dirty = false;
var immediate = this._immediate = storeOptions.immediate;
var flushInterval = Math.max(100, storeOptions.flushInterval || 10 * 1000);
if (!immediate) {
var saveProxy = $.proxy(this.save, this);
setInterval(saveProxy, flushInterval);
$(window).on("beforeunload", saveProxy);
if (window.cordova)
document.addEventListener("pause", saveProxy, false)
}
},
notifyChanged: function() {
this._dirty = true;
if (this._immediate)
this.save()
},
load: function() {
this._store._array = this._loadImpl();
this._dirty = false
},
save: function() {
if (!this._dirty)
return;
this._saveImpl(this._store._array);
this._dirty = false
},
_loadImpl: abstract,
_saveImpl: abstract
});
var DomLocalStoreBackend = LocalStoreBackend.inherit({
ctor: function(store, storeOptions) {
this.callBase(store, storeOptions);
var name = storeOptions.name;
if (!name)
throw DX.Error("E4013");
this._key = "dx-data-localStore-" + name
},
_loadImpl: function() {
var raw = localStorage.getItem(this._key);
if (raw)
return JSON.parse(raw);
return []
},
_saveImpl: function(array) {
if (!array.length)
localStorage.removeItem(this._key);
else
localStorage.setItem(this._key, JSON.stringify(array))
}
});
var localStoreBackends = {dom: DomLocalStoreBackend};
data.LocalStore = data.ArrayStore.inherit({
ctor: function(options) {
if (typeof options === "string")
options = {name: options};
else
options = options || {};
this.callBase(options);
this._backend = new localStoreBackends[options.backend || "dom"](this, options);
this._backend.load()
},
clear: function() {
this.callBase();
this._backend.notifyChanged()
},
_insertImpl: function(values) {
var b = this._backend;
return this.callBase(values).done($.proxy(b.notifyChanged, b))
},
_updateImpl: function(key, values) {
var b = this._backend;
return this.callBase(key, values).done($.proxy(b.notifyChanged, b))
},
_removeImpl: function(key) {
var b = this._backend;
return this.callBase(key).done($.proxy(b.notifyChanged, b))
}
})
})(jQuery, DevExpress);
/*! Module core, file data.store.odata.js */
(function($, DX, undefined) {
var Class = DX.Class,
data = DX.data,
utils = DX.utils,
odataUtils = data.utils.odata;
var DEFAULT_PROTOCOL_VERSION = 2;
var formatFunctionInvocationUrl = function(baseUrl, args) {
return DX.stringFormat("{0}({1})", baseUrl, $.map(args || {}, function(value, key) {
return DX.stringFormat("{0}={1}", key, value)
}).join(","))
};
var escapeServiceOperationParams = function(params, version) {
if (!params)
return params;
var result = {};
$.each(params, function(k, v) {
result[k] = odataUtils.serializeValue(v, version)
});
return result
};
var convertSimpleKey = function(keyType, keyValue) {
var converter = odataUtils.keyConverters[keyType];
if (!converter)
throw DX.Error("E4014", keyType);
return converter(keyValue)
};
var SharedMethods = {
_extractServiceOptions: function(options) {
options = options || {};
this._url = String(options.url).replace(/\/+$/, "");
this._beforeSend = options.beforeSend;
this._jsonp = options.jsonp;
this._version = options.version || DEFAULT_PROTOCOL_VERSION;
this._withCredentials = options.withCredentials
},
_sendRequest: function(url, method, params, payload) {
return odataUtils.sendRequest(this.version(), {
url: url,
method: method,
params: params || {},
payload: payload
}, {
beforeSend: this._beforeSend,
jsonp: this._jsonp,
withCredentials: this._withCredentials
})
},
version: function() {
return this._version
}
};
var ODataStore = data.Store.inherit({
ctor: function(options) {
this.callBase(options);
this._extractServiceOptions(options);
this._keyType = options.keyType;
if (this.version() === 2)
this._updateMethod = "MERGE";
else
this._updateMethod = "PATCH"
},
_customLoadOptions: function() {
return ["expand", "customQueryParams"]
},
_byKeyImpl: function(key, extraOptions) {
var params = {};
if (extraOptions)
if (extraOptions.expand)
params["$expand"] = $.map($.makeArray(extraOptions.expand), odataUtils.serializePropName).join();
return this._sendRequest(this._byKeyUrl(key), "GET", params)
},
createQuery: function(loadOptions) {
var url,
queryOptions;
loadOptions = loadOptions || {};
queryOptions = {
beforeSend: this._beforeSend,
errorHandler: this._errorHandler,
jsonp: this._jsonp,
version: this._version,
withCredentials: this._withCredentials,
expand: loadOptions.expand,
requireTotalCount: loadOptions.requireTotalCount
};
if (utils.isDefined(loadOptions.urlOverride))
url = loadOptions.urlOverride;
else
url = this._url;
if ("customQueryParams" in loadOptions) {
var params = escapeServiceOperationParams(loadOptions.customQueryParams, this.version());
if (this.version() === 4)
url = formatFunctionInvocationUrl(url, params);
else
queryOptions.params = params
}
return data.query(url, queryOptions)
},
_insertImpl: function(values) {
this._requireKey();
var that = this,
d = $.Deferred();
$.when(this._sendRequest(this._url, "POST", null, values)).done(function(serverResponse) {
d.resolve(values, that.keyOf(serverResponse))
}).fail(d.reject);
return d.promise()
},
_updateImpl: function(key, values) {
var d = $.Deferred();
$.when(this._sendRequest(this._byKeyUrl(key), this._updateMethod, null, values)).done(function() {
d.resolve(key, values)
}).fail(d.reject, d);
return d.promise()
},
_removeImpl: function(key) {
var d = $.Deferred();
$.when(this._sendRequest(this._byKeyUrl(key), "DELETE")).done(function() {
d.resolve(key)
}).fail(d.reject, d);
return d.promise()
},
_byKeyUrl: function(key, useOriginalHost) {
var keyObj = key,
keyType = this._keyType,
baseUrl = useOriginalHost ? DX._proxyUrlFormatter.formatLocalUrl(this._url) : this._url;
if ($.isPlainObject(keyType)) {
keyObj = {};
$.each(keyType, function(subKeyName, subKeyType) {
keyObj[subKeyName] = convertSimpleKey(subKeyType, key[subKeyName])
})
}
else if (keyType)
keyObj = convertSimpleKey(keyType, key);
return baseUrl + "(" + encodeURIComponent(odataUtils.serializeKey(keyObj, this._version)) + ")"
}
}).include(SharedMethods);
var ODataContext = Class.inherit({
ctor: function(options) {
var that = this;
that._extractServiceOptions(options);
that._errorHandler = options.errorHandler;
$.each(options.entities || [], function(entityAlias, entityOptions) {
that[entityAlias] = new ODataStore($.extend({}, options, {url: that._url + "/" + encodeURIComponent(entityOptions.name || entityAlias)}, entityOptions))
})
},
get: function(operationName, params) {
return this.invoke(operationName, params, "GET")
},
invoke: function(operationName, params, httpMethod) {
params = params || {};
httpMethod = (httpMethod || "POST").toLowerCase();
var d = $.Deferred(),
url = this._url + "/" + encodeURIComponent(operationName),
payload;
if (this.version() === 4)
if (httpMethod === "get") {
url = formatFunctionInvocationUrl(url, escapeServiceOperationParams(params, this.version()));
params = null
}
else if (httpMethod === "post") {
payload = params;
params = null
}
$.when(this._sendRequest(url, httpMethod, escapeServiceOperationParams(params, this.version()), payload)).done(function(r) {
if ($.isPlainObject(r) && operationName in r)
r = r[operationName];
d.resolve(r)
}).fail([this._errorHandler, data._errorHandler, d.reject]);
return d.promise()
},
objectLink: function(entityAlias, key) {
var store = this[entityAlias];
if (!store)
throw DX.Error("E4015", entityAlias);
if (!utils.isDefined(key))
return null;
return {__metadata: {uri: store._byKeyUrl(key, true)}}
}
}).include(SharedMethods);
$.extend(data, {
ODataStore: ODataStore,
ODataContext: ODataContext
})
})(jQuery, DevExpress);
/*! Module core, file data.store.custom.js */
(function($, DX, undefined) {
var data = DX.data;
var TOTAL_COUNT = "totalCount",
LOAD = "load",
BY_KEY = "byKey",
INSERT = "insert",
UPDATE = "update",
REMOVE = "remove";
function isPromise(obj) {
return obj && $.isFunction(obj.then)
}
function trivialPromise(value) {
return $.Deferred().resolve(value).promise()
}
function ensureRequiredFuncOption(name, obj) {
if (!$.isFunction(obj))
throw DX.Error("E4011", name);
}
function throwInvalidUserFuncResult(name) {
throw DX.Error("E4012", name);
}
function createUserFuncFailureHandler(pendingDeferred) {
function errorMessageFromXhr(promiseArguments) {
var xhr = promiseArguments[0],
textStatus = promiseArguments[1];
if (!xhr || !xhr.getResponseHeader)
return null;
return data.utils.errorMessageFromXhr(xhr, textStatus)
}
return function(arg) {
var error;
if (arg instanceof Error)
error = arg;
else
error = new Error(errorMessageFromXhr(arguments) || arg && String(arg) || "Unknown error");
pendingDeferred.reject(error)
}
}
data.CustomStore = data.Store.inherit({
ctor: function(options) {
options = options || {};
this.callBase(options);
this._useDefaultSearch = false;
this._loadFunc = options[LOAD];
this._totalCountFunc = options[TOTAL_COUNT];
this._byKeyFunc = options[BY_KEY];
this._insertFunc = options[INSERT];
this._updateFunc = options[UPDATE];
this._removeFunc = options[REMOVE]
},
createQuery: function() {
throw DX.Error("E4010");
},
_totalCountImpl: function(options) {
var userFunc = this._totalCountFunc,
userResult,
d = $.Deferred();
ensureRequiredFuncOption(TOTAL_COUNT, userFunc);
userResult = userFunc(options);
if (!isPromise(userResult)) {
userResult = Number(userResult);
if (!isFinite(userResult))
throwInvalidUserFuncResult(TOTAL_COUNT);
userResult = trivialPromise(userResult)
}
userResult.then(function(count) {
d.resolve(Number(count))
}, createUserFuncFailureHandler(d));
return d.promise()
},
_loadImpl: function(options) {
var userFunc = this._loadFunc,
userResult,
d = $.Deferred();
ensureRequiredFuncOption(LOAD, userFunc);
userResult = userFunc(options);
if ($.isArray(userResult))
userResult = trivialPromise(userResult);
else if (userResult === null || userResult === undefined)
userResult = trivialPromise([]);
else if (!isPromise(userResult))
throwInvalidUserFuncResult(LOAD);
userResult.then(function(data, extra) {
d.resolve(data, extra)
}, createUserFuncFailureHandler(d));
return this._addFailHandlers(d.promise())
},
_byKeyImpl: function(key, extraOptions) {
var userFunc = this._byKeyFunc,
userResult,
d = $.Deferred();
ensureRequiredFuncOption(BY_KEY, userFunc);
userResult = userFunc(key, extraOptions);
if (!isPromise(userResult))
userResult = trivialPromise(userResult);
userResult.then(function(obj) {
d.resolve(obj)
}, createUserFuncFailureHandler(d));
return d.promise()
},
_insertImpl: function(values) {
var userFunc = this._insertFunc,
userResult,
d = $.Deferred();
ensureRequiredFuncOption(INSERT, userFunc);
userResult = userFunc(values);
if (!isPromise(userResult))
userResult = trivialPromise(userResult);
userResult.then(function(newKey) {
d.resolve(values, newKey)
}, createUserFuncFailureHandler(d));
return d.promise()
},
_updateImpl: function(key, values) {
var userFunc = this._updateFunc,
userResult,
d = $.Deferred();
ensureRequiredFuncOption(UPDATE, userFunc);
userResult = userFunc(key, values);
if (!isPromise(userResult))
userResult = trivialPromise();
userResult.then(function() {
d.resolve(key, values)
}, createUserFuncFailureHandler(d));
return d.promise()
},
_removeImpl: function(key) {
var userFunc = this._removeFunc,
userResult,
d = $.Deferred();
ensureRequiredFuncOption(REMOVE, userFunc);
userResult = userFunc(key);
if (!isPromise(userResult))
userResult = trivialPromise();
userResult.then(function() {
d.resolve(key)
}, createUserFuncFailureHandler(d));
return d.promise()
}
})
})(jQuery, DevExpress);
/*! Module core, file data.dataSource.js */
(function($, DX, undefined) {
var data = DX.data,
CustomStore = data.CustomStore,
Class = DX.Class;
var storeTypeRegistry = {
jaydata: "JayDataStore",
breeze: "BreezeStore",
odata: "ODataStore",
local: "LocalStore",
array: "ArrayStore"
};
var nextLoadOperationId = function() {
var id = -1;
return function() {
return ++id
}
}();
var canceledOperationsRegistry = function() {
var registry = {};
return {
add: function(operationId) {
registry[operationId] = true
},
has: function(operationId) {
return operationId in registry
},
remove: function(operationId) {
delete registry[operationId]
}
}
}();
var ensureIsNotRejected = function(loadOperationId, pendingDeferred) {
if (canceledOperationsRegistry.has(loadOperationId)) {
canceledOperationsRegistry.remove(loadOperationId);
pendingDeferred.reject("canceled");
return false
}
return true
};
function normalizeDataSourceOptions(options) {
var store;
function createCustomStoreFromLoadFunc() {
var storeConfig = {};
$.each(["key", "load", "byKey", "lookup", "totalCount", "insert", "update", "remove"], function() {
storeConfig[this] = options[this];
delete options[this]
});
return new CustomStore(storeConfig)
}
function createStoreFromConfig(storeConfig) {
var storeCtor = data[storeTypeRegistry[storeConfig.type]];
delete storeConfig.type;
return new storeCtor(storeConfig)
}
function createCustomStoreFromUrl(url) {
return new CustomStore({load: function() {
return $.getJSON(url)
}})
}
if (typeof options === "string")
options = createCustomStoreFromUrl(options);
if (options === undefined)
options = [];
if ($.isArray(options) || options instanceof data.Store)
options = {store: options};
else
options = $.extend({}, options);
if (options.store === undefined)
options.store = [];
store = options.store;
if ("load" in options)
store = createCustomStoreFromLoadFunc();
else if ($.isArray(store))
store = new data.ArrayStore(store);
else if ($.isPlainObject(store))
store = createStoreFromConfig($.extend({}, store));
options.store = store;
return options
}
function normalizeStoreLoadOptionAccessorArguments(originalArguments) {
switch (originalArguments.length) {
case 0:
return undefined;
case 1:
return originalArguments[0]
}
return $.makeArray(originalArguments)
}
function generateStoreLoadOptionAccessor(optionName) {
return function() {
var args = normalizeStoreLoadOptionAccessorArguments(arguments);
if (args !== undefined)
this._storeLoadOptions[optionName] = args;
return this._storeLoadOptions[optionName]
}
}
function mapDataRespectingGrouping(items, mapper, groupInfo) {
function mapRecursive(items, level) {
if (!DX.utils.isArray(items))
return items;
return level ? mapGroup(items, level) : $.map(items, mapper)
}
function mapGroup(group, level) {
return $.map(group, function(item) {
var result = {
key: item.key,
items: mapRecursive(item.items, level - 1)
};
if ("aggregates" in item)
result.aggregates = item.aggregates;
return result
})
}
return mapRecursive(items, groupInfo ? data.utils.normalizeSortingInfo(groupInfo).length : 0)
}
var DataSource = Class.inherit({
ctor: function(options) {
options = normalizeDataSourceOptions(options);
this._store = options.store;
this._storeLoadOptions = this._extractLoadOptions(options);
this._mapFunc = options.map;
this._postProcessFunc = options.postProcess;
this._pageIndex = options.pageIndex !== undefined ? options.pageIndex : 0;
this._pageSize = options.pageSize !== undefined ? options.pageSize : 20;
this._items = [];
this._totalCount = -1;
this._isLoaded = false;
this._loadingCount = 0;
this._loadQueue = this._createLoadQueue();
this._searchValue = "searchValue" in options ? options.searchValue : null;
this._searchOperation = options.searchOperation || "contains";
this._searchExpr = options.searchExpr;
this._paginate = options.paginate;
if (this._paginate === undefined)
this._paginate = !this.group();
this._isLastPage = !this._paginate;
this._userData = {};
$.each(["changed", "loadError", "loadingChanged"], $.proxy(function(_, eventName) {
var callbacks = this[eventName] = $.Callbacks();
var originalAdd = callbacks.add;
callbacks.add = function() {
DX.log("W0003", "DataSource", eventName, "14.2", "Use the '" + eventName + "' event instead");
return originalAdd.apply(eventName, arguments)
}
}, this));
$.each(["changed", "loadError", "loadingChanged", "customizeLoadResult", "customizeStoreLoadOptions"], $.proxy(function(_, eventName) {
var optionName = "on" + eventName[0].toUpperCase() + eventName.slice(1);
if (options.hasOwnProperty(optionName))
this.on(eventName, options[optionName])
}, this))
},
dispose: function() {
this.changed.empty();
this.loadError.empty();
this.loadingChanged.empty();
this._disposeEvents();
delete this._store;
if (this._delayedLoadTask)
this._delayedLoadTask.abort();
this._disposed = true
},
_extractLoadOptions: function(options) {
var result = {},
names = ["sort", "filter", "select", "group", "requireTotalCount"],
customNames = this._store._customLoadOptions();
if (customNames)
names = names.concat(customNames);
$.each(names, function() {
result[this] = options[this]
});
return result
},
loadOptions: function() {
return this._storeLoadOptions
},
items: function() {
return this._items
},
pageIndex: function(newIndex) {
if (newIndex !== undefined) {
this._pageIndex = newIndex;
this._isLastPage = !this._paginate
}
return this._pageIndex
},
paginate: function(value) {
if (arguments.length < 1)
return this._paginate;
value = !!value;
if (this._paginate !== value) {
this._paginate = value;
this.pageIndex(0)
}
},
pageSize: function(value) {
if (arguments.length < 1)
return this._pageSize;
this._pageSize = value
},
isLastPage: function() {
return this._isLastPage
},
sort: generateStoreLoadOptionAccessor("sort"),
filter: function() {
var newFilter = normalizeStoreLoadOptionAccessorArguments(arguments);
if (newFilter !== undefined) {
this._storeLoadOptions.filter = newFilter;
this.pageIndex(0)
}
return this._storeLoadOptions.filter
},
group: generateStoreLoadOptionAccessor("group"),
select: generateStoreLoadOptionAccessor("select"),
requireTotalCount: generateStoreLoadOptionAccessor("requireTotalCount"),
searchValue: function(value) {
if (value !== undefined) {
this.pageIndex(0);
this._searchValue = value
}
return this._searchValue
},
searchOperation: function(op) {
if (op !== undefined) {
this.pageIndex(0);
this._searchOperation = op
}
return this._searchOperation
},
searchExpr: function(expr) {
var argc = arguments.length;
if (argc) {
if (argc > 1)
expr = $.makeArray(arguments);
this.pageIndex(0);
this._searchExpr = expr
}
return this._searchExpr
},
store: function() {
return this._store
},
key: function() {
return this._store && this._store.key()
},
totalCount: function() {
return this._totalCount
},
isLoaded: function() {
return this._isLoaded
},
isLoading: function() {
return this._loadingCount > 0
},
_createLoadQueue: function() {
return DX.createQueue()
},
_changeLoadingCount: function(increment) {
var oldLoading = this.isLoading(),
newLoading;
this._loadingCount += increment;
newLoading = this.isLoading();
if (oldLoading ^ newLoading) {
this.fireEvent("loadingChanged", [newLoading]);
this.loadingChanged.fire(newLoading)
}
},
_scheduleLoadCallbacks: function(deferred) {
var that = this;
that._changeLoadingCount(1);
deferred.always(function() {
that._changeLoadingCount(-1)
})
},
_scheduleChangedCallbacks: function(deferred) {
var that = this;
deferred.done(function() {
that.fireEvent("changed");
that.changed.fire()
})
},
loadSingle: function(propName, propValue) {
var that = this;
var d = $.Deferred().fail(function() {
that.fireEvent("loadError", arguments);
that.loadError.fire.apply(that, arguments)
}),
key = this.key(),
store = this._store,
loadOptions = this._createStoreLoadOptions();
function handleSuccess(data) {
if (data === null || typeof data === "undefined" || $.isArray(data) && data.length < 1)
d.reject();
else
d.resolve(that._transformLoadedData(data)[0])
}
if (arguments.length < 2) {
propValue = propName;
propName = key
}
delete loadOptions.skip;
delete loadOptions.group;
delete loadOptions.refresh;
delete loadOptions.pageIndex;
delete loadOptions.searchString;
if (propName === key || store instanceof data.CustomStore)
store.byKey(propValue, loadOptions).done(handleSuccess).fail(d.reject);
else {
loadOptions.take = 1;
loadOptions.filter = loadOptions.filter ? [loadOptions.filter, [propName, propValue]] : [propName, propValue];
store.load(loadOptions).done(handleSuccess).fail(d.reject)
}
return d.promise()
},
load: function() {
var that = this,
d = $.Deferred(),
loadOptions;
this._scheduleLoadCallbacks(d);
this._scheduleChangedCallbacks(d);
loadOptions = this._createLoadOptions();
this.fireEvent("customizeStoreLoadOptions", [loadOptions]);
if (!ensureIsNotRejected(loadOptions.operationId, d))
return d.promise();
function errorCallback() {
if (arguments[0] !== "canceled") {
that.fireEvent("loadError", arguments);
that.loadError.fire.apply(that.loadError, arguments)
}
}
function loadTask() {
if (that._disposed)
return undefined;
return that._loadFromStore(loadOptions, d)
}
this._loadQueue.add(function() {
if (typeof loadOptions.delay === "number")
that._delayedLoadTask = DX.utils.executeAsync(loadTask, loadOptions.delay);
else
loadTask();
return d.promise()
});
return d.promise({loadOperationId: loadOptions.operationId}).fail(errorCallback)
},
reload: function() {
var prop,
userData = this._userData;
for (prop in userData)
if (userData.hasOwnProperty(prop))
delete userData[prop];
this._totalCount = -1;
this._isLoaded = false;
return this.load()
},
cancel: function(loadOperationId) {
canceledOperationsRegistry.add(loadOperationId)
},
_addSearchOptions: function(storeLoadOptions) {
if (this._disposed)
return;
if (this.store()._useDefaultSearch)
this._addSearchFilter(storeLoadOptions);
else {
storeLoadOptions.searchOperation = this._searchOperation;
storeLoadOptions.searchValue = this._searchValue;
storeLoadOptions.searchExpr = this._searchExpr
}
},
_createStoreLoadOptions: function() {
var result = $.extend({}, this._storeLoadOptions);
this._addSearchOptions(result);
if (this._paginate)
if (this._pageSize) {
result.skip = this._pageIndex * this._pageSize;
result.take = this._pageSize
}
result.userData = this._userData;
return result
},
_createLoadOptions: function() {
return {
operationId: nextLoadOperationId(),
storeLoadOptions: this._createStoreLoadOptions()
}
},
_addSearchFilter: function(storeLoadOptions) {
var value = this._searchValue,
op = this._searchOperation,
selector = this._searchExpr,
searchFilter = [];
if (!value)
return;
if (!selector)
selector = "this";
if (!$.isArray(selector))
selector = [selector];
$.each(selector, function(i, item) {
if (searchFilter.length)
searchFilter.push("or");
searchFilter.push([item, op, value])
});
if (storeLoadOptions.filter)
storeLoadOptions.filter = [searchFilter, storeLoadOptions.filter];
else
storeLoadOptions.filter = searchFilter
},
_loadFromStore: function(loadOptions, pendingDeferred) {
var that = this;
function handleSuccess(data, extra) {
function processResult() {
var loadResult;
loadResult = $.extend({
data: data,
extra: extra
}, loadOptions);
that.fireEvent("customizeLoadResult", [loadResult]);
if (ensureIsNotRejected(loadOptions.operationId, pendingDeferred))
that._processStoreLoadResult(loadResult, pendingDeferred)
}
if (that._disposed)
return;
processResult()
}
if (!ensureIsNotRejected(loadOptions.operationId, pendingDeferred))
return pendingDeferred.promise();
return this.store().load(loadOptions.storeLoadOptions).done(handleSuccess).fail(pendingDeferred.reject)
},
_processStoreLoadResult: function(loadResult, pendingDeferred) {
var that = this;
var data = loadResult.data,
extra = loadResult.extra,
storeLoadOptions = loadResult.storeLoadOptions;
function resolvePendingDeferred() {
if (!ensureIsNotRejected(loadResult.operationId, pendingDeferred))
return pendingDeferred;
that._isLoaded = true;
that._totalCount = isFinite(extra.totalCount) ? extra.totalCount : -1;
return pendingDeferred.resolve(data, extra)
}
function proceedLoadingTotalCount() {
that.store().totalCount(storeLoadOptions).done(function(count) {
extra.totalCount = count;
resolvePendingDeferred()
}).fail(function(){})
}
if (that._disposed)
return;
data = that._transformLoadedData(data);
if (!$.isPlainObject(extra))
extra = {};
that._items = data;
if (!data.length || !that._paginate || that._pageSize && data.length < that._pageSize)
that._isLastPage = true;
if (storeLoadOptions.requireTotalCount && !isFinite(extra.totalCount))
proceedLoadingTotalCount();
else
resolvePendingDeferred()
},
_transformLoadedData: function(data) {
var result = $.makeArray(data);
if (this._mapFunc)
result = mapDataRespectingGrouping(result, this._mapFunc, this.group());
if (this._postProcessFunc)
result = this._postProcessFunc(result);
return result
}
}).include(DX.EventsMixin);
$.extend(true, data, {
DataSource: DataSource,
utils: {
storeTypeRegistry: storeTypeRegistry,
normalizeDataSourceOptions: normalizeDataSourceOptions
}
})
})(jQuery, DevExpress);
/*! Module core, file ko.js */
(function($, DX) {
if (DX.support.hasKo && DX.compareVersions(ko.version, [2, 3]) < 0)
throw DX.Error("E0013");
})(jQuery, DevExpress);
/*! Module core, file ng.js */
(function($, DX, undefined) {
if (!DX.support.hasNg)
return;
DX.ng = {module: window.angular.module("dx", ["ngSanitize"])}
})(jQuery, DevExpress);
/*! Module core, file component.js */
(function($, DX, undefined) {
var utils = DX.utils,
dataUtils = DX.data.utils,
inflector = DX.inflector;
var Component = DX.Class.inherit({
NAME: "Component",
_setDeprecatedOptions: function() {
this._deprecatedOptions = {}
},
_getDeprecatedOptions: function() {
return this._deprecatedOptions
},
_setOptionAliases: function() {
var aliases = this._optionAliases = {};
$.each(this._getDeprecatedOptions(), function(optionName, info) {
var optionAlias = info.alias;
if (optionAlias)
aliases[optionName] = optionAlias
})
},
_getOptionAliases: function() {
return this._optionAliases
},
_getOptionAliasesByName: function(optionName) {
return $.map(this._getOptionAliases(), function(aliasedOption, aliasName) {
return optionName === aliasedOption ? aliasName : undefined
})
},
_setDefaultOptions: function() {
this.option({
onInitialized: null,
onOptionChanged: null,
onDisposing: null,
defaultOptionsRules: null
})
},
_defaultOptionsRules: function() {
return []
},
_setOptionsByDevice: function(userRules) {
var rules = this._defaultOptionsRules();
if (this._customRules)
rules = rules.concat(this._customRules);
if ($.isArray(userRules))
rules = rules.concat(userRules);
this.option(this._convertRulesToOptions(rules))
},
_convertRulesToOptions: function(rules) {
var options = {};
var currentDevice = DX.devices.current();
var deviceMatch = function(device, filter) {
filter = $.makeArray(filter);
return filter.length === 1 && $.isEmptyObject(filter[0]) || utils.findBestMatches(device, filter).length > 0
};
$.each(rules, function(index, rule) {
var deviceFilter = rule.device || {},
match;
if ($.isFunction(deviceFilter))
match = deviceFilter(currentDevice);
else
match = deviceMatch(currentDevice, deviceFilter);
if (match)
$.extend(options, rule.options)
});
return options
},
_isInitialOptionValue: function(name) {
var isCustomOption = this._customRules && this._convertRulesToOptions(this._customRules).hasOwnProperty(name);
var isInitialOption = this.option(name) === this._initialOptions[name];
return !isCustomOption && isInitialOption
},
_setOptionsByReference: function() {
this._optionsByReference = {}
},
_getOptionsByReference: function() {
return this._optionsByReference
},
ctor: function(options) {
if (!this.NAME)
throw DX.Error("E0004");
options = options || {};
this._options = {};
this._cachedGetters = {};
this._updateLockCount = 0;
this._optionChangedCallbacks = options._optionChangedCallbacks || $.Callbacks();
this._disposingCallbacks = options._disposingCallbacks || $.Callbacks();
this.optionChanged = $.Callbacks();
this.disposing = $.Callbacks();
$.each(["optionChanged", "disposing"], $.proxy(function(_, propertyName) {
var that = this,
originalAdd = this[propertyName].add;
this[propertyName].add = function() {
DX.log("W0003", that.NAME, propertyName, "14.2", "Use the '" + propertyName + "' event instead");
return originalAdd.apply(this, arguments)
}
}, this));
this.beginUpdate();
try {
this._suppressDeprecatedWarnings();
this._setOptionsByReference();
this._setDeprecatedOptions();
this._setOptionAliases();
this._setDefaultOptions();
this._setOptionsByDevice(options.defaultOptionsRules);
this._resumeDeprecatedWarnings();
this._initialOptions = $.extend({}, this.option());
this._initOptions(options)
}
finally {
this.endUpdate()
}
},
_initOptions: function(options) {
this.option(options)
},
_optionValuesEqual: function(name, oldValue, newValue) {
oldValue = dataUtils.toComparable(oldValue, true);
newValue = dataUtils.toComparable(newValue, true);
if (oldValue && newValue && oldValue.jquery && newValue.jquery)
return newValue.is(oldValue);
var oldValueIsNaN = oldValue !== oldValue,
newValueIsNaN = newValue !== newValue;
if (oldValueIsNaN && newValueIsNaN)
return true;
if (oldValue === null || typeof oldValue !== "object")
return oldValue === newValue;
return false
},
_init: function() {
this._createOptionChangedAction();
this._createDisposingAction();
this.on("optionChanged", function(args) {
this._optionChangedCallbacks.fireWith(this, [args])
});
this.on("disposing", function(args) {
this._disposingCallbacks.fireWith(this, [args])
})
},
_createOptionChangedAction: function() {
this._optionChangedAction = this._createActionByOption("onOptionChanged", {excludeValidators: ["disabled", "readOnly"]})
},
_createDisposingAction: function() {
this._disposingAction = this._createActionByOption("onDisposing", {excludeValidators: ["disabled", "readOnly"]})
},
_optionChanged: function(args) {
switch (args.name) {
case"onInitialized":
break;
case"onOptionChanged":
this._createOptionChangedAction();
break;
case"onDisposing":
this._createDisposingAction();
break;
case"defaultOptionsRules":
break
}
},
_dispose: function() {
this.optionChanged.empty();
this.disposing.fireWith(this).empty();
this._disposingAction();
this._disposeEvents();
this._disposed = true
},
instance: function() {
return this
},
beginUpdate: function() {
this._updateLockCount++
},
endUpdate: function() {
this._updateLockCount--;
if (!this._updateLockCount)
if (!this._initializing && !this._initialized) {
this._initializing = true;
try {
this._init()
}
finally {
this._initializing = false;
this._initialized = true;
this._createActionByOption("onInitialized")()
}
}
},
_logWarningIfDeprecated: function(option) {
var info = this._getDeprecatedOptions()[option];
if (info && !this._deprecatedOptionsSuppressed)
this._logDeprecatedWarning(option, info)
},
_logDeprecatedWarningCount: 0,
_logDeprecatedWarning: function(option, info) {
var message = info.message || "Use the '" + info.alias + "' option instead";
DX.log("W0001", this.NAME, option, info.since, message);
++this._logDeprecatedWarningCount
},
_suppressDeprecatedWarnings: function() {
this._deprecatedOptionsSuppressed = true
},
_resumeDeprecatedWarnings: function() {
this._deprecatedOptionsSuppressed = false
},
_notifyOptionChanged: function(option, value, previousValue) {
var that = this;
if (this._initialized)
$.each(that._getOptionAliasesByName(option).concat([option]), function(index, name) {
var args = {
name: name.split(/[.\[]/)[0],
fullName: name,
value: value,
previousValue: previousValue
};
that.optionChanged.fireWith(that, [args.name, value, previousValue]);
that._optionChangedAction($.extend({}, args));
if (!that._disposed)
that._optionChanged(args)
})
},
initialOption: function(optionName) {
var options = this._initialOptions;
return options[optionName]
},
_defaultActionConfig: function() {
return {
context: this,
component: this
}
},
_defaultActionArgs: function() {
return {component: this}
},
_createAction: function(actionSource, config) {
var that = this,
action = new DX.Action(actionSource, $.extend(config, that._defaultActionConfig()));
return function(e) {
if (!arguments.length)
e = {};
if (e instanceof $.Event)
throw Error("Action must be executed with jQuery.Event like action({ jQueryEvent: event })");
if (!$.isPlainObject(e))
e = {actionValue: e};
return action.execute.call(action, $.extend(e, that._defaultActionArgs()))
}
},
_createActionByOption: function(optionName, config) {
config = config || {};
if (typeof optionName !== "string")
throw DX.Error("E0008");
var matches = /^on(\w+)/.exec(optionName);
if (matches) {
var eventName = inflector.camelize(matches[1]),
afterExecute = config.afterExecute || $.noop,
that = this;
config.afterExecute = function(args) {
that.fireEvent(eventName, args.args);
return afterExecute.apply(this, arguments)
}
}
else {
var optionAlias = this._getOptionAliasesByName(optionName),
isOptionDeprecated = Boolean(this._getDeprecatedOptions()[optionName]);
if (isOptionDeprecated) {
if (optionAlias.length)
throw Error("The '" + optionName + "' is deprecated and has alias '" + optionAlias + "'");
}
else
throw Error("The '" + optionName + "' option name should start with 'on' prefix");
}
this._suppressDeprecatedWarnings();
var action = this._createAction(this.option(optionName), config);
this._resumeDeprecatedWarnings();
return action
},
option: function(options) {
var that = this,
name = options,
value = arguments[1],
optionAliases = this._getOptionAliases();
var normalizeOptionName = function(name) {
if (name) {
that._logWarningIfDeprecated(name);
if (optionAliases[name])
name = optionAliases[name]
}
return name
};
var getOptionValue = function(name, unwrapObservables) {
if (!that._cachedGetters[name])
that._cachedGetters[name] = dataUtils.compileGetter(name);
return that._cachedGetters[name](that._options, {
functionsAsIs: true,
unwrapObservables: unwrapObservables
})
};
if (arguments.length < 2 && $.type(name) !== "object") {
name = normalizeOptionName(name);
return getOptionValue(name)
}
if (typeof name === "string") {
options = {};
options[name] = value
}
that.beginUpdate();
try {
$.each(options, function(name, value) {
name = normalizeOptionName(name);
var prevValue = getOptionValue(name, false);
if (that._optionValuesEqual(name, prevValue, value))
return;
dataUtils.compileSetter(name)(that._options, value, {
functionsAsIs: true,
merge: !that._getOptionsByReference()[name],
unwrapObservables: false
});
that._notifyOptionChanged(name, value, prevValue)
})
}
finally {
that.endUpdate()
}
}
}).include(DX.EventsMixin);
$.extend(DX, {Component: Component})
})(jQuery, DevExpress);
/*! Module core, file transitionExecutor.js */
(function($, DX) {
var directionPostfixes = {
forward: " dx-forward",
backward: " dx-backward",
none: " dx-no-direction",
undefined: " dx-no-direction"
};
var addToAnimate = function(targetArray, $elements, animationConfig, type) {
$elements.each(function() {
var resultAnimationConfig = prepareElementAnimationConfig(animationConfig, type);
if (resultAnimationConfig)
targetArray.push({
$element: $(this),
animationConfig: resultAnimationConfig
})
})
};
var prepareElementAnimationConfig = function(config, type) {
var result;
if (typeof config === "string") {
var presetName = config;
config = DX.animationPresets.getPreset(presetName)
}
if (!config)
result = undefined;
else if ($.isFunction(config[type]))
result = config[type];
else {
var cssClass = "dx-" + type;
result = $.extend({skipElementInitialStyles: true}, config);
if (!result.type || result.type === "css") {
var extraCssClasses = result.extraCssClasses ? " " + result.extraCssClasses : "";
result.type = "css";
result.from = result.from || cssClass + extraCssClasses;
result.to = result.to || cssClass + "-active"
}
}
return result
};
var setupAnimations = function(items, config) {
var result = [];
$.each(items, function(index, item) {
var animationConfig = item.animationConfig,
$element = item.$element,
animationInstance;
if ($.isPlainObject(animationConfig)) {
var fxConfig = getFXConfig(animationConfig, config);
fxConfig.staggerDelay = fxConfig.staggerDelay || 0;
fxConfig.delay = index * fxConfig.staggerDelay + fxConfig.delay;
animationInstance = DX.fx.createAnimation($element, fxConfig)
}
else if ($.isFunction(animationConfig))
animationInstance = animationConfig($element, config);
animationInstance.setup();
result.push({
$element: $element,
animationInstance: animationInstance
})
});
return result
};
var startAnimations = function(items) {
for (var i = 0; i < items.length; i++)
items[i].animationInstance.start()
};
var getFXConfig = function(animation, config) {
var result = animation;
result.cleanupWhen = config.cleanupWhen;
result.delay = result.delay || 0;
if (result.type === "css") {
var direction = animation.direction || config.direction,
directionPostfix = directionPostfixes[direction];
result.from += directionPostfix
}
return result
};
var TransitionExecutor = DevExpress.Class.inherit({
ctor: function() {
this.toEnterItems = [];
this.toLeaveItems = [];
this.reset()
},
reset: function() {
this.toEnterItems.length = 0;
this.toLeaveItems.length = 0
},
enter: function($elements, animation) {
animation = animation || {};
addToAnimate(this.toEnterItems, $elements, animation, "enter")
},
leave: function($elements, animation) {
animation = animation || {};
addToAnimate(this.toLeaveItems, $elements, animation, "leave")
},
start: function(config) {
config = $.extend({}, config);
var that = this,
result;
if (!this.toEnterItems.length && !this.toLeaveItems.length) {
that.reset();
result = $.Deferred().resolve().promise()
}
else {
var animationItems = [],
animationDeferreds,
completeDeferred = $.Deferred();
config.cleanupWhen = completeDeferred.promise();
animationItems.push.apply(animationItems, setupAnimations(this.toEnterItems, config));
animationItems.push.apply(animationItems, setupAnimations(this.toLeaveItems, config));
animationDeferreds = $.map(animationItems, function(item) {
return item.animationInstance.deferred
});
result = $.when.apply($, animationDeferreds).always(function() {
completeDeferred.resolve();
that.reset()
});
DX.utils.executeAsync(function() {
startAnimations(animationItems)
})
}
return result
}
});
var optionPrefix = "preset_";
var AnimationPresetCollection = DevExpress.Component.inherit({
ctor: function() {
this.callBase.apply(this, arguments);
this._customRules = [];
this._registeredPresets = [];
this.resetToDefaults()
},
_setDefaultOptions: function() {
this.callBase();
this.option({
defaultAnimationDuration: 400,
defaultAnimationDelay: 0,
defaultStaggerAnimationDuration: 300,
defaultStaggerAnimationDelay: 40,
defaultStaggerAnimationStartDelay: 500
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function(device) {
return device.phone
},
options: {
defaultStaggerAnimationDuration: 350,
defaultStaggerAnimationDelay: 50,
defaultStaggerAnimationStartDelay: 0
}
}, {
device: function(device) {
return device.android
},
options: {defaultAnimationDelay: 100}
}])
},
_getPresetOptionName: function(animationName) {
return optionPrefix + animationName
},
resetToDefaults: function() {
this.clear();
this.registerDefaultPresets();
this.applyChanges()
},
clear: function(name) {
var that = this,
newRegisteredPresets = [];
$.each(this._registeredPresets, function(index, preset) {
if (!name || name === preset.name)
that.option(that._getPresetOptionName(preset.name), undefined);
else
newRegisteredPresets.push(preset)
});
this._registeredPresets = newRegisteredPresets;
this.applyChanges()
},
registerPreset: function(name, config) {
this._registeredPresets.push({
name: name,
config: config
})
},
applyChanges: function() {
var that = this;
this._customRules.length = 0;
$.each(this._registeredPresets, function(index, preset) {
var rule = {
device: preset.config.device,
options: {}
};
rule.options[that._getPresetOptionName(preset.name)] = preset.config.animation;
that._customRules.push(rule)
});
this._setOptionsByDevice()
},
getPreset: function(name) {
var result = name;
while (typeof result === "string")
result = this.option(this._getPresetOptionName(result));
return result
},
registerDefaultPresets: function() {
this.registerPreset("fade", {animation: {
extraCssClasses: "dx-fade-animation",
delay: this.option("defaultAnimationDelay"),
duration: this.option("defaultAnimationDuration")
}});
this.registerPreset("slide", {animation: {
extraCssClasses: "dx-slide-animation",
delay: this.option("defaultAnimationDelay"),
duration: this.option("defaultAnimationDuration")
}});
this.registerPreset("ios7-slide", {animation: {
extraCssClasses: "dx-ios7-slide-animation",
delay: this.option("defaultAnimationDelay"),
duration: this.option("defaultAnimationDuration")
}});
this.registerPreset("overflow", {animation: {
extraCssClasses: "dx-overflow-animation",
delay: this.option("defaultAnimationDelay"),
duration: this.option("defaultAnimationDuration")
}});
this.registerPreset("ios7-toolbar", {animation: {
extraCssClasses: "dx-ios7-toolbar-animation",
delay: this.option("defaultAnimationDelay"),
duration: this.option("defaultAnimationDuration")
}});
this.registerPreset("stagger-fade", {animation: {
extraCssClasses: "dx-fade-animation",
staggerDelay: this.option("defaultStaggerAnimationDelay"),
duration: this.option("defaultStaggerAnimationDuration"),
delay: this.option("defaultStaggerAnimationStartDelay")
}});
this.registerPreset("stagger-slide", {animation: {
extraCssClasses: "dx-slide-animation",
staggerDelay: this.option("defaultStaggerAnimationDelay"),
duration: this.option("defaultStaggerAnimationDuration"),
delay: this.option("defaultStaggerAnimationStartDelay")
}});
this.registerPreset("stagger-fade-slide", {animation: {
extraCssClasses: "dx-fade-slide-animation",
staggerDelay: this.option("defaultStaggerAnimationDelay"),
duration: this.option("defaultStaggerAnimationDuration"),
delay: this.option("defaultStaggerAnimationStartDelay")
}});
this.registerPreset("stagger-drop", {animation: {
extraCssClasses: "dx-drop-animation",
staggerDelay: this.option("defaultStaggerAnimationDelay"),
duration: this.option("defaultStaggerAnimationDuration"),
delay: this.option("defaultStaggerAnimationStartDelay")
}});
this.registerPreset("stagger-fade-drop", {animation: {
extraCssClasses: "dx-fade-drop-animation",
staggerDelay: this.option("defaultStaggerAnimationDelay"),
duration: this.option("defaultStaggerAnimationDuration"),
delay: this.option("defaultStaggerAnimationStartDelay")
}});
this.registerPreset("stagger-3d-drop", {animation: {
extraCssClasses: "dx-3d-drop-animation",
staggerDelay: this.option("defaultStaggerAnimationDelay"),
duration: this.option("defaultStaggerAnimationDuration"),
delay: this.option("defaultStaggerAnimationStartDelay")
}});
this.registerPreset("stagger-fade-zoom", {animation: {
extraCssClasses: "dx-fade-zoom-animation",
staggerDelay: this.option("defaultStaggerAnimationDelay"),
duration: this.option("defaultStaggerAnimationDuration"),
delay: this.option("defaultStaggerAnimationStartDelay")
}})
}
});
DX.TransitionExecutor = TransitionExecutor;
DX.AnimationPresetCollection = AnimationPresetCollection;
DX.animationPresets = new AnimationPresetCollection
})(jQuery, DevExpress);
/*! Module core, file DOMComponent.js */
(function($, DX, undefined) {
var windowResizeCallbacks = DX.utils.windowResizeCallbacks;
var RTL_DIRECTION_CLASS = "dx-rtl",
COMPONENT_NAMES_DATA_KEY = "dxComponents",
VISIBILITY_CHANGE_CLASS = "dx-visibility-change-handler",
VISIBILITY_CHANGE_EVENTNAMESPACE = "dxVisibilityChange";
var DOMComponent = DX.Component.inherit({
NAME: "DOMComponent",
_setDefaultOptions: function() {
this.callBase();
this.option({
width: undefined,
height: undefined,
rtlEnabled: DX.rtlEnabled
})
},
ctor: function(element, options) {
this._$element = $(element);
this.element().data(this.NAME, this);
this._attachInstanceToElement(this._$element);
this.callBase(options)
},
_attachInstanceToElement: $.noop,
_visibilityChanged: DX.abstract,
_dimensionChanged: DX.abstract,
_init: function() {
this.callBase();
this._attachWindowResizeCallback()
},
_attachWindowResizeCallback: function() {
if (this._isDimensionChangeSupported()) {
var windowResizeCallBack = this._windowResizeCallBack = $.proxy(this._dimensionChanged, this);
windowResizeCallbacks.add(windowResizeCallBack)
}
},
_isDimensionChangeSupported: function() {
return this._dimensionChanged !== DX.abstract
},
_render: function() {
this._toggleRTLDirection(this.option("rtlEnabled"));
this._renderVisibilityChange();
this._renderDimensions()
},
_renderVisibilityChange: function() {
if (!this._isVisibilityChangeSupported())
return;
this.element().addClass(VISIBILITY_CHANGE_CLASS);
this._attachVisiblityChangeHandlers()
},
_renderDimensions: function() {
var width = this.option("width"),
height = this.option("height"),
$element = this.element();
$element.outerWidth(width);
$element.outerHeight(height)
},
_attachVisiblityChangeHandlers: function() {
var that = this;
that.element().off("." + VISIBILITY_CHANGE_EVENTNAMESPACE).on("dxhiding." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
that._visibilityChanged(false)
}).on("dxshown." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
that._visibilityChanged(true)
})
},
_isVisibilityChangeSupported: function() {
return this._visibilityChanged !== DX.abstract
},
_clean: $.noop,
_modelByElement: $.noop,
_invalidate: function() {
if (!this._updateLockCount)
throw DX.Error("E0007");
this._requireRefresh = true
},
_refresh: function() {
this._clean();
this._render()
},
_dispose: function() {
this.callBase();
this._clean();
this._detachWindowResizeCallback()
},
_detachWindowResizeCallback: function() {
if (this._isDimensionChangeSupported())
windowResizeCallbacks.remove(this._windowResizeCallBack)
},
_toggleRTLDirection: function(rtl) {
this.element().toggleClass(RTL_DIRECTION_CLASS, rtl)
},
_createComponent: function(element, name, config) {
config = config || {};
this._extendConfig(config, {rtlEnabled: this.option("rtlEnabled")});
var $element = $(element)[name](config);
return $element[name]("instance")
},
_extendConfig: function(config, extendConfig) {
$.each(extendConfig, function(key, value) {
config[key] = config.hasOwnProperty(key) ? config[key] : value
})
},
_defaultActionConfig: function() {
return $.extend(this.callBase(), {context: this._modelByElement(this.element())})
},
_defaultActionArgs: function() {
var element = this.element(),
model = this._modelByElement(this.element());
return $.extend(this.callBase(), {
element: element,
model: model
})
},
_optionChanged: function(args) {
switch (args.name) {
case"width":
case"height":
this._renderDimensions();
break;
case"rtlEnabled":
this._invalidate();
break;
default:
this.callBase(args);
break
}
},
endUpdate: function() {
var requireRender = !this._initializing && !this._initialized;
this.callBase.apply(this, arguments);
if (!this._updateLockCount)
if (requireRender)
this._render();
else if (this._requireRefresh) {
this._requireRefresh = false;
this._refresh()
}
},
element: function() {
return this._$element
}
});
var registerComponent = function(name, namespace, componentClass) {
if (!componentClass) {
componentClass = namespace;
namespace = DX
}
componentClass.redefine({_attachInstanceToElement: function($element) {
$element.data(name, this);
if (!$element.data(COMPONENT_NAMES_DATA_KEY))
$element.data(COMPONENT_NAMES_DATA_KEY, []);
$element.data(COMPONENT_NAMES_DATA_KEY).push(name)
}});
namespace[name] = componentClass;
componentClass.prototype.NAME = name;
componentClass.defaultOptions = function(rule) {
componentClass.prototype._customRules = componentClass.prototype._customRules || [];
componentClass.prototype._customRules.push(rule)
};
$.fn[name] = function(options) {
var isMemberInvoke = typeof options === "string",
result;
if (isMemberInvoke) {
var memberName = options,
memberArgs = $.makeArray(arguments).slice(1);
this.each(function() {
var instance = $(this).data(name);
if (!instance)
throw DX.Error("E0009", name);
var member = instance[memberName],
memberValue = member.apply(instance, memberArgs);
if (result === undefined)
result = memberValue
})
}
else {
this.each(function() {
var instance = $(this).data(name);
if (instance)
instance.option(options);
else
new componentClass(this, options)
});
result = this
}
return result
}
};
var getComponents = function(element) {
element = $(element);
var names = element.data(COMPONENT_NAMES_DATA_KEY);
if (!names)
return [];
return $.map(names, function(name) {
return element.data(name)
})
};
var disposeComponents = function() {
$.each(getComponents(this), function() {
this._dispose()
})
};
var originalCleanData = $.cleanData;
$.cleanData = function(element) {
$.each(element, disposeComponents);
return originalCleanData.apply(this, arguments)
};
registerComponent("DOMComponent", DOMComponent);
DX.registerComponent = registerComponent
})(jQuery, DevExpress);
/*! Module core, file ui.js */
(function($, DX, undefined) {
DX.ui = {};
var createValidatorByTargetElement = function(condition) {
return function(e) {
if (!e.args.length)
return;
var args = e.args[0],
element = args[e.validatingTargetName] || args.element;
if (element && condition(element))
e.cancel = true
}
};
DX.registerActionExecutor({
designMode: {validate: function(e) {
if (DX.designMode)
e.cancel = true
}},
disabled: {validate: createValidatorByTargetElement(function($target) {
return $target.is(".dx-state-disabled, .dx-state-disabled *")
})},
readOnly: {validate: createValidatorByTargetElement(function($target) {
return $target.is(".dx-state-readonly, .dx-state-readonly *")
})}
})
})(jQuery, DevExpress);
/*! Module core, file ui.templates.js */
(function($, DX, undefined) {
var ui = DX.ui,
triggerShownEvent = DX.utils.triggerShownEvent;
var getWidgetName = function(widgetConstructor) {
return widgetConstructor.prototype.NAME
};
var TemplateProviderBase = DX.Class.inherit({
ctor: function() {
this.widgetTemplatesCache = {}
},
createTemplate: DX.abstract,
getTemplates: function(widget) {
return this._getWidgetTemplates(widget.constructor)
},
_getWidgetTemplates: function(widgetConstructor) {
if (!getWidgetName(widgetConstructor))
return {};
return this._getCachedWidgetTemplates(widgetConstructor)
},
_getCachedWidgetTemplates: function(widgetConstructor) {
var widgetName = getWidgetName(widgetConstructor),
templatesCache = this.widgetTemplatesCache;
if (!templatesCache[widgetName])
templatesCache[widgetName] = $.extend({}, this._getWidgetTemplates(widgetConstructor.parent), this._templatesForWidget(widgetName));
return templatesCache[widgetName]
},
_templatesForWidget: DX.abstract
});
var TemplateBase = DX.Class.inherit({
ctor: function(element, owner) {
this._element = $(element);
this._owner = owner
},
owner: function() {
return this._owner
},
render: function(data, $container, index) {
if (data instanceof jQuery) {
$container = data;
data = undefined
}
if ($container)
data = this._prepareDataForContainer(data, $container);
var $result = this._renderCore(data, index, $container);
if (this._shouldAppend && $container) {
$container.append($result);
if ($.contains(document.body, $container.get(0)))
triggerShownEvent($result)
}
return $result
},
source: function() {
return this._element.clone()
},
_prepareDataForContainer: function(data) {
return data
},
_renderCore: DX.abstract,
_shouldAppend: true,
dispose: function() {
this._owner = null
}
});
$.extend(ui, {
TemplateProviderBase: TemplateProviderBase,
TemplateBase: TemplateBase
})
})(jQuery, DevExpress);
/*! Module core, file jquery.templates.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
isString = DX.utils.isString,
currentTemplateEngine,
templateEngines = {};
var Template = ui.TemplateBase.inherit({
ctor: function(element, owner) {
this.callBase(element, owner);
this._compiledTemplate = currentTemplateEngine.compile(element)
},
_renderCore: function(data) {
return $("
").append(currentTemplateEngine.render(this._compiledTemplate, data)).contents()
}
});
var setTemplateEngine = function(templateEngine) {
if (isString(templateEngine)) {
currentTemplateEngine = templateEngines[templateEngine];
if (!currentTemplateEngine)
throw DX.Error("E0020", templateEngine);
}
else
currentTemplateEngine = templateEngine
};
var registerTemplateEngine = function(name, templateEngine) {
templateEngines[name] = templateEngine
};
var outerHtml = function(element) {
element = $(element);
if (!element.length || element[0].nodeName.toLowerCase() !== "script")
element = $("
").append(element);
return element.html()
};
registerTemplateEngine("default", {
compile: function(element) {
return DX.utils.normalizeTemplateElement(element)
},
render: function(template, data) {
return template.clone()
}
});
registerTemplateEngine("jquery-tmpl", {
compile: function(element) {
return $("
").append(DX.utils.normalizeTemplateElement(element))
},
render: function(template, data) {
return template.tmpl(data)
}
});
registerTemplateEngine("jsrender", {
compile: function(element) {
return $.templates(outerHtml(element))
},
render: function(template, data) {
return template.render(data)
}
});
registerTemplateEngine("mustache", {
compile: function(element) {
return Mustache.compile(outerHtml(element))
},
render: function(template, data) {
return template(data)
}
});
registerTemplateEngine("hogan", {
compile: function(element) {
return Hogan.compile(outerHtml(element))
},
render: function(template, data) {
return template.render(data)
}
});
registerTemplateEngine("underscore", {
compile: function(element) {
return _.template(outerHtml(element))
},
render: function(template, data) {
return template(data)
}
});
registerTemplateEngine("handlebars", {
compile: function(element) {
return Handlebars.compile(outerHtml(element))
},
render: function(template, data) {
return template(data)
}
});
registerTemplateEngine("doT", {
compile: function(element) {
return doT.template(outerHtml(element))
},
render: function(template, data) {
return template(data)
}
});
setTemplateEngine("default");
var DefaultTemplate = ui.TemplateBase.inherit({
ctor: function(render, owner) {
this.callBase($("
"), owner);
this._render = render
},
_renderCore: function(data, index, container) {
return DX.utils.normalizeTemplateElement(this._render(data, index, container))
}
});
var TemplateProvider = new(ui.TemplateProviderBase.inherit({
createTemplate: function(element, owner) {
return new ui.Template(element, owner)
},
_templatesForWidget: function(widgetName) {
var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},
templates = {};
$.each(templateGenerators, function(name, generator) {
templates[name] = new ui.DefaultTemplate(function() {
var $markup = generator.apply(this, arguments);
if (name !== "itemFrame")
$markup = $markup.contents();
return $markup
}, TemplateProvider)
});
return templates
}
}));
var TEMPLATE_GENERATORS = {};
var emptyTemplate = function() {
return $()
};
var ITEM_CONTENT_PLACEHOLDER_CLASS = "dx-item-content-placeholder";
TEMPLATE_GENERATORS.CollectionWidget = {
item: function(itemData) {
var $itemContent = $("
");
if ($.isPlainObject(itemData)) {
if (itemData.text)
$itemContent.text(itemData.text);
if (itemData.html)
$itemContent.html(itemData.html)
}
else
$itemContent.html(String(itemData));
return $itemContent
},
itemFrame: function(itemData) {
var $itemFrame = $("
");
$itemFrame.toggleClass("dx-state-invisible", itemData.visible !== undefined && !itemData.visible);
$itemFrame.toggleClass("dx-state-disabled", !!itemData.disabled);
var $placeholder = $("
").addClass(ITEM_CONTENT_PLACEHOLDER_CLASS);
$itemFrame.append($placeholder);
return $itemFrame
}
};
var BUTTON_TEXT_CLASS = "dx-button-text";
TEMPLATE_GENERATORS.dxButton = {content: function(itemData) {
var $itemContent = $("
"),
$iconElement = utils.getImageContainer(itemData.icon),
$textContainer = itemData.text ? $("
").text(itemData.text).addClass(BUTTON_TEXT_CLASS) : undefined;
$itemContent.append($iconElement).append($textContainer);
return $itemContent
}};
var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",
LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",
BADGE_CLASS = "dx-badge",
LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",
LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";
TEMPLATE_GENERATORS.dxList = {
item: function(itemData) {
var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
if (itemData.key) {
var $key = $("").text(itemData.key);
$key.appendTo($itemContent)
}
return $itemContent
},
itemFrame: function(itemData) {
var $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
if (itemData.badge) {
var $badgeContainer = $("
").addClass(LIST_ITEM_BADGE_CONTAINER_CLASS),
$badge = $("
").addClass(LIST_ITEM_BADGE_CLASS).addClass(BADGE_CLASS);
$badge.text(itemData.badge);
$badgeContainer.append($badge).appendTo($itemFrame)
}
if (itemData.showChevron) {
var $chevronContainer = $("
").addClass(LIST_ITEM_CHEVRON_CONTAINER_CLASS),
$chevron = $("
").addClass(LIST_ITEM_CHEVRON_CLASS);
$chevronContainer.append($chevron).appendTo($itemFrame)
}
return $itemFrame
},
group: function(groupData) {
var $groupContent = $("
");
if ($.isPlainObject(groupData)) {
if (groupData.key)
$groupContent.text(groupData.key)
}
else
$groupContent.html(String(groupData));
return $groupContent
}
};
TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};
TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};
TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};
TEMPLATE_GENERATORS.dxScheduler = {item: function(itemData) {
var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
var $details = $("
").addClass("dx-scheduler-appointment-content-details");
if (itemData.startDate)
$("
").text(Globalize.format(DX.utils.makeDate(itemData.startDate), "t")).appendTo($details);
if (itemData.endDate)
$("").text(" - " + Globalize.format(DX.utils.makeDate(itemData.endDate), "t")).appendTo($details);
$details.appendTo($itemContent);
if (itemData.recurrenceRule)
$("").addClass("dx-scheduler-appointment-recurrence-icon").appendTo($itemContent);
return $itemContent
}};
TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};
TEMPLATE_GENERATORS.dxSlideOutView = {
menu: emptyTemplate,
content: emptyTemplate
};
TEMPLATE_GENERATORS.dxSlideOut = {
menuItem: TEMPLATE_GENERATORS.dxList.item,
menuGroup: TEMPLATE_GENERATORS.dxList.group,
content: emptyTemplate
};
TEMPLATE_GENERATORS.dxAccordion = {
title: function(titleData) {
var $titleContent = $(""),
icon = titleData.icon,
iconSrc = titleData.iconSrc,
$iconElement = utils.getImageContainer(icon || iconSrc);
if ($.isPlainObject(titleData)) {
if (titleData.title)
$titleContent.text(titleData.title)
}
else
$titleContent.html(String(titleData));
$iconElement && $iconElement.prependTo($titleContent);
return $titleContent
},
item: TEMPLATE_GENERATORS.CollectionWidget.item
};
TEMPLATE_GENERATORS.dxActionSheet = {item: function(itemData) {
return $("
").append($("
").dxButton($.extend({onClick: itemData.click}, itemData)))
}};
TEMPLATE_GENERATORS.dxGallery = {item: function(itemData) {
var $itemContent = $("
");
if (itemData.imageSrc)
$('
').attr('src', itemData.imageSrc).appendTo($itemContent);
else
$('
').attr('src', String(itemData)).appendTo($itemContent);
return $itemContent
}};
var DX_MENU_ITEM_CAPTION_CLASS = 'dx-menu-item-text',
DX_MENU_ITEM_POPOUT_CLASS = 'dx-menu-item-popout',
DX_MENU_ITEM_POPOUT_CONTAINER_CLASS = 'dx-menu-item-popout-container';
TEMPLATE_GENERATORS.dxMenuBase = {item: function(itemData) {
var $itemContent = $("
"),
icon = itemData.icon,
iconSrc = itemData.iconSrc,
$iconElement = utils.getImageContainer(icon || iconSrc);
$iconElement && $iconElement.appendTo($itemContent);
var $itemCaption;
if ($.isPlainObject(itemData) && itemData.text)
$itemCaption = $('
').addClass(DX_MENU_ITEM_CAPTION_CLASS).text(itemData.text);
else if (!$.isPlainObject(itemData))
$itemCaption = $('').addClass(DX_MENU_ITEM_CAPTION_CLASS).html(String(itemData));
$itemContent.append($itemCaption);
var $popOutImage,
$popOutContainer;
if (itemData.items && itemData.items.length > 0) {
$popOutContainer = $('').addClass(DX_MENU_ITEM_POPOUT_CONTAINER_CLASS).appendTo($itemContent);
$popOutImage = $('').addClass(DX_MENU_ITEM_POPOUT_CLASS).appendTo($popOutContainer)
}
return $itemContent
}};
var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";
TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function(itemData) {
var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
if (itemData.title) {
var $itemHeader = $("
").addClass(PANORAMA_ITEM_TITLE_CLASS).text(itemData.title);
$itemContent.prepend($itemHeader)
}
return $itemContent
}};
TEMPLATE_GENERATORS.dxPivotTabs = {item: function(itemData) {
var $itemContent = $("
");
var $itemText;
if ($.isPlainObject(itemData))
$itemText = $("
").text(itemData.title);
else
$itemText = $("").text(String(itemData));
$itemContent.html($itemText);
return $itemContent
}};
TEMPLATE_GENERATORS.dxPivot = {
title: TEMPLATE_GENERATORS.dxPivotTabs.item,
content: emptyTemplate
};
var TABS_ITEM_TEXT_CLASS = "dx-tab-text";
TEMPLATE_GENERATORS.dxTabs = {
item: function(itemData) {
var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
if (itemData.html)
return $itemContent;
var icon = itemData.icon,
iconSrc = itemData.iconSrc,
$iconElement = utils.getImageContainer(icon || iconSrc);
if (!itemData.html)
$itemContent.wrapInner($("").addClass(TABS_ITEM_TEXT_CLASS));
$iconElement && $iconElement.prependTo($itemContent);
return $itemContent
},
itemFrame: function(itemData) {
var $badge = $(),
$itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
if (itemData.badge)
$badge = $("", {"class": "dx-tabs-item-badge dx-badge"}).text(itemData.badge);
$itemFrame.append($badge);
return $itemFrame
}
};
TEMPLATE_GENERATORS.dxTabPanel = {
item: TEMPLATE_GENERATORS.CollectionWidget.item,
title: function(itemData) {
var itemTitleData = itemData;
if ($.isPlainObject(itemData))
itemTitleData = $.extend({}, itemData, {text: itemData.title});
var $title = TEMPLATE_GENERATORS.dxTabs.item(itemTitleData);
return $title
}
};
var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";
TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function(itemData) {
var $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
if (itemData.badge) {
var $badge = $("
").addClass(NAVBAR_ITEM_BADGE_CLASS).addClass(BADGE_CLASS);
$badge.text(itemData.badge);
$badge.appendTo($itemFrame)
}
return $itemFrame
}};
TEMPLATE_GENERATORS.dxToolbar = {
item: function(itemData) {
var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
var widget = itemData.widget;
if (widget) {
var widgetElement = $("
").appendTo($itemContent),
widgetName = DX.inflector.camelize("dx-" + widget),
options = itemData.options || {};
widgetElement[widgetName](options)
}
else if (itemData.text)
$itemContent.wrapInner("
");
return $itemContent
},
menuItem: TEMPLATE_GENERATORS.dxList.item,
actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item
};
TEMPLATE_GENERATORS.dxTreeView = {item: function(itemData) {
var $itemContent = $("
"),
icon = itemData.icon,
iconSrc = itemData.iconSrc,
$iconElement = utils.getImageContainer(icon || iconSrc);
if (itemData.html)
$itemContent.html(itemData.html);
else {
$iconElement && $iconElement.appendTo($itemContent);
$("
").text(itemData.text).appendTo($itemContent)
}
return $itemContent
}};
var popupTitleAndBottom = function(itemData) {
return $("").append($("
").dxToolbar({items: itemData}))
};
TEMPLATE_GENERATORS.dxPopup = {
title: popupTitleAndBottom,
bottom: popupTitleAndBottom
};
TEMPLATE_GENERATORS.dxLookup = {
title: TEMPLATE_GENERATORS.dxPopup.title,
group: TEMPLATE_GENERATORS.dxList.group
};
TEMPLATE_GENERATORS.dxTagBox = {tag: function(itemData) {
return $("
").append($("
").text(itemData))
}};
TEMPLATE_GENERATORS.dxCalendar = {cell: function(itemData) {
return $("").text(itemData.text || String(itemData))
}};
$.extend(ui, {
TemplateProvider: TemplateProvider,
Template: Template,
DefaultTemplate: DefaultTemplate,
setTemplateEngine: setTemplateEngine
})
})(jQuery, DevExpress);
/*! Module core, file ko.components.js */
(function($, DX, undefined) {
if (!DX.support.hasKo)
return;
var ko = window.ko,
ui = DX.ui,
LOCKS_DATA_KEY = "dxKoLocks",
CREATED_WITH_KO_DATA_KEY = "dxKoCreation";
var Locks = function() {
var info = {};
var currentCount = function(lockName) {
return info[lockName] || 0
};
return {
obtain: function(lockName) {
info[lockName] = currentCount(lockName) + 1
},
release: function(lockName) {
var count = currentCount(lockName);
if (count < 1)
throw DX.Error("E0014");
if (count === 1)
delete info[lockName];
else
info[lockName] = count - 1
},
locked: function(lockName) {
return currentCount(lockName) > 0
}
}
};
var editorsBingindHandlers = [];
var registerComponentKoBinding = function(componentName, componentClass) {
if (componentClass.subclassOf(ui.Editor))
editorsBingindHandlers.push(componentName);
ko.bindingHandlers[componentName] = {init: function(domNode, valueAccessor) {
var $element = $(domNode),
optionChangedCallbacks = $.Callbacks(),
ctorOptions = {
templateProvider: ui.KoTemplateProvider,
_optionChangedCallbacks: optionChangedCallbacks
},
optionNameToModelMap = {};
var applyModelValueToOption = function(optionName, modelValue) {
var component = $element.data(componentName),
locks = $element.data(LOCKS_DATA_KEY),
optionValue = ko.unwrap(modelValue);
if (ko.isWriteableObservable(modelValue))
optionNameToModelMap[optionName] = modelValue;
if (component) {
if (locks.locked(optionName))
return;
locks.obtain(optionName);
try {
component.option(optionName, optionValue)
}
finally {
locks.release(optionName)
}
}
else
ctorOptions[optionName] = optionValue
};
var handleOptionChanged = function(args) {
var optionName = args.fullName,
optionValue = args.value;
if (!(optionName in optionNameToModelMap))
return;
var $element = this._$element,
locks = $element.data(LOCKS_DATA_KEY);
if (locks.locked(optionName))
return;
locks.obtain(optionName);
try {
optionNameToModelMap[optionName](optionValue)
}
finally {
locks.release(optionName)
}
};
var createComponent = function() {
optionChangedCallbacks.add(handleOptionChanged);
$element.data(CREATED_WITH_KO_DATA_KEY, true).data(LOCKS_DATA_KEY, new Locks)[componentName](ctorOptions);
ctorOptions = null
};
var unwrapModelValue = function(option, model) {
var modelUnwrapped;
ko.computed(function() {
applyModelValueToOption(option, model);
modelUnwrapped = ko.unwrap(model)
}, null, {disposeWhenNodeIsRemoved: domNode});
if ($.isPlainObject(modelUnwrapped))
$.each(modelUnwrapped, function(optionName, modelValue) {
unwrapModelValue(option + "." + optionName, modelValue)
})
};
ko.computed(function() {
var component = $element.data(componentName);
if (component)
component.beginUpdate();
$.each(ko.unwrap(valueAccessor()), function(optionName, modelValue) {
unwrapModelValue(optionName, modelValue)
});
if (component)
component.endUpdate();
else
createComponent()
}, null, {disposeWhenNodeIsRemoved: domNode});
return {controlsDescendantBindings: componentClass.subclassOf(ui.Widget)}
}};
if (componentName === "dxValidator")
ko.bindingHandlers["dxValidator"].after = editorsBingindHandlers
};
DX.DOMComponent.redefine({_modelByElement: function(element) {
if (element.length)
return ko.dataFor(element.get(0))
}});
var originalRegisterComponent = DX.registerComponent;
var registerKoComponent = function(componentName, _, componentClass) {
componentClass = componentClass || _;
originalRegisterComponent.apply(this, arguments);
registerComponentKoBinding(componentName, componentClass)
};
DX.registerComponent = registerKoComponent;
var cleanKoData = function(element, andSelf) {
var cleanNode = function() {
ko.cleanNode(this)
};
if (andSelf)
element.each(cleanNode);
else
element.find("*").each(cleanNode)
};
var originalEmpty = $.fn.empty;
$.fn.empty = function() {
cleanKoData(this, false);
return originalEmpty.apply(this, arguments)
};
var originalRemove = $.fn.remove;
$.fn.remove = function(selector, keepData) {
if (!keepData) {
var subject = this;
if (selector)
subject = subject.filter(selector);
cleanKoData(subject, true)
}
return originalRemove.call(this, selector, keepData)
};
var originalHtml = $.fn.html;
$.fn.html = function(value) {
if (typeof value === "string")
cleanKoData(this, false);
return originalHtml.apply(this, arguments)
};
ko.bindingHandlers.dxAction = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var $element = $(element);
var unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
actionSource = unwrappedValue,
actionOptions = {context: element};
if (unwrappedValue.execute) {
actionSource = unwrappedValue.execute;
$.extend(actionOptions, unwrappedValue)
}
var action = new DX.Action(actionSource, actionOptions);
$element.off(".dxActionBinding").on("dxclick.dxActionBinding", function(e) {
action.execute({
element: $element,
model: viewModel,
evaluate: function(expression) {
var context = viewModel;
if (expression.length > 0 && expression[0] === "$")
context = ko.contextFor(element);
var getter = DX.data.utils.compileGetter(expression);
return getter(context)
},
jQueryEvent: e
});
if (!actionOptions.bubbling)
e.stopPropagation()
})
}};
ko.bindingHandlers.dxControlsDescendantBindings = {init: function(_, valueAccessor) {
return {controlsDescendantBindings: ko.unwrap(valueAccessor())}
}};
var render = function($element, options, viewModel, bindingContext) {
var result = $.Deferred();
$element.removeClass("dx-pending-rendering-manual");
$element.addClass("dx-pending-rendering-active");
if (options.showLoadIndicator && options.showLoadIndicatorImmediately !== true)
showLoadIndicator($element);
DX.utils.executeAsync(function() {
renderImpl($element, options, viewModel, bindingContext).done(function() {
var shownArgs = {element: $element};
if (options.onShown)
options.onShown.apply(viewModel, [shownArgs]);
result.resolve(shownArgs)
}).fail(function() {
result.rejectWith(result, arguments)
})
});
return result.promise()
};
var showLoadIndicator = function($container) {
var $indicator = $('
').dxLoadIndicator({visible: true}).addClass("dx-defered-rendering-load-indicator");
$container.append($indicator)
};
var isElementInViewport = function(element) {
var rect = element.getBoundingClientRect();
return rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth)
};
var renderImpl = function($element, options, viewModel, bindingContext) {
var animatePromise,
childBindingContext = bindingContext.createChildContext(viewModel),
renderedArgs = {element: $element};
$element.find(".dx-defered-rendering-load-indicator").remove();
ko.applyBindingsToDescendants(childBindingContext, $element[0]);
options._renderedDeferred.resolve(renderedArgs);
if (options.onRendered)
options.onRendered.apply(viewModel, [renderedArgs]);
$element.children().removeClass("dx-invisible-while-pending-rendering");
DX.utils.triggerShownEvent($element.children());
$element.removeClass("dx-pending-rendering");
$element.removeClass("dx-pending-rendering-active");
if (options.animation) {
var transitionExecutor = new DX.TransitionExecutor;
if (options.staggerItemSelector) {
$element.find(options.staggerItemSelector).each(function() {
if (isElementInViewport(this))
transitionExecutor.enter($(this), options.animation)
});
animatePromise = $.when(animatePromise, transitionExecutor.start())
}
else {
transitionExecutor.enter($element, options.animation || "content-rendered");
animatePromise = transitionExecutor.start()
}
}
else
animatePromise = $.Deferred().resolve().promise();
return animatePromise
};
var initElement = function($element, options) {
$element.addClass("dx-defer-rendering dx-pending-rendering dx-loadindicator-container");
$element.data("dx-rendered-promise", options._renderedDeferred.promise());
if (options.hiddenUntilRendered)
$element.children().addClass("dx-invisible-while-pending-rendering");
if (options.showLoadIndicator && options.showLoadIndicatorImmediately)
showLoadIndicator($element)
};
var initRender = function($element, options, viewModel, bindingContext) {
var doRender = function() {
return render($element, options, viewModel, bindingContext)
};
if (options.renderWhen)
options.renderWhen.done(doRender);
else {
$element.data("dx-render-delegate", doRender);
$element.addClass("dx-pending-rendering-manual")
}
};
ko.bindingHandlers.dxDeferRendering = {init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $element = $(element),
passedOptions = ko.unwrap(valueAccessor()),
showLoadIndicatorImmediately = ko.unwrap(passedOptions.showLoadIndicatorImmediately),
hiddenUntilRendered = ko.unwrap(passedOptions.hiddenUntilRendered),
options = {
showLoadIndicator: ko.unwrap(passedOptions.showLoadIndicator) || false,
showLoadIndicatorImmediately: showLoadIndicatorImmediately !== undefined ? showLoadIndicatorImmediately : true,
hiddenUntilRendered: hiddenUntilRendered !== undefined ? hiddenUntilRendered : true,
renderWhen: ko.unwrap(passedOptions.renderWhen),
animation: ko.unwrap(passedOptions.animation),
staggerItemSelector: ko.unwrap(passedOptions.staggerItemSelector),
onRendered: ko.unwrap(passedOptions.onRendered),
onShown: ko.unwrap(passedOptions.onShown),
_renderedDeferred: $.Deferred()
};
initElement($element, options);
initRender($element, options, viewModel, bindingContext);
return {controlsDescendantBindings: true}
}};
ko.bindingHandlers.dxIcon = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {},
iconElement = DevExpress.utils.getImageContainer(options);
ko.virtualElements.emptyNode(element);
if (iconElement)
ko.virtualElements.prepend(element, iconElement.get(0))
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {},
iconElement = DevExpress.utils.getImageContainer(options);
ko.virtualElements.emptyNode(element);
if (iconElement)
ko.virtualElements.prepend(element, iconElement.get(0))
}
};
ko.virtualElements.allowedBindings.dxIcon = true
})(jQuery, DevExpress);
/*! Module core, file ng.components.js */
(function($, DX, undefined) {
if (!DX.support.hasNg)
return;
var ui = DX.ui,
compileSetter = DX.data.utils.compileSetter,
compileGetter = DX.data.utils.compileGetter;
var ITEM_ALIAS_ATTRIBUTE_NAME = "dxItemAlias",
DEFAULT_MODEL_ALIAS = "scopeValue";
var SKIP_APPLY_ACTION_CATEGORIES = ["rendering"];
var phoneJsModule = DX.ng.module;
var safeApply = function(func, scope) {
if (scope.$root.$$phase)
func(scope);
else
scope.$apply(function() {
func(scope)
})
};
var ComponentBuilder = DX.Class.inherit({
ctor: function(options) {
this._$element = options.$element;
this._$templates = options.$templates;
this._componentClass = options.componentClass;
this._scope = options.scope;
this._parse = options.parse;
this._compile = options.compile;
this._ngOptions = this._normalizeOptions(options.ngOptions);
this._itemAlias = options.itemAlias;
this._componentDisposing = $.Callbacks();
if (options.ngOptions.data)
this._initDataScope(options.ngOptions.data)
},
_normalizeOptions: function(options) {
var result = $.extend({}, options);
if (options.bindingOptions)
$.each(options.bindingOptions, function(key, value) {
if ($.type(value) === 'string')
result.bindingOptions[key] = {dataPath: value}
});
return result
},
initComponentWithBindings: function() {
this._initComponentBindings();
this._initComponent(this._scope);
this._shownEventTimer = setTimeout($.proxy(function() {
DX.utils.triggerShownEvent(this._$element)
}, this))
},
_initDataScope: function(data) {
if (typeof data === "string") {
var dataStr = data,
rootScope = this._scope;
data = rootScope.$eval(data);
this._scope = rootScope.$new();
this._synchronizeDataScopes(rootScope, this._scope, data, dataStr)
}
$.extend(this._scope, data)
},
_synchronizeDataScopes: function(parentScope, childScope, data, parentPrefix) {
var that = this;
$.each(data, function(fieldPath) {
that._synchronizeScopeField({
parentScope: parentScope,
childScope: childScope,
fieldPath: fieldPath,
parentPrefix: parentPrefix
})
})
},
_initComponent: function(scope) {
this._component = new this._componentClass(this._$element, this._evalOptions(scope))
},
_initComponentBindings: function() {
var that = this,
optionDependencies = {};
that._disposingCallbacks = $.Callbacks();
if (that._ngOptions.bindingOptions)
$.each(that._ngOptions.bindingOptions, function(optionPath, value) {
var separatorIndex = optionPath.search(/\[|\./),
optionForSubscribe = separatorIndex > -1 ? optionPath.substring(0, separatorIndex) : optionPath,
prevWatchMethod,
clearWatcher,
valuePath = value.dataPath,
deepWatch = true,
forcePlainWatchMethod = false;
if (value.deep !== undefined)
forcePlainWatchMethod = deepWatch = !!value.deep;
if (!optionDependencies[optionForSubscribe])
optionDependencies[optionForSubscribe] = {};
optionDependencies[optionForSubscribe][optionPath] = valuePath;
var watchCallback = function(newValue, oldValue) {
if (newValue !== oldValue) {
that._component.option(optionPath, newValue);
updateWatcher()
}
};
var updateWatcher = function() {
var watchMethod = $.isArray(that._scope.$eval(valuePath)) && !forcePlainWatchMethod ? "$watchCollection" : "$watch";
if (prevWatchMethod !== watchMethod) {
if (clearWatcher)
clearWatcher();
clearWatcher = that._scope[watchMethod](valuePath, watchCallback, deepWatch);
prevWatchMethod = watchMethod
}
};
updateWatcher();
that._disposingCallbacks.add(function() {
clearWatcher();
that._componentDisposing.fire()
})
});
that._optionChangedCallbacks = $.Callbacks().add(function(args) {
var optionName = args.name,
optionValue = args.value;
if (that._scope.$root.$$phase === "$digest" || !optionDependencies || !optionDependencies[optionName])
return;
safeApply(function(scope) {
$.each(optionDependencies[optionName], function(optionPath, valuePath) {
var getter = compileGetter(optionPath);
var tmpData = {};
tmpData[optionName] = optionValue;
that._parse(valuePath).assign(that._scope, getter(tmpData))
})
}, that._scope)
});
that._disposingCallbacks.add(function() {
clearTimeout(that._shownEventTimer)
})
},
_compilerByTemplate: function(template) {
var that = this,
scopeItemsPath = this._getScopeItemsPath();
return function(data, index) {
var $resultMarkup = $(template).clone(),
templateScope;
if (data !== undefined) {
var dataIsScope = data.$id;
templateScope = dataIsScope ? data : that._createScopeWithData(data);
$resultMarkup.on("$destroy", function() {
var destroyAlreadyCalled = !templateScope.$parent;
if (destroyAlreadyCalled)
return;
templateScope.$destroy()
})
}
else
templateScope = that._scope;
if (scopeItemsPath)
that._synchronizeScopes(templateScope, scopeItemsPath, index);
safeApply(that._compile($resultMarkup), templateScope);
return $resultMarkup
}
},
_getScopeItemsPath: function() {
if (this._componentClass.subclassOf(ui.CollectionWidget) && this._ngOptions.bindingOptions && this._ngOptions.bindingOptions.items)
return this._ngOptions.bindingOptions.items.dataPath
},
_createScopeWithData: function(data) {
var newScope = this._scope.$new(true);
data = this._enshureDataIsPlainObject(data);
$.extend(newScope, data);
return newScope
},
_synchronizeScopes: function(itemScope, parentPrefix, itemIndex) {
var that = this,
item = compileGetter(parentPrefix + "[" + itemIndex + "]")(this._scope);
item = that._enshureDataIsPlainObject(item);
$.each(item, function(itemPath) {
that._synchronizeScopeField({
parentScope: that._scope,
childScope: itemScope,
fieldPath: itemPath,
parentPrefix: parentPrefix,
itemIndex: itemIndex
})
})
},
_synchronizeScopeField: function(args) {
var parentScope = args.parentScope,
childScope = args.childScope,
fieldPath = args.fieldPath,
parentPrefix = args.parentPrefix,
itemIndex = args.itemIndex;
var innerPathSuffix = fieldPath === (this._itemAlias || DEFAULT_MODEL_ALIAS) ? "" : "." + fieldPath,
collectionField = itemIndex !== undefined,
optionOuterBag = [parentPrefix],
optionOuterPath;
if (collectionField)
optionOuterBag.push("[", itemIndex, "]");
optionOuterBag.push(innerPathSuffix);
optionOuterPath = optionOuterBag.join("");
var clearParentWatcher = parentScope.$watch(optionOuterPath, function(newValue, oldValue) {
if (newValue !== oldValue)
compileSetter(fieldPath)(childScope, newValue)
});
var clearItemWatcher = childScope.$watch(fieldPath, function(newValue, oldValue) {
if (newValue !== oldValue) {
if (collectionField && !compileGetter(parentPrefix)(parentScope)[itemIndex]) {
clearItemWatcher();
return
}
compileSetter(optionOuterPath)(parentScope, newValue)
}
});
this._componentDisposing.add([clearParentWatcher, clearItemWatcher])
},
_evalOptions: function(scope) {
var result = $.extend({}, this._ngOptions);
delete result.data;
delete result.bindingOptions;
if (this._ngOptions.bindingOptions)
$.each(this._ngOptions.bindingOptions, function(key, value) {
result[key] = scope.$eval(value.dataPath)
});
result._optionChangedCallbacks = this._optionChangedCallbacks;
result._disposingCallbacks = this._disposingCallbacks;
result.templateProvider = ui.NgTemplateProvider;
result.templateCompiler = $.proxy(function($template) {
return this._compilerByTemplate($template)
}, this);
return result
},
_enshureDataIsPlainObject: function(object) {
var result;
if ($.isPlainObject(object))
result = object;
else {
result = {};
result[DEFAULT_MODEL_ALIAS] = object
}
if (this._itemAlias)
result[this._itemAlias] = object;
return result
}
});
ComponentBuilder = ComponentBuilder.inherit({
ctor: function(options) {
this.callBase.apply(this, arguments);
this._componentName = options.componentName;
this._ngModel = options.ngModel;
this._ngModelController = options.ngModelController
},
_isNgModelRequired: function() {
return this._componentClass.subclassOf(ui.Editor) && this._ngModel
},
_initComponentBindings: function() {
this.callBase.apply(this, arguments);
this._initNgModelBinding()
},
_initNgModelBinding: function() {
if (!this._isNgModelRequired())
return;
var that = this;
var ngModelWatcher = this._scope.$watch(this._ngModel, function(newValue, oldValue) {
if (newValue === oldValue)
return;
that._component.option(that._ngModelOption(), newValue)
});
that._optionChangedCallbacks.add(function(args) {
if (args.name !== that._ngModelOption())
return;
that._ngModelController.$setViewValue(args.value)
});
this._disposingCallbacks.add(function() {
ngModelWatcher()
})
},
_ngModelOption: function() {
if ($.inArray(this._componentName, ["dxFileUploader", "dxTagBox"]) > -1)
return "values";
return "value"
},
_evalOptions: function() {
if (!this._isNgModelRequired())
return this.callBase.apply(this, arguments);
var result = this.callBase.apply(this, arguments);
result[this._ngModelOption()] = this._parse(this._ngModel)(this._scope);
return result
}
});
var NgComponent = DX.DOMComponent.inherit({
_modelByElement: function(element) {
if (element.length)
return element.scope()
},
_createActionByOption: function(optionName, config) {
var action = this.callBase.apply(this, arguments);
if (config && $.inArray(config.category, SKIP_APPLY_ACTION_CATEGORIES) > -1)
return action;
var component = this,
wrappedAction = function() {
var that = this,
scope = component._modelByElement(component.element()),
args = arguments;
if (!scope || !scope.$root || scope.$root.$$phase)
return action.apply(that, args);
return scope.$apply(function() {
return action.apply(that, args)
})
};
return wrappedAction
},
_createComponent: function(element, name, config) {
return this.callBase(element, name, $.extend({templateCompiler: this.option("templateCompiler")}, config))
}
});
var registeredComponents = {};
var originalRegisterComponent = DX.registerComponent;
var registerNgComponent = function(componentName, _, componentClass) {
componentClass = componentClass || _;
originalRegisterComponent.apply(this, arguments);
if (!registeredComponents[componentName])
registerComponentDirective(componentName);
registeredComponents[componentName] = componentClass
};
var registerComponentDirective = function(componentName) {
var priority = componentName !== "dxValidator" ? 1 : 10;
phoneJsModule.directive(componentName, ["$compile", "$parse", function($compile, $parse) {
return {
restrict: "A",
require: "^?ngModel",
priority: priority,
compile: function($element) {
var componentClass = registeredComponents[componentName],
$content = componentClass.subclassOf(ui.Widget) ? $element.contents().detach() : null;
return function(scope, $element, attrs, ngModelController) {
$element.append($content);
var componentBuilder = new ComponentBuilder({
componentClass: componentClass,
componentName: componentName,
compile: $compile,
parse: $parse,
$element: $element,
scope: scope,
ngOptions: attrs[componentName] ? scope.$eval(attrs[componentName]) : {},
ngModel: attrs.ngModel,
ngModelController: ngModelController,
itemAlias: attrs[ITEM_ALIAS_ATTRIBUTE_NAME]
});
componentBuilder.initComponentWithBindings()
}
}
}
}])
};
phoneJsModule.filter('dxGlobalize', function() {
return function(input, param) {
return Globalize.format(input, param)
}
});
phoneJsModule.directive("dxIcon", ["$compile", function($compile) {
return {
restrict: 'E',
link: function($scope, $element, $attrs) {
var html = DX.utils.getImageContainer($scope.icon || $scope.iconSrc);
if (html) {
var e = $compile(html.get(0))($scope);
$element.replaceWith(e)
}
}
}
}]);
DX.registerComponent = registerNgComponent;
registerNgComponent("DOMComponent", NgComponent)
})(jQuery, DevExpress);
/*! Module core, file ko.templates.js */
(function($, DX, undefined) {
if (!DX.support.hasKo)
return;
var ko = window.ko,
ui = DX.ui;
var KoTemplate = ui.TemplateBase.inherit({
ctor: function(element) {
this.callBase.apply(this, arguments);
this._template = $("
").append(DX.utils.normalizeTemplateElement(element));
this._registerKoTemplate()
},
_registerKoTemplate: function() {
var template = this._template.get(0);
new ko.templateSources.anonymousTemplate(template)['nodes'](template)
},
_prepareDataForContainer: function(data, container) {
var result = data,
containerElement,
containerContext;
if (container.length) {
containerElement = container.get(0);
data = data !== undefined ? data : ko.dataFor(containerElement) || {};
containerContext = ko.contextFor(containerElement);
if (containerContext)
result = data === containerContext.$data ? containerContext : containerContext.createChildContext(data);
else
result = data
}
return result
},
_renderCore: function(data) {
var $renderBag = $("
");
ko.renderTemplate(this._template.get(0), data, null, $renderBag.get(0));
var $result = $renderBag.contents().detach();
$renderBag.remove();
return $result
},
dispose: function() {
this.callBase();
this._template.remove()
}
});
var KoTemplateProvider = new(ui.TemplateProviderBase.inherit({
createTemplate: function(element, owner) {
return new KoTemplate(element, owner)
},
applyTemplate: function(element, model) {
ko.applyBindings(model, element)
},
_templatesForWidget: function(widgetName) {
var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},
templates = {};
$.each(templateGenerators, function(name, generator) {
var $markup = DX.utils.createMarkupFromString(generator());
if (name !== "itemFrame")
$markup = $markup.contents();
templates[name] = new KoTemplate($markup, KoTemplateProvider)
});
return templates
}
}));
var createElementWithBindAttr = function(tagName, bindings, closeTag, additionalProperties) {
closeTag = closeTag === undefined ? true : closeTag;
var bindAttr = $.map(bindings, function(value, key) {
return key + ":" + value
}).join(",");
additionalProperties = additionalProperties || "";
return "<" + tagName + " data-bind=\"" + bindAttr + "\" " + additionalProperties + ">" + (closeTag ? "" + tagName + ">" : "")
};
var defaultKoTemplateBasicBindings = {css: "{ 'dx-state-disabled': $data.disabled, 'dx-state-invisible': !($data.visible === undefined || ko.unwrap($data.visible)) }"};
var TEMPLATE_GENERATORS = {};
var emptyTemplate = function() {
return ""
};
TEMPLATE_GENERATORS.CollectionWidget = {
itemFrame: function() {
var markup = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false), "
", "
"];
return markup.join("")
},
item: function() {
var htmlBinding = createElementWithBindAttr("div", {html: "html"}),
textBinding = createElementWithBindAttr("div", {text: "text"}),
primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
var markup = ["
", "", htmlBinding, "", "", textBinding, "", "", primitiveBinding, "", "
"];
return markup.join("")
}
};
var BUTTON_TEXT_CLASS = "dx-button-text";
TEMPLATE_GENERATORS.dxButton = {content: function() {
var textBinding = createElementWithBindAttr("span", {
text: "$data.text",
css: "{ '" + BUTTON_TEXT_CLASS + "' : !!$data.text }"
});
var markup = ["
", "", textBinding, "
"];
return markup.join("")
}};
var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",
LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",
BADGE_CLASS = "dx-badge",
LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",
LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";
TEMPLATE_GENERATORS.dxList = {
item: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
keyBinding = createElementWithBindAttr("div", {text: "key"});
template = [template.substring(0, template.length - 6), "" + keyBinding + "", "
"];
return template.join("")
},
itemFrame: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
badgeBinding = createElementWithBindAttr("div", {text: "badge"}, true, 'class="' + LIST_ITEM_BADGE_CLASS + " " + BADGE_CLASS + '"');
var markup = [template.substring(0, template.length - 6), "", "
", badgeBinding, "
", "", "", "
", "", "
"];
return markup.join("")
},
group: function() {
var keyBinding = createElementWithBindAttr("div", {text: "key"}),
primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
var markup = ["", "", keyBinding, "", "", primitiveBinding, "", "
"];
return markup.join("")
}
};
TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};
TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};
TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};
TEMPLATE_GENERATORS.dxScheduler = {item: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
startDateBinding = createElementWithBindAttr("strong", {text: "Globalize.format(DevExpress.utils.makeDate($data.startDate), 't')"}),
endDateBinding = createElementWithBindAttr("strong", {text: "' - ' + Globalize.format(DevExpress.utils.makeDate($data.endDate), 't')"});
template = [template.substring(0, template.length - 6), "", "" + startDateBinding + "", "" + endDateBinding + "", "
", " ", " "];
return template.join("")
}};
TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};
TEMPLATE_GENERATORS.dxSlideOutView = {
menu: emptyTemplate,
content: emptyTemplate
};
TEMPLATE_GENERATORS.dxSlideOut = {
menuItem: TEMPLATE_GENERATORS.dxList.item,
menuGroup: TEMPLATE_GENERATORS.dxList.group,
content: emptyTemplate
};
TEMPLATE_GENERATORS.dxAccordion = {
title: function() {
var titleBinding = createElementWithBindAttr("span", {text: "$.isPlainObject($data) ? $data.title : String($data)"});
var markup = ["
", "", titleBinding, "
"];
return markup.join("")
},
item: TEMPLATE_GENERATORS.CollectionWidget.item
};
TEMPLATE_GENERATORS.dxResponsiveBox = {item: TEMPLATE_GENERATORS.CollectionWidget.item},
TEMPLATE_GENERATORS.dxPivotTabs = {item: function() {
var titleBinding = createElementWithBindAttr("span", {text: "title"}),
primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
var markup = ["
", "", titleBinding, "", "", primitiveBinding, "", "
"];
return markup.join("")
}};
TEMPLATE_GENERATORS.dxPivot = {
title: TEMPLATE_GENERATORS.dxPivotTabs.item,
content: emptyTemplate
};
var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";
TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
headerBinding = createElementWithBindAttr("div", {text: "title"}, true, 'class="' + PANORAMA_ITEM_TITLE_CLASS + '"');
var divInnerStart = template.indexOf(">") + 1;
template = [template.substring(0, divInnerStart), "", headerBinding, "", template.substring(divInnerStart, template.length)];
return template.join("")
}};
TEMPLATE_GENERATORS.dxActionSheet = {item: function() {
return ["
", createElementWithBindAttr("div", {dxButton: "{ text: $data.text, onClick: $data.clickAction || $data.onClick, type: $data.type, disabled: !!ko.unwrap($data.disabled) }"}), "
"].join("")
}};
TEMPLATE_GENERATORS.dxToolbar = {
item: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.item();
template = [template.substring(0, template.length - 6), ""];
$.each(["button", "tabs", "dropDownMenu"], function() {
var bindingName = DX.inflector.camelize(["dx", "-", this].join("")),
bindingObj = {};
bindingObj[bindingName] = "$data.options";
template.push("", createElementWithBindAttr("div", bindingObj), "")
});
template.push("");
return template.join("")
},
menuItem: TEMPLATE_GENERATORS.dxList.item,
actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item
};
TEMPLATE_GENERATORS.dxGallery = {item: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),
imgBinding = createElementWithBindAttr("img", {attr: "{ src: String($data) }"}, false);
template = [template.substring(0, template.length - 6).replace(primitiveBinding, imgBinding), "", createElementWithBindAttr("img", {attr: "{ src: $data.imageSrc }"}, false), ""].join("");
return template
}};
TEMPLATE_GENERATORS.dxTabs = {
item: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
basePrimitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),
primitiveBinding = "
",
baseTextBinding = createElementWithBindAttr("div", {text: "text"}),
textBinding = "" + "
";
template = template.replace("", "").replace(basePrimitiveBinding, primitiveBinding).replace(baseTextBinding, textBinding);
return template
},
itemFrame: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
badgeBinding = createElementWithBindAttr("div", {
attr: "{ 'class': 'dx-tabs-item-badge dx-badge' }",
text: "badge"
});
var markup = [template.substring(0, template.length - 6), "", badgeBinding, "", "
"];
return markup.join("")
}
};
TEMPLATE_GENERATORS.dxTabPanel = {
item: TEMPLATE_GENERATORS.CollectionWidget.item,
title: function() {
var template = TEMPLATE_GENERATORS.dxTabs.item();
return template.replace(/\$data\.text/g, '$data.title')
}
};
var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";
TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
badgeBinding = createElementWithBindAttr("div", {text: "badge"}, true, 'class="' + NAVBAR_ITEM_BADGE_CLASS + " " + BADGE_CLASS + '"');
var markup = [template.substring(0, template.length - 6), "", badgeBinding, "", "
"];
return markup.join("")
}};
TEMPLATE_GENERATORS.dxMenuBase = {item: function() {
var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)],
textBinding = createElementWithBindAttr("span", {
text: "text",
css: "{ 'dx-menu-item-text': true }"
}),
primitiveBinding = createElementWithBindAttr("span", {
text: "String($data)",
css: "{ 'dx-menu-item-text': true }"
}),
popout = "";
template.push("", "", textBinding, "", "", primitiveBinding, "", "", popout, "", " ");
return template.join("")
}};
TEMPLATE_GENERATORS.dxTreeView = {item: function() {
var node = [],
link = createElementWithBindAttr("span", {text: "text"}, true),
htmlBinding = createElementWithBindAttr("div", {html: "html"});
node.push("
", "", htmlBinding, "", "", "" + link + "", "
");
return node.join("")
}};
TEMPLATE_GENERATORS.dxCalendar = {cell: function() {
var textBinding = createElementWithBindAttr("span", {text: "text"}),
primitiveBinding = createElementWithBindAttr("span", {text: "String($data)"});
var markup = ["
", "", textBinding, "", "", primitiveBinding, "", "
"];
return markup.join("")
}};
var popupTitleAndBottom = function() {
return ["
", createElementWithBindAttr("div", {dxToolbar: "{ items: $data }"}), "
"].join("")
};
TEMPLATE_GENERATORS.dxPopup = {
title: popupTitleAndBottom,
bottom: popupTitleAndBottom
};
TEMPLATE_GENERATORS.dxLookup = {
title: TEMPLATE_GENERATORS.dxPopup.title,
group: TEMPLATE_GENERATORS.dxList.group
};
TEMPLATE_GENERATORS.dxTagBox = {tag: function() {
return ["
", createElementWithBindAttr("span", {text: "$data"})].join("")
}};
$.extend(ui, {
KoTemplateProvider: KoTemplateProvider,
KoTemplate: KoTemplate
})
})(jQuery, DevExpress);
/*! Module core, file ng.templates.js */
(function($, DX, undefined) {
if (!DX.support.hasNg)
return;
var ui = DX.ui;
var TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";
var NgTemplate = ui.TemplateBase.inherit({
ctor: function() {
this.callBase.apply(this, arguments);
this.setCompiler(this._getParentTemplateCompiler())
},
_getParentTemplateCompiler: function() {
var templateCompiler = null,
owner = this.owner();
while (!templateCompiler && owner) {
templateCompiler = $.isFunction(owner.option) ? owner.option("templateCompiler") : null;
owner = $.isFunction(owner.owner) ? owner.owner() : null
}
return templateCompiler
},
_renderCore: function(data, index, $container) {
var compiledTemplate = this._compiledTemplate,
result = $.isFunction(compiledTemplate) ? compiledTemplate(data, index, $container) : compiledTemplate;
return result
},
setCompiler: function(templateCompiler) {
if (!templateCompiler)
return;
this._compiledTemplate = templateCompiler(DX.utils.normalizeTemplateElement(this._element))
}
});
var NgTemplateProvider = new(ui.TemplateProviderBase.inherit({
createTemplate: function(element, owner) {
return new NgTemplate(element, owner)
},
getTemplates: function(widget) {
var templateCompiler = widget.option("templateCompiler"),
templates = this.callBase.apply(this, arguments);
$.each(templates, function(_, template) {
template.setCompiler(templateCompiler)
});
return templates
},
_templatesForWidget: function(widgetName) {
var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},
templates = {};
$.each(templateGenerators, function(name, generator) {
var $markup = DX.utils.createMarkupFromString(generator());
templates[name] = new NgTemplate($markup.wrap(), NgTemplateProvider)
});
return templates
}
}));
var baseElements = {
container: function() {
return $("
").addClass(TEMPLATE_WRAPPER_CLASS)
},
html: function() {
return $("
").attr("ng-if", "html").attr("ng-bind-html", "html")
},
text: function() {
return $("
").attr("ng-if", "text").attr("ng-bind", "text")
},
primitive: function() {
return $("
").attr("ng-if", "scopeValue").attr("ng-bind-html", "'' + scopeValue")
}
};
var TEMPLATE_GENERATORS = {};
var emptyTemplate = function() {
return $()
};
TEMPLATE_GENERATORS.CollectionWidget = {
item: function() {
return baseElements.container().append(baseElements.html()).append(baseElements.text()).append(baseElements.primitive())
},
itemFrame: function() {
var $container = $("
").attr("ng-class", "{ 'dx-state-invisible': !visible && visible != undefined, 'dx-state-disabled': !!disabled }"),
$placeholder = $("
").addClass("dx-item-content-placeholder");
$container.append($placeholder);
return $container
}
};
var BUTTON_TEXT_CLASS = "dx-button-text";
TEMPLATE_GENERATORS.dxButton = {content: function() {
var $titleBinding = $("
").attr("ng-bind", "text").attr("ng-class", "{ '" + BUTTON_TEXT_CLASS + "' : !!text }"),
icon = $("");
return baseElements.container().append(icon).append($titleBinding).append(baseElements.primitive())
}};
var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",
LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",
BADGE_CLASS = "dx-badge",
LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",
LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";
TEMPLATE_GENERATORS.dxList = {
item: function() {
return TEMPLATE_GENERATORS.CollectionWidget.item().append($("").attr("ng-if", "key").attr("ng-bind", "key"))
},
itemFrame: function() {
var $badgeContainer = $("
").addClass(LIST_ITEM_BADGE_CONTAINER_CLASS).attr("ng-if", "badge"),
$badge = $("
").addClass(LIST_ITEM_BADGE_CLASS).addClass(BADGE_CLASS).attr("ng-bind", "badge");
var $chevronContainer = $("
").addClass(LIST_ITEM_CHEVRON_CONTAINER_CLASS).attr("ng-if", "showChevron"),
$chevron = $("
").addClass(LIST_ITEM_CHEVRON_CLASS);
return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badgeContainer.append($badge)).append($chevronContainer.append($chevron))
},
group: function() {
var $keyBinding = $("
").attr("ng-if", "key").attr("ng-bind", "key");
return baseElements.container().append($keyBinding).append(baseElements.primitive())
}
};
TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};
TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};
TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};
TEMPLATE_GENERATORS.dxScheduler = {item: function() {
var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item();
var $details = $("
").addClass("dx-scheduler-appointment-content-details");
$("
").attr("ng-if", "startDate").text("{{startDate | date : 'shortTime' }}").appendTo($details);
$("").attr("ng-if", "endDate").text(" - {{endDate | date : 'shortTime' }}").appendTo($details);
$details.appendTo($itemContent);
$("").attr("ng-if", "recurrenceRule").addClass("dx-scheduler-appointment-recurrence-icon").appendTo($itemContent);
return $itemContent
}};
TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};
TEMPLATE_GENERATORS.dxSlideOutView = {
menu: emptyTemplate,
content: emptyTemplate
};
TEMPLATE_GENERATORS.dxSlideOut = {
menuItem: TEMPLATE_GENERATORS.dxList.item,
menuGroup: TEMPLATE_GENERATORS.dxList.group,
content: emptyTemplate
};
TEMPLATE_GENERATORS.dxAccordion = {
title: function() {
var $titleBinding = $("").attr("ng-if", "title").attr("ng-bind", "title"),
icon = $("");
return baseElements.container().append(icon).append($titleBinding).append(baseElements.primitive())
},
content: TEMPLATE_GENERATORS.CollectionWidget.item
};
TEMPLATE_GENERATORS.dxPivotTabs = {item: function() {
return baseElements.container().append($("").attr("ng-if", "title").attr("ng-bind", "title")).append(baseElements.primitive())
}};
TEMPLATE_GENERATORS.dxPivot = {
title: TEMPLATE_GENERATORS.dxPivotTabs.item,
content: emptyTemplate
};
var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";
TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function() {
return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().prepend($("").addClass(PANORAMA_ITEM_TITLE_CLASS).attr("ng-if", "title").attr("ng-bind", "title"))
}};
TEMPLATE_GENERATORS.dxActionSheet = {item: function() {
return baseElements.container().append($("
").attr("dx-button", "{ bindingOptions: { text: 'text', onClick: 'onClick', type: 'type', disabled: 'disabled' } }"))
}};
TEMPLATE_GENERATORS.dxToolbar = {
item: function() {
var template = TEMPLATE_GENERATORS.CollectionWidget.item();
$.each(["button", "tabs", "dropDownMenu"], function(i, widgetName) {
var bindingName = "dx-" + DX.inflector.dasherize(this);
$("
").attr("ng-if", "widget === '" + widgetName + "'").attr(bindingName, "options").appendTo(template)
});
return template
},
menuItem: TEMPLATE_GENERATORS.dxList.item,
actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item
};
TEMPLATE_GENERATORS.dxGallery = {item: function() {
return baseElements.container().append(baseElements.html()).append(baseElements.text()).append($("
").attr("ng-if", "scopeValue").attr("ng-src", "{{'' + scopeValue}}")).append($("
").attr("ng-if", "imageSrc").attr("ng-src", "{{imageSrc}}"))
}};
var TABS_ITEM_TEXT_CLASS = "dx-tab-text";
TEMPLATE_GENERATORS.dxTabs = {
item: function() {
var container = baseElements.container();
var text = $("
").addClass(TABS_ITEM_TEXT_CLASS).attr("ng-bind", "text").attr("ng-if", "text"),
icon = $("");
return container.append(baseElements.html()).append(icon).append(text).append(baseElements.primitive().addClass(TABS_ITEM_TEXT_CLASS))
},
itemFrame: function() {
var $badge = $("").addClass("dx-tabs-item-badge dx-badge").attr("ng-bind", "badge").attr("ng-if", "badge");
return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badge)
}
};
var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";
TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function() {
var $badge = $("
").addClass(NAVBAR_ITEM_BADGE_CLASS).addClass(BADGE_CLASS).attr("ng-if", "badge").attr("ng-bind", "badge");
return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badge)
}};
TEMPLATE_GENERATORS.dxMenuBase = {item: function() {
var container = baseElements.container();
var text = $("
").attr("ng-if", "text").addClass("dx-menu-item-text").attr("ng-bind", "text"),
icon = $(""),
popout = $("").addClass("dx-menu-item-popout-container").attr("ng-if", "items").append($("").addClass("dx-menu-item-popout"));
container.append(baseElements.html()).append(icon).append(text).append(popout).append(baseElements.primitive()).appendTo(container);
return container
}};
TEMPLATE_GENERATORS.dxTreeView = {item: function() {
var content = baseElements.container(),
link = $("
").attr("ng-bind", "text"),
icon = $("
");
content.append(baseElements.html()).append(icon).append(link).append(baseElements.primitive());
return content
}};
TEMPLATE_GENERATORS.dxTabPanel = {
item: TEMPLATE_GENERATORS.CollectionWidget.item,
title: function() {
var content = TEMPLATE_GENERATORS.dxTabs.item();
content.find(".dx-tab-text").eq(0).attr("ng-bind", "title").attr("ng-if", "title");
return content
}
};
var popupTitleAndBottom = function() {
return $("").attr("dx-toolbar", "{ bindingOptions: { items: 'scopeValue' } }")
};
TEMPLATE_GENERATORS.dxPopup = {
title: popupTitleAndBottom,
bottom: popupTitleAndBottom
};
TEMPLATE_GENERATORS.dxLookup = {
title: TEMPLATE_GENERATORS.dxPopup.title,
group: TEMPLATE_GENERATORS.dxList.group
};
TEMPLATE_GENERATORS.dxTagBox = {tag: function() {
return $("
").append($("
").attr("ng-bind", "scopeValue"))
}};
TEMPLATE_GENERATORS.dxCalendar = {cell: function() {
var $cell = $("").attr("ng-if", "text").attr("ng-bind", "text");
return baseElements.container().append($cell).append(baseElements.primitive())
}};
$.extend(ui, {
NgTemplate: NgTemplate,
NgTemplateProvider: NgTemplateProvider
})
})(jQuery, DevExpress);
/*! Module core, file ko.validation.js */
(function($, DX, undefined) {
if (!DX.support.hasKo)
return;
var ko = window.ko;
var koDxValidator = DX.Class.inherit({
ctor: function(target, option) {
var that = this;
that.target = target;
that.validationRules = option.validationRules;
that.name = option.name;
that.isValid = ko.observable(true);
that.validationError = ko.observable();
$.each(this.validationRules, function(_, rule) {
rule.validator = that
})
},
validate: function() {
var result = DevExpress.validationEngine.validate(this.target(), this.validationRules, this.name);
this._applyValidationResult(result);
return result
},
reset: function() {
this.target(null);
var result = {
isValid: true,
brokenRule: null
};
this._applyValidationResult(result);
return result
},
_applyValidationResult: function(result) {
result.validator = this;
this.target.dxValidator.isValid(result.isValid);
this.target.dxValidator.validationError(result.brokenRule);
this.fireEvent("validated", [result])
}
}).include(DX.EventsMixin);
ko.extenders.dxValidator = function(target, option) {
target.dxValidator = new koDxValidator(target, option);
target.subscribe($.proxy(target.dxValidator.validate, target.dxValidator));
return target
};
DevExpress.validationEngine.registerModelForValidation = function(model) {
$.each(model, function(name, member) {
if (ko.isObservable(member) && member.dxValidator)
DevExpress.validationEngine.registerValidatorInGroup(model, member.dxValidator)
})
};
DevExpress.validationEngine.validateModel = DevExpress.validationEngine.validateGroup
})(jQuery, DevExpress);
/*! Module core, file ui.themes.js */
(function($, DX, undefined) {
var DX_LINK_SELECTOR = "link[rel=dx-theme]",
THEME_ATTR = "data-theme",
ACTIVE_ATTR = "data-active";
var context,
$activeThemeLink,
knownThemes,
currentThemeName,
pendingThemeName;
var THEME_MARKER_PREFIX = "dx.";
function readThemeMarker() {
var element = $("
", context).addClass("dx-theme-marker").appendTo(context.documentElement),
result;
try {
result = element.css("font-family");
if (!result)
return null;
result = result.replace(/["']/g, "");
if (result.substr(0, THEME_MARKER_PREFIX.length) !== THEME_MARKER_PREFIX)
return null;
return result.substr(THEME_MARKER_PREFIX.length)
}
finally {
element.remove()
}
}
function waitForThemeLoad(themeName, callback) {
var timerId,
waitStartTime;
pendingThemeName = themeName;
function handleLoaded() {
pendingThemeName = null;
callback()
}
if (isPendingThemeLoaded())
handleLoaded();
else {
waitStartTime = $.now();
timerId = setInterval(function() {
var isLoaded = isPendingThemeLoaded(),
isTimeout = !isLoaded && $.now() - waitStartTime > 15 * 1000;
if (isTimeout)
DX.log("W0004", pendingThemeName);
if (isLoaded || isTimeout) {
clearInterval(timerId);
handleLoaded()
}
}, 10)
}
}
function isPendingThemeLoaded() {
return !pendingThemeName || readThemeMarker() === pendingThemeName
}
function processMarkup() {
var $allThemeLinks = $(DX_LINK_SELECTOR, context);
if (!$allThemeLinks.length)
return;
knownThemes = {};
$activeThemeLink = $(DX.utils.createMarkupFromString(" "), context);
$allThemeLinks.each(function() {
var link = $(this, context),
fullThemeName = link.attr(THEME_ATTR),
url = link.attr("href"),
isActive = link.attr(ACTIVE_ATTR) === "true";
knownThemes[fullThemeName] = {
url: url,
isActive: isActive
}
});
$allThemeLinks.last().after($activeThemeLink);
$allThemeLinks.remove()
}
function resolveFullThemeName(desiredThemeName) {
var desiredThemeParts = desiredThemeName.split("."),
result = null;
if (knownThemes)
$.each(knownThemes, function(knownThemeName, themeData) {
var knownThemeParts = knownThemeName.split(".");
if (knownThemeParts[0] !== desiredThemeParts[0])
return;
if (desiredThemeParts[1] && desiredThemeParts[1] !== knownThemeParts[1])
return;
if (desiredThemeParts[2] && desiredThemeParts[2] !== knownThemeParts[2])
return;
if (!result || themeData.isActive)
result = knownThemeName;
if (themeData.isActive)
return false
});
return result
}
function initContext(newContext) {
try {
if (newContext !== context)
knownThemes = null
}
catch(x) {
knownThemes = null
}
context = newContext
}
function init(options) {
options = options || {};
initContext(options.context || document);
processMarkup();
currentThemeName = undefined;
current(options)
}
function current(options) {
if (!arguments.length)
return currentThemeName || readThemeMarker();
detachCssClasses(DX.viewPort(), currentThemeName);
options = options || {};
if (typeof options === "string")
options = {theme: options};
var isAutoInit = options._autoInit,
loadCallback = options.loadCallback,
currentThemeData;
currentThemeName = options.theme || currentThemeName;
if (isAutoInit && !currentThemeName)
currentThemeName = themeNameFromDevice(DX.devices.current());
currentThemeName = resolveFullThemeName(currentThemeName);
if (currentThemeName)
currentThemeData = knownThemes[currentThemeName];
if (currentThemeData) {
$activeThemeLink.attr("href", knownThemes[currentThemeName].url);
if (loadCallback)
waitForThemeLoad(currentThemeName, loadCallback);
else if (pendingThemeName)
pendingThemeName = currentThemeName
}
else if (isAutoInit) {
if (loadCallback)
loadCallback()
}
else
throw DX.Error("E0021", currentThemeName);
attachCssClasses(DX.viewPort(), currentThemeName)
}
function themeNameFromDevice(device) {
var themeName = device.platform;
if (themeName === "ios")
themeName += "7";
if (themeName === "android")
themeName += "5";
return themeName
}
function getCssClasses(themeName) {
themeName = themeName || current();
var result = [],
themeNameParts = themeName && themeName.split(".");
if (themeNameParts) {
result.push("dx-theme-" + themeNameParts[0], "dx-theme-" + themeNameParts[0] + "-typography");
if (themeNameParts.length > 1)
result.push("dx-color-scheme-" + themeNameParts[1])
}
return result
}
var themeClasses;
function attachCssClasses(element, themeName) {
themeClasses = getCssClasses(themeName).join(" ");
$(element).addClass(themeClasses)
}
function detachCssClasses(element, themeName) {
$(element).removeClass(themeClasses)
}
$.holdReady(true);
init({
_autoInit: true,
loadCallback: function() {
$.holdReady(false)
}
});
$(function() {
if ($(DX_LINK_SELECTOR, context).length)
throw DX.Error("E0022");
});
DX.viewPortChanged.add(function(viewPort, prevViewPort) {
detachCssClasses(prevViewPort);
attachCssClasses(viewPort)
});
DX.ui.themes = {
init: init,
current: current,
attachCssClasses: attachCssClasses,
detachCssClasses: detachCssClasses
};
DX.ui.themes.__internals = {
themeNameFromDevice: themeNameFromDevice,
waitForThemeLoad: waitForThemeLoad,
resetTheme: function() {
$activeThemeLink.attr("href", "about:blank");
currentThemeName = null;
pendingThemeName = null
}
}
})(jQuery, DevExpress);
/*! Module core, file ui.events.js */
(function($, DX, undefined) {
var ui = DX.ui,
eventNS = $.event,
hooksNS = eventNS.fixHooks,
specialNS = eventNS.special,
EVENT_SOURCES_REGEX = {
dx: /^dx/i,
mouse: /(mouse|wheel)/i,
touch: /^touch/i,
keyboard: /^key/i,
pointer: /^(ms)?pointer/i
};
var eventSource = function(e) {
var result = "other";
$.each(EVENT_SOURCES_REGEX, function(key) {
if (this.test(e.type)) {
result = key;
return false
}
});
return result
};
var isDxEvent = function(e) {
return eventSource(e) === "dx"
};
var isNativeMouseEvent = function(e) {
return eventSource(e) === "mouse"
};
var isNativeTouchEvent = function(e) {
return eventSource(e) === "touch"
};
var isPointerEvent = function(e) {
return eventSource(e) === "pointer"
};
var isMouseEvent = function(e) {
return isNativeMouseEvent(e) || (isPointerEvent(e) || isDxEvent(e)) && e.pointerType === "mouse"
};
var isTouchEvent = function(e) {
return isNativeTouchEvent(e) || (isPointerEvent(e) || isDxEvent(e)) && e.pointerType === "touch"
};
var isKeyboardEvent = function(e) {
return eventSource(e) === "keyboard"
};
var eventData = function(e) {
return {
x: e.pageX,
y: e.pageY,
time: e.timeStamp
}
};
var eventDelta = function(from, to) {
return {
x: to.x - from.x,
y: to.y - from.y,
time: to.time - from.time || 1
}
};
var hasTouches = function(e) {
if (isNativeTouchEvent(e))
return (e.originalEvent.touches || []).length;
if (isDxEvent(e))
return (e.pointers || []).length;
return 0
};
var needSkipEvent = function(e) {
var $target = $(e.target),
touchInInput = $target.is("input, textarea, select");
if (e.type === 'dxmousewheel')
return $target.is("input[type='number'], textarea, select") && $target.is(':focus');
if (isMouseEvent(e))
return touchInInput || e.which > 1;
if (isTouchEvent(e))
return touchInInput && $target.is(":focus")
};
var createEvent = function(originalEvent, args) {
var event = $.Event(originalEvent),
fixHook = hooksNS[originalEvent.type] || eventNS.mouseHooks;
var props = fixHook.props ? eventNS.props.concat(fixHook.props) : eventNS.props,
propIndex = props.length;
while (propIndex--) {
var prop = props[propIndex];
event[prop] = originalEvent[prop]
}
if (args)
$.extend(event, args);
return fixHook.filter ? fixHook.filter(event, originalEvent) : event
};
var fireEvent = function(props) {
var event = createEvent(props.originalEvent, props);
eventNS.trigger(event, null, props.delegateTarget || event.target);
return event
};
var addNamespace = function(eventNames, namespace) {
if (!namespace)
throw DX.Error("E0017");
if (typeof eventNames === "string")
return addNamespace(eventNames.split(/\s+/g), namespace);
$.each(eventNames, function(index, eventName) {
eventNames[index] = eventName + "." + namespace
});
return eventNames.join(" ")
};
var dxEventHook = {props: eventNS.mouseHooks.props.concat(["pointerType", "pointerId", "pointers"])};
var registerEvent = function(eventName, eventObject) {
var strategy = {};
if ("noBubble" in eventObject)
strategy.noBubble = eventObject.noBubble;
if ("bindType" in eventObject)
strategy.bindType = eventObject.bindType;
if ("delegateType" in eventObject)
strategy.delegateType = eventObject.delegateType;
$.each(["setup", "teardown", "add", "remove", "trigger", "handle", "_default", "dispose"], function(_, methodName) {
if (!eventObject[methodName])
return;
strategy[methodName] = function() {
var args = $.makeArray(arguments);
args.unshift(this);
return eventObject[methodName].apply(eventObject, args)
}
});
hooksNS[eventName] = dxEventHook;
specialNS[eventName] = strategy
};
ui.events = {
eventSource: eventSource,
isPointerEvent: isPointerEvent,
isMouseEvent: isMouseEvent,
isTouchEvent: isTouchEvent,
isKeyboardEvent: isKeyboardEvent,
hasTouches: hasTouches,
eventData: eventData,
eventDelta: eventDelta,
needSkipEvent: needSkipEvent,
createEvent: createEvent,
fireEvent: fireEvent,
addNamespace: addNamespace,
registerEvent: registerEvent
}
})(jQuery, DevExpress);
/*! Module core, file ko.events.js */
(function($, DX, undefined) {
if (!DX.support.hasKo)
return;
var ko = window.ko,
events = DX.ui.events;
var originalRegisterEvent = events.registerEvent;
var registerKoEvent = function(eventName, eventObject) {
originalRegisterEvent(eventName, eventObject);
var koBindingEventName = events.addNamespace(eventName, eventName + "Binding");
ko.bindingHandlers[eventName] = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var $element = $(element),
unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
eventSource = unwrappedValue.execute ? unwrappedValue.execute : unwrappedValue;
$element.off(koBindingEventName).on(koBindingEventName, $.isPlainObject(unwrappedValue) ? unwrappedValue : {}, function(e) {
eventSource.call(viewModel, viewModel, e)
})
}}
};
$.extend(events, {registerEvent: registerKoEvent})
})(jQuery, DevExpress);
/*! Module core, file ng.events.js */
(function($, DX, undefined) {
if (!DX.support.hasNg)
return;
var events = DX.ui.events;
var originalRegisterEvent = events.registerEvent;
var registerNgEvent = function(eventName, eventObject) {
originalRegisterEvent(eventName, eventObject);
var ngEventName = eventName.slice(0, 2) + eventName.charAt(2).toUpperCase() + eventName.slice(3);
DX.ng.module.directive(ngEventName, ['$parse', function($parse) {
return function(scope, element, attr) {
var attrValue = $.trim(attr[ngEventName]),
handler,
eventOptions = {};
if (attrValue.charAt(0) === "{") {
eventOptions = scope.$eval(attrValue);
handler = $parse(eventOptions.execute)
}
else
handler = $parse(attr[ngEventName]);
element.on(eventName, eventOptions, function(e) {
scope.$apply(function() {
handler(scope, {$event: e})
})
})
}
}])
};
$.extend(events, {registerEvent: registerNgEvent})
})(jQuery, DevExpress);
/*! Module core, file ui.keyboardProcessor.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
ui.KeyboardProcessor = DX.Class.inherit({
_keydown: events.addNamespace("keydown", "KeyboardProcessor"),
codes: {
"8": "backspace",
"9": "tab",
"13": "enter",
"27": "escape",
"33": "pageUp",
"34": "pageDown",
"35": "end",
"36": "home",
"37": "leftArrow",
"38": "upArrow",
"39": "rightArrow",
"40": "downArrow",
"46": "del",
"32": "space",
"70": "F",
"65": "A",
"106": "asterisk",
"109": "minus"
},
ctor: function(options) {
var _this = this;
options = options || {};
if (options.element)
this._element = $(options.element);
if (options.focusTarget)
this._focusTarget = options.focusTarget;
this._handler = options.handler;
this._context = options.context;
this._childProcessors = [];
if (this._element)
this._element.on(this._keydown, function(e) {
_this.process(e)
})
},
dispose: function() {
if (this._element)
this._element.off(this._keydown);
this._element = undefined;
this._handler = undefined;
this._context = undefined;
this._childProcessors = undefined
},
clearChildren: function() {
this._childProcessors = []
},
push: function(child) {
if (!this._childProcessors)
this.clearChildren();
this._childProcessors.push(child);
return child
},
attachChildProcessor: function() {
var childProcessor = new ui.KeyboardProcessor;
this._childProcessors.push(childProcessor);
return childProcessor
},
reinitialize: function(childHandler, childContext) {
this._context = childContext;
this._handler = childHandler;
return this
},
process: function(e) {
if (this._focusTarget && this._focusTarget !== e.target && $.inArray(e.target, this._focusTarget) < 0)
return false;
var args = {
key: this.codes[e.which] || e.which,
ctrl: e.ctrlKey,
shift: e.shiftKey,
alt: e.altKey,
originalEvent: e
};
var handlerResult = this._handler && this._handler.call(this._context, args);
if (handlerResult && this._childProcessors)
$.each(this._childProcessors, function(index, childProcessor) {
childProcessor.process(e)
})
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.dialog.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils;
var DEFAULT_BUTTON = {
text: "OK",
onClick: function() {
return true
}
};
var DX_DIALOG_CLASSNAME = "dx-dialog",
DX_DIALOG_WRAPPER_CLASSNAME = DX_DIALOG_CLASSNAME + "-wrapper",
DX_DIALOG_ROOT_CLASSNAME = DX_DIALOG_CLASSNAME + "-root",
DX_DIALOG_CONTENT_CLASSNAME = DX_DIALOG_CLASSNAME + "-content",
DX_DIALOG_MESSAGE_CLASSNAME = DX_DIALOG_CLASSNAME + "-message",
DX_DIALOG_BUTTONS_CLASSNAME = DX_DIALOG_CLASSNAME + "-buttons",
DX_DIALOG_BUTTON_CLASSNAME = DX_DIALOG_CLASSNAME + "-button";
var FakeDialogComponent = DX.Component.inherit({
NAME: "dxDialog",
ctor: function(element, options) {
this.callBase(options)
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: {platform: "ios"},
options: {width: 276}
}, {
device: {platform: "android"},
options: {
lWidth: "60%",
pWidth: "80%"
}
}, {
device: {
platform: "win8",
phone: false
},
options: {width: function() {
return $(window).width()
}}
}, {
device: {
platform: "win8",
phone: true
},
options: {position: {
my: "top center",
at: "top center",
of: window,
offset: "0 0"
}}
}])
}
});
var dialog = function(options) {
if (!ui.dxPopup)
throw DX.Error("E0018");
var deferred = $.Deferred();
var defaultOptions = (new FakeDialogComponent).option();
options = $.extend(defaultOptions, options);
var $element = $("").addClass(DX_DIALOG_CLASSNAME).appendTo(DX.viewPort());
var $message = $("
").addClass(DX_DIALOG_MESSAGE_CLASSNAME).html(String(options.message));
var popupButtons = [];
$.each(options.buttons || [DEFAULT_BUTTON], function() {
if (this.clickAction) {
DX.log("W0001", "Dialog", "clickAction", "14.2", "Use 'onClick' option instead");
this.onClick = this.clickAction
}
var action = new DX.Action(this.onClick || this.clickAction, {context: popupInstance});
popupButtons.push({
toolbar: 'bottom',
location: 'center',
widget: 'button',
options: {
text: this.text,
onClick: function() {
var result = action.execute(arguments);
hide(result)
}
}
})
});
var popupInstance = $element.dxPopup({
title: options.title || this.title,
showTitle: function() {
var isTitle = options.showTitle === undefined ? true : options.showTitle;
return isTitle
}(),
height: "auto",
width: function() {
var isPortrait = $(window).height() > $(window).width(),
key = (isPortrait ? "p" : "l") + "Width",
widthOption = options.hasOwnProperty(key) ? options[key] : options["width"];
return $.isFunction(widthOption) ? widthOption() : widthOption
},
showCloseButton: false,
focusStateEnabled: false,
onContentReady: function(args) {
args.component.content().addClass(DX_DIALOG_CONTENT_CLASSNAME).append($message)
},
onShowing: function(e) {
e.component.bottomToolbar().addClass(DX_DIALOG_BUTTONS_CLASSNAME).find(".dx-button").addClass(DX_DIALOG_BUTTON_CLASSNAME).first().focus()
},
buttons: popupButtons,
animation: {
show: {
type: "pop",
duration: 400
},
hide: {
type: "pop",
duration: 400,
to: {
opacity: 0,
scale: 0
},
from: {
opacity: 1,
scale: 1
}
}
},
rtlEnabled: DX.rtlEnabled,
boundaryOffset: {
h: 10,
v: 0
}
}).dxPopup("instance");
popupInstance._wrapper().addClass(DX_DIALOG_WRAPPER_CLASSNAME);
if (options.position)
popupInstance.option("position", options.position);
popupInstance._wrapper().addClass(DX_DIALOG_ROOT_CLASSNAME);
function show() {
popupInstance.show();
utils.resetActiveElement();
return deferred.promise()
}
function hide(value) {
popupInstance.hide().done(function() {
popupInstance.element().remove()
});
deferred.resolve(value)
}
return {
show: show,
hide: hide
}
};
var alert = function(message, title, showTitle) {
var dialogInstance,
options = $.isPlainObject(message) ? message : {
title: title,
message: message,
showTitle: showTitle
};
dialogInstance = ui.dialog.custom(options);
return dialogInstance.show()
};
var confirm = function(message, title, showTitle) {
var dialogInstance,
options = $.isPlainObject(message) ? message : {
title: title,
message: message,
showTitle: showTitle,
buttons: [{
text: Globalize.localize("Yes"),
onClick: function() {
return true
}
}, {
text: Globalize.localize("No"),
onClick: function() {
return false
}
}]
};
dialogInstance = ui.dialog.custom(options);
return dialogInstance.show()
};
var $notify = null;
var notify = function(message, type, displayTime) {
var options = $.isPlainObject(message) ? message : {message: message};
if (!ui.dxToast) {
alert(options.message);
return
}
if (options.hiddenAction) {
DX.log("W0001", "Dialog", "hiddenAction", "14.2", "Use 'onHidden' option instead");
options.onHidden = options.hiddenAction
}
var userHiddenAction = options.onHidden;
$.extend(options, {
type: type,
displayTime: displayTime,
onHidden: function(args) {
args.element.remove();
new DX.Action(userHiddenAction, {context: args.model}).execute(arguments)
}
});
$notify = $("
").appendTo(DX.viewPort()).dxToast(options);
$notify.dxToast("instance").show()
};
$.extend(ui, {
notify: notify,
dialog: {
custom: dialog,
alert: alert,
confirm: confirm
}
});
ui.dialog.FakeDialogComponent = FakeDialogComponent
})(jQuery, DevExpress);
/*! Module core, file ui.dataHelper.js */
(function($, DX, undefined) {
var data = DX.data;
var DATA_SOURCE_OPTIONS_METHOD = "_dataSourceOptions",
DATA_SOURCE_CHANGED_METHOD = "_dataSourceChangedHandler",
DATA_SOURCE_LOAD_ERROR_METHOD = "_dataSourceLoadErrorHandler",
DATA_SOURCE_LOADING_CHANGED_METHOD = "_dataSourceLoadingChangedHandler";
DX.ui.DataHelperMixin = {
postCtor: function() {
this.on("disposing", function() {
this._disposeDataSource()
})
},
_isDataSourceReady: function() {
return !this._dataSource || this._dataSource.isLoaded()
},
_refreshDataSource: function() {
this._initDataSource();
this._loadDataSource()
},
_initDataSource: function() {
var dataSourceOptions = this.option("dataSource"),
widgetDataSourceOptions,
dataSourceType;
this._disposeDataSource();
if (dataSourceOptions) {
if (dataSourceOptions instanceof data.DataSource) {
this._isSharedDataSource = true;
this._dataSource = dataSourceOptions
}
else {
widgetDataSourceOptions = DATA_SOURCE_OPTIONS_METHOD in this ? this[DATA_SOURCE_OPTIONS_METHOD]() : {};
dataSourceType = this._dataSourceType ? this._dataSourceType() : data.DataSource;
this._dataSource = new dataSourceType($.extend(true, {}, widgetDataSourceOptions, data.utils.normalizeDataSourceOptions(dataSourceOptions)))
}
this._addDataSourceHandlers()
}
},
_addDataSourceHandlers: function() {
if (DATA_SOURCE_CHANGED_METHOD in this)
this._addDataSourceChangeHandler();
if (DATA_SOURCE_LOAD_ERROR_METHOD in this)
this._addDataSourceLoadErrorHandler();
if (DATA_SOURCE_LOADING_CHANGED_METHOD in this)
this._addDataSourceLoadingChangedHandler();
this._addReadyWatcher()
},
_addReadyWatcher: function() {
this._dataSource.on("loadingChanged", $.proxy(function(isLoading) {
this._ready && this._ready(!isLoading)
}, this))
},
_addDataSourceChangeHandler: function() {
var dataSource = this._dataSource;
this._proxiedDataSourceChangedHandler = $.proxy(function() {
this[DATA_SOURCE_CHANGED_METHOD](dataSource.items())
}, this);
dataSource.on("changed", this._proxiedDataSourceChangedHandler)
},
_addDataSourceLoadErrorHandler: function() {
this._proxiedDataSourceLoadErrorHandler = $.proxy(this[DATA_SOURCE_LOAD_ERROR_METHOD], this);
this._dataSource.on("loadError", this._proxiedDataSourceLoadErrorHandler)
},
_addDataSourceLoadingChangedHandler: function() {
this._proxiedDataSourceLoadingChangedHandler = $.proxy(this[DATA_SOURCE_LOADING_CHANGED_METHOD], this);
this._dataSource.on("loadingChanged", this._proxiedDataSourceLoadingChangedHandler)
},
_loadDataSource: function() {
if (this._dataSource) {
var dataSource = this._dataSource;
if (dataSource.isLoaded())
this._proxiedDataSourceChangedHandler && this._proxiedDataSourceChangedHandler();
else
dataSource.load()
}
},
_loadSingle: function(key, value) {
key = key === "this" ? this._dataSource.key() || "this" : key;
return this._dataSource.loadSingle(key, value)
},
_isLastPage: function() {
return !this._dataSource || this._dataSource.isLastPage() || !this._dataSource._pageSize
},
_isDataSourceLoading: function() {
return this._dataSource && this._dataSource.isLoading()
},
_disposeDataSource: function() {
if (this._dataSource) {
if (this._isSharedDataSource) {
delete this._isSharedDataSource;
this._proxiedDataSourceChangedHandler && this._dataSource.off("changed", this._proxiedDataSourceChangedHandler);
this._proxiedDataSourceLoadErrorHandler && this._dataSource.off("loadError", this._proxiedDataSourceLoadErrorHandler);
this._proxiedDataSourceLoadingChangedHandler && this._dataSource.off("loadingChanged", this._proxiedDataSourceLoadingChangedHandler)
}
else
this._dataSource.dispose();
delete this._dataSource;
delete this._proxiedDataSourceChangedHandler;
delete this._proxiedDataSourceLoadErrorHandler;
delete this._proxiedDataSourceLoadingChangedHandler
}
}
}
})(jQuery, DevExpress);
/*! Module core, file ui.dataExpression.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
dataUtils = DX.data.utils;
ui.DataExpressionMixin = $.extend(ui.DataHelperMixin, {
_dataExpressionDeprecatedOptions: function() {
return {itemRender: {
since: "14.2",
alias: "itemTemplate"
}}
},
_dataExpressionDefaultOptions: function() {
return {
items: [],
dataSource: null,
itemTemplate: "item",
value: null,
valueExpr: "this",
displayExpr: undefined
}
},
_initDataExpressions: function() {
this._compileValueGetter();
this._compileDisplayGetter();
this._initDynamicTemplates();
this._initDataSource();
this._itemsToDataSource()
},
_itemsToDataSource: function() {
if (!this.option("dataSource"))
this._dataSource = new DevExpress.data.DataSource({
store: new DevExpress.data.ArrayStore(this.option("items")),
pageSize: 0
})
},
_compileDisplayGetter: function() {
this._displayGetter = dataUtils.compileGetter(this._displayGetterExpr())
},
_displayGetterExpr: function() {
return this.option("displayExpr")
},
_compileValueGetter: function() {
this._valueGetter = dataUtils.compileGetter(this._valueGetterExpr())
},
_valueGetterExpr: function() {
return this.option("valueExpr") || "this"
},
_loadValue: function(value) {
var deferred = $.Deferred();
value = this._unwrappedValue(value);
if (!utils.isDefined(value))
return deferred.reject().promise();
this._loadSingle(this._valueGetterExpr(), value).done($.proxy(function(item) {
this._isValueEquals(this._valueGetter(item), value) ? deferred.resolve(item) : deferred.reject()
}, this)).fail(function() {
deferred.reject()
});
return deferred.promise()
},
_unwrappedValue: function(value) {
value = DX.utils.isDefined(value) ? value : this.option("value");
if (value && this._dataSource && this._valueGetterExpr() === "this") {
var key = this._dataSource.key();
if (key && typeof value === "object")
value = value[key]
}
return utils.unwrapObservable(value)
},
_isValueEquals: function(value1, value2) {
var isDefined = utils.isDefined;
var ensureDefined = utils.ensureDefined;
var unwrapObservable = utils.unwrapObservable;
var dataSourceKey = this._dataSource && this._dataSource.key();
var result = this._compareValues(value1, value2);
if (!result && isDefined(value1) && isDefined(value2) && dataSourceKey) {
var valueKey1 = ensureDefined(unwrapObservable(value1[dataSourceKey]), value1);
var valueKey2 = ensureDefined(unwrapObservable(value2[dataSourceKey]), value2);
result = this._compareValues(valueKey1, valueKey2)
}
return result
},
_compareValues: function(value1, value2) {
return dataUtils.toComparable(value1) === dataUtils.toComparable(value2)
},
_initDynamicTemplates: function() {
if (this._displayGetterExpr())
this._dynamicTemplates["item"] = new ui.DefaultTemplate($.proxy(function(data) {
return this._displayGetter(data)
}, this));
else
delete this._dynamicTemplates["item"]
},
_setCollectionWidgetItemTemplate: function() {
this._initDynamicTemplates();
this._setCollectionWidgetOption("itemTemplate", this._getTemplateByOption("itemTemplate"))
},
_dataExpressionOptionChanged: function(args) {
switch (args.name) {
case"items":
this._itemsToDataSource();
this._setCollectionWidgetOption("items");
break;
case"dataSource":
this._initDataSource();
break;
case"itemTemplate":
this._setCollectionWidgetItemTemplate();
break;
case"valueExpr":
this._compileValueGetter();
break;
case"displayExpr":
this._compileDisplayGetter();
this._setCollectionWidgetItemTemplate();
break
}
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.touchHooks.js */
(function($, DX, undefined) {
var touchEventHook = {
filter: function(event, originalEvent) {
var touches = originalEvent.touches.length ? originalEvent.touches : originalEvent.changedTouches;
$.each(["pageX", "pageY", "screenX", "screenY", "clientX", "clientY"], function() {
event[this] = touches[0][this]
});
return event
},
props: $.event.mouseHooks.props.concat(["touches", "changedTouches", "targetTouches", "detail", "result", "originalTarget", "charCode", "prevValue"])
};
$.each(["touchstart", "touchmove", "touchend", "touchcancel"], function() {
$.event.fixHooks[this] = touchEventHook
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.mspointerHooks.js */
(function($, DX, undefined) {
var POINTER_TYPE_MAP = {
2: "touch",
3: "pen",
4: "mouse"
};
var pointerEventHook = {
filter: function(event, originalEvent) {
var pointerType = originalEvent.pointerType;
if ($.isNumeric(pointerType))
event.pointerType = POINTER_TYPE_MAP[pointerType];
return event
},
props: $.event.mouseHooks.props.concat(["pointerId", "pointerType", "originalTarget", "width", "height", "pressure", "result", "tiltX", "charCode", "tiltY", "detail", "isPrimary", "prevValue"])
};
$.each(["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel", "MSPointerOver", "MSPointerOut", "mouseenter", "mouseleave", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave"], function() {
$.event.fixHooks[this] = pointerEventHook
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.base.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var POINTER_EVENTS_NAMESPACE = "dxPointerEvents";
var BaseStrategy = DX.Class.inherit({
ctor: function(eventName, originalEvents) {
this._eventName = eventName;
this._eventNamespace = [POINTER_EVENTS_NAMESPACE, ".", this._eventName].join("");
this._originalEvents = originalEvents;
this._handlerCount = 0;
this.noBubble = this._isNoBubble()
},
_isNoBubble: function() {
var eventName = this._eventName;
return eventName === "dxpointerenter" || eventName === "dxpointerleave"
},
_handler: function(e) {
var delegateTarget = this._getDelegateTarget(e);
return this._fireEvent({
type: this._eventName,
pointerType: e.pointerType || events.eventSource(e),
originalEvent: e,
delegateTarget: delegateTarget
})
},
_getDelegateTarget: function(e) {
var delegateTarget;
if (this.noBubble)
delegateTarget = e.delegateTarget;
return delegateTarget
},
_fireEvent: function(args) {
return events.fireEvent(args)
},
setup: function() {
return true
},
add: function(element, handleObj) {
if (this._handlerCount <= 0 || this.noBubble) {
this._selector = handleObj.selector;
element = this.noBubble ? element : document;
$(element).on(events.addNamespace(this._originalEvents, this._eventNamespace), this._selector, $.proxy(this._handler, this))
}
if (!this.noBubble)
this._handlerCount++
},
remove: function(element) {
if (!this.noBubble)
this._handlerCount--
},
teardown: function(element) {
if (this._handlerCount && !this.noBubble)
return;
element = this.noBubble ? element : document;
$(element).off("." + this._eventNamespace, this._selector)
},
dispose: function(element) {
element = this.noBubble ? element : document;
$(element).off("." + this._eventNamespace)
}
});
events.pointer = {};
events.pointer.BaseStrategy = BaseStrategy
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.mouse.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
pointer = events.pointer;
var MouseStrategyEventMap = {
dxpointerdown: "mousedown",
dxpointermove: "mousemove",
dxpointerup: "mouseup",
dxpointercancel: "",
dxpointerover: "mouseover",
dxpointerout: "mouseout",
dxpointerenter: "mouseenter",
dxpointerleave: "mouseleave"
};
var normalizeMouseEvent = function(e) {
var pointers = [];
e.pointerId = 1;
if (e.type !== "mouseup")
pointers.push(e);
return {
pointers: pointers,
pointerId: 1
}
};
var MouseStrategy = pointer.BaseStrategy.inherit({_fireEvent: function(args) {
return this.callBase($.extend(normalizeMouseEvent(args.originalEvent), args))
}});
pointer.mouse = {
strategy: MouseStrategy,
map: MouseStrategyEventMap,
normalize: normalizeMouseEvent
}
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.touch.js */
(function($, DX, undefined) {
var ui = DX.ui,
device = $.proxy(DX.devices.real, DX.devices),
events = ui.events,
pointer = events.pointer;
var TouchStrategyEventMap = {
dxpointerdown: "touchstart",
dxpointermove: "touchmove",
dxpointerup: "touchend",
dxpointercancel: "touchcancel"
};
var normalizeTouchEvent = function(e) {
var pointers = [];
$.each(e.touches, function(_, touch) {
pointers.push($.extend({pointerId: touch.identifier}, touch))
});
return {
pointers: pointers,
pointerId: e.changedTouches[0].identifier
}
};
var skipTouchWithSameIdentifier = function(pointerEvent) {
return device().platform === "ios" && (pointerEvent === "dxpointerdown" || pointerEvent === "dxpointerup")
};
var TouchStrategy = pointer.BaseStrategy.inherit({
ctor: function() {
this.callBase.apply(this, arguments);
this._pointerId = 0
},
_handler: function(e) {
if (skipTouchWithSameIdentifier(this._eventName)) {
var touch = e.changedTouches[0];
if (this._pointerId === touch.identifier && this._pointerId !== 0)
return;
this._pointerId = touch.identifier
}
return this.callBase.apply(this, arguments)
},
_fireEvent: function(args) {
return this.callBase($.extend(normalizeTouchEvent(args.originalEvent), args))
}
});
pointer.touch = {
strategy: TouchStrategy,
map: TouchStrategyEventMap,
normalize: normalizeTouchEvent
}
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.mouseAndTouch.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
pointer = events.pointer;
var MouseAndTouchStrategyEventMap = {
dxpointerdown: "touchstart mousedown",
dxpointermove: "touchmove mousemove",
dxpointerup: "touchend mouseup",
dxpointercancel: "touchcancel",
dxpointerover: "mouseover",
dxpointerout: "mouseout",
dxpointerenter: "mouseenter",
dxpointerleave: "mouseleave"
};
var MouseAndTouchStrategy = pointer.BaseStrategy.inherit({
EVENT_LOCK_TIMEOUT: 100,
_handler: function(e) {
var isMouseEvent = events.isMouseEvent(e);
if (!isMouseEvent)
this._skipNextEvents = true;
if (isMouseEvent && this._mouseLocked)
return;
if (isMouseEvent && this._skipNextEvents) {
this._skipNextEvents = false;
this._mouseLocked = true;
clearTimeout(this._unlockMouseTimer);
this._unlockMouseTimer = setTimeout($.proxy(function() {
this._mouseLocked = false
}, this), this.EVENT_LOCK_TIMEOUT);
return
}
return this.callBase(e)
},
_fireEvent: function(args) {
var isMouseEvent = events.isMouseEvent(args.originalEvent),
normalizer = isMouseEvent ? pointer.mouse.normalize : pointer.touch.normalize;
return this.callBase($.extend(normalizer(args.originalEvent), args))
},
dispose: function() {
this.callBase();
this._skipNextEvents = false;
this._mouseLocked = false;
clearTimeout(this._unlockMouseTimer)
}
});
pointer.mouseAndTouch = {
strategy: MouseAndTouchStrategy,
map: MouseAndTouchStrategyEventMap
}
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.mspointer.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
pointer = events.pointer;
var MsPointerStrategyEventMap = {
dxpointerdown: "MSPointerDown pointerdown",
dxpointermove: "MSPointerMove pointermove",
dxpointerup: "MSPointerUp pointerup",
dxpointercancel: "MSPointerCancel pointercancel",
dxpointerover: "MSPointerOver pointerover",
dxpointerout: "MSPointerOut pointerout",
dxpointerenter: "mouseenter",
dxpointerleave: "mouseleave"
};
var pointers = [];
var getPointerIndex = function(e) {
var index = -1;
$.each(pointers, function(i, pointer) {
if (e.pointerId === pointer.pointerId) {
index = i;
return true
}
});
return index
};
var addPointer = function(e) {
if (getPointerIndex(e) === -1)
pointers.push(e)
};
var removePointer = function(e) {
pointers.splice(getPointerIndex(e), 1)
};
var updatePointer = function(e) {
pointers[getPointerIndex(e)] = e
};
var addEventsListner = function(events, handler) {
events = events.split(" ");
$.each(events, function(_, event) {
document.addEventListener(event, handler, true)
})
};
var activateMspointerStrategy = function() {
var eventMap = MsPointerStrategyEventMap;
addEventsListner(eventMap.dxpointerdown, addPointer);
addEventsListner(eventMap.dxpointermove, updatePointer);
addEventsListner(eventMap.dxpointerup, removePointer);
addEventsListner(eventMap.dxpointercancel, removePointer);
activateMspointerStrategy = $.noop
};
var MsPointerStrategy = pointer.BaseStrategy.inherit({
ctor: function() {
this.callBase.apply(this, arguments);
activateMspointerStrategy()
},
_fireEvent: function(args) {
return this.callBase($.extend({
pointers: pointers,
pointerId: args.originalEvent.pointerId
}, args))
}
});
pointer.msPointer = {
strategy: MsPointerStrategy,
map: MsPointerStrategyEventMap
};
DX.ui.events.__internals = DX.ui.events.__internals || {};
$.extend(DX.ui.events.__internals, {cleanMsPointers: function() {
pointers = []
}})
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.js */
(function($, DX, undefined) {
var ui = DX.ui,
support = DX.support,
device = $.proxy(DX.devices.real, DX.devices),
events = ui.events,
pointer = events.pointer;
var eventType = function() {
if (support.pointer)
return pointer.msPointer;
if (support.touch && !(device().tablet || device().phone))
return pointer.mouseAndTouch;
if (support.touch)
return pointer.touch;
return pointer.mouse
}();
$.each(eventType.map, function(pointerEvent, originalEvents) {
events.registerEvent(pointerEvent, new eventType.strategy(pointerEvent, originalEvents))
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.wheel.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var EVENT_NAME = "dxmousewheel",
EVENT_NAMESPACE = "dxWheel";
$.event.fixHooks["wheel"] = $.event.mouseHooks;
var wheelEvent = document.onmousewheel !== undefined ? "mousewheel" : "wheel";
var wheel = {
setup: function(element, data) {
var $element = $(element);
$element.on(events.addNamespace(wheelEvent, EVENT_NAMESPACE), $.proxy(wheel._wheelHandler, wheel))
},
teardown: function(element) {
var $element = $(element);
$element.off("." + EVENT_NAMESPACE)
},
_wheelHandler: function(e) {
var delta = this._getWheelDelta(e.originalEvent);
events.fireEvent({
type: EVENT_NAME,
originalEvent: e,
delta: delta,
pointerType: "mouse"
});
e.stopPropagation()
},
_getWheelDelta: function(event) {
return event.wheelDelta ? event.wheelDelta : -event.deltaY * 30
}
};
events.registerEvent(EVENT_NAME, wheel)
})(jQuery, DevExpress);
/*! Module core, file ui.events.hover.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var HOVERSTART_NAMESPACE = "dxHoverStart",
HOVERSTART = "dxhoverstart",
POINTERENTER_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerenter", HOVERSTART_NAMESPACE),
POINTERDOWN_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerdown", HOVERSTART_NAMESPACE),
POINTERUP_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerup", HOVERSTART_NAMESPACE),
HOVEREND_NAMESPACE = "dxHoverEnd",
HOVEREND = "dxhoverend",
POINTERLEAVE_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerleave", HOVEREND_NAMESPACE);
var Hover = DX.Class.inherit({
noBubble: true,
add: function(element, handleObj) {
var $element = $(element);
$element.off("." + this._namespace).on(this._originalEventName, handleObj.selector, $.proxy(this._handler, this))
},
_handler: function(e) {
if (events.isTouchEvent(e))
return;
events.fireEvent({
type: this._eventName,
originalEvent: e,
delegateTarget: e.delegateTarget
})
},
teardown: function(element) {
$(element).off("." + this._namespace)
}
});
var HoverStart = Hover.inherit({
ctor: function() {
this._eventName = HOVERSTART;
this._originalEventName = POINTERENTER_NAMESPACED_EVENT_NAME;
this._namespace = HOVERSTART_NAMESPACE;
this._isMouseDown = false;
this._eventsAttached = 0
},
_handler: function(e) {
if (!this._isMouseDown)
this.callBase.apply(this, arguments)
},
setup: function() {
$(document).off("." + HOVERSTART_NAMESPACE).on(POINTERDOWN_NAMESPACED_EVENT_NAME, $.proxy(function() {
this._isMouseDown = true
}, this)).on(POINTERUP_NAMESPACED_EVENT_NAME, $.proxy(function() {
this._isMouseDown = false
}, this));
this._eventsAttached++
},
teardown: function() {
this._eventsAttached--;
if (this._eventsAttached === 0)
$(document).off("." + HOVERSTART_NAMESPACE)
}
});
var HoverEnd = Hover.inherit({ctor: function() {
this._eventName = HOVEREND;
this._originalEventName = POINTERLEAVE_NAMESPACED_EVENT_NAME;
this._namespace = HOVEREND_NAMESPACE
}});
events.registerEvent(HOVERSTART, new HoverStart);
events.registerEvent(HOVEREND, new HoverEnd)
})(jQuery, DevExpress);
/*! Module core, file ui.events.manager.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var MANAGER_EVENT = "dxEventManager",
EMITTER_DATA = "dxEmitter";
var EventManager = DX.Class.inherit({
ctor: function() {
this._attachHandlers();
this.reset();
this._proxiedCancelHandler = $.proxy(this._cancelHandler, this);
this._proxiedAcceptHandler = $.proxy(this._acceptHandler, this)
},
_attachHandlers: function() {
$(document).on(events.addNamespace("dxpointerdown", MANAGER_EVENT), $.proxy(this._pointerDownHandler, this)).on(events.addNamespace("dxpointermove", MANAGER_EVENT), $.proxy(this._pointerMoveHandler, this)).on(events.addNamespace("dxpointerup dxpointercancel", MANAGER_EVENT), $.proxy(this._pointerUpHandler, this)).on(events.addNamespace("dxmousewheel", MANAGER_EVENT), $.proxy(this._mouseWheelHandler, this))
},
_eachEmitter: function(callback) {
var activeEmitters = this._activeEmitters || [];
var i = 0;
while (activeEmitters.length > i) {
var emitter = activeEmitters[i];
if (callback(emitter) === false)
break;
if (activeEmitters[i] === emitter)
i++
}
},
_applyToEmitters: function(method, arg) {
this._eachEmitter(function(emitter) {
emitter[method].call(emitter, arg)
})
},
reset: function() {
this._eachEmitter(this._proxiedCancelHandler);
this._activeEmitters = []
},
resetEmitter: function(emitter) {
this._proxiedCancelHandler(emitter)
},
_pointerDownHandler: function(e) {
if (events.isMouseEvent(e) && e.which > 1)
return;
this._updateEmitters(e)
},
_updateEmitters: function(e) {
if (!this._isSetChanged(e))
return;
this._cleanEmitters(e);
this._fetchEmitters(e)
},
_isSetChanged: function(e) {
var currentSet = this._closestEmitter(e);
var previousSet = this._emittersSet || [];
var setChanged = currentSet.length !== previousSet.length;
$.each(currentSet, function(index, emitter) {
setChanged = setChanged || previousSet[index] !== emitter;
return !setChanged
});
this._emittersSet = currentSet;
return setChanged
},
_closestEmitter: function(e) {
var that = this,
result = [],
$element = $(e.target);
function handleEmitter(_, emitter) {
if (!!emitter && emitter.validatePointers(e) && emitter.validate(e)) {
emitter.addCancelCallback(that._proxiedCancelHandler);
emitter.addAcceptCallback(that._proxiedAcceptHandler);
result.push(emitter)
}
}
while ($element.length) {
var emitters = $.data($element.get(0), EMITTER_DATA) || [];
$.each(emitters, handleEmitter);
$element = $element.parent()
}
return result
},
_acceptHandler: function(acceptedEmitter, e) {
var that = this;
this._eachEmitter(function(emitter) {
if (emitter !== acceptedEmitter)
that._cancelEmitter(emitter, e)
})
},
_cancelHandler: function(canceledEmitter, e) {
this._cancelEmitter(canceledEmitter, e)
},
_cancelEmitter: function(emitter, e) {
var activeEmitters = this._activeEmitters;
if (e)
emitter.cancel(e);
else
emitter.reset();
emitter.removeCancelCallback();
emitter.removeAcceptCallback();
var emitterIndex = $.inArray(emitter, activeEmitters);
if (emitterIndex > -1)
activeEmitters.splice(emitterIndex, 1)
},
_cleanEmitters: function(e) {
this._applyToEmitters("end", e);
this.reset(e)
},
_fetchEmitters: function(e) {
this._activeEmitters = this._emittersSet.slice();
this._applyToEmitters("start", e)
},
_pointerMoveHandler: function(e) {
this._applyToEmitters("move", e)
},
_pointerUpHandler: function(e) {
this._updateEmitters(e)
},
_mouseWheelHandler: function(e) {
var allowInterruption = true;
this._eachEmitter(function(emitter) {
allowInterruption = emitter.allowInterruptionByMousewheel() && allowInterruption;
return allowInterruption
});
if (!allowInterruption)
return;
e.pointers = [null];
this._pointerDownHandler(e);
this._eachEmitter(function(emitter) {
var direction = emitter.getDirection ? emitter.getDirection(e) : "",
prop = direction !== "horizontal" ? "pageY" : "pageX";
if (direction)
e[prop] += e.delta;
return !direction
});
this._pointerMoveHandler(e);
e.pointers = [];
this._pointerUpHandler(e)
},
isActive: function(element) {
var result = false;
this._eachEmitter(function(emitter) {
result = result || emitter.getElement().is(element)
});
return result
}
});
var eventManager = new EventManager;
var EMITTER_SUBSCRIPTION_DATA = "dxEmitterSubscription";
var registerEmitter = function(emitterConfig) {
var emitterClass = emitterConfig.emitter,
emitterName = emitterConfig.events[0],
emitterEvents = emitterConfig.events;
$.each(emitterEvents, function(_, eventName) {
events.registerEvent(eventName, {
noBubble: !emitterConfig.bubble,
setup: function(element, data) {
var subscriptions = $.data(element, EMITTER_SUBSCRIPTION_DATA) || {},
emitters = $.data(element, EMITTER_DATA) || {},
emitter = emitters[emitterName] || new emitterClass(element);
subscriptions[eventName] = true;
emitters[emitterName] = emitter;
$.data(element, EMITTER_DATA, emitters);
$.data(element, EMITTER_SUBSCRIPTION_DATA, subscriptions)
},
add: function(element, handleObj) {
var emitters = $.data(element, EMITTER_DATA),
emitter = emitters[emitterName];
emitter.configurate($.extend({delegateSelector: handleObj.selector}, handleObj.data), handleObj.type)
},
teardown: function(element) {
var subscriptions = $.data(element, EMITTER_SUBSCRIPTION_DATA),
emitters = $.data(element, EMITTER_DATA),
emitter = emitters[emitterName];
delete subscriptions[eventName];
var disposeEmitter = true;
$.each(emitterEvents, function(_, eventName) {
disposeEmitter = disposeEmitter && !subscriptions[eventName];
return disposeEmitter
});
if (disposeEmitter) {
if (eventManager.isActive(element))
eventManager.resetEmitter(emitter);
emitter && emitter.dispose();
delete emitters[emitterName]
}
}
})
})
};
$.extend(events, {registerEmitter: registerEmitter})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var Emitter = DX.Class.inherit({
ctor: function(element) {
this._$element = $(element);
this._cancelCallback = $.Callbacks();
this._acceptCallback = $.Callbacks()
},
getElement: function() {
return this._$element
},
validate: function(e) {
return e.type !== "dxmousewheel"
},
validatePointers: function(e) {
return events.hasTouches(e) === 1
},
allowInterruptionByMousewheel: function() {
return true
},
configurate: function(data) {
$.extend(this, data)
},
addCancelCallback: function(callback) {
this._cancelCallback.add(callback)
},
removeCancelCallback: function() {
this._cancelCallback.empty()
},
_cancel: function(e) {
this._cancelCallback.fire(this, e)
},
addAcceptCallback: function(callback) {
this._acceptCallback.add(callback)
},
removeAcceptCallback: function() {
this._acceptCallback.empty()
},
_accept: function(e) {
this._acceptCallback.fire(this, e)
},
_requestAccept: function(e) {
this._acceptRequestEvent = e
},
_forgetAccept: function() {
this._accept(this._acceptRequestEvent);
this._acceptRequestEvent = null
},
start: $.noop,
move: $.noop,
end: $.noop,
cancel: $.noop,
reset: function() {
if (this._acceptRequestEvent)
this._accept(this._acceptRequestEvent)
},
_fireEvent: function(eventName, e, params) {
var eventData = $.extend({
type: eventName,
originalEvent: e,
target: this._getEmitterTarget(e),
delegateTarget: this.getElement().get(0)
}, params);
e = events.fireEvent(eventData);
if (e.cancel)
this._cancel(e);
return e
},
_getEmitterTarget: function(e) {
return (this.delegateSelector ? $(e.target).closest(this.delegateSelector) : this.getElement()).get(0)
},
dispose: $.noop
});
$.extend(events, {Emitter: Emitter})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.feedback.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
ACTIVE_EVENT_NAME = "dxactive",
INACTIVE_EVENT_NAME = "dxinactive",
ACTIVE_TIMEOUT = 30,
INACTIVE_TIMEOUT = 400;
var activeEmitter;
var FeedbackEmitter = events.Emitter.inherit({
configurate: function(data, eventName) {
switch (eventName) {
case ACTIVE_EVENT_NAME:
data.activeTimeout = data.timeout;
break;
case INACTIVE_EVENT_NAME:
data.inactiveTimeout = data.timeout;
break
}
this.callBase(data)
},
start: function(e) {
var element = this.getElement().get(0);
var activeElement = activeEmitter && activeEmitter.getElement().get(0);
var activeChildExists = $.contains(element, activeElement);
var childJustActivated = activeEmitter && activeEmitter._activeTimer !== null;
if (activeChildExists && childJustActivated)
this._cancel();
else {
if (activeEmitter)
activeEmitter._forceInactiveTimer();
activeEmitter = this;
var eventTarget = this._getEmitterTarget(e);
this._forceActiveTimer = $.proxy(this._fireActive, this, e, eventTarget);
this._forceInactiveTimer = $.proxy(this._fireInctive, this, e, eventTarget);
this._startActiveTimer(e)
}
},
cancel: function(e) {
this.end(e)
},
end: function(e) {
var skipTimers = e.type !== "dxpointerup";
if (skipTimers)
this._stopActiveTimer();
else
this._forceActiveTimer();
this._startInactiveTimer(e);
if (skipTimers)
this._forceInactiveTimer()
},
dispose: function() {
this._stopActiveTimer();
this._stopInactiveTimer();
this.callBase()
},
_startActiveTimer: function(e) {
var activeTimeout = "activeTimeout" in this ? this.activeTimeout : ACTIVE_TIMEOUT;
this._activeTimer = window.setTimeout(this._forceActiveTimer, activeTimeout)
},
_fireActive: function(e, eventTarget) {
this._stopActiveTimer();
this._fireEvent(ACTIVE_EVENT_NAME, e, {target: eventTarget})
},
_stopActiveTimer: function() {
clearTimeout(this._activeTimer);
this._activeTimer = null
},
_forceActiveTimer: $.noop,
_startInactiveTimer: function(e) {
var inactiveTimeout = "inactiveTimeout" in this ? this.inactiveTimeout : INACTIVE_TIMEOUT;
this._inactiveTimer = window.setTimeout(this._forceInactiveTimer, inactiveTimeout)
},
_fireInctive: function(e, eventTarget) {
this._stopInactiveTimer();
activeEmitter = null;
this._fireEvent(INACTIVE_EVENT_NAME, e, {target: eventTarget})
},
_stopInactiveTimer: function() {
clearTimeout(this._inactiveTimer);
this._inactiveTimer = null
},
_forceInactiveTimer: $.noop,
lockInactive: function() {
this._forceActiveTimer();
this._stopInactiveTimer();
activeEmitter = null;
this._cancel();
return this._forceInactiveTimer
}
});
ui.events = $.extend(ui.events, {lockFeedback: function(deferred) {
var lockInactive = activeEmitter ? activeEmitter.lockInactive() : $.noop;
$.when(deferred).always(lockInactive)
}});
events.registerEmitter({
emitter: FeedbackEmitter,
events: [ACTIVE_EVENT_NAME, INACTIVE_EVENT_NAME]
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.click.js */
(function($, DX, wnd, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
abs = Math.abs,
CLICK_EVENT_NAME = "dxclick",
TOUCH_BOUNDARY = 10;
var isInput = function(element) {
return $(element).is("input, textarea, select, button ,:focus, :focus *")
};
var misc = {requestAnimationFrame: DX.requestAnimationFrame};
var ClickEmitter = events.Emitter.inherit({
ctor: function(element) {
this.callBase(element);
this._makeElementClickable($(element))
},
_makeElementClickable: function($element) {
if (!$element.attr("onclick"))
$element.attr("onclick", "void(0)")
},
start: function(e) {
this._blurPrevented = e.dxPreventBlur;
this._startTarget = e.target;
this._startEventData = events.eventData(e)
},
end: function(e) {
if (this._eventOutOfElement(e, this.getElement().get(0)) || e.type === "dxpointercancel") {
this._cancel(e);
return
}
if (!isInput(e.target) && !this._blurPrevented)
utils.resetActiveElement();
this._accept(e);
misc.requestAnimationFrame($.proxy(function() {
this._fireClickEvent(e)
}, this))
},
_eventOutOfElement: function(e, element) {
var target = e.target,
targetChanged = !$.contains(element, target) && element !== target,
gestureDelta = events.eventDelta(events.eventData(e), this._startEventData),
boundsExceeded = abs(gestureDelta.x) > TOUCH_BOUNDARY || abs(gestureDelta.y) > TOUCH_BOUNDARY;
return targetChanged || boundsExceeded
},
_fireClickEvent: function(e) {
this._fireEvent(CLICK_EVENT_NAME, e, {target: utils.closestCommonParent(this._startTarget, e.target)})
}
});
(function() {
var useNativeClick = DX.devices.real().generic;
if (useNativeClick) {
var prevented = null;
ClickEmitter = ClickEmitter.inherit({
start: function() {
prevented = null
},
end: $.noop,
cancel: function() {
prevented = true
}
});
var clickHandler = function(e) {
if ((!e.which || e.which === 1) && !prevented)
events.fireEvent({
type: CLICK_EVENT_NAME,
originalEvent: e
})
};
$(document).on(events.addNamespace("click", "NATIVE_DXCLICK_STRATEGY"), clickHandler)
}
$.extend(events.__internals, {useNativeClick: useNativeClick})
})();
(function() {
var fixBuggyInertia = DX.devices.real().ios;
if (fixBuggyInertia) {
var GESTURE_LOCK_KEY = "dxGestureLock";
ClickEmitter = ClickEmitter.inherit({_fireClickEvent: function(e) {
var $element = $(e.target);
while ($element.length) {
if ($.data($element.get(0), GESTURE_LOCK_KEY))
return;
$element = $element.parent()
}
this.callBase.apply(this, arguments)
}})
}
$.extend(events.__internals, {fixBuggyInertia: fixBuggyInertia})
})();
(function() {
var desktopDevice = DX.devices.real().generic;
if (!desktopDevice) {
var startTarget = null,
blurPrevented = false;
var pointerDownHandler = function(e) {
startTarget = e.target;
blurPrevented = e.dxPreventBlur
};
var clickHandler = function(e) {
var $target = $(e.target);
if (!blurPrevented && startTarget && !$target.is(startTarget) && !$(startTarget).is("label") && isInput($target))
utils.resetActiveElement();
startTarget = null;
blurPrevented = false
};
var NATIVE_CLICK_FIXER_NAMESPACE = "NATIVE_CLICK_FIXER";
$(document).on(events.addNamespace("dxpointerdown", NATIVE_CLICK_FIXER_NAMESPACE), pointerDownHandler).on(events.addNamespace("click", NATIVE_CLICK_FIXER_NAMESPACE), clickHandler)
}
})();
events.registerEmitter({
emitter: ClickEmitter,
bubble: true,
events: [CLICK_EVENT_NAME]
});
$.extend(events.__internals, {
useFastClick: !events.__internals.useNativeClick && !events.__internals.fixBuggyInertia,
misc: misc
})
})(jQuery, DevExpress, window);
/*! Module core, file ui.events.emitter.hold.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
abs = Math.abs,
HOLD_EVENT_NAME = "dxhold",
HOLD_TIMEOUT = 750,
TOUCH_BOUNDARY = 5;
var HoldEmitter = events.Emitter.inherit({
start: function(e) {
this._startEventData = events.eventData(e);
this._startTimer(e)
},
_startTimer: function(e) {
var holdTimeout = "timeout" in this ? this.timeout : HOLD_TIMEOUT;
this._holdTimer = setTimeout($.proxy(function() {
this._requestAccept(e);
this._fireEvent(HOLD_EVENT_NAME, e, {target: e.target});
this._forgetAccept()
}, this), holdTimeout)
},
move: function(e) {
if (this._touchWasMoved(e))
this._cancel(e)
},
_touchWasMoved: function(e) {
var delta = events.eventDelta(this._startEventData, events.eventData(e));
return abs(delta.x) > TOUCH_BOUNDARY || abs(delta.y) > TOUCH_BOUNDARY
},
end: function() {
this._stopTimer()
},
_stopTimer: function() {
clearTimeout(this._holdTimer)
},
cancel: function() {
this._stopTimer()
}
});
events.registerEmitter({
emitter: HoldEmitter,
bubble: true,
events: [HOLD_EVENT_NAME]
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.gesture.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
devices = DX.devices,
support = DX.support,
abs = Math.abs;
var SLEEP = 0,
INITED = 1,
STARTED = 2,
TOUCH_BOUNDARY = 10,
IMMEDIATE_TOUCH_BOUNDARY = 0,
IMMEDIATE_TIMEOUT = 180;
var isMousewheelEvent = function(e) {
return e && e.type === "dxmousewheel"
};
var GestureEmitter = events.Emitter.inherit({
configurate: function(data) {
this.getElement().css("msTouchAction", data.immediate ? "pinch-zoom" : "");
this.callBase(data)
},
allowInterruptionByMousewheel: function() {
return this._stage !== STARTED
},
getDirection: function() {
return this.direction
},
_cancel: function(e) {
this.callBase.apply(this, arguments);
this._togglePointerAddons(true);
this._stage = SLEEP
},
start: function(e) {
if (events.needSkipEvent(e)) {
this._cancel(e);
return
}
this._startEvent = events.createEvent(e);
this._startEventData = events.eventData(e);
this._prevEventData = this._startEventData;
this._stage = INITED;
this._init(e);
this._setupImmediateTimer()
},
_setupImmediateTimer: function() {
clearTimeout(this._immediateTimer);
this._immedeateAccepted = false;
if (!this.immediate)
return;
this._immediateTimer = setTimeout($.proxy(function() {
this._immedeateAccepted = true
}, this), IMMEDIATE_TIMEOUT)
},
move: function(e) {
if (this._stage === INITED && this._directionConfirmed(e)) {
this._stage = STARTED;
this._resetActiveElement();
this._togglePointerAddons(false, e);
this._clearSelection(e);
this._adjustStartEvent(e);
this._start(this._startEvent);
this._prevEventData = events.eventData(this._startEvent);
if (this._stage === SLEEP)
return;
this._requestAccept(e);
this._move(e);
this._forgetAccept()
}
else if (this._stage === STARTED)
this._move(e);
this._prevEventData = events.eventData(e)
},
_directionConfirmed: function(e) {
var touchBoundary = this._getTouchBoundary(e),
delta = events.eventDelta(this._startEventData, events.eventData(e)),
deltaX = abs(delta.x),
deltaY = abs(delta.y);
var horizontalMove = this._validateMove(touchBoundary, deltaX, deltaY),
verticalMove = this._validateMove(touchBoundary, deltaY, deltaX);
var direction = this.getDirection(e),
bothAccepted = direction === "both" && (horizontalMove || verticalMove),
horizontalAccepted = direction === "horizontal" && horizontalMove,
verticalAccepted = direction === "vertical" && verticalMove;
return bothAccepted || horizontalAccepted || verticalAccepted || this._immedeateAccepted
},
_validateMove: function(touchBoundary, mainAxis, crossAxis) {
return mainAxis && mainAxis >= touchBoundary && (this.immediate ? mainAxis >= crossAxis : true)
},
_getTouchBoundary: function(e) {
return this.immediate || isMousewheelEvent(e) ? IMMEDIATE_TOUCH_BOUNDARY : TOUCH_BOUNDARY
},
_adjustStartEvent: function(e) {
var touchBoundary = this._getTouchBoundary(e),
delta = events.eventDelta(this._startEventData, events.eventData(e));
this._startEvent.pageX += utils.sign(delta.x) * touchBoundary;
this._startEvent.pageY += utils.sign(delta.y) * touchBoundary
},
_resetActiveElement: function() {
if (devices.real().platform === "ios" && $(":focus", this.getElement()).length)
utils.resetActiveElement()
},
_togglePointerAddons: function(toggle, e) {
var isStarted = this._stage === STARTED;
if (isStarted) {
this._togglePointerInteration(toggle);
if (!isMousewheelEvent(e))
this._togglePointerCursor(toggle)
}
},
_togglePointerInteration: function(toggle) {
var isDesktop = devices.real().platform === "generic";
if (isDesktop) {
$("body").css("pointer-events", toggle ? "" : "none");
if (support.supportProp("user-select"))
$("body").css(support.styleProp("user-select"), toggle ? "" : "none")
}
},
_togglePointerCursor: function(toggle) {
if (toggle)
$("html").css("cursor", this._originalCursor);
else {
this._originalCursor = $("html").css("cursor");
$("html").css("cursor", this.getElement().css("cursor"))
}
},
_clearSelection: function(e) {
if (isMousewheelEvent(e) || events.isTouchEvent(e))
return;
utils.clearSelection()
},
end: function(e) {
this._togglePointerAddons(true, e);
if (this._stage === STARTED)
this._end(e);
else if (this._stage === INITED)
this._stop(e);
this._stage = SLEEP
},
dispose: function() {
clearTimeout(this._immediateTimer);
this.callBase.apply(this, arguments);
this._togglePointerAddons(true)
},
_init: $.noop,
_start: $.noop,
_move: $.noop,
_stop: $.noop,
_end: $.noop
});
$.extend(events, {GestureEmitter: GestureEmitter});
var ORIG_TOUCH_BOUNDARY = TOUCH_BOUNDARY;
$.extend(DX.ui.events.__internals, {
GESTURE_TOUCH_BOUNDARY: ORIG_TOUCH_BOUNDARY,
resetTouchBoundary: function() {
TOUCH_BOUNDARY = ORIG_TOUCH_BOUNDARY;
events.__internals.GESTURE_TOUCH_BOUNDARY = ORIG_TOUCH_BOUNDARY
},
cleanTouchBoundary: function() {
TOUCH_BOUNDARY = 0
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.gesture.scroll.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var SCROLL_INIT_EVENT = "dxscrollinit",
SCROLL_START_EVENT = "dxscrollstart",
SCROLL_MOVE_EVENT = "dxscroll",
SCROLL_END_EVENT = "dxscrollend",
SCROLL_STOP_EVENT = "dxscrollstop",
SCROLL_CANCEL_EVENT = "dxscrollcancel",
INERTIA_TIMEOUT = 100,
VELOCITY_CALC_TIMEOUT = 200,
FRAME_DURATION = Math.round(1000 / 60),
GESTURE_LOCK_KEY = "dxGestureLock",
GESTURE_LOCK_TIMEOUT = 200,
NAMESPACED_SCROLL_EVENT = events.addNamespace("scroll", "dxScrollEmitter");
var ScrollEmitter = events.GestureEmitter.inherit({
ctor: function(element) {
this.callBase.apply(this, arguments);
this.direction = "both";
$.data(element, "scroll", $.proxy(this._treatScroll, this));
$(element).on(NAMESPACED_SCROLL_EVENT, $.proxy(this._treatScroll, this))
},
validate: function() {
return true
},
_domElement: function() {
return this.getElement().get(0)
},
_treatScroll: function() {
this._prepareGesture();
this._forgetGesture()
},
_prepareGesture: function() {
if (this._gestureEndTimer)
this._clearGestureTimer();
else
$.data(this._domElement(), GESTURE_LOCK_KEY, true)
},
_forgetGesture: function() {
var that = this;
this._gestureEndTimer = setTimeout(function() {
$.data(that._domElement(), GESTURE_LOCK_KEY, false);
that._gestureEndTimer = null
}, GESTURE_LOCK_TIMEOUT)
},
_init: function(e) {
if ($.data(this._domElement(), GESTURE_LOCK_KEY))
this._accept(e);
this._fireEvent(SCROLL_INIT_EVENT, e)
},
move: function(e) {
this.callBase.apply(this, arguments);
e.isScrollingEvent = this.isNative || e.isScrollingEvent
},
_start: function(e) {
this._savedEventData = events.eventData(e);
this._fireEvent(SCROLL_START_EVENT, e, {delta: events.eventDelta(this._savedEventData, events.eventData(e))})
},
_move: function(e) {
var currentEventData = events.eventData(e);
this._fireEvent(SCROLL_MOVE_EVENT, e, {delta: events.eventDelta(this._prevEventData, currentEventData)});
var eventDelta = events.eventDelta(this._savedEventData, currentEventData);
if (eventDelta.time > VELOCITY_CALC_TIMEOUT)
this._savedEventData = this._prevEventData
},
_end: function(e) {
var endEventDelta = events.eventDelta(this._prevEventData, events.eventData(e));
var velocity = {
x: 0,
y: 0
};
var isWheelEvent = e.type === "dxmousewheel";
if (endEventDelta.time < INERTIA_TIMEOUT) {
var deltaEventData = events.eventDelta(this._savedEventData, this._prevEventData);
velocity = {
x: isWheelEvent ? 0 : deltaEventData.x * FRAME_DURATION / deltaEventData.time,
y: isWheelEvent ? 0 : deltaEventData.y * FRAME_DURATION / deltaEventData.time
}
}
this._fireEvent(SCROLL_END_EVENT, e, {velocity: velocity})
},
_stop: function(e) {
this._fireEvent(SCROLL_STOP_EVENT, e)
},
cancel: function(e) {
this.callBase.apply(this, arguments);
this._fireEvent(SCROLL_CANCEL_EVENT, e)
},
dispose: function() {
this.callBase.apply(this, arguments);
$.data(this._domElement(), GESTURE_LOCK_KEY, false);
this._clearGestureTimer();
this.getElement().off(NAMESPACED_SCROLL_EVENT)
},
_clearGestureTimer: function() {
clearTimeout(this._gestureEndTimer);
this._gestureEndTimer = null
}
});
events.registerEmitter({
emitter: ScrollEmitter,
events: [SCROLL_INIT_EVENT, SCROLL_START_EVENT, SCROLL_MOVE_EVENT, SCROLL_END_EVENT, SCROLL_STOP_EVENT, SCROLL_CANCEL_EVENT]
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.gesture.swipe.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
SWIPE_START_EVENT = "dxswipestart",
SWIPE_EVENT = "dxswipe",
SWIPE_END_EVENT = "dxswipeend";
var HorizontalStrategy = {
defaultItemSizeFunc: function() {
return this.getElement().width()
},
getBounds: function() {
return [this._maxLeftOffset, this._maxRightOffset]
},
calcOffsetRatio: function(e) {
var endEventData = events.eventData(e);
return (endEventData.x - (this._savedEventData && this._savedEventData.x || 0)) / this._itemSizeFunc().call(this, e)
},
isFastSwipe: function(e) {
var endEventData = events.eventData(e);
return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.x - this._tickData.x) >= endEventData.time - this._tickData.time
}
};
var VerticalStrategy = {
defaultItemSizeFunc: function() {
return this.getElement().height()
},
getBounds: function() {
return [this._maxTopOffset, this._maxBottomOffset]
},
calcOffsetRatio: function(e) {
var endEventData = events.eventData(e);
return (endEventData.y - (this._savedEventData && this._savedEventData.y || 0)) / this._itemSizeFunc().call(this, e)
},
isFastSwipe: function(e) {
var endEventData = events.eventData(e);
return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.y - this._tickData.y) >= endEventData.time - this._tickData.time
}
};
var STRATEGIES = {
horizontal: HorizontalStrategy,
vertical: VerticalStrategy
};
var SwipeEmitter = events.GestureEmitter.inherit({
TICK_INTERVAL: 300,
FAST_SWIPE_SPEED_LIMIT: 5,
ctor: function(element) {
this.callBase(element);
this.direction = "horizontal";
this.elastic = true
},
_getStrategy: function() {
return STRATEGIES[this.direction]
},
_defaultItemSizeFunc: function() {
return this._getStrategy().defaultItemSizeFunc.call(this)
},
_itemSizeFunc: function() {
return this.itemSizeFunc || this._defaultItemSizeFunc
},
_start: function(e) {
this._savedEventData = events.eventData(e);
this._tickData = {time: 0};
e = this._fireEvent(SWIPE_START_EVENT, e);
if (!e.cancel) {
this._maxLeftOffset = e.maxLeftOffset;
this._maxRightOffset = e.maxRightOffset;
this._maxTopOffset = e.maxTopOffset;
this._maxBottomOffset = e.maxBottomOffset
}
},
_move: function(e) {
var strategy = this._getStrategy(),
moveEventData = events.eventData(e),
offset = strategy.calcOffsetRatio.call(this, e);
offset = this._fitOffset(offset, this.elastic);
if (moveEventData.time - this._tickData.time > this.TICK_INTERVAL)
this._tickData = moveEventData;
this._fireEvent(SWIPE_EVENT, e, {offset: offset});
e.preventDefault()
},
_end: function(e) {
var strategy = this._getStrategy(),
offsetRatio = strategy.calcOffsetRatio.call(this, e),
isFast = strategy.isFastSwipe.call(this, e),
startOffset = offsetRatio,
targetOffset = this._calcTargetOffset(offsetRatio, isFast);
startOffset = this._fitOffset(startOffset, this.elastic);
targetOffset = this._fitOffset(targetOffset, false);
this._fireEvent(SWIPE_END_EVENT, e, {
offset: startOffset,
targetOffset: targetOffset
})
},
_fitOffset: function(offset, elastic) {
var strategy = this._getStrategy(),
bounds = strategy.getBounds.call(this);
if (offset < -bounds[0])
return elastic ? (-2 * bounds[0] + offset) / 3 : -bounds[0];
if (offset > bounds[1])
return elastic ? (2 * bounds[1] + offset) / 3 : bounds[1];
return offset
},
_calcTargetOffset: function(offsetRatio, isFast) {
var result;
if (isFast) {
result = Math.ceil(Math.abs(offsetRatio));
if (offsetRatio < 0)
result = -result
}
else
result = Math.round(offsetRatio);
return result
}
});
events.registerEmitter({
emitter: SwipeEmitter,
events: [SWIPE_START_EVENT, SWIPE_EVENT, SWIPE_END_EVENT]
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.gesture.drag.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
wrapToArray = utils.wrapToArray;
var DRAG_START_EVENT = "dxdragstart",
DRAG_EVENT = "dxdrag",
DRAG_END_EVENT = "dxdragend",
DRAG_ENTER_EVENT = "dxdragenter",
DRAG_LEAVE_EVENT = "dxdragleave",
DROP_EVENT = "dxdrop";
var knownDropTargets = [],
knownDropTargetSelectors = [],
knownDropTargetConfigs = [];
var dropTargetRegistration = {
setup: function(element, data) {
var knownDropTarget = $.inArray(element, knownDropTargets) !== -1;
if (!knownDropTarget) {
knownDropTargets.push(element);
knownDropTargetSelectors.push([]);
knownDropTargetConfigs.push(data || {})
}
},
add: function(element, handleObj) {
var index = $.inArray(element, knownDropTargets);
var selector = handleObj.selector;
if ($.inArray(selector, knownDropTargetSelectors[index]) === -1)
knownDropTargetSelectors[index].push(selector)
},
teardown: function(element, data) {
var elementEvents = $._data(element, "events"),
handlersCount = 0;
$.each([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT], function(_, eventName) {
var eventHandlers = elementEvents[eventName];
if (eventHandlers)
handlersCount += eventHandlers.length
});
if (!handlersCount) {
var index = $.inArray(element, knownDropTargets);
knownDropTargets.splice(index, 1);
knownDropTargetSelectors.splice(index, 1);
knownDropTargetConfigs.splice(index, 1)
}
}
};
events.registerEvent(DRAG_ENTER_EVENT, dropTargetRegistration);
events.registerEvent(DRAG_LEAVE_EVENT, dropTargetRegistration);
events.registerEvent(DROP_EVENT, dropTargetRegistration);
var getItemDelegatedTargets = function($element) {
var dropTargetIndex = $.inArray($element.get(0), knownDropTargets),
dropTargetSelectors = knownDropTargetSelectors[dropTargetIndex];
var $delegatedTargets = $element.find(dropTargetSelectors.join(", "));
if ($.inArray(undefined, dropTargetSelectors) !== -1)
$delegatedTargets = $delegatedTargets.addBack();
return $delegatedTargets
};
var getItemConfig = function($element) {
var dropTargetIndex = $.inArray($element.get(0), knownDropTargets);
return knownDropTargetConfigs[dropTargetIndex]
};
var getItemPosition = function(dropTargetConfig, $element) {
if (dropTargetConfig.itemPositionFunc)
return dropTargetConfig.itemPositionFunc($element);
else
return $element.offset()
};
var getItemSize = function(dropTargetConfig, $element) {
if (dropTargetConfig.itemSizeFunc)
return dropTargetConfig.itemSizeFunc($element);
return {
width: $element.width(),
height: $element.height()
}
};
var DragEmitter = events.GestureEmitter.inherit({
ctor: function(element) {
this.callBase(element);
this.direction = "both"
},
_init: function(e) {
this._initEvent = e
},
_start: function(e) {
e = this._fireEvent(DRAG_START_EVENT, this._initEvent);
this._maxLeftOffset = e.maxLeftOffset;
this._maxRightOffset = e.maxRightOffset;
this._maxTopOffset = e.maxTopOffset;
this._maxBottomOffset = e.maxBottomOffset;
var dropTargets = wrapToArray(e.targetElements || (e.targetElements === null ? [] : knownDropTargets));
this._dropTargets = $.map(dropTargets, function(element) {
return $(element).get(0)
})
},
_move: function(e) {
var eventData = events.eventData(e),
dragOffset = this._calculateOffset(eventData);
this._fireEvent(DRAG_EVENT, e, {offset: dragOffset});
this._processDropTargets(e, dragOffset);
e.preventDefault()
},
_calculateOffset: function(eventData) {
return {
x: this._calculateXOffset(eventData),
y: this._calculateYOffset(eventData)
}
},
_calculateXOffset: function(eventData) {
if (this.direction !== "vertical") {
var offset = eventData.x - this._startEventData.x;
return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset)
}
return 0
},
_calculateYOffset: function(eventData) {
if (this.direction !== "horizontal") {
var offset = eventData.y - this._startEventData.y;
return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset)
}
return 0
},
_fitOffset: function(offset, minOffset, maxOffset) {
if (minOffset != null)
offset = Math.max(offset, -minOffset);
if (maxOffset != null)
offset = Math.min(offset, maxOffset);
return offset
},
_processDropTargets: function(e, dragOffset) {
var target = this._findDropTarget(e),
sameTarget = target === this._currentDropTarget;
if (!sameTarget) {
this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT);
this._currentDropTarget = target;
this._fireDropTargetEvent(e, DRAG_ENTER_EVENT)
}
},
_fireDropTargetEvent: function(event, eventName) {
if (!this._currentDropTarget)
return;
var eventData = {
type: eventName,
originalEvent: event,
draggingElement: this._$element.get(0),
target: this._currentDropTarget
};
events.fireEvent(eventData)
},
_findDropTarget: function(e) {
var that = this,
result;
$.each(knownDropTargets, function(_, target) {
if (!that._checkDropTargetActive(target))
return;
var $target = $(target);
$.each(getItemDelegatedTargets($target), function(_, delegatedTarget) {
var $delegatedTarget = $(delegatedTarget);
if (that._checkDropTarget(getItemConfig($target), $delegatedTarget, e))
result = delegatedTarget
})
});
return result
},
_checkDropTargetActive: function(target) {
var active = false;
$.each(this._dropTargets, function(_, activeTarget) {
active = active || activeTarget === target || $.contains(activeTarget, target);
return !active
});
return active
},
_checkDropTarget: function(config, $target, e) {
var isDraggingElement = $target.get(0) === this._$element.get(0);
if (isDraggingElement)
return false;
var targetPosition = getItemPosition(config, $target);
if (e.pageX < targetPosition.left)
return false;
if (e.pageY < targetPosition.top)
return false;
var targetSize = getItemSize(config, $target);
if (e.pageX > targetPosition.left + targetSize.width)
return false;
if (e.pageY > targetPosition.top + targetSize.height)
return false;
return $target
},
_end: function(e) {
var eventData = events.eventData(e);
this._fireEvent(DRAG_END_EVENT, e, {offset: this._calculateOffset(eventData)});
this._fireDropTargetEvent(e, DROP_EVENT);
delete this._currentDropTarget
}
});
events.registerEmitter({
emitter: DragEmitter,
events: [DRAG_START_EVENT, DRAG_EVENT, DRAG_END_EVENT]
});
DX.ui.events.__internals = DX.ui.events.__internals || {};
$.extend(DX.ui.events.__internals, {dropTargets: knownDropTargets})
})(jQuery, DevExpress);
/*! Module core, file ui.events.emitter.transform.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
fitIntoRange = utils.fitIntoRange;
var DX_PREFIX = "dx",
TRANSFORM = "transform",
TRANSLATE = "translate",
ZOOM = "zoom",
PINCH = "pinch",
ROTATE = "rotate",
START_POSTFIX = "start",
UPDATE_POSTFIX = "",
END_POSTFIX = "end";
var eventAliases = [];
var addAlias = function(eventName, eventArgs) {
eventAliases.push({
name: eventName,
args: eventArgs
})
};
addAlias(TRANSFORM, {
scale: true,
deltaScale: true,
rotation: true,
deltaRotation: true,
translation: true,
deltaTranslation: true
});
addAlias(TRANSLATE, {
translation: true,
deltaTranslation: true
});
addAlias(ZOOM, {
scale: true,
deltaScale: true
});
addAlias(PINCH, {
scale: true,
deltaScale: true
});
addAlias(ROTATE, {
rotation: true,
deltaRotation: true
});
var getVector = function(first, second) {
return {
x: second.pageX - first.pageX,
y: -second.pageY + first.pageY,
centerX: (second.pageX + first.pageX) * 0.5,
centerY: (second.pageY + first.pageY) * 0.5
}
};
var getEventVector = function(e) {
var pointers = e.pointers;
return getVector(pointers[0], pointers[1])
};
var getDistance = function(vector) {
return Math.sqrt(vector.x * vector.x + vector.y * vector.y)
};
var getScale = function(firstVector, secondVector) {
return getDistance(firstVector) / getDistance(secondVector)
};
var getRotation = function(firstVector, secondVector) {
var scalarProduct = firstVector.x * secondVector.x + firstVector.y * secondVector.y;
var distanceProduct = getDistance(firstVector) * getDistance(secondVector);
if (distanceProduct === 0)
return 0;
var sign = utils.sign(firstVector.x * secondVector.y - secondVector.x * firstVector.y);
var angle = Math.acos(fitIntoRange(scalarProduct / distanceProduct, -1, 1));
return sign * angle
};
var getTranslation = function(firstVector, secondVector) {
return {
x: firstVector.centerX - secondVector.centerX,
y: firstVector.centerY - secondVector.centerY
}
};
var TransformEmitter = events.Emitter.inherit({
configurate: function(data, eventName) {
if (eventName.indexOf(ZOOM) > -1)
DX.log("W0005", eventName, "15.1", "Use '" + eventName.replace(ZOOM, PINCH) + "' event instead");
this.callBase(data)
},
validatePointers: function(e) {
return events.hasTouches(e) > 1
},
start: function(e) {
this._accept(e);
var startVector = getEventVector(e);
this._startVector = startVector;
this._prevVector = startVector;
this._fireEventAliases(START_POSTFIX, e)
},
move: function(e) {
var currentVector = getEventVector(e),
eventArgs = this._getEventArgs(currentVector);
this._fireEventAliases(UPDATE_POSTFIX, e, eventArgs);
this._prevVector = currentVector
},
end: function(e) {
var eventArgs = this._getEventArgs(this._prevVector);
this._fireEventAliases(END_POSTFIX, e, eventArgs)
},
_getEventArgs: function(vector) {
return {
scale: getScale(vector, this._startVector),
deltaScale: getScale(vector, this._prevVector),
rotation: getRotation(vector, this._startVector),
deltaRotation: getRotation(vector, this._prevVector),
translation: getTranslation(vector, this._startVector),
deltaTranslation: getTranslation(vector, this._prevVector)
}
},
_fireEventAliases: function(eventPostfix, originalEvent, eventArgs) {
eventArgs = eventArgs || {};
$.each(eventAliases, $.proxy(function(_, eventAlias) {
var args = {};
$.each(eventAlias.args, function(name) {
if (name in eventArgs)
args[name] = eventArgs[name]
});
this._fireEvent(DX_PREFIX + eventAlias.name + eventPostfix, originalEvent, args)
}, this))
}
});
events.registerEmitter({
emitter: TransformEmitter,
events: $.map(eventAliases, function(eventAlias) {
var eventNames = [];
$.each([START_POSTFIX, UPDATE_POSTFIX, END_POSTFIX], function(_, eventPostfix) {
eventNames.push(DX_PREFIX + eventAlias.name + eventPostfix)
});
return eventNames
})
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.dblclick.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
utils = DX.utils,
DBLCLICK_EVENT_NAME = "dxdblclick",
DBLCLICK_NAMESPACE = "dxDblClick",
NAMESPACED_CLICK_EVENT = events.addNamespace("dxclick", DBLCLICK_NAMESPACE),
DBLCLICK_TIMEOUT = 300;
var DblClick = DX.Class.inherit({
ctor: function() {
this._handlerCount = 0;
this._forgetLastClick()
},
_forgetLastClick: function() {
this._firstClickTarget = null;
this._lastClickTimeStamp = -DBLCLICK_TIMEOUT
},
add: function() {
if (this._handlerCount <= 0)
$(document).on(NAMESPACED_CLICK_EVENT, $.proxy(this._clickHandler, this));
this._handlerCount++
},
_clickHandler: function(e) {
var timeStamp = e.timeStamp || $.now();
if (timeStamp - this._lastClickTimeStamp < DBLCLICK_TIMEOUT) {
events.fireEvent({
type: DBLCLICK_EVENT_NAME,
target: utils.closestCommonParent(this._firstClickTarget, e.target),
originalEvent: e
});
this._forgetLastClick()
}
else {
this._firstClickTarget = e.target;
this._lastClickTimeStamp = timeStamp
}
},
remove: function() {
this._handlerCount--;
if (this._handlerCount <= 0) {
this._forgetLastClick();
$(document).off(NAMESPACED_CLICK_EVENT)
}
}
});
events.registerEvent(DBLCLICK_EVENT_NAME, new DblClick)
})(jQuery, DevExpress);
/*! Module core, file ui.events.remove.js */
(function($) {
(function(cleanData) {
$.cleanData = function(elements) {
$.each(elements, function() {
$(this).triggerHandler("dxremove")
});
return cleanData.apply(this, arguments)
}
})($.cleanData)
})(jQuery);
/*! Module core, file ui.events.contextmenu.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
support = DX.support,
CONTEXTMENU_NAMESPACE = "dxContexMenu",
CONTEXTMENU_NAMESPACED_EVENT_NAME = events.addNamespace("contextmenu", CONTEXTMENU_NAMESPACE),
HOLD_NAMESPACED_EVENT_NAME = events.addNamespace("dxhold", CONTEXTMENU_NAMESPACE),
CONTEXTMENU_EVENT_NAME = "dxcontextmenu";
var ContextMenu = DX.Class.inherit({
setup: function(element, data) {
var $element = $(element);
$element.on(CONTEXTMENU_NAMESPACED_EVENT_NAME, $.proxy(this._contextMenuHandler, this));
if (support.touch || DX.devices.isSimulator())
$element.on(HOLD_NAMESPACED_EVENT_NAME, $.proxy(this._holdHandler, this))
},
_holdHandler: function(e) {
if (events.isMouseEvent(e) && !DX.devices.isSimulator())
return;
this._fireContextMenu(e)
},
_contextMenuHandler: function(e) {
e = this._fireContextMenu(e);
if (!e.cancel)
e.preventDefault()
},
_fireContextMenu: function(e) {
return events.fireEvent({
type: CONTEXTMENU_EVENT_NAME,
originalEvent: e
})
},
teardown: function(element) {
$(element).off("." + CONTEXTMENU_NAMESPACE)
}
});
events.registerEvent(CONTEXTMENU_EVENT_NAME, new ContextMenu)
})(jQuery, DevExpress);
/*! Module core, file ui.widget.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
UI_FEEDBACK = "UIFeedback",
WIDGET_CLASS = "dx-widget",
ACTIVE_STATE_CLASS = "dx-state-active",
DISABLED_STATE_CLASS = "dx-state-disabled",
INVISIBLE_STATE_CLASS = "dx-state-invisible",
HOVER_STATE_CLASS = "dx-state-hover",
FOCUSED_STATE_CLASS = "dx-state-focused",
FEEDBACK_SHOW_TIMEOUT = 30,
FEEDBACK_HIDE_TIMEOUT = 400,
HOVER_START = "dxhoverstart",
HOVER_END = "dxhoverend",
FOCUS_NAMESPACE = "Focus",
ANONYMOUS_TEMPLATE_NAME = "template",
TEXT_NODE = 3,
TEMPLATE_SELECTOR = "[data-options*='dxTemplate']",
TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";
var DynamicTemplate = ui.TemplateBase.inherit({
ctor: function(compileFunction, owner) {
this.callBase($(), owner);
this._compileFunction = compileFunction
},
_renderCore: function(data, index, container) {
if (data === undefined && index === undefined) {
data = container;
container = undefined
}
var compiledTemplate = index === undefined ? this._compileFunction(data, container) : this._compileFunction(data, index, container);
var renderResult = compiledTemplate.render(data, container, index);
if (compiledTemplate.owner() === this)
compiledTemplate.dispose();
return renderResult
}
});
var EmptyTemplate = ui.TemplateBase.inherit({
ctor: function(owner) {
this.callBase($(), owner)
},
_renderCore: function(data, index, container) {
return $()
}
});
var RendererTemplate = ui.TemplateBase.inherit({_renderCore: function() {
return this._element
}});
ui.Widget = DX.DOMComponent.inherit({
NAME: "Widget",
_supportedKeys: function() {
return {}
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {contentReadyAction: {
since: "14.2",
alias: "onContentReady"
}})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
disabled: false,
visible: true,
hint: undefined,
activeStateEnabled: false,
onContentReady: null,
hoverStateEnabled: false,
focusStateEnabled: false,
tabIndex: 0,
accessKey: null,
onFocusIn: null,
onFocusOut: null,
templateProvider: ui.TemplateProvider,
_keyboardProcessor: undefined,
_templates: {}
})
},
_init: function() {
this.callBase();
this._feedbackShowTimeout = FEEDBACK_SHOW_TIMEOUT;
this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT;
this._tempTemplates = [];
this._dynamicTemplates = {};
this._initTemplates();
this._initContentReadyAction();
this._initFocusActions()
},
_initTemplates: function() {
this._extractTemplates();
this._extractAnonimousTemplate()
},
_extractTemplates: function() {
var templates = this.option("_templates"),
templateElements = this.element().contents().filter(TEMPLATE_SELECTOR);
var templatesMap = {};
templateElements.each(function(_, template) {
var templateOptions = utils.getElementOptions(template).dxTemplate;
if (!templateOptions)
return;
if (!templateOptions.name)
throw DX.Error("E0023");
$(template).addClass(TEMPLATE_WRAPPER_CLASS).detach();
templatesMap[templateOptions.name] = templatesMap[templateOptions.name] || [];
templatesMap[templateOptions.name].push(template)
});
$.each(templatesMap, $.proxy(function(templateName, value) {
var deviceTemplate = this._findTemplateByDevice(value);
if (deviceTemplate)
templates[templateName] = this._createTemplate(deviceTemplate, this)
}, this))
},
_findTemplateByDevice: function(templates) {
var suitableTemplate = DX.utils.findBestMatches(DX.devices.current(), templates, function(template) {
return utils.getElementOptions(template).dxTemplate
})[0];
$.each(templates, function(index, template) {
if (template !== suitableTemplate)
$(template).remove()
});
return suitableTemplate
},
_extractAnonimousTemplate: function() {
var templates = this.option("_templates"),
anonimiousTemplateName = this._getAnonimousTemplateName(),
$anonimiousTemplate = this.element().contents().detach();
var $notJunkTemplateContent = $anonimiousTemplate.filter(function(_, element) {
var isTextNode = element.nodeType === TEXT_NODE,
isEmptyText = $.trim($(element).text()).length < 1;
return !(isTextNode && isEmptyText)
}),
onlyJunkTemplateContent = $notJunkTemplateContent.length < 1;
if (!templates[anonimiousTemplateName] && !onlyJunkTemplateContent)
templates[anonimiousTemplateName] = this._createTemplate($anonimiousTemplate, this)
},
_getAriaTarget: function() {
return this.element()
},
_getAnonimousTemplateName: function() {
return ANONYMOUS_TEMPLATE_NAME
},
_getTemplateByOption: function(optionName) {
return this._getTemplate(this.option(optionName))
},
_getTemplate: function(templateSource) {
if ($.isFunction(templateSource)) {
var that = this;
return new DynamicTemplate(function() {
var templateSourceResult = templateSource.apply(that, arguments);
if (utils.isDefined(templateSourceResult))
return that._acquireTemplate(templateSourceResult, this, true);
else
return new EmptyTemplate
}, this)
}
return this._acquireTemplate(templateSource, this)
},
_acquireTemplate: function(templateSource, owner, preferRenderer) {
if (templateSource == null)
return this._createTemplate(utils.normalizeTemplateElement(templateSource), owner);
if (templateSource instanceof ui.TemplateBase)
return templateSource;
if (templateSource.nodeType || templateSource.jquery) {
templateSource = $(templateSource);
if (preferRenderer && !templateSource.is("script"))
return new RendererTemplate(templateSource, owner);
return this._createTemplate(templateSource, owner)
}
if (typeof templateSource === "string") {
var userTemplate = this.option("_templates")[templateSource];
if (userTemplate)
return userTemplate;
var dynamicTemplate = this._dynamicTemplates[templateSource];
if (dynamicTemplate)
return dynamicTemplate;
var defaultTemplate = this.option("templateProvider").getTemplates(this)[templateSource];
if (defaultTemplate)
return defaultTemplate;
return this._createTemplate(utils.normalizeTemplateElement(templateSource), owner)
}
return this._acquireTemplate(templateSource.toString(), owner)
},
_createTemplate: function(element, owner) {
var template = this.option("templateProvider").createTemplate(element, owner);
this._tempTemplates.push(template);
return template
},
_cleanTemplates: function() {
var that = this;
$.each(this.option("_templates"), function(_, template) {
if (that === template.owner())
template.dispose()
});
$.each(this._tempTemplates, function(_, template) {
template.dispose()
})
},
_initContentReadyAction: function() {
this._contentReadyAction = this._createActionByOption("onContentReady", {excludeValidators: ["designMode", "disabled", "readOnly"]})
},
_initFocusActions: function() {
var focusInAction = this._createActionByOption("onFocusIn", {excludeValidators: ["readOnly"]});
var focusOutAction = this._createActionByOption("onFocusOut", {excludeValidators: ["readOnly"]});
this._focusInAction = this._createAction(function(e) {
e.component._focusInHandler(e.jQueryEvent);
focusInAction(e)
}, {excludeValidators: ["readOnly"]});
this._focusOutAction = this._createAction(function(e) {
e.component._focusOutHandler(e.jQueryEvent);
focusOutAction(e)
}, {excludeValidators: ["readOnly"]})
},
_render: function() {
this.element().addClass(WIDGET_CLASS);
this.callBase();
this._toggleDisabledState(this.option("disabled"));
this._toggleVisibility(this.option("visible"));
this._renderHint();
this._renderContent();
this._renderFocusState();
this._attachFeedbackEvents();
this._attachHoverEvents()
},
_renderHint: function() {
utils.toggleAttr(this.element(), "title", this.option("hint"))
},
_renderContent: function() {
this._renderContentImpl();
this._fireContentReadyAction()
},
_renderContentImpl: $.noop,
_fireContentReadyAction: function() {
this._contentReadyAction()
},
_dispose: function() {
this._cleanTemplates();
this._contentReadyAction = null;
this.callBase()
},
_clean: function() {
this._cleanFocusState();
this.callBase();
this.element().empty()
},
_toggleVisibility: function(visible) {
this.element().toggleClass(INVISIBLE_STATE_CLASS, !visible);
this.setAria("hidden", !visible || undefined)
},
_renderFocusState: function() {
if (!this.option("focusStateEnabled") || this.option("disabled"))
return;
this._renderFocusTarget();
this._attachFocusEvents();
this._attachKeyboardEvents();
this._renderAccessKey()
},
_renderAccessKey: function() {
var focusTarget = this._focusTarget();
focusTarget.attr("accesskey", this.option("accessKey"));
var clickNamespace = events.addNamespace("dxclick", UI_FEEDBACK);
focusTarget.off(clickNamespace);
this.option("accessKey") && focusTarget.on(clickNamespace, $.proxy(function(e) {
if (e.screenX === 0 && !e.offsetX && e.pageX === 0) {
e.stopImmediatePropagation();
this.focus()
}
}, this))
},
_eventBindingTarget: function() {
return this.element()
},
_focusTarget: function() {
return this._getActiveElement()
},
_getActiveElement: function() {
var activeElement = this._eventBindingTarget();
if (this._activeStateUnit)
activeElement = activeElement.find(this._activeStateUnit).not("." + DISABLED_STATE_CLASS);
return activeElement
},
_renderFocusTarget: function() {
this._focusTarget().attr("tabindex", this.option("tabIndex"))
},
_keyboardEventBindingTarget: function() {
return this._eventBindingTarget()
},
_attachFocusEvents: function() {
var focusInEvent = events.addNamespace("focusin", this.NAME + FOCUS_NAMESPACE);
var focusOutEvent = events.addNamespace("focusout", this.NAME + FOCUS_NAMESPACE);
var beforeactivateEventNamespace = events.addNamespace("beforeactivate", this.NAME + FOCUS_NAMESPACE);
this._focusTarget().off("." + this.NAME + FOCUS_NAMESPACE).on(focusInEvent, $.proxy(function(e) {
this._focusInAction({jQueryEvent: e})
}, this)).on(focusOutEvent, $.proxy(function(e) {
this._focusOutAction({jQueryEvent: e})
}, this)).on(beforeactivateEventNamespace, function(e) {
if (!$(e.target).is(":dx-focusable"))
e.preventDefault()
})
},
_focusInHandler: function(e) {
this._updateFocusState(e, true)
},
_focusOutHandler: function(e) {
this._updateFocusState(e, false)
},
_updateFocusState: function(e, isFocused) {
var currentTarget = e.currentTarget,
focusTargets = this._focusTarget();
if ($.inArray(currentTarget, focusTargets) !== -1)
$(e.currentTarget).toggleClass(FOCUSED_STATE_CLASS, isFocused)
},
_attachKeyboardEvents: function() {
var processor = this.option("_keyboardProcessor") || new ui.KeyboardProcessor({
element: this._keyboardEventBindingTarget(),
focusTarget: this._focusTarget()
});
this._keyboardProcessor = processor.reinitialize(this._keyboardHandler, this)
},
_keyboardHandler: function(options) {
var e = options.originalEvent,
key = options.key;
var keys = this._supportedKeys(),
func = keys[key];
if (func !== undefined) {
var handler = $.proxy(func, this);
return handler(e) || false
}
else
return true
},
_refreshFocusState: function() {
this._cleanFocusState();
this._renderFocusState()
},
_cleanFocusState: function() {
var $element = this._focusTarget();
$element.off("." + this.NAME + FOCUS_NAMESPACE);
$element.removeClass(FOCUSED_STATE_CLASS);
$element.removeAttr("tabindex");
if (this._keyboardProcessor)
this._keyboardProcessor.dispose()
},
_attachHoverEvents: function() {
var that = this,
hoverableSelector = that._activeStateUnit,
nameStart = events.addNamespace(HOVER_START, UI_FEEDBACK),
nameEnd = events.addNamespace(HOVER_END, UI_FEEDBACK);
that._eventBindingTarget().off(nameStart, hoverableSelector).off(nameEnd, hoverableSelector);
if (that.option("hoverStateEnabled")) {
var startAction = new DX.Action(function(args) {
that._hoverStartHandler(args.event);
var $target = args.element;
that._refreshHoveredElement($target)
});
that._eventBindingTarget().on(nameStart, hoverableSelector, function(e) {
startAction.execute({
element: $(e.target),
event: e
})
}).on(nameEnd, hoverableSelector, function(e) {
that._hoverEndHandler(e);
that._forgetHoveredElement()
})
}
else
that._toggleHoverClass(false)
},
_hoverStartHandler: $.noop,
_hoverEndHandler: $.noop,
_attachFeedbackEvents: function() {
var that = this,
feedbackSelector = that._activeStateUnit,
activeEventName = events.addNamespace("dxactive", UI_FEEDBACK),
inactiveEventName = events.addNamespace("dxinactive", UI_FEEDBACK);
that._eventBindingTarget().off(activeEventName, feedbackSelector).off(inactiveEventName, feedbackSelector);
if (that.option("activeStateEnabled")) {
var feedbackActionHandler = function(args) {
var $element = args.element,
value = args.value;
that._toggleActiveState($element, value)
};
var feedbackAction = new DX.Action(function(args) {
feedbackActionHandler(args)
}),
feedbackActionDisabled = new DX.Action(function(args) {
feedbackActionHandler(args)
}, {excludeValidators: ["disabled", "readOnly"]});
that._eventBindingTarget().on(activeEventName, feedbackSelector, {timeout: that._feedbackShowTimeout}, function(e) {
feedbackAction.execute({
element: $(e.currentTarget),
value: true
})
}).on(inactiveEventName, feedbackSelector, {timeout: that._feedbackHideTimeout}, function(e) {
feedbackActionDisabled.execute({
element: $(e.currentTarget),
value: false
})
})
}
},
_toggleActiveState: function($element, value) {
this._toggleHoverClass(!value);
$element.toggleClass(ACTIVE_STATE_CLASS, value)
},
_refreshHoveredElement: function(hoveredElement) {
var selector = this._activeStateUnit || this.element();
this._forgetHoveredElement();
this._hoveredElement = hoveredElement.closest(selector);
this._toggleHoverClass(true)
},
_forgetHoveredElement: function() {
this._toggleHoverClass(false);
delete this._hoveredElement
},
_toggleHoverClass: function(value) {
if (this._hoveredElement)
this._hoveredElement.toggleClass(HOVER_STATE_CLASS, value && this.option("hoverStateEnabled"))
},
_toggleDisabledState: function(value) {
this.element().toggleClass(DISABLED_STATE_CLASS, Boolean(value));
this._toggleHoverClass(!value);
this.setAria("disabled", value || undefined)
},
_setWidgetOption: function(widgetName, args) {
if (!this[widgetName])
return;
if ($.isPlainObject(args[0])) {
$.each(args[0], $.proxy(function(option, value) {
this._setWidgetOption(widgetName, [option, value])
}, this));
return
}
var optionName = args[0];
var value = args[1];
if (args.length === 1)
value = this.option(optionName);
var widgetOptionMap = this[widgetName + "OptionMap"];
this[widgetName].option(widgetOptionMap ? widgetOptionMap(optionName) : optionName, value)
},
_createComponent: function(element, name, config) {
config = config || {};
this._extendConfig(config, {
templateProvider: this.option("templateProvider"),
_templates: this.option("_templates")
});
return this.callBase(element, name, config)
},
_optionChanged: function(args) {
switch (args.name) {
case"disabled":
this._toggleDisabledState(args.value);
this._refreshFocusState();
break;
case"hint":
this._renderHint();
break;
case"activeStateEnabled":
this._attachFeedbackEvents();
break;
case"hoverStateEnabled":
this._attachHoverEvents();
break;
case"tabIndex":
case"_keyboardProcessor":
case"focusStateEnabled":
this._refreshFocusState();
break;
case"onFocusIn":
case"onFocusOut":
this._initFocusActions();
break;
case"accessKey":
this._renderAccessKey();
break;
case"visible":
var visible = args.value;
this._toggleVisibility(visible);
if (this._isVisibilityChangeSupported())
this._visibilityChanged(visible);
break;
case"onContentReady":
this._initContentReadyAction();
break;
case"_templates":
case"templateProvider":
this._refresh();
break;
default:
this.callBase(args)
}
},
beginUpdate: function() {
this._ready(false);
this.callBase()
},
endUpdate: function() {
this.callBase();
if (this._initialized)
this._ready(true)
},
_ready: function(value) {
if (arguments.length === 0)
return this._isReady;
this._isReady = value
},
setAria: function() {
var setAttribute = function(option) {
var attrName = $.inArray(option.name, ["role", "id"]) + 1 ? option.name : "aria-" + option.name,
attrValue = option.value;
if (attrValue === null || attrValue === undefined)
attrValue = undefined;
else
attrValue = attrValue.toString();
utils.toggleAttr(option.target, attrName, attrValue)
};
if (!$.isPlainObject(arguments[0]))
setAttribute({
name: arguments[0],
value: arguments[1],
target: arguments[2] || this._getAriaTarget()
});
else {
var $target = arguments[1] || this._getAriaTarget();
$.each(arguments[0], function(key, value) {
setAttribute({
name: key,
value: value,
target: $target
})
})
}
},
isReady: function() {
return this._ready()
},
repaint: function() {
this._refresh()
},
focus: function() {
this._focusTarget().focus()
},
registerKeyHandler: function(key, handler) {
var currentKeys = this._supportedKeys(),
addingKeys = {};
addingKeys[key] = handler;
this._supportedKeys = function() {
return $.extend(currentKeys, addingKeys)
}
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.editor.js */
(function($, DX, undefined) {
var ui = DX.ui,
READONLY_STATE_CLASS = "dx-state-readonly",
INVALID_CLASS = "dx-invalid",
INVALID_MESSAGE = "dx-invalid-message",
INVALID_MESSAGE_AUTO = "dx-invalid-message-auto",
INVALID_MESSAGE_ALWAYS = "dx-invalid-message-always";
ui.validation = ui.validation || {};
ui.validation.findGroup = function() {
var group = this.option("validationGroup"),
$dxGroup;
if (!group) {
$dxGroup = this.element().parents(".dx-validationgroup:first");
if ($dxGroup.length)
group = $dxGroup.dxValidationGroup("instance");
else
group = this._modelByElement(this.element())
}
return group
};
ui.Editor = ui.Widget.inherit({
_init: function() {
this.callBase();
this.validationRequest = $.Callbacks();
var $element = this.element();
if ($element) {
$element.data("dx-validation-target", this);
this.on("disposing", function() {
$element.data("dx-validation-target", null)
})
}
this._createValueChangeAction()
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {valueChangeAction: {
since: "14.2",
alias: "onValueChanged",
message: "'onValueChanged' option instead"
}})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
value: null,
onValueChanged: null,
activeStateEnabled: true,
readOnly: false,
isValid: true,
validationError: null,
validationMessageMode: "auto",
validationTooltipOffset: {
h: 0,
v: -10
}
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function(device) {
return device.platform === "android"
},
options: {invalidTooltipOffset: {
h: 9,
v: -7
}}
}, {
device: {platform: "win8"},
options: {invalidTooltipOffset: {
h: 9,
v: -4
}}
}])
},
_attachKeyboardEvents: function() {
if (this.option("readOnly"))
return;
this.callBase.apply(this, arguments);
this._attachChildKeyboardEvents()
},
_attachChildKeyboardEvents: $.noop,
_setOptionsByReference: function() {
this.callBase();
$.extend(this._optionsByReference, {validationError: true})
},
_createValueChangeAction: function() {
this._valueChangeAction = this._createActionByOption("onValueChanged", {excludeValidators: ["disabled", "readOnly"]})
},
_suppressValueChangeAction: function() {
this._valueChangeActionSuppressed = true
},
_resumeValueChangeAction: function() {
this._valueChangeActionSuppressed = false
},
_render: function() {
this._renderValidationState();
this._toggleReadOnlyState();
this.callBase()
},
_raiseValueChangeAction: function(value, previousValue, extraArguments) {
this._valueChangeAction(this._valueChangeArgs(value, previousValue))
},
_valueChangeArgs: function(value, previousValue) {
return {
value: value,
previousValue: previousValue,
jQueryEvent: this._valueChangeEventInstance
}
},
_saveValueChangeEvent: function(e) {
this._valueChangeEventInstance = e
},
_renderValidationState: function() {
var isValid = this.option("isValid"),
validationError = this.option("validationError"),
validationMessageMode = this.option("validationMessageMode"),
$element = this.element();
$element.toggleClass(INVALID_CLASS, !isValid);
this.setAria("invalid", !isValid || undefined);
if (this._$validationMessage) {
this._$validationMessage.remove();
this._$validationMessage = null
}
if (!isValid && validationError && validationError.message) {
this._$validationMessage = $("
", {"class": INVALID_MESSAGE}).text(validationError.message).appendTo($element);
this._createComponent(this._$validationMessage, "dxTooltip", {
target: $element,
container: $element,
position: this._getValidationTooltipPosition("below"),
closeOnOutsideClick: false,
closeOnTargetScroll: false,
animation: null,
visible: true
});
this._$validationMessage.toggleClass(INVALID_MESSAGE_AUTO, validationMessageMode === "auto").toggleClass(INVALID_MESSAGE_ALWAYS, validationMessageMode === "always")
}
},
_getValidationTooltipPosition: function(positionRequest) {
var rtlEnabled = this.option("rtlEnabled"),
tooltipPositionSide = rtlEnabled ? "right" : "left",
tooltipOriginalOffset = this.option("validationTooltipOffset"),
tooltipOffset = {
h: tooltipOriginalOffset.h,
v: tooltipOriginalOffset.v
},
verticalPositions = positionRequest === "below" ? [" top", " bottom"] : [" bottom", " top"];
if (rtlEnabled)
tooltipOffset.h = -tooltipOffset.h;
if (positionRequest !== "below")
tooltipOffset.v = -tooltipOffset.v;
return {
offset: tooltipOffset,
my: tooltipPositionSide + verticalPositions[0],
at: tooltipPositionSide + verticalPositions[1],
collision: "none"
}
},
_toggleReadOnlyState: function() {
this.element().toggleClass(READONLY_STATE_CLASS, this.option("readOnly"));
this.setAria("readonly", this.option("readOnly") || undefined)
},
_optionChanged: function(args) {
switch (args.name) {
case"onValueChanged":
this._createValueChangeAction();
break;
case"isValid":
case"validationError":
case"validationMessageMode":
this._renderValidationState();
break;
case"readOnly":
this._toggleReadOnlyState();
this._refreshFocusState();
break;
case"value":
if (!this._valueChangeActionSuppressed) {
this._raiseValueChangeAction(args.value, args.previousValue);
this._saveValueChangeEvent(undefined)
}
if (args.value != args.previousValue)
this.validationRequest.fire({
value: args.value,
editor: this
});
break;
default:
this.callBase(args)
}
},
reset: function() {
this.option("value", null)
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.CollectionWidget.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events;
var COLLECTION_CLASS = "dx-collection",
ITEM_CLASS = "dx-item",
CONTENT_CLASS_POSTFIX = "-content",
ITEM_CONTENT_PLACEHOLDER_CLASS = "dx-item-content-placeholder",
ITEM_DATA_KEY = "dxItemData",
ITEM_TEMPLATE_ID_PREFIX = "tmpl-",
ITEMS_SELECTOR = "[data-options*='dxItem']",
SELECTED_ITEM_CLASS = "dx-item-selected",
FOCUSED_STATE_CLASS = "dx-state-focused",
ITEM_RESPONSE_WAIT_CLASS = "dx-item-response-wait",
EMPTY_COLLECTION = "dx-empty-collection",
TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";
var FOCUS_UP = "up",
FOCUS_DOWN = "down",
FOCUS_LEFT = "left",
FOCUS_RIGHT = "right",
FOCUS_PAGE_UP = "pageup",
FOCUS_PAGE_DOWN = "pagedown",
FOCUS_LAST = "last",
FOCUS_FIRST = "first";
var CollectionWidget = ui.Widget.inherit({
NAME: "CollectionWidget",
_activeStateUnit: "." + ITEM_CLASS,
_supportedKeys: function() {
var click = function(e) {
var $itemElement = this.option("focusedElement");
if (!$itemElement)
return;
e.target = $itemElement;
e.currentTarget = $itemElement;
this._itemClickHandler(e)
},
move = function(location, e) {
e.preventDefault();
e.stopPropagation();
this._moveFocus(location, e)
};
return $.extend(this.callBase(), {
space: click,
enter: click,
leftArrow: $.proxy(move, this, FOCUS_LEFT),
rightArrow: $.proxy(move, this, FOCUS_RIGHT),
upArrow: $.proxy(move, this, FOCUS_UP),
downArrow: $.proxy(move, this, FOCUS_DOWN),
pageUp: $.proxy(move, this, FOCUS_UP),
pageDown: $.proxy(move, this, FOCUS_DOWN),
home: $.proxy(move, this, FOCUS_FIRST),
end: $.proxy(move, this, FOCUS_LAST)
})
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {
itemClickAction: {
since: "14.2",
alias: "onItemClick"
},
itemHoldAction: {
since: "14.2",
alias: "onItemHold"
},
itemRenderedAction: {
since: "14.2",
alias: "onItemRendered"
},
itemRender: {
since: "14.2",
alias: "itemTemplate"
}
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
selectOnFocus: false,
loopItemFocus: true,
items: [],
itemTemplate: "item",
onItemRendered: null,
onItemClick: null,
onItemHold: null,
itemHoldTimeout: 750,
onItemContextMenu: null,
onFocusedItemChanged: null,
noDataText: Globalize.localize("dxCollectionWidget-noDataText"),
dataSource: null,
_itemAttributes: {},
itemTemplateProperty: "template",
focusOnSelectedItem: true,
focusedElement: null
})
},
_getAnonimousTemplateName: function() {
return "item"
},
_init: function() {
this.callBase();
this._cleanRenderedItems();
this._refreshDataSource()
},
_initTemplates: function() {
this._initItemsFromMarkup();
this.callBase()
},
_initItemsFromMarkup: function() {
var $items = this.element().contents().filter(ITEMS_SELECTOR);
if (!$items.length || this.option("items").length)
return;
var items = $.map($items, $.proxy(function(item) {
var $item = $(item);
var result = utils.getElementOptions(item).dxItem;
var isTemplateRequired = $.trim($item.html()) && !result.template;
if (isTemplateRequired)
result.template = this._prepareItemTemplate($item);
else
$item.remove();
return result
}, this));
this.option("items", items)
},
_prepareItemTemplate: function($item) {
var templateId = ITEM_TEMPLATE_ID_PREFIX + new DX.data.Guid;
var templateOptions = "dxTemplate: { name: \"" + templateId + "\" }";
$item.attr("data-options", templateOptions).data("options", templateOptions);
return templateId
},
_dataSourceOptions: function() {
return {paginate: false}
},
_cleanRenderedItems: function() {
this._renderedItemsCount = 0
},
_focusTarget: function() {
return this.element()
},
_focusInHandler: function(e) {
this.callBase.apply(this, arguments);
var $focusedElement = this.option("focusedElement");
if ($focusedElement && $focusedElement.length)
this._setFocusedItem($focusedElement);
else {
var $activeItem = this._getActiveItem();
this.option("focusedElement", $activeItem)
}
},
_focusOutHandler: function(e) {
this.callBase.apply(this, arguments);
var $target = this.option("focusedElement");
if ($target)
$target.removeClass(FOCUSED_STATE_CLASS)
},
_getActiveItem: function(last) {
var $focusedElement = this.option("focusedElement");
if ($focusedElement && $focusedElement.length)
return $focusedElement;
var index = this.option("focusOnSelectedItem") ? this.option("selectedIndex") : 0,
activeElements = this._getActiveElement(),
lastIndex = activeElements.length - 1;
if (index < 0)
index = last ? lastIndex : 0;
return activeElements.eq(index)
},
_renderFocusTarget: function() {
this.callBase.apply(this, arguments);
this._refreshActiveDescendant()
},
_moveFocus: function(location) {
var $items = this._itemElements().filter(":visible").not(".dx-state-disabled"),
$newTarget;
switch (location) {
case FOCUS_PAGE_UP:
case FOCUS_UP:
$newTarget = this._prevItem($items);
break;
case FOCUS_PAGE_DOWN:
case FOCUS_DOWN:
$newTarget = this._nextItem($items);
break;
case FOCUS_RIGHT:
$newTarget = this.option("rtlEnabled") ? this._prevItem($items) : this._nextItem($items);
break;
case FOCUS_LEFT:
$newTarget = this.option("rtlEnabled") ? this._nextItem($items) : this._prevItem($items);
break;
case FOCUS_FIRST:
$newTarget = $items.first();
break;
case FOCUS_LAST:
$newTarget = $items.last();
break;
default:
return false
}
if ($newTarget.length !== 0)
this.option("focusedElement", $newTarget)
},
_prevItem: function($items) {
var $target = this._getActiveItem(),
targetIndex = $items.index($target),
$last = $items.last(),
$item = $($items[targetIndex - 1]),
loop = this.option("loopItemFocus");
if ($item.length === 0 && loop)
$item = $last;
return $item
},
_nextItem: function($items) {
var $target = this._getActiveItem(true),
targetIndex = $items.index($target),
$first = $items.first(),
$item = $($items[targetIndex + 1]),
loop = this.option("loopItemFocus");
if ($item.length === 0 && loop)
$item = $first;
return $item
},
_selectFocusedItem: function($target) {
this.selectItem($target)
},
_removeFocusedItem: function($target) {
if ($target && $target.length) {
$target.removeClass(FOCUSED_STATE_CLASS);
$target.removeAttr("id")
}
},
_refreshActiveDescendant: function() {
this.setAria("activedescendant", "");
this.setAria("activedescendant", this.getFocusedItemId())
},
_setFocusedItem: function($target) {
if (!$target || !$target.length)
return;
$target.attr("id", this.getFocusedItemId());
$target.addClass(FOCUSED_STATE_CLASS);
this.onFocusedItemChanged(this.getFocusedItemId());
this._refreshActiveDescendant();
if (this.option("selectOnFocus"))
this._selectFocusedItem($target)
},
_optionChanged: function(args) {
switch (args.name) {
case"items":
case"_itemAttributes":
case"itemTemplateProperty":
this._cleanRenderedItems();
this._invalidate();
break;
case"dataSource":
this._refreshDataSource();
if (!this._dataSource)
this.option("items", []);
this._renderEmptyMessage();
break;
case"noDataText":
this._renderEmptyMessage();
break;
case"itemTemplate":
this._invalidate();
break;
case"onItemRendered":
this._createItemRenderAction();
break;
case"onItemClick":
break;
case"onItemHold":
case"itemHoldTimeout":
this._attachHoldEvent();
break;
case"onItemContextMenu":
this._attachContextMenuEvent();
break;
case"onFocusedItemChanged":
this.onFocusedItemChanged = this._createActionByOption("onFocusedItemChanged");
break;
case"selectOnFocus":
case"loopItemFocus":
case"focusOnSelectedItem":
break;
case"focusedElement":
this._removeFocusedItem(args.previousValue);
this._setFocusedItem(args.value);
break;
default:
this.callBase(args)
}
},
_loadNextPage: function() {
var dataSource = this._dataSource;
this._expectNextPageLoading();
dataSource.pageIndex(1 + dataSource.pageIndex());
return dataSource.load()
},
_expectNextPageLoading: function() {
this._startIndexForAppendedItems = 0
},
_expectLastItemLoading: function() {
this._startIndexForAppendedItems = -1
},
_forgetNextPageLoading: function() {
this._startIndexForAppendedItems = null
},
_dataSourceChangedHandler: function(newItems) {
var items = this.option("items");
if (this._initialized && items && this._shouldAppendItems()) {
this._renderedItemsCount = items.length;
if (!this._isLastPage() || this._startIndexForAppendedItems !== -1)
this.option().items = items.concat(newItems.slice(this._startIndexForAppendedItems));
this._forgetNextPageLoading();
this._renderContent();
this._renderFocusTarget()
}
else
this.option("items", newItems)
},
_dataSourceLoadErrorHandler: function() {
this._forgetNextPageLoading();
this.option("items", this.option("items"))
},
_shouldAppendItems: function() {
return this._startIndexForAppendedItems != null && this._allowDinamicItemsAppend()
},
_allowDinamicItemsAppend: function() {
return false
},
_clean: function() {
this._cleanFocusState();
this._cleanItemContainer()
},
_cleanItemContainer: function() {
this._itemContainer().empty()
},
_refresh: function() {
this._cleanRenderedItems();
this.callBase.apply(this, arguments)
},
_itemContainer: function() {
return this.element()
},
_itemClass: function() {
return ITEM_CLASS
},
_itemContentClass: function() {
return this._itemClass() + CONTENT_CLASS_POSTFIX
},
_selectedItemClass: function() {
return SELECTED_ITEM_CLASS
},
_itemResponseWaitClass: function() {
return ITEM_RESPONSE_WAIT_CLASS
},
_itemSelector: function() {
return "." + this._itemClass()
},
_itemDataKey: function() {
return ITEM_DATA_KEY
},
_itemElements: function() {
return this._itemContainer().find(this._itemSelector())
},
_render: function() {
this.callBase();
this.element().addClass(COLLECTION_CLASS);
this._attachClickEvent();
this._attachHoldEvent();
this._attachContextMenuEvent();
this.onFocusedItemChanged = this._createActionByOption("onFocusedItemChanged")
},
_attachClickEvent: function() {
var itemSelector = this._itemSelector(),
clickEventNamespace = events.addNamespace("dxclick", this.NAME),
pointerDownEventNamespace = events.addNamespace("dxpointerdown", this.NAME),
that = this;
var pointerDownAction = new DX.Action(function(args) {
var event = args.event;
that._itemPointerDownHandler(event)
});
this._itemContainer().off(clickEventNamespace, itemSelector).off(pointerDownEventNamespace, itemSelector).on(clickEventNamespace, itemSelector, $.proxy(this._itemClickHandler, this)).on(pointerDownEventNamespace, itemSelector, function(e) {
pointerDownAction.execute({
element: $(e.target),
event: e
})
})
},
_itemClickHandler: function(e) {
this._itemJQueryEventHandler(e, "onItemClick")
},
_itemPointerDownHandler: function(e) {
if (!this.option("focusStateEnabled"))
return;
var elementClass = this._itemClass(),
$target = $(e.target).closest("." + elementClass);
if ($target.hasClass(elementClass))
this.option("focusedElement", $target)
},
_attachHoldEvent: function() {
var $itemContainer = this._itemContainer(),
itemSelector = this._itemSelector(),
eventName = events.addNamespace("dxhold", this.NAME);
$itemContainer.off(eventName, itemSelector);
if (this._shouldAttachHoldEvent())
$itemContainer.on(eventName, itemSelector, {timeout: this._getHoldTimeout()}, $.proxy(this._itemHoldHandler, this))
},
_getHoldTimeout: function() {
return this.option("itemHoldTimeout")
},
_shouldAttachHoldEvent: function() {
return this.option("onItemHold")
},
_itemHoldHandler: function(e) {
this._itemJQueryEventHandler(e, "onItemHold")
},
_attachContextMenuEvent: function() {
var $itemContainer = this._itemContainer(),
itemSelector = this._itemSelector(),
eventName = events.addNamespace("dxcontextmenu", this.NAME);
$itemContainer.off(eventName, itemSelector);
if (this._shouldAttachContextMenuEvent())
$itemContainer.on(eventName, itemSelector, $.proxy(this._itemContextMenuHandler, this))
},
_shouldAttachContextMenuEvent: function() {
return this.option("onItemContextMenu")
},
_itemContextMenuHandler: function(e) {
this._itemJQueryEventHandler(e, "onItemContextMenu")
},
_renderContentImpl: function() {
var items = this.option("items") || [];
if (this._renderedItemsCount)
this._renderItems(items.slice(this._renderedItemsCount));
else
this._renderItems(items)
},
_renderItems: function(items) {
if (items.length)
$.each(items, $.proxy(this._renderItem, this));
this._renderEmptyMessage()
},
_renderItem: function(index, itemData, $container) {
$container = $container || this._itemContainer();
var $itemFrame = this._renderItemFrame(index, itemData, $container);
this._setElementData($itemFrame, itemData);
var $itemContent = $itemFrame.find("." + ITEM_CONTENT_PLACEHOLDER_CLASS);
$itemContent.removeClass(ITEM_CONTENT_PLACEHOLDER_CLASS);
$itemContent = this._renderItemContent(index, itemData, $itemContent);
this._postprocessRenderItem({
itemElement: $itemFrame,
itemContent: $itemContent,
itemData: itemData,
itemIndex: index
});
this._executeItemRenderAction(index, itemData, $itemFrame);
this._attachItemClickEvent(itemData, $itemFrame);
return $itemFrame.attr(this.option("_itemAttributes"))
},
_attachItemClickEvent: function(itemData, $itemElement) {
if (!itemData || !itemData.onClick)
return;
$itemElement.on("dxclick", $.proxy(function(e) {
this._itemEventHandlerByHandler($itemElement, itemData.onClick, {jQueryEvent: e})
}, this))
},
_renderItemContent: function(index, itemData, $container) {
var $itemNode = itemData && itemData.node;
var itemTemplateName = this._getItemTemplateName(itemData);
var itemTemplate = this._getTemplate(itemTemplateName, itemData, index, $container);
var renderArgs = {
index: index,
item: itemData,
container: $container
};
if ($itemNode) {
$container.replaceWith($itemNode);
$container = $itemNode;
this._addItemContentClasses($container, itemData)
}
else {
this._addItemContentClasses($container, itemData);
var $result = this._createItemByTemplate(itemTemplate, renderArgs);
if ($result.hasClass(TEMPLATE_WRAPPER_CLASS)) {
$container.replaceWith($result);
$container = $result;
this._addItemContentClasses($container, itemData)
}
}
return $container
},
_addItemContentClasses: function($container) {
$container.addClass([ITEM_CLASS + CONTENT_CLASS_POSTFIX, this._itemContentClass()].join(" "))
},
_renderItemFrame: function(index, itemData, $container) {
var itemFrameTemplate = this.option("templateProvider").getTemplates(this)["itemFrame"],
$itemFrame = itemFrameTemplate.render(utils.isDefined(itemData) ? itemData : {}, $container, index);
$itemFrame.appendTo($container);
return $itemFrame
},
_postprocessRenderItem: $.noop,
_executeItemRenderAction: function(index, itemData, itemElement) {
this._getItemRenderAction()({
itemElement: itemElement,
itemIndex: index,
itemData: itemData
})
},
_setElementData: function(element, data) {
element.addClass([ITEM_CLASS, this._itemClass()].join(" ")).data(this._itemDataKey(), data)
},
_createItemRenderAction: function() {
return this._itemRenderAction = this._createActionByOption("onItemRendered", {
element: this.element(),
excludeValidators: ["designMode", "disabled", "readOnly"],
category: "rendering"
})
},
_getItemRenderAction: function() {
return this._itemRenderAction || this._createItemRenderAction()
},
_getItemTemplateName: function(itemData) {
var templateProperty = this.option("itemTemplateProperty");
return itemData && itemData[templateProperty] || this.option("itemTemplate")
},
_createItemByTemplate: function(itemTemplate, renderArgs) {
return itemTemplate.render(renderArgs.item, renderArgs.container, renderArgs.index, "ignoreTarget")
},
_renderEmptyMessage: function() {
var noDataText = this.option("noDataText"),
items = this.option("items"),
hideNoData = !noDataText || items && items.length || this._isDataSourceLoading();
if (hideNoData && this._$nodata) {
this._$nodata.remove();
this._$nodata = null;
this.setAria("label", undefined)
}
if (!hideNoData) {
this._$nodata = this._$nodata || $("
").addClass("dx-empty-message");
this._$nodata.appendTo(this._itemContainer()).html(noDataText);
this.setAria("label", noDataText)
}
this.element().toggleClass(EMPTY_COLLECTION, !hideNoData)
},
_itemJQueryEventHandler: function(jQueryEvent, handlerOptionName, actionArgs, actionConfig) {
this._itemEventHandler(jQueryEvent.target, handlerOptionName, $.extend(actionArgs, {jQueryEvent: jQueryEvent}), actionConfig)
},
_itemEventHandler: function(initiator, handlerOptionName, actionArgs, actionConfig) {
var action = this._createActionByOption(handlerOptionName, $.extend({validatingTargetName: "itemElement"}, actionConfig));
return this._itemEventHandlerImpl(initiator, action, actionArgs)
},
_itemEventHandlerByHandler: function(initiator, handler, actionArgs, actionConfig) {
var action = this._createAction(handler, $.extend({validatingTargetName: "itemElement"}, actionConfig));
return this._itemEventHandlerImpl(initiator, action, actionArgs)
},
_itemEventHandlerImpl: function(initiator, action, actionArgs) {
var $itemElement = this._closestItemElement($(initiator));
return action($.extend(this._extendActionArgs($itemElement), actionArgs))
},
_extendActionArgs: function($itemElement) {
return {
itemElement: $itemElement,
itemIndex: $itemElement.index(this._itemSelector()),
itemData: this._getItemData($itemElement)
}
},
_closestItemElement: function($element) {
return $($element).closest(this._itemSelector())
},
_getItemData: function(itemElement) {
return $(itemElement).data(this._itemDataKey())
},
getFocusedItemId: function() {
if (!this._focusedItemId)
this._focusedItemId = new DevExpress.data.Guid;
return this._focusedItemId
},
itemElements: function() {
return this._itemElements()
},
itemsContainer: function() {
return this._itemContainer()
}
}).include(ui.DataHelperMixin);
ui.CollectionWidget = CollectionWidget
})(jQuery, DevExpress);
/*! Module core, file ui.CollectionWidget.edit.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils;
var ITEM_DELETING_DATA_KEY = "dxItemDeleting";
var CollectionWidget = ui.CollectionWidget.inherit({
_setOptionsByReference: function() {
this.callBase();
$.extend(this._optionsByReference, {selectedItem: true})
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {itemSelectAction: {
since: "14.2",
message: "Use the 'onSelectionChanged' option instead"
}})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
selectionMode: 'none',
selectionRequired: false,
selectionByClick: true,
selectedItems: [],
selectedIndex: -1,
selectedItem: null,
onSelectionChanged: null,
onItemReordered: null,
onItemDeleting: null,
onItemDeleted: null
})
},
_init: function() {
this.callBase();
this._initEditStrategy();
this._selectedItemIndices = []
},
_initEditStrategy: function() {
var strategy = ui.CollectionWidget.PlainEditStrategy;
this._editStrategy = new strategy(this)
},
_render: function() {
this._syncSelectionOptions();
this._normalizeSelectedItems();
this._initSelectedItems();
this.callBase();
this._renderSelection(this._selectedItemIndices, [])
},
_syncSelectionOptions: function(byOption) {
byOption = byOption || this._chooseSelectOption();
var selectedItem,
selectedItems;
switch (byOption) {
case"selectedIndex":
selectedItem = this._editStrategy.getItemDataByIndex(this.option("selectedIndex"));
if (utils.isDefined(selectedItem)) {
this._setOptionSilent("selectedItems", [selectedItem]);
this._setOptionSilent("selectedItem", selectedItem)
}
else {
this._setOptionSilent("selectedItems", []);
this._setOptionSilent("selectedItem", null)
}
break;
case"selectedItems":
selectedItems = this.option("selectedItems") || [];
this._setOptionSilent("selectedItem", selectedItems[0]);
this._setOptionSilent("selectedIndex", this._editStrategy.getIndexByItemData(selectedItems[0]));
break;
case"selectedItem":
selectedItem = this.option("selectedItem");
if (utils.isDefined(selectedItem)) {
this._setOptionSilent("selectedItems", [selectedItem]);
this._setOptionSilent("selectedIndex", this._editStrategy.getIndexByItemData(selectedItem))
}
else {
this._setOptionSilent("selectedItems", []);
this._setOptionSilent("selectedIndex", -1)
}
break
}
},
_chooseSelectOption: function() {
var optionName = "selectedIndex";
if (this.option("selectedItems").length)
optionName = "selectedItems";
else if (utils.isDefined(this.option("selectedItem")))
optionName = "selectedItem";
return optionName
},
_normalizeSelectedItems: function() {
if (this.option("selectionMode") === "none") {
this._setOptionSilent("selectedItems", []);
this._syncSelectionOptions("selectedItems")
}
else if (this.option("selectionMode") === "single") {
var newSelection = this._editStrategy.selectedItemIndices(this.option("selectedItems"));
if (newSelection.length > 1 || !newSelection.length && this.option("selectionRequired") && this.option("items") && this.option("items").length) {
var normalizedSelection = [newSelection[0] || this._selectedItemIndices[0] || 0];
this._setOptionSilent("selectedItems", this._editStrategy.fetchSelectedItems(normalizedSelection));
this._syncSelectionOptions("selectedItems")
}
}
},
_initSelectedItems: function() {
this._selectedItemIndices = this._editStrategy.selectedItemIndices(this.option("selectedItems"))
},
_renderSelection: $.noop,
_itemClickHandler: function(e) {
this._createAction($.proxy(function(e) {
this._itemSelectHandler(e.jQueryEvent)
}, this), {validatingTargetName: "itemElement"})({
itemElement: $(e.currentTarget),
jQueryEvent: e
});
this.callBase.apply(this, arguments)
},
_itemSelectHandler: function(e) {
if (!this.option("selectionByClick"))
return;
var $itemElement = e.currentTarget;
if (this.isItemSelected($itemElement))
this.unselectItem(e.currentTarget);
else
this.selectItem(e.currentTarget)
},
_selectedItemElement: function(index) {
return this._itemElements().eq(index)
},
_postprocessRenderItem: function(args) {
var $itemElement = $(args.itemElement);
if (this._isItemSelected(this._editStrategy.getNormalizedIndex($itemElement))) {
$itemElement.addClass(this._selectedItemClass());
this._setAriaSelected($itemElement, "true")
}
else
this._setAriaSelected($itemElement, "false")
},
_updateSelectedItems: function() {
var oldSelection = this._selectedItemIndices.slice(),
newSelection = this._editStrategy.selectedItemIndices(),
addedSelection = utils.removeDublicates(newSelection, oldSelection),
removedSelection = utils.removeDublicates(oldSelection, newSelection);
$.each(removedSelection, $.proxy(function(_, normalizedIndex) {
this._removeSelection(normalizedIndex)
}, this));
$.each(addedSelection, $.proxy(function(_, normalizedIndex) {
this._addSelection(normalizedIndex)
}, this));
if (removedSelection.length || addedSelection.length) {
var selectionChangePromise = this._selectionChangePromise;
this._updateSelection(addedSelection, removedSelection);
$.when(selectionChangePromise).done($.proxy(function() {
this._fireSelectItemEvent(addedSelection, removedSelection);
this._fireSelectionChangeEvent(addedSelection, removedSelection)
}, this))
}
},
_fireSelectionChangeEvent: function(addedSelection, removedSelection) {
this._createActionByOption("onSelectionChanged", {excludeValidators: ["disabled", "readOnly"]})({
addedItems: this._editStrategy.fetchSelectedItems(addedSelection),
removedItems: this._editStrategy.fetchSelectedItems(removedSelection)
})
},
_fireSelectItemEvent: function(addedSelection, removedSelection) {
if (this.NAME === "dxList" && this.option("selectionMode") !== "single")
return;
this._itemEventHandler(this._selectedItemElement(addedSelection[0]), "itemSelectAction", {
selectedIndex: addedSelection[0],
previousIndex: removedSelection[0]
}, {excludeValidators: ["disabled", "readOnly"]})
},
_updateSelection: function() {
this._renderSelection.apply(this, arguments)
},
_setAriaSelected: function($target, value) {
this.setAria("selected", value, $target)
},
_removeSelection: function(normalizedIndex) {
var $itemElement = this._editStrategy.getItemElement(normalizedIndex),
itemSelectionIndex = $.inArray(normalizedIndex, this._selectedItemIndices);
if (itemSelectionIndex > -1) {
$itemElement.removeClass(this._selectedItemClass());
this._setAriaSelected($itemElement, "false");
this._selectedItemIndices.splice(itemSelectionIndex, 1);
$itemElement.triggerHandler("stateChanged");
if (this.NAME === "dxList")
this._itemEventHandler($itemElement, "itemUnselectAction", {}, {excludeValidators: ["disabled", "readOnly"]})
}
},
_addSelection: function(normalizedIndex) {
var $itemElement = this._editStrategy.getItemElement(normalizedIndex);
if (normalizedIndex > -1 && !this._isItemSelected(normalizedIndex)) {
$itemElement.addClass(this._selectedItemClass());
this._setAriaSelected($itemElement, "true");
this._selectedItemIndices.push(normalizedIndex);
$itemElement.triggerHandler("stateChanged");
if (this.NAME === "dxList")
this._itemEventHandler($itemElement, "itemSelectAction", {}, {excludeValidators: ["disabled", "readOnly"]})
}
},
_isItemSelected: function(index) {
return $.inArray(index, this._selectedItemIndices) > -1
},
_optionChanged: function(args) {
if (this._cancelOptionChange)
return;
switch (args.name) {
case"items":
if (args.previousValue && args.previousValue.length > 0)
this._clearSelectedItems();
this.callBase(args);
break;
case"selectionMode":
this._invalidate();
break;
case"selectedIndex":
case"selectedItem":
case"selectedItems":
this._syncSelectionOptions(args.name);
this._normalizeSelectedItems();
this._updateSelectedItems();
break;
case"selectionRequired":
this._normalizeSelectedItems();
this._updateSelectedItems();
break;
case"selectionByClick":
case"onSelectionChanged":
case"onItemDeleting":
case"onItemDeleted":
case"onItemReordered":
case"itemSelectAction":
case"itemUnselectAction":
break;
default:
this.callBase(args)
}
},
_clearSelectedItems: function() {
this._selectedItemIndices = [];
this.option("selectedItems", [])
},
_setOptionSilent: function(name, value) {
this._cancelOptionChange = true;
this.option(name, value);
this._cancelOptionChange = false
},
_waitDeletingPrepare: function($itemElement) {
if ($itemElement.data(ITEM_DELETING_DATA_KEY))
return $.Deferred().resolve().promise();
$itemElement.data(ITEM_DELETING_DATA_KEY, true);
var deferred = $.Deferred(),
deletePromise = this._itemEventHandler($itemElement, "onItemDeleting", {}, {excludeValidators: ["disabled", "readOnly"]});
$.when(deletePromise).always($.proxy(function(value) {
var deletePromiseExists = !deletePromise,
deletePromiseResolved = !deletePromiseExists && deletePromise.state() === "resolved",
argumentsSpecified = !!arguments.length,
shouldDelete = deletePromiseExists || deletePromiseResolved && !argumentsSpecified || deletePromiseResolved && value;
$itemElement.data(ITEM_DELETING_DATA_KEY, false);
shouldDelete ? deferred.resolve() : deferred.reject()
}, this));
return deferred.promise()
},
_deleteItemFromDS: function($item) {
if (!this._dataSource)
return $.Deferred().resolve().promise();
var deferred = $.Deferred(),
disabledState = this.option("disabled"),
dataStore = this._dataSource.store();
this.option("disabled", true);
if (!dataStore.remove)
throw DX.Error("E1011");
dataStore.remove(dataStore.keyOf(this._getItemData($item))).done(function(key) {
if (key !== undefined)
deferred.resolve();
else
deferred.reject()
}).fail(function() {
deferred.reject()
});
deferred.always($.proxy(function() {
this.option("disabled", disabledState)
}, this));
return deferred
},
_tryRefreshLastPage: function() {
var deferred = $.Deferred();
if (this._isLastPage() || this.option("grouped"))
deferred.resolve();
else
this._refreshLastPage().done(function() {
deferred.resolve()
});
return deferred.promise()
},
_refreshLastPage: function() {
this._expectLastItemLoading();
return this._dataSource.load()
},
_updateSelectionAfterDelete: function(fromIndex) {
var itemIndex = $.inArray(fromIndex, this._selectedItemIndices);
if (itemIndex > -1)
this._selectedItemIndices.splice(itemIndex, 1);
this._editStrategy.updateSelectionAfterDelete(fromIndex);
this.option("selectedItems", this._editStrategy.fetchSelectedItems())
},
_simulateOptionChange: function(optionName) {
var optionValue = this.option(optionName);
if (optionValue instanceof DX.data.DataSource)
return;
this.fireEvent("optionChanged", [{
name: optionName,
fullName: optionName,
value: optionValue
}])
},
isItemSelected: function(itemElement) {
return this._isItemSelected(this._editStrategy.getNormalizedIndex(itemElement))
},
selectItem: function(itemElement) {
var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);
if (itemIndex === -1)
return;
var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);
if (itemSelectionIndex !== -1)
return;
if (this.option("selectionMode") === "single")
this.option("selectedItems", this._editStrategy.fetchSelectedItems([itemIndex]));
else {
var newSelectedIndices = this._selectedItemIndices.slice();
newSelectedIndices.push(itemIndex);
this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))
}
},
unselectItem: function(itemElement) {
var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);
if (itemIndex === -1)
return;
var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);
if (itemSelectionIndex === -1)
return;
var newSelectedIndices = this._selectedItemIndices.slice();
newSelectedIndices.splice(itemSelectionIndex, 1);
if (this.option("selectionRequired") && newSelectedIndices.length === 0)
return;
this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))
},
deleteItem: function(itemElement) {
var that = this,
deferred = $.Deferred(),
$item = this._editStrategy.getItemElement(itemElement),
index = this._editStrategy.getNormalizedIndex(itemElement),
changingOption = this._dataSource ? "dataSource" : "items",
itemResponseWaitClass = this._itemResponseWaitClass();
if (index > -1)
this._waitDeletingPrepare($item).done(function() {
$item.addClass(itemResponseWaitClass);
that._deleteItemFromDS($item).done(function() {
that._editStrategy.deleteItemAtIndex(index);
that._simulateOptionChange(changingOption);
that._updateSelectionAfterDelete(index);
that._itemEventHandler($item, "onItemDeleted", {}, {
beforeExecute: function() {
$item.detach()
},
excludeValidators: ["disabled", "readOnly"]
});
that._renderEmptyMessage();
that._tryRefreshLastPage().done(function() {
deferred.resolveWith(that)
})
}).fail(function() {
$item.removeClass(itemResponseWaitClass);
deferred.rejectWith(that)
})
}).fail(function() {
deferred.rejectWith(that)
});
else
deferred.rejectWith(that);
return deferred.promise()
},
reorderItem: function(itemElement, toItemElement) {
var deferred = $.Deferred(),
that = this,
strategy = this._editStrategy,
$movingItem = strategy.getItemElement(itemElement),
$destinationItem = strategy.getItemElement(toItemElement),
movingIndex = strategy.getNormalizedIndex(itemElement),
destinationIndex = strategy.getNormalizedIndex(toItemElement),
changingOption;
var canMoveItems = movingIndex > -1 && destinationIndex > -1 && movingIndex !== destinationIndex;
if (canMoveItems)
if (this._dataSource) {
changingOption = "dataSource";
deferred.resolveWith(this)
}
else {
changingOption = "items";
deferred.resolveWith(this)
}
else
deferred.rejectWith(this);
return deferred.promise().done(function() {
$destinationItem[strategy.itemPlacementFunc(movingIndex, destinationIndex)]($movingItem);
var newSelectedItems = strategy.getSelectedItemsAfterReorderItem(movingIndex, destinationIndex);
strategy.moveItemAtIndexToIndex(movingIndex, destinationIndex);
that._selectedItemIndices = strategy.selectedItemIndices(newSelectedItems);
that.option("selectedItems", strategy.fetchSelectedItems());
that._simulateOptionChange(changingOption);
that._itemEventHandler($movingItem, "onItemReordered", {
fromIndex: strategy.getIndex(movingIndex),
toIndex: strategy.getIndex(destinationIndex)
}, {excludeValidators: ["disabled", "readOnly"]})
})
}
});
ui.CollectionWidget = CollectionWidget
})(jQuery, DevExpress);
/*! Module core, file ui.collectionWidget.edit.strategy.js */
(function($, DX, undefined) {
var ui = DX.ui;
ui.CollectionWidget.EditStrategy = DX.Class.inherit({
ctor: function(collectionWidget) {
this._collectionWidget = collectionWidget
},
getIndexByItemData: DX.abstract,
getItemDataByIndex: DX.abstract,
getNormalizedIndex: function(value) {
if (this._isNormalisedItemIndex(value))
return value;
if (this._isItemIndex(value))
return this._normalizeItemIndex(value);
return this._getNormalizedItemIndex(value)
},
getIndex: function(value) {
if (this._isNormalisedItemIndex(value))
return this._denormalizeItemIndex(value);
if (this._isItemIndex(value))
return value;
return this._denormalizeItemIndex(this._getNormalizedItemIndex(value))
},
getItemElement: function(value) {
if (this._isNormalisedItemIndex(value))
return this._getItemByNormalizedIndex(value);
if (this._isItemIndex(value))
return this._getItemByNormalizedIndex(this._normalizeItemIndex(value));
return $(value)
},
deleteItemAtIndex: DX.abstract,
updateSelectionAfterDelete: DX.abstract,
fetchSelectedItems: DX.abstract,
selectedItemIndices: DX.abstract,
itemPlacementFunc: function(movingIndex, destinationIndex) {
return this._itemsFromSameParent(movingIndex, destinationIndex) && movingIndex < destinationIndex ? "after" : "before"
},
moveItemAtIndexToIndex: DX.abstract,
getSelectedItemsAfterReorderItem: function() {
return this._collectionWidget.option("selectedItems")
},
_isNormalisedItemIndex: function(index) {
return $.isNumeric(index)
},
_isItemIndex: DX.abstract,
_getNormalizedItemIndex: DX.abstract,
_normalizeItemIndex: DX.abstract,
_denormalizeItemIndex: DX.abstract,
_getItemByNormalizedIndex: DX.abstract,
_itemsFromSameParent: DX.abstract
})
})(jQuery, DevExpress);
/*! Module core, file ui.collectionWidget.edit.strategy.plain.js */
(function($, DX, undefined) {
var ui = DX.ui;
ui.CollectionWidget.PlainEditStrategy = ui.CollectionWidget.EditStrategy.inherit({
_getPlainItems: function() {
return this._collectionWidget.option("items") || []
},
getIndexByItemData: function(itemData) {
return $.inArray(itemData, this._getPlainItems())
},
getItemDataByIndex: function(index) {
return this._getPlainItems()[index]
},
deleteItemAtIndex: function(index) {
this._getPlainItems().splice(index, 1)
},
updateSelectionAfterDelete: function(fromIndex) {
var selectedItemIndices = this._collectionWidget._selectedItemIndices;
$.each(selectedItemIndices, function(i, index) {
if (index > fromIndex)
selectedItemIndices[i] -= 1
})
},
fetchSelectedItems: function(indices) {
indices = indices || this._collectionWidget._selectedItemIndices;
var items = this._getPlainItems(),
selectedItems = [];
$.each(indices, function(_, index) {
selectedItems.push(items[index])
});
return selectedItems
},
selectedItemIndices: function() {
var selectedIndices = [],
items = this._getPlainItems(),
selected = this._collectionWidget.option("selectedItems");
$.each(selected, function(_, selectedItem) {
var index = $.inArray(selectedItem, items);
if (index !== -1)
selectedIndices.push(index);
else
DX.log("W1002", selectedItem)
});
return selectedIndices
},
moveItemAtIndexToIndex: function(movingIndex, destinationIndex) {
var items = this._getPlainItems(),
movedItemData = items[movingIndex];
items.splice(movingIndex, 1);
items.splice(destinationIndex, 0, movedItemData)
},
_isItemIndex: function(index) {
return $.isNumeric(index)
},
_getNormalizedItemIndex: function(itemElement) {
return this._collectionWidget._itemElements().index(itemElement)
},
_normalizeItemIndex: function(index) {
return index
},
_denormalizeItemIndex: function(index) {
return index
},
_getItemByNormalizedIndex: function(index) {
return this._collectionWidget._itemElements().eq(index)
},
_itemsFromSameParent: function() {
return true
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.tooltip.js */
(function($, DX, undefined) {
var $tooltip = null;
var createTooltip = function(options) {
options = $.extend({position: "top"}, options);
var content = options.content;
delete options.content;
return $("
").html(content).appendTo(DX.viewPort()).dxTooltip(options)
};
var removeTooltip = function() {
if (!$tooltip)
return;
$tooltip.remove();
$tooltip = null
};
var tooltip = {
show: function(options) {
removeTooltip();
$tooltip = createTooltip(options);
return $tooltip.dxTooltip("show")
},
hide: function() {
if (!$tooltip)
return $.when();
return $tooltip.dxTooltip("hide").done(removeTooltip).promise()
}
};
DX.ui.tooltip = tooltip
})(jQuery, DevExpress)
}
if (!DevExpress.MOD_WIDGETS_BASE) {
if (!window.DevExpress)
throw Error('Required module is not referenced: core');
/*! Module widgets-base, file ui.errors.js */
(function($, DX) {
$.extend(DX.ERROR_MESSAGES, {
E1001: "Module '{0}'. Controller '{1}' is already registered",
E1002: "Module '{0}'. Controller '{1}' must be inheritor of DevExpress.ui.dxDataGrid.Controller",
E1003: "Module '{0}'. View '{1}' is already registered",
E1004: "Module '{0}'. View '{1}' must be inheritor of DevExpress.ui.dxDataGrid.View",
E1005: "Public method '{0}' is already registered",
E1006: "Public method '{0}.{1}' is not exists",
E1007: "State storing can not be provided due to the restrictions of your browser",
E1010: "A template should contain dxTextBox widget",
E1011: "You have to implement 'remove' method in dataStore used by dxList to be able to delete items",
E1012: "Editing type '{0}' with name '{1}' not supported",
E1016: "Unexpected type of data source is provided for a lookup column",
E1018: "The 'collapseAll' method cannot be called when using a remote data source",
E1019: "Search mode '{0}' is unavailable",
E1020: "Type can not be changed after initialization",
E1021: "{0} '{1}' you are trying to remove does not exist",
E1022: "Markers option should be an array",
E1023: "Routes option should be an array",
E1024: "Google provider cannot be used in WinJS application",
E1025: "This layout is too complex to render",
E1026: "The 'custom' value is set to a summary item's summaryType option, but a function for calculating the custom summary is not assigned to the grid's calculateCustomSummary option",
E1030: "Unknown dxScrollView refresh strategy: '{0}'",
E1031: "Unknown subscription is detected in the dxScheduler widget: '{0}'",
E1032: "Unknown start date is detected in an appointment of the dxScheduler widget: '{0}'",
E1033: "Unknown step is specified for the scheduler's navigator: '{0}'",
E1034: "The current browser does not implement an API required for saving files",
W1001: "Key option can not be modified after initialization",
W1002: "Item '{0}' you are trying to select does not exist",
W1003: "Group with key '{0}' in which you are trying to select items does not exist",
W1004: "Item '{0}' you are trying to select in group '{1}' does not exist",
W1005: "Due to column data types being unspecified, data has been loaded twice in order to apply initial filter settings. To resolve this issue, specify data types for all grid columns."
})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollable.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var SCROLLABLE = "dxScrollable",
SCROLLABLE_STRATEGY = "dxScrollableStrategy",
SCROLLABLE_CLASS = "dx-scrollable",
SCROLLABLE_DISABLED_CLASS = "dx-scrollable-disabled",
SCROLLABLE_CONTAINER_CLASS = "dx-scrollable-container",
SCROLLABLE_CONTENT_CLASS = "dx-scrollable-content",
VERTICAL = "vertical",
HORIZONTAL = "horizontal",
BOTH = "both";
var deviceDependentOptions = function() {
return [{
device: function(device) {
return !DX.support.nativeScrolling
},
options: {useNative: false}
}, {
device: function(device) {
return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic"
},
options: {
bounceEnabled: false,
scrollByThumb: true,
scrollByContent: DX.support.touch,
showScrollbar: "onHover"
}
}]
};
DX.registerComponent(SCROLLABLE, ui, DX.DOMComponent.inherit({
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {
updateAction: {
since: "14.2",
alias: "onUpdated"
},
scrollAction: {
since: "14.2",
alias: "onScroll"
},
startAction: {
since: "14.2",
alias: "onStart"
},
stopAction: {
since: "14.2",
alias: "onStop"
},
endAction: {
since: "14.2",
alias: "onEnd"
}
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
disabled: false,
onScroll: null,
direction: VERTICAL,
showScrollbar: "onScroll",
useNative: true,
bounceEnabled: true,
scrollByContent: true,
scrollByThumb: false,
onUpdated: null,
onStart: null,
onEnd: null,
onBounce: null,
onStop: null,
useSimulatedScrollbar: false,
useKeyboard: true,
inertiaEnabled: true,
pushBackValue: 0
})
},
_defaultOptionsRules: function() {
return this.callBase().concat(deviceDependentOptions(), [{
device: function(device) {
return DX.support.nativeScrolling && DX.devices.real().platform === "android"
},
options: {useSimulatedScrollbar: true}
}, {
device: function(device) {
return DX.devices.real().platform === "ios"
},
options: {pushBackValue: 1}
}])
},
_initOptions: function(options) {
this.callBase(options);
if (!("useSimulatedScrollbar" in options))
this._setUseSimulatedScrollbar()
},
_setUseSimulatedScrollbar: function() {
if (!this._initialOptions.useSimulatedScrollbar)
this.option("useSimulatedScrollbar", !this.option("useNative"))
},
_init: function() {
this.callBase();
this._initMarkup();
this._attachNativeScrollbarsCustomizationCss();
this._locked = false
},
_visibilityChanged: function(visible) {
if (this.element().is(":hidden"))
return;
if (visible) {
this.update();
this._toggleRTLDirection(this.option("rtlEnabled"));
this._savedScrollOffset && this.scrollTo(this._savedScrollOffset)
}
else
this._savedScrollOffset = this.scrollOffset()
},
_initMarkup: function() {
var $element = this.element().addClass(SCROLLABLE_CLASS),
$container = this._$container = $("
").addClass(SCROLLABLE_CONTAINER_CLASS),
$content = this._$content = $("
").addClass(SCROLLABLE_CONTENT_CLASS);
$content.append($element.contents()).appendTo($container);
$container.appendTo($element)
},
_dimensionChanged: function() {
this.update()
},
_attachNativeScrollbarsCustomizationCss: function() {
if (!(navigator.platform.indexOf('Mac') > -1 && DevExpress.browser['webkit']))
this.element().addClass("dx-scrollable-customizable-scrollbars")
},
_render: function() {
this._renderPushBackOffset();
this._renderDirection();
this._renderStrategy();
this._attachEventHandlers();
this._renderDisabledState();
this._createActions();
this.update();
this.callBase()
},
_renderPushBackOffset: function() {
var pushBackValue = this.option("pushBackValue");
this._$content.css({
paddingTop: pushBackValue,
paddingBottom: pushBackValue
})
},
_toggleRTLDirection: function(rtl) {
this.callBase(rtl);
if (rtl && this.option("direction") !== VERTICAL)
this.scrollTo({left: this.scrollWidth() - this.clientWidth()})
},
_attachEventHandlers: function() {
var strategy = this._strategy;
var initEventData = {
getDirection: $.proxy(strategy.getDirection, strategy),
validate: $.proxy(this._validate, this),
isNative: this.option("useNative")
};
this._$container.off("." + SCROLLABLE).on(events.addNamespace("scroll", SCROLLABLE), $.proxy(strategy.handleScroll, strategy)).on(events.addNamespace("dxscrollinit", SCROLLABLE), initEventData, $.proxy(this._initHandler, this)).on(events.addNamespace("dxscrollstart", SCROLLABLE), $.proxy(strategy.handleStart, strategy)).on(events.addNamespace("dxscroll", SCROLLABLE), $.proxy(strategy.handleMove, strategy)).on(events.addNamespace("dxscrollend", SCROLLABLE), $.proxy(strategy.handleEnd, strategy)).on(events.addNamespace("dxscrollcancel", SCROLLABLE), $.proxy(strategy.handleCancel, strategy)).on(events.addNamespace("dxscrollstop", SCROLLABLE), $.proxy(strategy.handleStop, strategy))
},
_validate: function(e) {
if (this._isLocked())
return false;
this.update();
return this._strategy.validate(e)
},
_initHandler: function() {
var strategy = this._strategy;
strategy.handleInit.apply(strategy, arguments)
},
_renderDisabledState: function() {
this.element().toggleClass(SCROLLABLE_DISABLED_CLASS, this.option("disabled"));
if (this.option("disabled"))
this._lock();
else
this._unlock()
},
_renderDirection: function() {
this.element().removeClass("dx-scrollable-" + HORIZONTAL).removeClass("dx-scrollable-" + VERTICAL).removeClass("dx-scrollable-" + BOTH).addClass("dx-scrollable-" + this.option("direction"))
},
_renderStrategy: function() {
this._createStrategy();
this._strategy.render();
this.element().data(SCROLLABLE_STRATEGY, this._strategy)
},
_createStrategy: function() {
this._strategy = this.option("useNative") ? new ui.dxScrollable.NativeStrategy(this) : new ui.dxScrollable.SimulatedStrategy(this)
},
_createActions: function() {
this._strategy.createActions()
},
_clean: function() {
this._strategy.dispose()
},
_optionChanged: function(args) {
switch (args.name) {
case"onStart":
case"onEnd":
case"onStop":
case"onUpdated":
case"onScroll":
case"onBounce":
this._createActions();
break;
case"direction":
this._resetInactiveDirection();
this._invalidate();
break;
case"useNative":
this._setUseSimulatedScrollbar();
this._invalidate();
break;
case"inertiaEnabled":
case"bounceEnabled":
case"scrollByContent":
case"scrollByThumb":
case"bounceEnabled":
case"useKeyboard":
case"showScrollbar":
case"useSimulatedScrollbar":
case"pushBackValue":
this._invalidate();
break;
case"disabled":
this._renderDisabledState();
break;
default:
this.callBase(args)
}
},
_resetInactiveDirection: function() {
var inactiveProp = this._getInactiveProp();
if (!inactiveProp)
return;
var scrollOffset = this.scrollOffset();
scrollOffset[inactiveProp] = 0;
this.scrollTo(scrollOffset)
},
_getInactiveProp: function() {
var direction = this.option("direction");
if (direction === VERTICAL)
return "left";
if (direction === HORIZONTAL)
return "top"
},
_location: function() {
return this._strategy.location()
},
_normalizeLocation: function(location) {
var direction = this.option("direction");
return {
left: $.isPlainObject(location) ? -(location.left || location.x || 0) : direction !== VERTICAL ? -location : 0,
top: $.isPlainObject(location) ? -(location.top || location.y || 0) : direction !== HORIZONTAL ? -location : 0
}
},
_isLocked: function() {
return this._locked
},
_lock: function() {
this._locked = true
},
_unlock: function() {
this._locked = false
},
_isDirection: function(direction) {
var current = this.option("direction");
if (direction === VERTICAL)
return current !== HORIZONTAL;
if (direction === HORIZONTAL)
return current !== VERTICAL;
return current === direction
},
_updateAllowedDirection: function() {
var allowedDirections = this._strategy._allowedDirections();
if (this._isDirection(BOTH) && allowedDirections.vertical && allowedDirections.horizontal)
this._allowedDirectionValue = BOTH;
else if (this._isDirection(HORIZONTAL) && allowedDirections.horizontal)
this._allowedDirectionValue = HORIZONTAL;
else if (this._isDirection(VERTICAL) && allowedDirections.vertical)
this._allowedDirectionValue = VERTICAL;
else
this._allowedDirectionValue = null
},
_allowedDirection: function() {
return this._allowedDirectionValue
},
content: function() {
return this._$content
},
scrollOffset: function() {
var location = this._location();
return {
top: -location.top,
left: -location.left
}
},
scrollTop: function() {
return this.scrollOffset().top
},
scrollLeft: function() {
return this.scrollOffset().left
},
clientHeight: function() {
return this._$container.height()
},
scrollHeight: function() {
return this.content().height()
},
clientWidth: function() {
return this._$container.width()
},
scrollWidth: function() {
return this.content().width()
},
update: function() {
this._strategy.update();
this._updateAllowedDirection();
return $.when().promise()
},
scrollBy: function(distance) {
distance = this._normalizeLocation(distance);
if (!distance.top && !distance.left)
return;
this._strategy.scrollBy(distance)
},
scrollTo: function(targetLocation) {
targetLocation = this._normalizeLocation(targetLocation);
var location = this._location();
this.scrollBy({
left: location.left - targetLocation.left,
top: location.top - targetLocation.top
})
},
scrollToElement: function(element, offset) {
offset = offset || {};
var $element = $(element);
var elementInsideContent = this.content().find(element).length;
var elementIsInsideContent = $element.parents("." + SCROLLABLE_CLASS).length - $element.parents("." + SCROLLABLE_CONTENT_CLASS).length === 0;
if (!elementInsideContent || !elementIsInsideContent)
return;
var scrollPosition = {
top: 0,
left: 0
};
var direction = this.option("direction");
if (direction !== VERTICAL)
scrollPosition.left = this._scrollToElementPosition($element, HORIZONTAL, offset);
if (direction !== HORIZONTAL)
scrollPosition.top = this._scrollToElementPosition($element, VERTICAL, offset);
this.scrollTo(scrollPosition)
},
_scrollToElementPosition: function($element, direction, offset) {
var isVertical = direction === VERTICAL;
var startOffset = (isVertical ? offset.top : offset.left) || 0;
var endOffset = (isVertical ? offset.bottom : offset.right) || 0;
var pushBackOffset = isVertical ? this.option("pushBackValue") : 0;
var elementPositionRelativeToContent = this._elementPositionRelativeToContent($element, isVertical ? 'top' : 'left');
var elementPosition = elementPositionRelativeToContent - pushBackOffset;
var elementSize = $element[isVertical ? 'outerHeight' : 'outerWidth']();
var elementBottom = elementPositionRelativeToContent + elementSize;
var scrollLocation = (isVertical ? this.scrollTop() : this.scrollLeft()) - startOffset;
var clientSize = (isVertical ? this.clientHeight() : this.clientWidth()) - startOffset - endOffset;
var scrollBottom = scrollLocation + clientSize;
var isEntirelyVisible = scrollLocation <= elementPosition && scrollBottom >= elementBottom;
var isEntirelyWithOversizeVisible = scrollLocation >= elementPosition && scrollBottom <= elementBottom;
var isAlreadyVisible = isEntirelyVisible || isEntirelyWithOversizeVisible;
var isElementAboveScrollLocation = scrollLocation > elementPosition;
return isAlreadyVisible ? scrollLocation : elementPosition - (isElementAboveScrollLocation ? 0 : clientSize - elementSize)
},
_elementPositionRelativeToContent: function($element, prop) {
var result = 0;
while (this._hasScrollContent($element)) {
result += $element.position()[prop];
$element = $element.offsetParent()
}
return result
},
_hasScrollContent: function($element) {
var $content = this.content();
return $element.closest($content).length && !$element.is($content)
}
}));
ui.dxScrollable.deviceDependentOptions = deviceDependentOptions
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollbar.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var SCROLLBAR = "dxScrollbar",
SCROLLABLE_SCROLLBAR_CLASS = "dx-scrollable-scrollbar",
SCROLLABLE_SCROLLBAR_ACTIVE_CLASS = SCROLLABLE_SCROLLBAR_CLASS + "-active",
SCROLLABLE_SCROLL_CLASS = "dx-scrollable-scroll",
SCROLLABLE_SCROLL_CONTENT_CLASS = "dx-scrollable-scroll-content",
HOVER_ENABLED_STATE = "dx-scrollbar-hoverable",
HORIZONTAL = "horizontal",
THUMB_MIN_SIZE = 15;
var SCROLLBAR_VISIBLE = {
onScroll: "onScroll",
onHover: "onHover",
always: "always",
never: "never"
};
DX.registerComponent(SCROLLBAR, ui.dxScrollable, ui.Widget.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
direction: null,
visible: false,
activeStateEnabled: false,
visibilityMode: SCROLLBAR_VISIBLE.onScroll,
containerSize: 0,
contentSize: 0,
expandable: true
})
},
_init: function() {
this.callBase();
this._isHovered = false
},
_render: function() {
this._renderThumb();
this.callBase();
this._renderDirection();
this._update();
this._attachPointerDownHandler();
this.option("hoverStateEnabled", this._isHoverMode());
this.element().toggleClass(HOVER_ENABLED_STATE, this.option("hoverStateEnabled"))
},
_renderThumb: function() {
this._$thumb = $("
").addClass(SCROLLABLE_SCROLL_CLASS);
$("
").addClass(SCROLLABLE_SCROLL_CONTENT_CLASS).appendTo(this._$thumb);
this.element().addClass(SCROLLABLE_SCROLLBAR_CLASS).append(this._$thumb)
},
isThumb: function($element) {
return !!this.element().find($element).length
},
_isHoverMode: function() {
return this.option("visibilityMode") === SCROLLBAR_VISIBLE.onHover && this.option("expandable")
},
_renderDirection: function() {
var direction = this.option("direction");
this.element().addClass("dx-scrollbar-" + direction);
this._dimension = direction === HORIZONTAL ? "width" : "height";
this._prop = direction === HORIZONTAL ? "left" : "top"
},
_attachPointerDownHandler: function() {
this._$thumb.on(events.addNamespace("dxpointerdown", SCROLLBAR), $.proxy(this.feedbackOn, this))
},
feedbackOn: function() {
this.element().addClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);
activeScrollbar = this
},
feedbackOff: function() {
this.element().removeClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);
activeScrollbar = null
},
cursorEnter: function() {
this._isHovered = true;
this.option("visible", true)
},
cursorLeave: function() {
this._isHovered = false;
this.option("visible", false)
},
_renderDimensions: function() {
this._$thumb.outerHeight(this.option("height"));
this._$thumb.outerWidth(this.option("width"))
},
_toggleVisibility: function(visible) {
if (this.option("visibilityMode") === SCROLLBAR_VISIBLE.onScroll)
this._$thumb.css("opacity");
visible = this._adjustVisibility(visible);
this.option().visible = visible;
this._$thumb.toggleClass("dx-state-invisible", !visible)
},
_adjustVisibility: function(visible) {
if (this.containerToContentRatio() && !this._needScrollbar())
return false;
switch (this.option("visibilityMode")) {
case SCROLLBAR_VISIBLE.onScroll:
break;
case SCROLLBAR_VISIBLE.onHover:
visible = visible || !!this._isHovered;
break;
case SCROLLBAR_VISIBLE.never:
visible = false;
break;
case SCROLLBAR_VISIBLE.always:
visible = true;
break
}
return visible
},
moveTo: function(location) {
if (this._isHidden())
return;
if ($.isPlainObject(location))
location = location[this._prop] || 0;
var scrollBarLocation = {};
scrollBarLocation[this._prop] = this._calculateScrollBarPosition(location);
DX.translator.move(this._$thumb, scrollBarLocation)
},
_calculateScrollBarPosition: function(location) {
return -location * this._thumbRatio
},
_update: function() {
var containerSize = this.option("containerSize"),
contentSize = this.option("contentSize");
this._containerToContentRatio = containerSize / contentSize;
var thumbSize = Math.round(Math.max(Math.round(containerSize * this._containerToContentRatio), THUMB_MIN_SIZE));
this._thumbRatio = (containerSize - thumbSize) / (contentSize - containerSize);
this.option(this._dimension, thumbSize);
this.element().toggle(this._needScrollbar())
},
_isHidden: function() {
return this.option("visibilityMode") === SCROLLBAR_VISIBLE.never
},
_needScrollbar: function() {
return !this._isHidden() && this._containerToContentRatio < 1
},
containerToContentRatio: function() {
return this._containerToContentRatio
},
_normalizeSize: function(size) {
return $.isPlainObject(size) ? size[this._dimension] || 0 : size
},
_clean: function() {
this.callBase();
if (this === activeScrollbar)
activeScrollbar = null;
this._$thumb.off("." + SCROLLBAR)
},
_optionChanged: function(args) {
if (this._isHidden())
return;
switch (args.name) {
case"containerSize":
case"contentSize":
this.option()[args.name] = this._normalizeSize(args.value);
this._update();
break;
case"visibilityMode":
case"direction":
this._invalidate();
break;
default:
this.callBase.apply(this, arguments)
}
},
update: function() {
this._adjustVisibility() && this.option("visible", true)
}
}));
var activeScrollbar = null;
$(document).on(events.addNamespace("dxpointerup", SCROLLBAR), function() {
if (activeScrollbar)
activeScrollbar.feedbackOff()
})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollable.native.js */
(function($, DX, undefined) {
var ui = DX.ui,
devices = DX.devices;
var SCROLLABLE_NATIVE = "dxNativeScrollable",
SCROLLABLE_NATIVE_CLASS = "dx-scrollable-native",
SCROLLABLE_SCROLLBAR_SIMULATED = "dx-scrollable-scrollbar-simulated",
SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden",
VERTICAL = "vertical",
HORIZONTAL = "horizontal",
HIDE_SCROLLBAR_TIMOUT = 500;
ui.dxScrollable.NativeStrategy = DX.Class.inherit({
ctor: function(scrollable) {
this._init(scrollable)
},
_init: function(scrollable) {
this._component = scrollable;
this._$element = scrollable.element();
this._$container = scrollable._$container;
this._$content = scrollable._$content;
this._direction = scrollable.option("direction");
this._useSimulatedScrollbar = scrollable.option("useSimulatedScrollbar");
this._showScrollbar = scrollable.option("showScrollbar");
this.option = $.proxy(scrollable.option, scrollable);
this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable);
this._isLocked = $.proxy(scrollable._isLocked, scrollable);
this._isDirection = $.proxy(scrollable._isDirection, scrollable);
this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable)
},
render: function() {
var device = devices.real(),
deviceType = device.platform;
this._$element.addClass(SCROLLABLE_NATIVE_CLASS).addClass(SCROLLABLE_NATIVE_CLASS + "-" + deviceType).toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this._showScrollbar);
if (this._showScrollbar && this._useSimulatedScrollbar)
this._renderScrollbars()
},
_renderScrollbars: function() {
this._scrollbars = {};
this._hideScrollbarTimeout = 0;
this._$element.addClass(SCROLLABLE_SCROLLBAR_SIMULATED);
this._renderScrollbar(VERTICAL);
this._renderScrollbar(HORIZONTAL)
},
_renderScrollbar: function(direction) {
if (!this._isDirection(direction))
return;
var $scrollbar = $("
").dxScrollbar({
direction: direction,
expandable: this._component.option("scrollByThumb")
}).appendTo(this._$element);
this._scrollbars[direction] = $scrollbar.dxScrollbar("instance")
},
handleInit: $.noop,
handleStart: $.noop,
handleMove: function(e) {
if (this._isLocked()) {
e.cancel = true;
return
}
if (this._allowedDirection())
e.originalEvent.isScrollingEvent = true
},
handleEnd: $.noop,
handleStop: $.noop,
_eachScrollbar: function(callback) {
callback = $.proxy(callback, this);
$.each(this._scrollbars || {}, function(direction, scrollbar) {
callback(scrollbar, direction)
})
},
createActions: function() {
this._scrollAction = this._createActionByOption("onScroll");
this._updateAction = this._createActionByOption("onUpdated")
},
_createActionArgs: function() {
var location = this.location();
return {
jQueryEvent: this._eventForUserAction,
scrollOffset: {
top: -location.top,
left: -location.left
},
reachedLeft: this._isDirection(HORIZONTAL) ? location.left >= 0 : undefined,
reachedRight: this._isDirection(HORIZONTAL) ? location.left <= this._containerSize.width - this._componentContentSize.width : undefined,
reachedTop: this._isDirection(VERTICAL) ? location.top >= 0 : undefined,
reachedBottom: this._isDirection(VERTICAL) ? location.top <= this._containerSize.height - this._componentContentSize.height : undefined
}
},
handleScroll: function(e) {
if (!this._isScrollLocationChanged()) {
e.stopImmediatePropagation();
return
}
this._eventForUserAction = e;
this._moveScrollbars();
this._scrollAction(this._createActionArgs());
this._lastLocation = this.location();
this._pushBackFromBoundary()
},
_pushBackFromBoundary: function() {
var pushBackValue = this.option("pushBackValue");
if (!pushBackValue)
return;
var scrollOffset = this._containerSize.height - this._contentSize.height,
scrollTopPos = this._$container.scrollTop(),
scrollBottomPos = scrollOffset + scrollTopPos - pushBackValue * 2;
if (!scrollTopPos)
this._$container.scrollTop(pushBackValue);
else if (!scrollBottomPos)
this._$container.scrollTop(pushBackValue - scrollOffset)
},
_isScrollLocationChanged: function() {
var currentLocation = this.location(),
lastLocation = this._lastLocation || {},
isTopChanged = lastLocation.top !== currentLocation.top,
isLeftChanged = lastLocation.left !== currentLocation.left;
return isTopChanged || isLeftChanged
},
_moveScrollbars: function() {
this._eachScrollbar(function(scrollbar) {
scrollbar.moveTo(this.location());
scrollbar.option("visible", true)
});
this._hideScrollbars()
},
_hideScrollbars: function() {
clearTimeout(this._hideScrollbarTimeout);
this._hideScrollbarTimeout = setTimeout($.proxy(function() {
this._eachScrollbar(function(scrollbar) {
scrollbar.option("visible", false)
})
}, this), HIDE_SCROLLBAR_TIMOUT)
},
location: function() {
return {
left: -this._$container.scrollLeft(),
top: this.option("pushBackValue") - this._$container.scrollTop()
}
},
disabledChanged: $.noop,
update: function() {
this._update();
this._updateAction(this._createActionArgs())
},
_update: function() {
this._updateDimensions();
this._updateScrollbars()
},
_updateDimensions: function() {
this._containerSize = {
height: this._$container.height(),
width: this._$container.width()
};
this._componentContentSize = {
height: this._component.content().height(),
width: this._component.content().width()
};
this._contentSize = {
height: this._$content.height(),
width: this._$content.width()
};
this._pushBackFromBoundary()
},
_updateScrollbars: function() {
this._eachScrollbar(function(scrollbar, direction) {
var dimension = direction === VERTICAL ? "height" : "width";
scrollbar.option({
containerSize: this._containerSize[dimension],
contentSize: this._componentContentSize[dimension]
});
scrollbar.update()
})
},
_allowedDirections: function() {
return {
vertical: this._isDirection(VERTICAL) && this._contentSize.height > this._containerSize.height,
horizontal: this._isDirection(HORIZONTAL) && this._contentSize.width > this._containerSize.width
}
},
dispose: function() {
this._$element.removeClass(function(index, className) {
var scrollableNativeRegexp = new RegExp(SCROLLABLE_NATIVE_CLASS + "\\S*", "g");
if (scrollableNativeRegexp.test(className))
return className.match(scrollableNativeRegexp).join(" ")
});
this._$element.off("." + SCROLLABLE_NATIVE);
this._$container.off("." + SCROLLABLE_NATIVE);
this._removeScrollbars();
clearTimeout(this._gestureEndTimer);
clearTimeout(this._hideScrollbarTimeout)
},
_removeScrollbars: function() {
this._eachScrollbar(function(scrollbar) {
scrollbar.element().remove()
})
},
scrollBy: function(distance) {
var location = this.location();
this._$container.scrollTop(-location.top - distance.top + this.option("pushBackValue"));
this._$container.scrollLeft(-location.left - distance.left)
},
validate: function() {
return !this.option("disabled") && this._allowedDirection()
},
getDirection: function() {
return this._allowedDirection()
}
})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollable.simulated.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
math = Math,
translator = DX.translator;
var realDevice = DX.devices.real;
var isSluggishPlatform = realDevice.platform === "win8" || realDevice.platform === "android";
var SCROLLABLE_SIMULATED = "dxSimulatedScrollable",
SCROLLABLE_STRATEGY = "dxScrollableStrategy",
SCROLLABLE_SIMULATED_CURSOR = SCROLLABLE_SIMULATED + "Cursor",
SCROLLABLE_SIMULATED_KEYBOARD = SCROLLABLE_SIMULATED + "Keyboard",
SCROLLABLE_SIMULATED_CLASS = "dx-scrollable-simulated",
SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden",
SCROLLABLE_SCROLLBAR_CLASS = "dx-scrollable-scrollbar",
VERTICAL = "vertical",
HORIZONTAL = "horizontal",
ACCELERATION = isSluggishPlatform ? 0.95 : 0.92,
OUT_BOUNDS_ACCELERATION = 0.5,
MIN_VELOCITY_LIMIT = 1,
FRAME_DURATION = math.round(1000 / 60),
SCROLL_LINE_HEIGHT = 20,
BOUNCE_MIN_VELOCITY_LIMIT = MIN_VELOCITY_LIMIT / 5,
BOUNCE_DURATION = isSluggishPlatform ? 300 : 400,
BOUNCE_FRAMES = BOUNCE_DURATION / FRAME_DURATION,
BOUNCE_ACCELERATION_SUM = (1 - math.pow(ACCELERATION, BOUNCE_FRAMES)) / (1 - ACCELERATION);
var KEY_CODES = {
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40
};
var scrollIntoViewIfNeededCallbacks = function() {
var callbacks = $.Callbacks();
var FOCUS_TIMEOUT = 50,
cancelChangeTimestamp = null;
$(window).on(events.addNamespace("focus", SCROLLABLE_STRATEGY), function() {
cancelChangeTimestamp = $.now()
});
$(document).on(events.addNamespace("dxpointerdown", SCROLLABLE_STRATEGY), function() {
cancelChangeTimestamp = $.now()
});
var focusChange = function(e) {
var keyboardElementChange = $.now() - cancelChangeTimestamp > FOCUS_TIMEOUT,
focusedCorrectElement = e.target === document.activeElement;
if (keyboardElementChange && focusedCorrectElement)
callbacks.fire(e.target)
};
if (window.addEventListener)
window.addEventListener("focus", focusChange, true);
else
window.attachEvent("onfocusin", focusChange);
return callbacks
}();
var InertiaAnimator = DX.Animator.inherit({
ctor: function(scroller) {
this.callBase();
this.scroller = scroller
},
VELOCITY_LIMIT: MIN_VELOCITY_LIMIT,
_isFinished: function() {
return math.abs(this.scroller._velocity) <= this.VELOCITY_LIMIT
},
_step: function() {
this.scroller._scrollStep(this.scroller._velocity);
this.scroller._velocity *= this._acceleration()
},
_acceleration: function() {
return this.scroller._inBounds() ? ACCELERATION : OUT_BOUNDS_ACCELERATION
},
_complete: function() {
this.scroller._scrollComplete()
},
_stop: function() {
this.scroller._stopComplete()
}
});
var BounceAnimator = InertiaAnimator.inherit({
VELOCITY_LIMIT: BOUNCE_MIN_VELOCITY_LIMIT,
_isFinished: function() {
return this.scroller._crossBoundOnNextStep() || this.callBase()
},
_acceleration: function() {
return ACCELERATION
},
_complete: function() {
this.scroller._move(this.scroller._bounceLocation);
this.callBase()
}
});
var isWheelEvent = function(e) {
return e.type === "dxmousewheel"
};
var Scroller = ui.dxScrollable.Scroller = DX.Class.inherit({
ctor: function(options) {
this._initOptions(options);
this._initAnimators();
this._initScrollbar()
},
_initOptions: function(options) {
this._location = 0;
this._topReached = false;
this._bottomReached = false;
this._axis = options.direction === HORIZONTAL ? "x" : "y";
this._prop = options.direction === HORIZONTAL ? "left" : "top";
this._dimension = options.direction === HORIZONTAL ? "width" : "height";
this._scrollProp = options.direction === HORIZONTAL ? "scrollLeft" : "scrollTop";
$.each(options, $.proxy(function(optionName, optionValue) {
this["_" + optionName] = optionValue
}, this))
},
_initAnimators: function() {
this._inertiaAnimator = new InertiaAnimator(this);
this._bounceAnimator = new BounceAnimator(this)
},
_initScrollbar: function() {
this._$scrollbar = $("
").dxScrollbar({
direction: this._direction,
visible: this._scrollByThumb,
visibilityMode: this._visibilityModeNormalize(this._scrollbarVisible),
containerSize: this._containerSize(),
contentSize: this._contentSize(),
expandable: this._scrollByThumb
}).appendTo(this._$container);
this._scrollbar = this._$scrollbar.dxScrollbar("instance")
},
_visibilityModeNormalize: function(mode) {
return mode === true ? "onScroll" : mode === false ? "never" : mode
},
_scrollStep: function(delta) {
var prevLocation = this._location;
this._location += delta;
this._suppressBounce();
this._move();
if (prevLocation !== this._location) {
this._scrollAction();
$.data(this._$container.get(0), "scroll")()
}
},
_suppressBounce: function() {
if (this._bounceEnabled || this._inBounds(this._location))
return;
this._velocity = 0;
this._location = this._boundLocation()
},
_boundLocation: function() {
var location = math.min(this._location, this._maxOffset);
return math.max(location, this._minOffset)
},
_move: function(location) {
this._location = location !== undefined ? location : this._location;
this._moveContent();
this._moveScrollbar()
},
_moveContent: function() {
var targetLocation = {};
targetLocation[this._prop] = this._location;
translator.move(this._$content, targetLocation)
},
_moveScrollbar: function() {
this._scrollbar.moveTo(this._location)
},
_scrollComplete: function() {
if (this._inBounds()) {
this._hideScrollbar();
this._correctLocation();
if (this._completeDeferred)
this._completeDeferred.resolve()
}
this._scrollToBounds()
},
_correctLocation: function() {
this._location = math.round(this._location);
this._move()
},
_scrollToBounds: function() {
if (this._inBounds())
return;
this._bounceAction();
this._setupBounce();
this._bounceAnimator.start()
},
_setupBounce: function() {
var boundLocation = this._bounceLocation = this._boundLocation(),
bounceDistance = boundLocation - this._location;
this._velocity = bounceDistance / BOUNCE_ACCELERATION_SUM
},
_inBounds: function(location) {
location = location !== undefined ? location : this._location;
return location >= this._minOffset && location <= this._maxOffset
},
_crossBoundOnNextStep: function() {
var location = this._location,
nextLocation = location + this._velocity;
return location < this._minOffset && nextLocation >= this._minOffset || location > this._maxOffset && nextLocation <= this._maxOffset
},
_initHandler: function(e) {
this._stopDeferred = $.Deferred();
this._stopScrolling();
this._prepareThumbScrolling(e);
return this._stopDeferred.promise()
},
_stopScrolling: function() {
this._hideScrollbar();
this._inertiaAnimator.stop();
this._bounceAnimator.stop()
},
_prepareThumbScrolling: function(e) {
if (isWheelEvent(e.originalEvent))
return;
var $target = $(e.originalEvent.target);
var scrollbarClicked = this._isScrollbar($target);
if (scrollbarClicked)
this._moveToMouseLocation(e);
this._thumbScrolling = scrollbarClicked || this._isThumb($target);
if (this._thumbScrolling)
this._scrollbar.feedbackOn()
},
_moveToMouseLocation: function(e) {
var mouseLocation = e["page" + this._axis.toUpperCase()] - this._$element.offset()[this._prop];
var location = this._location + mouseLocation / this._containerToContentRatio() - this._$container.height() / 2;
this._scrollStep(-location)
},
_stopComplete: function() {
if (this._stopDeferred)
this._stopDeferred.resolve()
},
_startHandler: function() {
this._showScrollbar()
},
_moveHandler: function(delta) {
delta = delta[this._axis];
if (this._thumbScrolling)
delta = -delta / this._containerToContentRatio();
if (!this._inBounds())
delta *= OUT_BOUNDS_ACCELERATION;
this._scrollStep(delta)
},
_containerToContentRatio: function() {
return this._scrollbar.containerToContentRatio()
},
_endHandler: function(velocity) {
this._completeDeferred = $.Deferred();
this._velocity = velocity[this._axis];
this._inertiaHandler();
this._resetThumbScrolling();
return this._completeDeferred.promise()
},
_inertiaHandler: function() {
this._suppressIntertia();
this._inertiaAnimator.start()
},
_suppressIntertia: function() {
if (!this._inertiaEnabled || this._thumbScrolling)
this._velocity = 0
},
_resetThumbScrolling: function() {
this._thumbScrolling = false
},
_stopHandler: function() {
this._resetThumbScrolling();
this._scrollToBounds()
},
_disposeHandler: function() {
this._stopScrolling();
this._$scrollbar.remove()
},
_updateHandler: function() {
this._update();
this._moveToBounds()
},
_update: function() {
this._stopScrolling();
this._updateLocation();
this._updateBounds();
this._updateScrollbar();
this._moveScrollbar();
this._scrollbar.update()
},
_updateLocation: function() {
this._location = translator.locate(this._$content)[this._prop]
},
_updateBounds: function() {
this._maxOffset = this._getMaxOffset();
this._minOffset = this._getMinOffset()
},
_getMaxOffset: function() {
return 0
},
_getMinOffset: function() {
return math.min(this._containerSize() - this._contentSize(), 0)
},
_updateScrollbar: function() {
this._scrollbar.option({
containerSize: this._containerSize(),
contentSize: this._contentSize()
})
},
_moveToBounds: function() {
this._location = this._boundLocation();
this._move()
},
_createActionsHandler: function(actions) {
this._scrollAction = actions.scroll;
this._bounceAction = actions.bounce
},
_showScrollbar: function() {
this._scrollbar.option("visible", true)
},
_hideScrollbar: function() {
this._scrollbar.option("visible", false)
},
_containerSize: function() {
return this._$container[this._dimension]()
},
_contentSize: function() {
return this._$content[this._dimension]()
},
_validateEvent: function(e) {
var $target = $(e.originalEvent.target);
if (this._isThumb($target) || this._isScrollbar($target)) {
e.preventDefault();
return true
}
return this._isContent($target)
},
_isThumb: function($element) {
return this._scrollByThumb && this._scrollbar.isThumb($element)
},
_isScrollbar: function($element) {
return this._scrollByThumb && $element && $element.is(this._$scrollbar)
},
_isContent: function($element) {
return this._scrollByContent && !!$element.closest(this._$element).length
},
_reachedMin: function() {
return this._location <= this._minOffset
},
_reachedMax: function() {
return this._location >= this._maxOffset
},
_cursorEnterHandler: function() {
this._scrollbar.cursorEnter()
},
_cursorLeaveHandler: function() {
this._scrollbar.cursorLeave()
},
dispose: $.noop
});
var hoveredScrollable,
activeScrollable;
ui.dxScrollable.SimulatedStrategy = DX.Class.inherit({
ctor: function(scrollable) {
this._init(scrollable)
},
_init: function(scrollable) {
this._component = scrollable;
this._$element = scrollable.element();
this._$container = scrollable._$container;
this._$content = scrollable._$content;
this.option = $.proxy(scrollable.option, scrollable);
this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable);
this._isLocked = $.proxy(scrollable._isLocked, scrollable);
this._isDirection = $.proxy(scrollable._isDirection, scrollable);
this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable);
this._proxiedActiveElementChangeHandler = $.proxy(this._activeElementChangeHandler, this);
scrollIntoViewIfNeededCallbacks.add(this._proxiedActiveElementChangeHandler)
},
_activeElementChangeHandler: function(activeElement) {
this._component.scrollToElement(activeElement)
},
render: function() {
this._$element.addClass(SCROLLABLE_SIMULATED_CLASS);
this._createScrollers();
if (this.option("useKeyboard"))
this._$container.prop("tabindex", 0);
this._attachKeyboardHandler();
this._attachCursorHandlers()
},
_createScrollers: function() {
this._scrollers = {};
if (this._isDirection(HORIZONTAL))
this._createScroller(HORIZONTAL);
if (this._isDirection(VERTICAL))
this._createScroller(VERTICAL);
this._$element.toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this.option("showScrollbar"))
},
_createScroller: function(direction) {
this._scrollers[direction] = new Scroller(this._scrollerOptions(direction))
},
_scrollerOptions: function(direction) {
return {
direction: direction,
$content: this._$content,
$container: this._$container,
$element: this._$element,
scrollByContent: this.option("scrollByContent"),
scrollByThumb: this.option("scrollByThumb"),
scrollbarVisible: this.option("showScrollbar"),
bounceEnabled: this.option("bounceEnabled"),
inertiaEnabled: this.option("inertiaEnabled")
}
},
handleInit: function(e) {
this._supressDirections(e);
this._eventForUserAction = e;
this._eventHandler("init", e).done(this._stopAction)
},
_supressDirections: function(e) {
if (isWheelEvent(e.originalEvent)) {
this._prepareDirections(true);
return
}
this._prepareDirections();
this._eachScroller(function(scroller, direction) {
var isValid = scroller._validateEvent(e);
this._validDirections[direction] = isValid
})
},
_prepareDirections: function(value) {
value = value || false;
this._validDirections = {};
this._validDirections[HORIZONTAL] = value;
this._validDirections[VERTICAL] = value
},
_eachScroller: function(callback) {
callback = $.proxy(callback, this);
$.each(this._scrollers, function(direction, scroller) {
callback(scroller, direction)
})
},
handleStart: function(e) {
this._saveActive();
this._eventHandler("start").done(this._startAction)
},
_saveActive: function() {
activeScrollable = this
},
_resetActive: function() {
activeScrollable = null
},
_validateDirection: function(delta) {
var result = false;
this._eachScroller(function(scroller) {
result = result || scroller._validateDirection(delta)
});
return result
},
handleMove: function(e) {
if (this._isLocked()) {
e.cancel = true;
this._resetActive();
return
}
e.preventDefault && e.preventDefault();
this._adjustDistance(e.delta);
this._eventForUserAction = e;
this._eventHandler("move", e.delta)
},
_adjustDistance: function(distance) {
distance.x *= this._validDirections[HORIZONTAL];
distance.y *= this._validDirections[VERTICAL]
},
handleEnd: function(e) {
this._resetActive();
this._refreshCursorState(e.originalEvent && e.originalEvent.target);
this._adjustDistance(e.velocity);
this._eventForUserAction = e;
return this._eventHandler("end", e.velocity).done(this._endAction)
},
handleCancel: function(e) {
this._resetActive();
this._eventForUserAction = e;
return this._eventHandler("end", {
x: 0,
y: 0
})
},
handleStop: function() {
this._resetActive();
this._eventHandler("stop")
},
handleScroll: function() {
var distance = {
left: this.option("direction") !== VERTICAL ? -this._$container.scrollLeft() : 0,
top: this.option("direction") !== HORIZONTAL ? -this._$container.scrollTop() : 0
};
if (!distance.left && !distance.top)
return;
this._$container.scrollLeft(0);
this._$container.scrollTop(0);
this.scrollBy(distance)
},
_attachKeyboardHandler: function() {
this._$element.off("." + SCROLLABLE_SIMULATED_KEYBOARD);
if (!this.option("disabled") && this.option("useKeyboard"))
this._$element.on(events.addNamespace("keydown", SCROLLABLE_SIMULATED_KEYBOARD), $.proxy(this._keyDownHandler, this))
},
_keyDownHandler: function(e) {
if (!this._$container.is(document.activeElement))
return;
var handled = true;
switch (e.keyCode) {
case KEY_CODES.DOWN:
this._scrollByLine({y: 1});
break;
case KEY_CODES.UP:
this._scrollByLine({y: -1});
break;
case KEY_CODES.RIGHT:
this._scrollByLine({x: 1});
break;
case KEY_CODES.LEFT:
this._scrollByLine({x: -1});
break;
case KEY_CODES.PAGE_DOWN:
this._scrollByPage(1);
break;
case KEY_CODES.PAGE_UP:
this._scrollByPage(-1);
break;
case KEY_CODES.HOME:
this._scrollToHome();
break;
case KEY_CODES.END:
this._scrollToEnd();
break;
default:
handled = false;
break
}
if (handled) {
e.stopPropagation();
e.preventDefault()
}
},
_scrollByLine: function(lines) {
this.scrollBy({
top: (lines.y || 0) * -SCROLL_LINE_HEIGHT,
left: (lines.x || 0) * -SCROLL_LINE_HEIGHT
})
},
_scrollByPage: function(page) {
var prop = this._wheelProp(),
dimension = this._dimensionByProp(prop);
var distance = {};
distance[prop] = page * -this._$container[dimension]();
this.scrollBy(distance)
},
_dimensionByProp: function(prop) {
return prop === "left" ? "width" : "height"
},
_scrollToHome: function() {
var prop = this._wheelProp();
var distance = {};
distance[prop] = 0;
this._component.scrollTo(distance)
},
_scrollToEnd: function() {
var prop = this._wheelProp(),
dimension = this._dimensionByProp(prop);
var distance = {};
distance[prop] = this._$content[dimension]() - this._$container[dimension]();
this._component.scrollTo(distance)
},
createActions: function() {
this._startAction = this._createActionHandler("onStart");
this._stopAction = this._createActionHandler("onStop");
this._endAction = this._createActionHandler("onEnd");
this._updateAction = this._createActionHandler("onUpdated");
this._createScrollerActions()
},
_createScrollerActions: function() {
this._eventHandler("createActions", {
scroll: this._createActionHandler("onScroll"),
bounce: this._createActionHandler("onBounce")
})
},
_createActionHandler: function(optionName) {
var that = this,
actionHandler = that._createActionByOption(optionName);
return function() {
actionHandler($.extend(that._createActionArgs(), arguments))
}
},
_createActionArgs: function() {
var scrollerX = this._scrollers[HORIZONTAL],
scrollerY = this._scrollers[VERTICAL];
return {
jQueryEvent: this._eventForUserAction,
scrollOffset: {
top: scrollerY && -scrollerY._location,
left: scrollerX && -scrollerX._location
},
reachedLeft: scrollerX && scrollerX._reachedMax(),
reachedRight: scrollerX && scrollerX._reachedMin(),
reachedTop: scrollerY && scrollerY._reachedMax(),
reachedBottom: scrollerY && scrollerY._reachedMin()
}
},
_eventHandler: function(eventName) {
var args = $.makeArray(arguments).slice(1),
deferreds = $.map(this._scrollers, function(scroller) {
return scroller["_" + eventName + "Handler"].apply(scroller, args)
});
return $.when.apply($, deferreds).promise()
},
location: function() {
return translator.locate(this._$content)
},
disabledChanged: function() {
this._attachCursorHandlers()
},
_attachCursorHandlers: function() {
this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR);
if (!this.option("disabled") && this._isHoverMode())
this._$element.on(events.addNamespace("mouseenter", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._cursorEnterHandler, this)).on(events.addNamespace("mouseleave", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._cursorLeaveHandler, this))
},
_isHoverMode: function() {
return this.option("showScrollbar") === "onHover"
},
_cursorEnterHandler: function(e) {
e = e || {};
e.originalEvent = e.originalEvent || {};
if (activeScrollable || e.originalEvent._hoverHandled)
return;
if (hoveredScrollable)
hoveredScrollable._cursorLeaveHandler();
hoveredScrollable = this;
this._eventHandler("cursorEnter");
e.originalEvent._hoverHandled = true
},
_cursorLeaveHandler: function(e) {
if (hoveredScrollable !== this || activeScrollable === hoveredScrollable)
return;
this._eventHandler("cursorLeave");
hoveredScrollable = null;
this._refreshCursorState(e && e.relatedTarget)
},
_refreshCursorState: function(target) {
if (!this._isHoverMode() && (!target || activeScrollable))
return;
var $target = $(target);
var $scrollable = $target.closest("." + SCROLLABLE_SIMULATED_CLASS + ":not(.dx-state-disabled)");
var targetScrollable = $scrollable.length && $scrollable.data(SCROLLABLE_STRATEGY);
if (hoveredScrollable && hoveredScrollable !== targetScrollable)
hoveredScrollable._cursorLeaveHandler();
if (targetScrollable)
targetScrollable._cursorEnterHandler()
},
update: function() {
return this._eventHandler("update").done(this._updateAction)
},
_allowedDirections: function() {
var bounceEnabled = this.option("bounceEnabled");
return {
vertical: this._isDirection(VERTICAL) && (this._scrollers[VERTICAL]._minOffset < 0 || bounceEnabled),
horizontal: this._isDirection(HORIZONTAL) && (this._scrollers[HORIZONTAL]._minOffset < 0 || bounceEnabled)
}
},
scrollBy: function(distance) {
this._prepareDirections(true);
this._eventHandler("start").done(this._startAction);
this._eventHandler("move", {
x: distance.left,
y: distance.top
});
this._eventHandler("end", {
x: 0,
y: 0
}).done(this._endAction)
},
validate: function(e) {
if (this.option("disabled"))
return false;
if (this.option("bounceEnabled"))
return true;
return isWheelEvent(e) ? this._validateWheel(e) : this._validateMove(e)
},
_validateWheel: function(e) {
var scroller = this._scrollers[this._wheelDirection()];
var reachedMin = scroller._reachedMin();
var reachedMax = scroller._reachedMax();
var contentGreaterThanContainer = !reachedMin || !reachedMax;
var locatedNotAtBound = !reachedMin && !reachedMax;
var scrollFromMin = reachedMin && e.delta > 0;
var scrollFromMax = reachedMax && e.delta < 0;
return contentGreaterThanContainer && (locatedNotAtBound || scrollFromMin || scrollFromMax)
},
_validateMove: function(e) {
if (!this.option("scrollByContent") && !$(e.target).closest("." + SCROLLABLE_SCROLLBAR_CLASS).length)
return false;
return this._allowedDirection()
},
getDirection: function(e) {
return isWheelEvent(e) ? this._wheelDirection() : this._allowedDirection()
},
_wheelProp: function() {
return this._wheelDirection() === HORIZONTAL ? "left" : "top"
},
_wheelDirection: function() {
switch (this.option("direction")) {
case HORIZONTAL:
return HORIZONTAL;
case VERTICAL:
return VERTICAL;
default:
return this._scrollers[VERTICAL]._containerToContentRatio() >= 1 ? HORIZONTAL : VERTICAL
}
},
dispose: function() {
scrollIntoViewIfNeededCallbacks.remove(this._proxiedActiveElementChangeHandler);
if (activeScrollable === this)
activeScrollable = null;
if (hoveredScrollable === this)
hoveredScrollable = null;
this._eventHandler("dispose");
this._detachEventHandlers();
this._$element.removeClass(SCROLLABLE_SIMULATED_CLASS);
this._eventForUserAction = null;
clearTimeout(this._gestureEndTimer)
},
_detachEventHandlers: function() {
this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR);
this._$container.off("." + SCROLLABLE_SIMULATED_KEYBOARD)
}
});
ui.dxScrollable.__internals = $.extend(ui.dxScrollable.__internals || {}, {
ACCELERATION: ACCELERATION,
MIN_VELOCITY_LIMIT: MIN_VELOCITY_LIMIT,
FRAME_DURATION: FRAME_DURATION,
SCROLL_LINE_HEIGHT: SCROLL_LINE_HEIGHT,
scrollIntoViewIfNeededCallbacks: scrollIntoViewIfNeededCallbacks
})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollView.js */
(function($, DX, undefined) {
var ui = DX.ui;
var SCROLLVIEW_CLASS = "dx-scrollview",
SCROLLVIEW_CONTENT_CLASS = SCROLLVIEW_CLASS + "-content",
SCROLLVIEW_TOP_POCKET_CLASS = SCROLLVIEW_CLASS + "-top-pocket",
SCROLLVIEW_BOTTOM_POCKET_CLASS = SCROLLVIEW_CLASS + "-bottom-pocket",
SCROLLVIEW_PULLDOWN_CLASS = SCROLLVIEW_CLASS + "-pull-down",
SCROLLVIEW_REACHBOTTOM_CLASS = SCROLLVIEW_CLASS + "-scrollbottom",
SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-indicator",
SCROLLVIEW_REACHBOTTOM_TEXT_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-text",
SCROLLVIEW_LOADPANEL = SCROLLVIEW_CLASS + "-loadpanel";
DX.registerComponent("dxScrollView", ui, ui.dxScrollable.inherit({
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {
pullDownAction: {
since: "14.2",
alias: "onPullDown"
},
reachBottomAction: {
since: "14.2",
alias: "onReachBottom"
}
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
pullingDownText: Globalize.localize("dxScrollView-pullingDownText"),
pulledDownText: Globalize.localize("dxScrollView-pulledDownText"),
refreshingText: Globalize.localize("dxScrollView-refreshingText"),
reachBottomText: Globalize.localize("dxScrollView-reachBottomText"),
onPullDown: null,
onReachBottom: null,
refreshStrategy: "pullDown"
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function(device) {
var realDevice = DevExpress.devices.real();
return realDevice.platform === "android"
},
options: {refreshStrategy: "swipeDown"}
}, {
device: function(device) {
return DevExpress.devices.real().platform === "win8"
},
options: {refreshStrategy: "slideDown"}
}])
},
_init: function() {
this.callBase();
this._loadingIndicatorEnabled = true
},
_initMarkup: function() {
this.callBase();
this.element().addClass(SCROLLVIEW_CLASS);
this._initContent();
this._initTopPocket();
this._initBottomPocket();
this._initLoadPanel()
},
_initContent: function() {
var $content = $("
").addClass(SCROLLVIEW_CONTENT_CLASS);
this._$content.wrapInner($content)
},
_initTopPocket: function() {
var $topPocket = this._$topPocket = $("
").addClass(SCROLLVIEW_TOP_POCKET_CLASS),
$pullDown = this._$pullDown = $("
").addClass(SCROLLVIEW_PULLDOWN_CLASS);
$topPocket.append($pullDown);
this._$content.prepend($topPocket)
},
_initBottomPocket: function() {
var $bottomPocket = this._$bottomPocket = $("
").addClass(SCROLLVIEW_BOTTOM_POCKET_CLASS),
$reachBottom = this._$reachBottom = $("
").addClass(SCROLLVIEW_REACHBOTTOM_CLASS),
$loadContainer = $("
").addClass(SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS),
$loadIndicator = $("
").dxLoadIndicator(),
$text = this._$reachBottomText = $("
").addClass(SCROLLVIEW_REACHBOTTOM_TEXT_CLASS);
this._updateReachBottomText();
$reachBottom.append($loadContainer.append($loadIndicator)).append($text);
$bottomPocket.append($reachBottom);
this._$content.append($bottomPocket)
},
_initLoadPanel: function() {
this._loadPanel = this._createComponent($("
").addClass(SCROLLVIEW_LOADPANEL).appendTo(this.element()), "dxLoadPanel", {
shading: false,
delay: 400,
message: this.option("refreshingText"),
position: {of: this.element()}
})
},
_updateReachBottomText: function() {
this._$reachBottomText.text(this.option("reachBottomText"))
},
_createStrategy: function() {
var strategyName = this.option("useNative") ? this.option("refreshStrategy") : "simulated";
var strategyClass = ui.dxScrollView.refreshStrategies[strategyName];
if (!strategyClass)
throw Error("E1030", this.option("refreshStrategy"));
this._strategy = new strategyClass(this);
this._strategy.pullDownCallbacks.add($.proxy(this._pullDownHandler, this));
this._strategy.releaseCallbacks.add($.proxy(this._releaseHandler, this));
this._strategy.reachBottomCallbacks.add($.proxy(this._reachBottomHandler, this))
},
_createActions: function() {
this.callBase();
this._pullDownAction = this._createActionByOption("onPullDown");
this._reachBottomAction = this._createActionByOption("onReachBottom");
this._pullDownEnable(!!this.option("onPullDown") && !DX.designMode);
this._reachBottomEnable(!!this.option("onReachBottom") && !DX.designMode)
},
_pullDownEnable: function(enabled) {
if (arguments.length === 0)
return this._pullDownEnabled;
this._$pullDown.toggle(enabled);
this._strategy.pullDownEnable(enabled);
this._pullDownEnabled = enabled
},
_reachBottomEnable: function(enabled) {
if (arguments.length === 0)
return this._reachBottomEnabled;
this._$reachBottom.toggle(enabled);
this._strategy.reachBottomEnable(enabled);
this._reachBottomEnabled = enabled
},
_pullDownHandler: function() {
this._loadingIndicator(false);
this._pullDownLoading()
},
_loadingIndicator: function(value) {
if (arguments.length < 1)
return this._loadingIndicatorEnabled;
this._loadingIndicatorEnabled = value
},
_pullDownLoading: function() {
this.startLoading();
this._pullDownAction()
},
_reachBottomHandler: function() {
this._loadingIndicator(false);
this._reachBottomLoading()
},
_reachBottomLoading: function() {
this.startLoading();
this._reachBottomAction()
},
_releaseHandler: function() {
this.finishLoading();
this._loadingIndicator(true)
},
_optionChanged: function(args) {
switch (args.name) {
case"onPullDown":
case"onReachBottom":
this._createActions();
break;
case"pullingDownText":
case"pulledDownText":
case"refreshingText":
case"refreshStrategy":
this._invalidate();
break;
case"reachBottomText":
this._updateReachBottomText();
break;
default:
this.callBase(args)
}
},
isEmpty: function() {
return !this.content().children().length
},
content: function() {
return this._$content.children().eq(1)
},
release: function(preventReachBottom) {
if (preventReachBottom !== undefined)
this.toggleLoading(!preventReachBottom);
return this._strategy.release()
},
toggleLoading: function(showOrHide) {
this._reachBottomEnable(showOrHide)
},
isFull: function() {
return this.content().height() >= this._$container.height()
},
refresh: function() {
if (!this.option("onPullDown"))
return;
this._strategy.pendingRelease();
this._pullDownLoading()
},
startLoading: function() {
if (this._loadingIndicator() && this.element().is(":visible"))
this._loadPanel.show();
this._lock()
},
finishLoading: function() {
this._loadPanel.hide();
this._unlock()
},
_dispose: function() {
this._strategy.dispose();
this.callBase();
if (this._loadPanel)
this._loadPanel.element().remove()
}
}));
ui.dxScrollView.refreshStrategies = {}
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollView.native.pullDown.js */
(function($, DX, undefined) {
var ui = DX.ui;
var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading",
SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready",
SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image",
SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",
SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text",
STATE_RELEASED = 0,
STATE_READY = 1,
STATE_REFRESHING = 2,
STATE_LOADING = 3;
var PullDownNativeScrollViewStrategy = ui.dxScrollable.NativeStrategy.inherit({
_init: function(scrollView) {
this.callBase(scrollView);
this._$topPocket = scrollView._$topPocket;
this._$pullDown = scrollView._$pullDown;
this._$bottomPocket = scrollView._$bottomPocket;
this._$refreshingText = scrollView._$refreshingText;
this._$scrollViewContent = scrollView.content();
this._initCallbacks()
},
_initCallbacks: function() {
this.pullDownCallbacks = $.Callbacks();
this.releaseCallbacks = $.Callbacks();
this.reachBottomCallbacks = $.Callbacks()
},
render: function() {
this.callBase();
this._renderPullDown();
this._releaseState()
},
_renderPullDown: function() {
var $image = $("
").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS),
$loadContainer = $("
").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),
$loadIndicator = $("
").dxLoadIndicator(),
$text = this._$pullDownText = $("
").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS);
this._$pullingDownText = $("
").text(this.option("pullingDownText")).appendTo($text);
this._$pulledDownText = $("
").text(this.option("pulledDownText")).appendTo($text);
this._$refreshingText = $("
").text(this.option("refreshingText")).appendTo($text);
this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text)
},
_releaseState: function() {
this._state = STATE_RELEASED;
this._refreshPullDownText()
},
_pushBackFromBoundary: function() {
if (!this._isLocked() && !this._component.isEmpty())
this.callBase()
},
_refreshPullDownText: function() {
this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0);
this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0);
this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0)
},
update: function() {
this.callBase();
this._setTopPocketOffset()
},
_updateDimensions: function() {
this.callBase();
this._topPocketSize = this._$topPocket.height();
this._bottomPocketSize = this._$bottomPocket.height();
this._scrollOffset = this._$container.height() - this._$content.height()
},
_allowedDirections: function() {
var allowedDirections = this.callBase();
allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled;
return allowedDirections
},
_setTopPocketOffset: function() {
this._$topPocket.css({top: -this._topPocketSize})
},
handleEnd: function() {
this._complete()
},
handleStop: function() {
this._complete()
},
_complete: function() {
if (this._state === STATE_READY) {
this._setPullDownOffset(this._topPocketSize);
clearTimeout(this._pullDownRefreshTimeout);
this._pullDownRefreshTimeout = setTimeout($.proxy(function() {
this._pullDownRefreshing()
}, this), 400)
}
},
_setPullDownOffset: function(offset) {
DX.translator.move(this._$topPocket, {top: offset});
DX.translator.move(this._$scrollViewContent, {top: offset})
},
handleScroll: function(e) {
this.callBase(e);
if (this._state === STATE_REFRESHING)
return;
this._location = this.location().top;
if (this._isPullDown())
this._pullDownReady();
else if (this._isReachBottom())
this._reachBottom();
else
this._stateReleased()
},
_isPullDown: function() {
return this._pullDownEnabled && this._location >= this._topPocketSize
},
_isReachBottom: function() {
return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize
},
_reachBottom: function() {
if (this._state === STATE_LOADING)
return;
this._state = STATE_LOADING;
this.reachBottomCallbacks.fire()
},
_pullDownReady: function() {
if (this._state === STATE_READY)
return;
this._state = STATE_READY;
this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
this._refreshPullDownText()
},
_stateReleased: function() {
if (this._state === STATE_RELEASED)
return;
this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
this._releaseState()
},
_pullDownRefreshing: function() {
if (this._state === STATE_REFRESHING)
return;
this._state = STATE_REFRESHING;
this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
this._refreshPullDownText();
this.pullDownCallbacks.fire()
},
pullDownEnable: function(enabled) {
this._pullDownEnabled = enabled
},
reachBottomEnable: function(enabled) {
this._reachBottomEnabled = enabled
},
pendingRelease: function() {
this._state = STATE_READY
},
release: function() {
var deferred = $.Deferred();
this._updateDimensions();
clearTimeout(this._releaseTimeout);
this._releaseTimeout = setTimeout($.proxy(function() {
this._setPullDownOffset(0);
this._stateReleased();
this.releaseCallbacks.fire();
this._updateAction();
deferred.resolve()
}, this), 400);
return deferred.promise()
},
dispose: function() {
clearTimeout(this._pullDownRefreshTimeout);
clearTimeout(this._releaseTimeout);
this.callBase()
}
});
ui.dxScrollView.refreshStrategies.pullDown = PullDownNativeScrollViewStrategy
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollView.native.swipeDown.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var SCROLLVIEW_PULLDOWN_DOWN_LOADING_CLASS = "dx-scrollview-pull-down-loading",
SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",
SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-refreshing",
PULLDOWN_ICON_CLASS = "dx-icon-pulldown",
STATE_RELEASED = 0,
STATE_READY = 1,
STATE_REFRESHING = 2,
STATE_TOUCHED = 4,
STATE_PULLED = 5;
var SwipeDownNativeScrollViewStrategy = ui.dxScrollable.NativeStrategy.inherit({
_init: function(scrollView) {
this.callBase(scrollView);
this._$topPocket = scrollView._$topPocket;
this._$bottomPocket = scrollView._$bottomPocket;
this._$pullDown = scrollView._$pullDown;
this._$scrollViewContent = scrollView.content();
this._initCallbacks();
this._location = 0
},
_initCallbacks: function() {
this.pullDownCallbacks = $.Callbacks();
this.releaseCallbacks = $.Callbacks();
this.reachBottomCallbacks = $.Callbacks()
},
render: function() {
this.callBase();
this._renderPullDown();
this._releaseState()
},
_renderPullDown: function() {
var $loadContainer = $("
").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),
$loadIndicator = $("
").dxLoadIndicator({});
this._$icon = $("
").addClass(PULLDOWN_ICON_CLASS);
this._$pullDown.empty().append(this._$icon).append($loadContainer.append($loadIndicator))
},
_releaseState: function() {
this._state = STATE_RELEASED;
this._releasePullDown();
this._updateDimensions()
},
_releasePullDown: function() {
this._$pullDown.css({opacity: 0})
},
_updateDimensions: function() {
this.callBase();
this._topPocketSize = this._$topPocket.height();
this._bottomPocketSize = this._$bottomPocket.height();
this._scrollOffset = this._$container.height() - this._$content.height()
},
_allowedDirections: function() {
var allowedDirections = this.callBase();
allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled;
return allowedDirections
},
handleInit: function(e) {
this.callBase(e);
if (this._state === STATE_RELEASED && this._location === 0) {
this._startClientY = events.eventData(e.originalEvent).y;
this._state = STATE_TOUCHED
}
},
handleMove: function(e) {
this.callBase(e);
this._deltaY = events.eventData(e.originalEvent).y - this._startClientY;
if (this._state === STATE_TOUCHED)
if (this._pullDownEnabled && this._deltaY > 0)
this._state = STATE_PULLED;
else
this._complete();
if (this._state === STATE_PULLED) {
e.preventDefault();
this._movePullDown()
}
},
_movePullDown: function() {
var pullDownHeight = this._getPullDownHeight(),
top = Math.min(pullDownHeight * 3, this._deltaY + this._getPullDownStartPosition()),
angle = 180 * top / pullDownHeight / 3;
this._$pullDown.css({opacity: 1}).toggleClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS, top < pullDownHeight);
DX.translator.move(this._$pullDown, {top: top});
this._$icon.css({transform: "rotate(" + angle + "deg)"})
},
_isPullDown: function() {
return this._pullDownEnabled && this._deltaY >= this._getPullDownHeight() - this._getPullDownStartPosition()
},
_getPullDownHeight: function() {
return Math.round(this._$element.outerHeight() * 0.05)
},
_getPullDownStartPosition: function() {
return -Math.round(this._$pullDown.outerHeight() * 1.5)
},
handleEnd: function() {
if (this._isPullDown())
this._pullDownRefreshing();
this._complete()
},
handleStop: function() {
this._complete()
},
_complete: function() {
if (this._state === STATE_TOUCHED || this._state === STATE_PULLED)
this._releaseState()
},
handleScroll: function(e) {
this.callBase(e);
if (this._state === STATE_REFRESHING)
return;
var currentLocation = this.location().top,
scrollDelta = this._location - currentLocation;
this._location = currentLocation;
if (scrollDelta > 0 && this._isReachBottom())
this._reachBottom();
else
this._stateReleased()
},
_isReachBottom: function() {
return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize
},
_reachBottom: function() {
this.reachBottomCallbacks.fire()
},
_stateReleased: function() {
if (this._state === STATE_RELEASED)
return;
this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_DOWN_LOADING_CLASS);
this._releaseState()
},
_pullDownRefreshing: function() {
this._state = STATE_REFRESHING;
this._pullDownRefreshHandler()
},
_pullDownRefreshHandler: function() {
this._refreshPullDown();
this.pullDownCallbacks.fire()
},
_refreshPullDown: function() {
this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_DOWN_LOADING_CLASS);
DX.translator.move(this._$pullDown, {top: this._getPullDownHeight()})
},
pullDownEnable: function(enabled) {
this._$topPocket.toggle(enabled);
this._pullDownEnabled = enabled
},
reachBottomEnable: function(enabled) {
this._reachBottomEnabled = enabled
},
pendingRelease: function() {
this._state = STATE_READY
},
release: function() {
var deferred = $.Deferred();
this._updateDimensions();
clearTimeout(this._releaseTimeout);
this._releaseTimeout = setTimeout($.proxy(function() {
this._stateReleased();
this.releaseCallbacks.fire();
this._updateAction();
deferred.resolve()
}, this), 800);
return deferred.promise()
},
dispose: function() {
clearTimeout(this._pullDownRefreshTimeout);
clearTimeout(this._releaseTimeout);
this.callBase()
}
});
ui.dxScrollView.refreshStrategies.swipeDown = SwipeDownNativeScrollViewStrategy
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollView.native.slideDown.js */
(function($, DX, undefined) {
var ui = DX.ui;
var STATE_RELEASED = 0,
STATE_READY = 1,
STATE_LOADING = 2,
LOADING_HEIGHT = 80;
var SlideDownNativeScrollViewStrategy = ui.dxScrollable.NativeStrategy.inherit({
_init: function(scrollView) {
this.callBase(scrollView);
this._$topPocket = scrollView._$topPocket;
this._$bottomPocket = scrollView._$bottomPocket;
this._initCallbacks()
},
_initCallbacks: function() {
this.pullDownCallbacks = $.Callbacks();
this.releaseCallbacks = $.Callbacks();
this.reachBottomCallbacks = $.Callbacks()
},
render: function() {
this.callBase();
this._renderPullDown();
this._renderBottom();
this._releaseState();
this._updateDimensions()
},
_renderPullDown: function() {
this._$topPocket.empty()
},
_renderBottom: function() {
this._$bottomPocket.empty().append("
")
},
_releaseState: function() {
if (this._state === STATE_RELEASED)
return;
this._state = STATE_RELEASED
},
_updateDimensions: function() {
this._scrollOffset = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight");
this._containerSize = {
height: this._$container.prop("clientHeight"),
width: this._$container.prop("clientWidth")
};
this._contentSize = this._componentContentSize = {
height: this._$container.prop("scrollHeight"),
width: this._$container.prop("scrollWidth")
}
},
handleScroll: function(e) {
this.callBase(e);
if (this._isReachBottom(this._lastLocation.top))
this._reachBottom()
},
_isReachBottom: function(location) {
this._scrollContent = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight");
return this._reachBottomEnabled && location < -this._scrollContent + LOADING_HEIGHT
},
_reachBottom: function() {
if (this._state === STATE_LOADING)
return;
this._state = STATE_LOADING;
this.reachBottomCallbacks.fire()
},
pullDownEnable: function(enabled) {
this._pullDownEnabled = enabled
},
reachBottomEnable: function(enabled) {
this._reachBottomEnabled = enabled;
this._$bottomPocket.toggle(enabled)
},
pendingRelease: function() {
this._state = STATE_READY
},
release: function() {
var deferred = $.Deferred();
this._state = STATE_RELEASED;
this.releaseCallbacks.fire();
this.update();
return deferred.resolve().promise()
}
});
ui.dxScrollView.refreshStrategies.slideDown = SlideDownNativeScrollViewStrategy
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.scrollView.simulated.js */
(function($, DX, undefined) {
var ui = DX.ui,
math = Math;
var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading",
SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready",
SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image",
SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",
SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text",
STATE_RELEASED = 0,
STATE_READY = 1,
STATE_REFRESHING = 2,
STATE_LOADING = 3;
var ScrollViewScroller = ui.dxScrollView.Scroller = ui.dxScrollable.Scroller.inherit({
ctor: function() {
this.callBase.apply(this, arguments);
this._initCallbacks();
this._releaseState()
},
_releaseState: function() {
this._state = STATE_RELEASED;
this._refreshPullDownText()
},
_refreshPullDownText: function() {
this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0);
this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0);
this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0)
},
_initCallbacks: function() {
this.pullDownCallbacks = $.Callbacks();
this.releaseCallbacks = $.Callbacks();
this.reachBottomCallbacks = $.Callbacks()
},
_updateBounds: function() {
var considerPockets = this._direction !== "horizontal";
this._topPocketSize = considerPockets ? this._$topPocket[this._dimension]() : 0;
this._bottomPocketSize = considerPockets ? this._$bottomPocket[this._dimension]() : 0;
this.callBase();
this._bottomBound = this._minOffset
},
_updateScrollbar: function() {
this._scrollbar.option({
containerSize: this._containerSize(),
contentSize: this._contentSize() - this._topPocketSize - this._bottomPocketSize
})
},
_moveContent: function() {
this.callBase();
if (this._isPullDown())
this._pullDownReady();
else if (this._isReachBottom())
this._reachBottomReady();
else if (this._state !== STATE_RELEASED)
this._stateReleased()
},
_moveScrollbar: function() {
this._scrollbar.moveTo(this._topPocketSize + this._location)
},
_isPullDown: function() {
return this._pullDownEnabled && this._location >= 0
},
_isReachBottom: function() {
return this._reachBottomEnabled && this._location <= this._bottomBound
},
_scrollComplete: function() {
if (this._inBounds() && this._state === STATE_READY)
this._pullDownRefreshing();
else if (this._inBounds() && this._state === STATE_LOADING)
this._reachBottomLoading();
else
this.callBase()
},
_reachBottomReady: function() {
if (this._state === STATE_LOADING)
return;
this._state = STATE_LOADING;
this._minOffset = this._getMinOffset()
},
_getMaxOffset: function() {
return -this._topPocketSize
},
_getMinOffset: function() {
return math.min(this.callBase(), -this._topPocketSize)
},
_reachBottomLoading: function() {
this.reachBottomCallbacks.fire()
},
_pullDownReady: function() {
if (this._state === STATE_READY)
return;
this._state = STATE_READY;
this._maxOffset = 0;
this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
this._refreshPullDownText()
},
_stateReleased: function() {
if (this._state === STATE_RELEASED)
return;
this._releaseState();
this._updateBounds();
this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
this.releaseCallbacks.fire()
},
_pullDownRefreshing: function() {
if (this._state === STATE_REFRESHING)
return;
this._state = STATE_REFRESHING;
this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
this._refreshPullDownText();
this.pullDownCallbacks.fire()
},
_releaseHandler: function() {
if (this._state === STATE_RELEASED)
this._moveToBounds();
this._update();
if (this._releaseTask)
this._releaseTask.abort();
this._releaseTask = DX.utils.executeAsync($.proxy(this._release, this));
return this._releaseTask.promise
},
_release: function() {
this._stateReleased();
this._scrollComplete()
},
_reachBottomEnablingHandler: function(enabled) {
if (this._reachBottomEnabled === enabled)
return;
this._reachBottomEnabled = enabled;
this._updateBounds()
},
_pullDownEnablingHandler: function(enabled) {
if (this._pullDownEnabled === enabled)
return;
this._pullDownEnabled = enabled;
this._considerTopPocketChange();
this._updateHandler()
},
_considerTopPocketChange: function() {
this._location -= this._$topPocket.height() || -this._topPocketSize;
this._move()
},
_pendingReleaseHandler: function() {
this._state = STATE_READY
},
dispose: function() {
if (this._releaseTask)
this._releaseTask.abort();
this.callBase()
}
});
var SimulatedScrollViewStrategy = ui.dxScrollable.SimulatedStrategy.inherit({
_init: function(scrollView) {
this.callBase(scrollView);
this._$pullDown = scrollView._$pullDown;
this._$topPocket = scrollView._$topPocket;
this._$bottomPocket = scrollView._$bottomPocket;
this._initCallbacks()
},
_initCallbacks: function() {
this.pullDownCallbacks = $.Callbacks();
this.releaseCallbacks = $.Callbacks();
this.reachBottomCallbacks = $.Callbacks()
},
render: function() {
this._renderPullDown();
this.callBase()
},
_renderPullDown: function() {
var $image = $("").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS),
$loadContainer = $("
").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),
$loadIndicator = $("
").dxLoadIndicator(),
$text = this._$pullDownText = $("
").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS);
this._$pullingDownText = $("
").text(this.option("pullingDownText")).appendTo($text);
this._$pulledDownText = $("
").text(this.option("pulledDownText")).appendTo($text);
this._$refreshingText = $("
").text(this.option("refreshingText")).appendTo($text);
this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text)
},
pullDownEnable: function(enabled) {
this._eventHandler("pullDownEnabling", enabled)
},
reachBottomEnable: function(enabled) {
this._eventHandler("reachBottomEnabling", enabled)
},
_createScroller: function(direction) {
var that = this;
var scroller = that._scrollers[direction] = new ScrollViewScroller(that._scrollerOptions(direction));
scroller.pullDownCallbacks.add(function() {
that.pullDownCallbacks.fire()
});
scroller.releaseCallbacks.add(function() {
that.releaseCallbacks.fire()
});
scroller.reachBottomCallbacks.add(function() {
that.reachBottomCallbacks.fire()
})
},
_scrollerOptions: function(direction) {
return $.extend(this.callBase(direction), {
$topPocket: this._$topPocket,
$bottomPocket: this._$bottomPocket,
$pullDown: this._$pullDown,
$pullDownText: this._$pullDownText,
$pullingDownText: this._$pullingDownText,
$pulledDownText: this._$pulledDownText,
$refreshingText: this._$refreshingText
})
},
pendingRelease: function() {
this._eventHandler("pendingRelease")
},
release: function() {
return this._eventHandler("release").done(this._updateAction)
},
location: function() {
var location = this.callBase();
location.top += this._$topPocket.height();
return location
},
dispose: function() {
$.each(this._scrollers, function() {
this.dispose()
});
this.callBase()
}
});
ui.dxScrollView.refreshStrategies.simulated = SimulatedScrollViewStrategy
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.map.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
utils = DX.utils,
winJS = DX.support.winJS,
wrapToArray = utils.wrapToArray,
removeDublicates = utils.removeDublicates,
titleize = DX.inflector.titleize;
var MAP_CLASS = "dx-map",
MAP_CONTAINER_CLASS = "dx-map-container",
MAP_SHIELD_CLASS = "dx-map-shield";
DX.registerComponent("dxMap", ui, ui.Widget.inherit({
ctor: function() {
this.callBase.apply(this, arguments);
this.addMarker = $.proxy(this._addFunction, this, "markers");
this.removeMarker = $.proxy(this._removeFunction, this, "markers");
this.addRoute = $.proxy(this._addFunction, this, "routes");
this.removeRoute = $.proxy(this._removeFunction, this, "routes")
},
_addFunction: function(optionName, addingValue) {
var deferred = $.Deferred(),
that = this,
providerDeffered = $.Deferred(),
optionValue = this.option(optionName),
addingValues = wrapToArray(addingValue);
optionValue.push.apply(optionValue, addingValues);
this._notificationDeffered = providerDeffered;
this.option(optionName, optionValue);
providerDeffered.done(function(instance) {
deferred.resolveWith(that, instance && instance.length > 1 ? [instance] : instance)
});
return deferred.promise()
},
_removeFunction: function(optionName, removingValue) {
var deferred = $.Deferred(),
that = this,
providerDeffered = $.Deferred(),
optionValue = this.option(optionName),
removingValues = wrapToArray(removingValue);
$.each(removingValues, function(_, removingValue) {
var index = $.isNumeric(removingValue) ? removingValue : $.inArray(removingValue, optionValue);
if (index !== -1)
optionValue.splice(index, 1);
else
throw DX.log("E1021", titleize(optionName.substring(0, optionName.length - 1)), removingValue);
});
this._notificationDeffered = providerDeffered;
this.option(optionName, optionValue);
providerDeffered.done(function() {
deferred.resolveWith(that)
});
return deferred.promise()
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {
markerAddedAction: {
since: "14.2",
alias: "onMarkerAdded"
},
markerRemovedAction: {
since: "14.2",
alias: "onMarkerRemoved"
},
readyAction: {
since: "14.2",
alias: "onReady"
},
routeAddedAction: {
since: "14.2",
alias: "onRouteAdded"
},
routeRemovedAction: {
since: "14.2",
alias: "onRouteRemoved"
},
clickAction: {
since: "14.2",
alias: "onClick"
}
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
bounds: {
northEast: null,
southWest: null
},
center: {
lat: 0,
lng: 0
},
zoom: 1,
width: 300,
height: 300,
type: "roadmap",
provider: "google",
autoAdjust: true,
markers: [],
markerIconSrc: null,
onMarkerAdded: null,
onMarkerRemoved: null,
routes: [],
onRouteAdded: null,
onRouteRemoved: null,
key: {
bing: "",
google: "",
googleStatic: ""
},
controls: false,
onReady: null,
onUpdated: null,
onClick: null
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function(device) {
return DX.devices.real().generic && !DX.devices.isSimulator()
},
options: {focusStateEnabled: true}
}])
},
_init: function() {
this.callBase();
this._asyncQueue = [];
this._checkProvider();
this._checkMarkersOption(this.option("markers"));
this._checkRoutesOption(this.option("routes"));
this._initContainer();
this._grabEvents();
this._cleanRenderedMarkers();
this._cleanRenderedRoutes()
},
_checkProvider: function() {
if (winJS && this.option("provider") === "google")
throw DX.Error("E1024");
},
_checkMarkersOption: function(markers) {
if (!$.isArray(markers))
throw DX.Error("E1022");
},
_checkRoutesOption: function(routes) {
if (!$.isArray(routes))
throw DX.Error("E1023");
},
_initContainer: function() {
this._$container = $("
").addClass(MAP_CONTAINER_CLASS);
this.element().append(this._$container)
},
_grabEvents: function() {
var eventName = events.addNamespace("dxpointerdown", this.NAME);
this.element().on(eventName, $.proxy(this._cancelEvent, this))
},
_cancelEvent: function(e) {
var cancelByProvider = this._provider.cancelEvents && !this.option("disabled");
if (!DX.designMode && cancelByProvider)
e.stopPropagation()
},
_cleanRenderedMarkers: function() {
this._renderedMarkers = []
},
_cleanRenderedRoutes: function(routes) {
this._renderedRoutes = []
},
_render: function() {
this.callBase();
this.element().addClass(MAP_CLASS);
this._renderShield();
this._queueAsyncAction("render", this.option("markers"), this.option("routes"));
this._saveRenderedMarkers();
this._saveRenderedRoutes()
},
_saveRenderedMarkers: function(markers) {
markers = markers || this.option("markers");
this._renderedMarkers = markers.slice()
},
_saveRenderedRoutes: function(routes) {
routes = routes || this.option("routes");
this._renderedRoutes = routes.slice()
},
_renderShield: function() {
var $shield;
if (DX.designMode || this.option("disabled")) {
$shield = $("
").addClass(MAP_SHIELD_CLASS);
this.element().append($shield)
}
else {
$shield = this.element().find("." + MAP_SHIELD_CLASS);
$shield.remove()
}
},
_clean: function() {
this._cleanFocusState();
if (!this._provider)
return;
this._queueAsyncAction("clean");
this._cleanRenderedMarkers();
this._cleanRenderedRoutes()
},
_optionChanged: function(args) {
var value = args.value;
if (this._cancelOptionChange)
return;
var notificationDeffered = this._notificationDeffered;
delete this._notificationDeffered;
switch (args.name) {
case"disabled":
this._renderShield();
this.callBase(args);
break;
case"width":
case"height":
this.callBase(args);
this._dimensionChanged();
break;
case"provider":
this._invalidate();
break;
case"key":
DX.log("W1001");
break;
case"bounds":
this._queueAsyncAction("updateBounds");
break;
case"center":
this._queueAsyncAction("updateCenter");
break;
case"zoom":
this._queueAsyncAction("updateZoom");
break;
case"type":
this._queueAsyncAction("updateMapType");
break;
case"controls":
this._queueAsyncAction("updateControls", this.option("markers"), this.option("routes"));
break;
case"autoAdjust":
this._queueAsyncAction("adjustViewport");
break;
case"markers":
this._checkMarkersOption(value);
this._queueAsyncAction("updateMarkers", notificationDeffered ? removeDublicates(this._renderedMarkers, value) : this._renderedMarkers, notificationDeffered ? removeDublicates(value, this._renderedMarkers) : value).done($.proxy(function() {
if (notificationDeffered)
notificationDeffered.resolve.apply(notificationDeffered, arguments)
}, this));
this._saveRenderedMarkers(value);
break;
case"markerIconSrc":
this._queueAsyncAction("updateMarkers", this._renderedMarkers, this._renderedMarkers);
break;
case"routes":
this._checkRoutesOption(value);
this._queueAsyncAction("updateRoutes", notificationDeffered ? removeDublicates(this._renderedRoutes, value) : this._renderedRoutes, notificationDeffered ? removeDublicates(value, this._renderedRoutes) : value).done($.proxy(function() {
if (notificationDeffered)
notificationDeffered.resolve.apply(notificationDeffered, arguments)
}, this));
this._saveRenderedRoutes(value);
break;
case"onReady":
case"onUpdated":
case"onMarkerAdded":
case"onMarkerRemoved":
case"onRouteAdded":
case"onRouteRemoved":
case"onClick":
break;
default:
this.callBase.apply(this, arguments)
}
},
_visibilityChanged: function(visible) {
if (visible)
this._dimensionChanged()
},
_dimensionChanged: function() {
this._queueAsyncAction("updateDimensions")
},
_queueAsyncAction: function(name) {
var deferred = $.Deferred(),
emptyQueue = !this._asyncQueue.length;
this._asyncQueue.push({
name: name,
options: $.makeArray(arguments).slice(1),
deferred: deferred
});
if (emptyQueue)
this._enqueueAsyncAction();
return deferred.promise()
},
_enqueueAsyncAction: function() {
var emptyQueue = !this._asyncQueue.length;
if (emptyQueue)
return;
this._execAsyncAction(this._asyncQueue[0]).done($.proxy(function() {
this._asyncQueue.shift();
this._enqueueAsyncAction()
}, this))
},
_execAsyncAction: function(action) {
var deferred = $.Deferred(),
actionName = action.name,
actionOptions = action.options,
actionDeferred = action.deferred,
provider = this._getProvider(actionName);
provider[actionName].apply(provider, actionOptions).done($.proxy(function(mapRefreshed) {
actionDeferred.resolve.apply(actionDeferred, $.makeArray(arguments).slice(1));
if (mapRefreshed)
this._triggerReadyAction();
else if (actionName !== "clean")
this._triggerUpdateAction();
deferred.resolve()
}, this));
return deferred.promise()
},
_getProvider: function(actionName) {
var currentProvider = this.option("provider");
if (actionName !== "clean" && this._usedProvider !== currentProvider) {
this._provider = new providers[currentProvider](this, this._$container);
this._usedProvider = currentProvider
}
return this._provider
},
_triggerReadyAction: function() {
this._createActionByOption("onReady")({originalMap: this._provider.map()})
},
_triggerUpdateAction: function() {
this._createActionByOption("onUpdated")()
},
setOptionSilent: function(name, value) {
this._cancelOptionChange = true;
this.option(name, value);
this._cancelOptionChange = false
}
}));
var providers = {};
ui.dxMap.registerProvider = function(name, provider) {
providers[name] = provider
}
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.map.provider.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
ui.dxMap.Provider = DX.Class.inherit({
_defaultRouteWeight: function() {
return 5
},
_defaultRouteOpacity: function() {
return 0.5
},
_defaultRouteColor: function() {
return "#0000FF"
},
cancelEvents: false,
ctor: function(map, $container) {
this._mapWidget = map;
this._$container = $container
},
render: function(markerOptions, routeOptions) {
var deferred = $.Deferred();
this._renderImpl().done($.proxy(function() {
var markersPromise = this.addMarkers(markerOptions);
var routesPromise = this.addRoutes(routeOptions);
$.when(markersPromise, routesPromise).done(function() {
deferred.resolve(true)
})
}, this));
return deferred.promise()
},
_renderImpl: DX.abstract,
updateDimensions: DX.abstract,
updateMapType: DX.abstract,
updateBounds: DX.abstract,
updateCenter: DX.abstract,
updateZoom: DX.abstract,
updateControls: DX.abstract,
updateMarkers: function(markerOptionsToRemove, markerOptionsToAdd) {
var deferred = $.Deferred(),
that = this;
this.removeMarkers(markerOptionsToRemove).done(function() {
that.addMarkers(markerOptionsToAdd).done(function() {
deferred.resolve.apply(deferred, arguments)
})
});
return deferred.promise()
},
addMarkers: DX.abstract,
removeMarkers: DX.abstract,
adjustViewport: DX.abstract,
updateRoutes: function(routeOptionsToRemove, routeOptionsToAdd) {
var deferred = $.Deferred(),
that = this;
this.removeRoutes(routeOptionsToRemove).done(function() {
that.addRoutes(routeOptionsToAdd).done(function() {
deferred.resolve.apply(deferred, arguments)
})
});
return deferred.promise()
},
addRoutes: DX.abstract,
removeRoutes: DX.abstract,
clean: DX.abstract,
map: function() {
return this._map
},
_option: function(name, value) {
if (value === undefined)
return this._mapWidget.option(name);
this._mapWidget.setOptionSilent(name, value)
},
_keyOption: function(providerName) {
var key = this._option("key");
return key[providerName] === undefined ? key : key[providerName]
},
_parseTooltipOptions: function(option) {
return {
text: option.text || option,
visible: option.isShown || false
}
},
_getLatLng: function(location) {
if (typeof location === "string") {
var coords = $.map(location.split(","), $.trim),
numericRegex = /[-+]?[0-9]*\.?[0-9]*/;
if (coords.length === 2 && coords[0].match(numericRegex) && coords[1].match(numericRegex))
return {
lat: parseFloat(coords[0]),
lng: parseFloat(coords[1])
}
}
else if ($.isArray(location) && location.length === 2)
return {
lat: location[0],
lng: location[1]
};
else if ($.isPlainObject(location) && $.isNumeric(location.lat) && $.isNumeric(location.lng))
return location;
return null
},
_isBoundsSetted: function() {
return this._option("bounds.northEast") && this._option("bounds.southWest")
},
_addEventNamespace: function(name) {
return events.addNamespace(name, this._mapWidget.NAME)
},
_createAction: function() {
var mapWidget = this._mapWidget;
return mapWidget._createAction.apply(mapWidget, arguments)
},
_fireAction: function(name, actionArguments) {
var option = this._option(name);
if (option)
this._createAction(option)(actionArguments)
},
_fireClickAction: function(actionArguments) {
this._fireAction("onClick", actionArguments)
},
_fireMarkerAddedAction: function(actionArguments) {
this._fireAction("onMarkerAdded", actionArguments)
},
_fireMarkerRemovedAction: function(actionArguments) {
this._fireAction("onMarkerRemoved", actionArguments)
},
_fireRouteAddedAction: function(actionArguments) {
this._fireAction("onRouteAdded", actionArguments)
},
_fireRouteRemovedAction: function(actionArguments) {
this._fireAction("onRouteRemoved", actionArguments)
}
})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.map.provider.googleStatic.js */
(function($, DX, undefined) {
var ui = DX.ui;
var GOOGLE_STATIC_URL = "https://maps.google.com/maps/api/staticmap?";
ui.dxMap.registerProvider("googleStatic", ui.dxMap.Provider.inherit({
_locationToString: function(location) {
var latlng = this._getLatLng(location);
return latlng ? latlng.lat + "," + latlng.lng : location.toString().replace(/ /g, "+")
},
_renderImpl: function() {
return this._updateMap()
},
updateDimensions: function() {
return this._updateMap()
},
updateMapType: function() {
return this._updateMap()
},
updateBounds: function() {
return $.Deferred().resolve().promise()
},
updateCenter: function() {
return this._updateMap()
},
updateZoom: function() {
return this._updateMap()
},
updateControls: function() {
return $.Deferred().resolve().promise()
},
addMarkers: function(options) {
var that = this;
return this._updateMap().done(function() {
$.each(options, function(_, options) {
that._fireMarkerAddedAction({options: options})
})
})
},
removeMarkers: function(options) {
var that = this;
return this._updateMap().done(function() {
$.each(options, function(_, options) {
that._fireMarkerRemovedAction({options: options})
})
})
},
adjustViewport: function() {
return $.Deferred().resolve().promise()
},
addRoutes: function(options) {
var that = this;
return this._updateMap().done(function() {
$.each(options, function(_, options) {
that._fireRouteAddedAction({options: options})
})
})
},
removeRoutes: function(options) {
var that = this;
return this._updateMap().done(function() {
$.each(options, function(_, options) {
that._fireRouteRemovedAction({options: options})
})
})
},
clean: function() {
this._$container.css("background-image", "none");
this._$container.off(this._addEventNamespace("dxclick"));
return $.Deferred().resolve().promise()
},
mapRendered: function() {
return true
},
_updateMap: function() {
var key = this._keyOption("googleStatic"),
$container = this._$container;
var requestOptions = ["sensor=false", "size=" + $container.width() + "x" + $container.height(), "maptype=" + this._option("type"), "center=" + this._locationToString(this._option("center")), "zoom=" + this._option("zoom"), this._markersSubstring()];
requestOptions.push.apply(requestOptions, this._routeSubstrings());
if (key)
requestOptions.push("key=" + key);
var request = GOOGLE_STATIC_URL + requestOptions.join("&");
this._$container.css("background", "url(\"" + request + "\") no-repeat 0 0");
this._attachClickEvent();
return $.Deferred().resolve(true).promise()
},
_markersSubstring: function() {
var that = this,
markers = [],
markerIcon = this._option("markerIconSrc");
if (markerIcon)
markers.push("icon:" + markerIcon);
$.each(this._option("markers"), function(_, marker) {
markers.push(that._locationToString(marker.location))
});
return "markers=" + markers.join("|")
},
_routeSubstrings: function() {
var that = this,
routes = [];
$.each(this._option("routes"), function(_, route) {
var color = new DX.Color(route.color || that._defaultRouteColor()).toHex().replace('#', '0x'),
opacity = Math.round((route.opacity || that._defaultRouteOpacity()) * 255).toString(16),
width = route.weight || that._defaultRouteWeight(),
locations = [];
$.each(route.locations, function(_, routePoint) {
locations.push(that._locationToString(routePoint))
});
routes.push("path=color:" + color + opacity + "|weight:" + width + "|" + locations.join("|"))
});
return routes
},
_attachClickEvent: function() {
var that = this,
eventName = this._addEventNamespace("dxclick");
this._$container.off(eventName).on(eventName, function(e) {
that._fireClickAction({jQueryEvent: e})
})
}
}));
ui.dxMap.__internals = $.extend(ui.dxMap.__internals, {remapGoogleStaticConstant: function(newValue) {
GOOGLE_STATIC_URL = newValue
}})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.map.provider.dynamic.js */
(function($, DX, undefined) {
var ui = DX.ui;
ui.dxMap.DynamicProvider = ui.dxMap.Provider.inherit({
cancelEvents: true,
_renderImpl: function(markerOptions, routeOptions) {
var deferred = $.Deferred();
this._load().done($.proxy(function() {
this._init().done($.proxy(function() {
var mapTypePromise = this.updateMapType(),
boundsPromise = this._isBoundsSetted() ? this.updateBounds() : this.updateCenter();
$.when(mapTypePromise, boundsPromise).done($.proxy(function() {
this._attachHandlers();
setTimeout(function() {
deferred.resolve()
})
}, this))
}, this))
}, this));
return deferred.promise()
},
_load: function() {
if (!this._mapsLoader) {
this._mapsLoader = $.Deferred();
this._loadImpl().done($.proxy(function() {
this._mapsLoader.resolve()
}, this))
}
this._markers = [];
this._routes = [];
return this._mapsLoader.promise()
},
_loadImpl: DX.abstract,
_init: DX.abstract,
_attachHandlers: DX.abstract,
addMarkers: function(options) {
var deferred = $.Deferred(),
that = this;
var markerPromises = $.map(options, function(options) {
return that._addMarker(options)
});
$.when.apply($, markerPromises).done(function() {
var instances = $.map($.makeArray(arguments), function(markerObject) {
return markerObject.marker
});
deferred.resolve(false, instances)
});
return deferred.promise()
},
_addMarker: function(options) {
var that = this;
return this._renderMarker(options).done(function(markerObject) {
that._markers.push($.extend({options: options}, markerObject));
that._fitBounds();
that._fireMarkerAddedAction({
options: options,
originalMarker: markerObject.marker
})
})
},
_renderMarker: DX.abstract,
removeMarkers: function(markersOptionsToRemove) {
var that = this;
$.each(markersOptionsToRemove, function(_, markerOptionToRemove) {
that._removeMarker(markerOptionToRemove)
});
return $.Deferred().resolve().promise()
},
_removeMarker: function(markersOptionToRemove) {
var that = this;
$.each(this._markers, function(markerIndex, markerObject) {
if (markerObject.options !== markersOptionToRemove)
return true;
that._destroyMarker(markerObject);
that._markers.splice(markerIndex, 1);
that._fireMarkerRemovedAction({options: markerObject.options});
return false
})
},
_destroyMarker: DX.abstract,
_clearMarkers: function() {
while (this._markers.length > 0)
this._removeMarker(this._markers[0].options)
},
addRoutes: function(options) {
var deferred = $.Deferred(),
that = this;
var routePromises = $.map(options, function(options) {
return that._addRoute(options)
});
$.when.apply($, routePromises).done(function() {
var instances = $.map($.makeArray(arguments), function(routeObject) {
return routeObject.instance
});
deferred.resolve(false, instances)
});
return deferred.promise()
},
_addRoute: function(options) {
var that = this;
return this._renderRoute(options).done(function(routeObject) {
that._routes.push($.extend({options: options}, routeObject));
that._fitBounds();
that._fireRouteAddedAction({
options: options,
originalRoute: routeObject.instance
})
})
},
_renderRoute: DX.abstract,
removeRoutes: function(options) {
var that = this;
$.each(options, function(routeIndex, options) {
that._removeRoute(options)
});
return $.Deferred().resolve().promise()
},
_removeRoute: function(options) {
var that = this;
$.each(this._routes, function(routeIndex, routeObject) {
if (routeObject.options !== options)
return true;
that._destroyRoute(routeObject);
that._routes.splice(routeIndex, 1);
that._fireRouteRemovedAction({options: options});
return false
})
},
_destroyRoute: DX.abstract,
_clearRoutes: function() {
while (this._routes.length > 0)
this._removeRoute(this._routes[0].options)
},
adjustViewport: function() {
return this._fitBounds()
},
_fitBounds: DX.abstract,
_updateBounds: function() {
var that = this;
this._clearBounds();
$.each(this._markers, function(_, markerObject) {
that._extendBounds(markerObject.location)
});
$.each(this._routes, function(_, routeObject) {
that._extendBounds(routeObject.northEast);
that._extendBounds(routeObject.southWest)
})
},
_clearBounds: function() {
this._bounds = null
},
_extendBounds: DX.abstract
})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.map.provider.dynamic.bing.js */
(function($, DX, undefined) {
var ui = DX.ui,
winJS = DX.support.winJS;
var BING_MAP_READY = "_bingScriptReady",
BING_URL = "https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1&onScriptLoad=" + BING_MAP_READY,
BING_LOCAL_FILES1 = "ms-appx:///Bing.Maps.JavaScript/js/veapicore.js",
BING_LOCAL_FILES2 = "ms-appx:///Bing.Maps.JavaScript/js/veapiModules.js",
BING_CREDENTIALS = "AhuxC0dQ1DBTNo8L-H9ToVMQStmizZzBJdraTSgCzDSWPsA1Qd8uIvFSflzxdaLH",
MIN_LOCATION_RECT_LENGTH = 0.0000000000000001;
var msMapsLoaded = function() {
return window.Microsoft && window.Microsoft.Maps
};
var msMapsLoader;
ui.dxMap.registerProvider("bing", ui.dxMap.DynamicProvider.inherit({
_mapType: function(type) {
var mapTypes = {
roadmap: Microsoft.Maps.MapTypeId.road,
hybrid: Microsoft.Maps.MapTypeId.aerial,
satellite: Microsoft.Maps.MapTypeId.aerial
};
return mapTypes[type] || mapTypes.road
},
_movementMode: function(type) {
var movementTypes = {
driving: Microsoft.Maps.Directions.RouteMode.driving,
walking: Microsoft.Maps.Directions.RouteMode.walking
};
return movementTypes[type] || movementTypes.driving
},
_resolveLocation: function(location) {
var d = $.Deferred();
var latLng = this._getLatLng(location);
if (latLng)
d.resolve(new Microsoft.Maps.Location(latLng.lat, latLng.lng));
else {
var searchManager = new Microsoft.Maps.Search.SearchManager(this._map);
var searchRequest = {
where: location,
count: 1,
callback: function(searchResponse) {
var boundsBox = searchResponse.results[0].location;
d.resolve(new Microsoft.Maps.Location(boundsBox.latitude, boundsBox.longitude))
}
};
searchManager.geocode(searchRequest)
}
return d.promise()
},
_normalizeLocation: function(location) {
return {
lat: location.latitude,
lng: location.longitude
}
},
_normalizeLocationRect: function(locationRect) {
var northWest = this._normalizeLocation(locationRect.getNorthwest()),
southEast = this._normalizeLocation(locationRect.getSoutheast());
return {
northEast: {
lat: northWest.lat,
lng: southEast.lng
},
southWest: {
lat: southEast.lat,
lng: northWest.lng
}
}
},
_loadImpl: function() {
this._msMapsLoader = $.Deferred();
if (msMapsLoaded())
this._mapReady();
else {
if (!msMapsLoader || msMapsLoader.state() === "resolved" && !msMapsLoaded()) {
msMapsLoader = $.Deferred();
window[BING_MAP_READY] = $.proxy(msMapsLoader.resolve, msMapsLoader);
if (winJS)
$.when($.getScript(BING_LOCAL_FILES1), $.getScript(BING_LOCAL_FILES2)).done(function() {
Microsoft.Maps.loadModule("Microsoft.Maps.Map", {callback: window[BING_MAP_READY]})
});
else
$.getScript(BING_URL)
}
msMapsLoader.done($.proxy(this._mapReady, this))
}
return this._msMapsLoader.promise()
},
_mapReady: function() {
try {
delete window[BING_MAP_READY]
}
catch(e) {
window[BING_MAP_READY] = undefined
}
var searchModulePromise = $.Deferred();
var directionsModulePromise = $.Deferred();
Microsoft.Maps.loadModule('Microsoft.Maps.Search', {callback: $.proxy(searchModulePromise.resolve, searchModulePromise)});
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', {callback: $.proxy(directionsModulePromise.resolve, directionsModulePromise)});
$.when(searchModulePromise, directionsModulePromise).done($.proxy(function() {
this._msMapsLoader.resolve()
}, this))
},
_init: function() {
var deferred = $.Deferred(),
initPromise = $.Deferred(),
controls = this._option("controls");
this._map = new Microsoft.Maps.Map(this._$container[0], {
credentials: this._keyOption("bing") || BING_CREDENTIALS,
zoom: this._option("zoom"),
showDashboard: controls,
showMapTypeSelector: controls,
showScalebar: controls
});
var handler = Microsoft.Maps.Events.addHandler(this._map, 'tiledownloadcomplete', $.proxy(initPromise.resolve, initPromise));
$.when(initPromise).done($.proxy(function() {
Microsoft.Maps.Events.removeHandler(handler);
deferred.resolve()
}, this));
return deferred.promise()
},
_attachHandlers: function() {
this._providerViewChangeHandler = Microsoft.Maps.Events.addHandler(this._map, 'viewchange', $.proxy(this._viewChangeHandler, this));
this._providerClickHandler = Microsoft.Maps.Events.addHandler(this._map, 'click', $.proxy(this._clickActionHandler, this))
},
_viewChangeHandler: function() {
var bounds = this._map.getBounds();
this._option("bounds", this._normalizeLocationRect(bounds));
var center = this._map.getCenter();
this._option("center", this._normalizeLocation(center));
if (!this._preventZoomChangeEvent)
this._option("zoom", this._map.getZoom())
},
_clickActionHandler: function(e) {
if (e.targetType === "map") {
var point = new Microsoft.Maps.Point(e.getX(), e.getY()),
location = e.target.tryPixelToLocation(point);
this._fireClickAction({location: this._normalizeLocation(location)})
}
},
updateDimensions: function() {
var $container = this._$container;
this._map.setOptions({
width: $container.width(),
height: $container.height()
});
return $.Deferred().resolve().promise()
},
updateMapType: function() {
var type = this._option("type"),
labelOverlay = Microsoft.Maps.LabelOverlay;
this._map.setView({
animate: false,
mapTypeId: this._mapType(type),
labelOverlay: type === "satellite" ? labelOverlay.hidden : labelOverlay.visible
});
return $.Deferred().resolve().promise()
},
updateBounds: function() {
var deferred = $.Deferred(),
that = this;
var northEastPromise = this._resolveLocation(this._option("bounds.northEast")),
southWestPromise = this._resolveLocation(this._option("bounds.southWest"));
$.when(northEastPromise, southWestPromise).done(function(northEast, southWest) {
var bounds = new Microsoft.Maps.LocationRect.fromLocations(northEast, southWest);
that._map.setView({
animate: false,
bounds: bounds
});
deferred.resolve()
});
return deferred.promise()
},
updateCenter: function() {
var deferred = $.Deferred(),
that = this;
this._resolveLocation(this._option("center")).done(function(location) {
that._map.setView({
animate: false,
center: location
});
deferred.resolve()
});
return deferred.promise()
},
updateZoom: function() {
this._map.setView({
animate: false,
zoom: this._option("zoom")
});
return $.Deferred().resolve().promise()
},
updateControls: function() {
this.clean();
return this.render.apply(this, arguments)
},
_renderMarker: function(options) {
var d = $.Deferred(),
that = this;
this._resolveLocation(options.location).done(function(location) {
var pushpinOptions = {icon: options.iconSrc || that._option("markerIconSrc")};
if (options.html) {
$.extend(pushpinOptions, {
htmlContent: options.html,
width: null,
height: null
});
var htmlOffset = options.htmlOffset;
if (htmlOffset)
pushpinOptions.anchor = new Microsoft.Maps.Point(-htmlOffset.left, -htmlOffset.top)
}
var pushpin = new Microsoft.Maps.Pushpin(location, pushpinOptions);
that._map.entities.push(pushpin);
var infobox = that._renderTooltip(location, options.tooltip);
if (options.clickAction) {
DX.log("W0001", "dxMap", "marker.clickAction", "14.2", "Use 'onClick' option instead");
options.onClick = options.clickAction
}
var handler;
if (options.onClick || options.tooltip) {
var markerClickAction = that._createAction(options.onClick || $.noop),
markerNormalizedLocation = that._normalizeLocation(location);
handler = Microsoft.Maps.Events.addHandler(pushpin, "click", function() {
markerClickAction({location: markerNormalizedLocation});
if (infobox)
infobox.setOptions({visible: true})
})
}
d.resolve({
location: location,
marker: pushpin,
infobox: infobox,
handler: handler
})
});
return d.promise()
},
_renderTooltip: function(location, options) {
if (!options)
return;
options = this._parseTooltipOptions(options);
var infobox = new Microsoft.Maps.Infobox(location, {
description: options.text,
offset: new Microsoft.Maps.Point(0, 33),
visible: options.visible
});
this._map.entities.push(infobox, null);
return infobox
},
_destroyMarker: function(marker) {
this._map.entities.remove(marker.marker);
if (marker.infobox)
this._map.entities.remove(marker.infobox);
if (marker.handler)
Microsoft.Maps.Events.removeHandler(marker.handler)
},
_renderRoute: function(options) {
var d = $.Deferred(),
that = this;
var points = $.map(options.locations, function(point) {
return that._resolveLocation(point)
});
$.when.apply($, points).done(function() {
var locations = $.makeArray(arguments),
direction = new Microsoft.Maps.Directions.DirectionsManager(that._map),
color = new DX.Color(options.color || that._defaultRouteColor()).toHex(),
routeColor = new Microsoft.Maps.Color.fromHex(color);
routeColor.a = (options.opacity || that._defaultRouteOpacity()) * 255;
direction.setRenderOptions({
autoUpdateMapView: false,
displayRouteSelector: false,
waypointPushpinOptions: {visible: false},
drivingPolylineOptions: {
strokeColor: routeColor,
strokeThickness: options.weight || that._defaultRouteWeight()
},
walkingPolylineOptions: {
strokeColor: routeColor,
strokeThickness: options.weight || that._defaultRouteWeight()
}
});
direction.setRequestOptions({
routeMode: that._movementMode(options.mode),
routeDraggable: false
});
$.each(locations, function(_, location) {
var waypoint = new Microsoft.Maps.Directions.Waypoint({location: location});
direction.addWaypoint(waypoint)
});
var handler = Microsoft.Maps.Events.addHandler(direction, 'directionsUpdated', function(args) {
Microsoft.Maps.Events.removeHandler(handler);
var routeSummary = args.routeSummary[0];
d.resolve({
instance: direction,
northEast: routeSummary.northEast,
southWest: routeSummary.southWest
})
});
direction.calculateDirections()
});
return d.promise()
},
_destroyRoute: function(routeObject) {
routeObject.instance.dispose()
},
_fitBounds: function() {
this._updateBounds();
if (this._bounds && this._option("autoAdjust")) {
var zoomBeforeFitting = this._map.getZoom();
this._preventZoomChangeEvent = true;
var bounds = this._bounds.clone();
bounds.height = bounds.height * 1.1;
bounds.width = bounds.width * 1.1;
this._map.setView({
animate: false,
bounds: bounds,
zoom: zoomBeforeFitting
});
var zoomAfterFitting = this._map.getZoom();
if (zoomBeforeFitting < zoomAfterFitting)
this._map.setView({
animate: false,
zoom: zoomBeforeFitting
});
else
this._option("zoom", zoomAfterFitting);
delete this._preventZoomChangeEvent
}
return $.Deferred().resolve().promise()
},
_extendBounds: function(location) {
if (this._bounds)
this._bounds = new Microsoft.Maps.LocationRect.fromLocations(this._bounds.getNorthwest(), this._bounds.getSoutheast(), location);
else
this._bounds = new Microsoft.Maps.LocationRect(location, MIN_LOCATION_RECT_LENGTH, MIN_LOCATION_RECT_LENGTH)
},
clean: function() {
if (this._map) {
Microsoft.Maps.Events.removeHandler(this._providerViewChangeHandler);
Microsoft.Maps.Events.removeHandler(this._providerClickHandler);
this._clearMarkers();
this._clearRoutes();
this._map.dispose()
}
return $.Deferred().resolve().promise()
}
}));
ui.dxMap.__internals = $.extend(ui.dxMap.__internals, {remapBingConstant: function(newValue) {
BING_URL = newValue
}})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.map.provider.dynamic.google.js */
(function($, DX, undefined) {
var ui = DX.ui;
var GOOGLE_MAP_READY = "_googleScriptReady",
GOOGLE_URL = "https://maps.google.com/maps/api/js?v=3.18&sensor=false&callback=" + GOOGLE_MAP_READY;
var CustomMarker;
var initCustomMarkerClass = function() {
CustomMarker = function(options) {
this._position = options.position;
this._offset = options.offset;
this._$overlayContainer = $("
").css({
position: "absolute",
display: "none",
cursor: "pointer"
}).append(options.html);
this.setMap(options.map)
};
CustomMarker.prototype = new google.maps.OverlayView;
CustomMarker.prototype.onAdd = function() {
var $pane = $(this.getPanes().overlayMouseTarget);
$pane.append(this._$overlayContainer);
this._clickListner = google.maps.event.addDomListener(this._$overlayContainer.get(0), 'click', $.proxy(function(e) {
google.maps.event.trigger(this, 'click');
e.preventDefault()
}, this));
this.draw()
};
CustomMarker.prototype.onRemove = function() {
google.maps.event.removeListener(this._clickListner);
this._$overlayContainer.remove()
};
CustomMarker.prototype.draw = function() {
var position = this.getProjection().fromLatLngToDivPixel(this._position);
this._$overlayContainer.css({
left: position.x + this._offset.left,
top: position.y + this._offset.top,
display: 'block'
})
}
};
var googleMapsLoaded = function() {
return window.google && window.google.maps
};
var googleMapsLoader;
ui.dxMap.registerProvider("google", ui.dxMap.DynamicProvider.inherit({
_mapType: function(type) {
var mapTypes = {
hybrid: google.maps.MapTypeId.HYBRID,
roadmap: google.maps.MapTypeId.ROADMAP,
satellite: google.maps.MapTypeId.SATELLITE
};
return mapTypes[type] || mapTypes.hybrid
},
_movementMode: function(type) {
var movementTypes = {
driving: google.maps.TravelMode.DRIVING,
walking: google.maps.TravelMode.WALKING
};
return movementTypes[type] || movementTypes.driving
},
_resolveLocation: function(location) {
var d = $.Deferred();
var latLng = this._getLatLng(location);
if (latLng)
d.resolve(new google.maps.LatLng(latLng.lat, latLng.lng));
else {
var geocoder = new google.maps.Geocoder;
geocoder.geocode({address: location}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK)
d.resolve(results[0].geometry.location)
})
}
return d.promise()
},
_normalizeLocation: function(location) {
return {
lat: location.lat(),
lng: location.lng()
}
},
_normalizeLocationRect: function(locationRect) {
return {
northEast: this._normalizeLocation(locationRect.getNorthEast()),
southWest: this._normalizeLocation(locationRect.getSouthWest())
}
},
_loadImpl: function() {
this._googleMapsLoader = $.Deferred();
if (googleMapsLoaded())
this._mapReady();
else {
if (!googleMapsLoader || googleMapsLoader.state() === "resolved" && !googleMapsLoaded()) {
googleMapsLoader = $.Deferred();
var key = this._keyOption("google");
window[GOOGLE_MAP_READY] = $.proxy(googleMapsLoader.resolve, googleMapsLoader);
$.getScript(GOOGLE_URL + (key ? "&key=" + key : ""))
}
googleMapsLoader.done($.proxy(this._mapReady, this))
}
return this._googleMapsLoader.promise()
},
_mapReady: function() {
try {
delete window[GOOGLE_MAP_READY]
}
catch(e) {
window[GOOGLE_MAP_READY] = undefined
}
initCustomMarkerClass();
this._googleMapsLoader.resolve()
},
_init: function() {
var deferred = $.Deferred(),
initPromise = $.Deferred(),
controls = this._option("controls");
this._map = new google.maps.Map(this._$container[0], {
zoom: this._option("zoom"),
panControl: controls,
zoomControl: controls,
mapTypeControl: controls,
streetViewControl: controls
});
var listner = google.maps.event.addListener(this._map, 'idle', $.proxy(initPromise.resolve, initPromise));
$.when(initPromise).done($.proxy(function() {
google.maps.event.removeListener(listner);
deferred.resolve()
}, this));
return deferred.promise()
},
_attachHandlers: function() {
this._boundsChangeListener = google.maps.event.addListener(this._map, 'bounds_changed', $.proxy(this._boundsChangeHandler, this));
this._clickListener = google.maps.event.addListener(this._map, 'click', $.proxy(this._clickActionHandler, this))
},
_boundsChangeHandler: function() {
var bounds = this._map.getBounds();
this._option("bounds", this._normalizeLocationRect(bounds));
var center = this._map.getCenter();
this._option("center", this._normalizeLocation(center));
if (!this._preventZoomChangeEvent)
this._option("zoom", this._map.getZoom())
},
_clickActionHandler: function(e) {
this._fireClickAction({location: this._normalizeLocation(e.latLng)})
},
updateDimensions: function() {
var center = this._option("center");
google.maps.event.trigger(this._map, 'resize');
this._option("center", center);
return this.updateCenter()
},
updateMapType: function() {
this._map.setMapTypeId(this._mapType(this._option("type")));
return $.Deferred().resolve().promise()
},
updateBounds: function() {
var deferred = $.Deferred(),
that = this;
var northEastPromise = this._resolveLocation(this._option("bounds.northEast")),
southWestPromise = this._resolveLocation(this._option("bounds.southWest"));
$.when(northEastPromise, southWestPromise).done(function(northEast, southWest) {
var bounds = new google.maps.LatLngBounds;
bounds.extend(northEast);
bounds.extend(southWest);
that._map.fitBounds(bounds);
deferred.resolve()
});
return deferred.promise()
},
updateCenter: function() {
var deferred = $.Deferred(),
that = this;
this._resolveLocation(this._option("center")).done(function(center) {
that._map.setCenter(center);
that._option("center", that._normalizeLocation(center));
deferred.resolve()
});
return deferred.promise()
},
updateZoom: function() {
this._map.setZoom(this._option("zoom"));
return $.Deferred().resolve().promise()
},
updateControls: function() {
var controls = this._option("controls");
this._map.setOptions({
panControl: controls,
zoomControl: controls,
mapTypeControl: controls,
streetViewControl: controls
});
return $.Deferred().resolve().promise()
},
_renderMarker: function(options) {
var d = $.Deferred(),
that = this;
this._resolveLocation(options.location).done(function(location) {
var marker;
if (options.html)
marker = new CustomMarker({
map: that._map,
position: location,
html: options.html,
offset: $.extend({
top: 0,
left: 0
}, options.htmlOffset)
});
else
marker = new google.maps.Marker({
position: location,
map: that._map,
icon: options.iconSrc || that._option("markerIconSrc")
});
var infoWindow = that._renderTooltip(marker, options.tooltip);
if (options.clickAction) {
DX.log("W0001", "dxMap", "marker.clickAction", "14.2", "Use 'onClick' option instead");
options.onClick = options.clickAction
}
var listner;
if (options.onClick || options.tooltip) {
var markerClickAction = that._createAction(options.onClick || $.noop),
markerNormalizedLocation = that._normalizeLocation(location);
listner = google.maps.event.addListener(marker, "click", function() {
markerClickAction({location: markerNormalizedLocation});
if (infoWindow)
infoWindow.open(that._map, marker)
})
}
d.resolve({
location: location,
marker: marker,
listner: listner
})
});
return d.promise()
},
_renderTooltip: function(marker, options) {
if (!options)
return;
options = this._parseTooltipOptions(options);
var infoWindow = new google.maps.InfoWindow({content: options.text});
if (options.visible)
infoWindow.open(this._map, marker);
return infoWindow
},
_destroyMarker: function(marker) {
marker.marker.setMap(null);
if (marker.listner)
google.maps.event.removeListener(marker.listner)
},
_renderRoute: function(options) {
var d = $.Deferred(),
that = this,
directionsService = new google.maps.DirectionsService;
var points = $.map(options.locations, function(point) {
return that._resolveLocation(point)
});
$.when.apply($, points).done(function() {
var locations = $.makeArray(arguments),
origin = locations.shift(),
destination = locations.pop(),
waypoints = $.map(locations, function(location) {
return {
location: location,
stopover: true
}
});
var request = {
origin: origin,
destination: destination,
waypoints: waypoints,
optimizeWaypoints: true,
travelMode: that._movementMode(options.mode)
};
directionsService.route(request, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
var color = new DX.Color(options.color || that._defaultRouteColor()).toHex(),
directionOptions = {
directions: response,
map: that._map,
suppressMarkers: true,
preserveViewport: true,
polylineOptions: {
strokeWeight: options.weight || that._defaultRouteWeight(),
strokeOpacity: options.opacity || that._defaultRouteOpacity(),
strokeColor: color
}
};
var route = new google.maps.DirectionsRenderer(directionOptions),
bounds = response.routes[0].bounds;
d.resolve({
instance: route,
northEast: bounds.getNorthEast(),
southWest: bounds.getSouthWest()
})
}
})
});
return d.promise()
},
_destroyRoute: function(routeObject) {
routeObject.instance.setMap(null)
},
_fitBounds: function() {
this._updateBounds();
if (this._bounds && this._option("autoAdjust")) {
var zoomBeforeFitting = this._map.getZoom();
this._preventZoomChangeEvent = true;
this._map.fitBounds(this._bounds);
var zoomAfterFitting = this._map.getZoom();
if (zoomBeforeFitting < zoomAfterFitting)
this._map.setZoom(zoomBeforeFitting);
else
this._option("zoom", zoomAfterFitting);
delete this._preventZoomChangeEvent
}
return $.Deferred().resolve().promise()
},
_extendBounds: function(location) {
if (this._bounds)
this._bounds.extend(location);
else {
this._bounds = new google.maps.LatLngBounds;
this._bounds.extend(location)
}
},
clean: function() {
if (this._map) {
google.maps.event.removeListener(this._boundsChangeListener);
google.maps.event.removeListener(this._clickListener);
this._clearMarkers();
this._clearRoutes();
delete this._map;
this._$container.empty()
}
return $.Deferred().resolve().promise()
}
}));
ui.dxMap.__internals = $.extend(ui.dxMap.__internals, {remapGoogleConstant: function(newValue) {
GOOGLE_URL = newValue
}})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.swipeable.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
DX_SWIPEABLE = "dxSwipeable",
SWIPEABLE_CLASS = "dx-swipeable",
ACTION_TO_EVENT_MAP = {
onStart: "dxswipestart",
onUpdated: "dxswipe",
onEnd: "dxswipeend",
onCancel: "dxswipecancel"
};
DX.registerComponent(DX_SWIPEABLE, ui, DX.DOMComponent.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
elastic: true,
immediate: false,
direction: "horizontal",
itemSizeFunc: null,
onStart: null,
onUpdated: null,
onEnd: null,
onCancel: null
})
},
_render: function() {
this.callBase();
this.element().addClass(SWIPEABLE_CLASS);
this._attachEventHandlers()
},
_attachEventHandlers: function() {
this._detachEventHanlers();
if (this.option("disabled"))
return;
var NAME = this.NAME;
this._createEventData();
$.each(ACTION_TO_EVENT_MAP, $.proxy(function(actionName, eventName) {
var action = this._createActionByOption(actionName, {context: this});
eventName = events.addNamespace(eventName, NAME);
this.element().on(eventName, this._eventData, function(e) {
return action({jQueryEvent: e})
})
}, this))
},
_createEventData: function() {
this._eventData = {
elastic: this.option("elastic"),
itemSizeFunc: this.option("itemSizeFunc"),
direction: this.option("direction"),
immediate: this.option("immediate")
}
},
_detachEventHanlers: function() {
this.element().off("." + DX_SWIPEABLE)
},
_optionChanged: function(args) {
switch (args.name) {
case"disabled":
case"onStart":
case"onUpdated":
case"onEnd":
case"onCancel":
case"elastic":
case"immediate":
case"itemSizeFunc":
case"direction":
this._detachEventHanlers();
this._attachEventHandlers();
break;
case"rtlEnabled":
break;
default:
this.callBase(args)
}
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.draggable.js */
(function($, DX, undefined) {
var ui = DX.ui,
translator = DX.translator,
inflector = DX.inflector,
events = ui.events,
DRAGGABLE = "dxDraggable",
DRAGSTART_EVENT_NAME = events.addNamespace("dxdragstart", DRAGGABLE),
DRAG_EVENT_NAME = events.addNamespace("dxdrag", DRAGGABLE),
DRAGEND_EVENT_NAME = events.addNamespace("dxdragend", DRAGGABLE),
POINTERDOWN_EVENT_NAME = events.addNamespace("dxpointerdown", DRAGGABLE),
DRAGGABLE_CLASS = inflector.dasherize(DRAGGABLE),
DRAGGABLE_DRAGGING_CLASS = DRAGGABLE_CLASS + "-dragging";
DX.registerComponent(DRAGGABLE, ui, DX.DOMComponent.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
onDragStart: $.noop,
onDrag: $.noop,
onDragEnd: $.noop,
direction: "both",
area: window,
boundOffset: 0,
allowMoveByClick: false
})
},
_init: function() {
this.callBase();
this._attachEventHandlers()
},
_attachEventHandlers: function() {
var $element = this.element().css("position", "absolute"),
eventHandlers = {},
allowMoveByClick = this.option("allowMoveByClick");
eventHandlers[DRAGSTART_EVENT_NAME] = $.proxy(this._dragStartHandler, this);
eventHandlers[DRAG_EVENT_NAME] = $.proxy(this._dragHandler, this);
eventHandlers[DRAGEND_EVENT_NAME] = $.proxy(this._dragEndHandler, this);
if (allowMoveByClick) {
eventHandlers[POINTERDOWN_EVENT_NAME] = $.proxy(this._pointerDownHandler, this);
$element = this._getArea()
}
$element.on(eventHandlers, {
direction: this.option("direction"),
immediate: true
})
},
_detachEventHandlers: function() {
this.element().off("." + DRAGGABLE);
this._getArea().off("." + DRAGGABLE)
},
_move: function(position) {
translator.move(this.element(), position)
},
_pointerDownHandler: function(e) {
var $area = $(e.currentTarget),
areaOffset = $.isWindow($area.get(0)) ? {
left: 0,
top: 0
} : $area.offset(),
direction = this.option("direction"),
position = {};
if (direction === "horizontal" || direction === "both")
position.left = e.pageX - this.element().width() / 2 - areaOffset.left;
if (direction === "vertical" || direction === "both")
position.top = e.pageY - this.element().height() / 2 - areaOffset.top;
this._move(position);
this._getAction("onDrag")({jQueryEvent: e})
},
_dragStartHandler: function(e) {
var $element = this.element(),
$area = this._getArea(),
boundOffset = this._getBoundOffset(),
areaWidth = $area.outerWidth(),
areaHeight = $area.outerHeight(),
elementWidth = $element.width(),
elementHeight = $element.height();
this._toggleDraggingClass(true);
this._startPosition = translator.locate($element);
e.maxLeftOffset = this._startPosition.left - boundOffset.h;
e.maxRightOffset = areaWidth - this._startPosition.left - elementWidth - boundOffset.h;
e.maxTopOffset = this._startPosition.top - boundOffset.v;
e.maxBottomOffset = areaHeight - this._startPosition.top - elementHeight - boundOffset.v;
this._getAction("onDragStart")({jQueryEvent: e})
},
_toggleDraggingClass: function(value) {
this.element().toggleClass(DRAGGABLE_DRAGGING_CLASS, value)
},
_getBoundOffset: function() {
var boundOffset = this.option("boundOffset");
if ($.isFunction(boundOffset))
boundOffset = boundOffset.call(this);
return DX.utils.stringPairToObject(boundOffset)
},
_getArea: function() {
var area = this.option("area");
if ($.isFunction(area))
area = area.call(this);
return $(area)
},
_dragHandler: function(e) {
var offset = e.offset,
startPosition = this._startPosition;
this._move({
left: startPosition.left + offset.x,
top: startPosition.top + offset.y
});
this._getAction("onDrag")({jQueryEvent: e})
},
_dragEndHandler: function(e) {
this._toggleDraggingClass(false);
this._getAction("onDragEnd")({jQueryEvent: e})
},
_getAction: function(name) {
return this["_" + name + "Action"] || this._createActionByOption(name)
},
_render: function() {
this.callBase();
this.element().addClass(DRAGGABLE_CLASS)
},
_optionChanged: function(args) {
var name = args.name;
switch (name) {
case"onDragStart":
case"onDrag":
case"onDragEnd":
this["_" + name + "Action"] = this._createActionByOption(name);
break;
case"allowMoveByClick":
case"direction":
this._detachEventHandlers();
this._attachEventHandlers();
break;
case"boundOffset":
case"area":
break;
default:
this.callBase(args)
}
},
_dispose: function() {
this.callBase();
this._detachEventHandlers()
}
}));
ui.dxDraggable.__internals = {DRAGGABLE_CLASS: DRAGGABLE_CLASS}
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.resizable.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
RESIZABLE = "dxResizable",
RESIZABLE_CLASS = "dx-resizable",
RESIZABLE_RESIZING_CLASS = "dx-resizable-resizing",
RESIZABLE_HANDLE_CLASS = "dx-resizable-handle",
RESIZABLE_HANDLE_TOP_CLASS = "dx-resizable-handle-top",
RESIZABLE_HANDLE_BOTTOM_CLASS = "dx-resizable-handle-bottom",
RESIZABLE_HANDLE_LEFT_CLASS = "dx-resizable-handle-left",
RESIZABLE_HANDLE_RIGHT_CLASS = "dx-resizable-handle-right",
RESIZABLE_HANDLE_CORNER_CLASS = "dx-resizable-handle-corner",
DRAGSTART_START_EVENT_NAME = events.addNamespace("dxdragstart", RESIZABLE),
DRAGSTART_EVENT_NAME = events.addNamespace("dxdrag", RESIZABLE),
DRAGSTART_END_EVENT_NAME = events.addNamespace("dxdragend", RESIZABLE);
DX.registerComponent(RESIZABLE, ui, DX.DOMComponent.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
handles: "all",
step: "1",
area: undefined,
minWidth: 30,
maxWidth: Infinity,
minHeight: 30,
maxHeight: Infinity,
onResizeStart: null,
onResize: null,
onResizeEnd: null
})
},
_init: function() {
this.callBase();
this.element().addClass(RESIZABLE_CLASS)
},
_render: function() {
this.callBase();
this._renderActions();
this._renderHandles()
},
_renderActions: function() {
this._resizeStartAction = this._createActionByOption("onResizeStart");
this._resizeEndAction = this._createActionByOption("onResizeEnd");
this._resizeAction = this._createActionByOption("onResize")
},
_renderHandles: function() {
var handles = this.option("handles");
if (handles === "none")
return;
var directions = handles === "all" ? ['top', 'bottom', 'left', 'right'] : handles.split(" ");
$.each(directions, $.proxy(function(index, handleName) {
this._renderHandle(handleName)
}, this));
$.inArray('bottom', directions) + 1 && $.inArray('right', directions) + 1 && this._renderHandle("corner-bottom-right");
$.inArray('bottom', directions) + 1 && $.inArray('left', directions) + 1 && this._renderHandle("corner-bottom-left");
$.inArray('top', directions) + 1 && $.inArray('right', directions) + 1 && this._renderHandle("corner-top-right");
$.inArray('top', directions) + 1 && $.inArray('left', directions) + 1 && this._renderHandle("corner-top-left")
},
_renderHandle: function(handleName) {
var $element = this.element(),
$handle = $("
");
$handle.addClass(RESIZABLE_HANDLE_CLASS).addClass(RESIZABLE_HANDLE_CLASS + "-" + handleName).appendTo($element);
var handlers = {};
handlers[DRAGSTART_START_EVENT_NAME] = $.proxy(this._dragStartHandler, this);
handlers[DRAGSTART_EVENT_NAME] = $.proxy(this._dragHandler, this);
handlers[DRAGSTART_END_EVENT_NAME] = $.proxy(this._dragEndHandler, this);
$handle.on(handlers, {
direction: this._dragEventDirection(handleName),
immediate: true
})
},
_dragEventDirection: function(handleName) {
switch (handleName) {
case"right":
case"left":
return "horizontal";
case"top":
case"bottom":
return "vertical";
default:
return "both"
}
},
_dragStartHandler: function(e) {
this._toggleResizingClass(true);
this._movingSides = this._getMovingSides(e);
var $element = this.element();
this._elementLocation = DX.translator.locate($element);
this._elementSize = {
width: $element.outerWidth(),
height: $element.outerHeight()
};
this._renderDragOffsets(e);
this._resizeStartAction({
jQueryEvent: e,
width: this._elementSize.width,
height: this._elementSize.height,
handles: this._movingSides
});
e.targetElements = null
},
_toggleResizingClass: function(value) {
this.element().toggleClass(RESIZABLE_RESIZING_CLASS, value)
},
_renderDragOffsets: function(e) {
var $area = this._getArea(),
$handle = $(e.target).closest("." + RESIZABLE_HANDLE_CLASS);
if (!$area.length)
return;
var areaWidth = $area.innerWidth(),
areaHeight = $area.innerHeight(),
handleWidth = $handle.outerWidth(),
handleHeight = $handle.outerHeight();
var handleOffset = $handle.offset(),
areaOffset = $area.offset() || {
top: 0,
left: 0
};
areaOffset.left += this._getBorderWidth($area, "left") + this._getBorderWidth(this.element(), "left");
areaOffset.top += this._getBorderWidth($area, "top") + this._getBorderWidth(this.element(), "top");
areaWidth -= this.element().outerWidth() - this.element().innerWidth();
areaHeight -= this.element().outerHeight() - this.element().innerHeight();
e.maxLeftOffset = handleOffset.left - areaOffset.left;
e.maxRightOffset = areaOffset.left + areaWidth - handleOffset.left - handleWidth;
e.maxTopOffset = handleOffset.top - areaOffset.top;
e.maxBottomOffset = areaOffset.top + areaHeight - handleOffset.top - handleHeight
},
_getBorderWidth: function($element, direction) {
var borderWidth = $element.css("border-" + direction + "-width");
return parseInt(borderWidth) || 0
},
_dragHandler: function(e) {
var $element = this.element(),
offset = this._getOffset(e),
sides = this._movingSides;
var location = this._elementLocation,
size = this._elementSize;
var width = size.width + offset.x * (sides.left ? -1 : 1),
height = size.height + offset.y * (sides.top ? -1 : 1);
this._renderSize(width, height);
var offsetTop = offset.y - (this.option("height") - height),
offsetLeft = offset.x - (this.option("width") - width);
DX.translator.move($element, {
top: location.top + (sides.top ? offsetTop : 0),
left: location.left + (sides.left ? offsetLeft : 0)
});
this._resizeAction({
jQueryEvent: e,
width: width,
height: height,
handles: this._movingSides
})
},
_getOffset: function(e) {
var offset = e.offset,
steps = DX.utils.stringPairToObject(this.option("step"));
return {
x: offset.x - offset.x % steps.h,
y: offset.y - offset.y % steps.v
}
},
_getMovingSides: function(e) {
var $target = $(e.target);
return {
top: $target.hasClass(RESIZABLE_HANDLE_TOP_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-left") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-right"),
left: $target.hasClass(RESIZABLE_HANDLE_LEFT_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-left") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-left"),
bottom: $target.hasClass(RESIZABLE_HANDLE_BOTTOM_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-left") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-right"),
right: $target.hasClass(RESIZABLE_HANDLE_RIGHT_CLASS) || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-top-right") || $target.hasClass(RESIZABLE_HANDLE_CORNER_CLASS + "-bottom-right")
}
},
_getArea: function() {
var area = this.option("area");
if ($.isFunction(area))
area = area.call(this);
return $(area)
},
_dragEndHandler: function(e) {
var $element = this.element();
this._resizeEndAction({
jQueryEvent: e,
width: $element.outerWidth(),
height: $element.outerHeight(),
handles: this._movingSides
});
this._toggleResizingClass(false)
},
_renderSize: function(width, height) {
this.option("width", utils.fitIntoRange(width, this.option("minWidth"), this.option("maxWidth")));
this.option("height", utils.fitIntoRange(height, this.option("minHeight"), this.option("maxHeight")))
},
_optionChanged: function(args) {
switch (args.name) {
case"handles":
this._invalidate();
break;
case"minWidth":
case"maxWidth":
case"minHeight":
case"maxHeight":
this._renderSize(this.element().outerWidth(), this.element().outerHeight());
break;
case"onResize":
case"onResizeStart":
case"onResizeEnd":
this._renderActions();
break;
case"gridStepHorizontal":
case"gridStepVertical":
case"area":
case"step":
break;
default:
this.callBase(args);
break
}
},
_clean: function() {
this.element().find("." + RESIZABLE_HANDLE_CLASS).remove()
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.box.js */
(function($, DX, undefined) {
var ui = DevExpress.ui,
utils = DX.utils;
var BOX_CLASS = "dx-box",
BOX_SELECTOR = ".dx-box",
BOX_ITEM_CLASS = "dx-box-item",
BOX_ITEM_DATA_KEY = "dxBoxItemData";
var flexGrowProp = DX.support.styleProp("flexGrow");
var flexShrinkProp = DX.support.styleProp("flexShrink");
var flexPropPrefix = DX.support.stylePropPrefix("flexDirection");
var MINSIZE_MAP = {
row: "minWidth",
col: "minHeight"
};
var MAXSIZE_MAP = {
row: "maxWidth",
col: "maxHeight"
};
var SHRINK = 1;
var FLEX_JUSTIFY_CONTENT_MAP = {
start: "flex-start",
end: "flex-end",
center: "center",
"space-between": "space-between",
"space-around": "space-around"
};
var FLEX_ALIGN_ITEMS_MAP = {
start: "flex-start",
end: "flex-end",
center: "center",
stretch: "stretch"
};
var FLEX_DIRECTION_MAP = {
row: "row",
col: "column"
};
var FlexLayoutStrategy = DX.Class.inherit({
ctor: function($element, option) {
this._$element = $element;
this._option = option
},
renderBox: function() {
this._$element.css({
display: DX.support.stylePropPrefix("flexDirection") + "flex",
flexDirection: FLEX_DIRECTION_MAP[this._option("direction")]
})
},
renderAlign: function() {
this._$element.css({justifyContent: this._normalizedAlign()})
},
_normalizedAlign: function() {
var align = this._option("align");
return align in FLEX_JUSTIFY_CONTENT_MAP ? FLEX_JUSTIFY_CONTENT_MAP[align] : align
},
renderCrossAlign: function() {
this._$element.css({alignItems: this._normalizedCrossAlign()})
},
_normalizedCrossAlign: function() {
var crossAlign = this._option("crossAlign");
return crossAlign in FLEX_ALIGN_ITEMS_MAP ? FLEX_ALIGN_ITEMS_MAP[crossAlign] : crossAlign
},
renderItems: function($items) {
var direction = this._option("direction");
$.each($items, function() {
var $item = $(this);
var item = $item.data(BOX_ITEM_DATA_KEY);
$item.css({
display: flexPropPrefix + "flex",
flexBasis: item.baseSize || 0
}).css(MAXSIZE_MAP[direction], item.maxSize || "none").css(MINSIZE_MAP[direction], item.minSize || "0");
var itemStyle = $item.get(0).style;
itemStyle[flexGrowProp] = item.ratio;
itemStyle[flexShrinkProp] = utils.isDefined(item.shrink) ? item.shrink : SHRINK;
$item.children().each(function(_, itemContent) {
$(itemContent).css({
width: "auto",
height: "auto",
display: DX.support.stylePropPrefix("flexDirection") + "flex",
flexDirection: $item.children().css("flexDirection") || "column"
});
itemContent.style[flexGrowProp] = 1
})
})
},
update: $.noop
});
var BOX_EVENTNAMESPACE = "dxBox",
UPDATE_EVENT = "dxupdate." + BOX_EVENTNAMESPACE,
FALLBACK_BOX_ITEM = "dx-box-fallback-item";
var FALLBACK_WRAP_MAP = {
row: "nowrap",
col: "normal"
};
var FALLBACK_MAIN_SIZE_MAP = {
row: "width",
col: "height"
};
var FALLBACK_CROSS_SIZE_MAP = {
row: "height",
col: "width"
};
var FALLBACK_PRE_MARGIN_MAP = {
row: "marginLeft",
col: "marginTop"
};
var FALLBACK_POST_MARGIN_MAP = {
row: "marginRight",
col: "marginBottom"
};
var FALLBACK_CROSS_PRE_MARGIN_MAP = {
row: "marginTop",
col: "marginLeft"
};
var FALLBACK_CROSS_POST_MARGIN_MAP = {
row: "marginBottom",
col: "marginRight"
};
var MARGINS_RTL_FLIP_MAP = {
marginLeft: "marginRight",
marginRight: "marginLeft"
};
var FallbackLayoutStrategy = DX.Class.inherit({
ctor: function($element, option) {
this._$element = $element;
this._option = option
},
renderBox: function() {
this._$element.css({
fontSize: 0,
whiteSpace: FALLBACK_WRAP_MAP[this._option("direction")],
verticalAlign: "top"
});
this._$element.off(UPDATE_EVENT).on(UPDATE_EVENT, $.proxy(this.update, this))
},
renderAlign: function() {
var $items = this._$items;
if (!$items)
return;
var align = this._option("align"),
shift = 0,
totalItemSize = this.totalItemSize,
direction = this._option("direction"),
boxSize = this._$element[FALLBACK_MAIN_SIZE_MAP[direction]](),
freeSpace = boxSize - totalItemSize;
this._setItemsMargins($items, direction, 0);
switch (align) {
case"start":
break;
case"end":
shift = freeSpace;
$items.first().css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), shift);
break;
case"center":
shift = 0.5 * freeSpace;
$items.first().css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), shift);
$items.last().css(this._chooseMarginSide(FALLBACK_POST_MARGIN_MAP[direction]), shift);
break;
case"space-between":
shift = 0.5 * freeSpace / ($items.length - 1);
this._setItemsMargins($items, direction, shift);
$items.first().css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), 0);
$items.last().css(this._chooseMarginSide(FALLBACK_POST_MARGIN_MAP[direction]), 0);
break;
case"space-around":
shift = 0.5 * freeSpace / $items.length;
this._setItemsMargins($items, direction, shift);
break
}
},
_setItemsMargins: function($items, direction, shift) {
$items.css(this._chooseMarginSide(FALLBACK_PRE_MARGIN_MAP[direction]), shift).css(this._chooseMarginSide(FALLBACK_POST_MARGIN_MAP[direction]), shift)
},
renderCrossAlign: function() {
var $items = this._$items;
if (!$items)
return;
var crossAlign = this._option("crossAlign"),
direction = this._option("direction"),
size = this._$element[FALLBACK_CROSS_SIZE_MAP[direction]]();
var that = this;
switch (crossAlign) {
case"start":
break;
case"end":
$.each($items, function() {
var $item = $(this),
itemSize = $item[FALLBACK_CROSS_SIZE_MAP[direction]](),
shift = size - itemSize;
$item.css(that._chooseMarginSide(FALLBACK_CROSS_PRE_MARGIN_MAP[direction]), shift)
});
break;
case"center":
$.each($items, function() {
var $item = $(this),
itemSize = $item[FALLBACK_CROSS_SIZE_MAP[direction]](),
shift = 0.5 * (size - itemSize);
$item.css(that._chooseMarginSide(FALLBACK_CROSS_PRE_MARGIN_MAP[direction]), shift).css(that._chooseMarginSide(FALLBACK_CROSS_POST_MARGIN_MAP[direction]), shift)
});
break;
case"stretch":
$items.css(that._chooseMarginSide(FALLBACK_CROSS_PRE_MARGIN_MAP[direction]), 0).css(that._chooseMarginSide(FALLBACK_CROSS_POST_MARGIN_MAP[direction]), 0).css(FALLBACK_CROSS_SIZE_MAP[direction], "100%");
break
}
},
_chooseMarginSide: function(value) {
if (!this._option("rtlEnabled"))
return value;
return MARGINS_RTL_FLIP_MAP[value] || value
},
renderItems: function($items) {
this._$items = $items;
var direction = this._option("direction"),
totalRatio = 0,
totalWeightedShrink = 0,
totalBaseSize = 0;
$.each($items, $.proxy(function(_, item) {
var $item = $(item);
$item.css({
display: "inline-block",
verticalAlign: "top"
});
$item[FALLBACK_MAIN_SIZE_MAP[direction]]("auto");
$item.removeClass(FALLBACK_BOX_ITEM);
var itemData = $item.data(BOX_ITEM_DATA_KEY),
ratio = itemData.ratio || 0,
size = this._baseSize($item),
shrink = utils.isDefined(itemData.shrink) ? itemData.shrink : SHRINK;
totalRatio += ratio;
totalWeightedShrink += shrink * size;
totalBaseSize += size
}, this));
var freeSpaceSize = this._boxSize() - totalBaseSize;
var itemSize = $.proxy(function($item) {
var itemData = $item.data(BOX_ITEM_DATA_KEY),
size = this._baseSize($item),
factor = freeSpaceSize >= 0 ? itemData.ratio || 0 : (utils.isDefined(itemData.shrink) ? itemData.shrink : SHRINK) * size,
totalFactor = freeSpaceSize >= 0 ? totalRatio : totalWeightedShrink,
shift = totalFactor ? Math.round(freeSpaceSize * factor / totalFactor) : 0;
return size + shift
}, this);
var totalItemSize = 0;
$.each($items, function(_, item) {
var $item = $(item),
itemData = $(item).data(BOX_ITEM_DATA_KEY),
size = itemSize($item);
totalItemSize += size;
$item.css(MAXSIZE_MAP[direction], itemData.maxSize || "none").css(MINSIZE_MAP[direction], itemData.minSize || "0").css(FALLBACK_MAIN_SIZE_MAP[direction], size);
$item.addClass(FALLBACK_BOX_ITEM)
});
this.totalItemSize = totalItemSize
},
_baseSize: function(item) {
var itemData = $(item).data(BOX_ITEM_DATA_KEY);
return itemData.baseSize == null ? 0 : itemData.baseSize === "auto" ? this._contentSize(item) : this._parseSize(itemData.baseSize)
},
_contentSize: function(item) {
return $(item)[FALLBACK_MAIN_SIZE_MAP[this._option("direction")]]()
},
_parseSize: function(size) {
return String(size).match(/.+%$/) ? 0.01 * parseFloat(size) * this._boxSize() : size
},
_boxSize: function() {
return this._$element[FALLBACK_MAIN_SIZE_MAP[this._option("direction")]]()
},
_totalBaseSize: function() {
var result = 0;
$.each(this._$items, $.proxy(function(_, item) {
result += this._baseSize(item)
}, this));
return result
},
update: function() {
if (!this._$items || this._$element.is(":hidden"))
return;
this.renderItems(this._$items);
this.renderAlign();
this.renderCrossAlign();
var element = this._$element.get(0);
this._$items.find(BOX_SELECTOR).each(function() {
if (element === $(this).parent().closest(BOX_SELECTOR).get(0))
$(this).triggerHandler(UPDATE_EVENT)
})
}
});
DX.registerComponent("dxBox", ui, ui.CollectionWidget.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
direction: "row",
align: "start",
crossAlign: "stretch",
activeStateEnabled: false,
focusStateEnabled: false,
_layoutStrategy: "flex"
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function() {
var device = DX.devices.real();
var isOldAndroid = device.platform === "android" && (device.version[0] < 4 || device.version[0] === 4 && device.version[1] < 4),
isOldIos = device.platform === "ios" && device.version[0] < 7;
return device.platform === "win8" || DX.browser["msie"] || isOldAndroid || isOldIos
},
options: {_layoutStrategy: "fallback"}
}])
},
_itemClass: function() {
return BOX_ITEM_CLASS
},
_itemDataKey: function() {
return BOX_ITEM_DATA_KEY
},
_itemElements: function() {
return this._itemContainer().children(this._itemSelector())
},
_init: function() {
this.callBase();
this.element().addClass(BOX_CLASS + "-" + this.option("_layoutStrategy"));
this._initLayout()
},
_initLayout: function() {
this._layout = this.option("_layoutStrategy") === "fallback" ? new FallbackLayoutStrategy(this.element(), $.proxy(this.option, this)) : new FlexLayoutStrategy(this.element(), $.proxy(this.option, this))
},
_render: function() {
this.callBase();
this.element().addClass(BOX_CLASS);
this._renderBox()
},
_renderBox: function() {
this._layout.renderBox();
this._layout.renderAlign();
this._layout.renderCrossAlign()
},
_renderItems: function(items) {
this.callBase(items);
this._layout.renderItems(this._itemElements());
clearTimeout(this._updateTimer);
this._updateTimer = setTimeout($.proxy(function() {
if (!this._isUpdated)
this._layout.update();
this._isUpdated = false
}, this))
},
_postprocessRenderItem: function(args) {
var boxConfig = args.itemData.box;
if (!boxConfig)
return;
this._createComponent(args.itemContent, "dxBox", $.extend({
itemTemplate: this.option("itemTemplate"),
itemHoldTimeout: this.option("itemHoldTimeout"),
onItemHold: this.option("onItemHold"),
onItemClick: this.option("onItemClick"),
onItemContextMenu: this.option("onItemContextMenu"),
onItemRendered: this.option("onItemRendered")
}, boxConfig))
},
_createItemByTemplate: function(itemTemplate, args) {
return args.item.box ? itemTemplate.source() : this.callBase(itemTemplate, args)
},
_visibilityChanged: function(visible) {
if (visible)
this._dimensionChanged()
},
_dimensionChanged: function() {
this._isUpdated = true;
this._layout.update()
},
_dispose: function() {
clearTimeout(this._updateTimer);
this.callBase.apply(this, arguments)
},
_optionChanged: function(args) {
switch (args.name) {
case"_layoutStrategy":
case"direction":
this._invalidate();
break;
case"align":
this._layout.renderAlign();
break;
case"crossAlign":
this._layout.renderCrossAlign();
break;
default:
this.callBase(args)
}
},
repaint: function() {
this._dimensionChanged()
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.responsiveBox.js */
(function($, DX, undefined) {
var ui = DX.ui;
var RESPONSIVE_BOX_CLASS = "dx-responsivebox",
BOX_ITEM_CLASS = "dx-box-item",
BOX_ITEM_DATA_KEY = "dxBoxItemData";
var DEFAULT_SCREEN_FACTOR_FUNC = function(width) {
if (width < 768)
return "xs";
else if (width < 992)
return "sm";
else if (width < 1200)
return "md";
else
return "lg"
};
DX.registerComponent("dxResponsiveBox", ui, ui.CollectionWidget.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
rows: [],
cols: [],
screenByWidth: DEFAULT_SCREEN_FACTOR_FUNC,
singleColumnScreen: "xs",
activeStateEnabled: false,
focusStateEnabled: false
})
},
_initOptions: function(options) {
if (options.screenByWidth)
this.option("singleColumnScreen", options.screenByWidth(0));
this.callBase(options)
},
_itemClass: function() {
return BOX_ITEM_CLASS
},
_itemDataKey: function() {
return BOX_ITEM_DATA_KEY
},
_render: function() {
this.callBase();
this.element().addClass(RESPONSIVE_BOX_CLASS);
this._updateRootBox()
},
_updateRootBox: function() {
clearTimeout(this._updateTimer);
this._updateTimer = setTimeout($.proxy(function() {
if (this._$root)
this._$root.trigger("dxupdate")
}, this))
},
_renderItems: function() {
this._screenItems = this._itemsByScreen();
this._prepareGrid();
this._spreadItems();
this._layoutItems();
this._linkNodeToItem()
},
_prepareGrid: function() {
var grid = this._grid = [];
this._prepareRowsAndCols();
$.each(this._rows, $.proxy(function() {
var row = [];
grid.push(row);
$.each(this._cols, $.proxy(function() {
row.push(this._createEmptyCell())
}, this))
}, this))
},
_prepareRowsAndCols: function() {
if (this._isSingleColumnScreen()) {
this._prepareSingleColumnScreenItems();
this._rows = this._defaultSizeConfig(this._screenItems.length);
this._cols = this._defaultSizeConfig(1)
}
else {
this._rows = this._sizesByScreen(this.option("rows"));
this._cols = this._sizesByScreen(this.option("cols"))
}
},
_isSingleColumnScreen: function() {
return this._screenRegExp().test(this.option("singleColumnScreen")) || !this.option("rows").length || !this.option("cols").length
},
_prepareSingleColumnScreenItems: function() {
this._screenItems.sort(function(item1, item2) {
return item1.location.row - item2.location.row || item1.location.col - item2.location.col
});
$.each(this._screenItems, function(index, item) {
$.extend(item.location, {
row: index,
col: 0,
rowspan: 1,
colspan: 1
})
})
},
_sizesByScreen: function(sizeConfigs) {
return $.map(this._filterByScreen(sizeConfigs), $.proxy(function(sizeConfig) {
return $.extend(this._defaultSizeConfig(), sizeConfig)
}, this))
},
_defaultSizeConfig: function(size) {
var defaultSizeConfig = {
ratio: 1,
baseSize: 0,
minSize: 0,
maxSize: 0
};
if (!arguments.length)
return defaultSizeConfig;
var result = [];
for (var i = 0; i < size; i++)
result.push(defaultSizeConfig);
return result
},
_filterByScreen: function(items) {
var screenRegExp = this._screenRegExp();
return $.grep(items, function(item) {
return !item.screen || screenRegExp.test(item.screen)
})
},
_screenRegExp: function() {
var width = this._screenWidth();
var screen = this.option("screenByWidth")(width);
return new RegExp("(^|\\s)" + screen + "($|\\s)", "i")
},
_screenWidth: function() {
return $(window).width()
},
_createEmptyCell: function() {
return {
item: {},
location: {
colspan: 1,
rowspan: 1
}
}
},
_spreadItems: function() {
$.each(this._screenItems, $.proxy(function(_, itemInfo) {
var location = itemInfo.location || {};
var itemCol = location.col;
var itemRow = location.row;
var row = this._grid[itemRow];
var itemCell = row && row[itemCol];
this._occupyCells(itemCell, itemInfo)
}, this))
},
_itemsByScreen: function() {
return $.map(this.option("items"), $.proxy(function(item) {
var locations = item.location || {};
locations = $.isPlainObject(locations) ? [locations] : locations;
return $.map(this._filterByScreen(locations), function(location) {
return {
item: item,
location: $.extend({
rowspan: 1,
colspan: 1
}, location)
}
})
}, this))
},
_occupyCells: function(itemCell, itemInfo) {
if (!itemCell || this._isItemCellOccupied(itemCell, itemInfo))
return;
$.extend(itemCell, itemInfo);
this._markSpanningCell(itemCell)
},
_isItemCellOccupied: function(itemCell, itemInfo) {
if (!$.isEmptyObject(itemCell.item))
return true;
var result = false;
this._loopOverSpanning(itemInfo.location, function(cell) {
result = result || !$.isEmptyObject(cell.item)
});
return result
},
_loopOverSpanning: function(location, callback) {
var rowEnd = location.row + location.rowspan - 1;
var colEnd = location.col + location.colspan - 1;
var boundRowEnd = Math.min(rowEnd, this._rows.length - 1);
var boundColEnd = Math.min(colEnd, this._cols.length - 1);
location.rowspan -= rowEnd - boundRowEnd;
location.colspan -= colEnd - boundColEnd;
for (var rowIndex = location.row; rowIndex <= boundRowEnd; rowIndex++)
for (var colIndex = location.col; colIndex <= boundColEnd; colIndex++)
if (rowIndex !== location.row || colIndex !== location.col)
callback(this._grid[rowIndex][colIndex])
},
_markSpanningCell: function(itemCell) {
this._loopOverSpanning(itemCell.location, function(cell) {
$.extend(cell, {
item: itemCell.item,
spanningCell: itemCell
})
})
},
_linkNodeToItem: function() {
$.each(this._itemElements(), function(_, itemNode) {
var $item = $(itemNode),
item = $item.data(BOX_ITEM_DATA_KEY);
if (!item.box)
item.node = $item.children()
})
},
_layoutItems: function() {
var rowsCount = this._grid.length;
var colsCount = rowsCount && this._grid[0].length;
if (!rowsCount && !colsCount)
return;
var result = this._layoutBlock({
direction: "col",
row: {
start: 0,
end: rowsCount - 1
},
col: {
start: 0,
end: colsCount - 1
}
});
var rootBox = this._prepareBoxConfig(result.box || {
direction: "col",
items: [result]
});
$.extend(rootBox, this._rootBoxConfig());
this._$root = $("
").appendTo(this._itemContainer());
this._createComponent(this._$root, "dxBox", rootBox)
},
_rootBoxConfig: function(config) {
return {
width: "100%",
height: "100%",
itemTemplate: this.option("itemTemplate"),
itemHoldTimeout: this.option("itemHoldTimeout"),
onItemHold: this.option("onItemHold"),
onItemClick: this.option("onItemClick"),
onItemContextMenu: this.option("onItemContextMenu"),
onItemRendered: this.option("onItemRendered")
}
},
_prepareBoxConfig: function(config) {
return $.extend(config || {}, {crossAlign: "stretch"})
},
_layoutBlock: function(options) {
if (this._isSingleItem(options))
return this._itemByCell(options.row.start, options.col.start);
return this._layoutDirection(options)
},
_isSingleItem: function(options) {
var firstCellLocation = this._grid[options.row.start][options.col.start].location;
var isItemRowSpanned = options.row.end - options.row.start === firstCellLocation.rowspan - 1;
var isItemColSpanned = options.col.end - options.col.start === firstCellLocation.colspan - 1;
return isItemRowSpanned && isItemColSpanned
},
_itemByCell: function(rowIndex, colIndex) {
var itemCell = this._grid[rowIndex][colIndex];
return itemCell.spanningCell ? null : itemCell.item
},
_layoutDirection: function(options) {
var items = [];
var direction = options.direction;
var crossDirection = this._crossDirection(direction);
var block;
while (block = this._nextBlock(options)) {
if (this._isBlockIndivisible(options.prevBlockOptions, block))
throw DX.Error("E1025");
var item = this._layoutBlock({
direction: crossDirection,
row: block.row,
col: block.col,
prevBlockOptions: options
});
if (item) {
$.extend(item, this._blockSize(block, crossDirection));
items.push(item)
}
options[crossDirection].start = block[crossDirection].end + 1
}
return {box: this._prepareBoxConfig({
direction: direction,
items: items
})}
},
_isBlockIndivisible: function(options, block) {
return options && options.col.start === block.col.start && options.col.end === block.col.end && options.row.start === block.row.start && options.row.end === block.row.end
},
_crossDirection: function(direction) {
return direction === "col" ? "row" : "col"
},
_nextBlock: function(options) {
var direction = options.direction;
var crossDirection = this._crossDirection(direction);
var startIndex = options[direction].start;
var endIndex = options[direction].end;
var crossStartIndex = options[crossDirection].start;
if (crossStartIndex > options[crossDirection].end)
return null;
var crossSpan = 1;
for (var crossIndex = crossStartIndex; crossIndex < crossStartIndex + crossSpan; crossIndex++) {
var lineCrossSpan = 1;
for (var index = startIndex; index <= endIndex; index++) {
var cell = this._cellByDirection(direction, index, crossIndex);
lineCrossSpan = Math.max(lineCrossSpan, cell.location[crossDirection + "span"])
}
var lineCrossEndIndex = crossIndex + lineCrossSpan;
var crossEndIndex = crossStartIndex + crossSpan;
if (lineCrossEndIndex > crossEndIndex)
crossSpan += lineCrossEndIndex - crossEndIndex
}
var result = {};
result[direction] = {
start: startIndex,
end: endIndex
};
result[crossDirection] = {
start: crossStartIndex,
end: crossStartIndex + crossSpan - 1
};
return result
},
_cellByDirection: function(direction, index, crossIndex) {
return direction === "col" ? this._grid[crossIndex][index] : this._grid[index][crossIndex]
},
_blockSize: function(block, direction) {
var sizeConfigs = direction === "row" ? this._rows : this._cols;
var result = {
ratio: 0,
baseSize: 0,
minSize: 0,
maxSize: 0
};
for (var index = block[direction].start; index <= block[direction].end; index++) {
var sizeConfig = sizeConfigs[index];
result.ratio += sizeConfig.ratio;
result.baseSize += sizeConfig.baseSize;
result.minSize += sizeConfig.minSize;
result.maxSize += sizeConfig.maxSize
}
result.minSize = result.minSize ? result.minSize : "auto";
result.maxSize = result.maxSize ? result.maxSize : "auto";
this._isSingleColumnScreen() && (result.baseSize = 'auto');
return result
},
_update: function() {
var $existingRoot = this._$root;
this._renderItems();
$existingRoot.remove()
},
_dispose: function() {
clearTimeout(this._updateTimer);
this.callBase.apply(this, arguments)
},
_optionChanged: function(args) {
switch (args.name) {
case"rows":
case"cols":
case"screenByWidth":
case"singleColumnScreen":
this._invalidate();
break;
case"width":
case"height":
this.callBase(args);
this._update();
break;
default:
this.callBase(args)
}
},
_dimensionChanged: function() {
this._update()
},
repaint: function() {
this._update()
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.button.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
utils = DX.utils;
var BUTTON_CLASS = "dx-button",
BUTTON_CONTENT_CLASS = "dx-button-content",
BUTTON_HAS_TEXT_CLASS = "dx-button-has-text",
BUTTON_HAS_ICON_CLASS = "dx-button-has-icon",
TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper",
BUTTON_FEEDBACK_HIDE_TIMEOUT = 100;
DX.registerComponent("dxButton", ui, ui.Widget.inherit({
_supportedKeys: function() {
var that = this,
click = function(e) {
e.preventDefault();
that._executeClickAction(e)
};
return $.extend(this.callBase(), {
space: click,
enter: click
})
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {
clickAction: {
since: "14.2",
alias: "onClick"
},
iconSrc: {
since: "15.1",
alias: "icon"
}
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
onClick: null,
type: "normal",
text: "",
icon: "",
validationGroup: undefined,
activeStateEnabled: true,
template: "content"
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function(device) {
return DX.devices.real().generic && !DX.devices.isSimulator()
},
options: {
hoverStateEnabled: true,
focusStateEnabled: true
}
}])
},
_init: function() {
this.callBase();
this._feedbackHideTimeout = BUTTON_FEEDBACK_HIDE_TIMEOUT
},
_render: function() {
this.callBase();
this.element().addClass(BUTTON_CLASS);
this._renderType();
this._renderClick();
this.setAria("role", "button");
this._updateAriaLabel()
},
_renderContentImpl: function() {
var $content = $("
").addClass(BUTTON_CONTENT_CLASS),
data = this._getContentData();
this.element().empty();
this.element().append($content);
this.element().toggleClass(BUTTON_HAS_ICON_CLASS, !!data.icon);
this.element().toggleClass(BUTTON_HAS_TEXT_CLASS, !!data.text);
var template = this._getTemplateByOption("template");
var $result = template.render(data, $content);
if ($result.hasClass(TEMPLATE_WRAPPER_CLASS)) {
$content.replaceWith($result);
$content = $result;
$content.addClass(BUTTON_CONTENT_CLASS)
}
},
_getContentData: function() {
var icon = this.option("icon"),
text = this.option("text"),
back = this.option("type") === "back";
if (back && !icon)
icon = "back";
if (back && !text)
text = DX.localization.localizeString("@Back");
return {
icon: icon,
text: text
}
},
_renderClick: function() {
var that = this,
eventName = events.addNamespace("dxclick", this.NAME);
this._clickAction = this._createActionByOption("onClick");
this.element().off(eventName).on(eventName, function(e) {
that._executeClickAction(e)
})
},
_executeClickAction: function(e) {
this._clickAction({
jQueryEvent: e,
validationGroup: DX.validationEngine.getGroupConfig(this._findGroup())
})
},
_updateAriaLabel: function() {
var icon = this.option("icon"),
text = this.option("text");
icon = utils.getImageSourceType(icon) === "image" ? icon.replace(/.+\/([^\.]+)\..+$/, "$1") : icon;
var ariaLabel = text || icon;
this.setAria("label", $.trim(ariaLabel))
},
_renderType: function() {
var type = this.option("type");
if (type)
this.element().addClass("dx-button-" + type)
},
_refreshType: function(prevType) {
var type = this.option("type");
prevType && this.element().removeClass("dx-button-" + prevType).addClass("dx-button-" + type);
if (!this.element().hasClass("dx-button-has-icon") && type === "back")
this._renderContentImpl()
},
_optionChanged: function(args) {
switch (args.name) {
case"onClick":
this._renderClick();
break;
case"icon":
case"text":
this._renderContentImpl();
this._updateAriaLabel();
break;
case"type":
this._refreshType(args.previousValue);
this._updateAriaLabel();
break;
case"template":
this._renderContentImpl();
break;
default:
this.callBase(args)
}
},
_findGroup: DX.ui.validation.findGroup
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.checkBox.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var CHECKBOX_CLASS = "dx-checkbox",
CHECKBOX_ICON_CLASS = "dx-checkbox-icon",
CHECKBOX_CHECKED_CLASS = "dx-checkbox-checked",
CHECKBOX_CONTAINER_CLASS = "dx-checkbox-container",
CHECKBOX_CONTAINER_SELECTOR = ".dx-checkbox-container",
CHECKBOX_TEXT_CLASS = "dx-checkbox-text",
CHECKBOX_TEXT_SELECTOR = ".dx-checkbox-text",
CHECKBOX_HAS_TEXT_CLASS = "dx-checkbox-has-text",
CHECKBOX_INDETERMINATE_CLASS = "dx-checkbox-indeterminate",
CHECKBOX_FEEDBACK_HIDE_TIMEOUT = 100,
CHECKBOX_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxCheckBox");
DX.registerComponent("dxCheckBox", ui, ui.Editor.inherit({
_supportedKeys: function() {
var click = function(e) {
e.preventDefault();
this._clickAction({jQueryEvent: e})
};
return $.extend(this.callBase(), {space: click})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
value: false,
text: ""
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function(device) {
return DX.devices.real().generic && !DX.devices.isSimulator()
},
options: {
hoverStateEnabled: true,
focusStateEnabled: true
}
}])
},
_init: function() {
this.callBase();
this._feedbackHideTimeout = CHECKBOX_FEEDBACK_HIDE_TIMEOUT
},
_render: function() {
this.callBase();
this.element().addClass(CHECKBOX_CLASS).append($("
").addClass(CHECKBOX_CONTAINER_CLASS));
this.setAria("role", "checkbox");
this._$container = this.element().find(CHECKBOX_CONTAINER_SELECTOR);
this._renderClick();
this._renderValue();
this._renderIcon();
this._renderText()
},
_renderDimensions: function() {
this.callBase()
},
_renderIcon: function() {
this._$icon = $("
").addClass(CHECKBOX_ICON_CLASS).prependTo(this._$container)
},
_renderText: function() {
this._$text = this._$container.find(CHECKBOX_TEXT_SELECTOR);
if (!this.option("text")) {
if (this._$text) {
this._$text.remove();
this.element().removeClass(CHECKBOX_HAS_TEXT_CLASS)
}
return
}
if (!this._$text.length)
this._$text = $("").addClass(CHECKBOX_TEXT_CLASS);
this._$text.text(this.option("text"));
this._$container.append(this._$text);
this.element().addClass(CHECKBOX_HAS_TEXT_CLASS)
},
_renderClick: function() {
this._clickAction = this._createAction(this._clickHandler);
this.element().off(CHECKBOX_DXCLICK_EVENT_NAME).on(CHECKBOX_DXCLICK_EVENT_NAME, $.proxy(function(e) {
this._clickAction({jQueryEvent: e})
}, this))
},
_clickHandler: function(args) {
var that = args.component;
that._saveValueChangeEvent(args.jQueryEvent);
that.option("value", !that.option("value"))
},
_renderValue: function() {
var $element = this.element(),
checked = this.option("value"),
indeterminate = checked === undefined;
$element.toggleClass(CHECKBOX_CHECKED_CLASS, Boolean(checked));
$element.toggleClass(CHECKBOX_INDETERMINATE_CLASS, indeterminate);
this.setAria("checked", indeterminate ? "mixed" : checked || "false")
},
_optionChanged: function(args) {
switch (args.name) {
case"value":
this._renderValue();
this.callBase(args);
break;
case"text":
this._renderText();
this._renderDimensions();
break;
default:
this.callBase(args)
}
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.switch.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
fx = DX.fx;
var SWITCH_CLASS = "dx-switch",
SWITCH_WRAPPER_CLASS = SWITCH_CLASS + "-wrapper",
SWITCH_CONTAINER_CLASS = SWITCH_CLASS + "-container",
SWITCH_INNER_CLASS = SWITCH_CLASS + "-inner",
SWITCH_HANDLE_CLASS = SWITCH_CLASS + "-handle",
SWITCH_ON_VALUE_CLASS = SWITCH_CLASS + "-on-value",
SWITCH_ON_CLASS = SWITCH_CLASS + "-on",
SWITCH_OFF_CLASS = SWITCH_CLASS + "-off",
SWITCH_ANIMATION_DURATION = 100;
DX.registerComponent("dxSwitch", ui, ui.Editor.inherit({
_supportedKeys: function() {
var isRTL = this.option("rtlEnabled");
var click = function(e) {
e.preventDefault();
this._clickAction({jQueryEvent: e})
},
move = function(value, e) {
e.preventDefault();
e.stopPropagation();
this._animateValue(value)
};
return $.extend(this.callBase(), {
space: click,
enter: click,
leftArrow: $.proxy(move, this, isRTL ? true : false),
rightArrow: $.proxy(move, this, isRTL ? false : true)
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
onText: Globalize.localize("dxSwitch-onText"),
offText: Globalize.localize("dxSwitch-offText"),
value: false
})
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: function(device) {
return DX.devices.real().generic && !DX.devices.isSimulator()
},
options: {
hoverStateEnabled: true,
focusStateEnabled: true
}
}])
},
_init: function() {
this.callBase();
this._animating = false;
this._animationDuration = SWITCH_ANIMATION_DURATION
},
_render: function() {
var element = this.element();
this._$switchInner = $("").addClass(SWITCH_INNER_CLASS);
this._$handle = $("
").addClass(SWITCH_HANDLE_CLASS).appendTo(this._$switchInner);
this._$labelOn = $("
").addClass(SWITCH_ON_CLASS).prependTo(this._$switchInner);
this._$labelOff = $("
").addClass(SWITCH_OFF_CLASS).appendTo(this._$switchInner);
this._$switchContainer = $("
").addClass(SWITCH_CONTAINER_CLASS).append(this._$switchInner);
this._$switchWrapper = $("
").addClass(SWITCH_WRAPPER_CLASS).append(this._$switchContainer);
element.addClass(SWITCH_CLASS).append(this._$switchWrapper);
this.setAria("role", "button");
this._createComponent(element, "dxSwipeable", {
elastic: false,
immediate: true,
onStart: $.proxy(this._swipeStartHandler, this),
onUpdated: $.proxy(this._swipeUpdateHandler, this),
onEnd: $.proxy(this._swipeEndHandler, this)
});
this._renderLabels();
this.callBase();
this._updateMarginBound();
this._renderValue();
this._renderClick()
},
_updateMarginBound: function() {
this._marginBound = this._$switchContainer.outerWidth(true) - this._$handle.outerWidth()
},
_marginDirection: function() {
return this.option("rtlEnabled") ? "Right" : "Left"
},
_offsetDirection: function() {
return this.option("rtlEnabled") ? -1 : 1
},
_renderPosition: function(state, swipeOffset) {
var stateInt = state ? 1 : 0,
marginDirection = this._marginDirection(),
resetMarginDirection = marginDirection === "Left" ? "Right" : "Left";
this._$switchInner.css("margin" + marginDirection, this._marginBound * (stateInt + swipeOffset - 1));
this._$switchInner.css("margin" + resetMarginDirection, 0)
},
_validateValue: function() {
var check = this.option("value");
if (typeof check !== "boolean")
this._options["value"] = !!check
},
_renderClick: function() {
var eventName = events.addNamespace("dxclick", this.NAME);
this._clickAction = this._createAction($.proxy(this._clickHandler, this));
this.element().off(eventName).on(eventName, $.proxy(function(e) {
this._clickAction({jQueryEvent: e})
}, this))
},
_clickHandler: function(args) {
var e = args.jQueryEvent;
this._saveValueChangeEvent(e);
if (this._animating || this._swiping)
return;
this._animateValue(!this.option("value"))
},
_animateValue: function(value) {
var startValue = this.option("value"),
endValue = value;
if (startValue === endValue)
return;
this._animating = true;
var that = this,
marginDirection = this._marginDirection(),
resetMarginDirection = marginDirection === "Left" ? "Right" : "Left",
fromConfig = {},
toConfig = {};
this._$switchInner.css("margin" + resetMarginDirection, 0);
fromConfig["margin" + marginDirection] = (Number(startValue) - 1) * this._marginBound;
toConfig["margin" + marginDirection] = (Number(endValue) - 1) * this._marginBound;
fx.animate(this._$switchInner, {
from: fromConfig,
to: toConfig,
duration: this._animationDuration,
complete: function() {
that._animating = false;
that.option("value", endValue)
}
})
},
_swipeStartHandler: function(e) {
var state = this.option("value"),
rtlEnabled = this.option("rtlEnabled"),
maxOffOffset = rtlEnabled ? 0 : 1,
maxOnOffset = rtlEnabled ? 1 : 0;
e.jQueryEvent.maxLeftOffset = state ? maxOffOffset : maxOnOffset;
e.jQueryEvent.maxRightOffset = state ? maxOnOffset : maxOffOffset;
this._swiping = true;
this._toggleActiveState(this.element(), true)
},
_swipeUpdateHandler: function(e) {
this._renderPosition(this.option("value"), this._offsetDirection() * e.jQueryEvent.offset)
},
_swipeEndHandler: function(e) {
var that = this,
offsetDirection = this._offsetDirection(),
toConfig = {};
toConfig["margin" + this._marginDirection()] = this._marginBound * (that.option("value") + offsetDirection * e.jQueryEvent.targetOffset - 1);
fx.animate(this._$switchInner, {
to: toConfig,
duration: that._animationDuration,
complete: function() {
that._swiping = false;
var pos = that.option("value") + offsetDirection * e.jQueryEvent.targetOffset;
that.option("value", Boolean(pos));
that._toggleActiveState(that.element(), false)
}
})
},
_renderValue: function() {
this._validateValue();
var val = this.option("value");
this._renderPosition(val, 0);
this.element().toggleClass(SWITCH_ON_VALUE_CLASS, val);
this.setAria({
pressed: val,
label: val ? this.option("onText") : this.option("offText")
})
},
_renderLabels: function() {
this._$labelOn.text(this.option("onText"));
this._$labelOff.text(this.option("offText"))
},
_visibilityChanged: function(visible) {
if (visible)
this.repaint()
},
_optionChanged: function(args) {
switch (args.name) {
case"visible":
case"width":
this._refresh();
break;
case"onText":
case"offText":
this._renderLabels();
break;
case"value":
this._renderValue();
this.callBase(args);
break;
default:
this.callBase(args)
}
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.textEditor.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
inflector = DX.inflector;
var TEXTEDITOR_CLASS = "dx-texteditor",
TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input",
TEXTEDITOR_INPUT_SELECTOR = "." + TEXTEDITOR_INPUT_CLASS,
TEXTEDITOR_CONTAINER_CLASS = "dx-texteditor-container",
TEXTEDITOR_BUTTONS_CONTAINER_CLASS = "dx-texteditor-buttons-container",
TEXTEDITOR_PLACEHOLDER_CLASS = "dx-placeholder",
TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS = "dx-show-clear-button",
TEXTEDITOR_ICON_CLASS = "dx-icon",
TEXTEDITOR_CLEAR_ICON_CLASS = "dx-icon-clear",
TEXTEDITOR_CLEAR_BUTTON_CLASS = "dx-clear-button-area",
TEXTEDITOR_EMPTY_INPUT_CLASS = "dx-texteditor-empty",
TEXTEDITOR_STATE_FOCUSED_CLASS = "dx-state-focused",
EVENTS_LIST = ["keyDown", "keyPress", "keyUp", "change", "cut", "copy", "paste", "input"];
DX.registerComponent("dxTextEditor", ui, ui.Editor.inherit({
_supportedKeys: function() {
var stop = function(e) {
e.stopPropagation()
};
return {
space: stop,
enter: stop,
leftArrow: stop,
rightArrow: stop
}
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {
keyDownAction: {
since: "14.2",
alias: "onKeyDown"
},
keyPressAction: {
since: "14.2",
alias: "onKeyPress"
},
keyUpAction: {
since: "14.2",
alias: "onKeyUp"
},
cutAction: {
since: "14.2",
alias: "onCut"
},
copyAction: {
since: "14.2",
alias: "onCopy"
},
pasteAction: {
since: "14.2",
alias: "onPaste"
},
changeAction: {
since: "14.2",
alias: "onChange"
},
inputAction: {
since: "14.2",
alias: "onInput"
},
focusInAction: {
since: "14.2",
alias: "onFocusIn"
},
focusOutAction: {
since: "14.2",
alias: "onFocusOut"
},
enterKeyAction: {
since: "14.2",
alias: "onEnterKey"
}
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
value: "",
spellcheck: false,
showClearButton: false,
valueChangeEvent: "change",
placeholder: "",
attr: {},
onFocusIn: null,
onFocusOut: null,
onKeyDown: null,
onKeyPress: null,
onKeyUp: null,
onChange: null,
onInput: null,
onCut: null,
onCopy: null,
onPaste: null,
onEnterKey: null,
mode: "text",
hoverStateEnabled: true,
focusStateEnabled: true,
text: undefined,
valueFormat: function(value) {
return value
}
})
},
_input: function() {
return this.element().find(TEXTEDITOR_INPUT_SELECTOR).first()
},
_inputWrapper: function() {
return this.element()
},
_buttonsContainer: function() {
return this._inputWrapper().find("." + TEXTEDITOR_BUTTONS_CONTAINER_CLASS)
},
_render: function() {
this.element().addClass(TEXTEDITOR_CLASS);
this._renderInput();
this._renderInputType();
this._renderValue();
this._renderProps();
this._renderPlaceholder();
this._renderEvents();
this._renderEnterKeyAction();
this._renderEmptinessEvent();
this.callBase()
},
_renderInput: function() {
$("
").addClass(TEXTEDITOR_CONTAINER_CLASS).append(this._createInput()).append($("
").addClass(TEXTEDITOR_BUTTONS_CONTAINER_CLASS)).appendTo(this.element())
},
_createInput: function() {
return $("
").addClass(TEXTEDITOR_INPUT_CLASS).attr("autocomplete", "off").attr(this.option("attr"))
},
_renderValue: function() {
this._renderInputValue();
this._renderInputAddons()
},
_renderInputValue: function() {
var text = this.option("text"),
value = this.option("value"),
displayValue = this.option("displayValue"),
valueFormat = this.option("valueFormat");
if (displayValue !== undefined)
text = valueFormat(displayValue);
else if (!DX.utils.isDefined(text))
text = valueFormat(value);
if (this._input().val() !== (DX.utils.isDefined(text) ? text : ""))
this._renderDisplayText(text)
},
_renderDisplayText: function(text) {
this._input().val(text);
this._toggleEmptinessEventHandler()
},
_isValueValid: function() {
var validity = this._input().get(0).validity;
if (validity)
return validity.valid;
return true
},
_toggleEmptiness: function(isEmpty) {
this.element().toggleClass(TEXTEDITOR_EMPTY_INPUT_CLASS, isEmpty);
this._togglePlaceholder(isEmpty)
},
_togglePlaceholder: function(isEmpty) {
if (!this._$placeholder)
return;
if (DX.browser["msie"])
this._$placeholder.toggle(!this._input().is(":focus") && isEmpty);
else
this._$placeholder.toggle(isEmpty)
},
_renderProps: function() {
this._toggleDisabledState(this.option("disabled"));
this._toggleReadOnlyState(this._readOnlyPropValue());
this._toggleSpellcheckState()
},
_toggleDisabledState: function() {
this.callBase.apply(this, arguments);
var $input = this._input();
if (this.option("disabled"))
$input.attr("disabled", true).attr("tabindex", -1);
else
$input.removeAttr("disabled").removeAttr("tabindex")
},
_toggleReadOnlyState: function(value) {
this._input().prop("readOnly", value);
this.callBase()
},
_readOnlyPropValue: function() {
return this.option("readOnly")
},
_toggleSpellcheckState: function() {
this._input().prop("spellcheck", this.option("spellcheck"))
},
_renderPlaceholder: function() {
if (this._$placeholder) {
this._$placeholder.remove();
this._$placeholder = null
}
var that = this,
$input = that._input(),
placeholderText = that.option("placeholder"),
$placeholder = this._$placeholder = $('
').attr("data-dx_placeholder", placeholderText),
startEvent = events.addNamespace("dxpointerup", this.NAME);
$placeholder.on(startEvent, function() {
$input.focus()
});
$placeholder.insertAfter($input);
$placeholder.addClass(TEXTEDITOR_PLACEHOLDER_CLASS)
},
_placeholder: function() {
return this._$placeholder || $()
},
_renderInputAddons: function() {
this._renderClearButton()
},
_checkIfClearButtonShouldBeRendered: function() {
return this.option("showClearButton") && !this.option("readOnly")
},
_renderClearButton: function() {
var shouldClearButtonBeRendered = this._checkIfClearButtonShouldBeRendered();
this.element().toggleClass(TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS, shouldClearButtonBeRendered);
if (!shouldClearButtonBeRendered) {
this._$clearButton && this._$clearButton.remove();
this._$clearButton = null;
return
}
if (this._$clearButton)
return;
this._$clearButton = this._createClearButton()
},
_createClearButton: function() {
return $("
").addClass(TEXTEDITOR_CLEAR_BUTTON_CLASS).append($("").addClass(TEXTEDITOR_ICON_CLASS).addClass(TEXTEDITOR_CLEAR_ICON_CLASS)).prependTo(this._buttonsContainer()).on(events.addNamespace("dxpointerdown", this.NAME), function(e) {
e.preventDefault();
e.dxPreventBlur = true
}).on(events.addNamespace("dxclick", this.NAME), $.proxy(this._clearValueHandler, this))
},
_clearValueHandler: function(e) {
var $input = this._input();
e.stopPropagation();
this.reset();
if ($input.is(":focus")) {
$input.val("");
this._toggleEmptinessEventHandler()
}
else
$input.focus()
},
_renderEvents: function() {
var that = this,
$input = that._input();
that._renderValueChangeEvent();
that._attachFocusEvents();
$.each(EVENTS_LIST, function(_, event) {
var eventName = events.addNamespace(event.toLowerCase(), that.NAME),
action = that._createActionByOption("on" + inflector.camelize(event, true), {excludeValidators: ["readOnly"]});
$input.off(eventName).on(eventName, function(e) {
action({jQueryEvent: e})
})
})
},
_keyUpHandler: function(e) {
this.option("text", this._input().val())
},
_renderValueChangeEvent: function() {
var eventNamespace = this.NAME + "ValueChange";
var keyUpNamespace = events.addNamespace(this._renderValueEventName(), this.NAME + "TextChange");
this._input().off(keyUpNamespace).on(keyUpNamespace, $.proxy(this._keyUpHandler, this));
var valueChangeEventNamespace = events.addNamespace(this.option("valueChangeEvent"), eventNamespace);
this._input().off("." + eventNamespace).on(valueChangeEventNamespace, $.proxy(this._valueChangeEventHandler, this)).on("paste", $.proxy(this._pasteHandler, this))
},
_renderValueEventName: function() {
return "input change keyup"
},
_focusTarget: function() {
return this._input()
},
_pasteHandler: function(e) {
clearTimeout(this._pasteTimer);
this._pasteTimer = setTimeout($.proxy(this._valueChangeEventHandler, this, e))
},
_focusInHandler: function(e) {
e.stopPropagation();
this.element().addClass(TEXTEDITOR_STATE_FOCUSED_CLASS)
},
_focusOutHandler: function(e) {
e.stopPropagation();
this.element().removeClass(TEXTEDITOR_STATE_FOCUSED_CLASS)
},
_renderEmptinessEvent: function() {
var $input = this._input();
$input.on("input blur", $.proxy(this._toggleEmptinessEventHandler, this));
this._toggleEmptinessEventHandler()
},
_toggleEmptinessEventHandler: function(value) {
var text = this._input().val(),
isEmpty = (text === "" || text === null) && this._isValueValid();
this._toggleEmptiness(isEmpty)
},
_valueChangeEventHandler: function(e, formattedValue) {
this._saveValueChangeEvent(e);
this.option("value", arguments.length > 1 ? formattedValue : this._input().val())
},
_renderEnterKeyAction: function() {
if (this.option("onEnterKey")) {
this._enterKeyAction = this._createActionByOption("onEnterKey", {excludeValidators: ["readOnly"]});
this._input().on("keyup.onEnterKey.dxTextEditor", $.proxy(this._enterKeyHandlerUp, this))
}
else {
this._input().off("keyup.onEnterKey.dxTextEditor");
this._enterKeyAction = undefined
}
},
_enterKeyHandlerUp: function(e) {
if (e.which === 13)
this._enterKeyAction({jQueryEvent: e})
},
_updateValue: function() {
this.option("text", undefined);
this._renderValue()
},
_clean: function() {
if (this._$placeholder) {
this._$placeholder.remove();
delete this._$placeholder
}
delete this._$clearButton;
this.callBase()
},
_dispose: function() {
clearTimeout(this._pasteTimer);
this.callBase()
},
_optionChanged: function(args) {
var name = args.name;
if ($.inArray(inflector.camelize(name.replace("on", "")), EVENTS_LIST) > -1) {
this._renderEvents();
return
}
switch (name) {
case"valueChangeEvent":
this._renderValueChangeEvent();
break;
case"onValueChanged":
this._createValueChangeAction();
break;
case"readOnly":
this._toggleReadOnlyState(args.value);
this.callBase(args);
this._renderInputAddons();
break;
case"spellcheck":
this._toggleSpellcheckState();
break;
case"mode":
this._renderInputType();
break;
case"onEnterKey":
this._renderEnterKeyAction();
break;
case"placeholder":
this._invalidate();
break;
case"showClearButton":
this._renderInputAddons();
break;
case"text":
break;
case"value":
this._updateValue();
this.callBase(args);
break;
case"attr":
this._input().attr(args.value);
break;
case"valueFormat":
this._invalidate();
break;
default:
this.callBase(args)
}
},
_renderInputType: function() {
this._setInputType(this.option("mode"))
},
_setInputType: function(type) {
var input = this._input();
if (type === "search")
type = "text";
try {
input.prop("type", type)
}
catch(e) {
input.prop("type", "text")
}
},
focus: function() {
this._input().focus()
},
blur: function() {
if (this._input().is(document.activeElement))
DX.utils.resetActiveElement()
},
reset: function() {
this.option("value", "")
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.textEditor.mask.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
utils = DX.utils;
var EMPTY_CHAR = " ";
var EMPTY_CHAR_CODE = 32;
var TEXTEDITOR_MASKED_CLASS = "dx-texteditor-masked";
var MASK_EVENT_NAMESPACE = "dxMask";
var FORWARD_DIRECTION = "forward";
var BACKWARD_DIRECTION = "backward";
var buildInMaskRules = {
"0": /[0-9]/,
"9": /[0-9\s]/,
"#": /[-+0-9\s]/,
L: /[a-zA-Z]/,
l: /[a-zA-Z\s]/,
C: /\S/,
c: /./,
A: /[0-9a-zA-Z]/,
a: /[0-9a-zA-Z\s]/
};
var CONTROL_KEYS = {
35: "end",
36: "home",
37: "leftArrow",
38: "upArrow",
39: "rightArrow",
40: "downArrow"
};
DX.registerComponent("dxTextEditor", ui, ui.dxTextEditor.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
mask: "",
maskChar: "_",
maskRules: {},
maskInvalidMessage: Globalize.localize("validation-mask")
})
},
_supportedKeys: function() {
var that = this;
var keyHandlerMap = {
backspace: that._maskBackspaceHandler,
del: that._maskDelHandler,
enter: that._changeHandler
};
var result = that.callBase();
$.each(keyHandlerMap, function(key, callback) {
var parentHandler = result[key];
result[key] = function(e) {
that.option("mask") && callback.call(that, e);
parentHandler && parentHandler(e)
}
});
return result
},
_render: function() {
this.callBase();
this._renderMask()
},
_renderMask: function() {
this.element().removeClass(TEXTEDITOR_MASKED_CLASS);
this._maskRulesChain = null;
if (!this.option("mask"))
return;
this.element().addClass(TEXTEDITOR_MASKED_CLASS);
this._attachMaskEventHandlers();
this._parseMask();
this._renderMaskedValue()
},
_attachMaskEventHandlers: function() {
this._input().off("." + MASK_EVENT_NAMESPACE).on(events.addNamespace("focus", MASK_EVENT_NAMESPACE), $.proxy(this._maskFocusHandler, this)).on(events.addNamespace("keypress", MASK_EVENT_NAMESPACE), $.proxy(this._maskKeyPressHandler, this)).on(events.addNamespace("paste", MASK_EVENT_NAMESPACE), $.proxy(this._maskPasteHandler, this)).on(events.addNamespace("cut", MASK_EVENT_NAMESPACE), $.proxy(this._maskCutHandler, this)).on(events.addNamespace("drop", MASK_EVENT_NAMESPACE), $.proxy(this._maskDragHandler, this));
this._attachChangeEventHandlers()
},
_attachChangeEventHandlers: function() {
if ($.inArray("change", this.option("valueChangeEvent").split(" ")) === -1)
return;
this._input().on(events.addNamespace("blur", MASK_EVENT_NAMESPACE), $.proxy(this._changeHandler, this))
},
_changeHandler: function(e) {
this._valueChangeEventHandler(events.createEvent(e, {type: "change"}))
},
_parseMask: function() {
this._maskRules = $.extend({}, buildInMaskRules, this.option("maskRules"));
this._maskRulesChain = this._parseMaskRule(0)
},
_parseMaskRule: function(index) {
var mask = this.option("mask");
if (index >= mask.length)
return new ui.dxTextEditor.EmptyMaskRule;
var result = this._getMaskRule(mask[index]);
result.next(this._parseMaskRule(index + 1));
return result
},
_getMaskRule: function(pattern) {
var ruleConfig;
$.each(this._maskRules, function(rulePattern, allowedChars) {
if (rulePattern === pattern) {
ruleConfig = {
pattern: rulePattern,
allowedChars: allowedChars
};
return false
}
});
return utils.isDefined(ruleConfig) ? new ui.dxTextEditor.MaskRule($.extend({maskChar: this.option("maskChar")}, ruleConfig)) : new ui.dxTextEditor.StubMaskRule({maskChar: pattern})
},
_renderMaskedValue: function() {
if (!this._maskRulesChain)
return;
var value = this.option("value");
this._maskRulesChain.clear();
this._handleChain({
value: value,
length: value.length
});
this._displayMask()
},
_displayMask: function() {
var caret = this._caret();
this._renderValue();
this._caret(caret)
},
_renderValue: function() {
if (this._maskRulesChain)
this.option("text", this._maskRulesChain.text());
this.callBase()
},
_valueChangeEventHandler: function(e) {
if (this._maskRulesChain) {
this._saveValueChangeEvent(e);
this.option("value", (this._value || "").replace(/\s+$/, ""));
return
}
this.callBase.apply(this, arguments)
},
_maskFocusHandler: function() {
this._direction(FORWARD_DIRECTION);
this._adjustCaret()
},
_maskKeyPressHandler: function(e) {
if (this._isControlKeyFired(e))
return;
this._maskKeyHandler(e, function() {
this._handleKey(e.which);
return true
})
},
_isControlKeyFired: function(e) {
return CONTROL_KEYS[e.keyCode] && !e.which || e.metaKey
},
_maskBackspaceHandler: function(e) {
this._maskKeyHandler(e, function() {
if (this._hasSelection())
return true;
if (this._tryMoveCaretBackward())
return false;
this._handleKey(EMPTY_CHAR_CODE, BACKWARD_DIRECTION);
return true
})
},
_maskDelHandler: function(e) {
this._maskKeyHandler(e, function() {
!this._hasSelection() && this._handleKey(EMPTY_CHAR_CODE);
return true
})
},
_maskPasteHandler: function(e) {
var caret = this._caret();
this._maskKeyHandler(e, function() {
var pastingText = utils.clipboardText(e);
var restText = this._maskRulesChain.text().substring(caret.end);
var accepted = this._handleChain({
text: pastingText,
start: caret.start,
length: pastingText.length
});
var newCaret = caret.start + accepted;
this._handleChain({
text: restText,
start: newCaret,
length: restText.length
});
this._caret({
start: newCaret,
end: newCaret
});
return true
})
},
_handleChain: function(args) {
var handledCount = this._maskRulesChain.handle(args);
this._value = this._maskRulesChain.value();
return handledCount
},
_maskCutHandler: function(e) {
var caret = this._caret();
var selectedText = this._input().val().substring(caret.start, caret.end);
this._maskKeyHandler(e, function() {
utils.clipboardText(e, selectedText);
return true
})
},
_maskDragHandler: function() {
this._clearDragTimer();
this._dragTimer = setTimeout($.proxy(function() {
this.option("value", this._convertToValue(this._input().val()))
}, this))
},
_convertToValue: function(text) {
return text.replace(new RegExp(this.option("maskChar"), "g"), EMPTY_CHAR)
},
_maskKeyHandler: function(e, tryHandleKeyCallback) {
this._direction(FORWARD_DIRECTION);
e.preventDefault();
this._handleSelection();
if (!tryHandleKeyCallback.call(this))
return;
this._direction(FORWARD_DIRECTION);
this._adjustCaret();
this._displayMask();
this._maskRulesChain.reset()
},
_handleKey: function(keyCode, direction) {
var char = String.fromCharCode(keyCode);
this._direction(direction || FORWARD_DIRECTION);
this._adjustCaret(char);
this._handleKeyChain(char);
this._moveCaret()
},
_handleSelection: function() {
if (!this._hasSelection())
return;
var caret = this._caret();
var emptyChars = new Array(caret.end - caret.start + 1).join(EMPTY_CHAR);
this._handleKeyChain(emptyChars)
},
_handleKeyChain: function(chars) {
var caret = this._caret();
var start = this._isForwardDirection() ? caret.start : caret.start - 1;
var end = this._isForwardDirection() ? caret.end : caret.end - 1;
var length = start === end ? 1 : end - start;
this._handleChain({
text: chars,
start: start,
length: length
})
},
_tryMoveCaretBackward: function() {
this._direction(BACKWARD_DIRECTION);
var currentCaret = this._caret().start;
this._adjustCaret();
return !currentCaret || currentCaret !== this._caret().start
},
_adjustCaret: function(char) {
var caret = this._maskRulesChain.adjustedCaret(this._caret().start, this._isForwardDirection(), char);
this._caret({
start: caret,
end: caret
})
},
_moveCaret: function() {
var currentCaret = this._caret().start;
var maskRuleIndex = currentCaret + (this._isForwardDirection() ? 0 : -1);
var caret = this._maskRulesChain.isAccepted(maskRuleIndex) ? currentCaret + (this._isForwardDirection() ? 1 : -1) : currentCaret;
this._caret({
start: caret,
end: caret
})
},
_caret: function(position) {
if (!arguments.length)
return utils.caret(this._input());
utils.caret(this._input(), position)
},
_hasSelection: function() {
var caret = this._caret();
return caret.start !== caret.end
},
_direction: function(direction) {
if (!arguments.length)
return this._typingDirection;
this._typingDirection = direction
},
_isForwardDirection: function() {
return this._direction() === FORWARD_DIRECTION
},
_clearDragTimer: function() {
clearTimeout(this._dragTimer)
},
_clean: function() {
this._clearDragTimer();
this.callBase()
},
_validateMask: function() {
if (!this._maskRulesChain)
return;
var isValid = this._maskRulesChain.isValid();
this.option({
isValid: isValid,
validationError: isValid ? null : {
editorSpecific: true,
message: this.option("maskInvalidMessage")
}
})
},
_optionChanged: function(args) {
switch (args.name) {
case"mask":
case"maskChar":
case"maskRules":
this._renderMask();
this._validateMask();
break;
case"value":
this._renderMaskedValue();
this._validateMask();
this.callBase(args);
break;
case"maskInvalidMessage":
break;
default:
this.callBase(args)
}
}
}))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.textEditor.mask.rule.js */
(function($, DX, undefined) {
var ui = DX.ui;
var EMPTY_CHAR = " ";
var BaseMaskRule = DX.Class.inherit({
ctor: function(config) {
this._value = EMPTY_CHAR;
$.extend(this, config)
},
next: function(rule) {
if (!arguments.length)
return this._next;
this._next = rule
},
text: $.noop,
value: $.noop,
rawValue: $.noop,
handle: $.noop,
_prepareHandlingArgs: function(args, config) {
var handlingProperty = args.hasOwnProperty("value") ? "value" : "text";
args[handlingProperty] = DX.utils.isDefined(config.str) ? config.str : args[handlingProperty];
args.start = DX.utils.isDefined(config.start) ? config.start : args.start;
args.length = DX.utils.isDefined(config.length) ? config.length : args.length;
return args
},
reset: $.noop,
clear: $.noop,
isAccepted: function() {
return false
},
adjustedCaret: function(caret, isForwardDirection, char) {
return isForwardDirection ? this._adjustedForward(caret, 0, char) : this._adjustedBackward(caret, 0, char)
},
_adjustedForward: $.noop,
_adjustedBackward: $.noop,
isValid: $.noop
});
var EmptyMaskRule = BaseMaskRule.inherit({
next: $.noop,
handle: function() {
return 0
},
text: function() {
return ""
},
value: function() {
return ""
},
rawValue: function() {
return ""
},
adjustedCaret: function() {
return 0
},
isValid: function() {
return true
}
});
var MaskRule = BaseMaskRule.inherit({
text: function() {
return (this._value !== EMPTY_CHAR ? this._value : this.maskChar) + this.next().text()
},
value: function() {
return this._value + this.next().value()
},
rawValue: function() {
return this._value + this.next().rawValue()
},
handle: function(args) {
var str = args.hasOwnProperty("value") ? args.value : args.text;
if (!str.length || !args.length)
return 0;
if (args.start)
return this.next().handle(this._prepareHandlingArgs(args, {start: args.start - 1}));
var char = str[0];
var rest = str.substring(1);
this._tryAcceptChar(char);
return this._accepted() ? this.next().handle(this._prepareHandlingArgs(args, {
str: rest,
length: args.length - 1
})) + 1 : this.handle(this._prepareHandlingArgs(args, {
str: rest,
length: args.length - 1
}))
},
clear: function() {
this._tryAcceptChar(EMPTY_CHAR);
this.next().clear()
},
reset: function() {
this._accepted(false);
this.next().reset()
},
_tryAcceptChar: function(char) {
this._accepted(false);
if (!this._isAllowed(char))
return;
this._accepted(true);
this._value = char
},
_accepted: function(value) {
if (!arguments.length)
return !!this._isAccepted;
this._isAccepted = !!value
},
_isAllowed: function(char) {
if (char === EMPTY_CHAR)
return true;
return this._isValid(char)
},
_isValid: function(char) {
var allowedChars = this.allowedChars;
if (allowedChars instanceof RegExp)
return allowedChars.test(char);
if ($.isFunction(allowedChars))
return allowedChars(char);
if ($.isArray(allowedChars))
return $.inArray(char, allowedChars) > -1;
return allowedChars === char
},
isAccepted: function(caret) {
return caret === 0 ? this._accepted() : this.next().isAccepted(caret - 1)
},
_adjustedForward: function(caret, index, char) {
if (index >= caret)
return index;
return this.next()._adjustedForward(caret, index + 1, char) || index + 1
},
_adjustedBackward: function(caret, index) {
if (index >= caret - 1)
return caret;
return this.next()._adjustedBackward(caret, index + 1) || index + 1
},
isValid: function() {
return this._isValid(this._value) && this.next().isValid()
}
});
var StubMaskRule = MaskRule.inherit({
value: function() {
return this.next().value()
},
handle: function(args) {
var hasValueProperty = args.hasOwnProperty("value");
var str = hasValueProperty ? args.value : args.text;
if (!str.length || !args.length)
return 0;
if (args.start || hasValueProperty)
return this.next().handle(this._prepareHandlingArgs(args, {start: args.start && args.start - 1}));
var char = str[0];
var rest = str.substring(1);
this._tryAcceptChar(char);
var nextArgs = this._isAllowed(char) ? this._prepareHandlingArgs(args, {
str: rest,
length: args.length - 1
}) : args;
return this.next().handle(nextArgs) + 1
},
clear: function() {
this._accepted(false);
this.next().clear()
},
_tryAcceptChar: function(char) {
this._accepted(this._isValid(char))
},
_isValid: function(char) {
return char === this.maskChar
},
_adjustedForward: function(caret, index, char) {
if (index >= caret && char === this.maskChar)
return index;
if (caret === index + 1 && this._accepted())
return caret;
return this.next()._adjustedForward(caret, index + 1, char)
},
_adjustedBackward: function(caret, index) {
if (index >= caret - 1)
return 0;
return this.next()._adjustedBackward(caret, index + 1)
},
isValid: function() {
return this.next().isValid()
}
});
$.extend(ui.dxTextEditor, {
MaskRule: MaskRule,
StubMaskRule: StubMaskRule,
EmptyMaskRule: EmptyMaskRule
})
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.textBox.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
devices = DX.devices,
ua = window.navigator.userAgent,
ignoreCode = [8, 9, 13, 33, 34, 35, 36, 37, 38, 39, 40, 46],
TEXTBOX_CLASS = "dx-textbox",
SEARCHBOX_CLASS = "dx-searchbox",
ICON_CLASS = "dx-icon",
SEARCH_ICON_CLASS = "dx-icon-search";
DX.registerComponent("dxTextBox", ui, ui.dxTextEditor.inherit({
ctor: function(element, options) {
if (options)
this._showClearButton = options.showClearButton;
this.callBase.apply(this, arguments)
},
_setDefaultOptions: function() {
this.callBase();
this.option({
mode: "text",
maxLength: null
})
},
_render: function() {
this.callBase();
this.element().addClass(TEXTBOX_CLASS);
this.setAria("role", "textbox");
this._renderMaxLengthHandlers()
},
_renderInputType: function() {
this.callBase();
this._renderSearchMode()
},
_renderMaxLengthHandlers: function() {
if (this._isAndroid())
this._input().on(events.addNamespace("keydown", this.NAME), $.proxy(this._onKeyDownAndroidHandler, this)).on(events.addNamespace("change", this.NAME), $.proxy(this._onChangeAndroidHandler, this))
},
_getAriaTarget: function() {
return this._input()
},
_renderProps: function() {
this.callBase();
this._toggleMaxLengthProp()
},
_toggleMaxLengthProp: function() {
if (this._isAndroid())
return;
var maxLength = this.option("maxLength");
if (maxLength > 0)
this._input().attr("maxLength", maxLength);
else
this._input().removeAttr("maxLength")
},
_renderSearchMode: function() {
var $element = this._$element;
if (this.option("mode") === "search") {
$element.addClass(SEARCHBOX_CLASS);
this._renderSearchIcon();
if (this._showClearButton === undefined) {
this._showClearButton = this.option("showClearButton");
this.option("showClearButton", true)
}
}
else {
$element.removeClass(SEARCHBOX_CLASS);
this._$searchIcon && this._$searchIcon.remove();
this.option("showClearButton", this._showClearButton === undefined ? this.option("showClearButton") : this._showClearButton);
delete this._showClearButton
}
},
_renderSearchIcon: function() {
var $searchIcon = $("").addClass(ICON_CLASS).addClass(SEARCH_ICON_CLASS);
$searchIcon.prependTo(this._input().parent());
this._$searchIcon = $searchIcon
},
_optionChanged: function(args) {
switch (args.name) {
case"maxLength":
this._toggleMaxLengthProp();
this._renderMaxLengthHandlers();
break;
default:
this.callBase(args)
}
},
_onKeyDownAndroidHandler: function(e) {
var maxLength = this.option("maxLength");
if (maxLength) {
var $input = $(e.target),
code = e.keyCode;
this._cutOffExtraChar($input);
return $input.val().length < maxLength || $.inArray(code, ignoreCode) !== -1 || window.getSelection().toString() !== ""
}
else
return true
},
_onChangeAndroidHandler: function(e) {
var $input = $(e.target);
if (this.option("maxLength"))
this._cutOffExtraChar($input)
},
_cutOffExtraChar: function($input) {
var maxLength = this.option("maxLength"),
textInput = $input.val();
if (textInput.length > maxLength)
$input.val(textInput.substr(0, maxLength))
},
_isAndroid: function() {
var realDevice = devices.real();
var version = realDevice.version.join(".");
return realDevice.platform === "android" && version && /^(2\.|4\.1)/.test(version) && !/chrome/i.test(ua)
}
}));
ui.dxTextBox.__internals = {
uaAccessor: function(value) {
if (!arguments.length)
return ui;
ua = value
},
SEARCHBOX_CLASS: SEARCHBOX_CLASS,
SEARCH_ICON_CLASS: SEARCH_ICON_CLASS
}
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.dropDownEditor.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
DROP_DOWN_EDITOR_CLASS = "dx-dropdowneditor",
DROP_DOWN_EDITOR_READONLY_CLASS = "dx-dropdowneditor-readonly",
DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS = "dx-dropdowneditor-input-wrapper",
DROP_DOWN_EDITOR_BUTTON_CLASS = "dx-dropdowneditor-button",
DROP_DOWN_EDITOR_BUTTON_ICON = "dx-dropdowneditor-icon",
DROP_DOWN_EDITOR_OVERLAY = "dx-dropdowneditor-overlay",
DROP_DOWN_EDITOR_OVERLAY_FLIPPED = "dx-dropdowneditor-overlay-flipped",
DROP_DOWN_EDITOR_ACTIVE = "dx-dropdowneditor-active",
DROP_DOWN_EDITOR_BUTTON_VISIBLE = "dx-dropdowneditor-button-visible",
DROP_DOWN_EDITOR_FIELD_CLICKABLE = "dx-dropdowneditor-field-clickable",
DROP_DOWN_EDITOR = "dxDropDownEditor",
CLICK_EVENT_NAME = events.addNamespace("dxclick", DROP_DOWN_EDITOR);
DX.registerComponent(DROP_DOWN_EDITOR, ui, ui.dxTextBox.inherit({
_supportedKeys: function() {
return $.extend(this.callBase(), {
escape: function(e) {
if (this.option("opened"))
e.preventDefault();
this.close()
},
upArrow: function(e) {
e.preventDefault();
e.stopPropagation();
if (e.altKey) {
this.close();
return false
}
return true
},
downArrow: function(e) {
e.preventDefault();
e.stopPropagation();
if (e.altKey) {
this._validatedOpening();
return false
}
return true
},
enter: function(e) {
if (this.option("opened")) {
e.preventDefault();
this._valueChangeEventHandler(e)
}
return true
}
})
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, {
openAction: {
since: "14.2",
alias: "onOpened"
},
closeAction: {
since: "14.2",
alias: "onClosed"
},
shownAction: {
since: "14.2",
alias: "onOpened"
},
hiddenAction: {
since: "14.2",
alias: "onClosed"
},
editEnabled: {
since: "14.2",
alias: "fieldEditEnabled"
}
})
},
_setDefaultOptions: function() {
this.callBase();
this.option({
value: null,
onOpened: null,
onClosed: null,
opened: false,
fieldEditEnabled: true,
applyValueMode: "instantly",
fieldTemplate: null,
contentTemplate: null,
openOnFieldClick: false,
deferRendering: true,
showDropButton: true,
dropPosition: this._getDefaultDropPosition(),
applyButtonText: Globalize.localize("OK"),
cancelButtonText: Globalize.localize("Cancel"),
buttonsLocation: "default",
showPopupTitle: false
})
},
_getDefaultDropPosition: function() {
var position = this.option("rtlEnabled") ? "right" : "left";
return {
offset: {
h: 0,
v: -1
},
my: position + " top",
at: position + " bottom",
collision: "flip flip"
}
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: {platform: "generic"},
options: {dropPosition: {offset: {v: 0}}}
}])
},
_inputWrapper: function() {
return this.element().find("." + DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS)
},
_init: function() {
this.callBase();
this._initVisibilityActions()
},
_initVisibilityActions: function() {
this._openAction = this._createActionByOption("onOpened");
this._closeAction = this._createActionByOption("onClosed")
},
_render: function() {
this.callBase();
this._renderOpenHandler();
this.element().addClass(DROP_DOWN_EDITOR_CLASS);
this._renderOpenedState();
this.setAria("role", "combobox")
},
_renderContentImpl: function() {
if (!this.option("deferRendering"))
this._createPopup()
},
_renderInput: function() {
this.callBase();
this.element().wrapInner($("
").addClass(DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS));
this._$container = this.element().children().eq(0);
this.setAria({
haspopup: "true",
autocomplete: "list"
})
},
_readOnlyPropValue: function() {
return !this.option("fieldEditEnabled") || this.callBase()
},
_renderField: function() {
var fieldTemplate = this._getTemplateByOption("fieldTemplate");
if (!(fieldTemplate && this.option("fieldTemplate")))
return;
var isFocused = this._input().is(":focus");
isFocused && this._input().focusout();
this._cleanFocusState();
var $container = this._$container;
var data = this._fieldRenderData();
$container.empty();
this._$dropButton = null;
this._$clearButton = null;
fieldTemplate.render(data, $container);
if (!this._input().length)
throw DX.Error("E1010");
this._renderFocusState();
isFocused && this._input().focus()
},
_fieldRenderData: function() {
return this.option("value")
},
_renderInputAddons: function() {
this._renderField();
this.callBase();
this._renderDropButton()
},
_renderDropButton: function(hideButton) {
var dropButtonVisible = this.option("showDropButton");
this.element().toggleClass(DROP_DOWN_EDITOR_BUTTON_VISIBLE, dropButtonVisible);
if (!dropButtonVisible) {
this._$dropButton && this._$dropButton.remove();
this._$dropButton = null;
return
}
if (!this._$dropButton)
this._$dropButton = this._createDropButton().addClass(DROP_DOWN_EDITOR_BUTTON_CLASS);
this._$dropButton.prependTo(this._buttonsContainer())
},
_createDropButton: function() {
var $button = $("
");
this._createComponent($button, "dxButton", {
focusStateEnabled: false,
disabled: this.option("readOnly"),
_templates: {}
});
var $buttonIcon = $("
").addClass(DROP_DOWN_EDITOR_BUTTON_ICON);
$button.append($buttonIcon).removeClass("dx-button").on("mousedown", function(e) {
e.preventDefault()
});
$button.find(".dx-button-content").remove();
return $button
},
_renderOpenHandler: function() {
var $inputWrapper = this.element().find(".dx-dropdowneditor-input-wrapper");
$inputWrapper.off(CLICK_EVENT_NAME);
var openOnFieldClick = this.option("openOnFieldClick");
this.element().toggleClass(DROP_DOWN_EDITOR_FIELD_CLICKABLE, openOnFieldClick);
if (openOnFieldClick) {
$inputWrapper.on(events.addNamespace("mousedown", this.NAME), function(e) {
DX.devices.real().platform !== "generic" && e.preventDefault()
});
$inputWrapper.on(CLICK_EVENT_NAME, $.proxy(this._openHandler, this));
return
}
if (this.option("showDropButton"))
this._$dropButton.dxButton("option", "onClick", $.proxy(this._openHandler, this))
},
_openHandler: function() {
this._toggleOpenState()
},
_keyboardEventBindingTarget: function() {
return this._input()
},
_toggleOpenState: function(isVisible) {
if (this.option("disabled"))
return;
this._input().focus();
if (!this.option("readOnly")) {
isVisible = arguments.length ? isVisible : !this.option("opened");
this.option("opened", isVisible)
}
},
_renderOpenedState: function() {
var opened = this.option("opened");
if (opened)
this._createPopup();
this.element().toggleClass(DROP_DOWN_EDITOR_ACTIVE, opened);
this._setPopupOption("visible", opened);
this.setAria("expanded", opened)
},
_createPopup: function() {
if (this._$popup)
return;
this._$popup = $("
").addClass(DROP_DOWN_EDITOR_OVERLAY).addClass(this.option("customOverlayCssClass")).appendTo(this.element());
this._renderPopup();
this._renderPopupContent()
},
_renderPopup: function() {
this._popup = this._createComponent(this._$popup, "dxPopup", this._popupConfig());
this._popup.on({
showing: $.proxy(this._popupShowingHandler, this),
shown: $.proxy(this._popupShownHandler, this),
hiding: $.proxy(this._popupHidingHandler, this),
hidden: $.proxy(this._popupHiddenHandler, this)
});
this._popup.option("onContentReady", $.proxy(this._contentReadyHandler, this));
this._contentReadyHandler()
},
_contentReadyHandler: $.noop,
_popupConfig: function() {
return {
position: $.extend(this.option("dropPosition"), {of: this.element()}),
showTitle: this.option("showPopupTitle"),
width: "auto",
height: "auto",
shading: false,
closeOnTargetScroll: true,
closeOnOutsideClick: $.proxy(this._closeOutsideDropDownHandler, this),
animation: {
show: {
type: "fade",
duration: 0,
from: 0,
to: 1
},
hide: {
type: "fade",
duration: 400,
from: 1,
to: 0
}
},
deferRendering: false,
focusStateEnabled: false,
showCloseButton: false,
buttons: this._getPopupButtons(),
onPositioned: $.proxy(this._popupPositionedHandler, this)
}
},
_popupPositionedHandler: function(e) {
this._popup.overlayContent().toggleClass(DROP_DOWN_EDITOR_OVERLAY_FLIPPED, e.position.v.flip)
},
_popupShowingHandler: $.noop,
_popupHidingHandler: function() {
this.option("opened", false)
},
_popupShownHandler: function() {
this._openAction();
if (this._$validationMessage)
this._$validationMessage.dxTooltip("option", "position", this._getValidationTooltipPosition())
},
_popupHiddenHandler: function() {
this._closeAction();
if (this._$validationMessage)
this._$validationMessage.dxTooltip("option", "position", this._getValidationTooltipPosition())
},
_getValidationTooltipPosition: function() {
var positionRequest = "below";
if (this._popup && this._popup.option("visible")) {
var myTop = DX.position(this.element()).top,
popupTop = DX.position(this._popup.content()).top;
positionRequest = myTop + this.option("dropPosition").offset.v > popupTop ? "below" : "above"
}
return this.callBase(positionRequest)
},
_renderPopupContent: function() {
var contentTemplate = this._getTemplateByOption("contentTemplate");
if (!(contentTemplate && this.option("contentTemplate")))
return;
var $popupContent = this._popup.content();
$popupContent.empty();
contentTemplate.render($popupContent)
},
_closeOutsideDropDownHandler: function(e) {
var $target = $(e.target);
var isInputClicked = !!$target.closest(this.element()).length;
var isDropButtonClicked = !!$target.closest(this._$dropButton).length;
var isOutsideClick = !isInputClicked && !isDropButtonClicked;
return isOutsideClick
},
_clean: function() {
delete this._$dropButton;
if (this._$popup) {
this._$popup.remove();
delete this._$popup;
delete this._popup
}
this.callBase()
},
_setPopupOption: function(optionName, value) {
this._setWidgetOption("_popup", arguments)
},
_validatedOpening: function() {
if (!this.option("readOnly"))
this._toggleOpenState(true)
},
_getAriaTarget: function() {
return this._input()
},
_getPopupButtons: function() {
return this.option("applyValueMode") === "useButtons" ? this._popupButtonsConfig() : []
},
_popupButtonsConfig: function() {
var buttonsConfig = [{
shortcut: "done",
options: {
onClick: $.proxy(this._applyButtonHandler, this),
text: this.option("applyButtonText")
}
}, {
shortcut: "cancel",
options: {
onClick: $.proxy(this._cancelButtonHandler, this),
text: this.option("cancelButtonText")
}
}];
return this._applyButtonsLocation(buttonsConfig)
},
_applyButtonsLocation: function(buttonsConfig) {
var buttonsLocation = this.option("buttonsLocation"),
resultConfig = buttonsConfig;
if (buttonsLocation !== "default") {
var position = DX.utils.splitPair(buttonsLocation);
$.each(resultConfig, function(_, element) {
$.extend(element, {
toolbar: position[0],
location: position[1]
})
})
}
return resultConfig
},
_applyButtonHandler: function() {
this.close();
this.option("focusStateEnabled") && this.focus()
},
_cancelButtonHandler: function() {
this.close();
this.option("focusStateEnabled") && this.focus()
},
_optionChanged: function(args) {
switch (args.name) {
case"opened":
this._renderOpenedState();
break;
case"onOpened":
case"onClosed":
this._initVisibilityActions();
break;
case"fieldTemplate":
case"fieldRender":
this._renderInputAddons();
break;
case"showDropButton":
case"contentTemplate":
case"contentRender":
case"fieldEditEnabled":
case"openOnFieldClick":
this._invalidate();
break;
case"dropPosition":
case"deferRendering":
break;
case"applyValueMode":
case"applyButtonText":
case"cancelButtonText":
case"buttonsLocation":
this._setPopupOption("buttons", this._getPopupButtons());
break;
case"showPopupTitle":
this._setPopupOption("showTitle", args.value);
break;
default:
this.callBase(args)
}
},
open: function() {
this.option("opened", true)
},
close: function() {
this.option("opened", false)
},
reset: function() {
this.option("value", null)
},
field: function() {
return this._input()
},
content: function() {
return this._popup ? this._popup.content() : null
}
}));
ui.dxDropDownEditor.__internals = {
DROP_DOWN_EDITOR_CLASS: DROP_DOWN_EDITOR_CLASS,
DROP_DOWN_EDITOR_READONLY_CLASS: DROP_DOWN_EDITOR_READONLY_CLASS,
DROP_DOWN_EDITOR_BUTTON_ICON: DROP_DOWN_EDITOR_BUTTON_ICON,
DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS: DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS,
DROP_DOWN_EDITOR_BUTTON_CLASS: DROP_DOWN_EDITOR_BUTTON_CLASS,
DROP_DOWN_EDITOR_OVERLAY: DROP_DOWN_EDITOR_OVERLAY,
DROP_DOWN_EDITOR_ACTIVE: DROP_DOWN_EDITOR_ACTIVE,
DROP_DOWN_EDITOR_BUTTON_VISIBLE: DROP_DOWN_EDITOR_BUTTON_VISIBLE
}
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.dropDownList.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils;
var LIST_ITEM_SELECTOR = ".dx-list-item",
LIST_ITEM_DATA_KEY = "dxListItemData",
DROPDOWNLIST_SELECTED_CLASS = "dx-dropdownlist-selected",
DROPDOWNLIST_POPUP_WRAPPER_CLASS = "dx-dropdownlist-popup-wrapper",
SEARCH_MODES = ["startswith", "contains", "endwith", "notcontains"];
DX.registerComponent("dxDropDownList", ui, ui.dxDropDownEditor.inherit({
_supportedKeys: function() {
return $.extend(this.callBase(), {
tab: function(e) {
if (this.option("opened") === true) {
var $focusedItem = this._list.option("focusedElement");
if ($focusedItem) {
var $selectedItem = this._listSelectedItemElements();
this._changeSelectedItem($selectedItem, $focusedItem);
this.option("value", this._selectedItemValue())
}
this.close()
}
else
this._focusTarget().focusout()
},
space: $.noop,
home: $.noop,
end: $.noop
})
},
_setDeprecatedOptions: function() {
this.callBase();
$.extend(this._deprecatedOptions, this._dataExpressionDeprecatedOptions(), {pagingEnabled: {
since: "15.1",
message: "Use the 'dataSource.paginate' option instead"
}})
},
_setDefaultOptions: function() {
this.callBase();
this.option($.extend(this._dataExpressionDefaultOptions(), {
displayValue: undefined,
searchEnabled: false,
searchMode: "contains",
searchTimeout: 500,
minSearchLength: 0,
searchExpr: null,
valueChangeEvent: "change keyup",
selectedItem: null,
pagingEnabled: undefined,
noDataText: Globalize.localize("dxCollectionWidget-noDataText"),
onSelectionChanged: null,
onItemClick: $.noop,
dropPosition: {
my: "left top",
at: "left bottom",
offset: {
h: 0,
v: 0
},
collision: "flip"
},
popupWidthExtension: 0
}))
},
_defaultOptionsRules: function() {
return this.callBase().concat([{
device: {platform: "win8"},
options: {dropPosition: {offset: {v: -6}}}
}, {
device: function(device) {
return device.platform === "android"
},
options: {popupWidthExtension: 32}
}])
},
_setOptionsByReference: function() {
this.callBase();
$.extend(this._optionsByReference, {
value: true,
selectedItem: true,
displayValue: true
})
},
_init: function() {
this.callBase();
this._initDataExpressions();
this._initActions();
this._setListDataSource();
this._validateSearchMode();
this._clearSelectedItem()
},
_initActions: function() {
this._initContentReadyAction();
this._initSelectionChangedAction();
this._initItemClickAction()
},
_initContentReadyAction: function() {
this._contentReadyAction = this._createActionByOption("onContentReady")
},
_initSelectionChangedAction: function() {
this._selectionChangedAction = this._createActionByOption("onSelectionChanged", {excludeValidators: ["disabled", "readOnly"]})
},
_initItemClickAction: function() {
this._itemClickAction = this._createActionByOption("onItemClick")
},
_renderContentImpl: function() {
this.callBase();
if (this.option("deferRendering"))
this._loadDataSource()
},
_renderField: function() {
this.callBase();
this._input().on("input", $.proxy(this._setFocusPolicy, this))
},
_preventFocusOnPopup: function(e) {
if (this._list && this._list.initialOption("focusStateEnabled"))
e.preventDefault()
},
_createPopup: function() {
this.callBase();
this._popup._wrapper().addClass(this._popupWrapperClass());
this._popup.content().off("mousedown").on("mousedown", $.proxy(this._preventFocusOnPopup, this))
},
_popupWrapperClass: function() {
return DROPDOWNLIST_POPUP_WRAPPER_CLASS
},
_renderInputValue: function() {
var callBase = $.proxy(this.callBase, this);
return this._loadItem(this.option("value")).always($.proxy(function(item) {
this._setSelectedItem(item);
this._refreshSelected();
callBase()
}, this))
},
_loadItem: function(value) {
var selectedItem = $.grep(this.option("items") || [], $.proxy(function(item) {
return this._isValueEquals(this._valueGetter(item), value)
}, this))[0];
return selectedItem !== undefined ? $.Deferred().resolve(selectedItem).promise() : this._loadValue(value)
},
_setSelectedItem: function(item) {
var displayValue = this._displayValue(item);
this.option("selectedItem", item);
this.option("displayValue", displayValue)
},
_displayValue: function(item) {
return this._displayGetter(item)
},
_refreshSelected: function() {
this._listItemElements().each($.proxy(function(_, itemElement) {
var $itemElement = $(itemElement);
var itemValue = this._valueGetter($itemElement.data(LIST_ITEM_DATA_KEY));
var isItemSelected = this._isSelectedValue(itemValue);
$itemElement.toggleClass(this._selectedItemClass(), isItemSelected);
if (isItemSelected)
this._list.selectItem($itemElement);
else
this._list.unselectItem($itemElement)
}, this))
},
_popupShownHandler: function() {
this.callBase();
this._setFocusPolicy()
},
_setFocusPolicy: function() {
if (!this.option("focusStateEnabled") || !this._list)
return;
this._list.option("focusedElement", null)
},
_isSelectedValue: function(value) {
return this._isValueEquals(value, this.option("value"))
},
_validateSearchMode: function() {
var searchMode = this.option("searchMode"),
normalizedSearchMode = searchMode.toLowerCase();
if ($.inArray(normalizedSearchMode, SEARCH_MODES) < 0)
throw DX.Error("E1019", searchMode);
},
_clearSelectedItem: function() {
this.option("selectedItem", null)
},
_processDataSourceChanging: function() {
this._setListDataSource();
this._renderInputValue().fail($.proxy(this.reset, this))
},
reset: function() {
this.option("value", null);
this._clearSelectedItem()
},
_selectedItemClass: function() {
return DROPDOWNLIST_SELECTED_CLASS
},
_listItemElements: function() {
return this._$list ? this._$list.find(LIST_ITEM_SELECTOR) : $()
},
_listSelectedItemElements: function() {
return this._$list ? this._$list.find("." + this._selectedItemClass()) : $()
},
_popupConfig: function() {
return $.extend(this.callBase(), {width: this.option("width")})
},
_renderPopupContent: function() {
this._renderList()
},
_attachChildKeyboardEvents: function() {
this._childKeyboardProcessor = this._keyboardProcessor.attachChildProcessor();
this._setListOption("_keyboardProcessor", this._childKeyboardProcessor)
},
_fireContentReadyAction: $.noop,
_renderList: function() {
var listId = (new DevExpress.data.Guid)._value,
$list = this._$list = $("
", {id: listId}).appendTo(this._popup.content());
this._list = this._createComponent($list, "dxList", this._listConfig());
this.setAria({
activedescendant: this._list.getFocusedItemId(),
owns: listId
});
this._refreshList()
},
_refreshList: function() {
if (this._list && this._shouldRefreshDataSource())
this._setListDataSource()
},
_shouldRefreshDataSource: function() {
var dataSourceProvided = !!this._list.option("dataSource");
return dataSourceProvided !== this._isMinFilterLengthExceeded()
},
_refreshActiveDescendant: function() {
this.setAria("activedescendant", "");
this.setAria("activedescendant", this._list.getFocusedItemId())
},
_listConfig: function() {
return {
_templates: this.option("_templates"),
templateProvider: this.option("templateProvider"),
noDataText: this.option("noDataText"),
onContentReady: $.proxy(this._listContentReadyHandler, this),
itemTemplate: this._getTemplateByOption("itemTemplate"),
indicateLoading: false,
tabIndex: -1,
onItemClick: $.proxy(this._listItemClickAction, this),
dataSource: this._isMinFilterLengthExceeded() ? this._dataSource : null,
_keyboardProcessor: this._childKeyboardProcessor,
onOptionChanged: $.proxy(function(args) {
if (args.name === "focusedElement")
this._refreshActiveDescendant()
}, this)
}
},
_dataSourceOptions: function() {
this._suppressDeprecatedWarnings();
var pagingEnabled = this.option("pagingEnabled");
this._resumeDeprecatedWarnings();
return {paginate: utils.ensureDefined(pagingEnabled, false)}
},
_listContentReadyHandler: function() {
this._list = this._list || this._$list.dxList("instance");
this.option().items = this._list.option("items");
this._refreshSelected();
this._dimensionChanged();
this._contentReadyAction()
},
_setListOption: function(optionName, value) {
this._setWidgetOption("_list", arguments)
},
_listItemClickAction: function(e) {
this._listItemClickHandler(e);
this._itemClickAction(e)
},
_listItemClickHandler: $.noop,
_setListDataSource: function() {
if (!this._list)
return;
var isMinFilterLengthExceeded = this._isMinFilterLengthExceeded();
this._setListOption("dataSource", isMinFilterLengthExceeded ? this._dataSource : null);
if (!isMinFilterLengthExceeded)
this._setListOption("items", [])
},
_isMinFilterLengthExceeded: function() {
return this._searchValue().toString().length >= this.option("minSearchLength")
},
_searchValue: function() {
return this._input().val() || ""
},
_search: function() {
if (!this._isMinFilterLengthExceeded()) {
this._searchCanceled();
return
}
var searchTimeout = this.option("searchTimeout");
if (searchTimeout) {
if (!this._searchTimer)
this._searchTimer = setTimeout($.proxy(this._searchDataSource, this), searchTimeout)
}
else
this._searchDataSource()
},
_searchCanceled: function() {
this._clearSearchTimer();
this._refreshList()
},
_searchDataSource: function() {
this._filterDataSource(this._searchValue())
},
_filterDataSource: function(searchValue) {
var dataSource = this._dataSource;
dataSource.searchExpr(this.option("searchExpr") || this._displayGetterExpr());
dataSource.searchOperation(this.option("searchMode"));
dataSource.searchValue(searchValue);
dataSource.pageIndex(0);
return dataSource.load().done($.proxy(this._dataSourceFiltered, this))
},
_clearFilter: function() {
this._dataSource.searchValue("")
},
_dataSourceFiltered: function() {
this._clearSearchTimer();
this._refreshList();
this._refreshPopupVisibility()
},
_refreshPopupVisibility: function() {
this.option("opened", this._hasItemsToShow());
if (this.option("opened"))
this._dimensionChanged()
},
_hasItemsToShow: function() {
var resultItems = this._dataSource && this._dataSource.items() || [];
var resultAmount = resultItems.length;
var isMinFilterLengthExceeded = this._isMinFilterLengthExceeded();
return isMinFilterLengthExceeded && resultAmount && this.element().hasClass("dx-state-focused")
},
_clearSearchTimer: function() {
clearTimeout(this._searchTimer);
delete this._searchTimer
},
_popupShowingHandler: function() {
this._dimensionChanged()
},
_dimensionChanged: function() {
this._popup && this._updatePopupDimensions()
},
_updatePopupDimensions: function() {
this._updatePopupWidth();
this._updatePopupHeight()
},
_updatePopupWidth: function() {
this._setPopupOption("width", this.element().outerWidth() + this.option("popupWidthExtension"))
},
_updatePopupHeight: function() {
var popupPadding = this._popup.overlayContent().outerHeight() - this._popup.content().height();
var listMargin = this._list ? this._list.element().outerHeight() - this._list.clientHeight() : 0;
var listHeight = this._list ? this._list.scrollHeight() + listMargin : 0;
var popupHeight = Math.min(listHeight + popupPadding, this._getMaxHeight());
this._setPopupOption("height", popupHeight);
this._list && this._list.updateDimensions()
},
_getMaxHeight: function() {
var $element = this.element(),
offset = $element.offset(),
windowHeight = $(window).height(),
maxHeight = Math.max(offset.top, windowHeight - offset.top - $element.outerHeight());
return Math.min(windowHeight * 0.5, maxHeight)
},
_changeSelectedItem: function($selectedItem, $newItem) {
var selectedItemClass = this._selectedItemClass();
$selectedItem.removeClass(selectedItemClass);
$newItem.addClass(selectedItemClass)
},
_selectedItemValue: function() {
var $selectedItem = this._listSelectedItemElements();
return this._valueGetter($selectedItem.data(LIST_ITEM_DATA_KEY))
},
_valueChangeArgs: function() {
return $.extend(this.callBase.apply(this, arguments), {
selectedItem: this.option("selectedItem"),
itemData: this.option("selectedItem")
})
},
_clean: function() {
if (this._list)
delete this._list;
this.callBase()
},
_dispose: function() {
this._clearSearchTimer();
this.callBase()
},
_setCollectionWidgetOption: function() {
this._setListOption.apply(this, arguments)
},
_optionChanged: function(args) {
this._dataExpressionOptionChanged(args);
switch (args.name) {
case"items":
if (!this.option("dataSource"))
this._processDataSourceChanging();
break;
case"dataSource":
this._processDataSourceChanging();
break;
case"valueExpr":
case"displayExpr":
this._renderValue();
break;
case"searchMode":
this._validateSearchMode();
break;
case"minSearchLength":
this._refreshList();
break;
case"searchEnabled":
case"searchExpr":
case"pagingEnabled":
this._invalidate();
break;
case"onContentReady":
this._initContentReadyAction();
break;
case"onSelectionChanged":
this._initSelectionChangedAction();
break;
case"onItemClick":
this._initItemClickAction();
break;
case"noDataText":
this._setListOption("noDataText");
break;
case"displayValue":
this.option("text", args.value);
break;
case"itemTemplate":
case"searchTimeout":
case"popupWidthExtension":
break;
case"selectedItem":
this._selectionChangedAction({selectedItem: args.value});
break;
default:
this.callBase(args)
}
}
}).include(ui.DataExpressionMixin))
})(jQuery, DevExpress);
/*! Module widgets-base, file ui.textArea.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var TEXTAREA_CLASS = "dx-textarea",
TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input";
DX.registerComponent("dxTextArea", ui, ui.dxTextBox.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({spellcheck: true})
},
_render: function() {
this.callBase();
this.element().addClass(TEXTAREA_CLASS);
this.setAria("multiline", "true")
},
_renderInput: function() {
this.callBase();
this._renderScrollHandler()
},
_createInput: function() {
return $("