PageSourceSearch

https://routenetwerk.nl/DXR.axd?r=1_11,1_12,1_13,1_40,1_15,1_22,1_…9,1_192,23_38,1_6,23_53,1_203-Tkqku&order=1

js routenetwerk.nl collected 2026-10-01 14:20:51 UTC 1,596,748 bytes, 40,207 lines download raw bytes

1ASPx.IS(function(ASPx, dx, DevExpress){
2(function() {
3var CheckingScriptObjectCommand = ASPx.CreateClass(null, {
4 constructor: function(scriptName, markerObjectName) {
5  this.scriptName = scriptName;
6  this.markerObjectName = markerObjectName;
7  this.isExisted = false;
8 },
9 Run: function() {
10  var markerObj = this.GetMarkerObject();
11  this.isExisted = !!markerObj;
12  if(this.isExisted)
13   markerObj.DXPatched = true;
14 },
15 GetErrorMessage: function() {
16  return this.GetErrorMessageCore(true);
17 },
18 GetErrorMessageCore: function(isScriptRequired){
19  var markerObj = this.GetMarkerObject();
20  if(this.isExisted && markerObj && markerObj.DXPatched || !isScriptRequired && !markerObj)
21   return null;
22  if(isScriptRequired && !this.GetMarkerObject()){
23   if(this.isExisted)
24    return this.scriptName + " script was attached but has been overridden.";
25   else
26    return this.scriptName + " script was not attached.";
27  }
28  if(!this.isExisted)
29   return this.scriptName + " script was attached after DevExpress scripts.";
30  return this.scriptName + " script was attached multiple times and mixed up with DevExpress scripts.";
31 },
32 GetMarkerObject: function() {
33  return ASPx.GetGlobalObject(this.markerObjectName);
34 }
35});
36var PatchScriptCommand = ASPx.CreateClass(CheckingScriptObjectCommand, {
37 constructor: function(scriptName, markerObjectName, patchMethod, required) {
38  this.constructor.prototype.constructor.call(this, scriptName, markerObjectName);
39  this.required = required;
40  this.patchMethod = patchMethod;
41 },
42 Run: function() {
43  CheckingScriptObjectCommand.prototype.Run.call(this);
44  if(this.isExisted)
45   this.patchMethod();
46 },
47 GetErrorMessage: function() {  
48  return this.GetErrorMessageCore(this.required);
49 }
50});
51var ExternalScriptProcessor = ASPx.CreateClass(null, {
52 constructor: function() {
53  this.commands = {};
54 },
55 Process: function(scriptName, markerObjectName, patchMethod, required) {
56  var newCommand = this.CreateCommand(scriptName, markerObjectName, patchMethod, !!required);
57  var oldCommand = this.commands[markerObjectName];
58  if(oldCommand) {
59   if(!oldCommand.patchMethod && !newCommand.patchMethod)
60    newCommand = null;
61   else if(newCommand.patchMethod && (!oldCommand.patchMethod || oldCommand.required))
62    newCommand.required = true;
63   else if(oldCommand.patchMethod && !newCommand.patchMethod) {
64    oldCommand.required = true;
65    newCommand = null;
66   }
67  }
68  if(newCommand) {
69   this.commands[markerObjectName] = newCommand;
70   newCommand.Run();
71  }
72 },
73 CreateCommand: function(scriptName, markerObjectName, patchMethod, required) {
74  if(patchMethod)
75   return new PatchScriptCommand(scriptName, markerObjectName, patchMethod, required);
76  return new CheckingScriptObjectCommand(scriptName, markerObjectName);
77 },
78 ShowErrorMessages: function() {
79  var messages = this.GetErrorMessages();
80  var console = window.console;
81  if(!messages.length || !console || !ASPx.IsFunction(console.error))
82   return;
83  for(var i = 0; i < messages.length; i++) {
84   console.error(messages[i]);
85  }
86  ASPx.ShowKBErrorMessage("Please check the correctness of script registration on the page. For details, see ", "T272309");
87 },
88 GetErrorMessages: function() {
89  var messages = [];
90  for (var key in this.commands) {
91   if (this.commands.hasOwnProperty(key)) {
92    var message = this.commands[key].GetErrorMessage();
93    if (message)
94     messages.push(message);
95   }
96  }
97  return messages;
98 }
99});
100ExternalScriptProcessor.Instance = null;
101ExternalScriptProcessor.getInstance = function() {
102 if(!ExternalScriptProcessor.Instance)
103  ExternalScriptProcessor.Instance = new ExternalScriptProcessor();
104 return ExternalScriptProcessor.Instance;
105};
106ASPx.ExternalScriptProcessor = ExternalScriptProcessor;
107})();
108(function module(ASPx) {
109ASPx.modules.Controls = module;
110var ASPxClientBeginCallbackEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
111 constructor: function(command){
112  this.constructor.prototype.constructor.call(this);
113  this.command = command;
114 }
115});
116var ASPxClientGlobalBeginCallbackEventArgs = ASPx.CreateClass(ASPxClientBeginCallbackEventArgs, {
117 constructor: function(control, command){
118  this.constructor.prototype.constructor.call(this, command);
119  this.control = control;
120 }
121});
122var ASPxClientEndCallbackEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
123 constructor: function(command){
124  this.constructor.prototype.constructor.call(this);
125  this.command = command;
126 }
127});
128var ASPxClientGlobalEndCallbackEventArgs = ASPx.CreateClass(ASPxClientEndCallbackEventArgs, {
129 constructor: function(control){
130  this.constructor.prototype.constructor.call(this);
131  this.control = control;
132 }
133});
134var ASPxClientCustomDataCallbackEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
135 constructor: function(result) {
136  this.constructor.prototype.constructor.call(this);
137  this.result = result;
138 }
139});
140var ASPxClientCallbackErrorEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
141 constructor: function (message, callbackId) {
142  this.constructor.prototype.constructor.call(this);
143  this.message = message;
144  this.handled = false;
145  this.callbackId = callbackId;
146 }
147});
148var ASPxClientGlobalCallbackErrorEventArgs = ASPx.CreateClass(ASPxClientCallbackErrorEventArgs, {
149 constructor: function (control, message, callbackId) {
150  this.constructor.prototype.constructor.call(this, message, callbackId);
151  this.control = control;
152 }
153});
154var ASPxClientValidationCompletedEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
155 constructor: function (container, validationGroup, invisibleControlsValidated, isValid, firstInvalidControl, firstVisibleInvalidControl) {
156  this.constructor.prototype.constructor.call(this);
157  this.container = container;
158  this.validationGroup = validationGroup;
159  this.invisibleControlsValidated = invisibleControlsValidated;
160  this.isValid = isValid;
161  this.firstInvalidControl = firstInvalidControl;
162  this.firstVisibleInvalidControl = firstVisibleInvalidControl;
163 }
164});
165var ASPxClientControlsInitializedEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
166 constructor: function(isCallback) {
167  this.isCallback = isCallback;
168 }
169});
170var ASPxClientControlBeforePronounceEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
171 constructor: function(messageParts, control){
172  this.constructor.prototype.constructor.call(this);
173  this.messageParts = messageParts;
174  this.control = control;
175 }
176});
177var ASPxClientControlUnloadEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
178 constructor: function(control){
179  this.constructor.prototype.constructor.call(this);
180  this.control = control;
181 }
182});
183var ASPxClientEndFocusEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
184 constructor: function(item) {
185  this.constructor.prototype.constructor.call(this);
186  this.item = item;
187 }
188});
189var ASPxClientItemFocusedEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
190 constructor: function(item) {
191  this.constructor.prototype.constructor.call(this);
192  this.item = item;
193 }
194});
195var BeforeInitCallbackEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
196 constructor: function(callbackOwnerID){
197  this.constructor.prototype.constructor.call(this);
198  this.callbackOwnerID = callbackOwnerID;
199 }
200});
201var ASPxClientBrowserWindowResizedInternalEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
202 constructor: function(eventInfo) {
203  this.constructor.prototype.constructor.call(this);
204  this.htmlEvent = eventInfo.htmlEvent;
205  this.windowClientWidth = eventInfo.wndWidth;
206  this.windowClientHeigth = eventInfo.wndHeight;
207  this.previousWindowClientWidth = eventInfo.prevWndWidth;
208  this.previousWindowClientHeight = eventInfo.prevWndHeight;
209  this.virtualKeyboardShownOnAndroid = eventInfo.virtualKeyboardShownOnAndroid;
210 }
211});
212ASPx.createControl = function(type, name, windowName, properties, events, setupMethod, data){
213 var globalName = windowName && windowName.length > 0 ? windowName : name;
214 var dxo = new type(name);
215 var haveWrapper = ASPx.Platform === "NETCORE" && dxo.createWrapper && !DevExpress.AspNetCore.Internal.BackwardCompatibility.useLegacyClientAPI;
216 if(haveWrapper) {
217  window[globalName] = dxo.createWrapper();
218  dxo.aspNetCoreWrapperInstance = window[globalName];
219 }
220 else
221  dxo.InitGlobalVariable(globalName);
222 if(properties)
223  dxo.SetProperties(properties);
224 if(events)
225  dxo.SetEvents(events);
226 if(setupMethod)
227  setupMethod.call(dxo);
228 if(data)
229  dxo.SetData(data);
230 dxo.AfterCreate();
231};
232var ASPxClientControlBase = ASPx.CreateClass(null, {
233 constructor: function(name){
234  this.name = name;
235  this.uniqueID = name;   
236  this.globalName = name;
237  this.stateObject = null;
238  this.needEncodeState = true;
239  this.encodeHtml = true;
240  this.enabled = true;
241  this.clientEnabled = true;
242  this.savedClientEnabled = true;
243  this.clientVisible = true;
244  this.accessibilityCompliant = false;
245  this.parseJSPropertiesOnCallbackError = false;
246  this.autoPostBack = false;
247  this.allowMultipleCallbacks = true;
248  this.callBack = null;
249  this.enableCallbackAnimation = false;
250  this.enableSlideCallbackAnimation = false;
251  this.slideAnimationDirection = null;
252  this.beginCallbackAnimationProcessing = false;
253  this.endCallbackAnimationProcessing = false;
254  this.savedCallbackResult = null;
255  this.savedCallbacks = null;
256  this.isCallbackAnimationPrevented = false;
257  this.lpDelay = 300;
258  this.lpTimer = -1;
259  this.requestCount = 0;
260  this.enableSwipeGestures = false;
261  this.disableSwipeGestures = false;
262  this.supportGestures = false;
263  this.repeatedGestureValue = 0;
264  this.repeatedGestureCount = 0;
265  this.isInitialized = false;
266  this.initialFocused = false;
267  this.leadingAfterInitCall = ASPxClientControl.LeadingAfterInitCallConsts.None; 
268  this.serverEvents = [];
269  this.loadingPanelElement = null;
270  this.loadingDivElement = null;  
271  this.hasPhantomLoadingElements = false;
272  this.mainElement = null;
273  this.touchUIMouseScroller = null;
274  this.hiddenFields = {};
275  this.scPrefix = "dx";
276  this.callbackHandlersQueue = new ASPx.ControlCallbackHandlersQueue(this);
277  this.callbackCommand = {};
278  this.currentCallbackID = -1;
279  this.InitializeIntersectionObserversManager();
280  this.Init = new ASPxClientEvent();
281  this.BeginCallback = new ASPxClientEvent();
282  this.EndCallback = new ASPxClientEvent();
283  this.EndCallbackAnimationStart = new ASPxClientEvent();
284  this.CallbackError = new ASPxClientEvent();
285  this.CustomDataCallback = new ASPxClientEvent();
286  this.BeforePronounce = new ASPxClientEvent();
287  this.Unload = new ASPxClientEvent();
288  this.Disposed = new ASPxClientEvent(); 
289  aspxGetControlCollection().Add(this);
290 },
291 Initialize: function() {
292  if(this.callBack != null)
293   this.InitializeCallBackData();
294  if (this.useCallbackQueue())
295   this.callbackQueueHelper = new ASPx.ControlCallbackQueueHelper(this);
296  ASPx.AccessibilityUtils.createAccessibleBackgrounds(this);
297  if(this.accessibilityCompliant)
298   ASPx.AccessibilityPronouncer.EnsureInitialize();
299 },
300 FinalizeInitialization: function() { },
301 InlineInitialize: function() {
302  this.savedClientEnabled = this.clientEnabled;
303 },
304 InitializeGestures: function() {
305  if(this.isSwipeGesturesEnabled() && this.supportGestures) {
306   ASPx.GesturesHelper.AddSwipeGestureHandler(this.name, 
307    function() { return this.GetCallbackAnimationElement(); }.aspxBind(this), 
308    function(evt) { return this.CanHandleGestureCore(evt); }.aspxBind(this), 
309    function(value) { return this.AllowStartGesture(value); }.aspxBind(this),
310    function(value) { return this.StartGesture(); }.aspxBind(this),
311    function(value) { return this.AllowExecuteGesture(value); }.aspxBind(this),
312    function(value) { this.ExecuteGesture(value); }.aspxBind(this),
313    function(value) { this.CancelGesture(value); }.aspxBind(this),
314    this.GetDefaultanimationEngineType(),
315    this.rtl
316   );
317   if(ASPx.Browser.MSTouchUI)
318    this.touchUIMouseScroller = ASPx.MouseScroller.Create(
319     function() { return this.GetCallbackAnimationElement(); }.aspxBind(this),
320     function() { return null; },
321     function() { return this.GetCallbackAnimationElement(); }.aspxBind(this),
322     function(element) { return this.NeedPreventTouchUIMouseScrolling(element); }.aspxBind(this),
323     true
324    );
325  }
326 },
327 isSwipeGesturesEnabled: function() {
328  return !this.disableSwipeGestures && (this.enableSwipeGestures || ASPx.Browser.TouchUI);
329 },
330 isSlideCallbackAnimationEnabled: function() {
331  return this.enableSlideCallbackAnimation || this.isSwipeGesturesEnabled(); 
332 },
333 InitGlobalVariable: function(varName){
334  if(!window) return;
335  this.globalName = varName;
336  window[varName] = this;
337 },
338 SetElementDisplay: function(element, value, checkCurrentStyle, makeInline) {
339  ASPx.SetElementDisplay(element, value, checkCurrentStyle, makeInline);
340 },
341 SetProperties: function(properties, obj){
342  if(!obj) obj = this;
343  var isAspNetCoreWrapperInstanceExist = !!obj.aspNetCoreWrapperInstance;
344  for(var name in properties){
345   if(!properties.hasOwnProperty(name)) continue;
346   obj[name] = properties[name];
347   if(isAspNetCoreWrapperInstanceExist && name.indexOf("cp") === 0)
348    obj.aspNetCoreWrapperInstance[name] = properties[name]; 
349  }
350 },
351 SetEvents: function(events, obj){
352  if(!obj) obj = this;
353  for(var name in events){
354   if(events.hasOwnProperty(name) && obj[name] && obj[name].AddHandler)
355    obj[name].AddHandler(events[name]);
356  }
357 },
358 SetData: function(data){
359 },
360 useCallbackQueue: function(){
361  return false;
362 },
363 NeedPreventTouchUIMouseScrolling: function(element) {
364  return false;
365 },
366 InitializeFocus: function() {
367  if(this.initialFocused && this.IsVisible()) {
368   if(ASPxClientUtils.iOSPlatform || ASPxClientUtils.androidPlatform)
369    setTimeout(function() { this.Focus(); }.bind(this), ASPx.FOCUS_TIMEOUT);
370   else
371    this.Focus();
372  }
373 },
374 AfterCreate: function() {
375  this.AddDefaultStateControllerItems();
376  this.InlineInitialize();
377  this.InitializeGestures();
378 },
379 AfterInitialize: function() {
380  this.initializeAriaDescriptor();
381  this.InitializeFocus();
382  this.isInitialized = true;
383  this.RaiseInit();
384  if(this.savedCallbacks) {
385   for(var i = 0; i < this.savedCallbacks.length; i++) 
386    this.CreateCallbackInternal(this.savedCallbacks[i].arg, this.savedCallbacks[i].command, 
387     false, this.savedCallbacks[i].callbackInfo);
388   this.savedCallbacks = null;
389  }
390 },
391 InitializeCallBackData: function() {
392 },
393 AtlasPreInitialize: function() {
394 },
395 AtlasInitialize: function() {
396 },
397 IsDOMDisposed: function() { 
398  return !ASPx.IsExistsElement(this.GetMainElement());
399 },
400 initializeAriaDescriptor: function() {
401  if(this.ariaDescription) {
402   var descriptionObject = ASPx.Json.Eval(this.ariaDescription);
403   if(descriptionObject) {
404    this.ariaDescriptor = new AriaDescriptor(this, descriptionObject);
405    this.applyAccessibilityAttributes(this.ariaDescriptor); 
406   }
407  }
408 },
409 applyAccessibilityAttributes: function() { },
410 setAriaDescription: function(selector, argsList) {
411  if(this.ariaDescriptor)
412   this.ariaDescriptor.setDescription(selector, argsList || [[]]);
413 },
414 allowRestoreFocusOnCallbacks: function(){
415  return this.accessibilityCompliant;
416 },
417 HtmlEncode: function(text) {
418  return this.encodeHtml ? ASPx.Str.EncodeHtml(text) : text;
419 },
420 IsServerEventAssigned: function(eventName){
421  return ASPx.Data.ArrayIndexOf(this.serverEvents, eventName) >= 0;
422 },
423 OnPost: function(args){
424  this.SerializeStateHiddenField();
425 },
426 SerializeStateHiddenField: function() {
427  this.UpdateStateObject();
428  if(this.stateObject != null)
429   this.UpdateStateHiddenField();
430 },
431 OnPostFinalization: function(args){
432 },
433 UpdateStateObject: function(){
434 },
435 UpdateStateObjectWithObject: function(obj){
436  if(!obj) return;
437  if(!this.stateObject)
438   this.stateObject = { };
439  for(var key in obj)
440   if(obj.hasOwnProperty(key))
441    this.stateObject[key] = obj[key];
442 },
443 UpdateStateHiddenField: function() {
444  var stateHiddenField = this.GetStateHiddenField();
445  if(stateHiddenField) {
446   var stateObjectStr = ASPx.Json.ToJson(this.stateObject, !this.needEncodeState);
447   stateHiddenField.value = this.needEncodeState ? ASPx.Str.EncodeHtml(stateObjectStr) : stateObjectStr;
448  }
449 },
450 GetStateHiddenField: function() {
451  return this.GetHiddenField(this.GetStateHiddenFieldName(), this.GetStateHiddenFieldID(), 
452   this.GetStateHiddenFieldParent(), this.GetStateHiddenFieldOrigin());
453 },
454 GetStateHiddenFieldName: function() {
455  return this.uniqueID;
456 },
457 GetStateHiddenFieldID: function() {
458  return this.name + "_State";
459 },
460 GetStateHiddenFieldOrigin: function() {
461  return this.GetMainElement();
462 },
463 GetStateHiddenFieldParent: function() {
464  var element = this.GetStateHiddenFieldOrigin();
465  return element ? element.parentNode : null;
466 },
467 GetHiddenField: function(name, id, parent, beforeElement) {
468  var hiddenField = this.hiddenFields[id];
469  if(!hiddenField || !ASPx.IsValidElement(hiddenField)) {
470   if(parent) {
471    var existingHiddenField = ASPx.GetElementById(this.GetStateHiddenFieldID());
472    this.hiddenFields[id] = hiddenField = existingHiddenField || ASPx.CreateHiddenField(name, id);
473    if(existingHiddenField)
474     return existingHiddenField;
475    if(beforeElement)
476     parent.insertBefore(hiddenField, beforeElement);
477    else
478     parent.appendChild(hiddenField);
479   }
480  }
481  return hiddenField;
482 },
483 GetChildElement: function(idPostfix){
484  var mainElement = this.GetMainElement();
485  if(idPostfix.charAt && idPostfix.charAt(0) !== "_")
486   idPostfix = "_" + idPostfix;
487  return mainElement ? ASPx.CacheHelper.GetCachedChildById(this, mainElement, this.name + idPostfix) : null;
488 },
489 getChildControl: function(idPostfix) {
490  var result = null;
491  var childControlId = this.getChildControlUniqueID(idPostfix);
492  ASPx.GetControlCollection().ProcessControlsInContainer(this.GetMainElement(), function(control) {
493   if(control.uniqueID == childControlId)
494    result = control;
495  });
496  return result;  
497 },
498 getChildControlUniqueID: function(idPostfix) {
499  idPostfix = idPostfix.split("_").join("$");
500  if(idPostfix.charAt && idPostfix.charAt(0) !== "$")
501   idPostfix = "$" + idPostfix;
502  return this.uniqueID + idPostfix;  
503 },
504 getInnerControl: function(idPostfix) {
505  var name = this.name + idPostfix;
506  var result = window[name];
507  return result && Ident.IsASPxClientControl(result)
508   ? result
509   : null;
510 },
511 GetParentForm: function(){
512  return ASPx.GetParentByTagName(this.GetMainElement(), "FORM");
513 },
514 GetMainElement: function(){
515  if(!ASPx.IsExistsElement(this.mainElement))
516   this.mainElement = ASPx.GetElementById(this.GetMainElementId());
517  return this.mainElement;
518 },
519 GetMainElementId: function() {
520  return this.name;
521 },
522 IsLoadingContainerVisible: function(){
523  return this.IsVisible();
524 },
525 GetLoadingPanelElement: function(){
526  return ASPx.GetElementById(this.name + "_LP");
527 },
528 GetClonedLoadingPanel: function(){
529  return document.getElementById(this.GetLoadingPanelElement().id + "V"); 
530 },
531 CloneLoadingPanel: function(element, parent) {
532  var clone = element.cloneNode(true);
533  clone.id = element.id + "V";
534  parent.appendChild(clone);
535  return clone;
536 },
537 CreateLoadingPanelWithoutBordersInsideContainer: function(container) {
538  var loadingPanel = this.CreateLoadingPanelInsideContainer(container, false, true, true);
539  var contentStyle = ASPx.GetCurrentStyle(container);
540  if(!loadingPanel || !contentStyle)
541   return;
542  var elements = [ ];
543  var table = (loadingPanel.tagName == "TABLE") ? loadingPanel : ASPx.GetNodeByTagName(loadingPanel, "TABLE", 0);
544  if(table != null)
545   elements.push(table);
546  else
547   elements.push(loadingPanel);
548  var cells = ASPx.GetNodesByTagName(loadingPanel, "TD");
549  if(!cells) cells = [ ];
550  for(var i = 0; i < cells.length; i++)
551   elements.push(cells[i]);
552  for(var i = 0; i < elements.length; i++) {
553   var el = elements[i];
554   el.style.backgroundColor = contentStyle.backgroundColor;
555   ASPx.RemoveBordersAndShadows(el);
556  }
557 },
558 CreateLoadingPanelInsideContainer: function(parentElement, hideContent, collapseHeight, collapseWidth) {
559  if(this.ShouldHideExistingLoadingElements())
560   this.HideLoadingPanel();
561  if(parentElement == null)
562   return null;
563  if(!this.IsLoadingContainerVisible()) {
564   this.hasPhantomLoadingElements = true;
565   return null;
566  }
567  var element = this.GetLoadingPanelElement();
568  if(element != null){
569   var width = collapseWidth ? 0 : ASPx.GetClearClientWidth(parentElement);
570   var height = collapseHeight ? 0 : ASPx.GetClearClientHeight(parentElement);
571   if(hideContent){
572    for(var i = parentElement.childNodes.length - 1; i > -1; i--){
573     if(parentElement.childNodes[i].style)
574      parentElement.childNodes[i].style.display = "none";
575     else if(parentElement.childNodes[i].nodeType == 3) 
576      parentElement.removeChild(parentElement.childNodes[i]);
577    }
578   }
579   else
580    parentElement.innerHTML = "";
581   var table = document.createElement("TABLE");
582   parentElement.appendChild(table);
583   table.border = 0;
584   table.cellPadding = 0;
585   table.cellSpacing = 0;
586   ASPx.SetStyles(table, {
587    width: (width > 0) ? width : "100%",
588    height: (height > 0) ? height : "100%"
589   });
590   var tbody = document.createElement("TBODY");
591   table.appendChild(tbody);
592   var tr = document.createElement("TR");
593   tbody.appendChild(tr);
594   var td = document.createElement("TD");
595   tr.appendChild(td);
596   td.align = "center";
597   td.vAlign = "middle";
598   element = this.CloneLoadingPanel(element, td);
599   ASPx.SetElementDisplay(element, true);
600   this.loadingPanelElement = element;
601   return element;
602  } else
603   parentElement.innerHTML = "&nbsp;";
604  return null;
605 },
606 CreateLoadingPanelWithAbsolutePosition: function(parentElement, offsetElement) {
607  if(this.ShouldHideExistingLoadingElements())
608   this.HideLoadingPanel();
609  if(parentElement == null)
610   return null;
611  if(!this.IsLoadingContainerVisible()) {
612   this.hasPhantomLoadingElements = true;
613   return null;
614  }
615  if(!offsetElement)
616   offsetElement = parentElement;
617  var element = this.GetLoadingPanelElement();
618  if(element != null) {
619   element = this.CloneLoadingPanel(element, parentElement);
620   ASPx.SetStyles(element, {
621    position: "absolute"
622   });
623   ASPx.SetElementDisplay(element, true);
624   ASPx.Evt.AttachEventToElement(element, ASPx.Evt.GetMouseWheelEventName(), ASPx.Evt.PreventEvent);
625   this.SetLoadingPanelLocation(offsetElement, element);
626   this.loadingPanelElement = element;
627   return element;
628  }
629  return null;
630 },
631 CreateLoadingPanelInline: function(parentElement, centerInParent){
632  if(this.ShouldHideExistingLoadingElements())
633   this.HideLoadingPanel();
634  if(parentElement == null)
635   return null;
636  if(!this.IsLoadingContainerVisible()) {
637   this.hasPhantomLoadingElements = true;
638   return null;
639  }
640  var element = this.GetLoadingPanelElement();
641  if(element != null) {
642   element = this.CloneLoadingPanel(element, parentElement);
643   if(centerInParent){
644    ASPx.SetElementDisplay(element, true);
645    parentElement.style.textAlign = "center";
646   }
647   else
648    ASPx.SetElementDisplay(element, true);
649   this.loadingPanelElement = element;
650   return element;
651  }
652  return null;
653 },
654 ShowLoadingPanel: function() {
655 },
656 ShowLoadingElements: function() {
657  if(this.InCallback() || this.lpTimer > -1) return;
658  this.ShowLoadingDiv();
659  if(this.IsCallbackAnimationEnabled())
660   this.StartBeginCallbackAnimation();
661  else
662   this.ShowLoadingElementsInternal();
663 },
664 ShowLoadingElementsInternal: function() {
665  if(this.lpDelay > 0 && !this.IsCallbackAnimationEnabled()) 
666   this.lpTimer = window.setTimeout(function() { 
667    this.ShowLoadingPanelOnTimer(); 
668   }.aspxBind(this), this.lpDelay);
669  else {
670   this.RestoreLoadingDivOpacity();
671   this.ShowLoadingPanel();
672  }
673 },
674 GetLoadingPanelOffsetElement: function (baseElement) {
675  if(this.IsCallbackAnimationEnabled()) {
676   var element = this.GetLoadingPanelCallbackAnimationOffsetElement();
677   if(element) {
678    var container = typeof(ASPx.AnimationHelper) != "undefined" ? ASPx.AnimationHelper.findSlideAnimationContainer(element) : null;
679    if(container)
680     return container.parentNode.parentNode;
681    else
682     return element;
683   }
684  }
685  return baseElement;
686 },
687 GetLoadingPanelCallbackAnimationOffsetElement: function () {
688  return this.GetCallbackAnimationElement();
689 },
690 IsCallbackAnimationEnabled: function () {
691  return (this.enableCallbackAnimation || this.isSlideCallbackAnimationEnabled()) && !this.isCallbackAnimationPrevented;
692 },
693 GetDefaultanimationEngineType: function() {
694  return ASPx.AnimationEngineType.DEFAULT;
695 },
696 StartBeginCallbackAnimation: function () {
697  this.beginCallbackAnimationProcessing = true;
698  this.isCallbackFinished = false;
699  var element = this.GetCallbackAnimationElement();
700  if (element && this.isSlideCallbackAnimationEnabled() && this.slideAnimationDirection)
701   ASPx.AnimationHelper.slideOut(element, this.slideAnimationDirection, this.FinishBeginCallbackAnimation.aspxBind(this), this.GetDefaultanimationEngineType(), this.rtl);
702  else if(element && this.enableCallbackAnimation) 
703   ASPx.AnimationHelper.fadeOut(element, this.FinishBeginCallbackAnimation.aspxBind(this), null, ASPx.AnimationEngineType.JS);
704  else
705   this.FinishBeginCallbackAnimation();
706 },
707 CancelBeginCallbackAnimation: function() {
708  if(this.beginCallbackAnimationProcessing) {
709   this.beginCallbackAnimationProcessing = false;
710   var element = this.GetCallbackAnimationElement();
711   ASPx.AnimationHelper.cancelAnimation(element);
712  }
713 },
714 FinishBeginCallbackAnimation: function () {
715  this.beginCallbackAnimationProcessing = false;
716  if(!this.isCallbackFinished)
717   this.ShowLoadingElementsInternal();
718  else {
719   this.DoCallback(this.savedCallbackResult);
720   this.savedCallbackResult = null;
721  }
722 },
723 CheckBeginCallbackAnimationInProgress: function(callbackResult) {
724  if(this.beginCallbackAnimationProcessing) {
725   this.savedCallbackResult = callbackResult;
726   this.isCallbackFinished = true;
727   return true;
728  }
729  return false;
730 },
731 StartEndCallbackAnimation: function () {
732  this.HideLoadingPanel();
733  this.SetInitialLoadingDivOpacity();
734  this.RaiseEndCallbackAnimationStart();
735  this.endCallbackAnimationProcessing = true;
736  var element = this.GetCallbackAnimationElement();
737  if(element && this.isSlideCallbackAnimationEnabled() && this.slideAnimationDirection) 
738   ASPx.AnimationHelper.slideIn(element, this.slideAnimationDirection, this.FinishEndCallbackAnimation.aspxBind(this), this.GetDefaultanimationEngineType(), this.rtl);
739  else if(element && this.enableCallbackAnimation) 
740   ASPx.AnimationHelper.fadeIn(element, this.FinishEndCallbackAnimation.aspxBind(this), null, ASPx.AnimationEngineType.JS);
741  else
742   this.FinishEndCallbackAnimation();
743  this.slideAnimationDirection = null;
744 },
745 FinishEndCallbackAnimation: function () {
746  this.DoEndCallback();
747  this.endCallbackAnimationProcessing = false;
748  this.CheckRepeatGesture();
749 },
750 CheckEndCallbackAnimationNeeded: function() {
751  if(!this.endCallbackAnimationProcessing && this.requestCount == 1) {
752   this.StartEndCallbackAnimation();
753   return true;
754  }
755  return false;
756 },
757 PreventCallbackAnimation: function() {
758  this.isCallbackAnimationPrevented = true;
759 },
760 GetCallbackAnimationElement: function() {
761  return null;
762 },
763 AssignSlideAnimationDirectionByPagerArgument: function(arg, currentPageIndex) {
764  this.slideAnimationDirection = null;
765  if(this.isSlideCallbackAnimationEnabled() && typeof(ASPx.AnimationHelper) != "undefined") {
766   if(arg == PagerCommands.Next || arg == PagerCommands.Last)
767    this.slideAnimationDirection = ASPx.AnimationHelper.SLIDE_LEFT_DIRECTION;
768   else if(arg == PagerCommands.First || arg == PagerCommands.Prev)
769    this.slideAnimationDirection = ASPx.AnimationHelper.SLIDE_RIGHT_DIRECTION;
770   else if(!isNaN(currentPageIndex) && arg.indexOf(PagerCommands.PageNumber) == 0) {
771    var newPageIndex = parseInt(arg.substring(2));
772    if (!isNaN(newPageIndex)) {
773     var leftDir = this.rtl ? ASPx.AnimationHelper.SLIDE_LEFT_DIRECTION : ASPx.AnimationHelper.SLIDE_RIGHT_DIRECTION;
774     var rightDir = this.rtl ? ASPx.AnimationHelper.SLIDE_RIGHT_DIRECTION : ASPx.AnimationHelper.SLIDE_LEFT_DIRECTION;
775     this.slideAnimationDirection = newPageIndex < currentPageIndex ? leftDir : rightDir;
776    }
777   }
778  }
779 },
780 TryShowPhantomLoadingElements: function () {
781  if(this.hasPhantomLoadingElements && this.InCallback()) {
782   this.hasPhantomLoadingElements = false;
783   this.ShowLoadingDivAndPanel();
784  }
785 },
786 ShowLoadingDivAndPanel: function () {
787  this.ShowLoadingDiv();
788  this.RestoreLoadingDivOpacity();
789  this.ShowLoadingPanel();
790 },
791 HideLoadingElements: function() {
792  this.CancelBeginCallbackAnimation();
793  this.HideLoadingPanel();
794  this.HideLoadingDiv();
795 },
796 ShowLoadingPanelOnTimer: function() {
797  this.ClearLoadingPanelTimer();
798  if(!this.IsDOMDisposed()) {
799   this.RestoreLoadingDivOpacity();
800   this.ShowLoadingPanel();
801  }
802 },
803 ClearLoadingPanelTimer: function() {
804  this.lpTimer = ASPx.Timer.ClearTimer(this.lpTimer);  
805 },
806 HideLoadingPanel: function() {
807  this.ClearLoadingPanelTimer();
808  this.hasPhantomLoadingElements = false;
809  if(ASPx.IsExistsElement(this.loadingPanelElement)) {
810   ASPx.RemoveElement(this.loadingPanelElement);
811   this.loadingPanelElement = null;
812  }
813 },
814 SetLoadingPanelLocation: function(offsetElement, loadingPanel, x, y, offsetX, offsetY) {
815  if(!ASPx.IsExists(x) || !ASPx.IsExists(y)){
816   var x1 = ASPx.GetAbsoluteX(offsetElement);
817   var y1 = ASPx.GetAbsoluteY(offsetElement);
818   var x2 = x1;
819   var y2 = y1;
820   if(offsetElement == document.body) {
821    x1 = 0;
822    y1 = 0;
823    x2 = ASPx.GetDocumentMaxClientWidth();
824    y2 = ASPx.GetDocumentMaxClientHeight();
825   }
826   else{
827    x2 += offsetElement.offsetWidth;
828    y2 += offsetElement.offsetHeight;
829   }
830   if(x1 < ASPx.GetDocumentScrollLeft())
831    x1 = ASPx.GetDocumentScrollLeft();
832   if(y1 < ASPx.GetDocumentScrollTop())
833    y1 = ASPx.GetDocumentScrollTop();
834   if(x2 > ASPx.GetDocumentScrollLeft() + ASPx.GetDocumentClientWidth())
835    x2 = ASPx.GetDocumentScrollLeft() + ASPx.GetDocumentClientWidth();
836   if(y2 > ASPx.GetDocumentScrollTop() + ASPx.GetDocumentClientHeight())
837    y2 = ASPx.GetDocumentScrollTop() + ASPx.GetDocumentClientHeight();
838   x = x1 + ((x2 - x1 - loadingPanel.offsetWidth) / 2);
839   y = y1 + ((y2 - y1 - loadingPanel.offsetHeight) / 2);
840  }
841  if(ASPx.IsExists(offsetX) && ASPx.IsExists(offsetY)){
842   x += offsetX;
843   y += offsetY;
844  }
845  x = ASPx.PrepareClientPosForElement(x, loadingPanel, true);
846  y = ASPx.PrepareClientPosForElement(y, loadingPanel, false);
847  ASPx.SetStyles(loadingPanel, { left: x, top: y });
848 },
849 GetLoadingDiv: function(){
850  return ASPx.GetElementById(this.name + "_LD");
851 },
852 CreateLoadingDiv: function(parentElement, offsetElement){
853  if(this.ShouldHideExistingLoadingElements())
854   this.HideLoadingDiv();
855  if(parentElement == null) 
856   return null;
857  if(!this.IsLoadingContainerVisible()) {
858   this.hasPhantomLoadingElements = true;
859   return null;
860  }
861  if(!offsetElement)
862   offsetElement = parentElement;
863  var div = this.GetLoadingDiv();
864  if(div != null){
865   div = div.cloneNode(true);
866   parentElement.appendChild(div);
867   ASPx.SetElementDisplay(div, true);
868   ASPx.Evt.AttachEventToElement(div, ASPx.TouchUIHelper.touchMouseDownEventName, ASPx.Evt.PreventEvent);
869   ASPx.Evt.AttachEventToElement(div, ASPx.TouchUIHelper.touchMouseMoveEventName, ASPx.Evt.PreventEvent);
870   ASPx.Evt.AttachEventToElement(div, ASPx.TouchUIHelper.touchMouseUpEventName, ASPx.Evt.PreventEvent);
871   ASPx.Evt.AttachEventToElement(div, ASPx.Evt.GetMouseWheelEventName(), ASPx.Evt.PreventEvent);
872   this.SetLoadingDivBounds(offsetElement, div);
873   this.loadingDivElement = div;
874   this.SetInitialLoadingDivOpacity();
875   return div;
876  }
877  return null;
878 },
879 SetInitialLoadingDivOpacity: function() {
880  if(!this.loadingDivElement) return;
881  ASPx.Attr.SaveStyleAttribute(this.loadingDivElement, "opacity");
882  ASPx.Attr.SaveStyleAttribute(this.loadingDivElement, "filter");
883  ASPx.SetElementOpacity(this.loadingDivElement, 0.01);
884 },
885 RestoreLoadingDivOpacity: function() {
886  if(!this.loadingDivElement) return;
887  ASPx.Attr.RestoreStyleAttribute(this.loadingDivElement, "opacity");
888  ASPx.Attr.RestoreStyleAttribute(this.loadingDivElement, "filter");
889 },
890 SetLoadingDivBounds: function(offsetElement, loadingDiv) {
891  var absX = (offsetElement == document.body) ? 0 : ASPx.GetAbsoluteX(offsetElement);
892  var absY = (offsetElement == document.body) ? 0 : ASPx.GetAbsoluteY(offsetElement);
893  ASPx.SetStyles(loadingDiv, {
894   left: ASPx.PrepareClientPosForElement(absX, loadingDiv, true),
895   top: ASPx.PrepareClientPosForElement(absY, loadingDiv, false)
896  });
897  var width = (offsetElement == document.body) ? ASPx.GetDocumentWidth() : offsetElement.offsetWidth;
898  var height = (offsetElement == document.body) ? ASPx.GetDocumentHeight() : offsetElement.offsetHeight;
899  if(height < 0) 
900   height = 0;
901  ASPx.SetStyles(loadingDiv, { width: width, height: height });
902  var correctedWidth = 2 * width - loadingDiv.offsetWidth;
903  if(correctedWidth <= 0) correctedWidth = width;
904  var correctedHeight = 2 * height - loadingDiv.offsetHeight;
905  if(correctedHeight <= 0) correctedHeight = height;
906  ASPx.SetStyles(loadingDiv, { width: correctedWidth, height: correctedHeight });
907 },
908 ShowLoadingDiv: function() {
909 },
910 HideLoadingDiv: function() {
911  this.hasPhantomLoadingElements = false;
912  if(ASPx.IsExistsElement(this.loadingDivElement)){
913   ASPx.RemoveElement(this.loadingDivElement);
914   this.loadingDivElement = null;
915  }
916 },
917 CanHandleGesture: function(evt) {
918  return false;
919 },
920 CanHandleGestureCore: function(evt) {
921  var source = ASPx.Evt.GetEventSource(evt);
922  if(ASPx.GetIsParent(this.loadingPanelElement, source) || ASPx.GetIsParent(this.loadingDivElement, source))
923   return true; 
924  var callbackAnimationElement = this.GetCallbackAnimationElement();
925  if(!callbackAnimationElement)
926   return false;
927  var animationContainer = ASPx.AnimationHelper.getSlideAnimationContainer(callbackAnimationElement, false, false);
928  if(animationContainer && ASPx.GetIsParent(animationContainer, source) && !ASPx.GetIsParent(animationContainer.childNodes[0], source))
929   return true; 
930  return this.CanHandleGesture(evt); 
931 },
932 AllowStartGesture: function() {
933  return !this.beginCallbackAnimationProcessing && !this.endCallbackAnimationProcessing;
934 },
935 StartGesture: function() {
936 },
937 AllowExecuteGesture: function(value) {
938  return false;
939 },
940 ExecuteGesture: function(value) {
941 },
942 CancelGesture: function(value) {
943  if(this.repeatedGestureCount === 0) {
944   this.repeatedGestureValue = value;
945   this.repeatedGestureCount = 1;
946  }
947  else {
948   if(this.repeatedGestureValue * value > 0)
949    this.repeatedGestureCount++;
950   else
951    this.repeatedGestureCount--;
952   if(this.repeatedGestureCount === 0)
953    this.repeatedGestureCount = 0;
954  }
955 },
956 CheckRepeatGesture: function() {
957  if(this.repeatedGestureCount !== 0) {
958   if(this.AllowExecuteGesture(this.repeatedGestureValue))
959    this.ExecuteGesture(this.repeatedGestureValue, this.repeatedGestureCount);
960   this.repeatedGestureValue = 0;
961   this.repeatedGestureCount = 0;
962  }
963 },
964 AllowExecutePagerGesture: function (pageIndex, pageCount, value) {
965  if(pageIndex < 0) return false;
966  if(pageCount <= 1) return false;
967  if(value > 0 && pageIndex === 0) return false;
968  if(value < 0 && pageIndex === pageCount - 1) return false;
969  return true;
970 },
971 ExecutePagerGesture: function(pageIndex, pageCount, value, count, method) {
972  if(!count) count = 1;
973  var pageIndex = pageIndex + (value < 0 ? count : -count);
974  if(pageIndex < 0) pageIndex = 0;
975  if(pageIndex > pageCount - 1) pageIndex = pageCount - 1;
976  method(PagerCommands.PageNumber + pageIndex);
977 },
978 RaiseInit: function(){
979  if(!this.Init.IsEmpty()){
980   var args = new ASPxClientEventArgs();
981   this.Init.FireEvent(this, args);
982  }
983 },
984 RaiseBeginCallbackInternal: function(command){
985  if(!this.BeginCallback.IsEmpty()){
986   var args = new ASPxClientBeginCallbackEventArgs(command);
987   this.BeginCallback.FireEvent(this, args);
988  }
989 },
990 RaiseEndCallbackInternal: function(command) {
991  if(!this.EndCallback.IsEmpty()){
992   var args = new ASPxClientEndCallbackEventArgs(command);
993   this.EndCallback.FireEvent(this, args);
994  }
995 },
996 RaiseCallbackErrorInternal: function(message, callbackId) {
997  if(!this.CallbackError.IsEmpty()) {
998   var args = new ASPxClientCallbackErrorEventArgs(message, callbackId);
999   this.CallbackError.FireEvent(this, args);
1000   if(args.handled)
1001    return { isHandled: true, errorMessage: args.message };
1002  }
1003 },
1004 RaiseBeginCallback: function(command){
1005  this.RaiseBeginCallbackInternal(command);    
1006  aspxGetControlCollection().RaiseBeginCallback(this, command);
1007 },
1008 RaiseEndCallback: function(command){
1009  this.RaiseEndCallbackInternal(command);
1010  aspxGetControlCollection().RaiseEndCallback(this, command);
1011 },
1012 RaiseCallbackError: function (message, callbackId) {
1013  var result = this.RaiseCallbackErrorInternal(message, callbackId);
1014  if(!result) 
1015   result = aspxGetControlCollection().RaiseCallbackError(this, message, callbackId);
1016  return result;
1017 },
1018 RaiseEndCallbackAnimationStart: function(){
1019  if(!this.EndCallbackAnimationStart.IsEmpty()){
1020   var args = new ASPxClientEventArgs();
1021   this.EndCallbackAnimationStart.FireEvent(this, args);
1022  }
1023 },
1024 RaiseBeforePronounce: function(message) {
1025  var args = new ASPxClientControlBeforePronounceEventArgs(message, this);
1026  if(!this.BeforePronounce.IsEmpty())
1027   this.BeforePronounce.FireEvent(this, args);
1028  return args;
1029 },
1030 RaiseUnload: function() {
1031  var args = new ASPxClientControlUnloadEventArgs(this);
1032  if(!this.Unload.IsEmpty())
1033   this.Unload.FireEvent(this, args);
1034 },
1035 RaiseDisposed: function() {
1036  this.Disposed.FireEvent(this, new ASPxClientEventArgs(this));
1037 },
1038 SendMessageToAssistiveTechnology: function(message) {
1039  if(!this.accessibilityCompliant)
1040   return;
1041  this.PronounceMessageInternal(message, ASPx.AccessibilityPronouncerType.live);
1042 },
1043 PronounceMessageInternal: function(messageArg, type) {
1044  var message = messageArg;
1045  if(!ASPx.Ident.IsArray(messageArg))
1046   message = [messageArg];
1047  var args = this.RaiseBeforePronounce(message);
1048  ASPx.AccessibilityPronouncer.Pronounce(args, type);
1049 },
1050 IsVisible: function() {
1051  var element = this.GetMainElement();
1052  return ASPx.IsElementVisible(element);
1053 },
1054 IsDisplayedElement: function(element) {
1055  while(element && element.tagName != "BODY") {
1056   if(!ASPx.GetElementDisplay(element)) 
1057    return false;
1058   element = element.parentNode;
1059  }
1060  return true;
1061 },
1062 IsDisplayed: function() {
1063  return this.IsDisplayedElement(this.GetMainElement());
1064 },
1065 IsHiddenElement: function(element) {
1066  return element && element.offsetWidth == 0 && element.offsetHeight == 0;
1067 },
1068 IsHidden: function() {
1069  return this.IsHiddenElement(this.GetMainElement());
1070 },
1071 IsDisposed: function() {
1072  return this.disposed;
1073 },
1074 GetParentControl: function() {
1075  var mainElement = this.getActualMainElement();
1076  var popupPostfix = ASPx.PCWIdSuffix + "-1";
1077  var result = null;
1078  ASPx.GetParent(mainElement, function(element) {
1079   if(element === mainElement || !element.id)
1080    return false;
1081   var controlName = element.id.replace(popupPostfix, "");
1082   result = ASPx.GetControlCollection().Get(controlName);
1083   return !!result;
1084  });
1085  return result;
1086 },
1087 getActualMainElement: function() { return this.GetMainElement(); },
1088 findParentByType: function (type) {
1089  var ctrl = this;
1090  while (ctrl) {
1091   var parent = ctrl.GetParentControl();
1092   if (parent && parent instanceof type)
1093    return parent;
1094   ctrl = parent;
1095  }
1096  return null;
1097 },
1098 Focus: function() {
1099 },
1100 GetClientVisible: function(){
1101  return this.GetVisible();
1102 },
1103 SetClientVisible: function(visible){
1104  this.SetVisible(visible);
1105 },
1106 GetVisible: function(){
1107  return this.clientVisible;
1108 },
1109 SetVisible: function(visible){
1110  if(this.clientVisible != visible){
1111   this.clientVisible = visible;
1112   ASPx.SetElementDisplay(this.GetMainElement(), visible);
1113   if(visible) {
1114    this.AdjustControl();
1115    var mainElement = this.GetMainElement();
1116    if(mainElement)
1117     aspxGetControlCollection().AdjustControls(mainElement);
1118   }
1119  }
1120 },
1121 GetEnabled: function() {
1122  return this.clientEnabled;
1123 },
1124 SetEnabled: function(enabled) {
1125  this.clientEnabled = enabled;
1126  if(ASPxClientControl.setEnabledLocked)
1127   return;
1128  else
1129   ASPxClientControl.setEnabledLocked = true;
1130  this.savedClientEnabled = enabled;
1131  aspxGetControlCollection().ProcessControlsInContainer(this.GetMainElement(), function(control) {
1132   if(ASPx.IsFunction(control.SetEnabled))
1133    control.SetEnabled(enabled && control.savedClientEnabled);
1134  });
1135  delete ASPxClientControl.setEnabledLocked;
1136 },
1137 InCallback: function() {
1138  return this.requestCount > 0;
1139 },
1140 DoBeginCallback: function(command) {
1141  this.RaiseBeginCallback(command || "");
1142  aspxGetControlCollection().Before_WebForm_InitCallback(this.name);
1143  if(typeof(WebForm_InitCallback) != "undefined" && WebForm_InitCallback) {
1144   __theFormPostData = "";
1145   __theFormPostCollection = [ ];
1146   this.ClearPostBackEventInput("__EVENTTARGET");
1147   this.ClearPostBackEventInput("__EVENTARGUMENT");
1148   WebForm_InitCallback();
1149   this.savedFormPostData = __theFormPostData;
1150   this.savedFormPostCollection = __theFormPostCollection;
1151  }
1152 },
1153 ClearPostBackEventInput: function(id){
1154  var element = ASPx.GetElementById(id);
1155  if(element != null) element.value = "";
1156 },
1157 PerformDataCallback: function(arg, handler) {
1158  this.CreateCustomDataCallback(arg, "", handler);
1159 },
1160 sendCallbackViaQueue: function (prefix, arg, showLoadingPanel, context, handler, onBeforeSend) {
1161  if (!this.useCallbackQueue())
1162   return false;
1163  var context = context || this;
1164  var token = this.callbackQueueHelper.sendCallback(ASPx.FormatCallbackArg(prefix, arg), context, handler || context.OnCallback, prefix, onBeforeSend);
1165  if (showLoadingPanel)
1166   this.callbackQueueHelper.showLoadingElements();
1167  return token;
1168 },
1169 CreateCallback: function (arg, command, handler) {
1170  var callbackInfo = this.CreateCallbackInfo(ASPx.CallbackType.Common, handler || null);
1171  var callbackID = this.CreateCallbackByInfo(arg, command, callbackInfo);
1172  return callbackID;
1173 },
1174 CreateCustomDataCallback: function(arg, command, handler) {
1175  var callbackInfo = this.CreateCallbackInfo(ASPx.CallbackType.Data, handler);
1176  this.CreateCallbackByInfo(arg, command, callbackInfo);
1177 },
1178 CreateCallbackByInfo: function(arg, command, callbackInfo) {
1179  if(!this.CanCreateCallback()) return;
1180  var callbackID;
1181  if(typeof(WebForm_DoCallback) != "undefined" && WebForm_DoCallback && ASPx.documentLoaded || ASPx.Platform === "NETCORE")
1182   callbackID = this.CreateCallbackInternal(arg, command, true, callbackInfo);
1183  else {
1184   if(!this.savedCallbacks)
1185    this.savedCallbacks = [];
1186   var callbackInfo = { arg: arg, command: command, callbackInfo: callbackInfo };
1187   if(this.allowMultipleCallbacks)
1188    this.savedCallbacks.push(callbackInfo);
1189   else
1190    this.savedCallbacks[0] = callbackInfo;
1191  }
1192  return callbackID;
1193 },
1194 CreateCallbackInternal: function(arg, command, viaTimer, callbackInfo) {
1195  var watcher = ASPx.ControlUpdateWatcher.getInstance();
1196  if(watcher && !watcher.CanSendCallback(this, arg)) {
1197   this.CancelCallbackInternal();
1198   return;
1199  }
1200  this.requestCount++;
1201  this.DoBeginCallback(command);
1202  if(typeof(arg) == "undefined")
1203   arg = "";
1204  if(typeof(command) == "undefined")
1205   command = "";
1206  var callbackID = this.SaveCallbackInfo(callbackInfo, command),
1207   customArgs = this.GetCustomCallbackArgs();
1208  if(viaTimer)
1209   window.setTimeout(function() { this.CreateCallbackCoreWithCustomArgs(arg, command, callbackID, customArgs); }.aspxBind(this), 0);
1210  else
1211   this.CreateCallbackCoreWithCustomArgs(arg, command, callbackID, customArgs);
1212  return callbackID;
1213 },
1214 CreateCallbackCoreWithCustomArgs: function(arg, command, callbackID, customArgs) {
1215  this.CreateCallbackCore(arg, command, callbackID);
1216 },
1217 GetCustomCallbackArgs: function() {
1218  return {};
1219 },
1220 CancelCallbackInternal: function() {
1221  this.CancelCallbackCore();
1222  this.HideLoadingElements();
1223 },
1224 CancelCallbackCore: function() {
1225 },
1226 CreateCallbackCore: function(arg, command, callbackID) {
1227  var callBackMethod = this.GetCallbackMethod(command);
1228  __theFormPostData = this.savedFormPostData;
1229  __theFormPostCollection = this.savedFormPostCollection;
1230  callBackMethod.call(this, this.GetSerializedCallbackInfoByID(callbackID) + arg);
1231 },
1232 GetCallbackMethod: function(command){
1233  return this.callBack;
1234 },
1235 CanCreateCallback: function() {
1236  return !this.InCallback() || (this.allowMultipleCallbacks && !this.beginCallbackA
1236nimationProcessing && !this.endCallbackAnimationProcessing);
1237 },
1238 DoLoadCallbackScripts: function() {
1239  ASPx.ProcessScriptsAndLinks(this.name, true);
1240 },
1241 DoEndCallback: function() {
1242  if(this.IsCallbackAnimationEnabled() && this.CheckEndCallbackAnimationNeeded()) 
1243   return;
1244  this.requestCount--;
1245  if (this.requestCount < 1) 
1246   this.callbackHandlersQueue.executeCallbacksHandlers();
1247  if(this.HideLoadingPanelOnCallback() && this.requestCount < 1) 
1248   this.HideLoadingElements();
1249  if(this.isSwipeGesturesEnabled() && this.supportGestures) {
1250   ASPx.GesturesHelper.UpdateSwipeAnimationContainer(this.name);
1251   if(this.touchUIMouseScroller)
1252    this.touchUIMouseScroller.update();
1253  }
1254  this.isCallbackAnimationPrevented = false;
1255  this.OnCallbackFinalized();
1256  this.AssignEllipsisTooltips();
1257  var command = this.GetCallbackCommand();
1258  this.RaiseEndCallback(command);
1259  this.InitializeIntersectionObserversManager();
1260  this.currentCallbackID = -1;
1261 },
1262 DoFinalizeCallback: function() {
1263 },
1264 OnCallbackFinalized: function() {
1265 },
1266 AssignEllipsisTooltips: function() { },
1267 GetCallbackCommand: function() {
1268  var result = "";
1269  if(this.currentCallbackID != -1) {
1270   var command = this.callbackCommand[this.currentCallbackID];
1271   if(command)
1272    result = command;
1273  }
1274  return result;
1275 },
1276 HideLoadingPanelOnCallback: function() {
1277  return true;
1278 },
1279 ShouldHideExistingLoadingElements: function() {
1280  return true;
1281 },
1282 EvalCallbackResult: function(resultString) {
1283  return eval(resultString);
1284 },
1285 ParseJSProperties: function(resultObj) {
1286  if(resultObj.cp) {
1287   for(var name in resultObj.cp)
1288    if(resultObj.cp.hasOwnProperty(name)) {
1289     this[name] = resultObj.cp[name];
1290     if(this.aspNetCoreWrapperInstance)
1291      this.aspNetCoreWrapperInstance[name] = resultObj.cp[name]; 
1292    }
1293  }
1294 },
1295 DoCallback: function(result) {
1296  if(this.IsCallbackAnimationEnabled() && this.CheckBeginCallbackA
1296nimationInProgress(result))
1297   return;
1298  result = ASPx.Str.Trim(result);
1299  if(result instanceof ASPx.NetworkError || result.indexOf(ASPx.CallbackResultPrefix) != 0)
1300   this.ProcessCallbackGeneralError(result, false);
1301  else {
1302   var resultObj = null;
1303   try {
1304    resultObj = this.EvalCallbackResult(result);
1305   } 
1306   catch(e) {
1307   }
1308   if(resultObj) {
1309    this.currentCallbackID = resultObj.id;
1310    ASPx.CacheHelper.DropCache(this);
1311    if(resultObj.redirect) {
1312     this.ParseJSProperties(resultObj); 
1313     ASPx.Url.Redirect(resultObj.redirect);
1314    }
1315    else if(ASPx.IsExists(resultObj.generalError)) {
1316     this.ProcessCallbackGeneralError(resultObj.generalError, true);
1317    }
1318    else {
1319     var errorObj = resultObj.error;
1320     if(errorObj) { 
1321      if(this.parseJSPropertiesOnCallbackError)
1322       this.ParseJSProperties(resultObj);
1323      this.ProcessCallbackError(errorObj,resultObj.id);
1324     } else {
1325      this.ParseJSProperties(resultObj);
1326      var callbackInfo = this.DequeueCallbackInfo(resultObj.id);
1327      if(callbackInfo && callbackInfo.type == ASPx.CallbackType.Data)
1328       this.ProcessCustomDataCallback(resultObj.result, callbackInfo);
1329      else {
1330       if (this.useCallbackQueue() && this.callbackQueueHelper.getCallbackInfoById(resultObj.id))
1331        this.callbackQueueHelper.processCallback(resultObj.result, resultObj.id);
1332       else {
1333        this.ProcessCallback(resultObj.result, resultObj.id);
1334        if(callbackInfo && callbackInfo.handler) {
1335         var handlerInfo = { handler: callbackInfo.handler, result: resultObj.result.data };
1336         this.callbackHandlersQueue.addCallbackHandler(handlerInfo);
1337        }
1338       }
1339      }
1340     }
1341    }
1342   }
1343  }
1344  this.DoLoadCallbackScripts();
1345 },
1346 DoCallbackError: function(result) {
1347  this.HideLoadingElements();
1348  this.ProcessCallbackGeneralError(result, false); 
1349 },
1350 DoControlClick: function(evt) {
1351  this.OnControlClick(ASPx.Evt.GetEventSource(evt), evt);
1352 },
1353 ProcessCallback: function (result, callbackId) {
1354  this.OnCallback(result, callbackId);
1355 },
1356 ProcessCustomDataCallback: function(result, callbackInfo) {
1357  if(callbackInfo.handler != null)
1358   callbackInfo.handler(this, result);
1359  this.RaiseCustomDataCallback(result);
1360 },
1361 RaiseCustomDataCallback: function(result) {
1362  if(!this.CustomDataCallback.IsEmpty()) {
1363   var arg = new ASPxClientCustomDataCallbackEventArgs(result);
1364   this.CustomDataCallback.FireEvent(this, arg);
1365  }
1366 },
1367 OnCallback: function(result) {
1368 },
1369 CreateCallbackInfo: function(type, handler) {
1370  return { type: type, handler: handler };
1371 },
1372 GetSerializedCallbackInfoByID: function(callbackID) {
1373  return this.GetCallbackInfoByID(callbackID).type + callbackID + ASPx.CallbackSeparator;
1374 },
1375 SaveCallbackInfo: function(info, command) {
1376  var callbacks = this.GetActiveCallbacksInfo();
1377  var index = callbacks.indexOf(null);
1378  if(index === -1)
1379   index = callbacks.length;
1380  callbacks[index] = info;
1381  this.callbackCommand[index] = command;
1382  return index;
1383 },
1384 GetActiveCallbacksInfo: function() {
1385  var persistentProperties = this.GetPersistentProperties();
1386  if(!persistentProperties.activeCallbacks)
1387   persistentProperties.activeCallbacks = [ ];
1388  return persistentProperties.activeCallbacks;
1389 },
1390 GetPersistentProperties: function() {
1391  var storage = _aspxGetPersistentControlPropertiesStorage();
1392  var persistentProperties = storage[this.name];
1393  if(!persistentProperties) {
1394   persistentProperties = { };
1395   storage[this.name] = persistentProperties;
1396  }
1397  return persistentProperties;
1398 },
1399 GetCallbackInfoByID: function(callbackID) {
1400  return this.GetActiveCallbacksInfo()[callbackID];
1401 },
1402 DequeueCallbackInfo: function(index) {
1403  var activeCallbacksInfo = this.GetActiveCallbacksInfo();
1404  if(index < 0 || index >= activeCallbacksInfo.length)
1405   return null;
1406  var result = activeCallbacksInfo[index];
1407  activeCallbacksInfo[index] = null;
1408  return result;
1409 },
1410 ProcessCallbackError: function (errorObj, callbackId) {
1411  var data = ASPx.IsExists(errorObj.data) ? errorObj.data : null;
1412  var result = this.RaiseCallbackError(errorObj.message, callbackId);
1413  if(result.isHandled)
1414   this.OnCallbackErrorAfterUserHandle(result.errorMessage, data); 
1415  else
1416   this.OnCallbackError(result.errorMessage, data); 
1417 },
1418 OnCallbackError: function(errorMessage, data) {
1419  if(errorMessage)
1420   ASPx.ShowErrorAlert(errorMessage);
1421 },
1422 OnCallbackErrorAfterUserHandle: function(errorMessage, data) {
1423 },
1424 ProcessCallbackGeneralError: function(error, serverExceptionOnLastCallback) {
1425  this.serverExceptionOnLastCallback = serverExceptionOnLastCallback;
1426  var isNetworkError = error instanceof ASPx.NetworkError;
1427  var errorMessage = isNetworkError ? error.message : error;
1428  var result = this.RaiseCallbackError(errorMessage);
1429  if(result.isHandled)
1430   this.OnCallbackGeneralErrorAfterUserHandle(result.errorMessage);
1431  else if(isNetworkError)
1432   this.OnCallbackNetworkError(result.errorMessage);
1433  else
1434   this.OnCallbackGeneralError(result.errorMessage);
1435 },
1436 OnCallbackGeneralError: function(errorMessage) {
1437  this.OnCallbackError(errorMessage, null);
1438 },
1439 OnCallbackNetworkError: function(errorMessage) {
1440  console.error(errorMessage);
1441 },
1442 OnCallbackGeneralErrorAfterUserHandle: function (errorMessage) {
1443 },
1444 SendPostBack: function(params, preventConvertToUpdatePanelCallback) {
1445  if(preventConvertToUpdatePanelCallback)
1446   this.sendMSAjaxCompatPostBack(params);
1447  else
1448   this.sendPostBackInternal(params);
1449 },
1450 sendPostBackInternal: function(params) {
1451  if(typeof(__doPostBack) != "undefined")
1452   __doPostBack(this.uniqueID, params);
1453  else{
1454   var form = this.GetParentForm();
1455   if(form) form.submit();
1456  }
1457 },
1458 sendMSAjaxCompatPostBack: function(params) {
1459  var rm = ASPx.GetMSAjaxRequestManager();
1460  var triggers = rm ? rm._postBackControlClientIDs : null;
1461  var needRegister = triggers && ASPx.Ident.IsArray(triggers) && ASPx.Data.ArrayIndexOf(triggers, this.name) == -1;
1462  if(needRegister)
1463   triggers.unshift(this.name);
1464  this.sendPostBackInternal(params);
1465  if(needRegister)
1466   triggers.shift();
1467 },
1468 IsValidInstance: function () {
1469  return aspxGetControlCollection().GetByName(this.name) === this;
1470 },
1471 OnDispose: function() { 
1472  this.RaiseDisposed();
1473  var varName = this.globalName;
1474  if(varName && varName !== "" && window && window[varName] && window[varName] == this){
1475   try{
1476    delete window[varName];
1477   }
1478   catch(e){  }
1479  }
1480  if(this.callbackQueueHelper)
1481   this.callbackQueueHelper.detachEvents();
1482  if (!this.IsDisposed())
1483   this.disposed = true;
1484 },
1485 OnGlobalControlsInitialized: function(args) { 
1486 },
1487 OnGlobalBrowserWindowResized: function(args) { 
1488 },
1489 OnGlobalBeginCallback: function(args) { 
1490 },
1491 OnGlobalEndCallback: function(args) { 
1492 },
1493 OnGlobalCallbackError: function(args) { 
1494 },
1495 OnGlobalValidationCompleted: function(args) { 
1496 },
1497 AddDefaultStateControllerItems: function() {
1498  var states = this.scStates;
1499  if(!states) return;
1500  var postfix = this.scPostfix ? ("_" + this.scPostfix) : "";
1501  var mainElementId = this.GetMainElementId();
1502  if(states & 2)
1503   this.AddDefaultReadOnlyStateControllerItem(this.scPrefix + "ReadOnly" + postfix, mainElementId);
1504  if(states & 4)
1505   this.AddDefaultDisabledStateControllerItem(this.scPrefix + "Disabled" + postfix, mainElementId);
1506 },
1507 AddDefaultReadOnlyStateControllerItem: function(cssClass, mainElementId) { throw "Not implemented"; },
1508 AddDefaultDisabledStateControllerItem: function(cssClass, mainElementId) { throw "Not implemented"; },
1509 DOMContentLoaded: function() { },
1510 IsStateControllerEnabled: function() { return false; },
1511 InitializeDOM: function() {
1512  var mainElement = this.GetMainElement();
1513  if(mainElement)
1514   ASPx.SetElementInitializedFlag(mainElement);
1515 },
1516 IsDOMInitialized: function() {
1517  var mainElement = this.GetMainElement();
1518  return mainElement && ASPx.GetElementInitializedFlag(mainElement);
1519 },
1520 AdjustControl: function(nestedCall) { },
1521 OnBrowserWindowResizeInternal: function(e) { },
1522 RegisterInControlTree: function(tree) { },
1523 InitializeIntersectionObserversManager: function () {
1524  var elementToObserve = this.getElementToObserveVisibilityChange();
1525  if(elementToObserve) {
1526   ASPx.IntersectionObserversManager.SubscribeElemensVisibilityChangeInBrowserWindow(elementToObserve, this.processVisibilityChanged.bind(this));
1527  }
1528 },
1529 getElementToObserveVisibilityChange: function () { },
1530 processVisibilityChanged: function (visible) { }
1531});
1532ASPxClientControlBase.Cast = function(obj) {
1533 if(typeof obj == "string")
1534  return window[obj];
1535 return obj;
1536};
1537var persistentControlPropertiesStorage = null;
1538function _aspxGetPersistentControlPropertiesStorage() {
1539 if(persistentControlPropertiesStorage == null)
1540  persistentControlPropertiesStorage = { };
1541 return persistentControlPropertiesStorage;
1542}
1543var ELLIPSIS_MARKER_CLASS = "dx-ellipsis";
1544var ELLIPSIS_TOOLTIP_MARKER_ATTR = "dxEllipsisTitle";
1545var ASPxClientControl = ASPx.CreateClass(ASPxClientControlBase, {
1546 constructor: function(name){
1547  this.constructor.prototype.constructor.call(this, name);
1548  this.rtl = false;
1549  this.enableEllipsis = false;
1550  this.isNative = false;
1551  this.isControlCollapsed = false;
1552  this.isInsideHierarchyAdjustment = false;
1553  this.controlOwner = null;
1554  this.adjustedSizes = { };
1555  this.dialogContentHashTable = { };
1556  this.renderIFrameForPopupElements = false;
1557  this.widthValueSetInPercentage = false;
1558  this.heightValueSetInPercentage = false;
1559  this.verticalAlignedElements = { };
1560  this.wrappedTextContainers = { };
1561  this.scrollPositionState = { };
1562  this.sizingConfig = {
1563   allowSetWidth: true,
1564   allowSetHeight: true,
1565   correction : false,
1566   adjustControl : false,
1567   supportPercentHeight: false,
1568   supportAutoHeight: false
1569  };
1570  this.percentSizeConfig = {
1571   width: -1,
1572   height: -1,
1573   markerWidth: -1,
1574   markerHeight: -1
1575  };  
1576 },
1577 querySelector: function(selector) { return this.querySelectorAll(selector)[0] || null; },
1578 querySelectorAll: function(selector) {
1579  return ASPx.CacheHelper.GetCachedElement(this, "querySelectorAll_" + selector,
1580   function() { return Array.prototype.slice.call(this.GetMainElement().querySelectorAll(selector)); });
1581 },
1582 createAccessKey: function (popupItem, getPopupElement, keyTipElement, key, onlyClick, manualStopProcessing) {
1583  return new ASPx.AccessKey(popupItem, getPopupElement, keyTipElement, key, onlyClick, manualStopProcessing);
1584 },
1585 InlineInitialize: function() {
1586  this.InitializeDOM();
1587  ASPxClientControlBase.prototype.InlineInitialize.call(this);
1588 },
1589 AfterCreate: function() { 
1590  ASPxClientControlBase.prototype.AfterCreate.call(this);
1591  if(!this.CanInitializeAdjustmentOnDOMContentLoaded() || ASPx.IsStartupScriptsRunning())
1592   this.InitializeAdjustment();
1593 },
1594 DOMContentLoaded: function() {
1595  if(this.CanInitializeAdjustmentOnDOMContentLoaded()) 
1596   this.InitializeAdjustment();
1597 },
1598 CanInitializeAdjustmentOnDOMContentLoaded: function() {
1599  return true;
1600 },
1601 InitializeAdjustment: function() {
1602  this.UpdateAdjustmentFlags();
1603  this.AdjustControl();
1604 },
1605 AfterInitialize: function() {
1606  this.AdjustControl();
1607  ASPxClientControlBase.prototype.AfterInitialize.call(this);
1608 },
1609 IsStateControllerEnabled: function(){
1610  return typeof(ASPx.GetStateController) != "undefined" && ASPx.GetStateController();
1611 },
1612 GetWidth: function() {
1613  return this.GetMainElement().offsetWidth;
1614 },
1615 GetHeight: function() {
1616  return this.GetMainElement().offsetHeight;
1617 },
1618 SetWidth: function(width) {
1619  if(this.sizingConfig.allowSetWidth)
1620   this.SetSizeCore("width", width, "GetWidth", false);
1621 },
1622 SetHeight: function(height) {
1623  if(this.sizingConfig.allowSetHeight)
1624   this.SetSizeCore("height", height, "GetHeight", false);
1625 },
1626 SetSizeCore: function(sizePropertyName, size, getFunctionName, corrected) {
1627  if(size < 0 || !this.GetMainElement())
1628   return;
1629  this.GetMainElement().style[sizePropertyName] = size + "px";
1630  this.UpdateAdjustmentFlags(sizePropertyName);
1631  if(this.sizingConfig.adjustControl)
1632   this.AdjustControl(true);
1633  if(this.sizingConfig.correction && !corrected) {
1634   var realSize = this[getFunctionName]();
1635   if(realSize != size) {
1636    var correctedSize = size - (realSize - size);
1637    this.SetSizeCore(sizePropertyName, correctedSize, getFunctionName, true);
1638   }
1639  }
1640 },
1641 AdjustControl: function(nestedCall) {
1642  if(this.IsAdjustmentRequired() && (!ASPxClientControl.adjustControlLocked || nestedCall)) {
1643   ASPxClientControl.adjustControlLocked = true;
1644   try {
1645    if(!this.IsAdjustmentAllowed())
1646     return;
1647    this.AdjustControlCore();
1648    this.UpdateAdjustedSizes();
1649   } 
1650   finally {
1651    delete ASPxClientControl.adjustControlLocked;
1652   }
1653  }
1654  this.AssignEllipsisTooltips();
1655  this.TryShowPhantomLoadingElements();
1656 },
1657 ResetControlAdjustment: function () {
1658  this.adjustedSizes = { };
1659 },
1660 UpdateAdjustmentFlags: function(sizeProperty) {
1661  var mainElement = this.GetMainElement();
1662  if(mainElement) {
1663   var mainElementStyle = ASPx.GetCurrentStyle(mainElement);
1664   this.UpdatePercentSizeConfig([mainElementStyle.width, mainElement.style.width], [mainElementStyle.height, mainElement.style.height], sizeProperty);
1665  }
1666 },
1667 UpdatePercentSizeConfig: function(widths, heights, modifyStyleProperty) {
1668  switch(modifyStyleProperty) {
1669   case "width":
1670    this.UpdatePercentWidthConfig(widths);
1671    break;
1672   case "height":
1673    this.UpdatePercentHeightConfig(heights);
1674    break;
1675   default:
1676    this.UpdatePercentWidthConfig(widths);
1677    this.UpdatePercentHeightConfig(heights);
1678    break;
1679  }
1680  this.ResetControlPercentMarkerSize();
1681 },
1682 UpdatePercentWidthConfig: function(widths) {
1683  this.widthValueSetInPercentage = false;
1684  for(var i = 0; i < widths.length; i++) {
1685   if(this.IsPercentageWidth(widths[i])) {
1686    this.percentSizeConfig.width = widths[i];
1687    this.widthValueSetInPercentage = true;
1688    break;
1689   }
1690  }
1691 },
1692 IsPercentageWidth: function(width) { return ASPx.IsPercentageSize(width); },
1693 UpdatePercentHeightConfig: function(heights) {
1694  this.heightValueSetInPercentage = false;
1695    for(var i = 0; i < heights.length; i++) {
1696   if(ASPx.IsPercentageSize(heights[i])) {
1697    this.percentSizeConfig.height = heights[i];
1698    this.heightValueSetInPercentage = true;
1699    break;
1700   }
1701  }
1702 },
1703 GetAdjustedSizes: function() {
1704  var mainElement = this.GetMainElement();
1705  if(mainElement) 
1706   return { width: mainElement.offsetWidth, height: mainElement.offsetHeight };
1707  return { width: 0, height: 0 };
1708 },
1709 IsAdjusted: function() {
1710  return (this.adjustedSizes.width && this.adjustedSizes.width > 0) && (this.adjustedSizes.height && this.adjustedSizes.height > 0);
1711 },
1712 IsAdjustmentRequired: function() {
1713  if(!this.IsAdjusted())
1714   return true;
1715  if(this.widthValueSetInPercentage)
1716   return true;
1717  if(this.heightValueSetInPercentage)
1718   return true;
1719  var sizes = this.GetAdjustedSizes();
1720  for(var name in sizes){
1721   if(this.adjustedSizes[name] !== sizes[name])
1722    return true;
1723  }
1724  return false;
1725 },
1726 IsAdjustmentAllowed: function() {
1727  var mainElement = this.GetMainElement();
1728  return mainElement && this.IsDisplayed() && !this.IsHidden() && this.IsDOMInitialized();
1729 },
1730 UpdateAdjustedSizes: function() {
1731  var sizes = this.GetAdjustedSizes();
1732  for(var name in sizes)
1733   if(sizes.hasOwnProperty(name))
1734    this.adjustedSizes[name] = sizes[name];
1735 },
1736 AdjustControlCore: function() {
1737 },
1738 AdjustAutoHeight: function() {
1739 },
1740 IsControlCollapsed: function() {
1741  return this.isControlCollapsed;
1742 },
1743 NeedCollapseControl: function() {
1744  return this.NeedCollapseControlCore() && this.IsAdjustmentRequired() && this.IsAdjustmentAllowed();
1745 },
1746 NeedCollapseControlCore: function() {
1747  return false;
1748 },
1749 CollapseEditor: function() {
1750 },
1751 CollapseControl: function() {
1752  this.SaveScrollPositions();
1753  var mainElement = this.GetMainElement(),
1754   marker = this.GetControlPercentSizeMarker();
1755  marker.style.height = this.heightValueSetInPercentage && this.sizingConfig.supp
1755ortPercentHeight
1756   ? this.percentSizeConfig.height 
1757   : (mainElement.offsetHeight + "px");
1758  mainElement.style.display = "none";
1759  this.isControlCollapsed = true;
1760 },
1761 ExpandControl: function() {
1762  var mainElement = this.GetMainElement();
1763  mainElement.style.display = "";
1764  this.GetControlPercentSizeMarker().style.height = "0px";
1765  this.isControlCollapsed = false;
1766  this.RestoreScrollPositions();
1767 },
1768 CanCauseReadjustment: function() {
1769  return this.NeedCollapseControlCore();
1770 },
1771 IsExpandableByAdjustment: function() {
1772  return false;
1773 },
1774 HasFixedPosition: function() {
1775  return false;
1776 },
1777 SaveScrollPositions: function() {
1778  var mainElement = this.GetMainElement();
1779  this.scrollPositionState.outer = ASPx.GetOuterScrollPosition(mainElement.parentNode);
1780  this.scrollPositionState.inner = ASPx.GetInnerScrollPositions(mainElement);
1781 },
1782 RestoreScrollPositions: function() {
1783  ASPx.RestoreOuterScrollPosition(this.scrollPositionState.outer);
1784  ASPx.RestoreInnerScrollPositions(this.scrollPositionState.inner);
1785 },
1786 GetControlPercentSizeMarker: function() {
1787  if(this.percentSizeMarker === undefined) {
1788   this.percentSizeMarker = ASPx.CreateHtmlElementFromString("<div style='height:0px;font-size:0px;line-height:0;width:100%;'></div>");
1789   ASPx.InsertElementAfter(this.percentSizeMarker, this.GetMainElement());
1790  }
1791  return this.percentSizeMarker;
1792 },
1793 KeepControlPercentSizeMarker: function(needCollapse, needCalculateHeight) {
1794  var marker = this.GetControlPercentSizeMarker(),
1795   markerHeight;
1796  if(needCollapse)
1797   this.CollapseControl();
1798  if(this.widthValueSetInPercentage && marker.style.width !== this.percentSizeConfig.width)
1799   marker.style.width = this.percentSizeConfig.width;
1800  if(needCalculateHeight) {
1801   if(this.IsControlCollapsed())
1802    markerHeight = marker.style.height;
1803   marker.style.height = this.percentSizeConfig.height;
1804  }
1805  this.percentSizeConfig.markerWidth = marker.offsetWidth;
1806  if(needCalculateHeight) {
1807   this.percentSizeConfig.markerHeight = marker.offsetHeight;
1808   if(this.IsControlCollapsed())
1809    marker.style.height = markerHeight;
1810   else
1811    marker.style.height = "0px";
1812  }
1813  if(needCollapse)
1814   this.ExpandControl();
1815 },
1816 ResetControlPercentMarkerSize: function() {
1817  this.percentSizeConfig.markerWidth = -1;
1818  this.percentSizeConfig.markerHeight = -1;
1819 },
1820 GetControlPercentMarkerSize: function(hideControl, force) {
1821  var needCalculateHeight = this.heightValueSetInPercentage && this.sizingConfig.supportPercentHeight;
1822  if(force || this.percentSizeConfig.markerWidth < 1 || (needCalculateHeight && this.percentSizeConfig.markerHeight < 1))
1823   this.KeepControlPercentSizeMarker(hideControl && !this.IsControlCollapsed(), needCalculateHeight);
1824  return {
1825   width: this.percentSizeConfig.markerWidth,
1826   height: this.percentSizeConfig.markerHeight
1827  };
1828 },
1829 AssignEllipsisTooltips: function() {
1830  if(this.RequireAssignTooltips())
1831   this.AssignEllipsisTooltipsCore();
1832 },
1833 AssignEllipsisTooltipsCore: function(rootElement, reassingExistingTooltips) {
1834  var requirePaddingManipulation = ASPx.Browser.Edge || ASPx.Browser.Firefox;
1835  rootElement = rootElement || this.GetMainElement();
1836  var nodes = this.GetEllipsisNodes(rootElement);
1837  var nodeInfos = [];
1838  var nodesCount = nodes.length;
1839  for(var i = 0; i < nodesCount; i++) {
1840   var node = nodes[i];
1841   var info = { node: node };
1842   if(requirePaddingManipulation) {
1843    var style = ASPx.GetCurrentStyle(node);
1844    info.paddingLeft = node.style.paddingLeft;
1845    info.totalPadding = ASPx.GetLeftRightPaddings(node, style);
1846   }
1847   nodeInfos.push(info);
1848  }
1849  if(requirePaddingManipulation) {
1850   for(var i = 0; i < nodesCount; i++) {
1851    var info = nodeInfos[i];
1852    ASPx.SetStyles(info.node, { paddingLeft: info.totalPadding }, true);
1853   }
1854  }
1855  for(var i = 0; i < nodesCount; i++) {
1856   var info = nodeInfos[i];
1857   var node = info.node;
1858   info.isTextShortened = node.scrollWidth > node.clientWidth;
1859   info.hasTitle = ASPx.Attr.GetAttribute(node, "title") !== null;
1860   if(!info.hasTitle || reassingExistingTooltips)
1861    info.title = ASPx.GetEllipsisTooltipText(node);
1862  }
1863  for(var i = 0; i < nodesCount; i++) {
1864   var info = nodeInfos[i];
1865   var node = info.node;
1866   if(info.isTextShortened && info.title) {
1867    ASPx.Attr.SetAttribute(node, "title", info.title);
1868    ASPx.Attr.SetAttribute(node, ELLIPSIS_TOOLTIP_MARKER_ATTR, true);
1869   }
1870   if(!info.isTextShortened && info.hasTitle)
1871    ASPx.Attr.RemoveAttribute(node, "title");
1872  }
1873  if(requirePaddingManipulation) {
1874   for(var i = 0; i < nodesCount; i++) {
1875    var info = nodeInfos[i];
1876    var node = info.node;
1877    node.style.paddingLeft = info.paddingLeft;
1878   }
1879  }
1880 },
1881 GetEllipsisNodes: function(element) {
1882  var ellipsibleNodes = ASPx.Data.CollectionToArray(ASPx.GetNodesByClassName(element, ELLIPSIS_MARKER_CLASS));
1883  if(ASPx.ElementHasCssClass(element, ELLIPSIS_MARKER_CLASS))
1884   ellipsibleNodes.push(element);
1885  return ellipsibleNodes.filter(function(node) {
1886   return !ASPx.Attr.IsExistsAttribute(node, "title") || ASPx.Attr.IsExistsAttribute(node, ELLIPSIS_TOOLTIP_MARKER_ATTR);
1887  });
1888 },
1889 RequireAssignTooltips: function() {
1890  return this.enableEllipsis && !ASPx.Browser.MobileUI;
1891 },
1892 RemoveEllipsisFromNode: function(node) {
1893  ASPx.RemoveClassNameFromElement(node, ELLIPSIS_MARKER_CLASS);
1894  this.RemoveEllipsisTooltip(node);
1895 },
1896 RemoveEllipsisTooltip: function(node) {
1897  if(ASPx.Attr.IsExistsAttribute(node, ELLIPSIS_TOOLTIP_MARKER_ATTR)) {
1898   ASPx.Attr.RemoveAttribute(node, "title");
1899   ASPx.Attr.RemoveAttribute(node, ELLIPSIS_TOOLTIP_MARKER_ATTR);
1900  }
1901 },
1902 OnBrowserWindowResize: function(e) {
1903 },
1904 OnBrowserWindowResizeInternal: function(e){
1905  if(this.BrowserWindowResizeSubscriber()) 
1906   this.OnBrowserWindowResize(e);
1907 },
1908 BrowserWindowResizeSubscriber: function() {
1909  return this.widthValueSetInPercentage || !this.IsAdjusted();
1910 },
1911 ShrinkWrappedText: function(getElements, key, reCorrect) {
1912  if(!ASPx.Browser.Safari) return;
1913  var elements = ASPx.CacheHelper.GetCachedElements(this, key, getElements, this.wrappedTextContainers);
1914  for(var i = 0; i < elements.length; i++)
1915   this.ShrinkWrappedTextInContainer(elements[i], reCorrect);
1916 },
1917 ShrinkWrappedTextInContainer: function(container, reCorrect) {
1918  if(!ASPx.Browser.Safari || !container || (container.dxWrappedTextShrinked && !reCorrect) || container.offsetWidth === 0) return;
1919  ASPx.ShrinkWrappedTextInContainer(container);
1920  container.dxWrappedTextShrinked = true;
1921 },
1922 CorrectWrappedText: function(getElements, key, reCorrect) {
1923  var elements = ASPx.CacheHelper.GetCachedElements(this, key, getElements, this.wrappedTextContainers);
1924  for(var i = 0; i < elements.length; i++)
1925   this.CorrectWrappedTextInContainer(elements[i], reCorrect);
1926 },
1927 CorrectWrappedTextInContainer: function(container, reCorrect) {
1928  if(!container || (container.dxWrappedTextCorrected && !reCorrect) || container.offsetWidth === 0) return;
1929  ASPx.AdjustWrappedTextInContainer(container);
1930  container.dxWrappedTextCorrected = true;
1931 },
1932 CorrectVerticalAlignment: function(alignMethod, getElements, key, reAlign) {
1933  var elements = ASPx.CacheHelper.GetCachedElements(this, key, getElements, this.verticalAlignedElements);
1934  for(var i = 0; i < elements.length; i++)
1935   this.CorrectElementVerticalAlignment(alignMethod, elements[i], reAlign);
1936 },
1937 CorrectElementVerticalAlignment: function(alignMethod, element, reAlign) {
1938  if(!element || (element.dxVerticalAligned && !reAlign) || element.offsetHeight === 0) return;
1939  alignMethod(element);
1940  element.dxVerticalAligned = true;
1941 },
1942 ClearVerticalAlignedElementsCache: function() {
1943  ASPx.CacheHelper.DropCache(this.verticalAlignedElements);
1944 },
1945 ClearWrappedTextContainersCache: function() {
1946  ASPx.CacheHelper.DropCache(this.wrappedTextContainers);
1947 },
1948 AdjustPagerControls: function() {
1949  if(typeof(ASPx.GetPagersCollection) != "undefined")
1950   ASPx.GetPagersCollection().AdjustControls(this.GetMainElement());
1951 },
1952 RegisterInControlTree: function(tree) {
1953  var mainElement = this.GetMainElement();
1954  if(mainElement && mainElement.id)
1955   tree.createNode(mainElement.id, this);
1956 },
1957 GetItemElementName: function(element) {
1958  var name = "";
1959  if(element.id)
1960   name = element.id.substring(this.name.length + 1);
1961  return name;
1962 },
1963 GetLinkElement: function(element) {
1964  if(element == null) return null;
1965  return (element.tagName == "A") ? element : ASPx.GetNodeByTagName(element, "A", 0);
1966 },
1967 GetInternalHyperlinkElement: function(parentElement, index) {
1968  var element = ASPx.GetNodeByTagName(parentElement, "A", index);
1969  if(element == null) 
1970   element = ASPx.GetNodeByTagName(parentElement, "SPAN", index);
1971  return element;
1972 },
1973 OnControlClick: function(clickedElement, htmlEvent) {
1974 }
1975});
1976ASPxClientControl.Cast = function(obj) {
1977 if(typeof obj == "string")
1978  return window[obj];
1979 return obj;
1980};
1981ASPxClientControl.AdjustControls = function(container, collapseControls){
1982 aspxGetControlCollection().AdjustControls(container, collapseControls);
1983};
1984ASPxClientControl.GetControlCollection = function(){
1985 return aspxGetControlCollection();
1986};
1987ASPxClientControl.LeadingAfterInitCallConsts = {
1988 None: 0,
1989 Direct: 1,
1990 Reverse: 2
1991};
1992var ASPxClientComponent = ASPx.CreateClass(ASPxClientControl, {
1993 constructor: function (name) {
1994  this.constructor.prototype.constructor.call(this, name);
1995 },
1996 IsDOMDisposed: function() { 
1997  return false;
1998 }
1999});
2000var ASPxClientControlCollection = ASPx.CreateClass(ASPx.CollectionBase, {
2001 constructor: function(){
2002  this.constructor.prototype.constructor.call(this);
2003  this.prevWndWidth = "";
2004  this.prevWndHeight = "";
2005  this.requestCountInternal = 0; 
2006  this.BeforeInitCallback = new ASPxClientEvent();
2007  this.ControlsInitialized = new ASPxClientEvent();
2008  this.BrowserWindowResized = new ASPxClientEvent();
2009  this.BrowserWindowResizedInternal = new ASPxClientEvent();
2010  this.BeginCallback = new ASPxClientEvent();
2011  this.EndCallback = new ASPxClientEvent();
2012  this.CallbackError = new ASPxClientEvent();
2013  this.ValidationCompleted = new ASPxClientEvent();
2014  aspxGetControlCollectionCollection().Add(this);
2015 },
2016 Add: function(element) {
2017  var existsElement = this.Get(element.name);
2018  if(existsElement && existsElement !== element) 
2019   this.Remove(existsElement);
2020  ASPx.CollectionBase.prototype.Add.call(this, element.name, element);
2021 },
2022 Remove: function(element) {
2023  if(element && element instanceof ASPxClientControl && !element.IsDisposed())
2024   element.OnDispose();
2025  ASPx.CollectionBase.prototype.Remove.call(this, element.name);
2026 },
2027 GetGlobal: function(name) {
2028  var result = window[name];
2029  return result && Ident.IsASPxClientControl(result)
2030   ? result
2031   : null;
2032 },
2033 GetByName: function(name){
2034  return this.Get(name) || this.GetGlobal(name);
2035 },
2036 GetCollectionType: function(){
2037  return ASPxClientControlCollection.BaseCollectionType;
2038 },
2039 GetControlsByPredicate: function(predicate) {
2040  var result = [];
2041  this.ForEachControl(function(control) {
2042   if(!predicate || predicate(control))
2043    result.push(control);
2044  });
2045  return result;
2046 },
2047 GetControlsByType: function(type) {
2048  return this.GetControlsByPredicate(function(control) { 
2049   return type && (control instanceof type);
2050  });
2051 },
2052 ForEachControl: function(action, context) {
2053  context = context || this;
2054  this.elementsMap.forEachEntry(function(name, control) {
2055   if(Ident.IsASPxClientControl(control) && (!this.filterPredicate || this.filterPredicate(control)))
2056    return action.call(context, control);
2057  }, context);
2058 },
2059 ProcessActionByPredicate: function(action, predicate) {
2060  try {
2061   this.filterPredicate = predicate;
2062   action(this);
2063  }
2064  finally {
2065   this.filterPredicate = null;
2066  }
2067 },
2068 adjustControlsInternal: function(container, context, collapseControls, adjustFunc) {
2069  context = context || this;
2070  var func = function(control) {
2071   adjustFunc.call(context, control);
2072  };
2073  ASPx.GetControlAdjuster().adjustControlsInHierarchy(this, func, container, collapseControls);
2074 },
2075 AdjustControls: function(container, collapseControls) {
2076  container = container || null;
2077  window.setTimeout(function() {
2078   this.AdjustControlsCore(container, collapseControls);
2079  }.aspxBind(this), 0);
2080 },
2081 AdjustControlsCore: function(container, collapseControls) {
2082  var adjustFunction = function(control) { control.AdjustControl(); };
2083  this.adjustControlsInternal(container, this, collapseControls, adjustFunction);
2084 },
2085 CollapseControls: function(container) {
2086  this.ProcessControlsInContainer(container, function(control) {
2087   if(control.isASPxClientEdit)
2088    control.CollapseEditor();
2089   else if(!!window.ASPxClientRibbon && control instanceof ASPxClientRibbon)
2090    control.CollapseControl();
2091  });
2092 },
2093 AtlasInitialize: function(isCallback) {
2094  this.ForEachControl(function(control) {
2095   control.AtlasPreInitialize();
2096  });
2097  ASPx.ProcessScriptsAndLinks("", isCallback);
2098  this.ForEachControl(function(control) {
2099   control.AtlasInitialize();
2100  });
2101 },
2102 DOMContentLoaded: function() {
2103  this.ForEachControl(function(control){
2104    control.DOMContentLoaded();
2105  });
2106 },
2107 OnDocumentUnload: function() {
2108  this.ForEachControl(function(control) {
2109   control.RaiseUnload();
2110  });
2111 },
2112 Initialize: function() {
2113  ASPx.GetPostHandler().Post.AddHandler(
2114   function(s, e) { this.OnPost(e); }.aspxBind(this)
2115  );
2116  ASPx.GetPostHandler().PostFinalization.AddHandler(
2117   function(s, e) { this.OnPostFinalization(e); }.aspxBind(this)
2118  );
2119  this.InitializeElements(false );
2120  if(typeof(Sys) != "undefined" && typeof(Sys.Application) != "undefined") {
2121   var checkIsInitialized = function() {
2122    if(Sys.Application.get_isInitialized())
2123     Sys.Application.add_load(aspxCAInit);
2124    else
2125     setTimeout(checkIsInitialized, 0);
2126   };
2127   checkIsInitialized();
2128  }
2129  this.InitWindowSizeCache();
2130 },
2131 FinalizeInitialization: function() {
2132  this.ForEachControl(function(control) {
2133   control.FinalizeInitialization();
2134  });
2135 },
2136 InitializeElements: function(isCallback) {
2137  this.ForEachControl(function(control){
2138   if(!control.isInitialized)
2139    control.Initialize();
2140  });
2141  this.AfterInitializeElementsLeadingCall();
2142  this.AfterInitializeElements();
2143  this.RaiseControlsInitialized(isCallback);
2144 },
2145 AfterInitializeElementsLeadingCall: function() {
2146  var controls = {};
2147  controls[ASPxClientControl.LeadingAfterInitCallConsts.Direct] = [];
2148  controls[ASPxClientControl.LeadingAfterInitCallConsts.Reverse] = [];
2149  this.ForEachControl(function(control) {
2150   if(control.leadingAfterInitCall != ASPxClientControl.LeadingAfterInitCallConsts.None && !control.isInitialized)
2151    controls[control.leadingAfterInitCall].push(control);
2152  });
2153  var directInitControls = controls[ASPxClientControl.LeadingAfterInitCallConsts.Direct],
2154   reverseInitControls = controls[ASPxClientControl.LeadingAfterInitCallConsts.Reverse];
2155  for(var i = 0, control; control = directInitControls[i]; i++)
2156   control.AfterInitialize();
2157  for(var i = reverseInitControls.length - 1, control; control = reverseInitControls[i]; i--)
2158   control.AfterInitialize();
2159 },
2160 AfterInitializeElements: function() {
2161  this.ForEachControl(function(control) {
2162   if(control.leadingAfterInitCall == ASPxClientControl.LeadingAfterInitCallConsts.None && !control.isInitialized)
2163    control.AfterInitialize();
2164  });
2165  ASPx.RippleHelper.Init();
2166 },
2167 DoFinalizeCallback: function() {
2168  this.ForEachControl(function(control){
2169   control.DoFinalizeCallback();
2170  });
2171 },
2172 ProcessControlsInContainer: function(container, processFunc, filterFunc) {
2173  this.ForEachControl(function(control){
2174   if((!filterFunc || filterFunc(control)) && (!container || this.IsControlInContainer(container, control)))
2175    processFunc(control);
2176  });
2177 },
2178 IsControlInContainer: function(container, control) {
2179  if(control.GetMainElement) {
2180   var mainElement = control.GetMainElement();
2181   if(mainElement && (mainElement != container)) {
2182    if(ASPx.GetIsParent(container, mainElement))
2183     return true;
2184   }
2185  }
2186  return false;
2187 },
2188 RaiseControlsInitialized: function(isCallback) {
2189  if(typeof(isCallback) == "undefined")
2190   isCallback = true;
2191  var args = new ASPxClientControlsInitializedEventArgs(isCallback);
2192  if(!this.ControlsInitialized.IsEmpty())  
2193   this.ControlsInitialized.FireEvent(this, args);
2194  this.ForEachControl(function(control){
2195   control.OnGlobalControlsInitialized(args);
2196  });
2197 },
2198 RaiseBrowserWindowResized: function() {
2199  var args = new ASPxClientEventArgs();
2200  if(!this.BrowserWindowResized.IsEmpty())
2201   this.BrowserWindowResized.FireEvent(this, args);
2202  this.ForEachControl(function(control){
2203   control.OnGlobalBrowserWindowResized(args);
2204  });
2205 },
2206 RaiseBrowserWindowResizedInternal: function(eventInfo) {
2207  var args = new ASPxClientBrowserWindowResizedInternalEventArgs(eventInfo);
2208  if(!this.BrowserWindowResizedInternal.IsEmpty())
2209   this.BrowserWindowResizedInternal.FireEvent(this, args);
2210 },
2211 RaiseBeginCallback: function (control, command) {
2212  var args = new ASPxClientGlobalBeginCallbackEventArgs(control, command);
2213  if(!this.BeginCallback.IsEmpty())
2214   this.BeginCallback.FireEvent(this, args);
2215  this.ForEachControl(function(control){
2216   control.OnGlobalBeginCallback(args);
2217  });
2218  this.IncrementRequestCount();
2219 },
2220 RaiseEndCallback: function (control) {
2221  var args = new ASPxClientGlobalEndCallbackEventArgs(control);
2222  if (!this.EndCallback.IsEmpty()) 
2223   this.EndCallback.FireEvent(this, args);
2224  this.ForEachControl(function(control){
2225   control.OnGlobalEndCallback(args);
2226  });
2227  this.DecrementRequestCount();
2228 },
2229 InCallback: function() {
2230  return this.requestCountInternal > 0;
2231 },
2232 RaiseCallbackError: function (control, message, callbackId) {
2233  var args = new ASPxClientGlobalCallbackErrorEventArgs(control, message, callbackId);
2234  if (!this.CallbackError.IsEmpty()) 
2235   this.CallbackError.FireEvent(this, args);
2236  this.ForEachControl(function(control){
2237   control.OnGlobalCallbackError(args);
2238  });
2239  if(args.handled)
2240   return { isHandled: true, errorMessage: args.message };  
2241  return { isHandled: false, errorMessage: message };
2242 },
2243 RaiseValidationCompleted: function (container, validationGroup, invisibleControlsValidated, isValid, firstInvalidControl, firstVisibleInvalidControl) {
2244  var args = new ASPxClientValidationCompletedEventArgs(container, validationGroup, invisibleControlsValidated, isValid, firstInvalidControl, firstVisibleInvalidControl);
2245  if (!this.ValidationCompleted.IsEmpty()) 
2246   this.ValidationCompleted.FireEvent(this, args);
2247  this.ForEachControl(function(control){
2248   control.OnGlobalValidationCompleted(args);
2249  });
2250  return args.isValid;
2251 },
2252 Before_WebForm_InitCallback: function(callbackOwnerID){
2253  var args = new BeforeInitCallbackEventArgs(callbackOwnerID);
2254  this.BeforeInitCallback.FireEvent(this, args);
2255 },
2256 InitWindowSizeCache: function(){
2257  this.prevWndWidth = ASPx.GetDocumentClientWidth();
2258  this.prevWndHeight = ASPx.GetDocumentClientHeight();
2259 },
2260 OnBrowserWindowResize: function(evt){
2261  this.OnBrowserWindowResizeCore(evt);
2262 },
2263 OnBrowserWindowResizeCore: function(htmlEvent){
2264  var args = this.CreateOnBrowserWindowResizeEventArgs(htmlEvent);
2265  if(this.CalculateIsBrowserWindowSizeChanged()) {
2266   this.RaiseBrowserWindowResizedInternal(args);
2267   this.adjustControlsInternal(null, this, true, function(control) {
2268    if(control.IsDOMInitialized())
2269     control.OnBrowserWindowResizeInternal(args);
2270   });
2271   this.RaiseBrowserWindowResized();
2272  }
2273 },
2274 CreateOnBrowserWindowResizeEventArgs: function(htmlEvent) {
2275  return {
2276   htmlEvent: htmlEvent,
2277   wndWidth: ASPx.GetDocumentClientWidth(),
2278   wndHeight: ASPx.GetDocumentClientHeight(),
2279   prevWndWidth: this.prevWndWidth,
2280   prevWndHeight: this.prevWndHeight,
2281   virtualKeyboardShownOnAndroid: this.IsVirtualKeyboardShownOnAndroid()
2282  };
2283 },
2284 IsVirtualKeyboardShownOnAndroid: function() {
2285  if(!ASPx.Browser.AndroidMobilePlatform)
2286   return false;
2287  var documentClientWidth = ASPx.GetDocumentClientWidth();
2288  var documentClientHeight = ASPx.GetDocumentClientHeight();
2289  var isDocumentClientHeightChangedOnly = documentClientWidth === this.prevWndWidth && documentClientHeight !== this.prevWndHeight;
2290  return isDocumentClientHeightChangedOnly && this.IsElementSupportKeyboardInput(document.activeElement);
2291 },
2292 IsElementSupportKeyboardInput: function(element) {
2293  if(!element || !element.tagName)
2294   return false;
2295  var supportedKeyboardInputTagNames = ["INPUT", "TEXTAREA"];
2296  return supportedKeyboardInputTagNames.indexOf(element.tagName) !== -1;
2297 },
2298 CalculateIsBrowserWindowSizeChanged: function(){
2299  var wndWidth = ASPx.GetDocumentClientWidth();
2300  var wndHeight = ASPx.GetDocumentClientHeight();
2301  var isBrowserWindowSizeChanged = (this.prevWndWidth != wndWidth) || (this.prevWndHeight != wndHeight);
2302  if(isBrowserWindowSizeChanged){
2303   this.prevWndWidth = wndWidth;
2304   this.prevWndHeight = wndHeight;
2305   return true;
2306  }
2307  return false;
2308 },
2309 OnPost: function(args){
2310  this.ForEachControl(function(control) {
2311   control.OnPost(args);
2312  }, null);
2313 },
2314 OnPostFinalization: function(args){
2315  this.ForEachControl(function(control) {
2316   control.OnPostFinalization(args);
2317  }, null);
2318 },
2319 IncrementRequestCount: function() {
2320  this.requestCountInternal++;
2321 },
2322 DecrementRequestCount: function() {
2323  this.requestCountInternal--;
2324 },
2325 ResetRequestCount: function() {
2326  this.requestCountInternal = 0;
2327 }
2328});
2329ASPxClientControlCollection.BaseCollectionType = "Control";
2330var controlCollection = null;
2331function aspxGetControlCollection(){
2332 if(controlCollection == null) {
2333  controlCollection = new ASPxClientControlCollection();
2334  if(ASPx.loadControlCollectionPreloadHandlers)
2335   ASPx.loadControlCollectionPreloadHandlers(controlCollection);
2336 }
2337 return controlCollection;
2338}
2339var ControlCollectionCollection = ASPx.CreateClass(ASPx.CollectionBase, {
2340 constructor: function(){
2341  this.constructor.prototype.constructor.call(this);
2342 },
2343 Add: function(element) {
2344  var key = element.GetCollectionType();
2345  if(!key) throw "The collection type isn't specified.";
2346  if(this.Get(key)) throw "The collection with type='" + key + "' already exists.";
2347  ASPx.CollectionBase.prototype.Add.call(this, key, element);
2348 },
2349 RemoveDisposedControls: function(){
2350  var baseCollection = this.Get(ASPxClientControlCollection.BaseCollectionType);
2351  var disposedControls = [];
2352  baseCollection.elementsMap.forEachEntry(function(name, control) {
2353   if(!ASPx.Ident.IsASPxClientControl(control)) return;
2354   if(control.IsDOMDisposed())
2355    disposedControls.push(control);
2356  });
2357  this.RemoveControls(disposedControls);
2358 },
2359 RemoveControls: function(controls){
2360  for(var i = 0; i < controls.length; i++) {
2361   this.elementsMap.forEachEntry(function(key, collection) {
2362    if(ASPx.Ident.IsASPxClientCollection(collection))
2363     collection.Remove(controls[i]);
2364   });
2365  }
2366 }
2367});
2368var controlCollectionCollection = null;
2369function aspxGetControlCollectionCollection(){
2370 if(controlCollectionCollection == null)
2371  controlCollectionCollection = new ControlCollectionCollection();
2372 return controlCollectionCollection;
2373}
2374var AriaDescriptionAttributes = {
2375 Role: "0",
2376 AriaLabel: "1",
2377 TabIndex: "2",
2378 AriaOwns: "3",
2379 AriaDescribedBy: "4",
2380 AriaDisabled: "5",
2381 AriaHasPopup: "6",
2382 AriaLevel: "7"
2383};
2384var AriaDescriptor = ASPx.CreateClass(null, {
2385 constructor: function(ownerControl, description) {
2386  this.ownerControl = ownerControl;
2387  this.rootElement = ownerControl.GetMainElement();
2388  this.description = description;
2389 },
2390 setDescription: function(name, argList) {
2391  var description = this.findChildDescription(name);
2392  if(description) {
2393   var elements = name ? this.rootElement.querySelectorAll(this.getDescriptionSelector(description)) : [this.rootElement];
2394   for(var i = 0; i < elements.length; i++)
2395    this.applyDescriptionToElement(elements[i], description, argList[i] || argList[0]);
2396  }
2397 },
2398 getDescriptionName: function(description) {
2399  return description.n;
2400 },
2401 getDescriptionSelector: function(description) {
2402  return description.s;
2403 },
2404 findChildDescription: function(name) {
2405  if(name === this.getDescriptionName(this.description))
2406   return this.description;
2407  var childCollection = this.description.c || [];
2408  for(var i = 0; i < childCollection.length; i++) {
2409   var childDescription = childCollection[i];
2410   if(this.getDescriptionName(childDescription) === name)
2411    return childDescription;
2412  }
2413  return null;
2414 },
2415 applyDescriptionToElement: function(element, description, args) {
2416  if(!description || !element)
2417   return;
2418  this.trySetAriaOwnsAttribute(element, description);
2419  this.trySetAriaDescribedByAttribute(element, description);
2420  this.trySetAttribute(element, description, AriaDescriptionAttributes.Role, "role");
2421  this.trySetAttribute(element, description, AriaDescriptionAttributes.TabIndex, "tabindex");
2422  this.trySetAttribute(element, description, AriaDescriptionAttributes.AriaLevel, "aria-level");
2423  this.executeOnDescription(description, AriaDescriptionAttributes.AriaLabel, function(value) {
2424   ASPx.Attr.SetAttribute(element, "aria-label", ASPx.Str.ApplyReplacement(value, args
2424));
2425  });
2426  this.executeOnDescription(description, AriaDescriptionAttributes.AriaDisabled, function(value) {
2427   ASPx.Attr.SetAttribute(element, "aria-disabled", !!value); 
2428  });
2429  this.executeOnDescription(description, AriaDescriptionAttributes.AriaHasPopup, function(value) {
2430   ASPx.Attr.SetAttribute(element, "aria-haspopup", !!value);
2431  });
2432 },
2433 trySetAriaDescribedByAttribute: function(element, description) {
2434  this.executeOnDescription(description, AriaDescriptionAttributes.AriaDescribedBy, function(selectorInfo) {
2435   var descriptor = this.getNodesBySelector(element, selectorInfo.descriptorSelector)[0];
2436   var target = this.getNodesBySelector(element, selectorInfo.targetSelector)[0];
2437   if(!target || !descriptor)
2438    return;
2439   ASPx.Attr.SetAttribute(target, "aria-describedby", this.getNodeId(descriptor));
2440  });
2441 },
2442 trySetAriaOwnsAttribute: function(element, description) {
2443  this.executeOnDescription(description, AriaDescriptionAttributes.AriaOwns, function(selector) {
2444   var ownedNodes = this.getNodesBySelector(element, selector);
2445   var ariaOwnsAttributeValue = "";
2446   for(var i = 0; i < ownedNodes.length; i++)
2447    ariaOwnsAttributeValue += (this.getNodeId(ownedNodes[i]) + (i != ownedNodes.length - 1 ? " " : ""));
2448   ASPx.Attr.SetAttribute(element, "aria-owns", ariaOwnsAttributeValue);
2449  });
2450 },
2451 trySetAttribute: function(element, description, ariaAttribute, attributeName) {
2452  this.executeOnDescription(description, ariaAttribute, function(value) { 
2453   ASPx.Attr.SetAttribute(element, attributeName, description[ariaAttribute]); 
2454  });
2455 },
2456 executeOnDescription: function(description, ariaDescAttr, callback) {
2457  var descInfo = description[ariaDescAttr];
2458  if(ASPx.IsExists(descInfo))
2459   callback.aspxBind(this)(descInfo);
2460 },
2461 getNodesBySelector: function(element, selector) {
2462  var id = element.id || "";
2463  var childNodes = element.querySelectorAll("#" + this.getNodeId(element) + " > " + selector);
2464  ASPx.Attr.SetOrRemoveAttribute(element, "id", id);
2465  return childNodes;
2466 },
2467 getNodeId: function(node) {
2468  if(!node.id)
2469   node.id = this.createRandomId();
2470  return node.id; 
2471 },
2472 createRandomId: function() {
2473  return "r" + ASPx.CreateGuid();
2474 }
2475});
2476PagerCommands = {
2477 Next : "PBN",
2478 Prev : "PBP",
2479 Last : "PBL",
2480 First : "PBF",
2481 PageNumber : "PN",
2482 PageSize : "PSP"
2483};
2484ASPx.callbackProcessed = false;
2485ASPx.Callback = function(result, context){ 
2486 var collection = aspxGetControlCollection();
2487 collection.DoFinalizeCallback();
2488 var control = collection.Get(context);
2489 if(control != null)
2490  control.DoCallback(result);
2491 ASPx.RippleHelper.ReInit();
2492 ASPx.callbackProcessed = true;
2493};
2494ASPx.CallbackError = function(result, context){
2495 var control = aspxGetControlCollection().Get(context);
2496 if(control != null)
2497  control.DoCallbackError(result, false);
2498 ASPx.callbackProcessed = true;
2499};
2500ASPx.CClick = function(name, evt) {
2501 var control = aspxGetControlCollection().Get(name);
2502 if(control != null) control.DoControlClick(evt);
2503};
2504function aspxCAInit() {
2505 var isAppInit = typeof(Sys$_Application$initialize) != "undefined" &&
2506  ASPx.FunctionIsInCallstack(arguments.callee, Sys$_Application$initialize, 10 );
2507 aspxGetControlCollection().AtlasInitialize(!isAppInit);
2508}
2509ASPx.Evt.AttachEventToElement(window, "resize", aspxGlobalWindowResize);
2510function aspxGlobalWindowResize(evt){
2511 aspxGetControlCollection().OnBrowserWindowResize(evt); 
2512}
2513ASPx.Evt.AttachEventToElement(window, "unload", aspxClassesUnload);
2514function aspxClassesUnload(evt) {
2515 aspxGetControlCollection().OnDocumentUnload();
2516}
2517ASPx.attachToLoad(aspxClassesDOMContentLoaded);
2518function aspxClassesDOMContentLoaded(evt){
2519 aspxGetControlCollection().DOMContentLoaded();
2520}
2521ASPx.GetControlCollection = aspxGetControlCollection;
2522ASPx.GetControlCollectionCollection = aspxGetControlCollectionCollection;
2523ASPx.GetPersistentControlPropertiesStorage = _aspxGetPersistentControlPropertiesStorage;
2524ASPx.PagerCommands = PagerCommands;
2525ASPx.ELLIPSIS_MARKER_CLASS = ELLIPSIS_MARKER_CLASS;
2526window.ASPxClientBeginCallbackEventArgs = ASPxClientBeginCallbackEventArgs;
2527window.ASPxClientGlobalBeginCallbackEventArgs = ASPxClientGlobalBeginCallbackEventArgs;
2528window.ASPxClientEndCallbackEventArgs = ASPxClientEndCallbackEventArgs;
2529window.ASPxClientGlobalEndCallbackEventArgs = ASPxClientGlobalEndCallbackEventArgs;
2530window.ASPxClientCallbackErrorEventArgs = ASPxClientCallbackErrorEventArgs;
2531window.ASPxClientGlobalCallbackErrorEventArgs = ASPxClientGlobalCallbackErrorEventArgs;
2532window.ASPxClientCustomDataCallbackEventArgs = ASPxClientCustomDataCallbackEventArgs;
2533window.ASPxClientValidationCompletedEventArgs = ASPxClientValidationCompletedEventArgs;
2534window.ASPxClientControlsInitializedEventArgs = ASPxClientControlsInitializedEventArgs;
2535window.ASPxClientControlBeforePronounceEventArgs = ASPxClientControlBeforePronounceEventArgs;
2536window.ASPxClientControlUnloadEventArgs = ASPxClientControlUnloadEventArgs;
2537window.ASPxClientEndFocusEventArgs = ASPxClientEndFocusEventArgs;
2538window.ASPxClientItemFocusedEventArgs = ASPxClientItemFocusedEventArgs;
2539window.ASPxClientControlCollection = ASPxClientControlCollection;
2540window.ASPxClientControlBase = ASPxClientControlBase;
2541window.ASPxClientControl = ASPxClientControl;
2542window.ASPxClientComponent = ASPxClientComponent;
2543})(ASPx);
2544
2545(function () {
2546 var PositionAnimationTransition = ASPx.CreateClass(ASPx.AnimationTransitionBase, {
2547  constructor: function (element, options) {
2548   this.constructor.prototype.constructor.call(this, element, options);
2549   this.direction = options.direction;
2550   this.animationTransition = this.createAnimationTransition();
2551   AnimationHelper.appendWKAnimationClassNameIfRequired(this.element);
2552  },
2553  Start: function (to) {
2554   var from = this.GetValue();
2555   if(ASPx.AnimationUtils.CanUseCssTransform()) {
2556    from = this.convertPosToCssTransformPos(from);
2557    to = this.convertPosToCssTransformPos(to);
2558   }
2559   this.animationTransition.Start(from, to);
2560  },
2561  SetValue: function (value) {
2562   ASPx.AnimationUtils.SetTransformValue(this.element, value, this.direction == AnimationHelper.SLIDE_VERTICAL_DIRECTION);
2563  },
2564  GetValue: function () {
2565   return ASPx.AnimationUtils.GetTransformValue(this.element, this.direction == AnimationHelper.SLIDE_VERTICAL_DIRECTION);
2566  },
2567  createAnimationTransition: function () {
2568   var transition = ASPx.AnimationUtils.CanUseCssTransform() ? this.createTransformAnimationTransition() : this.createPositionAnimationTransition();
2569   transition.transition = ASPx.AnimationConstants.Transitions.POW_EASE_OUT;
2570   return transition;
2571  },
2572  createTransformAnimationTransition: function () {
2573   return ASPx.AnimationUtils.createCssAnimationTransition(this.element, {
2574    property: ASPx.AnimationUtils.CanUseCssTransform(),
2575    duration: this.duration,
2576    onComplete: this.onComplete
2577   });
2578  },
2579  createPositionAnimationTransition: function () {
2580   return AnimationHelper.createAnimationTransition(this.element, {
2581    property: this.direction == AnimationHelper.SLIDE_VERTICAL_DIRECTION ? "top" : "left",
2582    unit: "px",
2583    duration: this.duration,
2584    onComplete: this.onComplete
2585   });
2586  },
2587  convertPosToCssTransformPos: function (position) {
2588   return ASPx.AnimationUtils.GetTransformCssText(position, this.direction == AnimationHelper.SLIDE_VERTICAL_DIRECTION);
2589  }
2590 });
2591 var AnimationHelper = {
2592  SLIDE_HORIZONTAL_DIRECTION: 0,
2593  SLIDE_VERTICAL_DIRECTION: 1,
2594  SLIDE_TOP_DIRECTION: 0,
2595  SLIDE_RIGHT_DIRECTION: 1,
2596  SLIDE_BOTTOM_DIRECTION: 2,
2597  SLIDE_LEFT_DIRECTION: 3,
2598  SLIDE_CONTAINER_CLASS: "dxAC",
2599  MAXIMUM_DEPTH: 3,
2600  createAnimationTransition: function (element, options) {
2601   if(options.onStep)
2602    options.animationEngineType = AnimationEngineType.JS;
2603   switch(options.animationEngineType) {
2604    case AnimationEngineType.JS:
2605     return ASPx.AnimationUtils.createJsAnimationTransition(element, options);
2606    case AnimationEngineType.CSS:
2607     return ASPx.AnimationUtils.createCssAnimationTransition(element, options);
2608    default:
2609     return ASPx.AnimationUtils.CanUseCssTransition() ? ASPx.AnimationUtils.createCssAnimationTransition(element, options) :
2610      ASPx.AnimationUtils.createJsAnimationTransition(element, options);
2611   }
2612  },
2613  createMultipleAnimationTransition: function (element, options) {
2614   return ASPx.AnimationUtils.createMultipleAnimationTransition(element, options);
2615  },
2616  createSimpleAnimationTransition: function (options) {
2617   return ASPx.AnimationUtils.createSimpleAnimationTransition(options);
2618  },
2619  cancelAnimation: function (element) {
2620   ASPx.AnimationTransitionBase.Cancel(element);
2621  },
2622  fadeIn: function(element, onComplete, duration, animationEngineType) {
2623   AnimationHelper.fadeTo(element, {
2624    from: 0, to: 1,
2625    onComplete: onComplete,
2626    animationEngineType: animationEngineType || AnimationEngineType.DEFAULT,
2627    duration: duration || ASPx.AnimationConstants.Durations.DEFAULT
2628   });
2629  },
2630  fadeOut: function(element, onComplete, duration, animationEngineType) {
2631   AnimationHelper.fadeTo(element, {
2632    from: ASPx.GetElementOpacity(element), to: 0,
2633    onComplete: onComplete,
2634    animationEngineType: animationEngineType || AnimationEngineType.DEFAULT,
2635    duration: duration || ASPx.AnimationConstants.Durations.DEFAULT
2636   });
2637  },
2638  fadeTo: function (element, options) {
2639   options.property = "opacity";
2640   if(!options.duration)
2641    options.duration = ASPx.AnimationConstants.Durations.SHORT;
2642   var transition = AnimationHelper.createAnimationTransition(element, options);
2643   if(!ASPx.IsExists(options.from))
2644    options.from = transition.GetValue();
2645   transition.Start(options.from, options.to);
2646  },
2647  slideIn: function (element, direction, onComplete, animationEngineType, rtl) {
2648   AnimationHelper.setOpacity(element, 1);
2649   var animationContainer = AnimationHelper.getSlideAnimationContainer(element, true, true);
2650   var pos = AnimationHelper.getSlideInStartPos(animationContainer, direction, rtl);
2651   var transition = AnimationHelper.createSlideTransition(animationContainer, direction,
2652    function (el) {
2653     AnimationHelper.resetSlideAnimationContainerSize(animationContainer);
2654     if(onComplete)
2655      onComplete(el);
2656    }, animationEngineType, rtl);
2657   transition.Start(pos, 0);
2658  },
2659  slideOut: function (element, direction, onComplete, animationEngineType, rtl) {
2660   var animationContainer = AnimationHelper.getSlideAnimationContainer(element, true, true);
2661   var pos = AnimationHelper.getSlideOutFinishPos(animationContainer, direction, rtl);
2662   var transition = AnimationHelper.createSlideTransition(animationContainer, direction,
2663    function (el) {
2664     AnimationHelper.setOpacity(el.firstChild, 0);
2665     if(onComplete)
2666      onComplete(el);
2667    }, animationEngineType, rtl);
2668   transition.Start(pos);
2669  },
2670  slideTo: function (element, options) {
2671   if(!ASPx.IsExists(options.direction))
2672    options.direction = AnimationHelper.SLIDE_HORIZONTAL_DIRECTION;
2673   var transition = new PositionAnimationTransition(element, options);
2674   transition.Start(options.to);
2675  },
2676  setOpacity: function (element, value) {
2677   ASPx.AnimationUtils.setOpacity(element, value);
2678  },
2679  appendWKAnimationClassNameIfRequired: function (element) {
2680   if(ASPx.AnimationUtils.CanUseCssTransform() && ASPx.Browser.WebKitFamily && !ASPx.ElementHasCssClass(element, "dx-wbv"))
2681    element.className += " dx-wbv";
2682  },
2683  findSlideAnimationContainer: function (element) {
2684   var container = element;
2685   for(var i = 0; i < AnimationHelper.MAXIMUM_DEPTH; i++) {
2686    if(container.tagName == "BODY")
2687     return null;
2688    if(ASPx.ElementHasCssClass(container, AnimationHelper.SLIDE_CONTAINER_CLASS))
2689     return container;
2690    container = container.parentNode;
2691   }
2692   return null;
2693  },
2694  createSlideAnimationContainer: function (element) {
2695   var rootContainer = document.createElement("DIV");
2696   ASPx.SetStyles(rootContainer, {
2697    className: AnimationHelper.SLIDE_CONTAINER_CLASS,
2698    overflow: "hidden"
2699   });
2700   var elementContainer = document.createElement("DIV");
2701   rootContainer.appendChild(elementContainer);
2702   var parentNode = element.parentNode;
2703   parentNode.insertBefore(rootContainer, element);
2704   elementContainer.appendChild(element);
2705   return rootContainer;
2706  },
2707  getSlideAnimationContainer: function (element, create, fixSize) {
2708   if(!element) return;
2709   var width = element.offsetWidth;
2710   var height = element.offsetHeight;
2711   var container;
2712   if(element.className == AnimationHelper.SLIDE_CONTAINER_CLASS)
2713    container = element;
2714   if(!container)
2715    container = AnimationHelper.findSlideAnimationContainer(element);
2716   if(!container && create)
2717    container = AnimationHelper.createSlideAnimationContainer(element);
2718   if(container && fixSize) {
2719    ASPx.SetStyles(container, {
2720     width: width, height: height
2721    });
2722    ASPx.SetStyles(container.firstChild, {
2723     width: width, height: height
2724    });
2725   }
2726   return container;
2727  },
2728  resetSlideAnimationContainerSize: function (container) {
2729   ASPx.SetStyles(container, {
2730    width: "", height: ""
2731   });
2732   ASPx.SetStyles(container.firstChild, {
2733    width: "", height: ""
2734   });
2735  },
2736  getModifyProperty: function (direction, rtl) {
2737   if(direction == AnimationHelper.SLIDE_TOP_DIRECTION || direction == AnimationHelper.SLIDE_BOTTOM_DIRECTION)
2738    return "marginTop";
2739   return rtl ? "margin-right" : "margin-left";
2740  },
2741  createSlideTransition: function (animationContainer, direction, complete, animationEngineType, rtl) {
2742   if(rtl == undefined)
2743    rtl = false;
2744   return AnimationHelper.createAnimationTransition(animationContainer.firstChild, {
2745    unit: "px",
2746    property: AnimationHelper.getModifyProperty(direction, rtl),
2747    needForceTransitionEndByTimerFlag: true, 
2748    onComplete: complete,
2749    animationEngineType: animationEngineType
2750   });
2751  },
2752  getSlideInStartPos: function (animationContainer, direction, rtl) {
2753   var dir = rtl ? -1 : 1;
2754   switch (direction) {
2755    case AnimationHelper.SLIDE_TOP_DIRECTION:
2756     return animationContainer.offsetHeight;
2757    case AnimationHelper.SLIDE_LEFT_DIRECTION:
2758     return animationContainer.offsetWidth * dir;
2759    case AnimationHelper.SLIDE_RIGHT_DIRECTION:
2760     return -animationContainer.offsetWidth * dir;
2761    case AnimationHelper.SLIDE_BOTTOM_DIRECTION:
2762     return -animationContainer.offsetHeight;
2763   }
2764  },
2765  getSlideOutFinishPos: function (animationContainer, direction, rtl) {
2766   var dir = rtl ? -1 : 1;
2767   switch (direction) {
2768    case AnimationHelper.SLIDE_TOP_DIRECTION:
2769     return -animationContainer.offsetHeight;
2770    case AnimationHelper.SLIDE_LEFT_DIRECTION:
2771     return -animationContainer.offsetWidth * dir;
2772    case AnimationHelper.SLIDE_RIGHT_DIRECTION:
2773     return animationContainer.offsetWidth * dir;
2774    case AnimationHelper.SLIDE_BOTTOM_DIRECTION:
2775     return animationContainer.offsetHeight;
2776   }
2777  }
2778 };
2779 var GestureHandler = ASPx.CreateClass(null, {
2780  constructor: function (getAnimationElement, canHandle, allowStart) {
2781   this.getAnimationElement = getAnimationElement;
2782   this.canHandle = canHandle;
2783   this.allowStart = allowStart;
2784   this.startMousePosX = 0;
2785   this.startMousePosY = 0;
2786   this.startTime = null;
2787   this.isEventsPrevented = false;
2788   this.savedElements = [];
2789  },
2790  OnSelectStart: function(evt) {
2791   ASPx.Evt.PreventEvent(evt); 
2792  },
2793  OnDragStart: function(evt) {
2794   ASPx.Evt.PreventEvent(evt);  
2795  },
2796  OnMouseDown: function (evt) {
2797   this.startMousePosX = ASPx.Evt.GetEventX(evt);
2798   this.startMousePosY = ASPx.Evt.GetEventY(evt);
2799   this.startTime = new Date();
2800  },
2801  OnMouseMove: function(evt) {
2802   if(!ASPx.Browser.MobileUI)
2803    ASPx.Selection.Clear();
2804   if(Math.abs(this.GetCurrentDistanceX(evt)) < GestureHandler.SLIDER_MIN_START_DISTANCE && Math.abs(this.GetCurrentDistanceY(evt)) < GestureHandler.SLIDER_MIN_START_DISTANCE)
2805    GesturesHelper.isExecutedGesture = false;
2806  },
2807  OnMouseUp: function (evt) {
2808  },
2809  CanHandleEvent: function (evt) {
2810   return !this.canHandle || this.canHandle(evt);
2811  },
2812  IsStartAllowed: function(value) {
2813   return !this.allowStart || this.allowStart(value);
2814  },
2815  RollbackGesture: function () {
2816  },
2817  GetRubberPosition: function (position) {
2818   return position / GestureHandler.FACTOR_RUBBER;
2819  },
2820  GetCurrentDistanceX: function (evt) {
2821   return ASPx.Evt.GetEventX(evt) - this.startMousePosX;
2822  },
2823  GetCurrentDistanceY: function (evt) {
2824   return ASPx.Evt.GetEventY(evt) - this.startMousePosY;
2825  },
2826  GetDistanceLimit: function () {
2827   return (new Date() - this.startTime) < GestureHandler.MAX_TIME_SPAN ? GestureHandler.MIN_DISTANCE_LIMIT : GestureHandler.MAX_DISTANCE_LIMIT;
2828  },
2829  GetContainerElement: function () {
2830  },
2831  AttachPreventEvents: function (evt) {
2832   if(!this.isEventsPrevented) {
2833    var element = ASPx.Evt.GetEventSource(evt);
2834    var container = this.GetContainerElement();
2835    while(element && element != container) {
2836     ASPx.Evt.AttachEventToElement(element, "mouseup", ASPx.Evt.PreventEvent);
2837     ASPx.Evt.AttachEventToElement(element, "click", ASPx.Evt.PreventEvent);
2838     this.savedElements.push(element);
2839     element = element.parentNode;
2840    }
2841    this.isEventsPrevented = true;
2842   }
2843  },
2844  DetachPreventEvents: function () {
2845   if(this.isEventsPrevented) {
2846    window.setTimeout(function () {
2847     while(this.savedElements.length > 0) {
2848      var element = this.savedElements.pop();
2849      ASPx.Evt.DetachEventFromElement(element, "mouseup", ASPx.Evt.PreventEvent);
2850      ASPx.Evt.DetachEventFromElement(element, "click", ASPx.Evt.PreventEvent);
2851     }
2852    }.aspxBind(this), 0);
2853    this.isEventsPrevented = false;
2854   }
2855  }
2856 });
2857 GestureHandler.MAX_DISTANCE_LIMIT = 70;
2858 GestureHandler.MIN_DISTANCE_LIMIT = 10;
2859 GestureHandler.MIN_START_DISTANCE = 0;
2860 GestureHandler.SLIDER_MIN_START_DISTANCE = 5;
2861 GestureHandler.MAX_TIME_SPAN = 300;
2862 GestureHandler.FACTOR_RUBBER = 4;
2863 GestureHandler.RETURN_ANIMATION_DURATION = 150;
2864 var SwipeSlideGestureHandler = ASPx.CreateClass(GestureHandler, {
2865  constructor: function (getAnimationElement, direction, canHandle, backward, forward, rollback, move) {
2866   this.constructor.prototype.constructor.call(this, getAnimationElement, canHandle);
2867   this.slideElement = this.getAnimationElement();
2868   this.container = this.slideElement.parentNode;
2869   this.direction = direction;
2870   this.backward = backward;
2871   this.forward = forward;
2872   this.rollback = rollback;
2873   this.slideElementSize = 0;
2874   this.containerElementSize = 0;
2875   this.startSliderElementPosition = 0;
2876   this.centeredSlideElementPosition = 0;
2877  },
2878  OnMouseDown: function (evt) {
2879   GestureHandler.prototype.OnMouseDown.call(this, evt);
2880   this.slideElementSize = this.GetElementSize();
2881   this.startSliderElementPosition = this.GetElementPosition();
2882   this.containerElementSize = this.GetContainerElementSize();
2883   if(this.slideElementSize <= this.containerElementSize)
2884    this.centeredSlideElementPosition = (this.containerElementSize - this.slideElementSize) / 2;
2885  },
2886  OnMouseMove: function (evt) {
2887   GestureHandler.prototype.OnMouseMove.call(this, evt);
2888   if(!ASPx.Browser.TouchUI && !ASPx.GetIsParent(this.container, ASPx.Evt.GetEventSource(evt))) {
2889    GesturesHelper.OnDocumentMouseUp(evt);
2890    return;
2891   }
2892   var distance = this.GetCurrentDistance(evt);
2893   if(Math.abs(distance) < GestureHandler.SLIDER_MIN_START_DISTANCE || ASPx.TouchUIHelper.isGesture)
2894    return;
2895   this.SetElementPosition(this.GetCalculatedPosition(distance));
2896   this.AttachPreventEvents(evt);
2897   ASPx.Evt.PreventEvent(evt);
2898  },
2899  GetCalculatedPosition: function (distance) {
2900   ASPx.AnimationTransitionBase.Cancel(this.slideElement);
2901   var position = this.startSliderElementPosition + distance,
2902    maxPosition = -(this.slideElementSize - this.containerElementSize),
2903    minPosition = 0;
2904   if(this.centeredSlideElementPosition > 0)
2905    position = this.GetRubberPosition(distance) + this.centeredSlideElementPosition;
2906   else if(position > minPosition)
2907    position = this.GetRubberPosition(distance);
2908   else if(position < maxPosition)
2909    position = this.GetRubberPosition(distance) + maxPosition;
2910   return position;
2911  },
2912  OnMouseUp: function (evt) {
2913   this.DetachPreventEvents();
2914   if(this.GetCurrentDistance(evt) != 0)
2915    this.OnMouseUpCore(evt);
2916  },
2917  OnMouseUpCore: function (evt) {
2918   var distance = this.GetCurrentDistance(evt);
2919   if(this.centeredSlideElementPosition > 0 || this.CheckSlidePanelIsOutOfBounds())
2920    this.PerformRollback();
2921   else
2922    this.PerformAction(distance);
2923  },
2924  PerformAction: function (distance) {
2925   if(Math.abs(distance) < this.GetDistanceLimit())
2926    this.PerformRollback();
2927   else if(distance < 0)
2928    this.PerformForward();
2929   else
2930    this.PerformBackward();
2931  },
2932  PerformBackward: function () {
2933   this.backward();
2934  },
2935  PerformForward: function () {
2936   this.forward();
2937  },
2938  PerformRollback: function () {
2939   this.rollback();
2940  },
2941  CheckSlidePanelIsOutOfBounds: function () {
2942   var minOffset = -(this.slideElementSize - this.containerElementSize), maxOffset = 0;
2943   var slideElementPos = this.GetElementPosition();
2944   if(slideElementPos > maxOffset || slideElementPos < minOffset)
2945    return true;
2946   return false;
2947  },
2948  GetContainerElement: function () {
2949   return this.container;
2950  },
2951  GetElementSize: function () {
2952   return this.IsHorizontalDirection() ? this.slideElement.offsetWidth : this.slideElement.offsetHeight;
2953  },
2954  GetContainerElementSize: function () {
2955   return this.IsHorizontalDirection() ? ASPx.GetClearClientWidth(this.container) : ASPx.GetClearClientHeight(this.container);
2956  },
2957  GetCurrentDistance: function (evt) {
2958   return this.IsHorizontalDirection() ? this.GetCurrentDistanceX(evt) : this.GetCurrentDistanceY(evt);
2959  },
2960  GetElementPosition: function () {
2961   return ASPx.AnimationUtils.GetTransformValue(this.slideElement, !this.IsHorizontalDirection());
2962  },
2963  SetElementPosition: function (position) {
2964   ASPx.AnimationUtils.SetTransformValue(this.slideElement, position, !this.IsHorizontalDirection());
2965  },
2966  IsHorizontalDirection: function () {
2967   return this.direction == AnimationHelper.SLIDE_HORIZONTAL_DIRECTION;
2968  }
2969 });
2970 var SwipeSimpleSlideGestureHandler = ASPx.CreateClass(SwipeSlideGestureHandler, {
2971  constructor: function (getAnimationElement, direction, canHandle, backward, forward, rollback, updatePosition) {
2972   this.constructor.prototype.constructor.call(this, getAnimationElement, direction, canHandle, backward, forward, rollback);
2973   this.container = this.slideElement;
2974   this.updatePosition = updatePosition;
2975   this.prevDistance = 0;
2976  },
2977  OnMouseDown: function (evt) {
2978   GestureHandler.prototype.OnMouseDown.call(this, evt);
2979   this.prevDistance = 0;
2980  },
2981  OnMouseUpCore: function (evt) {
2982   this.PerformAction(this.GetCurrentDistance(evt));
2983  },
2984  PerformAction: function (distance) {
2985   if(Math.abs(distance) < this.GetDistanceLimit())
2986    this.PerformRollback();
2987   else if(distance < 0)
2988    this.PerformForward();
2989   else
2990    this.PerformBackward();
2991  },
2992  GetCalculatedPosition: function (distance) {
2993   var position = distance - this.prevDistance;
2994   this.prevDistance = distance;
2995   return position;
2996  },
2997  SetElementPosition: function (position) {
2998   this.updatePosition(position);
2999  }
3000 });
3001 var SwipeGestureHandler = ASPx.CreateClass(GestureHandler, {
3002  constructor: function (getAnimationElement, canHandle, allowStart, start, allowComplete, complete, cancel, animationEngineType, rtl) {
3003   this.constructor.prototype.constructor.call(this, getAnimationElement, canHandle, allowStart);
3004   this.start = start;
3005   this.allowComplete = allowComplete;
3006   this.complete = complete;
3007   this.cancel = cancel;
3008   this.animationTween = null;
3009   this.currentDistanceX = 0;
3010   this.currentDistanceY = 0;
3011   this.tryStartGesture = false;
3012   this.tryStartScrolling = false;
3013   this.animationEngineType = animationEngineType;
3014   this.rtl = rtl;
3015   this.UpdateAnimationContainer();
3016  },
3017  UpdateAnimationContainer: function () {
3018   this.animationContainer = AnimationHelper.getSlideAnimationContainer(this.getAnimationElement(), true, false);
3019  },
3020  CanHandleEvent: function (evt) {
3021   if(GestureHandler.prototype.CanHandleEvent.call(this, evt))
3022    return true;
3023   return this.animationTween && this.animationContainer && ASPx.GetIsParent(this.animationContainer, ASPx.Evt.GetEventSource(evt));
3024  },
3025  OnMouseDown: function (evt) {
3026   GestureHandler.prototype.OnMouseDown.call(this, evt);
3027   if(this.animationTween)
3028    this.animationTween.Cancel();
3029   this.currentDistanceX = 0;
3030   this.currentDistanceY = 0;
3031   this.tryStartGesture = false;
3032   this.tryStartScrolling = false;
3033  },
3034  OnMouseMove: function (evt) {
3035   GestureHandler.prototype.OnMouseMove.call(this, evt);
3036   var isZoomGestureConflict = evt.touches && evt.touches.length > 1;
3037   if (isZoomGestureConflict)
3038    return false;
3039   this.currentDistanceX = this.GetCurrentDistanceX(evt);
3040   this.currentDistanceY = this.GetCurrentDistanceY(evt);
3041   if(this.rtl)
3042    this.currentDistanceX = -this.currentDistanceX;
3043   if(!this.animationTween && !this.tryStartScrolling && (Math.abs(this.currentDistanceX) >
3044    GestureHandler.MIN_START_DISTANCE || Math.abs(this.currentDistanceY) > GestureHandler.MIN_START_DISTANCE)) {
3045    if(Math.abs(this.currentDistanceY) < Math.abs(this.currentDistanceX)) {
3046     this.tryStartGesture = true;
3047     if(this.IsStartAllowed(this.currentDistanceX)) {
3048      this.animationContainer = AnimationHelper.getSlideAnimationContainer(this.getAnimationElement(), true, true);
3049      this.animationTween = AnimationHelper.createSlideTransition(this.animationContainer, AnimationHelper.SLIDE_LEFT_DIRECTION,
3050       function () {
3051        AnimationHelper.resetSlideAnimationContainerSize(this.animationContainer);
3052        this.animationContainer = null;
3053        this.animationTween = null;
3054       }.aspxBind(this), this.animationEngineType, this.rtl);
3055      this.PerformStart(this.currentDistanceX);
3056      this.AttachPreventEvents(evt);
3057     }
3058    }
3059    else
3060     this.tryStartScrolling = true;
3061   }
3062   if(this.animationTween) {
3063    if(this.allowComplete && !this.allowComplete(this.currentDistanceX))
3064     this.currentDistanceX = this.GetRubberPosition(this.currentDistanceX);
3065    this.animationTween.SetValue(this.currentDistanceX);
3066   }
3067   if(!this.tryStartScrolling && !ASPx.TouchUIHelper.isGesture && evt.touches && evt.touches.length < 2)
3068    ASPx.Evt.PreventEvent(evt);
3069  },
3070  OnMouseUp: function (evt) {
3071   if(!this.animationTween) {
3072    if(this.tryStartGesture)
3073     this.PerformCancel(this.currentDistanceX);
3074   }
3075   else {
3076    if(Math.abs(this.currentDistanceX) < this.GetDistanceLimit())
3077     this.RollbackGesture();
3078    else {
3079     if(this.IsCompleteAllowed(this.currentDistanceX)) {
3080      this.PerformComplete(this.currentDistanceX);
3081      this.animationContainer = null;
3082      this.animationTween = null;
3083     }
3084     else
3085      this.RollbackGesture();
3086    }
3087   }
3088   this.DetachPreventEvents();
3089   this.tryStartGesture = false;
3090   this.tryStartScrolling = false;
3091  },
3092  PerformStart: function (value) {
3093   if(this.start)
3094    this.start(value);
3095  },
3096  IsCompleteAllowed: function (value) {
3097   return !this.allowComplete || this.allowComplete(value);
3098  },
3099  PerformComplete: function (value) {
3100   if(this.complete)
3101    this.complete(value);
3102  },
3103  PerformCancel: function (value) {
3104   if(this.cancel)
3105    this.cancel(value);
3106  },
3107  RollbackGesture: function () {
3108   this.animationTween.Start(this.currentDistanceX, 0);
3109  },
3110  ResetGestureElementPosition: function () {
3111   if (this.currentDistanceX === 0) return;
3112   var container = AnimationHelper.getSlideAnimationContainer(this.getAnimationElement());
3113   var onComplete = function () { AnimationHelper.resetSlideAnimationContainerSize(container); };
3114   var animation = AnimationHelper.createSlideTransition(container, AnimationHelper.SLIDE_LEFT_DIRECTION, onComplete, this.animationEngineType, this.rtl);
3115   animation.Start(this.currentDistanceX, 0);
3116  },
3117  GetContainerElement: function () {
3118   return this.animationContainer;
3119  }
3120 });
3121 var GesturesHelper = {
3122  handlers: {},
3123  activeHandler: null,
3124  isAttachedEvents: false,
3125  isExecutedGesture: false,
3126  AddSwipeGestureHandler: function (id, getAnimationElement, canHandle, allowStart, start, allowComplete, complete, cancel, animationEngineType, rtl) {
3127   this.handlers[id] = new SwipeGestureHandler(getAnimationElement, canHandle, allowStart, start, allowComplete, complete, cancel, animationEngineType, rtl);
3128  },
3129  UpdateSwipeAnimationContainer: function (id) {
3130   if(this.handlers[id])
3131    this.handlers[id].UpdateAnimationContainer();
3132  },
3133  AddSwipeSlideGestureHandler: function (id, getAnimationElement, direction, canHandle, backward, forward, rollback, updatePosition) {
3134   if(updatePosition)
3135    this.handlers[id] = new SwipeSimpleSlideGestureHandler(getAnimationElement, direction, canHandle, backward, forward, rollback, updatePosition);
3136   else
3137    this.handlers[id] = new SwipeSlideGestureHandler(getAnimationElement, direction, canHandle, backward, forward, rollback);
3138  },
3139  getParentDXEditorWithSwipeGestures: function(element) {
3140     return ASPx.GetParent(element, function(parent) {
3141      var parentObj = ASPx.GetControlCollection().Get(parent.id);
3142      return parentObj && parentObj.supportGestures && parentObj.isSwipeGesturesEnabled();
3143   });
3144  },
3145  canHandleMouseDown: function(evt) {
3146   if(!ASPx.Evt.IsLeftButtonPressed(evt))
3147    return false;
3148   var element = ASPx.Evt.GetEventSource(evt);
3149   var dxFocusedEditor = ASPx.Ident.scripts.ASPxClientEdit && ASPx.GetFocusedEditor();
3150   if(dxFocusedEditor && dxFocusedEditor.IsEditorElement(element)) {
3151    var elementParentDXEditorWithSwipeGestures = GesturesHelper.getParentDXEditorWithSwipeGestures(element);
3152    if(!elementParentDXEditorWithSwipeGestures || !dxFocusedEditor.IsEditorElement(elementParentDXEditorWithSwipeGestures))
3153     return false;
3154   }
3155   var isTextEditor = element.tagName == "TEXTAREA" || element.tagName == "INPUT" && ASPx.Attr.GetAttribute(element, "type") == "text";
3156   if(isTextEditor && document.activeElement == element)
3157    return false;
3158   return true;  
3159  },
3160  OnDocumentDragStart: function(evt) {
3161   if(GesturesHelper.activeHandler)
3162    GesturesHelper.activeHandler.OnDragStart(evt);
3163  },
3164  OnDocumentMouseDown: function (evt) {
3165   if(!GesturesHelper.canHandleMouseDown(evt))
3166    return;
3167   GesturesHelper.activeHandler = GesturesHelper.FindHandler(evt);
3168   if(GesturesHelper.activeHandler)
3169    GesturesHelper.activeHandler.OnMouseDown(evt);
3170  },
3171  OnDocumentMouseMove: function (evt) {
3172   if(GesturesHelper.activeHandler) {
3173    GesturesHelper.isExecutedGesture = true;
3174    GesturesHelper.activeHandler.OnMouseMove(evt);
3175   }
3176  },
3177  OnDocumentMouseUp: function (evt) {
3178   if(GesturesHelper.activeHandler) {
3179    GesturesHelper.activeHandler.OnMouseUp(evt);
3180    GesturesHelper.activeHandler = null;
3181    window.setTimeout(function () { GesturesHelper.isExecutedGesture = false; }, 0);
3182   }
3183  },
3184  AttachEvents: function () {
3185   if(!GesturesHelper.isAttachedEvents) {
3186    GesturesHelper.Attach(ASPx.Evt.AttachEventToElement);
3187    GesturesHelper.isAttachedEvents = true;
3188   }
3189  },
3190  DetachEvents: function () {
3191   if(GesturesHelper.isAttachedEvents) {
3192    GesturesHelper.Attach(ASPx.Evt.DetachEventFromElement);
3193    GesturesHelper.isAttachedEvents = false;
3194   }
3195  },
3196  Attach: function (changeEventsMethod) {
3197   var doc = window.document;
3198   changeEventsMethod(doc, ASPx.TouchUIHelper.touchMouseDownEventName, GesturesHelper.OnDocumentMouseDown);
3199   changeEventsMethod(doc, ASPx.TouchUIHelper.touchMouseMoveEventName, GesturesHelper.OnDocumentMouseMove);
3200   changeEventsMethod(doc, ASPx.TouchUIHelper.touchMouseUpEventName, GesturesHelper.OnDocumentMouseUp);
3201   if(!ASPx.Browser.MobileUI) {
3202    changeEventsMethod(doc, "dragstart", GesturesHelper.OnDocumentDragStart);
3203   }
3204  },
3205  FindHandler: function (evt) {
3206   var handlers = [];
3207   for(var id in GesturesHelper.handlers) {
3208    if(GesturesHelper.handlers.hasOwnProperty(id)) {
3209     var handler = GesturesHelper.handlers[id];
3210     if(handler.CanHandleEvent && handler.CanHandleEvent(evt))
3211      handlers.push(handler);
3212    }
3213   }
3214   if(!handlers.length)
3215    return null;
3216   handlers.sort(function (a, b) {
3217    return ASPx.GetIsParent(a.getAnimationElement(), b.getAnimationElement()) ? 1 : -1;
3218   });
3219   return handlers[0];
3220  },
3221  IsExecutedGesture: function () {
3222   return GesturesHelper.isExecutedGesture;
3223  }
3224 };
3225 GesturesHelper.AttachEvents();
3226 var AnimationEngineType = {
3227  "DEFAULT": 0,
3228  "CSS": 1,
3229  "JS": 2
3230 };
3231 ASPx.AnimationEngineType = AnimationEngineType;
3232 ASPx.AnimationHelper = AnimationHelper;
3233 ASPx.GesturesHelper = GesturesHelper;
3234})();
3235
3236(function () {
3237var Constants = {
3238 Name: "ASPxGlobalEvents"
3239};
3240var ASPxClientGlobalEvents = ASPx.CreateClass(ASPxClientComponent, {
3241 constructor: function () {
3242  this.constructor.prototype.constructor.call(this, Constants.Name);
3243  this.ControlsInitialized = new ASPxClientEvent();
3244  this.BrowserWindowResized = new ASPxClientEvent();
3245  this.BeginCallback = new ASPxClientEvent();
3246  this.EndCallback = new ASPxClientEvent();
3247  this.CallbackError = new ASPxClientEvent();
3248  this.ValidationCompleted = new ASPxClientEvent();
3249 },
3250 OnGlobalControlsInitialized: function(args) { 
3251  this.ControlsInitialized.FireEvent(this, args);
3252 },
3253 OnGlobalBrowserWindowResized: function(args) { 
3254  this.BrowserWindowResized.FireEvent(this, args);
3255 },
3256 OnGlobalBeginCallback: function(args) { 
3257  this.BeginCallback.FireEvent(this, args);
3258 },
3259 OnGlobalEndCallback: function(args) { 
3260  this.EndCallback.FireEvent(this, args);
3261 },
3262 OnGlobalCallbackError: function(args) { 
3263  this.CallbackError.FireEvent(this, args);
3264 },
3265 OnGlobalValidationCompleted: function(args) { 
3266  this.ValidationCompleted.FireEvent(this, args);
3267 }
3268});
3269var globalEvents = null;
3270function aspxGetGlobalEvents() {
3271 if(globalEvents == null)
3272  globalEvents = new ASPxClientGlobalEvents();
3273 return globalEvents;
3274}
3275ASPx.GetGlobalEvents = aspxGetGlobalEvents;
3276window.ASPxClientGlobalEvents = ASPxClientGlobalEvents;
3277})();
3278(function () {
3279var PopupUtils = {
3280 NotSetAlignIndicator: "NotSet",
3281 InnerAlignIndicator: "Sides",
3282 OutsideLeftAlignIndicator: "OutsideLeft",
3283 LeftSidesAlignIndicator: "LeftSides",
3284 RightSidesAlignIndicator: "RightSides",
3285 OutsideRightAlignIndicator: "OutsideRight",
3286 CenterAlignIndicator: "Center",
3287 AboveAlignIndicator: "Above",
3288 TopSidesAlignIndicator: "TopSides",
3289 MiddleAlignIndicator: "Middle",
3290 BottomSidesAlignIndicator: "BottomSides",
3291 BelowAlignIndicator: "Below",
3292 WindowCenterAlignIndicator: "WindowCenter",
3293 LeftAlignIndicator: "Left",
3294 RightAlignIndicator: "Right",
3295 TopAlignIndicator: "Top",
3296 BottomAlignIndicator: "Bottom",
3297 WindowLeftAlignIndicator: "WindowLeft",
3298 WindowRightAlignIndicator: "WindowRight",
3299 WindowTopAlignIndicator: "WindowTop",
3300 WindowBottomAlignIndicator: "WindowBottom",
3301 IsAlignNotSet: function (align) {
3302  return align == PopupUtils.NotSetAlignIndicator;
3303 },
3304 IsInnerAlign: function (align) {
3305  return align.indexOf(PopupUtils.InnerAlignIndicator) != -1;
3306 },
3307 IsRightSidesAlign: function(align) {
3308  return align == PopupUtils.RightSidesAlignIndicator;
3309 },
3310 IsOutsideRightAlign: function(align) {
3311  return align == PopupUtils.OutsideRightAlignIndicator;
3312 },
3313 IsCenterAlign: function(align) {
3314  return align == PopupUtils.CenterAlignIndicator;
3315 },
3316 FindPopupElementById: function (id) {
3317  if(id == "")
3318   return null; 
3319  var popupElement = ASPx.GetElementById(id);
3320  if(!ASPx.IsExistsElement(popupElement)) {
3321   var idParts = id.split("_");
3322   var uniqueId = idParts.join("$");
3323   popupElement = ASPx.GetElementById(uniqueId);
3324  }
3325  return popupElement;
3326 },
3327 FindEventSourceParentByTestFunc: function (evt, testFunc) {
3328  return ASPx.GetParent(ASPx.Evt.GetEventSource(evt), testFunc);
3329 },
3330 PreventContextMenu: function (evt) {
3331  ASPx.Evt.PreventEventAndBubble(evt);
3332  if(ASPx.Browser.WebKitFamily)
3333   evt.returnValue = false;
3334 },
3335 GetDocumentClientWidthForPopup: function() {
3336  return ASPx.Browser.WebKitTouchUI ? document.body.offsetWidth : ASPx.GetDocumentClientWidth();
3337 },
3338 GetDocumentClientHeightForPopup: function() {
3339  return ASPx.Browser.WebKitTouchUI ? document.body.offsetHeight : ASPx.GetDocumentClientHeight();
3340 },
3341 AdjustPositionToClientScreen: function (element, pos, rtl, isX) {
3342  var min = isX ? ASPx.GetDocumentScrollLeft() : ASPx.GetDocumentScrollTop(),
3343   max = min + (isX ? ASPx.GetDocumentClientWidth() : ASPx.GetDocumentClientHeight());
3344  max -= (isX ? element.offsetWidth : element.offsetHeight);
3345  if(rtl && isX) {
3346   if(pos < min) pos = min;
3347   if(pos > max) pos = max;
3348  } else {
3349   if(pos > max) pos = max;
3350   if(pos < min) pos = min;
3351  }
3352  return pos;
3353 },
3354 GetPopupAbsoluteX: function(element, popupElement, hAlign, hOffset, x, left, rtl, isPopupFullCorrectionOn, showPopupInsideScreenBounds) {
3355  return PopupUtils.getPopupAbsolutePos(element, popupElement, hAlign, hOffset, x, left, rtl, isPopupFullCorrectionOn, false, false, true, showPopupInsideScreenBounds);
3356 },
3357 GetPopupAbsoluteY: function(element, popupElement, vAlign, vOffset, y, top, isPopupFullCorrectionOn, ignoreAlignWithoutScrollReserve, ignorePopupElementBorders, showPopupInsideScreenBounds) {
3358  return PopupUtils.getPopupAbsolutePos(element, popupElement, vAlign, vOffset, y, top, false, isPopupFullCorrectionOn, ignoreAlignWithoutScrollReserve, ignorePopupElementBorders, false, showPopupInsideScreenBounds);
3359 },
3360 getPopupAbsolutePos: function(element, popupElement, align, offset, startPos, startPosInit, rtl, isPopupFullCorrectionOn, ignoreAlignWithoutScrollReserve, ignorePopupElementBorders, isHorizontal, showPopupInsideScreenBounds) {
3361  var calculator = getPositionCalculator();
3362  calculator.applyParams(element, popupElement, align, offset, startPos, startPosInit, rtl, isPopupFullCorrectionOn, ignoreAlignWithoutScrollReserve, ignorePopupElementBorders, isHorizontal, showPopupInsideScreenBounds);
3363  var position = calculator.getPopupAbsolutePos();
3364  calculator.disposeState();
3365  return position;
3366 },
3367 InitAnimationProperties: function(element, onAnimStopCallString) {
3368  element.popuping = true;
3369  element.onAnimStopCallString = onAnimStopCallString;
3370 },
3371 InitAnimationDiv: function (element, x, y, onAnimStopCallString, skipSizeInit) {
3372  PopupUtils.InitAnimationProperties(element, onAnimStopCallString);
3373  PopupUtils.InitAnimationDivCore(element);
3374  if(!skipSizeInit) {
3375   ASPx.SetStyles(element, { width: "", height: "" });
3376   ASPx.SetStyles(element, { width: element.offsetWidth, height: element.offsetHeight });
3377  }
3378  ASPx.SetStyles(element, { left: x, top: y });
3379 },
3380 InitAnimationDivCore: function (element) {
3381  ASPx.SetStyles(element, {
3382   overflow: "hidden",
3383   position: "absolute"
3384  });
3385 },
3386 StartSlideAnimation: function (animationDivElement, element, iframeElement, duration, preventChangingWidth, preventChangingHeight) {
3387  if(iframeElement) {
3388   var endLeft = ASPx.PxToInt(iframeElement.style.left);
3389   var endTop = ASPx.PxToInt(iframeElement.style.top);
3390   var startLeft = ASPx.PxToInt(element.style.left) < 0 ? endLeft : animationDivElement.offsetLeft + animationDivElement.offsetWidth;
3391   var startTop = ASPx.PxToInt(element.style.top) < 0 ? endTop : animationDivElement.offsetTop + animationDivElement.offsetHeight;
3392   var properties = {
3393    left: { from: startLeft, to: endLeft, unit: "px" },
3394    top: { from: startTop, to: endTop, unit: "px" }
3395   };
3396   if(!preventChangingWidth)
3397    properties.width = { to: element.offsetWidth, unit: "px" };
3398   if(!preventChangingHeight)
3399    properties.height = { to: element.offsetHeight, unit: "px" };
3400   ASPx.AnimationHelper.createMultipleAnimationTransition(iframeElement, {
3401    duration: duration
3402   }).Start(properties);
3403  }
3404  ASPx.AnimationHelper.createMultipleAnimationTransition(element, {
3405   duration: duration,
3406   onComplete: function () { PopupUtils.AnimationFinished(animationDivElement, element); }
3407  }).Start({
3408   left: { to: 0, unit: "px" },
3409   top: { to: 0, unit: "px" }
3410  });
3411 },
3412 AnimationFinished: function (animationDivElement, element) {
3413  if(PopupUtils.StopAnimation(animationDivElement, element) && ASPx.IsExists(animationDivElement.onAnimStopCallString) &&
3414   animationDivElement.onAnimStopCallString !== "") {
3415   window.setTimeout(animationDivElement.onAnimStopCallString, 0);
3416  }
3417 },
3418 StopAnimation: function (animationDivElement, element) {
3419  if(animationDivElement.popuping) {
3420   ASPx.AnimationHelper.cancelAnimation(element);
3421   animationDivElement.popuping = false;
3422   animationDivElement.style.overflow = "visible";
3423   return true;
3424  }
3425  return false;
3426 },
3427 GetAnimationHorizontalDirection: function (popupPosition, horizontalAlign, verticalAlign, rtl) {
3428  if(PopupUtils.IsInnerAlign(horizontalAlign)
3429   && !PopupUtils.IsInnerAlign(verticalAlign)
3430   && !PopupUtils.IsAlignNotSet(verticalAlign))
3431   return 0;
3432  var toTheLeft = (horizontalAlign == PopupUtils.OutsideLeftAlignIndicator || horizontalAlign == PopupUtils.RightSidesAlignIndicator || (horizontalAlign == PopupUtils.NotSetAlignIndicator && rtl)) ^ popupPosition.isInverted;
3433  return toTheLeft ? 1 : -1;
3434 },
3435 GetAnimationVerticalDirection: function (popupPosition, horizontalAlign, verticalAlign) {
3436  if(PopupUtils.IsInnerAlign(verticalAlign)
3437   && !PopupUtils.IsInnerAlign(horizontalAlign)
3438   && !PopupUtils.IsAlignNotSet(horizontalAlign))
3439   return 0;
3440  var toTheTop = (verticalAlign == PopupUtils.AboveAlignIndicator || verticalAlign == PopupUtils.BottomSidesAlignIndicator) ^ popupPosition.isInverted;
3441  return toTheTop ? 1 : -1;
3442 },
3443 IsVerticalScrollExists: function () {
3444  var scrollIsNotHidden = ASPx.GetCurrentStyle(document.body).overflowY !== "hidden" && ASPx.GetCurrentStyle(document.documentElement).overflowY !== "hidden";
3445  return (scrollIsNotHidden && ASPx.GetDocumentHeight() > ASPx.GetDocumentClientHeight());
3446 },
3447 CoordinatesInDocumentRect: function (x, y) {
3448  var docScrollLeft = ASPx.GetDocumentScrollLeft();
3449  var docScrollTop = ASPx.GetDocumentScrollTop();
3450  return (x > docScrollLeft && y > docScrollTop &&
3451   x < ASPx.GetDocumentClientWidth() + docScrollLeft &&
3452   y < ASPx.GetDocumentClientHeight() + docScrollTop);
3453 },
3454 GetElementZIndexArray: function (element) {
3455  var currentElement = element;
3456  var zIndexesArray = [0];
3457  while(currentElement && currentElement.tagName != "BODY") {
3458   if(currentElement.style) {
3459    if(typeof (currentElement.style.zIndex) != "undefined" && currentElement.style.zIndex != "")
3460     zIndexesArray.unshift(currentElement.style.zIndex);
3461   }
3462   currentElement = currentElement.parentNode;
3463  }
3464  return zIndexesArray;
3465 },
3466 IsHigher: function (higherZIndexArrat, zIndexArray) {
3467  if(zIndexArray == null) return true;
3468  var count = (higherZIndexArrat.length >= zIndexArray.length) ? higherZIndexArrat.length : zIndexArray.length;
3469  for(var i = 0; i < count; i++)
3470   if(typeof (higherZIndexArrat[i]) != "undefined" && typeof (zIndexArray[i]) != "undefined") {
3471    var higherZIndexArrayCurrentElement = parseInt(higherZIndexArrat[i].toString());
3472    var zIndexArrayCurrentElement = parseInt(zIndexArray[i].toString());
3473    if(higherZIndexArrayCurrentElement != zIndexArrayCurrentElement)
3474     return higherZIndexArrayCurrentElement > zIndexArrayCurrentElement;
3475   } else return typeof (zIndexArray[i]) == "undefined";
3476  return true;
3477 },
3478 TestIsPopupElement: function (element) {
3479  return !!element.DXPopupElementControl;
3480 },
3481 adjustViewportScrollWrapper: function(wrapper, wrapperScroll, windowElement) {
3482  var document = wrapper.ownerDocument;
3483  var window = document.defaultView || document.parentWindow;
3484  var isWindowElementDisplayed = ASPx.IsElementDisplayed(windowElement);
3485  if(!isWindowElementDisplayed) {
3486   wrapper.style.cssText = "";
3487   wrapperScroll.style.cssText = "";
3488   return; 
3489  }
3490  var windowRect = windowElement.getBoundingClientRect();
3491  var yAxis = this.calculateViewPortScrollDataByAxis(wrapper.style.top, windowRect.top, windowElement.offsetHeight, window.innerHeight, wrapper.scrollTop);
3492  var xAxis = this.calculateViewPortScrollDataByAxis(wrapper.style.left, windowRect.left, windowElement.offsetWidth, window.innerWidth, wrapper.scrollLeft);
3493  this.prepareViewPortScrollData(xAxis, yAxis);
3494  ASPx.SetStyles(windowElement, {
3495   top: yAxis.windowOffset,
3496   left: xAxis.windowOffset
3497  });
3498  ASPx.SetStyles(wrapper, {
3499   width: xAxis.wrapperSize,
3500   height: yAxis.wrapperSize,
3501   position: "absolute",
3502   overflow: ASPx.Browser.MobileUI ? "scroll" : "auto",
3503   zIndex: windowElement.style.zIndex
3504  });
3505  ASPx.SetAbsoluteX(wrapper, ASPx.GetDocumentScrollLeft());
3506  ASPx.SetAbsoluteY(wrapper, ASPx.GetDocumentScrollTop());
3507  ASPx.SetStyles(wrapperScroll, {
3508   width: xAxis.wrapperScrollSize,
3509   height: yAxis.wrapperScrollSize,
3510   position: "absolute",
3511   overflow: "hidden"
3512  });
3513  wrapper.scrollLeft = xAxis.scrollSize;
3514  wrapper.scrollTop = yAxis.scrollSize;
3515 },
3516 calculateViewPortScrollDataByAxis: function(wrapperOffsetStyle, windowOffset, windowSize, viewPortSize, scrollSize) {
3517  var isWindowOffsetNegative = windowOffset < 0;
3518  windowOffset = isWindowOffsetNegative ? 0 : windowOffset;
3519  var wrapperScrollSize = Math.max(viewPortSize + Math.abs(Math.min(0, windowOffset)), windowSize + Math.abs(windowOffset));
3520  return { 
3521   windowOffset: isWindowOffsetNegative ? 0 : windowOffset,
3522   wrapperSize: viewPortSize,
3523   wrapperScrollSize: wrapperScrollSize,
3524   scrollSize: isWindowOffsetNegative ? scrollSize + Math.abs(windowOffset) : 0,
3525   hasScroll: wrapperScrollSize > viewPortSize
3526  };
3527 },
3528 prepareViewPortScrollData: function(xAxis, yAxis) {
3529  var scrollBarSize = ASPx.GetVerticalScrollBarWidth();
3530  if(yAxis.hasScroll && !xAxis.hasScroll) {
3531   xAxis.wrapperScrollSize = Math.min(xAxis.wrapperSize - scrollBarSize, xAxis.wrapperScrollSize);
3532  } else if(xAxis.hasScroll && !yAxis.hasScroll) {
3533   yAxis.wrapperScrollSize = Math.min(yAxis.wrapperSize - scrollBarSize, yAxis.wrapperScrollSize);
3534  } else if(yAxis.hasScroll && xAxis.hasScroll) {
3535   yAxis.wrapperScrollSize -= scrollBarSize;
3536   xAxis.wrapperScrollSize -= scrollBarSize;
3537  }
3538 }
3539};
3540PopupUtils.OverControl = {
3541 GetPopupElementByEvt: function (evt) {
3542  return PopupUtils.FindEventSourceParentByTestFunc(evt, PopupUtils.TestIsPopupElement);
3543 },
3544 OnMouseEvent: function (evt, mouseOver) {
3545  var popupElement = PopupUtils.OverControl.GetPopupElementByEvt(evt);
3546  if(mouseOver)
3547   popupElement.DXPopupElementControl.OnPopupElementMouseOver(evt, popupElement);
3548  else
3549   popupElement.DXPopupElementControl.OnPopupElementMouseOut(evt, popupElement);
3550 },
3551 OnMouseOut: function (evt) {
3552  PopupUtils.OverControl.OnMouseEvent(evt, false);
3553 },
3554 OnMouseOver: function (evt) {
3555  PopupUtils.OverControl.OnMouseEvent(evt, true);
3556 }
3557};
3558PopupUtils.BodyScrollHelper = (function () {
3559 var windowScrollLock = {},
3560  windowScroll = {},
3561  hideScrollbarsClassName = "dxpc-hideScrollbars";
3562 function lockWindowScroll(windowId) {
3563  windowScrollLock[windowId] = true;
3564 }
3565 function unlockWindowScroll(windowId) {
3566  delete windowScrollLock[windowId];
3567 }
3568 function isLocked(windowId) {
3569  return !!windowScrollLock[windowId];
3570 }
3571 function isAnyWindowScrollLocked() {
3572  for(var key in windowScrollLock) 
3573   if (windowScrollLock.hasOwnProperty(key) && windowScrollLock[key] === true)
3574    return true;
3575  return false;
3576 }
3577 function replaceVerticalScrollByPadding() {
3578  var currentBodyStyle = ASPx.GetCurrentStyle(document.body),
3579   paddingWidth = ASPx.GetVerticalScrollBarWidth() + ASPx.PxToInt(currentBodyStyle.paddingRight);
3580  ASPx.Attr.ChangeStyleAttribute(document.body, "padding-right", paddingWidth + "px");
3581 }
3582 function changeOverflow() {
3583  ASPx.Attr.ChangeStyleAttribute(document.documentElement, "overflow", "hidden");
3584  if(ASPx.GetCurrentStyle(document.body).overflowY === "scroll")
3585   ASPx.Attr.ChangeStyleAttribute(document.body, "overflow", "hidden");
3586  resetOverflowCache();
3587 }
3588 function restoreOverflow() {
3589  ASPx.Attr.RestoreStyleAttribute(document.documentElement, "overflow");
3590  ASPx.Attr.RestoreStyleAttribute(document.body, "overflow");
3591  resetOverflowCache();
3592 }
3593 function resetOverflowCache() {
3594  ASPx.verticalScrollIsNotHidden = null;
3595  ASPx.horizontalScrollIsNotHidden = null;
3596 }
3597 function saveScrollPosition(windowId) {
3598  windowScroll[windowId] = {
3599   x: window.pageXOffset,
3600   y: window.pageYOffset
3601  };
3602 }
3603 function restoreScrollPosition(windowId) {
3604  var currentWindowScroll = windowScroll[windowId];
3605  if(!!currentWindowScroll)
3606   window.scrollTo(currentWindowScroll.x, currentWindowScroll.y);
3607 }
3608 function restoreBodyScroll(windowId) {
3609  unlockWindowScroll(windowId);
3610  if(isAnyWindowScrollLocked())
3611   return;
3612  if(ASPx.Browser.WebKitTouchUI) {
3613   ASPx.Attr.RestoreStyleAttribute(document.body, "position");
3614   ASPx.Attr.RestoreStyleAttribute(document.body, "height");
3615   ASPx.Attr.RestoreStyleAttribute(document.body, "margin");
3616   ASPx.RemoveClassNameFromElement(document.documentElement, hideScrollbarsClassName);
3617   ASPx.Attr.RestoreStyleAttribute(document.body, "overflow");
3618   restoreScrollPosition(windowId);
3619  } else {
3620   restoreOverflow();
3621   restoreScrollPosition(windowId);
3622  }
3623  if(ASPx.Browser.Chrome)
3624   var dummy = document.documentElement.scrollTop; 
3625  ASPx.Attr.RestoreStyleAttribute(document.body, "padding-right");
3626  ASPx.Attr.RestoreStyleAttribute(document.body, "height");
3627  ASPx.Attr.RestoreStyleAttribute(document.body, "width");
3628 }
3629 return {
3630  RestoreIfLocked: function(windowId) {
3631   if(isLocked(windowId))
3632    restoreBodyScroll(windowId);
3633  },
3634  HideBodyScroll: function(windowId) {
3635   if(isAnyWindowScrollLocked()) { 
3636    lockWindowScroll(windowId);
3637    return;
3638   }
3639   lockWindowScroll(windowId);
3640   if(PopupUtils.IsVerticalScrollExists())
3641    replaceVerticalScrollByPadding();
3642   if(ASPx.Browser.WebKitTouchUI) {
3643    saveScrollPosition(windowId);
3644    ASPx.Attr.ChangeStyleAttribute(document.body, "overflow", "hidden");
3645    ASPx.Attr.ChangeStyleAttribute(document.body, "position", "relative");
3646    ASPx.Attr.ChangeStyleAttribute(document.body, "height", "100%");
3647    ASPx.Attr.ChangeStyleAttribute(document.body, "margin", "0");
3648    ASPx.AddClassNameToElement(document.documentElement, hideScrollbarsClassName);
3649   } else {
3650    saveScrollPosition(windowId);
3651    changeOverflow();
3652    var documentHeight = ASPx.GetDocumentHeight();
3653    var documentWidth = ASPx.GetDocumentWidth();
3654    if(window.pageYOffset > 0 && ASPx.PxToInt(window.getComputedStyle(document.body, null)) != documentHeight)
3655     ASPx.Attr.ChangeStyleAttribute(document.body, "height", documentHeight + "px");
3656    if(window.pageXOffset > 0 && ASPx.PxToInt(window.getComputedStyle(document.body, null)) != documentWidth)
3657     ASPx.Attr.ChangeStyleAttribute(document.body, "width", documentWidth + "px");
3658   }
3659  },
3660  RestoreBodyScroll: restoreBodyScroll
3661 };
3662})();
3663var PositionAlignConsts = {
3664 NOT_SET: 0,
3665 OUTSIDE_START: 1,
3666 NEAR_BOUND_START: 2,
3667 INNER_START: 3,
3668 CENTER: 4,
3669 INNER_END: 5,
3670 NEAR_BOUND_END: 6,
3671 OUTSIDE_END: 7,
3672 WINDOW_CENTER: 8,
3673 WINDOW_START: 9,
3674 WINDOW_END: 10
3675};
3676var AlignIndicatorTable = {};
3677var PositionCalculator = ASPx.CreateClass(null, {
3678 constructor: function() {
3679  this.element = null;
3680  this.popupElement = null;
3681  this.align = 0;
3682  this.offset = 0;
3683  this.startPos = 0;
3684  this.startPosInit = 0;
3685  this.rtl = false;
3686  this.isPopupFullCorrectionOn = false;
3687  this.isHorizontal = true;
3688  this.size = 0;
3689  this.bodySize = 0;
3690  this.actualBodySize = 0;
3691  this.elementStartPos = 0;
3692  this.scrollStartPos = 0;
3693  this.isInverted = false;
3694  this.popupElementSize = 0;
3695  this.boundStartPos = 0;
3696  this.boundEndPos = 0;
3697  this.innerBoundStartPos = 0;
3698  this.innerBoundEndPos = 0;
3699  this.isMoreFreeSpaceLeft = false;
3700  this.nearBoundOverlapRate = 0.25;
3701  this.functionsTable = {};
3702  this.initializeFunctionsTable();
3703 },
3704 applyParams: function(element, popupElement, align, offset, startPos, startPosInit, rtl, isPopupFullCorrectionOn, ignoreAlignWithoutScrollReserve, ignorePopupElementBorders, isHorizontal, showPopupInsideScreenBounds) {
3705  this.isHorizontal = isHorizontal;
3706  this.element = element;
3707  this.popupElement = popupElement;
3708  this.align = this.getAlignValueFromIndicator(align);
3709  this.offset = offset;
3710  this.startPos = startPos;
3711  this.startPosInit = startPosInit;
3712  this.rtl = rtl;
3713  this.isPopupFullCorrectionOn = isPopupFullCorrectionOn;
3714  this.ignoreAlignWithoutScrollReserve = ignoreAlignWithoutScrollReserve;
3715  this.ignorePopupElementBorders = ignorePopupElementBorders;
3716  this.showPopupInsideScreenBounds = showPopupInsideScreenBounds;
3717  this.calculateParams();
3718 },
3719 disposeState: function() {
3720  this.element = null;
3721  this.popupElement = null;
3722 },
3723 getPopupAbsolutePos: function() {
3724  if(this.isWindowAlign()) {
3725   var showAtPos = this.startPos != ASPx.InvalidPosition && !this.popupElement;
3726   if(showAtPos)
3727    this.align = PositionAlignConsts.NOT_SET;
3728   else
3729    return this.getWindowAlignPos();
3730  }
3731  if(this.popupElement)
3732   this.calculatePopupElement();
3733  else
3734   this.align = PositionAlignConsts.NOT_SET;
3735  return this.getPopupAbsolutePosCore();
3736 },
3737 initializeFunctionsTable: function() {
3738  var table = this.functionsTable;
3739  table[PositionAlignConsts.NOT_SET] = this.calculateNotSet;
3740  table[PositionAlignConsts.OUTSIDE_START] = this.calculateOutsideStart;
3741  table[PositionAlignConsts.INNER_START] = this.calculateInnerStart;
3742  table[PositionAlignConsts.CENTER] = this.calculateCenter;
3743  table[PositionAlignConsts.INNER_END] = this.calculateInnerEnd;
3744  table[PositionAlignConsts.OUTSIDE_END] = this.calculateOutsideEnd;
3745  table[PositionAlignConsts.NEAR_BOUND_START] = this.calculateNearBoundStart;
3746  table[PositionAlignConsts.NEAR_BOUND_END] = this.calculateNearBoundEnd;
3747  table[PositionAlignConsts.WINDOW_CENTER] = this.calculateWindowCenter;
3748  table[PositionAlignConsts.WINDOW_START] = this.calculateWindowStart;
3749  table[PositionAlignConsts.WINDOW_END] = this.calculateWindowEnd;
3750 },
3751 calculateParams: function() {
3752  this.size = this.getElementSize();
3753  if(this.isHorizontal) {
3754   this.bodySize = ASPx.GetDocumentClientWidth();
3755   this.elementStartPos = ASPx.GetAbsoluteX(this.popupElement) + this.getBorderCorrection();
3756   this.scrollStartPos = ASPx.GetDocumentScrollLeft();
3757  }
3758  else {
3759   this.bodySize = ASPx.GetDocumentClientHeight();
3760   this.elementStartPos = ASPx.GetAbsoluteY(this.popupElement) + this.getBorderCorrection();
3761   this.scrollStartPos = ASPx.GetDocumentScrollTop();
3762  }
3763 },
3764 getBorderCorrection: function() {
3765  if(!this.ignorePopupElementBorders)
3766   return 0;
3767  var style = getComputedStyle(this.popupElement);
3768  return ASPx.PxToInt(this.isHorizontal ? style.borderLeftWidth : style.borderTopWidth);
3769 },
3770 isWindowAlign: function() {
3771  return this.align == PositionAlignConsts.WINDOW_CENTER || this.align == PositionAlignConsts.WINDOW_START ||
3772   this.align == PositionAlignConsts.WINDOW_END;
3773 },
3774 getWindowAlignPos: function() {
3775  this.actualBodySize = ASPx.Browser.WebKitTouchUI ? this.getWindowInnerSize() : this.bodySize;
3776  return this.getPopupAbsolutePosCore();
3777 },
3778 getPopupAbsolutePosCore: function() {
3779  var calculationFunc = this.functionsTable[this.align];
3780  calculationFunc.call(this);
3781  return new ASPx.PopupPosition(this.startPos, this.isInverted);
3782 },
3783 calculateWindowCenter: function() {
3784  this.startPos = Math.max(Math.ceil(this.actualBodySize / 2 - this.size / 2), 0) + this.scrollStartPos + this.offset;
3785 },
3786 calculateWindowStart: function() {
3787  this.startPos = this.scrollStartPos + this.offset;
3788 },
3789 calculateWindowEnd: function() {
3790  this.startPos = this.scrollStartPos + this.actualBodySize - this.size + this.offset;
3791 },
3792 calculatePopupElement: function() {
3793  this.popupElementSize = this.getPopupElementSize();
3794  this.boundStartPos = this.elementStartPos - this.size;
3795  this.boundEndPos = this.elementStartPos + this.popupElementSize;
3796  this.innerBoundStartPos = this.elementStartPos;
3797  this.innerBoundEndPos = this.elementStartPos + this.popupElementSize - this.size;
3798  var hasLeftScrollReserve = this.boundStartPos >= 0;
3799  this.isMoreFreeSpaceLeft = (this.bodySize - (this.boundEndPos + this.size) < this.boundStartPos - 2 * this.scrollStartPos) && (!this.ignoreAlignWithoutScrollReserve || hasLeftScrollReserve);
3800 },
3801 calculateOutsideStart: function() {
3802  this.isInverted = this.isPopupFullCorrectionOn && (!(this.boundStartPos - this.scrollStartPos > 0 || this.isMoreFreeSpaceLeft));
3803  if(this.isInverted)
3804   this.startPos = this.boundEndPos - this.offset;
3805  else
3806   this.startPos = this.boundStartPos + this.offset;
3807 },
3808 calculateInnerStart: function() {
3809  this.startPos = this.innerBoundStartPos + this.offset;
3810  if(this.isPopupFullCorrectionOn)
3811   this.startPos = PopupUtils.AdjustPositionToClientScreen(this.element, this.startPos, this.rtl, this.isHorizontal);
3812 },
3813 calculateCenter: function() {
3814  this.startPos = this.elementStartPos + Math.round((this.popupElementSize - this.size) / 2) + this.offset;
3815  if(this.showPopupInsideScreenBounds) {
3816   if(this.startPos < 0)
3817    this.startPos = 0;
3818   if(this.startPos + this.size > this.bodySize)
3819    this.startPos = this.bodySize - this.size;
3820  }
3821 },
3822 calculateInnerEnd: function() {
3823  this.startPos = this.innerBoundEndPos + this.offset;
3824  if(this.isPopupFullCorrectionOn)
3825   this.startPos = PopupUtils.AdjustPositionToClientScreen(this.element, this.startPos, this.rtl, this.isHorizontal);
3826 },
3827 calculateOutsideEnd: function() {
3828  this.isInverted = this.isPopupFullCorrectionOn && (!(this.boundEndPos + this.size < this.bodySize + this.scrollStartPos || !this.isMoreFreeSpaceLeft));
3829  if(this.isInverted)
3830   this.startPos = this.boundStartPos - this.offset;
3831  else
3832   this.startPos = this.boundEndPos + this.offset;
3833 },
3834 calculateNotSet: function() {
3835  if(this.rtl)
3836   this.calculateNotSetRightToLeft();
3837  else
3838   this.calculateNotSetLeftToRight();
3839 },
3840 calculateNotSetLeftToRight: function() {
3841  if(!ASPx.IsValidPosition(this.startPos)) {
3842   if(this.popupElement)
3843    this.startPos = this.elementStartPos;
3844   else if(this.offset)
3845    this.startPos = 0;
3846   else
3847    this.startPos = this.startPosInit;
3848  }
3849  this.isInverted = this.isPopupFullCorrectionOn && (this.startPos - this.scrollStartPos + this.size > this.bodySize && this.startPos - this.scrollStartPos > this.bodySize / 2);
3850  if(this.isInverted)
3851   this.startPos = this.startPos - this.size - this.offset;
3852  else
3853   this.startPos = this.startPos + this.offset;
3854 },
3855 calculateNotSetRightToLeft: function() {
3856  if(!ASPx.IsValidPosition(this.startPos)) {
3857   if(this.popupElement)
3858    this.startPos = this.innerBoundEndPos;
3859   else if(this.offset)
3860    this.startPos = 0;
3861   else
3862    this.startPos = this.startPosInit;
3863  }
3864  else
3865   this.startPos -= this.size;
3866  this.isInverted = this.isPopupFullCorrectionOn && (this.startPos < this.scrollStartPos && this.startPos - this.scrollStartPos < this.bodySize / 2);
3867  if(this.isInverted)
3868   this.startPos = this.startPos + this.size + this.offset;
3869  else
3870   this.startPos = this.startPos - this.offset;
3871 },
3872 calculateNearBoundStart: function() {
3873  this.startPos = this.boundStartPos + this.offset + this.size * this.nearBoundOverlapRate;
3874  if(this.isPopupFullCorrectionOn)
3875   this.startPos = PopupUtils.AdjustPositionToClientScreen(this.element, this.startPos, this.rtl, this.isHorizontal);
3876 },
3877 calculateNearBoundEnd: function() {
3878  this.startPos = this.boundEndPos + this.offset - this.size * this.nearBoundOverlapRate;
3879  if(this.isPopupFullCorrectionOn)
3880   this.startPos = PopupUtils.AdjustPositionToClientScreen(this.element, this.startPos, this.rtl, this.isHorizontal);
3881 },
3882 getAlignValueFromIndicator: function(alignIndicator) {
3883  var alignValue = AlignIndicatorTable[alignIndicator];
3884  if(alignValue === undefined)
3885   throw "Incorrect align indicator.";
3886  return alignValue;
3887 },
3888 getElementSize: function() {
3889  return this.getCustomElementSize(this.element, false);
3890 },
3891 getPopupElementSize: function() {
3892  return this.getCustomElementSize(this.popupElement, this.ignorePopupElementBorders);
3893 },
3894 getCustomElementSize: function(customElement, ignoreBorders) {
3895  if(ignoreBorders) {
3896   return this.isHorizontal ? ASPx.GetClearClientWidth(customElement) : ASPx.GetClearClientHeight(customElement);
3897  }
3898  return this.isHorizontal ? ASPx.GetElementOffsetWidth(customElement) : ASPx.GetElementOffsetHeight(customElement);
3899 },
3900 getWindowInnerSize: function() {
3901  return this.isHorizontal ? window.innerWidth : window.innerHeight;
3902 }
3903});
3904var positionCalculator = null;
3905function getPositionCalculator() {
3906 if(positionCalculator == null)
3907  positionCalculator = new PositionCalculator();
3908 return positionCalculator;
3909}
3910function initializeAlignIndicatorTable() {
3911 AlignIndicatorTable[PopupUtils.NotSetAlignIndicator] = PositionAlignConsts.NOT_SET;
3912 AlignIndicatorTable[PopupUtils.OutsideLeftAlignIndicator] = PositionAlignConsts.OUT
3912SIDE_START;
3913 AlignIndicatorTable[PopupUtils.AboveAlignIndicator] = PositionAlignConsts.OUTSIDE_START;
3914 AlignIndicatorTable[PopupUtils.LeftAlignIndicator] = PositionAlignConsts.NEAR_BOUND_START;
3915 AlignIndicatorTable[PopupUtils.TopAlignIndicator] = PositionAlignConsts.NEAR_BOUND_START;
3916 AlignIndicatorTable[PopupUtils.LeftSidesAlignIndicator] = PositionAlignConsts.INNER_START;
3917 AlignIndicatorTable[PopupUtils.TopSidesAlignIndicator] = PositionAlignConsts.INNER_START;
3918 AlignIndicatorTable[PopupUtils.CenterAlignIndicator] = PositionAlignConsts.CENTER;
3919 AlignIndicatorTable[PopupUtils.MiddleAlignIndicator] = PositionAlignConsts.CENTER;
3920 AlignIndicatorTable[PopupUtils.RightSidesAlignIndicator] = PositionAlignConsts.INNER_END;
3921 AlignIndicatorTable[PopupUtils.BottomSidesAlignIndicator] = PositionAlignConsts.INNER_END;
3922 AlignIndicatorTable[PopupUtils.RightAlignIndicator] = PositionAlignConsts.NEAR_BOUND_END;
3923 AlignIndicatorTable[PopupUtils.BottomAlignIndicator] = PositionAlignConsts.NEAR_BOUND_END;
3924 AlignIndicatorTable[PopupUtils.OutsideRightAlignIndicator] = PositionAlignConsts.OUTSIDE_END;
3925 AlignIndicatorTable[PopupUtils.BelowAlignIndicator] = PositionAlignConsts.OUTSIDE_END;
3926 AlignIndicatorTable[PopupUtils.WindowCenterAlignIndicator] = PositionAlignConsts.WINDOW_CENTER;
3927 AlignIndicatorTable[PopupUtils.WindowLeftAlignIndicator] = PositionAlignConsts.WINDOW_START;
3928 AlignIndicatorTable[PopupUtils.WindowTopAlignIndicator] = PositionAlignConsts.WINDOW_START;
3929 AlignIndicatorTable[PopupUtils.WindowRightAlignIndicator] = PositionAlignConsts.WINDOW_END;
3930 AlignIndicatorTable[PopupUtils.WindowBottomAlignIndicator] = PositionAlignConsts.WINDOW_END;
3931}
3932initializeAlignIndicatorTable();
3933ASPx.PopupPosition = function(position, isInverted) {
3934 this.position = position;
3935 this.isInverted = isInverted;
3936};
3937ASPx.PopupSize = function(width, height) {
3938 this.width = width;
3939 this.height = height;
3940};
3941ASPx.PopupUtils = PopupUtils;
3942ASPx.PositionCalculator = PositionCalculator;
3943})();
3944
3945(function(){
3946 var ScrollingManager = ASPx.CreateClass(null, {
3947  constructor: function(owner, options) {
3948   this.owner = owner;
3949   this.scrollableArea = options.scrollableArea;
3950   this.orientation = options.orientation;
3951   this.animationDelay = 1;
3952   this.animationStep = 2;
3953   this.animationOffset = 5;
3954   this.animationAcceleration = 0;
3955   this.scrollSessionInterval = 10;
3956   this.stopScrolling = true;
3957   this.busy = false;
3958   this.currentAcceleration = 0;
3959   this.startPos = 0;
3960   this.onBeforeScrolling = options.onBeforeScrolling;
3961   this.onAfterScrolling = options.onAfterScrolling;
3962   this.emulationMode = options.forseEmulation === true || !ASPx.Browser.TouchUI;
3963   this.useMarginForPosition = options.useMarginForPosition;
3964   this.handleMouseWheel = !!options.handleMouseWheel;
3965   this.Initialize();
3966  },
3967  Initialize: function(){
3968   this.setParentNodeOverflow();
3969   if(this.emulationMode) {
3970    this.wrapper = new ScrollingManager.scrollWrapper(this.scrollableArea, this.useMarginForPosition);
3971   } else {
3972    this.wrapper = new ScrollingManager.scrollWrapperTouchUI(this.scrollableArea, function(direction){
3973     if(this.onAfterScrolling)
3974      this.onAfterScrolling(this, direction);
3975    }.aspxBind(this)); 
3976   }
3977   if(this.handleMouseWheel)
3978    ASPx.Evt.AttachEventToElement(this.scrollableArea, ASPx.Evt.GetMouseWheelEventName(), this.onMouseWheel.aspxBind(this));
3979  },
3980  onMouseWheel: function(e) {
3981   ASPx.Evt.PreventEvent(e);
3982   var delta = ASPx.Evt.GetWheelDelta(e);
3983   if(ASPx.Browser.Firefox && ASPx.Browser.Version < 89)
3984    delta = delta / 0.03;
3985   this.DoScrollSessionToOffset(-delta);
3986  },
3987  setParentNodeOverflow: function() {
3988   if(ASPx.Browser.MSTouchUI){
3989    this.scrollableArea.parentNode.style.overflow = "auto";
3990    this.scrollableArea.parentNode.style["-ms-overflow-style"] = "-ms-autohiding-scrollbar";
3991   } 
3992  },
3993  GetScrolledAreaPosition: function() {
3994   return this.wrapper.GetScrollLeft() * this.orientation[0]
3995    + this.wrapper.GetScrollTop() * this.orientation[1];
3996  },
3997  SetScrolledAreaPosition: function(pos) {
3998   this.wrapper.SetScrollLeft(pos * this.orientation[0]);
3999   this.wrapper.SetScrollTop(pos * this.orientation[1]);
4000  },
4001  PrepareForScrollAnimation: function() {
4002   if(!this.scrollableArea)
4003    return;  
4004   this.currentAcceleration = 0;
4005   this.startPos = this.GetScrolledAreaPosition();
4006   this.busy = false;
4007  },
4008  GetAnimationStep: function(dir) {
4009   var step = dir * (this.animationStep + this.currentAcceleration);
4010   var newPos = this.GetScrolledAreaPosition() + step;
4011   var requiredPos = this.startPos + dir * this.animationOffset;
4012   if((dir == 1 && newPos >= requiredPos) || (dir == -1 && newPos <= requiredPos)) {
4013    step = requiredPos - this.GetScrolledAreaPosition();
4014   } 
4015   return step;
4016  },
4017  DoScrollSessionToOffset: function(offset) {
4018   var newScrollPos = this.GetScrolledAreaPosition() - offset;
4019   this.stopScrolling = false;
4020   if(this.onBeforeScrolling)
4021    this.onBeforeScrolling(this, offset);
4022   if(this.stopScrolling) return;
4023   newScrollPos = Math.min(newScrollPos, 0);
4024   this.SetScrolledAreaPosition(newScrollPos);
4025   if(this.onAfterScrolling)
4026    this.onAfterScrolling(this, offset); 
4027  },
4028  DoScrollSessionAnimation: function(direction) {
4029   if(!this.scrollableArea)
4030    return;
4031   this.SetScrolledAreaPosition(this.GetScrolledAreaPosition() + this.GetAnimationStep(direction));
4032   var self = this;
4033   if(!this.ShouldStopScrollSessionAnimation()) {
4034    this.busy = true;
4035    this.currentAcceleration += this.animationAcceleration;
4036    window.setTimeout(function() { self.DoScrollSessionAnimation(direction); }, this.animationDelay);
4037   } else {
4038    this.busy = false;
4039    if(this.onAfterScrolling)
4040     this.onAfterScrolling(this, -direction);   
4041    this.currentAcceleration = 0;
4042    window.setTimeout(function() { self.DoScroll(direction); }, this.scrollSessionInterval);
4043   }
4044  },
4045  ShouldStopScrollSessionAnimation: function() {
4046   return (Math.abs(this.GetScrolledAreaPosition() - this.startPos) >= Math.abs(this.animationOffset));
4047  },
4048  DoScroll: function(direction) {
4049   if(!this.scrollableArea)
4050    return; 
4051   if(!this.busy && !this.stopScrolling) {
4052    if(this.onBeforeScrolling)
4053     this.onBeforeScrolling(this, -direction);
4054    if(this.stopScrolling) return;
4055    this.PrepareForScrollAnimation();
4056    this.DoScrollSessionAnimation(direction);
4057   } 
4058  },
4059  StartScrolling: function(direction, delay, step) {
4060   this.stopScrolling = false;
4061   this.animationDelay = delay;
4062   this.animationStep = step;
4063   this.DoScroll(-direction);
4064  },
4065  StopScrolling: function() {
4066   this.stopScrolling = true;
4067  },
4068  IsStopped: function() {
4069   return this.stopScrolling;
4070  },
4071  IsInProgress: function() {
4072   return this.busy;
4073  }
4074 });
4075 var MouseScrollingManager = ASPx.CreateClass(ScrollingManager, {
4076  constructor: function(owner, options) {
4077   this.mouseEventsElement = options.mouseEventsElement;
4078   this.preventOuterScroll = options.preventOuterScroll;
4079   this.enableMouseScrollInternal = true;
4080   this.constructor.prototype.constructor.call(this, owner, options);
4081  },
4082  Initialize: function() {
4083   ASPx.ScrollingManager.prototype.Initialize.call(this);
4084   this.initializeMouseScroll();
4085  },
4086  initializeMouseScroll: function() {
4087   this.mouseDown = false;
4088   this.vx = 0;
4089   this.prevX = 0;
4090   this.scrollTime = null;
4091   this.mouseScrollAcceleration = 0.7;
4092   this.mouseScrollTimeStep = 30;
4093   ASPx.Evt.AttachEventToElement(this.mouseEventsElement, ASPx.TouchUIHelper.touchMouseDownEventName, this.startMouseScroll.aspxBind(this));
4094  },
4095  scrollToOffset: function(mouseOffset) {
4096   var newOffset = this.GetScrolledAreaPosition() - mouseOffset;
4097   if(this.getValidNewScrollOffset)
4098    newOffset = this.getValidNewScrollOffset(newOffset);
4099   this.SetScrolledAreaPosition(newOffset);
4100  },
4101  preventTextSelectionAndOuterDivScrollOnScroll: function(e) {
4102   if(this.preventOuterScroll)
4103    ASPx.Evt.PreventEvent(e);
4104   ASPx.Selection.Clear();
4105  },
4106  mouseScroll: function(e) {
4107   if(!this.mouseDown) return;
4108   this.preventTextSelectionAndOuterDivScrollOnScroll(e);
4109   var x = ASPx.Evt.GetEventX(e),
4110    dx = this.prevX - x,
4111    dt = new Date() - this.scrollTime;
4112   if(dt < 1) dt = 1;
4113   this.vx = dx / dt;
4114   this.scrollToOffset(dx);
4115   this.prevX = x;
4116   this.scrollTime = new Date();
4117  },
4118  startMouseScroll: function(e) {
4119   if(!this.enableMouseScrollInternal) return;
4120   this.detachMouseEvents();
4121   this.mouseMoveHandler = this.mouseScroll.aspxBind(this);
4122   this.mouseUpHandler = this.stopMouseScroll.aspxBind(this);
4123   ASPx.Evt.AttachEventToElement(document, ASPx.TouchUIHelper.touchMouseMoveEventName, this.mouseMoveHandler);
4124   ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseUpEventName, this.mouseUpHandler);
4125   this.mouseDown = true;
4126   window.clearTimeout(this.inertialStopTimerId);
4127   this.prevX = ASPx.Evt.GetEventX(e);
4128   this.scrollTime = new Date();
4129  },
4130  detachMouseEvents: function() {
4131   ASPx.Evt.DetachEventFromElement(document, ASPx.TouchUIHelper.touchMouseMoveEventName, this.mouseMoveHandler);
4132   ASPx.Evt.DetachEventFromDocument(ASPx.TouchUIHelper.touchMouseUpEventName, this.mouseUpHandler);
4133  },
4134  stopMouseScroll: function() {
4135   this.detachMouseEvents();
4136   this.mouseDown = false;
4137   this.inertialStopTimerId = window.setTimeout(function() {
4138    this.vx *= this.mouseScrollAcceleration;
4139    if(Math.abs(this.vx) < 0.1) {
4140     this.vx = 0;
4141     if(this.onAfterScrolling)
4142      this.onAfterScrolling(this);
4143     return;
4144    }
4145    var dx = Math.ceil(this.vx * this.mouseScrollTimeStep);
4146    this.scrollToOffset(dx);
4147    this.stopMouseScroll();
4148   }.aspxBind(this), this.mouseScrollTimeStep);
4149  }
4150 });
4151 ScrollingManager.scrollWrapper = function(scrollableArea, useMarginForPosition) {
4152  this.scrollableArea = scrollableArea;
4153  this.useMarginForPosition = useMarginForPosition;
4154  this.Initialize();
4155 };
4156 ScrollingManager.scrollWrapper.prototype = {
4157  Initialize: function() {
4158   if(this.useMarginForPosition) {
4159    this.leftScrollProperty = "margin-left";
4160    this.topScrollProperty = "margin-top";
4161   } else {
4162    this.scrollableArea.style.position = "relative";
4163    this.scrollableArea.parentNode.style.position = "relative";
4164    this.leftScrollProperty = "left";
4165    this.topScrollProperty = "top";
4166   }
4167  },
4168  GetScrollLeft: function() { return ASPx.PxToFloat(this.scrollableArea.style[this.leftScrollProperty]); },
4169  GetScrollTop: function() { return ASPx.PxToFloat(this.scrollableArea.style[this.topScrollProperty]); },
4170  SetScrollLeft: function(value) {
4171   this.scrollableArea.style[this.leftScrollProperty] = value + "px";
4172  },
4173  SetScrollTop: function(value) {
4174   this.scrollableArea.style[this.topScrollProperty] = value + "px";
4175  }
4176 };
4177 ScrollingManager.scrollWrapperTouchUI = function(scrollableArea, onScroll){
4178  this.scrollableArea = scrollableArea;
4179  this.scrollTimerId = -1;
4180  this.onScroll = onScroll;
4181  this.Initialize(onScroll);
4182 };
4183 ScrollingManager.scrollWrapperTouchUI.prototype = {
4184  Initialize: function(){
4185   var div = this.scrollableArea.parentNode;
4186   var timeout = ASPx.Browser.MSTouchUI ? 500 : 1000;
4187   var nativeScrollSupported = ASPx.TouchUIHelper.nativeScrollingSupported();
4188   this.onScrollCore = function(){
4189     ASPx.Timer.ClearTimer(this.scrollTimerId);
4190     if(this.onScrollLocked) return;
4191     this.scrollTimerId = window.setTimeout(this.onScrollByTimer, timeout);
4192    }.aspxBind(this);
4193   this.onScrollByTimer = function(){
4194     if(this.onScrollLocked) return;
4195     var direction = this.lastScrollTop < div.scrollTop ? 1 : -1;
4196     this.lastScrollTop = div.scrollTop;
4197     this.onScrollLocked = true;
4198     this.onScroll(direction);
4199     this.onScrollLocked = false;
4200    }.aspxBind(this);
4201   this.lastScrollTop = div.scrollTop;
4202   var onscroll = nativeScrollSupported ? this.onScrollCore : this.onScrollByTimer;
4203   ASPx.Evt.AttachEventToElement(div, "scroll", onscroll);
4204   if(ASPx.Browser.WebKitTouchUI)
4205    this.scrollExtender = ASPx.TouchUIHelper.MakeScrollable(div, {showHorizontalScrollbar: false});
4206  },
4207  GetScrollLeft: function(){ return -this.scrollableArea.parentNode.scrollLeft; },
4208  GetScrollTop:  function(){ return -this.scrollableArea.parentNode.scrollTop; },
4209  SetScrollLeft: function(value){ 
4210   this.onScrollLocked = true;
4211   this.scrollableArea.parentNode.scrollLeft = -value; 
4212   this.onScrollLocked = false;
4213  },
4214  SetScrollTop:  function(value){ 
4215   this.onScrollLocked = true;
4216   this.scrollableArea.parentNode.scrollTop  = -value; 
4217   this.onScrollLocked = false;
4218  }
4219 };
4220 ASPx.ScrollingManager = ScrollingManager;
4221 ASPx.MouseScrollingManager = MouseScrollingManager;
4222})();
4223(function() {
4224var Constants = {
4225 MIIdSuffix: "_DXI",
4226 MMIdSuffix: "_DXM",
4227 SBIdSuffix: "_DXSB",
4228 SBUIdEnd: "_U",
4229 SBDIdEnd: "_D",
4230 ATSIdSuffix: "_ATS",
4231 SampleCssClassNameForImageElement: "SAMPLE_CSS_CLASS",
4232 ImagePostfix: "Img",
4233 PopupImagePostfix: "PImg",
4234 ItemPopoutElementPostfix: "P",
4235 ItemContentElementPostfix: "T"
4236};
4237var SLIDE_DURATION_VALUE = 300;
4238var SIDE_MENU_ZINDEX_VALUE = 10000;
4239var MENU_PREFIX_CLASS_NAME = 'dxm';
4240var SLIDE_PANEL_EXPANDED_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-expanded';
4241var BREAD_CRUMBS_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-bread-crumbs';
4242var OVERLAY_PANEL_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-overlay';
4243var BURGER_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-side-menu-button';
4244var BACK_ICON_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-back-icon';
4245var NO_MAIN_POP_OUT_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-no-main-popout';
4246var TEMPORARY_VISIBILITY_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-temp-visibility';
4247var SIDE_MENU_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-side-menu-mode';
4248var PRE_HOVERED_ELEMENT_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-pre-hovered';
4249var PRE_SELECTED_ELEMENT_CLASS_NAME = MENU_PREFIX_CLASS_NAME + '-pre-selected';
4250var MenuItemInfo = ASPx.CreateClass(null, {
4251 constructor: function(menu, indexPath) {
4252  var itemElement = menu.GetItemElement(indexPath);
4253  this.clientHeight = itemElement.clientHeight;
4254  this.clientWidth = itemElement.clientWidth;
4255  this.clientTop = ASPx.GetClientTop(itemElement);
4256  this.clientLeft = ASPx.GetClientLeft(itemElement);
4257  this.offsetHeight = itemElement.offsetHeight;
4258  this.offsetWidth = itemElement.offsetWidth;
4259  this.offsetTop = 0;
4260  this.offsetLeft = 0;
4261 }
4262});
4263var MenuCssClasses = {};
4264MenuCssClasses.Prefix = "dxm-";
4265MenuCssClasses.Menu = "dxmLite";
4266MenuCssClasses.BorderCorrector = "dxmBrdCor";
4267MenuCssClasses.Disabled = MenuCssClasses.Prefix + "disabled";
4268MenuCssClasses.MainMenu = MenuCssClasses.Prefix + "main";
4269MenuCssClasses.PopupMenu = MenuCssClasses.Prefix + "popup";
4270MenuCssClasses.ItemTemplate = MenuCssClasses.Prefix + "tmpl";
4271MenuCssClasses.HorizontalMenu = MenuCssClasses.Prefix + "horizontal";
4272MenuCssClasses.VerticalMenu = MenuCssClasses.Prefix + "vertical";
4273MenuCssClasses.NoWrapMenu = MenuCssClasses.Prefix + "noWrap";
4274MenuCssClasses.AutoWidthMenu = MenuCssClasses.Prefix + "autoWidth";
4275MenuCssClasses.CalculateMenu = MenuCssClasses.Prefix + "calc";
4276MenuCssClasses.DX = "dx";
4277MenuCssClasses.Separator = MenuCssClasses.Prefix + "separator";
4278MenuCssClasses.Spacing = MenuCssClasses.Prefix + "spacing";
4279MenuCssClasses.AlignSpacing = MenuCssClasses.Prefix + "alignSpacing";
4280MenuCssClasses.Gutter = MenuCssClasses.Prefix + "gutter";
4281MenuCssClasses.WithoutImages = MenuCssClasses.Prefix + "noImages";
4282MenuCssClasses.Item = MenuCssClasses.Prefix + "item";
4283MenuCssClasses.ItemHovered = MenuCssClasses.Prefix + "hovered";
4284MenuCssClasses.ItemSelected = MenuCssClasses.Prefix + "selected";
4285MenuCssClasses.ItemChecked = MenuCssClasses.Prefix + "checked";
4286MenuCssClasses.ItemWithoutImage = MenuCssClasses.Prefix + "noImage";
4287MenuCssClasses.ItemWithSubMenu = MenuCssClasses.Prefix + "subMenu";
4288MenuCssClasses.ItemDropDownMode = MenuCssClasses.Prefix + "dropDownMode";
4289MenuCssClasses.ItemWithoutSubMenu = MenuCssClasses.Prefix + "noSubMenu"; 
4290MenuCssClasses.AdaptiveMenuItem = MenuCssClasses.Prefix + "ami";
4291MenuCssClasses.AdaptiveFakeMenuItem = MenuCssClasses.Prefix + "fami";
4292MenuCssClasses.AdaptiveMenuItemSpacing = MenuCssClasses.Prefix + "amis";
4293MenuCssClasses.AdaptiveMenu = MenuCssClasses.Prefix + "am";
4294MenuCssClasses.AdaptiveMenuHiddenElement = MenuCssClasses.Prefix + "amhe";
4295MenuCssClasses.ContentContainer = MenuCssClasses.Prefix + "content";
4296MenuCssClasses.ContentContainerWithVerticalAlignment = MenuCssClasses.Prefix + "valign";
4297MenuCssClasses.Image = MenuCssClasses.Prefix + "image";
4298MenuCssClasses.PopOutContainer = MenuCssClasses.Prefix + "popOut";
4299MenuCssClasses.PopOutImage = MenuCssClasses.Prefix + "pImage";
4300MenuCssClasses.ImageLeft = MenuCssClasses.Prefix + "image-l";
4301MenuCssClasses.ImageRight = MenuCssClasses.Prefix + "image-r";
4302MenuCssClasses.ImageTop = MenuCssClasses.Prefix + "image-t";
4303MenuCssClasses.ImageBottom = MenuCssClasses.Prefix + "image-b";
4304MenuCssClasses.ScrollArea = MenuCssClasses.Prefix + "scrollArea";
4305MenuCssClasses.ScrollUpButton = MenuCssClasses.Prefix + "scrollUpBtn";
4306MenuCssClasses.ScrollDownButton = MenuCssClasses.Prefix + "scrollDownBtn";
4307MenuCssClasses.ItemClearElement = MenuCssClasses.DX + "-clear";
4308MenuCssClasses.ItemTextElement = MenuCssClasses.Prefix + "contentText";
4309MenuCssClasses.SmallImage = MenuCssClasses.DX + "-small-image";
4310var MenuRenderHelper = ASPx.CreateClass(null, {
4311 constructor: function(menu) {
4312  this.menu = menu;
4313  this.itemLinkMode = "ContentBounds";
4314  this.elementsToHide = [];
4315 },
4316 InlineInitializeElements: function() {
4317  if(!this.menu.isPopupMenu)
4318   this.InlineInitializeMainMenuElements(this.menu.GetMainElement());
4319  else
4320   this.InlineInitializePopupMenuElements(this.menu.GetMainElement());
4321  var popupMenuElements = this.GetPopupMenuElements(this.menu.GetMainElement());
4322  for(var i = 0; i < popupMenuElements.length; i++) {
4323   if(popupMenuElements[i] == this.menu.GetMainElement()) continue;
4324   this.InlineInitializePopupMenuElements(popupMenuElements[i]);
4325  }
4326 },
4327 InlineInitializeSubMenuElements: function(parentItemIndexPath) {
4328  var popupMenuElements = this.GetPopupMenuElements(this.menu.GetMainElement());
4329  for(var i = 0; i < popupMenuElements.length; i++) {
4330   if(popupMenuElements[i].id.indexOf(Constants.MMIdSuffix + parentItemIndexPath + "_") > 0)
4331    this.InlineInitializePopupMenuElements(popupMenuElements[i]);
4332  }
4333 },
4334 InlineInitializeScrollElements: function(indexPath, menuElement) {
4335  var scrollArea = ASPx.GetNodeByClassName(menuElement, MenuCssClasse
4335s.ScrollArea);
4336  if(scrollArea) scrollArea.id = this.menu.GetScrollAreaId(indexPath);
4337  this.InitializeScrollButton(menuElement, MenuCssClasses.ScrollUpButton, this.menu.GetScrollUpButtonId(indexPath));
4338  this.InitializeScrollButton(menuElement, MenuCssClasses.ScrollDownButton, this.menu.GetScrollDownButtonId(indexPath));
4339 },
4340 InitializeScrollButton: function(menuElement, buttonClassName, id) {
4341  var scrollButton = ASPx.GetNodeByClassName(menuElement, buttonClassName);
4342  if(!scrollButton) return;
4343  scrollButton.id = id;
4344  if(this.menu.NeedCreateItemsOnClientSide()) {
4345   ASPx.GetStateController().AddHoverItem(id, ["dxm-scrollBtnHovered"], [""]);
4346   ASPx.GetStateController().AddPressedItem(id, ["dxm-scrollBtnPressed"], [""]);
4347  }
4348 },
4349 InlineInitializeMainMenuElements: function(menuElement) {
4350  this.menu.CheckElementsCache(menuElement);
4351  var contentElement = this.GetContentElement(menuElement);
4352  if(contentElement.className.indexOf("dxm-ti") > 1)
4353   this.itemLinkMode = "TextAndImage";
4354  else if(contentElement.className.indexOf("dxm-t") > -1)
4355   this.itemLinkMode = "TextOnly";
4356  var itemElements = this.GetItemElements(menuElement);
4357  for(var i = 0; i < itemElements.length; i++)
4358   this.InlineInitializeItemElement(itemElements[i], "", i);
4359  this.InlineInitializeScrollElements("", menuElement);
4360 },
4361 InlineInitializePopupMenuElements: function(parentElement) {
4362  parentElement.style.position = "absolute";
4363  var indexPath = this.GetSubMenuIndexPathByMenuParentElement(parentElement);
4364  var borderCorrectorElement = ASPx.GetNodeByClassName(parentElement, MenuCssClasses.BorderCorrector);
4365  if(borderCorrectorElement != null) {
4366   borderCorrectorElement.id = this.menu.GetMenuBorderCorrectorElementId(indexPath);
4367   borderCorrectorElement.style.position = "absolute";
4368   parentElement.removeChild(borderCorrectorElement);
4369   parentElement.parentNode.appendChild(borderCorrectorElement);
4370  }
4371  this.InlineInitializePopupMenuMenuElement(parentElement, indexPath);
4372 },
4373 GetSubMenuIndexPathByMenuParentElement: function(element){
4374  return this.menu.GetMenuIndexPathById(element.id);
4375 },
4376 InlineInitializePopupMenuMenuElement: function(parentElement, indexPath) {
4377  var menuElement = ASPx.GetNodeByClassName(parentElement, MenuCssClasses.PopupMenu);
4378  menuElement.id = this.menu.GetMenuMainElementId(indexPath);
4379  this.InlineInitializePopupMenuContentElements(parentElement, menuElement, indexPath);
4380 },
4381 InlineInitializePopupMenuContentElements: function(parentElement, menuElement, indexPath) {
4382  this.menu.CheckElementsCache(menuElement);
4383  var contentElement = this.GetContentElement(menuElement);
4384  if(contentElement != null) {
4385   var itemElements = this.GetItemElements(menuElement);
4386   var parentIndexPath = parentElement == this.menu.GetMainElement() ? "" : indexPath;
4387   for(var i = 0; i < itemElements.length; i++) {
4388    var itemElementId = itemElements[i].id;
4389    if(itemElementId && aspxGetMenuCollection().GetMenu(itemElementId) != this.menu)
4390     continue;
4391    this.InlineInitializeItemElement(itemElements[i], parentIndexPath, i);
4392   }
4393  }
4394  this.InlineInitializeScrollElements(indexPath, menuElement);
4395 },
4396 HasSubMenuTemplate: function(menuElement) {
4397  var contentElement = this.GetContentElement(menuElement);
4398  return contentElement && (contentElement.tagName != "UL" || !ASPx.GetNodesByPartialClassName(contentElement, MenuCssClasses.ContentContainer).length);
4399 },
4400 InlineInitializeItemElement: function(itemElement, parentIndexPath, visibleIndex) {
4401  function getItemIndex(visibleIndex) {
4402   var itemData = parentItemData[Math.max(visibleIndex, 0)];
4403   return itemData.constructor == Array
4404    ? itemData[0]
4405    : itemData;
4406  }
4407  var parentItemData = this.menu.renderData[parentIndexPath],
4408   prepareItemOnClick = parentItemData[visibleIndex].constructor == Array,
4409   indexPathPrefix = parentIndexPath + (parentIndexPath != "" ? ASPx.ItemIndexSeparator : ""),
4410   indexPath = indexPathPrefix + getItemIndex(visibleIndex);
4411  itemElement.id = this.menu.GetItemElementId(indexPath);
4412  if(this.canAssignAccessibilityEventsToChildrenLinks())
4413   ASPx.AssignAccessibilityEventsToChildrenLinks(itemElement, true);
4414  if(this.canContainSeparators()) {
4415   var separatorElement = itemElement.previousSibling;
4416   if(separatorElement && separatorElement.className) {
4417    if(ASPx.ElementContainsCssClass(separatorElement, MenuCssClasse
4417s.Spacing))
4418     separatorElement.id = this.menu.GetItemIndentElementId(indexPath);
4419    else if(ASPx.ElementContainsCssClass(separatorElement, MenuCssClasses.Separator))
4420     separatorElement.id = this.menu.GetItemSeparatorElementId(indexPath);
4421   }
4422  }
4423  var contentElement = this.GetItemContentElement(itemElement);
4424  if(contentElement != null) {
4425   contentElement.id = this.menu.GetItemContentElementId(indexPath);
4426   if (this.canContainImageElement()) {
4427    var imageElement = ASPx.GetNodeByClassName(contentElement, MenuCssClasses.Image);
4428    if(imageElement == null) {
4429     var hyperLinkElement = ASPx.GetNodeByClassName(contentElement, MenuCssClasses.DX);
4430     if(hyperLinkElement != null)
4431      imageElement = ASPx.GetNodeByClassName(hyperLinkElement, MenuCssClasses.Image);
4432    }
4433    if(imageElement != null)
4434     imageElement.id = this.menu.GetItemImageId(indexPath);
4435   }
4436  }
4437  else
4438   prepareItemOnClick = false;
4439  this.InlineInitializeItemPopOutElement(itemElement, indexPath);
4440  if(prepareItemOnClick)
4441   this.InlineInitializeItemOnClick(itemElement, indexPath);
4442  if(ASPx.ElementContainsCssClass(itemElement, MenuCssClasses.ItemSelected)) 
4443   this.menu.serverSideSelectedItemPath = indexPath;
4444 },
4445 canAssignAccessibilityEventsToChildrenLinks: function () { return true; },
4446 canContainSeparators: function () { return true; },
4447 canContainImageElement: function () { return true; },
4448 InlineInitializeItemPopOutElement: function(itemElement, indexPath) {
4449  var popOutElement = this.GetItemPopOutElement(itemElement);
4450  if(popOutElement != null) {
4451   popOutElement.id = this.menu.GetItemPopOutElementId(indexPath);
4452   var popOutImageElement = ASPx.GetNodeByClassName(popOutElement, MenuCssClasses.PopOutImage);
4453   if(popOutImageElement != null)
4454    popOutImageElement.id = this.menu.GetItemPopOutImageId(indexPath);
4455  }
4456 },
4457 InlineInitializeItemOnClick: function(itemElement, indexPath) {
4458  var name = this.menu.name;
4459  var onclick = this.GetItemOnClick(name, itemElement, indexPath);
4460  if(this.menu.IsDropDownItem(indexPath)) {
4461   var contentElement = this.menu.GetItemContentElement(indexPath);
4462   var dropDownElement = this.menu.GetItemPopOutElement(indexPath);
4463   var dropDownOnclick = this.GetItemDropdownOnClick(name, itemElement, indexPath);
4464   this.AssignItemOnClickToElement(contentElement, this.itemLinkMode, onclick);
4465   this.AssignItemOnClickToElement(dropDownElement, this.itemLinkMode, dropDownOnclick);
4466  }
4467  else
4468   this.AssignItemOnClickToElement(itemElement, this.itemLinkMode, onclick);
4469 },
4470 AssignItemOnClickToElement: function(element, itemLinkMode, method) {
4471  switch(itemLinkMode){
4472   case "ContentBounds":
4473    this.AssignItemOnClickToElementCore(element, method);
4474    break;
4475   case "TextOnly":
4476    var textElement = ASPx.GetNodeByTagName(element, "A");
4477    if(!textElement)
4478     textElement = ASPx.GetNodeByTagName(element, "SPAN");
4479    if(textElement)
4480     this.AssignItemOnClickToElementCore(textElement, method);
4481    break;
4482   case "TextAndImage":
4483    var linkElement = ASPx.GetNodeByTagName(element, "A");
4484    if(linkElement)
4485     this.AssignItemOnClickToElementCore(linkElement, method);
4486    else{
4487     var textElement = ASPx.GetNodeByTagName(element, "SPAN");
4488     if(textElement)
4489      this.AssignItemOnClickToElementCore(textElement, method);
4490     var imageElement = ASPx.GetNodeByTagName(element, "IMG");
4491     if(imageElement)
4492      this.AssignItemOnClickToElementCore(imageElement, method);
4493    }
4494    break;
4495  }
4496 },
4497 AssignItemOnClickToElementCore: function(element, method) {
4498  ASPx.Evt.AttachEventToElement(element, "click", method);
4499 },
4500 GetItemOnClick: function(name, itemElement, indexPath) { 
4501  var menu = this.menu;
4502  var sendPostBackHandler = function() {
4503   menu.SendPostBack("CLICK:" + indexPath);
4504  };
4505  var itemClickHandler = function(e) {
4506   ASPx.MIClick(e, name, indexPath);
4507  };
4508  var itemLink = this.GetItemLinkElement(itemElement);
4509  var handler = menu.autoPostBack && !menu.IsClientSideEventsAssigned() && (!itemLink || itemLink.href === "")
4510   ? sendPostBackHandler
4511   : itemClickHandler;
4512  return function(e) {
4513   if(!itemElement.clientDisabled)
4514    handler(e);
4515  };
4516 },
4517 GetItemDropdownOnClick: function(name, itemElement, indexPath) {
4518  return function(e) {
4519   if(!itemElement.clientDisabled)
4520    ASPx.MIDDClick(e, name, indexPath);
4521  };
4522 },
4523 ChangeItemEnabledAttributes: function(itemElement, enabled, accessibilityCompliant) {
4524  if(!itemElement) return;
4525  itemElement.clientDisabled = !enabled;
4526  ASPx.Attr.ChangeStyleAttributesMethod(enabled)(itemElement, "cursor");
4527  var hyperLink = this.GetItemLinkElement(itemElement);
4528  if(hyperLink)
4529   this.ChangeItemLinkEnabledAttributes(hyperLink, itemElement, enabled, accessibilityCompliant);
4530 },
4531 ChangeItemLinkEnabledAttributes: function(hyperLink, itemElement, enabled, accessibilityCompliant) {
4532  if(accessibilityCompliant) {
4533   var action = enabled ? ASPx.Attr.RemoveAttribute : ASPx.Attr.SetAttribute;
4534   action(hyperLink, "aria-disabled", "true");
4535  }
4536  ASPx.Attr.ChangeAttributesMethod(enabled)(hyperLink, "href");
4537  if(accessibilityCompliant && !enabled && itemElement.enabled)
4538   hyperLink.href = ASPx.AccessibilityEmptyUrl;
4539 },
4540 GetPopupMenuElements: function(menuElement) {
4541  return ASPx.GetChildNodesByTagName(menuElement.parentNode, "DIV");
4542 },
4543 GetContentElement: function(menuElement) {
4544  return ASPx.CacheHelper.GetCachedElement(this, "contentElement", 
4545   function() {
4546    var contentElement = ASPx.GetNodeByTagName(menuElement, "DIV", 0);
4547    if(contentElement && contentElement.className == MenuCssClasses.DX && contentElement.parentNode == menuElement) 
4548     return contentElement;
4549    contentElement = ASPx.GetNodeByTagName(menuElement, "UL", 0);
4550    if(contentElement)
4551     return contentElement;
4552    return ASPx.GetNodeByTagName(menuElement, "TABLE", 0); 
4553   }, menuElement);
4554 },
4555 GetItemElements: function(menuElement) {
4556  return ASPx.CacheHelper.GetCachedElements(this, "itemElements", 
4557   function() {
4558    var contentElement = this.GetContentElement(menuElement);
4559    return contentElement ? ASPx.GetNodesByClassName(contentElement, MenuCssClasses.Item) : null;
4560   }, menuElement);
4561 },
4562 GetSpacingElements: function(menuElement) {
4563  return ASPx.CacheHelper.GetCachedElements(this, "spacingElements", 
4564   function() {
4565    var contentElement = this.GetContentElement(menuElement);
4566    return contentElement ? ASPx.GetNodesByClassName(contentElement, MenuCssClasses.Spacing) : null;
4567   }, menuElement);
4568 },
4569 GetAlignSpacingElements: function(menuElement) {
4570  return ASPx.CacheHelper.GetCachedElements(this, "alignSpacingElements",
4571   function() {
4572    var contentElement = this.GetContentElement(menuElement);
4573    return contentElement ? ASPx.GetNodesByClassName(contentElement, MenuCssClasses.AlignSpacing) : null;
4574   }, menuElement);
4575 },
4576 GetSeparatorElements: function(menuElement) {
4577  return ASPx.CacheHelper.GetCachedElements(this, "separatorElements", 
4578   function() {
4579    var contentElement = this.GetContentElement(menuElement);
4580    return contentElement ? ASPx.GetNodesByClassName(contentElement, MenuCssClasses.Separator) : null;
4581   }, menuElement);
4582 },
4583 GetItemContentElement: function(itemElement) {
4584  return ASPx.CacheHelper.GetCachedElement(this, "contentElement", 
4585   function() {
4586    return ASPx.GetNodeByClassName(itemElement, MenuCssClasses.ContentContainer);
4587   }, itemElement);
4588 },
4589 GetItemPopOutElement: function(itemElement) {
4590  return ASPx.CacheHelper.GetCachedElement(this, "popOutElement", 
4591   function() {
4592    return ASPx.GetNodeByClassName(itemElement, MenuCssClasses.PopOutContainer);
4593   }, itemElement);
4594 },
4595 GetAdaptiveMenuItemElement: function(menuElement) {
4596  return ASPx.CacheHelper.GetCachedElement(this, "adaptiveMenuItemElement", 
4597   function() {
4598    var contentElement = this.GetContentElement(menuElement);
4599    return contentElement ? ASPx.GetNodeByClassName(contentElement, this.menu.getAdaptiveMenuItemCssClass()) : null;
4600   }, menuElement);
4601 },
4602 GetAdaptiveMenuItemSpacingElement: function(menuElement) {
4603  return ASPx.CacheHelper.GetCachedElement(this, "adaptiveMenuItemSpacingElement", 
4604   function() {
4605    var contentElement = this.GetContentElement(menuElement);
4606    return contentElement ? ASPx.GetNodeByClassName(contentElement, this.menu.getAdaptiveMenuItemSpacingCssClass()) : null;
4607   }, menuElement);
4608 },
4609 GetAdaptiveMenuElement: function(menuElement) {
4610  return ASPx.CacheHelper.GetCachedElement(this, "adaptiveMenuElement", 
4611   function() {
4612    var adaptiveItemElement = this.GetAdaptiveMenuItemElement(menuElement);
4613    if(adaptiveItemElement){
4614     var adaptiveItemIndexPath = this.menu.GetIndexPathById(adaptiveItemElement.id);
4615     var adaptiveMenuParentElement = this.menu.GetMenuElement(adaptiveItemIndexPath);
4616     if(adaptiveMenuParentElement) 
4617      return this.menu.GetMenuMainElement(adaptiveMenuParentElement);
4618    }
4619    return null;
4620   }, menuElement);
4621 },
4622 GetAdaptiveMenuContentElement: function(menuElement) {
4623  return ASPx.CacheHelper.GetCachedElement(this, "adaptiveMenuContentElement", 
4624   function() {
4625    var adaptiveMenuElement = this.GetAdaptiveMenuElement(menuElement);
4626    return adaptiveMenuElement ? this.GetContentElement(adaptiveMenuElement) : null;
4627   }, menuElement);
4628 },
4629 GetItemLinkElement: function(itemElement) {
4630  return ASPx.GetNodeByTagName(itemElement, "A", 0);
4631 },
4632 CalculateMenuControl: function(menuElement, recalculate) {
4633  if(menuElement.offsetWidth === 0) return;
4634  this.PrecalculateMenuPopOuts(menuElement);
4635  var isVertical = this.menu.IsVertical("");
4636  var isAutoWidth = ASPx.ElementContainsCssClass(menuElement, MenuCssClasse
4636s.AutoWidthMenu);
4637  var isNoWrap = ASPx.ElementContainsCssClass(menuElement, MenuCssClasses.NoWrapMenu);
4638  var contentElement = this.GetContentElement(menuElement);
4639  if(this.menu.enableAdaptivity) 
4640   this.CalculateAdaptiveMainMenu(menuElement, contentElement, isVertical, isAutoWidth, isNoWrap, recalculate);
4641  else
4642   this.CalculateMainMenu(menuElement, contentElement, isVertical, isAutoWidth, isNoWrap, recalculate);
4643 },
4644 CalculateMainMenu: function(menuElement, contentElement, isVertical, isAutoWidth, isNoWrap, recalculate) {
4645  var itemElements = this.GetItemElements(menuElement);
4646  this.PrecalculateMenuItems(menuElement, itemElements, recalculate);
4647  this.CalculateMenuItemsAutoWidth(menuElement, itemElements, isVertical, isAutoWidth);
4648  this.CalculateMinSize(menuElement, contentElement, itemElements, isVertical, isAutoWidth, isNoWrap, recalculate);
4649  this.CalculateMenuItems(menuElement, contentElement, itemElements, isVertical, recalculate);
4650  this.CalculateSeparatorsAndSpacers(menuElement, itemElements, contentElement, isVertical);
4651 },
4652 PrecalculateMenuPopOuts: function(menuElement) {
4653  if(menuElement.popOutsPreCalculated) return;
4654  var elements = this.GetItemElements(menuElement);
4655  for(var i = 0; i < elements.length; i++) {
4656   var popOutElement = this.GetItemPopOutElement(elements[i]);
4657   if (popOutElement)
4658    popOutElement.style.display = "block";
4659  }
4660  menuElement.popOutsPreCalculated = true;
4661 },
4662 PrecalculateMenuItems: function(menuElement, itemElements, recalculate) {
4663  if(!recalculate) return;
4664  for(var i = 0; i < itemElements.length; i++) {
4665   var itemContentElement = this.GetItemContentElement(itemElements[i]);
4666   if(!itemContentElement || itemContentElement.offsetWidth === 0) continue;
4667   ASPx.SetElementFloat(itemContentElement, "");
4668   ASPx.Attr.RestoreStyleAttribute(itemContentElement, "padding-left");
4669   ASPx.Attr.RestoreStyleAttribute(itemContentElement, "padding-right");
4670     this.ReCalculateMenuItemContent(itemElements[i], itemContentElement);
4671  }
4672 },
4673 ReCalculateMenuItemContent: function(itemElement, itemContentElement) {
4674  for(var j = 0; j < itemElement.childNodes.length; j++) {
4675   var child = itemElement.childNodes[j];
4676   if(!child.offsetWidth) continue;
4677   if(child !== itemContentElement) {
4678    ASPx.Attr.RestoreStyleAttribute(child, "margin-top");
4679    ASPx.Attr.RestoreStyleAttribute(child, "margin-bottom");
4680   }
4681  }
4682 },
4683 CalculateMenuItemsAutoWidth: function(menuElement, itemElements, isVertical, isAutoWidth) {
4684  if(!isAutoWidth) return;
4685  for(var i = 0; i < itemElements.length; i++) 
4686   ASPx.Attr.RestoreStyleAttribute(itemElements[i], "width");
4687  if(!isVertical) {
4688   var autoWidthItemCount = 0;
4689   var adaptiveItemCssClass = this.menu.getAdaptiveMenuItemCssClass();
4690   for(var i = 0; i < itemElements.length; i++) {
4691    if(ASPx.GetElementDisplay(itemElements[i]) && !ASPx.ElementHasCssClass(itemElements[i], adaptiveItemCssClass))
4692     autoWidthItemCount++;
4693   }
4694   for(var i = 0; i < itemElements.length; i++) {
4695    if(autoWidthItemCount > 0 && !ASPx.ElementHasCssClass(itemElements[i], adaptiveItemCssClass) && (itemElements[i].style.width === "" || itemElements[i].autoWidth)) {
4696     ASPx.Attr.ChangeStyleAttribute(itemElements[i], "width", (100 / autoWidthItemCount) + "%");
4697     itemElements[i].autoWidth = true;
4698    }
4699   }
4700  }
4701 },
4702 CalculateMenuItems: function(menuElement, contentElement, itemElements, isVertical, recalculate) {
4703  if(contentElement.itemsCalculated && recalculate)
4704   contentElement.itemsCalculated = false;
4705  if(menuElement.offsetWidth === 0) return;
4706  if(contentElement.style.margin === "0px auto")
4707   ASPx.SetStyles(contentElement, { float: "none" }); 
4708  var menuWidth = ASPx.GetCurrentStyle(menuElement).width;
4709  var menuRequireItemCorrection = isVertical && menuWidth;
4710  this.ApplyItemsVerticalAlignment(menuElement, itemElements);
4711  for(var i = 0; i < itemElements.length; i++) {
4712   if(!itemElements[i].style.width && !menuRequireItemCorrection) continue;
4713   if(ASPx.IsPercentageSize(itemElements[i].style.width) && contentElement.style.width === "")
4714    contentElement.style.width = "100%"; 
4715   var itemContentElement = this.GetItemContentElement(itemElements[i]);
4716   if(!itemContentElement || itemContentElement.offsetWidth === 0) continue;
4717   if(!contentElement.itemsCalculated) {
4718    ASPx.Attr.RestoreStyleAttribute(itemContentElement, "padding-left");
4719    ASPx.Attr.RestoreStyleAttribute(itemContentElement, "padding-right");
4720    ASPx.SetElementFloat(itemContentElement, "none");
4721    var itemContentCurrentStyle = ASPx.GetCurrentStyle(itemContentElement);
4722    if(!isVertical || (itemContentCurrentStyle.textAlign != "center" && menuWidth)) {
4723     var originalPaddingLeft = parseInt(itemContentCurrentStyle.paddingLeft);
4724     var originalPaddingRight = parseInt(itemContentCurrentStyle.paddingRight);
4725     var leftChildrenWidth = 0, rightChildrenWidth = 0;
4726     for(var j = 0; j < itemElements[i].childNodes.length; j++) {
4727      var child = itemElements[i].childNodes[j];
4728      if(!child.offsetWidth) continue;
4729      if(child !== itemContentElement) {
4730       if(ASPx.GetElementFloat(child) === "right")
4731        rightChildrenWidth += child.offsetWidth + ASPx.GetLeftRightMargins(child);
4732       else if(ASPx.GetElementFloat(child) === "left")
4733        leftChildrenWidth += child.offsetWidth + ASPx.GetLeftRightMargins(child);
4734      }
4735     }
4736     if(leftChildrenWidth > 0 || rightChildrenWidth > 0){
4737      ASPx.Attr.ChangeStyleAttribute(itemContentElement, "padding-left", (leftChildrenWidth + originalPaddingLeft) + "px");
4738      ASPx.Attr.ChangeStyleAttribute(itemContentElement, "padding-right", (rightChildrenWidth + originalPaddingRight) + "px");
4739     }
4740    }
4741   }
4742   ASPx.AdjustWrappedTextInContainer(itemContentElement);
4743   this.CalculateMenuItemContent(itemElements[i], itemContentElement);
4744  }
4745  contentElement.itemsCalculated = true;
4746 },
4747 ApplyItemsVerticalAlignment: function(menuElement, itemElements) {
4748  var menuAlignmentInProgressClassName = "miva";
4749  ASPx.AddClassNameToElement(menuElement, menuAlignmentInProgressClassName);
4750  if(!ASPx.IsExists(itemElements))
4751   itemElements = this.GetItemElements(menuElement);
4752  for(var i = 0; i < itemElements.length; i++) {
4753   var itemContentElement = this.GetItemContentElement(itemElements[i]);
4754   if(itemContentElement && itemContentElement.offsetWidth !== 0 && itemContentElement.style.verticalAlign) {
4755    this.CalculateItemContentLineHeight(itemElements[i], itemContentElement);
4756    ASPx.RemoveClassNameFromElement(itemContentElement, MenuCssClasses.ContentContainerWithVerticalAlignment);
4757   }
4758  }
4759  ASPx.RemoveClassNameFromElement(menuElement, menuAlignmentInProgressClassName);
4760 },
4761 CalculateItemContentLineHeight: function(itemElement, itemContentElement) {
4762  var lineHeight = 0;
4763  var maxHeight = itemElement.getBoundingClientRect().height - this.GetBordersAndPaddingSummaryHeight(itemElement);
4764  if(itemContentElement && itemContentElement.offsetHeight != maxHeight)
4765   lineHeight = maxHeight - this.GetBordersAndPaddingSummaryHeight(itemContentElement);
4766  if(lineHeight > 0) {
4767   var link = this.GetItemLinkElement(itemElement);
4768   if(link)
4769    ASPx.SetStyles(link, { lineHeight: lineHeight }, false);
4770   else
4771    ASPx.SetStyles(itemContentElement, { lineHeight: lineHeight }, false);
4772  }
4773 },
4774 GetBordersAndPaddingSummaryHeight: function(element) {
4775  var elementStyle = getComputedStyle(element);
4776  return ASPx.GetVerticalBordersWidth(element, elementStyle) + ASPx.PxToFloat(elementStyle.paddingTop) + ASPx.PxToFloat(elementStyle.paddingBottom);
4777 },
4778 CalculateMenuItemContent: function(itemElement, itemContentElement) {
4779  var itemContentFound = false;
4780  for(var j = 0; j < itemElement.childNodes.length; j++) {
4781   var child = itemElement.childNodes[j];
4782   if(!child.offsetWidth) continue;
4783   var contentHeight = itemContentElement.offsetHeight;
4784   if(child !== itemContentElement) {
4785    if(itemContentFound)
4786     ASPx.Attr.ChangeStyleAttribute(child, "margin-top", "-" + contentHeight + "px");
4787    else
4788     ASPx.Attr.ChangeStyleAttribute(child, "margin-bottom", "-" + contentHeight + "px");
4789   }
4790   else
4791    itemContentFound = true;
4792  }
4793 },
4794 CalculateSubMenu: function(parentElement, recalculate) {
4795  var menuElement = this.menu.GetMenuMainElement(parentElement);
4796  var contentElement = this.GetContentElement(menuElement);
4797  if(!parentElement.isSubMenuCalculated || recalculate) {
4798   menuElement.style.width = "";
4799   menuElement.style.display = "table";
4800   menuElement.style.borderSpacing = "0px";
4801   parentElement.isSubMenuCalculated = true;
4802   if(contentElement.tagName === "UL") {
4803    if(contentElement.offsetWidth > 0) {
4804     menuElement.style.width = contentElement.offsetWidth + "px";
4805     menuElement.style.display = "";
4806     if(ASPx.IsPercentageSize(contentElement.style.width))
4807      contentElement.style.width = menuElement.style.width;
4808    }
4809    else
4810     parentElement.isSubMenuCalculated = false;
4811   }
4812  }
4813  this.CalculateSubMenuItems(menuElement, contentElement, recalculate);
4814 },
4815 CalculateSubMenuItems: function(menuElement, contentElement, recalculate) {
4816  var itemElements = this.GetItemElements(menuElement);
4817  this.PrecalculateMenuItems(menuElement, itemElements, recalculate);
4818  this.CalculateMenuItems(menuElement, contentElement, itemElements, true, recalculate);
4819 },
4820 ResetMinSize: function() {
4821  var menuElement = this.menu.GetMainElement();
4822  if(!menuElement.isMinSizeCalculated || this.menu.isVertical) return;
4823  var itemElements = this.GetItemElements(menuElement);
4824  var contentElement = this.GetContentElement(menuElement);
4825  if(!!contentElement.adaptiveInfo)
4826   itemElements = itemElements.concat(contentElement.adaptiveInfo.elements);
4827  for(var i = 0; i < itemElements.length; i++)
4828   this.ResetItemMinSize(itemElements[i]);
4829  menuElement.isMinSizeCalculated = false;
4830 },
4831 ResetItemMinSize: function(itemElement) {
4832  itemElement.style.minWidth = "";
4833  itemElement.isMinSizeCalculated = false;
4834 },
4835 CalculateMinSize: function(menuElement, contentElement, itemElements, isVertical, isAutoWidth, isNoWrap, recalculate) {
4836  if(menuElement.isMinSizeCalculated && !recalculate) return;
4837  if(isVertical) {
4838   menuElement.style.minWidth = "";
4839   if(!this.menu.IsSidePanelExpanded()) {
4840    ASPx.Attr.ChangeStyleAttribute(contentElement, "width", "1px");
4841    for(var i = 0; i < itemElements.length; i++) {
4842     var itemContentElement = this.GetItemContentElement(itemElements[i]);
4843     if(!itemContentElement || itemElements[i].offsetWidth === 0) continue;
4844     this.CalculateItemMinSize(itemElements[i], recalculate);
4845    }
4846    ASPx.Attr.RestoreStyleAttribute(contentElement, "width");
4847   }
4848  }
4849  else {
4850   ASPx.RemoveClassNameFromElement(menuElement, MenuCssClasses.NoWrapMenu);
4851   ASPx.RemoveClassNameFromElement(menuElement, MenuCssClasses.AutoWidthMenu);
4852   if(isAutoWidth || isNoWrap)
4853    menuElement.style.minWidth = "";
4854   ASPx.Attr.ChangeStyleAttribute(menuElement, "width", "1px");
4855   for(var i = 0; i < itemElements.length; i++) {
4856    var itemContentElement = this.GetItemContentElement(itemElements[i]);
4857    if((!itemContentElement || itemElements[i].offsetWidth === 0) && !ASPx.ElementHasCssClass(itemElements[i], MenuCssClasses.ItemTemplate)) continue;
4858    var textContainer = ASPx.GetNodeByTagName(itemContentElement, "SPAN", 0);
4859    if(textContainer && ASPx.GetCurrentStyle(textContainer).whiteSpace !== "nowrap")
4860     ASPx.AdjustWrappedTextInContainer(itemContentElement);
4861    this.CalculateItemMinSize(itemElements[i], recalculate);
4862   }
4863   if(isAutoWidth)
4864    ASPx.AddClassNameToElement(menuElement, MenuCssClasses.AutoWidthMenu);
4865   if(isNoWrap)
4866    ASPx.AddClassNameToElement(menuElement, MenuCssClasses.NoWrapMenu);
4867   if(isAutoWidth || isNoWrap)
4868    menuElement.style.minWidth = (contentElement.offsetWidth + ASPx.GetLeftRightBordersAndPaddingsSummaryValue(menuElement)) + "px";
4869   ASPx.Attr.RestoreStyleAttribute(menuElement, "width");
4870  }
4871  menuElement.isMinSizeCalculated = true;
4872 },
4873 CalculateItemMinSize: function(itemElement, recalculate) {
4874  if(itemElement.isMinSizeCalculated && !recalculate) return;
4875  itemElement.style.minWidth = "";
4876  var childrenWidth = 0;
4877  if(ASPx.ElementHasCssClass(itemElement, MenuCssClasses.ItemTemplate)) {
4878   ASPx.Attr.ChangeStyleAttribute(itemElement, "display", "table");
4879   childrenWidth += itemElement.getBoundingClientRect().width;
4880   ASPx.Attr.RestoreStyleAttribute(itemElement, "display");
4881   if(ASPx.Browser.Edge && ASPx.Browser.MajorVersion >= 16)
4882    var dummy = itemElement.clientWidth;
4883  } 
4884  else {
4885   for(var j = 0; j < itemElement.childNodes.length; j++) {
4886    var child = itemElement.childNodes[j];
4887    if(!child.offsetWidth) continue;
4888    var float = ASPx.GetElementFloat(child);
4889    if(float === "none") {
4890     childrenWidth = child.getBoundingClientRect().width;
4891     break;
4892    }
4893    else
4894     childrenWidth += child.getBoundingClientRect().width;
4895   }
4896  }
4897  itemElement.style.minWidth = Math.ceil(childrenWidth) + "px";
4898  itemElement.isMinSizeCalculated = true;
4899 },
4900 CalculateSeparatorsAndSpacers: function(menuElement, itemElements, contentElement, isVertical, isAutoWidth, isNoWrap) {
4901  var spacerElements = this.GetSpacingElements(menuElement);
4902  var spacerAndSeparatorElements = spacerElements.concat(this.GetSeparatorElements(menuElement));
4903  for(var i = 0; i < spacerAndSeparatorElements.length; i++) {
4904   ASPx.Attr.RestoreStyleAttribute(spacerAndSeparatorElements[i], "height");
4905   if(ASPx.Browser.Edge) {
4906    var savedDisplay = spacerAndSeparatorElements[i].style.display;
4907    spacerAndSeparatorElements[i].style.display = "none";
4908    var temp = spacerAndSeparatorElements[i].offsetHeight; 
4909    spacerAndSeparatorElements[i].style.display = savedDisplay;
4910   }
4911  }
4912  if(!isVertical && itemElements) {
4913   var menuHeight = 0;
4914   if(!isAutoWidth && !isNoWrap) {
4915    for(var i=0; i < itemElements.length; i++) {
4916     var newHeight = itemElements[i].getBoundingClientRect().height;
4917     if(newHeight > menuHeight)
4918      menuHeight = newHeight;
4919    }
4920   }
4921   for(var i = 0; i < spacerAndSeparatorElements.length; i++){
4922    var separatorHeight = menuHeight - ASPx.GetTopBottomBordersAndPaddingsSummaryValue(spacerAndSeparatorElements[i]) - ASPx.GetTopBottomMargins(spacerAndSeparatorElements[i]);
4923    ASPx.Attr.ChangeStyleAttribute(spacerAndSeparatorElements[i], "height", separatorHeight + "px");
4924   }
4925   for(var i = 0; i < spacerElements.length; i++){
4926    if(!ASPx.ElementContainsCssClass(spacerElements[i], this.menu.getAdaptiveMenuItemSpacingCssClass()))
4927     spacerElements[i].style.minWidth = spacerElements[i].style.width; 
4928   }
4929   this.calculateAlignSpacings(menuElement, contentElement);
4930  }
4931 },
4932 calculateAlignSpacings: function(menuElement, contentElement) {
4933  var separatorElements = this.GetAlignSpacingElements(menuElement),
4934   separatorsCount = separatorElements.length;
4935  if(separatorsCount === 0) return;
4936  ASPx.Data.ForEach(separatorElements, function(separator) {
4937   separator.style.width = "0";
4938  });
4939  var unit = this.menu.enableAdaptivity ? "%" : "px";
4940  var width = this.menu.enableAdaptivity ? 100 / separatorsCount :
4941   (ASPx.GetClearClientWidth(menuElement) - contentElement.offsetWidth) / separatorsCount;
4942  ASPx.Data.ForEach(separatorElements, function(separator) {
4943   separator.style.width = width + unit;
4944  });
4945  if(!this.menu.enableAdaptivity)
4946   separatorElements[0].style.width = (width - 1) + unit;
4947 },
4948 CalculateAdaptiveMainMenu: function(menuElement, contentElement, isVertical, isAutoWidth, isNoWrap, recalculate) {
4949  var adaptiveItemElement = this.GetAdaptiveMenuItemElement(menuElement);
4950  if(!adaptiveItemElement) return;
4951  var adaptiveItemSpacing = this.GetAdaptiveMenuItemSpacingElement(menuElement);
4952  if(adaptiveItemSpacing) adaptiveItemSpacing.style.width = "";
4953  var adaptiveMenuElement = this.GetAdaptiveMenuElement(menuElement);
4954  if(!adaptiveMenuElement) return;
4955  var adaptiveMenuContentElement = this.GetAdaptiveMenuContentElement(menuElement);
4956  var adaptiveFakeMenuItem = ASPx.GetNodeByClassName(adaptiveMenuContentElement, MenuCssClasse
4956s.AdaptiveFakeMenuItem);
4957  if(adaptiveFakeMenuItem) ASPx.RemoveElement(adaptiveFakeMenuItem);
4958  if(!contentElement.adaptiveInfo)
4959   this.InitAdaptiveInfo(contentElement);
4960  var wasAdaptivity = contentElement.adaptiveInfo.hasAdaptivity;
4961  if(wasAdaptivity) {
4962   var previousSibling = this.GetAdaptiveItemElementPreviousSibling(adaptiveItemSpacing || adaptiveItemElement);
4963   this.RestoreAdaptiveItems(previousSibling, contentElement, isVertical);
4964  }
4965  if(!isVertical) {
4966   ASPx.SetElementDisplay(adaptiveItemElement, true);
4967   if(adaptiveItemSpacing) ASPx.SetElementDisplay(adaptiveItemSpacing, true);
4968   ASPx.AddClassNameToElement(menuElement, MenuCssClasses.CalculateMenu);
4969   ASPx.RemoveClassNameFromElement(menuElement, MenuCssClasses.NoWrapMenu);
4970   menuElement.style.minWidth = "";
4971   var adaptiveItemWidth = adaptiveItemElement.offsetWidth;
4972   if(isAutoWidth) {
4973    ASPx.Attr.ChangeStyleAttribute(contentElement, "display", "none");
4974    ASPx.Attr.ChangeStyleAttribute(menuElement, "min-width", "");
4975   }
4976   var menuWidth = menuElement.offsetWidth - ASPx.GetLeftRightBordersAndPaddingsSummaryValue(menuElement) - adaptiveItemWidth;
4977   if(isAutoWidth) {
4978    ASPx.Attr.RestoreStyleAttribute(contentElement, "display");
4979    ASPx.Attr.RestoreStyleAttribute(menuElement, "min-width");
4980   }
4981   var additionalWidth = adaptiveItemWidth;
4982   if(adaptiveItemSpacing) {
4983    menuWidth -= adaptiveItemSpacing.offsetWidth;
4984    additionalWidth += adaptiveItemSpacing.offsetWidth;
4985   }
4986   var hasAdaptivity = this.HideAdaptiveItems(menuWidth, additionalWidth, contentElement, adaptiveMenuContentElement);
4987   contentElement.adaptiveInfo.hasAdaptivity = hasAdaptivity;
4988   this.SetAdaptiveItemElementVisibility(adaptiveItemElement, adaptiveItemSpacing, hasAdaptivity);
4989   contentElement.style.width = hasAdaptivity ? "100%" : "";
4990   if(hasAdaptivity){
4991    ASPx.CacheHelper.DropCache(adaptiveMenuElement);
4992    this.CalculateSubMenu(adaptiveMenuElement, true);
4993    this.CalculateSeparatorsAndSpacers(adaptiveMenuElement, null, adaptiveMenuContentElement, true);
4994   }
4995   if(isNoWrap) {
4996    ASPx.AddClassNameToElement(menuElement, MenuCssClasses.NoWrapMenu);
4997    if(adaptiveItemSpacing) adaptiveItemSpacing.style.width = hasAdaptivity ? "100%" : "";
4998   }
4999   ASPx.RemoveClassNameFromElement(menuElement, MenuCssClasses.CalculateMenu);
5000  }
5001  else {
5002   this.SetAdaptiveItemElementVisibility(adaptiveItemElement, adaptiveItemSpacing, false);
5003  }
5004  if(wasAdaptivity || contentElement.adaptiveInfo.hasAdaptivity)
5005   ASPx.CacheHelper.DropCache(menuElement);
5006  if(!ASPx.GetNodesByTagName(adaptiveMenuContentElement, "li").length)
5007   adaptiveMenuContentElement.innerHTML = "<li class='" + MenuCssClasses.AdaptiveFakeMenuItem + "' role='menuitem'></li>";
5008  this.CalculateMainMenu(menuElement, contentElement, isVertical, isAutoWidth, isNoWrap, wasAdaptivity || contentElement.adaptiveInfo.hasAdaptivity || recalculate);
5009 },
5010 InitAdaptiveInfo: function(contentElement) {
5011  if(contentElement.adaptiveInfo) return;
5012  contentElement.adaptiveInfo = { };
5013  contentElement.adaptiveInfo.elements = this.CreateAdaptiveElementsArray(contentElement);
5014  contentElement.adaptiveInfo.hasAdaptivity = false;
5015 },
5016 GetAdaptiveItemElementByIndex: function(adaptiveInfo, index) {
5017  return adaptiveInfo.elements[index];
5018 },
5019 GetAdaptiveItemElementParent: function(adaptiveInfo, index) {
5020  return undefined;
5021 },
5022 GetAdaptiveItemElementPreviousSibling: function(defaultPreviousSibling) {
5023  return defaultPreviousSibling;
5024 },
5025 RestoreAdaptiveItems: function(previousSibling, contentElement, isVertical) {
5026  this.SetLastSeparatorsVisible(true, contentElement);
5027  for(var i = 0; i < contentElement.adaptiveInfo.elements.length; i++) {
5028   var element = this.GetAdaptiveItemElementByIndex(contentElement.adaptiveInfo, i);
5029   var isReplacedIndent = !element.parent;
5030   if(isReplacedIndent)
5031    ASPx.RemoveElement(ASPx.GetElementById(element.id));
5032   var itemParentElement = this.GetAdaptiveItemElementParent(contentElement.adaptiveInfo, i) || contentElement;
5033   itemParentElement.insertBefore(element, previousSibling);
5034   ASPx.Attr.RestoreStyleAttribute(element, "width");
5035   if(!isVertical)
5036    this.SetItemItemPopOutImageHorizontal(element);
5037   if(ASPx.ElementContainsCssClass(element, MenuCssClasses.Separator) || ASPx.ElementContainsCssClass(element, MenuCssClasses.Spacing))
5038    ASPx.RemoveClassNameFromElement(element, MenuCssClasses.AdaptiveMenuHiddenElement);
5039  }
5040  if(this.menu.GetRootItem()) {
5041   for(var i = this.elementsToHide.length - 1; i >= 0; i--) {
5042    if(!this.elementsToHide[i]) continue;
5043    var indexPath = this.elementsToHide[i].indexPath;
5044    if(this.menu.GetItemByIndexPath(indexPath).GetVisible())
5045     this.menu.UpdateItemCssClasses(indexPath, true);
5046    this.elementsToHide[i] = null;
5047   }
5048  }
5049  this.elementsToHide = [];
5050 },
5051 SetLastSeparatorsVisible: function(isVisible, contentElement) {
5052  var elements = ASPx.GetChildElementNodes(contentElement);
5053  for(var i = 0; i < elements.length; i++) {
5054   var element = elements[i];
5055   if(ASPx.ElementContainsCssClass(element, MenuCssClasses.Separator) || ASPx.ElementContainsCssClass(element, MenuCssClasses.Spacing))
5056    ASPx.RemoveClassNameFromElement(element, MenuCssClasses.AdaptiveMenuHiddenElement);
5057   else
5058    break;
5059  }
5060 },
5061 CreateAdaptiveElementsArray: function(contentElement) {
5062  var result = [];
5063  var elements = ASPx.GetChildElementNodes(contentElement);
5064  for(var i = 0; i < elements.length; i++) {
5065   if(this.CheckElementIsAdaptive(elements[i]))
5066    result.push(elements[i]);
5067  }
5068  return result;
5069 },
5070 SetItemItemPopOutImageHorizontal: function(element) {
5071  var popOutElements = ASPx.GetNodesByPartialClassName(element, "dxWeb_mVerticalPopOut");
5072  for(var i = 0; i < popOutElements.length; i++)
5073   popOutElements[i].className = popOutElements[i].className.replace("Vertical", "Horizontal");
5074 },
5075 CheckElementIsAdaptive: function(element) {
5076  return !ASPx.ElementHasCssClass(element, this.menu.getAdaptiveMenuItemCssClass()) && !ASPx.ElementHasCssClass(element, this.menu.getAdaptiveMenuItemSpacingCssClass());
5077 },
5078 CheckAdaptiveItemsWidth: function(contentElement, menuWidth, additionalWidth) {
5079  var itemsWidth = 0;
5080  var elements = ASPx.GetChildElementNodes(contentElement);
5081  for(var i = 0; i < elements.length; i++) {
5082   var element = elements[i];
5083   if(this.CheckElementIsAdaptive(element) && element.offsetWidth > 0)
5084    itemsWidth += this.GetAdaptiveElementWidth(element);
5085   if(itemsWidth > menuWidth + additionalWidth)
5086    return false;
5087  }
5088  return true;
5089 },
5090 GetAdaptiveElementWidth: function(element) {
5091  return element.style.minWidth !== "" ?
5092   parseInt(element.style.minWidth) + ASPx.GetHorizontalBordersWidth(element) + ASPx.GetLeftRightPaddings(element) :
5093   element.offsetWidth;
5094 },
5095 HideAdaptiveItems: function(menuWidth, additionalWidth, contentElement, adaptiveMenuContentElement) {
5096  if(this.CheckAdaptiveItemsWidth(contentElement, menuWidth, additionalWidth))
5097   return false;
5098  this.elementsToHide = [];
5099  var elementsToHide = this.elementsToHide;
5100  var adaptiveItemSpacingCssClass = this.menu.getAdaptiveMenuItemSpacingCssClass();
5101  var addToHide = function(index, indexPath, itemElement, separatorElement, indentElement, insteadSeparatorElement) {
5102   if(!itemElement) return;
5103   if(separatorElement && ASPx.ElementHasCssClass(separatorElement, adaptiveItemSpacingCssClass))
5104    separatorElement = null;
5105   if(indentElement && ASPx.ElementHasCssClass(indentElement, adaptiveItemSpacingCssClass))
5106    indentElement = null;
5107   elementsToHide[index] = { indexPath: indexPath, itemElement: itemElement, separatorElement: separatorElement, indentElement: indentElement, insteadSeparatorElement: insteadSeparatorElement };
5108   ASPx.Attr.ChangeStyleAttribute(itemElement, "display", "none");
5109   if(separatorElement) {
5110    var elementForHide = insteadSeparatorElement || separatorElement;
5111    ASPx.Attr.ChangeStyleAttribute(elementForHide, "display", "none");
5112   }
5113   if(indentElement)
5114    ASPx.Attr.ChangeStyleAttribute(indentElement, "display", "none");
5115  };
5116  for(var i = 0; i < this.menu.adaptiveItemsOrder.length; i++){
5117   var indexPath = this.menu.adaptiveItemsOrder[i],
5118    index = parseInt(indexPath, 10),
5119    itemToKeepSeparator = this.menu.GetRootItem() ? this.GetItemForKeepSeparator(index) : null,
5120    insteadSeparatorElement = itemToKeepSeparator ? this.menu.GetItemIndentElement(itemToKeepSeparator.indexPath) : null;
5121   addToHide(index, indexPath, this.menu.GetItemElement(indexPath), this.menu.GetItemSeparatorElement(indexPath), this.menu.GetItemIndentElement(indexPath), insteadSeparatorElement);
5122   var actualAdditionalWidth = this.NeedShowAdaptiveItemForHiddenElements(elementsToHide) ? 0 : additionalWidth;
5123   if(this.CheckAdaptiveItemsWidth(contentElement, menuWidth, actualAdditionalWidth))
5124    break;
5125  }
5126  var hasImages = false;
5127  for(var i = 0; i < elementsToHide.length; i++) {
5128   if(!elementsToHide[i]) continue;
5129   ASPx.Attr.RestoreStyleAttribute(elementsToHide[i].itemElement, "display");
5130   if(elementsToHide[i].separatorElement) {
5131    var elementForRestore = elementsToHide[i].insteadSeparatorElement || elementsToHide[i].separatorElement;
5132    ASPx.Attr.RestoreStyleAttribute(elementForRestore, "display");
5133   }
5134   if(elementsToHide[i].indentElement)
5135    ASPx.Attr.RestoreStyleAttribute(elementsToHide[i].indentElement, "display");
5136   this.menu.UpdateItemCssClasses(elementsToHide[i].indexPath, false);
5137   if(elementsToHide[i].separatorElement) {
5138    if(this.menu.GetRootItem())
5139     this.KeepSeparatorInRoot(i);
5140    adaptiveMenuContentElement.appendChild(elementsToHide[i].separatorElement);
5141   }
5142   else if(this.menu.GetRootItem())
5143    this.InsertSeparatorInAdaptiveMenu(i, elementsToHide[i].indexPath);
5144   if(elementsToHide[i].indentElement)
5145    adaptiveMenuContentElement.appendChild(elementsToHide[i].indentElement);
5146   adaptiveMenuContentElement.appendChild(elementsToHide[i].itemElement);
5147   this.PrepareHiddenAdaptiveItemElement(elementsToHide[i].itemElement);
5148   if(ASPx.GetNodeByClassName(elementsToHide[i].itemElement, "dxm-image"))
5149    hasImages = true;
5150  }
5151  for(var i = 0; i < elementsToHide.length; i++) {
5152   if(!elementsToHide[i]) continue;
5153   if(elementsToHide[i].separatorElement) 
5154    ASPx.AddClassNameToElement(elementsToHide[i].separatorElement, MenuCssClasses.AdaptiveMenuHiddenElement);
5155   if(elementsToHide[i].indentElement) 
5156    ASPx.AddClassNameToElement(elementsToHide[i].indentElement, MenuCssClasses.AdaptiveMenuHiddenElement);
5157   break;
5158  }
5159  this.SetLastSeparatorsVisible(false, contentElement);
5160  this.PrepareAdaptiveMenuContentElement(adaptiveMenuContentElement, hasImages);
5161  return elementsToHide.length > 0;
5162 },
5163 PrepareHiddenAdaptiveItemElement: function(itemElement) {
5164  ASPx.Attr.ChangeStyleAttribute(itemElement, "width", "auto");
5165  this.SetItemPopOutImageVertical(itemElement);
5166 },
5167 PrepareAdaptiveMenuContentElement: function(contentElement, hasImages) {
5168  if(hasImages)
5169   ASPx.RemoveClassNameFromElement(contentElement, MenuCssClasses.WithoutImages);
5170  else
5171   ASPx.AddClassNameToElement(contentElement, MenuCssClasses.WithoutImages);
5172 },
5173 SetAdaptiveItemElementVisibility: function(adaptiveItemElement, adaptiveItemSpacing, visible) {
5174  ASPx.SetElementDisplay(adaptiveItemElement, visible);
5175  if(adaptiveItemSpacing)
5176   ASPx.SetElementDisplay(adaptiveItemSpacing, visible);
5177 },
5178 NeedShowAdaptiveItemForHiddenElements: function(elementsToHide) {
5179  return true;
5180 },
5181 KeepSeparatorInRoot: function(index) {
5182  var nextItemInGroup = this.GetItemForKeepSeparator(index);
5183  if(nextItemInGroup) {
5184   var separatorElement = this.elementsToHide[index].separatorElement;
5185   this.ReplaceIndentElement(nextItemInGroup.indexPath, separatorElement);
5186  }
5187 },
5188 InsertSeparatorInAdaptiveMenu: function(index, indexPath) {
5189  var itemWithSeparator = this.GetItemWithSeparatorForAdaptiveMenu(index);
5190  if(itemWithSeparator) {
5191   var separatorElement = this.menu.GetItemSeparatorElement(itemWithSeparator.indexPath);
5192   if(!separatorElement) return;
5193   this.elementsToHide[index].indentElement = this.ReplaceIndentElement(indexPath, separatorElement);
5194  }
5195 },
5196 ReplaceIndentElement: function(indexPath, separatorElement) {
5197  var itemElement = this.menu.GetItemElement(indexPath),
5198   itemIndent = this.menu.GetItemIndentElement(indexPath),
5199   newIndentElement = separatorElement.cloneNode(true),
5200   parentNode = itemElement.parentNode;
5201  newIndentElement.id = this.menu.GetItemIndentElementId(indexPath);
5202  if(itemIndent)
5203   itemIndent.parentNode.removeChild(itemIndent);
5204  parentNode.insertBefore(newIndentElement, itemElement);
5205  return newIndentElement;
5206 },
5207 GetItemForKeepSeparator: function(index) {
5208  var rootItem = this.menu.GetRootItem(),
5209   nextItemInGroup = this.menu.GetNextVisibleItemInGroup(rootItem, index, true);
5210  if(nextItemInGroup && this.IsItemInAdaptiveMenu(nextItemInGroup.index)) {
5211   while(nextItemInGroup && this.IsItemInAdaptiveMenu(nextItemInGroup.index))
5212    nextItemInGroup = this.menu.GetNextVisibleItemInGroup(rootItem, nextItemInGroup.index, true);
5213  }
5214  return nextItemInGroup;
5215 },
5216 GetItemWithSeparatorForAdaptiveMenu: function(index) {
5217  var rootItem = this.menu.GetRootItem(),
5218   prevItemInGroup = this.menu.GetPrevVisibleItemInGroup(rootItem, index);
5219  if(prevItemInGroup && !this.IsItemInAdaptiveMenu(prevItemInGroup.index) && !this.menu.IsItemBeginsGroup(prevItemInGroup)) {
5220   while(prevItemInGroup && !this.IsItemInAdaptiveMenu(prevItemInGroup.index) && !this.menu.IsItemBeginsGroup(prevItemInGroup))
5221    prevItemInGroup = this.menu.GetPrevVisibleItemInGroup(rootItem, prevItemInGroup.index);
5222  }
5223  return prevItemInGroup && !this.IsItemInAdaptiveMenu(prevItemInGroup.index) ? prevItemInGroup : null;
5224 },
5225 IsItemInAdaptiveMenu: function(index) {
5226  return this.elementsToHide.length >= index ? !!this.elementsToHide[index] : false;
5227 },
5228 SetItemPopOutImageVertical: function(element) {
5229  var popOutElements = ASPx.GetNodesByPartialClassName(element, "dxWeb_mHorizontalPopOut");
5230  for(var i = 0; i < popOutElements.length; i++)
5231   popOutElements[i].className = popOutElements[i].className.replace("Horizontal", "Vertical");
5232 },
5233 ChangeItemsPopOutImages: function(menuElement, isVertical) {
5234  var itemElements = this.GetItemElements(menuElement);
5235  for(var i = 0; i < itemElements.length; i++){
5236   if(isVertical)
5237    this.SetItemPopOutImageVertical(itemElements[i]);
5238   else
5239    this.SetItemItemPopOutImageHorizontal(itemElements[i]);
5240  }
5241 },
5242 ChangeOrientaion: function(menuElement, isVertical) {
5243  var oldCssSelector = isVertical ? MenuCssClasses.HorizontalMenu : MenuCssClasses.VerticalMenu;
5244  var newCssSelector = isVertical ? MenuCssClasses.VerticalMenu : MenuCssClasses.HorizontalMenu;
5245  menuElement.className = menuElement.className.replace(oldCssSelector, newCssSelector);
5246  this.ChangeItemsPopOutImages(menuElement, isVertical);
5247  this.CalculateMenuControl(menuElement, true);
5248  this.ChangeItemsPopOutImages(menuElement, isVertical);
5249 }
5250});
5251var MenuScrollingManager = ASPx.CreateClass(ASPx.ScrollingManager, {
5252 constructor: function(menuScrollHelper) {
5253  this.constructor.prototype.constructor.call(this, menuScrollHelper, {
5254   scrollableArea: menuScrollHelper.scrollingAreaElement,
5255   orientation: [0, 1],
5256   onBeforeScrolling: function(manager, direction) {
5257    manager.owner.OnBeforeScrolling(direction);
5258   },
5259   onAfterScrolling: function(manager, direction) {
5260    manager.owner.OnAfterScrolling(direction);
5261   },
5262   forseEmulation: false,
5263   useMarginForPosition: true,
5264   handleMouseWheel: menuScrollHelper.handleMouseWheel
5265  });
5266 },
5267 setParentNodeOverflow: function() { 
5268  if(ASPx.Browser.MSTouchUI) {
5269   this.scrollableArea.parentNode.style.overflow = "auto";
5270   this.scrollableArea.parentNode.style["-ms-overflow-style"] = "none";
5271  }  
5272 }
5273});
5274var MenuScrollHelper = ASPx.CreateClass(null, {
5275 constructor: function(menu, indexPath) {
5276  this.menu = menu;
5277  this.indexPath = indexPath;
5278  this.scrollingAreaElement = null;
5279  this.manager = null;
5280  this.initialized = false;
5281  this.visibleItems = [];
5282  this.itemsHeight = 0;
5283  this.scrollHeight = 0;
5284  this.scrollUpButtonHeight = 0;
5285  this.scrollDownButtonHeight = 0;
5286  this.scrollAreaHeight = null;
5287  this.scrollUpButtonVisible = false;
5288  this.scrollDownButtonVisible = false;
5289  this.handleMouseWheel = true;
5290 },
5291 Initialize: function() {
5292  if(this.initialized && !this.menu.NeedCreateItemsOnClientSide()) return;
5293  this.scrollingAreaElement = this.menu.GetScrollContentItemsContainer(this.indexPath);
5294  this.manager = new MenuScrollingManager(this);
5295  this.ShowScrollButtons();
5296  var scrollUpButton = this.menu.GetScrollUpButtonElement(this.indexPath);
5297  if(scrollUpButton) {
5298   this.scrollUpButtonHeight = this.GetScrollButtonHeight(scrollUpButton);
5299   ASPx.Selection.SetElementSelectionEnabled(scrollUpButton, false);
5300  }
5301  var scrollDownButton = this.menu.GetScrollDownButtonElement(this.indexPath);
5302  if(scrollDownButton) {
5303   this.scrollDownButtonHeight = this.GetScrollButtonHeight(scrollDownButton);
5304   ASPx.Selection.SetElementSelectionEnabled(scrollDownButton, false);
5305  }
5306  if(ASPx.Browser.WebKitTouchUI) {
5307   var preventDefault = function(event) { event.preventDefault(); };
5308   ASPx.Evt.AttachEventToElement(scrollUpButton, "touchstart", preventDefault);
5309   ASPx.Evt.AttachEventToElement(scrollDownButton, "touchstart", preventDefault);
5310  }
5311  this.HideScrollButtons();
5312  this.initialized = true;
5313 },
5314 GetScrollButtonHeight: function(button) {
5315  var style = ASPx.GetCurrentStyle(button);
5316  return button.offsetHeight + ASPx.PxToInt(style.marginTop) + ASPx.PxToInt(style.marginBottom);
5317 },
5318 FillVisibleItemsList: function() {
5319  var index = 0;
5320  this.visibleItems = [];
5321  while(true) {
5322   var childIndexPath = (this.indexPath != "" ? this.indexPath + ASPx.ItemIndexSeparator : "") + index;
5323   var itemElement = this.menu.GetItemElement(childIndexPath);
5324   if(itemElement == null)
5325    break;
5326   if(ASPx.GetElementDisplay(itemElement))
5327    this.visibleItems.push(itemElement);
5328   index++;
5329  }
5330 },
5331 CanCalculate: function() {
5332  return this.scrollingAreaElement && ASPx.IsElementDisplayed(this.scrollingAreaElement);
5333 },
5334 Calculate: function(scrollHeight) {
5335  if(!this.CanCalculate()) return;
5336  this.FillVisibleItemsList();
5337  this.itemsHeight = 0;
5338  this.scrollHeight = scrollHeight;
5339  var itemsContainer = this.menu.GetScrollContentItemsContainer(this.indexPath);
5340  if(itemsContainer) this.itemsHeight = itemsContainer.offsetHeight;
5341  this.SetPosition(0);
5342  this.CalculateScrollingElements(-1);
5343 },
5344 GetPosition: function() {
5345  return -this.manager.GetScrolledAreaPosition();
5346 },
5347 SetPosition: function(pos) {
5348  this.manager.SetScrolledAreaPosition(-pos);
5349 },
5350 CalculateScrollingElements: function(direction) {
5351  if(this.itemsHeight <= this.scrollHeight) {
5352   this.scrollUpButtonVisible = false;
5353   this.scrollDownButtonVisible = false;
5354   this.scrollAreaHeight = null;
5355   this.SetPosition(0);
5356  }
5357  else {
5358   var scrollTop = this.GetPosition();
5359   this.scrollAreaHeight = this.scrollHeight;
5360   if(direction > 0) {
5361    var showScrollUpButton = !this.scrollUpButtonVisible;
5362    this.scrollUpButtonVisible = true;
5363    this.scrollAreaHeight -= this.scrollUpButtonHeight;
5364    this.scrollDownButtonVisible = this.itemsHeight - this.scrollAreaHeight - scrollTop > this.scrollDownButtonHeight;
5365    if(this.scrollDownButtonVisible) {
5366     this.scrollAreaHeight -= this.scrollDownButtonHeight;
5367     if(showScrollUpButton)
5368      this.SetPosition(this.GetPosition() + this.scrollUpButtonHeight);
5369    }
5370    else {
5371     this.SetPosition(this.itemsHeight - this.scrollAreaHeight);
5372    }
5373   }
5374   else {
5375    this.scrollDownButtonVisible = true;
5376    this.scrollAreaHeight -= this.scrollDownButtonHeight;
5377    this.scrollUpButtonVisible = scrollTop > this.scrollUpButtonHeight;
5378    if(this.scrollUpButtonVisible)
5379     this.scrollAreaHeight -= this.scrollUpButtonHeight;
5380    else
5381     this.SetPosition(0);
5382   }
5383   if(this.scrollAreaHeight < 1) this.scrollAreaHeight = 1;
5384  }
5385  this.UpdateScrollingElements();
5386 },
5387 UpdateScrollingElements: function() {
5388  this.UpdateScrollAreaHeight();
5389  this.UpdateScrollButtonsVisibility();
5390 },
5391 UpdateScrollAreaHeight: function() {
5392  var scrollAreaElement = this.menu.GetScrollAreaElement(this.indexPath);
5393  if(scrollAreaElement)
5394   scrollAreaElement.style.height = (this.scrollAreaHeight) ? (this.scrollAreaHeight + "px") : "";
5395 },
5396 UpdateScrollButtonsVisibility: function() {
5397  var scrollUpButton = this.menu.GetScrollUpButtonElement(this.indexPath);
5398  if(scrollUpButton) ASPx.SetElementDisplay(scrollUpButton, this.scrollUpButtonVisible);
5399  var scrollDownButton = this.menu.GetScrollDownButtonElement(this.indexPath);
5400  if(scrollDownButton) ASPx.SetElementDisplay(scrollDownButton, this.scrollDownButtonVisible);
5401 },
5402 ChangeScrollButtonsVisibility: function(visible) {
5403  this.scrollUpButtonVisible = visible;
5404  this.scrollDownButtonVisible = visible;
5405  this.UpdateScrollButtonsVisibility();
5406 },
5407 ShowScrollButtons: function() {
5408  this.ChangeScrollButtonsVisibility(true);
5409 },
5410 HideScrollButtons: function() {
5411  this.ChangeScrollButtonsVisibility(false);
5412 },
5413 ResetScrolling: function() {
5414  if(!this.initialized)
5415   return;
5416  this.HideScrollButtons();
5417  this.SetPosition(0);
5418  this.scrollAreaHeight = null;
5419  this.UpdateScrollAreaHeight();
5420 },
5421 GetScrollAreaHeight: function() {
5422  var scrollAreaElement = this.menu.GetScrollAreaElement(this.indexPath);
5423  if(scrollAreaElement)
5424   return scrollAreaElement.offsetHeight;
5425  return 0;
5426 },
5427 OnAfterScrolling: function(direction) {
5428  this.CalculateScrollingElements(direction);
5429 },
5430 OnBeforeScrolling: function(direction) {
5431  var scrollButton = (direction > 0) ? this.menu.GetScrollDownButtonElement(this.indexPath) :
5432   this.menu.GetScrollUpButtonElement(this.indexPath);
5433  if(!scrollButton || !ASPx.GetElementDisplay(scrollButton))
5434   this.manager.StopScrolling();
5435 },
5436 StartScrolling: function(direction, delay, step) {
5437  this.manager.StartScrolling(direction, delay, step);
5438 },
5439 StopScrolling: function() {
5440  this.manager.StopScrolling();
5441 }
5442});
5443MenuScrollHelper.GetMenuByScrollButtonId = function(id) {
5444 var menuName = aspxGetMenuCollection().GetMenuNameBySuffixes(id, [Constants.SBIdSuffix]);
5445 return aspxGetMenuCollection().Get(menuName);
5446};
5447var ASPxClientMenuBase = ASPx.CreateClass(ASPxClientControl, {
5448 constructor: function(name) {
5449  this.constructor.prototype.constructor.call(this, name);
5450  this.renderData = null;
5451  this.renderHelper = this.CreateRenderHelper();
5452  this.sampleItemsFlags = {
5453   TextOnly: 0,
5454   SubItems: 1,
5455   Image: 2,
5456   NavigateUrl: 4,
5457   DropDownMode: 8,
5458   CheckBox: 16,
5459   ImageClassName: 32,
5460   Svg: 64
5461  };
5462  this.rootMenuSample = null;
5463  this.dropElementsCache = false;
5464  this.allowSelectItem = false;
5465  this.allowCheckItems = false;
5466  this.allowMultipleCallbacks = false;
5467  this.appearAfter = 300;
5468  this.slideAnimationDuration = 60;
5469  this.disappearAfter = 500;
5470  this.enableAnimation = true;
5471  this.enableAdaptivity = false;
5472  this.adaptiveItemsOrder = [];
5473  this.enableSubMenuFullWidth = false;
5474  this.checkedItems = [];
5475  this.isVertical = true;
5476  this.itemCheckedGroups = [];
5477  this.itemCheckedGroups.groupNames = {};
5478  this.lockHoverEvents = false;
5479  this.popupToLeft = false;
5480  this.popupCount = 0;
5481  this.rootItem = null;
5482  this.showSubMenus = false;
5483  this.savedCallbackHoverItem = null;
5484  this.savedCallbackHoverElement = null;
5485  this.selectedItemIndexPath = "";
5486  this.checkedState = null;
5487  this.scrollInfo = [];
5488  this.scrollHelpers = {};
5489  this.scrollVertOffset = 1;
5490  this.keyboardHelper = null;
5491  this.isContextMenu = false;
5492  this.accessibleFocusElement = null;
5493  this.rootSubMenuFIXOffset = 0;
5494  this.rootSubMenuFIYOffset = 0;
5495  this.rootSubMenuLIXOffset = 0;
5496  this.rootSubMenuLIYOffset = 0;
5497  this.rootSubMenuXOffset = 0;
5498  this.rootSubMenuYOffset = 0;
5499  this.subMenuFIXOffset = 0;
5500  this.subMenuFIYOffset = 0;
5501  this.subMenuLIXOffset = 0;
5502  this.subMenuLIYOffset = 0;
5503  this.subMenuXOffset = 0;
5504  this.subMenuYOffset = 0;
5505  this.maxHorizontalOverlap = -3;
5506  this.sizingConfig.allowSetHeight = false;
5507  this.ItemClick = new ASPxClientEvent();
5508  this.ItemMouseOver = new ASPxClientEvent();
5509  this.ItemMouseOut = new ASPxClientEvent();
5510  this.PopUp = new ASPxClientEvent();
5511  this.CloseUp = new ASPxClientEvent();
5512  aspxGetMenuCollection().Add(this);
5513 },
5514 SetData: function(data) {
5515  if(data.items)
5516   this.CreateItems(data.items);
5517 },
5518 InlineInitialize: function() {
5519  ASPxClientControl.prototype.InlineInitialize.call(this);
5520  if(!this.NeedCreateItemsOnClientSide())
5521   this.renderHelper.InlineInitializeElements();
5522  else
5523   this.renderHelper.InlineInitializeScrollElements("", this.GetMainElement());
5524  this.InitializeInternal(true);
5525  if(this.IsCallbacksEnabled()) {
5526   this.showSubMenus = this.GetLoadingPanelElement() != null;
5527   this.CreateCallback("DXMENUCONTENT");
5528  }
5529  else
5530   this.showSubMenus = true;
5531  this.popupToLeft = this.rtl;
5532 },
5533 InitializeInternal: function(inline) {
5534  if(!this.NeedCreateItemsOnClientSide()) {
5535   this.InitializeCheckedItems();
5536   this.InitializeSelectedItem();
5537  }
5538  this.InitializeEnabledAndVisible(!inline || !this.IsCallbacksEnabled());
5539  if(!this.IsCallbacksEnabled())
5540   this.InitializeScrollableMenus();
5541  this.InitializeKeyboardHelper();
5542 },
5543 InitializeEnabledAndVisible: function(recursive) {
5544  if(this.rootItem == null) return;
5545  for(var i = 0; i < this.rootItem.items.length; i++)
5546   this.rootItem.items[i].InitializeEnabledAndVisible(recursive);
5547 },
5548 InitializeScrollableMenus: function() {
5549  var info = eval(this.scrollInfo);
5550  this.scrollHelpers = {};
5551  for(var i = 0; i < info.length; i++)
5552   this.InitializeScrollableMenu(info[i]);
5553 },
5554 InitializeScrollableMenu: function(indexPath) {
5555  if(!this.scrollHelpers[indexPath])
5556   this.scrollHelpers[indexPath] = new MenuScrollHelper(this, indexPath);
5557 },
5558 GetScrollHelper: function(indexPath) {
5559  var scrollsEnabledOnServer = this.scrollInfo.length > 0;
5560  if(this.NeedCreateItemsOnClientSide() && scrollsEnabledOnServer)
5561   this.InitializeScrollableMenu(indexPath);
5562  return this.scrollHelpers[indexPath];
5563 },
5564 InitializeKeyboardHelper: function() {
5565  this.keyboardHelper = new ASPxMenuKeyboardHelper(this);
5566 },
5567 InitializeMenuSamples: function() {
5568  this.rootMenuSample = this.GetSampleNode(this.samples.root);
5569  this.samples.spacing = this.GetSampleNode(this.samples.spacing);
5570  this.samples.separator = this.GetSampleNode(this.samples.separator);
5571  this.InitializeItemsSamples(this.samples.rootItems);
5572  if(this.samples.submenu) {
5573   this.samples.submenu = this.GetSampleNode(this.samples.submenu);
5574   this.InitializeItemsSamples(this.samples.submenuItems);
5575  }
5576 },
5577 InitializeItemsSamples: function(itemsSamples) {
5578  for(var sampleProperty in itemsSamples) {
5579   if(itemsSamples.hasOwnProperty(sampleProperty)) {
5580    itemsSamples[sampleProperty] = itemsSamples[sampleProperty].replace(/DXFAKE/, "");
5581    itemsSamples[sampleProperty] = this.GetSampleNode(itemsSamples[sampleProperty]);
5582   }
5583  }
5584 },
5585 CheckElementsCache: function(menuElement){
5586  if(this.dropElementsCache) {
5587   ASPx.CacheHelper.DropCache(menuElement);
5588   this.dropElementsCache = false;
5589  }
5590 },
5591 NeedCreateItemsOnClientSide: function() {
5592  return false;
5593 },
5594 IsClientSideEventsAssigned: function() {
5595  return !this.ItemClick.IsEmpty()
5596   || !this.ItemMouseOver.IsEmpty()
5597   || !this.ItemMouseOut.IsEmpty()
5598   || !this.PopUp.IsEmpty()
5599   || !this.CloseUp.IsEmpty()
5600   || !this.Init.IsEmpty();
5601 },
5602 IsCallbacksEnabled: function() {
5603  return ASPx.IsFunction(this.callBack);
5604 },
5605 ShouldHideExistingLoadingElements: function() {
5606  return false;
5607 },
5608 CreateRenderHelper: function(){
5609  return new MenuRenderHelper(this);
5610 },
5611 IsSidePanelExpanded: function() {
5612  return false;
5613 },
5614 GetMenuElementId: function(indexPath) {
5615  return this.name + Constants.MMIdSuffix + indexPath + "_";
5616 },
5617 GetMenuMainElementId: function(indexPath) {
5618  return this.name + "_DXME" + indexPath + "_";
5619 },
5620 GetMenuBorderCorrectorElementId: function(indexPath) {
5621  return this.name + "_DXMBC" + indexPath + "_";
5622 },
5623 GetMenuIFrameElementId: function(indexPath) {
5624  return this.name + "_DXMIF" + this.GetMenuLevel(indexPath);
5625 },
5626 GetScrollAreaId: function(indexPath) {
5627  return this.name + "_DXSA" + indexPath;
5628 },
5629 GetMenuTemplateContainerID: function(indexPath) {
5630  return this.name + "_MTCNT" + indexPath;
5631 },
5632 GetItemTemplateContainerID: function(indexPath) {
5633  return this.name + "_ITCNT" + indexPath;
5634 },
5635 GetScrollUpButtonId: function(indexPath) {
5636  return this.name + Constants.SBIdSuffix + indexPath + Constants.SBUIdEnd;
5637 },
5638 GetScrollDownButtonId: function(indexPath) {
5639  return this.name + Constants.SBIdSuffix + indexPath + Constants.SBDIdEnd;
5640 },
5641 GetItemElementId: function(indexPath) {
5642  return this.name + Constants.MIIdSuffix + indexPath + "_";
5643 },
5644 GetItemContentElementId: function(indexPath) {
5645  return this.GetItemElementId(indexPath) + Constants.ItemContentElementPostfix;
5646 },
5647 GetItemPopOutElementId: function(indexPath) {
5648  return this.GetItemElementId(indexPath) + Constants.ItemPopoutElementPostfix;
5649 },
5650 GetItemImageId: function(indexPath) {
5651  return this.GetItemElementId(indexPath) + Constants.ImagePostfix;
5652 },
5653 GetItemPopOutImageId: function(indexPath) {
5654  return this.GetItemElementId(indexPath) + Constants.PopupImagePostfix;
5655 },
5656 GetItemIndentElementId: function(indexPath) {
5657  return this.GetItemElementId(indexPath) + "II";
5658 },
5659 GetItemSeparatorElementId: function(indexPath) {
5660  return this.GetItemElementId(indexPath) + "IS";
5661 },
5662 GetMenuElement: function (indexPath) { 
5663  if(indexPath == "")
5664   return this.GetMainElement();
5665  return ASPx.CacheHelper.GetCachedElementById(this, this.GetMenuElementId(indexPath));
5666 },
5667 GetMenuIFrameElement: function(indexPath) {
5668  var elementId = this.GetMenuIFrameElementId(indexPath);
5669  var element = ASPx.GetElementById(elementId);
5670  if(!element && this.renderIFrameForPopupElements)
5671   return this.CreateIFrameElement(elementId);
5672  return element;
5673 },
5674 CreateIFrameElement: function(elementId) {
5675  var element = document.createElement("IFRAME");
5676  ASPx.Attr.SetAttribute(element, "id", elementId);
5677  ASPx.Attr.SetAttribute(element, "src", "javascript:false");
5678  ASPx.Attr.SetAttribute(element, "scrolling", "no");
5679  ASPx.Attr.SetAttribute(element, "frameborder", "0");
5680  if(this.accessibilityCompliant)
5681   ASPx.Attr.SetAttribute(element, "title", ASPx.AccessibilitySR.AccessibilityIFrameTitle);
5682  element.style.position = "absolute";
5683  element.style.display = "none";
5684  element.style.zIndex = "19997";
5685  element.style.filter = "progid:DXImageTransform.Microsoft.Alpha(Style=0, Opacity=0)";
5686  ASPx.InsertElementAfter(element, this.GetMainElement());
5687  return element;
5688 },
5689 GetMenuBorderCorrectorElement: function(indexPath) {
5690  return ASPx.CacheHelper.GetCachedElementById(this, this.GetMenuBorderCorrectorElementId(indexPath));
5691 },
5692 GetMenuMainElement: function(element) {
5693  var indexPath = this.GetIndexPathById(element.id, true);
5694  return ASPx.CacheHelper.GetCachedElement(this, "menuMainElement" + indexPath, 
5695   function() { 
5696    var shadowTable = ASPx.GetElementById(this.GetMenuMainElementId(indexPath));
5697    return shadowTable != null ? shadowTable : element;
5698   });
5699 },
5700 GetScrollAreaElement: function(indexPath) {
5701  return ASPx.CacheHelper.GetCachedElementById(this, this.GetScrollAreaId(indexPath));
5702 },
5703 GetScrollContentItemsContainer: function(indexPath) {
5704  return ASPx.CacheHelper.GetCachedElement(this, "scrollContentItemsContainer" + indexPath, 
5705   function() { 
5706    return ASPx.GetNodeByTagName(this.GetScrollAreaElement(indexPath), "UL", 0);
5707   });
5708 },
5709 GetScrollUpButtonElement: function(indexPath) {
5710  return ASPx.CacheHelper.GetCachedElementById(this, this.GetScrollUpButtonId(indexPath));
5711 },
5712 GetScrollDownButtonElement: function(indexPath) {
5713  return ASPx.CacheHelper.GetCachedElementById(this, this.GetScrollDownButtonId(indexPath));
5714 },
5715 GetItemElement: function(indexPath) {
5716  return ASPx.CacheHelper.GetCachedElementById(this, this.GetItemElementId(indexPath));
5717 },
5718 GetItemTemplateElement: function(indexPath) { 
5719  return this.GetItemTextTemplateContainer(indexPath);
5720 },
5721 GetItemTemplateContainer: function(indexPath) {
5722  return this.GetItemElement(indexPath);
5723 },
5724 GetItemTextTemplateContainer: function(indexPath) {
5725  return this.GetItemContentElement(indexPath);
5726 },
5727 GetItemContentElement: function(indexPath) {
5728  return ASPx.CacheHelper.GetCachedElementById(this, this.GetItemContentElementId(indexPath));
5729 },
5730 GetItemPopOutElement: function(indexPath) {
5731  return ASPx.CacheHelper.GetCachedElementById(this, this.GetItemPopOutElementId(indexPath));
5732 },
5733 GetPopOutElements: function() {
5734  return ASPx.GetNodesByClassName(this.GetMainElement().parentNode, "dxm-popOut");
5735 },
5736 GetPopOutImages: function() {
5737  return ASPx.GetNodesByClassName(this.GetMainElement().parentNode, "dxm-pImage");
5738 },
5739 GetSubMenuXPosition: function(indexPath, isVertical) {
5740  var itemElement = this.GetItemElement(indexPath);
5741  var pos = ASPx.GetAbsoluteX(itemElement) + (isVertical ? itemElement.clientWidth + itemElement.clientLeft : 0);
5742  if(ASPx.Browser.WebKitFamily && !this.IsParentElementPositionStatic(indexPath))
5743   pos -= document.body.offsetLeft;
5744  return pos;
5745 },
5746 GetSubMenuYPosition: function(indexPath, isVertical) {
5747  var position = 0;
5748  var element = this.GetItemElement(indexPath);
5749  if(element != null) {
5750   if(isVertical) {
5751    position = ASPx.GetAbsoluteY(element); 
5752   }
5753   else {
5754    if(ASPx.Browser.Opera && ASPx.Browser.Version >= 9 || ASPx.Browser.AndroidDefaultBrowser)
5755     position = ASPx.GetAbsoluteY(element) + element.offsetHeight - ASPx.GetClientTop(element);
5756    else
5757     position = ASPx.GetAbsoluteY(element) + element.clientHeight + ASPx.GetClientTop(element);
5758   }
5759  }
5760  if(ASPx.Browser.WebKitFamily && !this.IsParentElementPositionStatic(indexPath))
5761   position -= document.body.offsetTop;
5762  return position;
5763 },
5764 GetClientSubMenuXPosition: function(element, x, indexPath, isVertical) {
5765  var docClientWidth = ASPx.GetDocumentClientWidth();
5766  if(isVertical)
5767   return this.GetClientSubMenuXPositionVerticalCore(element, x, indexPath, isVertical, docClientWidth);
5768  return this.GetClientSubMenuXPositionHorizontalCore(element, x, indexPath, isVertical, docClientWidth);
5769 },
5770 GetClientSubMenuXPositionVerticalCore: function(element, x, indexPath, isVertical, docClientWidth) {
5771  var itemInfo = new MenuItemInfo(this, indexPath);
5772  var itemWidth = itemInfo.clientWidth;
5773  var subMenuWidth = this.GetMenuMainElement(element).offsetWidth;
5774  var left = x - ASPx.GetDocumentScrollLeft();
5775  var right = left + subMenuWidth;
5776  var toLeftX = x - subMenuWidth - itemWidth;
5777  var toLeftLeft = left - subMenuWidth - itemWidth;
5778  if(this.IsCorrectionDisableMethodRequired(indexPath))
5779   return this.GetCorrectionDisabledResult(x, toLeftX);
5780  if(this.popupToLeft) {
5781   if(toLeftLeft > this.maxHorizontalOverlap)
5782    return toLeftX;
5783   if(docClientWidth - right > this.maxHorizontalOverlap || !this.rtl) {
5784    this.popupToLeft = false;
5785    return x;
5786   }
5787   return ASPx.InvalidPosition;
5788  }
5789  else {
5790   if(docClientWidth - right > this.maxHorizontalOverlap)
5791    return x;
5792   if(toLeftLeft > this.maxHorizontalOverlap || this.rtl) {
5793    this.popupToLeft = true;
5794    return toLeftX;
5795   }
5796   return ASPx.InvalidPosition;
5797  }
5798 },
5799 GetClientSubMenuXPositionHorizontalCore: function(element, x, indexPath, isVertical, docClientWidth) {
5800  var itemInfo = new MenuItemInfo(this, indexPath);
5801  var itemOffsetWidth = itemInfo.offsetWidth;
5802  var subMenuWidth = this.GetMenuMainElement(element).offsetWidth;
5803  var left = x - ASPx.GetDocumentScrollLeft();
5804  if(this.popupToLeft) {
5805   var rtlX = left - subMenuWidth + itemOffsetWidth;
5806   return rtlX < 0 ? 0 : rtlX;
5807  }
5808  else {
5809   if(docClientWidth - (left + subMenuWidth) < 0) {
5810    x = docClientWidth - subMenuWidth;
5811    if(x < 0)
5812     x = 0;
5813    return x;
5814   }
5815   return x;
5816  }
5817 },
5818 GetClientSubMenuYPosition: function(element, y, indexPath, isVertical) {
5819  var itemInfo = new MenuItemInfo(this, indexPath);
5820  var itemHeight = itemInfo.offsetHeight;
5821  var subMenuHeight = this.GetMenuMainElement(element).offsetHeight;
5822  var menuItemTop = y - ASPx.GetDocumentScrollTop();
5823  var subMenuBottom = menuItemTop + subMenuHeight;
5824  var docClientHeight = ASPx.GetDocumentClientHeight();
5825  var clientSubMenuYPos = y;
5826  if(isVertical) {
5827   var notEnoughSpaceToShowDown = subMenuBottom > docClientHeight;
5828   var menuItemBottom = menuItemTop + itemHeight;
5829   if(menuItemBottom > docClientHeight) {
5830    menuItemBottom = docClientHeight;
5831    itemHeight = menuItemBottom - menuItemTop;
5832   }
5833   var notEnoughSpaceToShowUp = menuItemBottom < subMenuHeight;
5834   var subMenuIsFitToDisplayFrames = docClientHeight >= subMenuHeight;
5835   if(!subMenuIsFitToDisplayFrames) clientSubMenuYPos = y - menuItemTop;
5836   else if(notEnoughSpaceToShowDown) {
5837    if(notEnoughSpaceToShowUp) {
5838     var docClientBottom = ASPx.GetDocumentScrollTop() + docClientHeight;
5839     clientSubMenuYPos = docClientBottom - subMenuHeight;
5840    } else
5841     clientSubMenuYPos = y + itemHeight - subMenuHeight;
5842   }
5843  }
5844  else {
5845   if(this.IsHorizontalSubmenuNeedInversion(subMenuBottom, docClientHeight, menuItemTop, subMenuHeight, itemHeight))
5846    clientSubMenuYPos = y - subMenuHeight - itemHeight;
5847  }
5848  return clientSubMenuYPos;
5849 },
5850 IsHorizontalSubmenuNeedInversion: function(subMenuBottom, docClientHeight, menuItemTop, subMenuHeight, itemHeight) {
5851  return subMenuBottom > docClientHeight && menuItemTop - subMenuHeight - itemHeight > docClientHeight - subMenuBottom;
5852 },
5853 IsCorrectionDisableMethodRequired: function(indexPath) {
5854  return false;
5855 },
5856 HasChildren: function(indexPath) {
5857  return (this.GetMenuElement(indexPath) != null);
5858 },
5859 IsVertical: function(indexPath) {
5860  return true;
5861 },
5862 IsRootItem: function(indexPath) {
5863  return this.GetMenuLevel(indexPath) <= 1;
5864 },
5865 IsParentElementPositionStatic: function(indexPath) {
5866  return this.IsRootItem(indexPath);
5867 },
5868 GetItemIndexPath: function(indexes) {
5869  return aspxGetMenuCollection().GetItemIndexPath(indexes);
5870 },
5871 GetItemIndexes: function(indexPath) {
5872  return aspxGetMenuCollection().GetItemIndexes(indexPath);
5873 },
5874 GetItemIndexPathById: function(id) {
5875  return aspxGetMenuCollection().GetIndexPathById(id, Constants.MIIdSuffix);
5876 },
5877 GetMenuIndexPathById: function(id) {
5878  return aspxGetMenuCollection().GetIndexPathById(id, Constants.MMIdSuffix);
5879 },
5880 GetScrollButtonIndexPathById: function(id) {
5881  return aspxGetMenuCollection().GetIndexPathById(id, Constants.SBIdSuffix);
5882 },
5883 GetIndexPathById: function(id, checkMenu) {
5884  var indexPath = this.GetItemIndexPathById(id);
5885  if(indexPath == "" && checkMenu)
5886   indexPath = this.GetMenuIndexPathById(id);
5887  return indexPath;
5888 },
5889 GetMenuLevelInternal: function(indexPath) {
5890  if(indexPath == "")
5891   return 0;
5892  else {
5893   var indexes = this.GetItemIndexes(indexPath);
5894   return indexes.length;
5895  }
5896 },
5897 GetMenuLevel: function(indexPath) {
5898  var level = this.GetMenuLevelInternal(indexPath);
5899  if(this.IsAdaptiveMenuItem(indexPath))
5900   level ++;
5901  return level;
5902 },
5903 IsAdaptiveMenuItem: function(indexPath){
5904  var level = this.GetMenuLevelInternal(indexPath);
5905  while(level > 1){
5906   indexPath = this.GetParentIndexPath(indexPath);
5907   level = this.GetMenuLevelInternal(indexPath);
5908  }
5909  var itemElement = this.GetItemElement(indexPath);
5910  if(itemElement && ASPx.GetParentByClassName(itemElement, this.getAdaptiveMenuCssClass()))
5911   return true;
5912  return false;
5913 },
5914 IsAdaptiveItem: function(indexPath){
5915  var itemElement = this.GetItemElement(indexPath);
5916  if(itemElement && ASPx.ElementContainsCssClass(itemElement, this.getAdaptiveMenuItemCssClass()))
5917   return true;
5918  return false;
5919 },
5920 GetParentIndexPath: function(indexPath) {
5921  var indexes = this.GetItemIndexes(indexPath);
5922  indexes.length--;
5923  return (indexes.length > 0) ? this.GetItemIndexPath(indexes) : "";
5924 },
5925 IsLastElement: function(element) {
5926  return element && (!element.nextSibling || !element.nextSibling.tagName);
5927 },
5928 IsLastItem: function(indexPath) {
5929  var itemElement = this.GetItemElement(indexPath);
5930  return this.IsLastElement(itemElement);
5931 },
5932 IsFirstElement: function(element) {
5933  return element && (!element.previousSibling || !element.previousSibling.tagName);
5934 },
5935 IsFirstItem: function(indexPath) {
5936  var itemElement = this.GetItemElement(indexPath);
5937  return this.IsFirstElement(itemElement);
5938 },
5939 IsItemElement: function(element) {
5940  return ASPx.ElementContainsCssClass(element, MenuCssClasses.Item);
5941 },
5942 GetPreviousItem: function(itemPath, isItemNameUsed) {
5943  var indexPath = itemPath;
5944  if(isItemNameUsed) {
5945   var indexPath = this.GetMenuIndexPathById(itemPath);
5946   if(indexPath == "")
5947    indexPath = this.GetItemIndexPathById(itemPath);
5948  }
5949  var currentItem = this.GetItemByIndexPath(indexPath),
5950   previousItem = null;
5951  if(currentItem) {
5952   for(var i = currentItem.index - 1; i >= 0 && previousItem === null; i--) {
5953    if(currentItem.parent.items[i].GetVisible())
5954     previousItem = currentItem.parent.items[i];
5955   }
5956  }
5957  return previousItem;
5958 },
5959 GetClientSubMenuPos: function(element, indexPath, pos, isVertical, isXPos) {
5960  if(!ASPx.IsValidPosition(pos)) {
5961   pos = isXPos ? this.GetSubMenuXPosition(indexPath, isVertical) : this.GetSubMenuYPosition(indexPath, isVertical);
5962  }
5963  var clientPos = isXPos ? this.GetClientSubMenuXPosition(element, pos, indexPath, isVertical) : this.GetClientSubMenuYPosition(element, pos, indexPath, isVertical);
5964  var isInverted = pos != clientPos;
5965  if(clientPos !== ASPx.InvalidPosition){
5966   var offset = isXPos ? this.GetSubMenuXOffset(indexPath) : this.GetSubMenuYOffset(indexPath);
5967   clientPos += isInverted ? -offset : offset;
5968   clientPos -= ASPx.GetPositionElementOffset(this.GetMenuElement(indexPath), isXPos);
5969  }
5970  return new ASPx.PopupPosition(clientPos, isInverted);
5971 },
5972 GetSubMenuXOffset: function(indexPath) {
5973  if(indexPath == "")
5974   return 0;
5975  else if(this.IsRootItem(indexPath)) {
5976   if(this.IsFirstItem(indexPath))
5977    return this.rootSubMenuFIXOffset;
5978   else if(this.IsLastItem(indexPath))
5979    return this.rootSubMenuLIXOffset;
5980   else
5981    return this.rootSubMenuXOffset;
5982  }
5983  else {
5984   if(this.IsFirstItem(indexPath))
5985    return this.subMenuFIXOffset;
5986   else if(this.IsLastItem(indexPath))
5987    return this.subMenuLIXOffset;
5988   else
5989    return this.subMenuXOffset;
5990  }
5991 },
5992 GetSubMenuYOffset: function(indexPath) {
5993  if(indexPath == "")
5994   return 0;
5995  else if(this.IsRootItem(indexPath)) {
5996   if(this.IsFirstItem(indexPath))
5997    return this.rootSubMenuFIYOffset;
5998   else if(this.IsLastItem(indexPath))
5999    return this.rootSubMenuLIYOffset;
6000   else
6001    return this.rootSubMenuYOffset;
6002  }
6003  else {
6004   if(this.IsFirstItem(indexPath))
6005    return this.subMenuFIYOffset;
6006   else if(this.IsLastItem(indexPath))
6007    return this.subMenuLIYOffset;
6008   else
6009    return this.subMenuYOffset;
6010  }
6011 },
6012 CalculateSubMenuPosition: function(element, x, y, indexPath, enableAnimation) {
6013  var isVertical = this.IsVertical(indexPath);
6014  var horizontalPopupPosition = this.GetClientSubMenuPos(element, indexPath, x, isVertical, true);
6015  if(horizontalPopupPosition.position === ASPx.InvalidPosition) {
6016   isVertical = !isVertical;
6017   horizontalPopupPosition = this.GetClientSubMenuPos(element, indexPath, x, isVertical, true);
6018  }
6019  var verticalPopupPosition = this.GetClientSubMenuPos(element, indexPath, y, isVertical, false);
6020  var clientX = horizontalPopupPosition.position;
6021  var clientY = verticalPopupPosition.position;
6022  var toTheLeft = horizontalPopupPosition.isInverted;
6023  var toTheTop = verticalPopupPosition.isInverted;
6024  clientY += this.GetScrollingCorrection(element, indexPath, clientY);
6025  verticalPopupPosition.position = clientY;
6026  var parentElement = this.GetItemContentElement(indexPath);
6027  var prevParentPos = ASPx.GetAbsoluteX(parentElement);
6028  ASPx.SetStyles(element, {
6029   left: clientX, top: clientY
6030  });
6031  clientX += ASPx.GetAbsoluteX(parentElement) - prevParentPos;
6032  if(enableAnimation) {
6033   this.StartAnimation(element, indexPath, horizontalPopupPosition, verticalPopupPosition, isVertical);
6034  }
6035  else {
6036   ASPx.SetStyles(element, { left: clientX, top: clientY });
6037   ASPx.SetElementVisibility(element, true);
6038   if(this.enableSubMenuFullWidth)
6039    this.ApplySubMenuFullWidth(element);
6040   this.DoShowPopupMenuIFrame(element, clientX, clientY, ASPx.InvalidDimension, ASPx.InvalidDimension, indexPath);
6041   this.DoShowPopupMenuBorderCorrector(element, clientX, clientY, indexPath, toTheLeft, toTheTop);
6042  }
6043 },
6044 StartScrolling: function(buttonId, delay, step) {
6045  var indexPath = this.GetScrollButtonIndexPathById(buttonId);
6046  var level = this.GetMenuLevel(indexPath);
6047  aspxGetMenuCollection().DoHidePopupMenus(null, level, this.name, false, "");
6048  var direction = (buttonId.lastIndexOf(Constants.SBDIdEnd) == buttonId.length - Constants.SBDIdEnd.length) ? 1 : -1;
6049  var scrollHelper = this.GetScrollHelper(indexPath);
6050  if(scrollHelper) scrollHelper.StartScrolling(direction, delay, step);
6051 },
6052 StopScrolling: function(buttonId) {
6053  var indexPath = this.GetScrollButtonIndexPathById(buttonId);
6054  var scrollHelper = this.GetScrollHelper(indexPath);
6055  if(scrollHelper) scrollHelper.StopScrolling();
6056 },
6057 ClearAppearTimer: function() {
6058  aspxGetMenuCollection().ClearAppearTimer();
6059 },
6060 ClearDisappearTimer: function() {
6061  aspxGetMenuCollection().ClearDisappearTimer();
6062 },
6063 IsAppearTimerActive: function() {
6064  return aspxGetMenuCollection().IsAppearTimerActive();
6065 },
6066 IsDisappearTimerActive: function() {
6067  return aspxGetMenuCollection().IsDisappearTimerActive();
6068 },
6069 IsAdaptiveItemAnimationActive: function() {
6070  return this.inSubmenuShowAnimation;
6071 },
6072 GetAppearAfter: function(indexPath) {
6073  return this.appearAfter;
6074 },
6075 SetAppearTimer: function(indexPath, preventSubMenu) {
6076  aspxGetMenuCollection().SetAppearTimer(this.name, indexPath, this.GetAppearAfter(indexPath), preventSubMenu);
6077 },
6078 GetDisappearAfter: function() {
6079  return this.disappearAfter;
6080 },
6081 SetDisappearTimer: function() {
6082  aspxGetMenuCollection().SetDisappearTimer(this.name, this.GetDisappearAfter());
6083 },
6084 IsDropDownItem: function(indexPath) {
6085  return ASPx.ElementContainsCssClass(this.GetItemElement(indexPath), MenuCssClasses.ItemDropDownMode);
6086 },
6087 DoItemClick: function(indexPath, hasItemLink, htmlEvent) {
6088  aspxGetMenuCollection().LockMenusVisibility();
6089  var processOnServer = this.RaiseItemClick(indexPath, htmlEvent);
6090  if(processOnServer && !hasItemLink) {
6091   if(ASPx.Browser.Edge) { 
6092    var activeElement = document.activeElement;
6093    if(activeElement)
6094     activeElement.blur();
6095   }
6096   this.SendPostBack("CLICK:" + indexPath);
6097  }
6098  else {
6099   this.ClearDisappearTimer();
6100   this.ClearAppearTimer();
6101   if(this.CanCloseSubMenuOnClick(indexPath) && (!this.HasChildren(indexPath) || this.IsDropDownItem(indexPath)))
6102    aspxGetMenuCollection().DoHidePopupMenus(null, -1, this.name, false, "");
6103   else if(this.IsItemEnabled(indexPath) && !this.IsDropDownItem(indexPath))
6104    this.ShowSubMenu(indexPath);
6105  }
6106  aspxGetMenuCollection().UnlockMenusVisibility();
6107 },
6108 CanCloseSubMenuOnClick: function(indexPath) {
6109  return true;
6110 },
6111 HasContent: function(mainCell) {
6112  for(var i = 0; i < mainCell.childNodes.length; i++)
6113   if(mainCell.childNodes[i].tagName)
6114    return true;
6115  return false;
6116 },
6117 DoShowPopupMenu: function(element, x, y, indexPath) {
6118  var parent = this.GetItemByIndexPath(indexPath);
6119  var menuElement = this.GetMenuMainElement(element);
6120  var popupMenuHasVisibleContent = menuElement && (this.renderHelper.HasSubMenuTemplate(menuElement) || 
6121   ASPx.ElementContainsCssClass(menuElement, this.getAdaptiveMenuCssClass())) ||
6122   parent && this.HasVisibleItems(parent);
6123  if(popupMenuHasVisibleContent === false)
6124   return;
6125  if(element && this.IsCallbacksEnabled())
6126   this.ShowLoadingPanelInMenu(element);
6127  if(ASPx.GetElementVisibility(element))
6128   ASPx.SetStyles(element, { left: ASPx.InvalidPosition, top: ASPx.InvalidPosition });
6129  ASPx.SetElementDisplay(element, true);
6130  if(parent) {
6131   for(var i = 0; i < parent.GetItemCount() ; i++) {
6132    var item = parent.GetItem(i);
6133    this.SetPopOutElementVisible(item.indexPath, this.HasVisibleItems(item));
6134   }
6135  }
6136  this.renderHelper.CalculateSubMenu(element, false);
6137  if(this.popupCount == 0) this.popupToLeft = this.rtl;
6138  this.RaisePopUp(indexPath);
6139  this.CalculateSubMenuPosition(element, x, y, indexPath, this.enableAnimation);
6140  aspxGetMenuCollection().RegisterVisiblePopupMenu(this.name, element.i
6140d);
6141  this.popupCount++;
6142  ASPx.GetControlCollection().AdjustControls(element);
6143  this.CorrectVerticalAlignment(ASPx.AdjustHeight, this.GetPopOutElements, "PopOut");
6144  this.CorrectVerticalAlignment(ASPx.AdjustVerticalMargins, this.GetPopOutImages, "PopOutImg");
6145 },
6146 ShowLoadingPanelInMenu: function(element) {
6147  var lpParent = this.GetMenuMainElement(element);
6148  if(lpParent && !this.HasContent(lpParent))
6149   this.CreateLoadingPanelInsideContainer(lpParent);
6150 },
6151 GetScrollSubMenuYCorrection: function(element, scrollHelper, clientY) {
6152  var absoluteClientY = clientY + ASPx.GetPositionElementOffset(element);
6153  var excessTop = this.GetScrollExcessTop(absoluteClientY);
6154  var excessBottom = this.GetScrollExcessBottom(element, absoluteClientY);
6155  var correction = 0;
6156  if(excessTop > 0)
6157   correction += excessTop + this.scrollVertOffset;
6158  if(excessBottom > 0 && (absoluteClientY + correction == ASPx.GetDocumentScrollTop())) {
6159   excessBottom += this.scrollVertOffset;
6160   correction += this.scrollVertOffset;
6161  }
6162  this.PrepareScrolling(element, scrollHelper, excessTop, excessBottom);
6163  return correction;
6164 },
6165 GetScrollExcessTop: function(clientY) {
6166  return ASPx.GetDocumentScrollTop() - clientY;
6167 },
6168 GetScrollExcessBottom: function(element, clientY) {
6169  ASPx.SetElementDisplay(element, false);
6170  var docHeight = ASPx.GetDocumentClientHeight();
6171  ASPx.SetElementDisplay(element, true);
6172  return clientY + element.offsetHeight - ASPx.GetDocumentScrollTop() - docHeight;
6173 },
6174 PrepareScrolling: function(element, scrollHelper, excessTop, excessBottom) {
6175  scrollHelper.Initialize();
6176  var corrector = element.offsetHeight - scrollHelper.GetScrollAreaHeight() + this.scrollVertOffset;
6177  if(excessTop > 0)
6178   scrollHelper.Calculate(element.offsetHeight - excessTop - corrector);
6179  if(excessBottom > 0)
6180   scrollHelper.Calculate(element.offsetHeight - excessBottom - corrector);
6181 },
6182 ApplySubMenuFullWidth: function(element) {
6183  ASPx.SetStyles(element, { left: 0, right: 0, width: "auto" });
6184  var menuElement = this.GetMenuMainElement(element);
6185  ASPx.SetStyles(menuElement, { width: "100%", "box-sizing": "border-box" });
6186  var templateElement = ASPx.GetChildByClassName(menuElement, "dx");
6187  if(templateElement) ASPx.SetStyles(templateElement, { width: "100%" });
6188 },
6189 DoShowPopupMenuIFrame: function(element, x, y, width, height, indexPath) {
6190  if(!this.renderIFrameForPopupElements) return;
6191  var iFrame = element.overflowElement;
6192  if(!iFrame) {
6193   iFrame = this.GetMenuIFrameElement(indexPath);
6194   element.overflowElement = iFrame;
6195  }
6196  if(iFrame) {
6197   var menuElement = this.GetMenuMainElement(element);
6198   if(width < 0)
6199    width = menuElement.offsetWidth;
6200   if(height < 0)
6201    height = menuElement.offsetHeight;
6202   ASPx.SetStyles(iFrame, {
6203    width: width, height: height,
6204    left: x, top: y, display: ""
6205   });
6206  }
6207 },
6208 DoShowPopupMenuBorderCorrector: function(element, x, y, indexPath, toTheLeft, toTheTop) {
6209  var borderCorrectorElement = this.GetMenuBorderCorrectorElement(indexPath);
6210  if(borderCorrectorElement) {
6211   var params = this.GetPopupMenuBorderCorrectorPositionAndSize(element, x, y, indexPath, toTheLeft, toTheTop);
6212   ASPx.SetStyles(borderCorrectorElement, {
6213    width: params.width, height: params.height,
6214    left: params.left, top: params.top,
6215    display: "", visibility: "visible"
6216   });
6217   element.borderCorrectorElement = borderCorrectorElement;
6218  }
6219 },
6220 GetPopupMenuBorderCorrectorPositionAndSize: function(element, x, y, indexPath, toTheLeft, toTheTop) {
6221  var result = {};
6222  var itemInfo = new MenuItemInfo(this, indexPath);
6223  var menuXOffset = ASPx.GetClientLeft(this.GetMenuMainElement(element));
6224  var menuYOffset = ASPx.GetClientTop(this.GetMenuMainElement(element));
6225  var menuElement = this.GetMenuMainElement(element);
6226  var menuClientWidth = menuElement.clientWidth;
6227  var menuClientHeight = menuElement.clientHeight;
6228  if(this.IsVertical(indexPath)) {
6229   var commonClientHeight = itemInfo.clientHeight < menuClientHeight
6230    ? itemInfo.clientHeight
6231    : menuClientHeight;
6232   result.width = menuXOffset;
6233   result.height = commonClientHeight + itemInfo.clientTop - menuYOffset;
6234   result.left = x;
6235   if(toTheLeft)
6236    result.left += menuClientWidth + menuXOffset;
6237   result.top = y + menuYOffset;
6238   if(toTheTop)
6239    result.top += menuClientHeight - result.height;
6240  }
6241  else {
6242   var itemWidth = itemInfo.clientWidth;
6243   if(this.IsDropDownItem(indexPath))
6244    itemWidth = this.GetItemContentElement(indexPath).clientWidth;
6245   var commonClientWidth = itemWidth < menuClientWidth
6246    ? itemWidth
6247    : menuClientWidth;
6248   result.width = commonClientWidth + itemInfo.clientLeft - menuXOffset;
6249   result.height = menuYOffset;
6250   result.left = x + menuXOffset;
6251   if(toTheLeft)
6252    result.left += menuClientWidth - result.width;
6253   result.top = y;
6254   if(toTheTop)
6255    result.top += menuClientHeight + menuYOffset;
6256  }
6257  return result;
6258 },
6259 DoHidePopupMenu: function(evt, element) {
6260  this.DoHidePopupMenuBorderCorrector(element);
6261  this.DoHidePopupMenuIFrame(element);
6262  var menuElement = this.GetMenuMainElement(element);
6263  ASPx.PopupUtils.StopAnimation(element, menuElement);
6264  ASPx.SetElementVisibility(element, false);
6265  ASPx.SetElementDisplay(element, false);
6266  ASPx.SetStyles(element, {
6267   width: 'unset', height: 'unset'
6268  });
6269  this.CancelSubMenuItemHoverItem(element);
6270  aspxGetMenuCollection().UnregisterVisiblePopupMenu(this.name, element.i
6270d);
6271  this.popupCount--;
6272  var indexPath = this.GetIndexPathById(element.id, true);
6273  this.DoResetScrolling(element, indexPath);
6274  this.RaiseCloseUp(indexPath);
6275 },
6276 DoResetScrolling: function(element, indexPath) {
6277  var scrollHelper = this.GetScrollHelper(indexPath);
6278  if(scrollHelper) {
6279   element.style.height = "";
6280   scrollHelper.ResetScrolling();
6281  }
6282 },
6283 DoHidePopupMenuIFrame: function(element) {
6284  if(!this.renderIFrameForPopupElements) return;
6285  var iFrame = element.overflowElement;
6286  if(iFrame)
6287   ASPx.SetElementDisplay(iFrame, false);
6288 },
6289 DoHidePopupMenuBorderCorrector: function(element) {
6290  var borderCorrectorElement = element.borderCorrectorElement;
6291  if(borderCorrectorElement) {
6292   ASPx.SetElementVisibility(borderCorrectorElement, false);
6293   ASPx.SetElementDisplay(borderCorrectorElement, false);
6294   element.borderCorrectorElement = null;
6295  }
6296 },
6297 MarkPrecedingItem: function(currentItemName, className, isItemNameUsed) {
6298  this.MarkPrecedingItemCore(currentItemName, className, true, isItemNameUsed);
6299 },
6300 UnmarkPrecedingItem: function(currentItemName, className, isItemNameUsed) {
6301  this.MarkPrecedingItemCore(currentItemName, className, false, isItemNameUsed);
6302 },
6303 MarkPrecedingItemCore: function(currentItemName, className, addClass, isItemNameUsed) {
6304  var previousItem = this.GetPreviousItem(currentItemName, isItemNameUsed);
6305  if(previousItem) {
6306   var element = this.GetItemElement(previousItem.indexPath);
6307   if(addClass)
6308    ASPx.AddClassNameToElement(element, className);
6309   else
6310    ASPx.RemoveClassNameFromElement(element, className);
6311  }
6312 },
6313 SetHoverElement: function(element) {
6314  if(!this.IsStateControllerEnabled()) return;
6315  this.lockHoverEvents = true;
6316  ASPx.GetStateController().SetCurrentHoverElementBySrcElement(element);
6317  this.lockHoverEvents = false;
6318 },
6319 ApplySubMenuItemHoverItem: function(element, hoverItem, hoverElement) {
6320  if(!element.hoverItem && ASPx.GetElementDisplay(element)) {
6321   var newHoverItem = hoverItem.Clone();
6322   element.hoverItem = newHoverItem;
6323   element.hoverElement = hoverElement;
6324   newHoverItem.Apply(hoverElement);
6325  }
6326 },
6327 CancelSubMenuItemHoverItem: function(element) {
6328  if(element.hoverItem) {
6329   element.hoverItem.Cancel(element.hoverElement);
6330   element.hoverItem = null;
6331   element.hoverElement = null;
6332  }
6333 },
6334 ShowSubMenu: function(indexPath) {
6335  var element = this.GetMenuElement(indexPath);
6336  if(element != null) {
6337   var level = this.GetMenuLevel(indexPath);
6338   aspxGetMenuCollection().DoHidePopupMenus(null, level - 1, this.name, false, this.getExceptIdsForShowSubMenu(indexPath, element.id));
6339   if(!this.isSubMenuElementVisible(element) && this.IsItemEnabled(indexPath))
6340    this.DoShowPopupMenu(element, ASPx.InvalidPosition, ASPx.InvalidPosition, indexPath);
6341  }
6342  this.ClearAppearTimer();
6343 },
6344 getExceptIdsForShowSubMenu: function (itemIndexPath, exceptId) {
6345  return [exceptId];
6346 },
6347 isSubMenuElementVisible: function(subMenuElement) {
6348  return ASPx.GetElementDisplay(subMenuElement);
6349 },
6350 SelectItem: function(indexPath) {
6351  if(!this.IsStateControllerEnabled()) return;
6352  var element = this.GetItemContentElement(indexPath);
6353  if(element != null) {
6354   ASPx.GetStateController().SelectElementBySrcElement(element);
6355   if(this.sideMenuModeOn)
6356    this.MarkPrecedingItem(indexPath, PRE_SELECTED_ELEMENT_CLASS_NAME, false);
6357  }
6358 },
6359 DeselectItem: function(indexPath) {
6360  if(!this.IsStateControllerEnabled()) return;
6361  var element = this.GetItemContentElement(indexPath);
6362  if(element != null) {
6363   var hoverItem = null;
6364   var hoverElement = null;
6365   var menuElement = this.GetMenuElement(indexPath);
6366   if(menuElement && menuElement.hoverItem) {
6367    hoverItem = menuElement.hoverItem;
6368    hoverElement = menuElement.hoverElement;
6369    this.CancelSubMenuItemHoverItem(menuElement);
6370   }
6371   ASPx.GetStateController().DeselectElementBySrcElement(element);
6372   if(menuElement != null && hoverItem != null)
6373    this.ApplySubMenuItemHoverItem(menuElement, hoverItem, hoverElement);
6374   if(this.sideMenuModeOn)
6375    this.UnmarkPrecedingItem(indexPath, PRE_SELECTED_ELEMENT_CLASS_NAME, false);
6376  }
6377 },
6378 InitializeSelectedItem: function() {
6379  if(!this.allowSelectItem && !this.HasServerSideSelectedItem()) return;
6380  this.SelectItem(this.GetSelectedItemIndexPath());
6381  this.InitializeServerSideSelectedItem();
6382 },
6383 InitializeServerSideSelectedItem: function() {
6384  if(!this.allowSelectItem && this.sideMenuModeOn && this.HasServerSideSelectedItem())
6385   this.MarkPrecedingItem(this.serverSideSelectedItemPath, PRE_SELECTED_ELEMENT_CLASS_NAME, false);
6386 },
6387 HasServerSideSelectedItem: function() {
6388  return typeof (this.serverSideSelectedItemPath) !== "undefined";
6389 },
6390 GetSelectedItemIndexPath: function() {
6391  return this.selectedItemIndexPath;
6392 },
6393 SetSelectedItemInternal: function(indexPath, modifyHotTrackSelection) {
6394  if(modifyHotTrackSelection)
6395   this.SetHoverElement(null);
6396  this.DeselectItem(this.selectedItemIndexPath);
6397  this.selectedItemIndexPath = indexPath;
6398  var item = this.GetItemByIndexPath(indexPath);
6399  if(item == null || item.GetEnabled())
6400   this.SelectItem(this.selectedItemIndexPath);
6401  if(modifyHotTrackSelection) {
6402   var element = this.GetItemContentElement(indexPath);
6403   if(element != null)
6404    this.SetHoverElement(element);
6405  }
6406 },
6407 InitializeCheckedItems: function() {
6408  if(!this.allowCheckItems) return;
6409  var indexPathes = this.checkedState.split(";");
6410  for(var i = 0; i < indexPathes.length; i++) {
6411   if(indexPathes[i] != "") {
6412    this.checkedItems.push(indexPathes[i]);
6413    this.SelectItem(indexPathes[i]);
6414   }
6415  }
6416 },
6417 ChangeCheckedItem: function(indexPath) {
6418  this.SetHoverElement(null);
6419  var itemsGroup = this.GetItemsGroup(indexPath);
6420  if(itemsGroup != null) {
6421   if(itemsGroup.length > 1) {
6422    if(!this.IsCheckedItem(indexPath)) {
6423     for(var i = 0; i < itemsGroup.length; i++) {
6424      if(itemsGroup[i] == indexPath) continue;
6425      if(this.IsCheckedItem(itemsGroup[i])) {
6426       ASPx.Data.ArrayRemove(this.checkedItems, itemsGroup[i]);
6427       this.DeselectItem(itemsGroup[i]);
6428      }
6429     }
6430     this.SelectItem(indexPath);
6431     this.checkedItems.push(indexPath);
6432    }
6433   }
6434   else {
6435    if(this.IsCheckedItem(indexPath)) {
6436     ASPx.Data.ArrayRemove(this.checkedItems, indexPath);
6437     this.DeselectItem(indexPath);
6438    }
6439    else {
6440     this.SelectItem(indexPath);
6441     this.checkedItems.push(indexPath);
6442    }
6443   }
6444  }
6445  var element = this.GetItemContentElement(indexPath);
6446  if(element != null)
6447   this.SetHoverElement(element);
6448 },
6449 GetItemsGroup: function(indexPath) {
6450  for(var i = 0; i < this.itemCheckedGroups.length; i++) {
6451   if(ASPx.Data.ArrayIndexOf(this.itemCheckedGroups[i], indexPath) > -1)
6452    return this.itemCheckedGroups[i];
6453  }
6454  return null;
6455 },
6456 IsCheckedItem: function(indexPath) {
6457  return ASPx.Data.ArrayIndexOf(this.checkedItems, indexPath) > -1;
6458 },
6459 UpdateStateObject: function(){
6460  this.UpdateStateObjectWithObject({ selectedItemIndexPath: this.selectedItemIndexPath, checkedState: this.GetCheckedState() });
6461 },
6462 GetCheckedState: function() {
6463  return this.checkedItems.map(function(checkedItem) {
6464   return this.GetCheckedItemInfo(checkedItem);
6465  }.bind(this)).join(";");
6466 },
6467 GetCheckedItemInfo: function(itemIndexPath) {
6468  return itemIndexPath;
6469 },
6470 GetAnimationVerticalDirection: function(indexPath, popupPosition, isVertical) {
6471  var verticalDirection = (this.IsRootItem(indexPath) && !isVertical) ? -1 : 0;
6472  if(popupPosition.isInverted) verticalDirection *= -1;
6473  return verticalDirection;
6474 },
6475 GetAnimationHorizontalDirection: function(indexPath, popupPosition, isVertical) {
6476  var horizontalDirection = (this.IsRootItem(indexPath) && !isVertical) ? 0 : -1;
6477  if(popupPosition.isInverted) horizontalDirection *= -1;
6478  return horizontalDirection;
6479 },
6480 skipPopupMenuSizeInit: function() {
6481  return false;
6482 },
6483 StartAnimation: function(animationDivElement, indexPath, horizontalPopupPosition, verticalPopupPosition, isVertical) {
6484  this.inSubmenuShowAnimation = true;
6485  var element = this.GetMenuMainElement(animationDivElement);
6486  var clientX = horizontalPopupPosition.position;
6487  var clientY = verticalPopupPosition.position;
6488  ASPx.PopupUtils.InitAnimationDiv(animationDivElement, clientX, clientY, this.OnAnimationFinished.aspxBind(this), this.skipPopupMenuSizeInit());
6489  var verticalDirection = this.GetAnimationVerticalDirection(indexPath, verticalPopupPosition, isVertical);
6490  var horizontalDirection = this.GetAnimationHorizontalDirection(indexPath, horizontalPopupPosition, isVertical);
6491  var yPos = verticalDirection * element.offsetHeight;
6492  var xPos = horizontalDirection * element.offsetWidth;
6493  ASPx.SetStyles(element, { left: xPos, top: yPos });
6494  ASPx.SetElementVisibility(animationDivElement, true);
6495  if(this.enableSubMenuFullWidth)
6496   this.ApplySubMenuFullWidth(animationDivElement);
6497  this.DoShowPopupMenuIFrame(animationDivElement, clientX, clientY, 0, 0, indexPath);
6498  this.DoShowPopupMenuBorderCorrector(animationDivElement, clientX, clientY, indexPath,
6499   horizontalPopupPosition.isInverted, verticalPopupPosition.isInverted);
6500  ASPx.PopupUtils.StartSlideAnimation(animationDivElement, element, this.GetMenuIFrameElement(indexPath), this.slideAnimationDuration, this.enableSubMenuFullWidth, false);
6501 },
6502 OnAnimationFinished: function() {
6503  window.setTimeout(function() { this.inSubmenuShowAnimation = false; }.aspxBind(this), 100);
6504 },
6505 OnItemClick: function(indexPath, evt) {
6506  var sourceElement = ASPx.Evt.GetEventSource(evt);
6507  var clickedLinkElement = ASPx.GetParentByTagName(sourceElement, "A");
6508  var isLinkClicked = (clickedLinkElement != null && clickedLinkElement.href != ASPx.AccessibilityEmptyUrl);
6509  var element = this.GetItemContentElement(indexPath);
6510  var linkElement = (element != null) ? (element.tagName === "A" ? element : ASPx.GetNodeByTagName(element, "A", 0)) : null;
6511  if(linkElement != null && linkElement.href == ASPx.AccessibilityEmptyUrl)
6512   linkElement = null;
6513  if(this.allowSelectItem)
6514   this.SetSelectedItemInternal(indexPath, true);
6515  if(this.allowCheckItems || this.canCheckItem(element))
6516   this.ChangeCheckedItem(indexPath);
6517  this.DoItemClick(indexPath, isLinkClicked || (linkElement != null), evt);
6518  if(!isLinkClicked && linkElement != null && !(ASPx.Browser.WebKitTouchUI && this.HasChildren(indexPath)))
6519   ASPx.Url.NavigateByLink(linkElement);
6520 },
6521 canCheckItem: function (itemElement) {
6522  return false;
6523 },
6524 OnItemDropDownClick: function(indexPath, evt) {
6525  if(this.IsItemEnabled(indexPath)) {
6526   if(this.IsAdaptiveItem(indexPath))
6527    this.toggleAdaptiveSubmenu(indexPath);
6528   else
6529    this.keyboardHelper.ShowSubMenuAccessible(indexPath);
6530  }
6531 },
6532 toggleAdaptiveSubmenu: function(indexPath) {
6533  var element = this.GetMenuElement(indexPath);
6534  if(ASPx.GetElementDisplay(element) && !this.IsAdaptiveItemAnimationActive())
6535   this.DoHidePopupMenu(null, element);
6536  else
6537   this.keyboardHelper.ShowSubMenuAccessible(indexPath);
6538 },
6539 AfterItemOverAllowed: function(hoverItem) {
6540  return hoverItem.name != "" && !this.lockHoverEvents;
6541 },
6542 OnAfterItemOver: function(hoverItem, hoverElement) {
6543  if(!this.AfterItemOverAllowed(hoverItem)) return;
6544  if(!this.showSubMenus) {
6545   this.savedCallbackHoverItem = hoverItem;
6546   this.savedCallbackHoverElement = hoverElement;
6547   return;
6548  }
6549  this.ClearDisappearTimer();
6550  this.ClearAppearTimer();
6551  var indexPath = this.GetMenuIndexPathById(hoverItem.name);
6552  if(indexPath == "") {
6553   indexPath = this.GetItemIndexPathById(hoverItem.name);
6554   var canShowSubMenu = true;
6555   if(this.IsDropDownItem(indexPath)) {
6556    var popOutImageElement = this.GetItemPopOutElement(indexPath);
6557    if(popOutImageElement != null && popOutImageElement != hoverElement) {
6558     hoverItem.needRefreshBetweenElements = true;
6559     canShowSubMenu = false;
6560    }
6561   }
6562   var preventSubMenu = !(canShowSubMenu && hoverItem.enabled && hoverItem.kind == ASPx.HoverItemKind);
6563   this.SetAppearTimer(indexPath, preventSubMenu);
6564   this.RaiseItemMouseOver(indexPath);
6565  }
6566 },
6567 OnBeforeItemOver: function(hoverItem, hoverElement) {
6568  if(ASPx.Browser.NetscapeFamily && ASPx.IsExists(hoverElement.offsetParent) &&
6569    hoverElement.offsetParent.style.borderCollapse == "collapse") {
6570   hoverElement.offsetParent.style.borderCollapse = "separate";
6571   hoverElement.offsetParent.style.borderCollapse = "collapse";
6572  }
6573  var indexPath = this.GetItemIndexPathById(hoverItem.name);
6574  var element = this.GetMenuElement(indexPath);
6575  if(element) this.CancelSubMenuItemHoverItem(element);
6576 },
6577 OnItemOverTimer: function(indexPath, preventSubMenu) {
6578  var element = this.GetMenuElement(indexPath);
6579  if(element == null || preventSubMenu) {
6580   var level = this.GetMenuLevel(indexPath);
6581   aspxGetMenuCollection().DoHidePopupMenus(null, level - 1, this.name, false, this.getExceptIdsForItemOverTimer(indexPath));
6582  }
6583  if(this.IsAppearTimerActive() && !preventSubMenu) {
6584   this.ClearAppearTimer();
6585   if(this.GetItemContentElement(indexPath) != null || this.GetItemPopOutElement(indexPath) != null) {
6586    this.ShowSubMenu(indexPath);
6587   }
6588  }
6589 },
6590 getExceptIdsForItemOverTimer: function(indexPath) {
6591  var result = [];
6592  aspxGetMenuCollection().ForEachControl(function(menu) {
6593   var isPopupMenu = ASPx.IsExists(menu.popupAction) && ASPx.IsExists(menu.closeAction);
6594   if(isPopupMenu && menu.closeAction === "OuterMouseClick")
6595    result.push(menu.GetMainElementId());
6596  }, this);
6597  return result;
6598 },
6599 OnBeforeItemDisabled: function(disabledItem, disabledElement) {
6600  this.ClearAppearTimer();
6601  var indexPath = this.GetItemIndexPathById(disabledElement.id);
6602  if(indexPath != "") {
6603   var element = this.GetMenuElement(indexPath);
6604   if(element != null) this.DoHidePopupMenu(null, element);
6605  }
6606 },
6607 OnAfterItemOut: function(hoverItem, hoverElement, newHoverElement) {
6608  if(!this.showSubMenus) {
6609   this.savedCallbackHoverItem = null;
6610   this.savedCallbackHoverElement = null;
6611  }
6612  if(hoverItem.name == "" || this.lockHoverEvents) return;
6613  if(hoverItem.IsChildElement(newHoverElement)) return;
6614  var indexPath = this.GetItemIndexPathById(hoverItem.name);
6615  var element = this.GetMenuElement(indexPath);
6616  this.ClearDisappearTimer();
6617  this.ClearAppearTimer();
6618  if(element == null || !ASPx.GetIsParent(element, newHoverElement))
6619   this.SetDisappearTimer();
6620  if(element != null)
6621   this.ApplySubMenuItemHoverItem(element, hoverItem, hoverElement);
6622  if(indexPath != "")
6623   this.RaiseItemMouseOut(indexPath);
6624 },
6625 OnItemOutTimer: function() {
6626  if(this.IsDisappearTimerActive()) {
6627   this.ClearDisappearTimer();
6628   if(aspxGetMenuCollection().CheckFocusedElement())
6629    this.SetDisappearTimer();
6630   else
6631    this.OnHideByItemOut();
6632  }
6633 },
6634 OnHideByItemOut: function() {
6635  aspxGetMenuCollection().DoHidePopupMenus(null, 0, this.name, true, "");
6636 },
6637 TryFocusItem: function(itemIndex) {
6638  var item = this.GetItem(itemIndex);
6639  if(item.GetVisible() && item.GetEnabled()) {
6640   this.FocusItemByIndexPath(item.GetIndexPath());
6641   return true;
6642  }
6643  return false;
6644 },
6645 Focus: function() {
6646  if(this.rootItem != null) { 
6647   for(var i = 0; i < this.GetItemCount() ; i++) {
6648    if(this.TryFocusItem(i))
6649     return true;
6650   }
6651  }
6652  else
6653   this.keyboardHelper.FocusNextItem("-1");
6654 },
6655 FocusLastItem: function() {
6656  if(this.rootItem != null) { 
6657   for(var i = this.GetItemCount() - 1; i >= 0; i--) {
6658    if(this.TryFocusItem(i))
6659     return true;
6660   }
6661  }
6662  else
6663   this.keyboardHelper.FocusPrevItem(this.GetItemCount() - 1);
6664 },
6665 FocusItemByIndexPath: function(indexPath) {
6666  this.keyboardHelper.FocusItemByIndexPath(indexPath);
6667 },
6668 OnFocusedItemKeyDown: function(evt, focusedItem) {
6669  this.keyboardHelper.OnFocusedItemKeyDown(evt, focusedItem);
6670 },
6671 ProcessLostFocus: function(evt) {
6672  if(!this.isContextMenu || !this.accessibilityCompliant) return;
6673  if(this.accessibleFocusElement)
6674   this.accessibleFocusElement.focus();
6675  this.Hide();
6676  if(evt)
6677   ASPx.Evt.PreventEventAndBubble(evt);
6678 },
6679 OnCallback: function(result) {
6680  ASPx.InitializeScripts(); 
6681  this.InitializeScrollableMenus();
6682  for (var indexPath in result) {
6683   if(result.hasOwnProperty(indexPath)) {
6684    var menuElement = this.GetMenuElement(indexPath);
6685    if(menuElement) {
6686     var menuResult = result[indexPath];
6687     if(aspxGetMenuCollection().IsSubMenuVisible(menuElement.id))
6688      this.ShowPopupSubMenuAfterCallback(menuElement, menuResult);
6689     else
6690      this.SetSubMenuInnerHtml(menuElement, menuResult);
6691    }
6692   }
6693  }
6694  this.ClearVerticalAlignedElementsCache();
6695  this.CorrectVerticalAlignment(ASPx.AdjustHeight, this.GetPopOutElements, "PopOut");
6696  this.CorrectVerticalAlignment(ASPx.AdjustVerticalMargins, this.GetPopOutImages, "PopOutImg");
6697  this.InitializeInternal(false);
6698  if(!this.showSubMenus) {
6699   this.showSubMenus = true;
6700   if(this.savedCallbackHoverItem != null && this.savedCallbackHoverElement != null)
6701    this.OnAfterItemOver(this.savedCallbackHoverItem, this.savedCallbackHoverElement);
6702   this.savedCallbackHoverItem = null;
6703   this.savedCallbackHoverElement = null;
6704  }
6705 },
6706 SetSubMenuInnerHtml: function(menuElement, html) {
6707  ASPx.SetInnerHtml(this.GetMenuMainElement(menuElement), html);
6708  this.dropElementsCache = true;
6709  this.renderHelper.InlineInitializePopupMenuMenuElement(menuElement, this.GetIndexPathById(menuElement.id, true));
6710  this.renderHelper.CalculateSubMenu(menuElement, true);
6711 },
6712 ShowPopupSubMenuAfterCallback: function(element, callbackResult) {
6713  var indexPath = this.GetIndexPathById(element.id, true);
6714  var currentX = ASPx.PxToInt(element.style.left);
6715  var currentY = ASPx.PxToInt(element.style.top);
6716  var showedToTheTop = this.ShowedToTheTop(element, indexPath);
6717  var showedToTheLeft = this.ShowedToTheLeft(element, indexPath);
6718  ASPx.SetStyles(element, {
6719   left: ASPx.InvalidPosition, top: ASPx.InvalidPosition
6720  });
6721  this.SetSubMenuInnerHtml(element, callbackResult);
6722  var vertPos = this.GetClientSubMenuPos(element, indexPath, ASPx.InvalidPosition, this.IsVertical(indexPath), false);
6723  var clientY = vertPos.position;
6724  var toTheTop = vertPos.isInverted;
6725  if(!this.IsVertical(indexPath) && showedToTheTop != toTheTop) {
6726   clientY = currentY;
6727   toTheTop = showedToTheTop;
6728  }
6729  clientY += this.GetScrollingCorrection(element, indexPath, clientY);
6730  ASPx.SetStyles(element, { left: currentX, top: clientY });
6731  if(this.enableSubMenuFullWidth)
6732   this.ApplySubMenuFullWidth(element);
6733  this.DoShowPopupMenuIFrame(element, currentX, clientY, ASPx.InvalidDimension, ASPx.InvalidDimension, indexPath);
6734  this.DoShowPopupMenuBorderCorrector(element, currentX, clientY, indexPath, showedToTheLeft, toTheTop);
6735  ASPx.GetControlCollection().AdjustControls(element);
6736 },
6737 GetScrollingCorrection: function(element, indexPath, clientY) {
6738  var scrollHelper = this.GetScrollHelper(indexPath);
6739  if(scrollHelper) {
6740   var yClientCorrection = this.GetScrollSubMenuYCorrection(element, scrollHelper, clientY);
6741   if(yClientCorrection > 0)
6742    return yClientCorrection;
6743  }
6744  return 0;
6745 },
6746 ShowedToTheTop: function(element, indexPath) {
6747  var currentY = ASPx.PxToInt(element.style.top);
6748  var parentBottomY = this.GetSubMenuYPosition(indexPath, this.IsVertical(indexPath));
6749  return currentY < parentBottomY;
6750 },
6751 ShowedToTheLeft: function(element, indexPath) {
6752  var currentX = ASPx.PxToInt(element.style.left);
6753  var parentX = this.GetSubMenuXPosition(indexPath, this.IsVertical(indexPath));
6754  return currentX < parentX;
6755 },
6756 CreateItems: function(items) {
6757  if (items.length == 0)
6758   return;
6759  if(this.NeedCreateItemsOnClientSide())
6760   this.CreateClientItems(items);
6761  else
6762   this.CreateServerItems(items);
6763 },
6764 AddItem: function(item) {
6765  this.CreateClientItems([item]);
6766 },
6767 CreateClientItems: function(items) {
6768  this.PreInitializeClientMenuItems();
6769  this.rootItem.CreateItems(items);
6770  this.RenderItems(this.rootItem.items);
6771  this.InitializeClientItems();
6772 },
6773 CreateServerItems: function(items) {
6774  this.CreateRootItemIfRequired();
6775  this.rootItem.CreateItems(items);
6776 },
6777 PreInitializeClientMenuItems: function() {
6778  if(!this.rootMenuSample)
6779   this.InitializeMenuSamples();
6780  this.CreateRootItemIfRequired();
6781  if(!this.renderData)
6782   this.CreateRenderData();
6783 },
6784 InitializeClientItems: function() {
6785  this.dropElementsCache = true;
6786  this.renderHelper.InlineInitializeElements();
6787  this.ApplyItemsProperties(this.rootItem.items);
6788  this.InitializeEnabledAndVisible(true);
6789  if(this.isPopupMenu)
6790   this.renderHelper.CalculateSubMenu(this.GetMainElement(), true);
6791  else
6792   this.renderHelper.CalculateMenuControl(this.GetMainElement(), true);
6793 },
6794 ApplyItemsProperties: function(items) {
6795  var itemsCount = items.length;
6796  if(itemsCount == 0)
6797   return;
6798  for(var i = 0; i < itemsCount; i++) {
6799   var item = items[i];
6800   this.ApplyItemProperties(item);
6801   this.ApplyItemsProperties(item.items);
6802  }
6803 },
6804 ApplyItemProperties: function(item) {
6805  var indexPath = item.GetIndexPath();
6806  if(item.imageUrl)
6807   this.SetItemImageUrl(indexPath, item.imageUrl);
6808  if(item.imageClassName) {
6809   this.AddItemImageClassName(indexPath, item.imageClassName);
6810   this.AddItemAdditionalImageClassName(indexPath, item.imageClassName);
6811  }
6812  if(item.navigateUrl)
6813   this.SetItemNavigateUrl(indexPath, item.navigateUrl, item.target);
6814  if(item.tooltip != "")
6815   this.SetItemTooltip(indexPath, item.tooltip);
6816  var textNode = this.FindTextNode(indexPath);
6817  if(textNode)
6818   textNode.parentNode.innerHTML = this.HtmlEncode(item.text);
6819  this.SetItemChecked(indexPath, item.checked);
6820  if(item.textTemplate)
6821   this.SetItemTextTemplate(indexPath, item.textTemplate);
6822 },
6823 ProcessItemGroupName: function(item, groupName) {
6824  if(this.allowSelectItem || !groupName)
6825   return;
6826  this.allowCheckItems = true;
6827  var groupNames = this.itemCheckedGroups.groupNames;
6828  if(groupNames[groupName])
6829   groupNames[groupName].push(item.indexPath);
6830  else {
6831   groupNames[groupName] = [item.indexPath];
6832   this.itemCheckedGroups.push(groupNames[groupName]);
6833  }
6834  item.checkedGroup = groupNames[groupName];
6835 },
6836 CreateRootItemIfRequired: function() {
6837  if(!this.rootItem) {
6838   var itemType = this.GetClientItemType();
6839   this.rootItem = new itemType(this, null, 0, "");
6840  }
6841 },
6842 ClearRootMenuElement: function() {
6843  var wrapperElement = this.GetMainElement().parentNode;
6844  wrapperElement.innerHTML = "";
6845  wrapperElement.appendChild(this.rootMenuSample.cloneNode(true));
6846  this.renderHelper.InlineInitializeScrollElements("", this.GetMainElement());
6847 }, 
6848 NeedAppendToRenderData: function(item) {
6849  return this.NeedCreateItemsOnClientSide() && item.visible || typeof(item.visible) == "undefined";
6850 },
6851 ClearItems: function() {
6852  this.PreInitializeClientMenuItems();
6853  this.ClearRootMenuElement();
6854  this.ClearRenderData();
6855  this.rootItem.items = [];
6856  this.checkedItems = [];
6857 },
6858 GetSampleNode: function(sampleHtml) {
6859  return ASPx.CreateHtmlElementFromString(sampleHtml);
6860 },
6861 GetParentItem: function(rootItemIndexPath) {
6862  if(!rootItemIndexPath)
6863   return this.rootItem;
6864  return this.GetItemByIndexPath(rootItemIndexPath);
6865 },
6866 RenderItems: function(items) {
6867  for(var i=0; i < items.length; i++) {
6868   var item = items[i];
6869   this.RenderItemIfRequired(item);
6870   this.RenderItems(item.items);
6871  }
6872 },
6873 RenderItemIfRequired: function(item) {
6874  if(!this.GetItemElement(item.indexPath)) {
6875   var isRootItem = !this.GetItemElement(item.parent.indexPath);
6876   var rootMenuElement = this.GetOrRenderRootItem(item, isRootItem);
6877   this.RenderItemInternal(rootMenuElement, item, isRootItem);
6878   this.ApplyStylesToRenderItem(item, isRootItem);
6879  }
6880 },
6881 ApplyStylesToRenderItem: function(item, isRootItem) {
6882  var styles = JSON.parse(JSON.stringify(isRootItem ? this.samples.itemsStyles : this.samples.subitemsStyles));
6883  var hoverStyle = styles.hover;
6884  var disabledStyle = styles.disable;
6885  var selectedStyle = styles.select;
6886  var checkedStyle = styles.check;
6887  var itemElementId = this.GetItemElementId(item.indexPath);
6888  if(item.styles && item.styles.ho) {
6889   var itemHover = item.styles.ho;
6890   if(!!itemHover.style)
6891    hoverStyle.cssTexts[0] = itemHover.style;
6892   if(!!itemHover.cssClass)
6893    hoverStyle.classNames[0] += " " + itemHover.cssClass;
6894  }
6895  if(item.styles && item.styles.st) {
6896   var itemElement = this.GetItemElement(item.indexPath);
6897   var style = item.styles.st;
6898   itemElement.setAttribute("style", style.style);
6899   if(!!style.cssClass)
6900    ASPx.AddClassNameToElement(itemElement, style.cssClass);
6901  }
6902  ASPx.GetStateController().AddHoverItem(itemElementId, hoverStyle.classNames || [MenuCssClasses.ItemHovered], hoverStyle.cssTexts || [""], hoverStyle.postfixes || [""], item.imageHottrackSrc ? [item.imageHottrackSrc] : null, [Constants.ImagePostfix, Constants.PopupImagePostfix], false);
6903  ASPx.GetStateController().AddDisabledItem(itemElementId, disabledStyle.classNames || [MenuCssClasses.Disabled], disabledStyle.cssTexts || [""], disabledStyle.postfixes || [""], null, null, false);
6904  if(selectedStyle && this.allowSelectItem)
6905   ASPx.GetStateController().AddSelectedItem(itemElementId, selectedStyle.classNames || [MenuCssClasses.ItemSelected], selectedStyle.cssTexts || [""], selectedStyle.postfixes || [""], null, null, false);
6906  else if (checkedStyle && this.allowCheckItems && item.checkedGroup.length) {
6907   var checkedClassName = null;
6908   if(!item.imageClassName)
6909    checkedClassName = [this.samples.checkedClassName];
6910   ASPx.GetStateController().AddSelectedItem(itemElementId, checkedStyle.classNames || [MenuCssClasses.ItemChecked], checkedStyle.cssTexts || [""], checkedStyle.postfixes || [""], checkedClassName, ['Img'], false);
6911  }
6912 },
6913 GetOrRenderRootItem: function(item, isRootItem) {
6914  if(!isRootItem) {
6915   var rootMenuElement = this.GetMenuElement(item.parent.indexPath);
6916   return rootMenuElement ? rootMenuElement : this.RenderSubMenuItem(item.parent.indexPath);
6917  } else
6918   return this.GetMenuElement("");
6919 },
6920 RenderItemInternal: function(rootItem, item, isRootItem) {
6921  var contentElement = this.renderHelper.GetContentElement(rootItem);
6922  var element = this.CreateItemElement(item, isRootItem);
6923  this.RenderSeparatorElementIfRequired(contentElement, item);
6924  this.RenderSpaceElementIfRequired(contentElement, item);
6925  contentElement.appendChild(element);
6926 },
6927 RenderSeparatorElementIfRequired: function(rootItem, item) {
6928  if(item.beginGroup && item.index > 0) {
6929   var separatorElement = this.CreateSeparatorElement(item.indexPath);
6930   rootItem.appendChild(separatorElement);
6931  }
6932 },
6933 RenderSpaceElementIfRequired: function(rootItem, item) {
6934  if(!item.beginGroup && item.index > 0 && rootItem.childNodes.length > 0) {
6935   if(this.samples.spacing) {
6936    var spacingElement = this.CreateSpacingElement(item.indexPath);
6937    rootItem.appendChild(spacingElement);
6938   }
6939  }
6940 },
6941 RenderSubMenuItem: function(indexPath) {
6942  var subMenuElement = this.CreateSubMenuElement(indexPath);
6943  this.GetMainElement().parentElement.appendChild(subMenuElement);
6944  return subMenuElement;
6945 },
6946 HasSeparatorOnCurrentPosition: function(itemElements, position) {
6947  return itemElements[position - 1 >
6947 0 ? position - 1 : 0].className.indexOf(MenuCssClasses.Separator) > -1;
6948 },
6949 CreateItemElement: function(item, isRootItem) {
6950  var itemSample = isRootItem ? this.GetRootItemSample(item) : this.GetSubitemSample(item);
6951  var itemElement = itemSample.cloneNode(true);
6952  itemElement.id = this.GetItemElementId(item.indexPath);
6953  return itemElement;
6954 },
6955 GetRootItemSample: function(item) {
6956  return this.GetItemSample(this.samples.rootItems, item);
6957 },
6958 GetSubitemSample: function(item) {
6959  return this.GetItemSample(this.samples.submenuItems, item);
6960 },
6961 GetItemSample: function(samples, item) {
6962  var key = this.sampleItemsFlags.TextOnly;
6963  if(item.items.length > 0)
6964   key = key | this.sampleItemsFlags.SubItems;
6965  if(item.imageUrl)
6966   key = key | this.sampleItemsFlags.Image;
6967  if(item.navigateUrl)
6968   key = key | this.sampleItemsFlags.NavigateUrl;
6969  if(item.dropDownMode)
6970   key = key | this.sampleItemsFlags.DropDownMode;
6971  if(item.checkedGroup.length)
6972   key = key | this.sampleItemsFlags.CheckBox;
6973  if(item.imageClassName)
6974   key = key | this.sampleItemsFlags.ImageClassName;
6975  if(item.isSvg)
6976   key = key | this.sampleItemsFlags.Svg;
6977  return samples[key];
6978 },
6979 CreateSpacingElement: function(indexPath) {
6980  var item = this.samples.spacing.cloneNode();
6981  item.id = this.GetItemIndentElementId(indexPath);
6982  return item;
6983 },
6984 CreateSeparatorElement: function(indexPath) {
6985  var item = this.samples.separator.cloneNode(true);
6986  item.id = this.GetItemSeparatorElementId(indexPath);
6987  return item;
6988 },
6989 CreateSubMenuElement: function(indexPath) {
6990  var subMenu = this.samples.submenu.cloneNode(true);
6991  subMenu.id =  this.name + Constants.MMIdSuffix + indexPath + "_";
6992  return subMenu;
6993 },
6994 AppendToRenderData: function(rootItemIndexPath, index) {
6995  if(rootItemIndexPath) {
6996   if(!this.renderData[rootItemIndexPath])
6997    this.renderData[rootItemIndexPath] = [[index]];
6998   this.renderData[rootItemIndexPath][index] = [index];
6999  } else {
7000   this.renderData[""].push([[index]]);
7001  }
7002 },
7003 CreateRenderData: function() {
7004  this.renderData = {"" : []};
7005 },
7006 ClearRenderData: function() {
7007  this.renderData = null;
7008 },
7009 GetClientItemType: function() {
7010  return ASPxClientMenuItem;
7011 },
7012 GetItemByIndexPath: function(indexPath) {
7013  var item = this.rootItem;
7014  if(indexPath != "" && item != null) {
7015   var indexes = this.GetItemIndexes(indexPath);
7016   for(var i = 0; i < indexes.length; i++)
7017    item = item.GetItem(indexes[i]);
7018  }
7019  return item;
7020 },
7021 GetLinkElementByIndexPath: function(indexPath) {
7022  var itemElement = this.GetItemElement(indexPath);
7023  return this.renderHelper.GetItemLinkElement(itemElement);
7024 },
7025 SetItemChecked: function(indexPath, checked) {
7026  var itemsGroup = this.GetItemsGroup(indexPath);
7027  if(itemsGroup != null) {
7028   if(!checked && this.IsCheckedItem(indexPath)) {
7029    ASPx.Data.ArrayRemove(this.checkedItems, indexPath);
7030    this.DeselectItem(indexPath);
7031   }
7032   else if(checked && !this.IsCheckedItem(indexPath)) {
7033    if(itemsGroup.length > 1) {
7034     for(var i = 0; i < itemsGroup.length; i++) {
7035      if(itemsGroup[i] == indexPath) continue;
7036      if(this.IsCheckedItem(itemsGroup[i])) {
7037       ASPx.Data.ArrayRemove(this.checkedItems, itemsGroup[i]);
7038       this.DeselectItem(itemsGroup[i]);
7039      }
7040     }
7041    }
7042    this.SelectItem(indexPath);
7043    this.checkedItems.push(indexPath);
7044   }
7045   if(this.accessibilityCompliant) {
7046    var link = this.GetLinkElementByIndexPath(indexPath);
7047    if(link)
7048     ASPx.Attr.SetAttribute(link, "aria-checked", checked ? "true" : "false");
7049   }
7050  }
7051 },
7052 ChangeItemEnabledAttributes: function(indexPath, enabled) {
7053  this.renderHelper.ChangeItemEnabledAttributes(this.GetItemElement(indexPath), enabled, this.accessibilityCompliant);
7054 },
7055 IsItemEnabled: function(indexPath) {
7056  var item = this.GetItemByIndexPath(indexPath);
7057  return (item != null) ? item.GetEnabled() : true;
7058 },
7059 SetItemEnabled: function(indexPath, enabled, initialization) {
7060  if(indexPath == "" || !this.GetItemByIndexPath(indexPath).enabled) return;
7061  if(!enabled) {
7062   if(this.GetSelectedItemIndexPath() == indexPath)
7063    this.DeselectItem(indexPath);
7064  }
7065  if(!initialization || !enabled)
7066   this.ChangeItemEnabledStateItems(indexPath, enabled);
7067  this.ChangeItemEnabledAttributes(indexPath, enabled);
7068  if(enabled) {
7069   if(this.GetSelectedItemIndexPath() == indexPath)
7070    this.SelectItem(indexPath);
7071  }
7072 },
7073 ChangeItemEnabledStateItems: function(indexPath, enabled) {
7074  if(!this.IsStateControllerEnabled()) return;
7075  this.UpdateHoverableItems(indexPath, enabled);
7076  var element = this.GetItemElement(indexPath);
7077  if(element)
7078   ASPx.GetStateController().SetElementEnabled(element, enabled);
7079 },
7080 UpdateHoverableItems: function(indexPath, enabled) {
7081  var menuItemElement = this.GetItemElement(indexPath);
7082  if(menuItemElement) {
7083   var postfixes = ["", Constants.ItemPopoutElementPostfix, Constants.ItemContentElementPostfix];
7084   for(var i = 0; i < postfixes.length; i++) {
7085    var element = ASPx.CacheHelper.GetCachedElementById(this, this.GetItemElementId(indexPath) + postfixes[i]);
7086    if(element) {
7087     if(enabled) {
7088      var hoverItem = element.savedHoverItem;
7089      if(hoverItem)
7090       ASPx.GetStateController().AddHoverItem(hoverItem.name, hoverItem.classNames, hoverItem.cssTexts, hoverItem.postfixes, hoverItem.imageObjs, hoverItem.imagePostfixes, hoverItem.disableApplyingStyleToLink);
7091     }
7092     else {
7093      element.savedHoverItem = ASPx.GetStateController().GetHoverItem(element);
7094     }
7095    }
7096   }
7097   ASPx.GetStateController().ClearElementCacheInContainer(menuItemElement);
7098   if(!enabled)
7099    ASPx.GetStateController().RemoveItem(ASPx.GetStateController().hoverItems, this.GetItemElementId(indexPath), postfixes);
7100  }
7101 },
7102 GetItemImageUrl: function(indexPath) {
7103  var image = this.GetItemImage(indexPath);
7104  if(image)
7105   return image.src;
7106  return "";
7107 },
7108 SetItemImageUrl: function(indexPath, url) {
7109  var image = this.GetItemImage(indexPath);
7110  if(image)
7111   image.src = url;
7112 },
7113 AddItemImageClassName: function(indexPath, className) {
7114  var image = this.GetItemImage(indexPath);
7115  if(image) {
7116   var accessibilityElement = image.parentNode;
7117   if(accessibilityElement.tagName == "SPAN")
7118    ASPx.AddClassNameToElement(accessibilityElement, className);
7119   else
7120    ASPx.AddClassNameToElement(image, className);
7121  }
7122  else {
7123   var svgElement = this.getSvgElement(indexPath);
7124   if(svgElement) {
7125    ASPx.AddClassNameToElement(svgElement, className);
7126    var useElement = ASPx.GetNodeByTagName(svgElement, "use", 0);
7127    useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', "#" + className);
7128   }
7129  }
7130 },
7131 AddItemAdditionalImageClassName: function(indexPath) {
7132 },
7133 getSvgElement: function(indexPath) {
7134  var element = this.GetItemContentElement(indexPath);
7135  if(element != null) {
7136   var svgElement = ASPx.GetNodeByTagName(element, "svg", 0);
7137   if(svgElement != null) {
7138    return svgElement;
7139   }
7140  }
7141 },
7142 GetItemImage: function(indexPath) {
7143  var element = this.GetItemContentElement(indexPath);
7144  if(element != null) {
7145   var img = ASPx.GetNodeByTagName(element, "IMG", 0);
7146   if(img != null)
7147    return img;
7148  }
7149 },
7150 GetItemNavigateUrl: function(indexPath) {
7151  var element = this.GetItemContentElement(indexPath);
7152  if(element != null && element.tagName === "A")
7153   return ASPx.Attr.GetAttribute(element, "savedhref") || element.href;
7154  if(element != null) {
7155   var link = ASPx.GetNodeByTagName(element, "A", 0);
7156   if(link != null)
7157    return ASPx.Attr.GetAttribute(link, "savedhref") || link.href;
7158  }
7159  return "";
7160 },
7161 SetUrl: function(link, url, target) {
7162  if(link != null) {
7163   if(ASPx.Attr.IsExistsAttribute(link, "savedhref"))
7164    ASPx.Attr.SetAttribute(link, "savedhref", url);
7165   else if(ASPx.Attr.IsExistsAttribute(link, "href"))
7166    link.href = url;
7167   if(!!target)
7168    link.target = target;
7169  }
7170 },
7171 SetItemNavigateUrl: function(indexPath, url, target) {
7172  var element = this.GetItemContentElement(indexPath);
7173  if(element != null) {
7174   if(element.tagName === "A")
7175    this.SetUrl(element, url, target);
7176   else {
7177    this.SetUrl(ASPx.GetNodeByTagName(element, "A", 0), url, target);
7178    this.SetUrl(ASPx.GetNodeByTagName(element, "A", 1), url, target);
7179   }
7180  }
7181 },
7182 FindTextNode: function(indexPath) {
7183  var contentElement = this.GetItemContentElement(indexPath);
7184  if(contentElement) {
7185   var link = this.GetLinkElementByIndexPath(indexPath);
7186   if(link)
7187    return ASPx.GetNormalizedTextNode(link);
7188   var textElement = this.GetContentTextElement(contentElement);
7189   if(textElement)
7190    return ASPx.GetNormalizedTextNode(textElement);
7191   return ASPx.GetNormalizedTextNode(contentElement);
7192  }
7193  return null;
7194 },
7195 GetContentTextElement: function(contentElement) {
7196  return ASPx.GetChildByClassName(contentElement, MenuCssClasses.ItemTextElement, 0);
7197 },
7198 GetItemText: function(indexPath) {
7199  var textNode = this.FindTextNode(indexPath);
7200  return textNode
7201   ? ASPx.Str.Trim(textNode.nodeValue) 
7202   : "";
7203 },
7204 SetItemText: function(indexPath, text) {
7205  var textNode = this.FindTextNode(indexPath);
7206  if(textNode) {
7207   textNode.nodeValue = text;
7208   var menuElement = this.GetMenuElement(this.GetParentIndexPath(indexPath));
7209   if(menuElement && (!this.IsRootItem(indexPath) || this.isPopupMenu))
7210    this.renderHelper.CalculateSubMenu(menuElement, true);
7211   if(this.IsRootItem(indexPath) && !this.isPopupMenu) {
7212    var itemElement = this.GetItemElement(indexPath);
7213    if(itemElement)
7214     this.renderHelper.CalculateItemMinSize(itemElement, true);
7215   }
7216   this.AdjustControl();
7217  }
7218 },
7219 SetItemTextTemplate: function(indexPath, textTemplate) {
7220  var contentElement = this.GetItemContentElement(indexPath);
7221  var textElement = this.GetContentTextElement(contentElement);
7222  if(textElement) {
7223   var container = document.createElement("DIV");
7224   container.innerHTML = textTemplate;
7225   contentElement.replaceChild(container.firstChild, textElement);
7226  }
7227 },
7228 SetItemTooltip: function(indexPath, tooltip) {
7229  var itemElement = this.GetItemElement(indexPath);
7230  if(itemElement && tooltip)
7231   itemElement.title = tooltip;
7232 },
7233 SetItemVisible: function(indexPath, visible, initialization) {
7234  var item = this.GetItemByIndexPath(indexPath);
7235  if(indexPath == "" || !item.visible) return;
7236  if(visible && initialization) return;
7237  var element = this.GetItemElement(indexPath);
7238  if(element != null)
7239   this.SetElementDisplay(element, visible);
7240  this.SetIndentsVisiblility(indexPath);
7241  var parentIndexPath = this.GetParentIndexPath(indexPath);
7242  if(this.isPopupMenu && this.inPopUpHandler)
7243   this.postponeSetItemVisible(parentIndexPath);
7244  else
7245   this.SetSeparatorsVisiblility(parentIndexPath);
7246  if(!this.IsItemInAdaptiveMenu(item))
7247   this.UpdateItemCssClasses(indexPath, visible);
7248  var parent = this.GetItemByIndexPath(indexPath).parent;
7249  var parentHasVisibleItems = this.HasVisibleItems(parent);
7250  if(this.IsRootItem(indexPath) && !this.isPopupMenu) {
7251   if(this.clientVisible)
7252    this.SetElementDisplay(this.GetMainElement(), parentHasVisibleItems);
7253  }
7254  else
7255   this.SetPopOutElementVisible(parent.indexPath, parentHasVisibleItems);
7256  if(this.GetMenuLevel(parentIndexPath) !== 0 || this.isPopupMenu && !this.inPopUpHandler)
7257   this.calculateSubMenuByIndexPath(parentIndexPath);
7258  if(this.IsRootItem(indexPath) && !this.isPopupMenu) 
7259   this.renderHelper.CalculateMenuControl(this.GetMainElement(), true);
7260 },
7261 SetElementDisplay: function (element, visible) {
7262  ASPx.SetElementDisplay(element, visible);
7263 },
7264 prepareSideMenuCssClasses: function(addClass) {
7265  if(this.sideMenuModeOn) {
7266   this.MarkPrecedingItemCore(this.GetSelectedItemIndexPath(), PRE_SELECTED_ELEMENT_CLASS_NAME, addClass, false);
7267   if(this.hoverItemName)
7268    this.MarkPrecedingItemCore(this.hoverItemName, PRE_HOVERED_ELEMENT_CLASS_NAME, addClass, true);
7269  }
7270 },
7271 calculateSubMenuByIndexPath: function(indexPath) {
7272  var menuElement = this.GetMenuElement(indexPath);
7273  if(menuElement)
7274   this.renderHelper.CalculateSubMenu(menuElement, true);
7275 },
7276 postponeSetItemVisible: function(indexPath) {
7277  if(!this.postponedIndexPath)
7278   this.postponedIndexPath = [];
7279  for(var i = 0; i < this.postponedIndexPath.length; i++) {
7280   if(this.postponedIndexPath[i] === indexPath)
7281    return;
7282  }
7283  this.postponedIndexPath.push(indexPath);
7284 },
7285 postponedSetItemVisible: function() {
7286  if(!!this.postponedIndexPath && this.postponedIndexPath.length > 0)
7287   ASPx.Data.ForEach(this.postponedIndexPath, function(indexPath) {
7288    this.SetSeparatorsVisiblility(indexPath);
7289    this.calculateSubMenuByIndexPath(indexPath);
7290   }.aspxBind(this));
7291  this.postponedIndexPath = [];
7292 },
7293 SetIndentsVisiblility: function(indexPath) {
7294  var parent = this.GetItemByIndexPath(indexPath).parent;
7295  for(var i = 0; i < parent.GetItemCount(); i++) {
7296   var item = parent.GetItem(i);
7297   var separatorVisible = this.HasPrevVisibleItems(parent, i) && item.GetVisible();
7298   var element = this.GetItemIndentElement(item.GetIndexPath());
7299   if(element != null) ASPx.SetElementDisplay(element, separatorVisible);
7300  }
7301 },
7302 SetSeparatorsVisiblility: function(indexPath) {
7303  var parent = this.GetItemByIndexPath(indexPath);
7304  for(var i = 0; i < parent.GetItemCount(); i++) {
7305   var item = parent.GetItem(i);
7306   var separatorVisible = this.HasPrevVisibleItems(parent, i) && (item.GetVisible() || this.HasNextVisibleItemInGroup(parent, i));
7307   var element = this.GetItemSeparatorElement(item.GetIndexPath());
7308   if(element != null) ASPx.SetElementDisplay(element, separatorVisible);
7309  }
7310 },
7311 UpdateItemCssClasses: function(indexPath, visible) {
7312 },
7313 SetPopOutElementVisible: function(indexPath, visible) {
7314  var popOutElement = this.GetItemPopOutElement(indexPath);
7315  if(popOutElement)
7316   popOutElement.style.display = visible ? 'block' : 'none';
7317 },
7318 GetPrevVisibleItemInGroup: function(parent, index, skipItemsInAdaptiveMenu) {
7319  if(this.IsItemBeginsGroup(parent.GetItem(index)))
7320   return null;
7321  for(var i = index - 1; i >= 0; i--) {
7322   var item = parent.GetItem(i);
7323   if(item.GetVisible() && !this.IsAdaptiveItem(item.indexPath) && (!skipItemsInAdaptiveMenu || !this.IsItemInAdaptiveMenu(item)))
7324    return item;
7325   if(this.IsItemBeginsGroup(item))
7326    return null;
7327  }
7328  return null;
7329 },
7330 GetNextVisibleItemInGroup: function(parent, index, skipItemsInAdaptiveMenu) {
7331  for(var i = index + 1; i < parent.GetItemCount(); i++) {
7332   var item = parent.GetItem(i);
7333   if(this.IsItemBeginsGroup(item))
7334    return null;
7335   if(item.GetVisible() && !this.IsAdaptiveItem(item.indexPath) && (!skipItemsInAdaptiveMenu || !this.IsItemInAdaptiveMenu(item)))
7336    return item;
7337  }
7338  return null;
7339 },
7340 HasNextVisibleItemInGroup: function(parent, index, skipItemsInAdaptiveMenu) {
7341  return !!this.GetNextVisibleItemInGroup(parent, index, skipItemsInAdaptiveMenu);
7342 },
7343 IsItemBeginsGroup: function(item) {
7344  var itemSeparator = this.GetItemSeparatorElement(item.GetIndexPath());
7345  return itemSeparator && ASPx.ElementContainsCssClass(itemSeparator, this.get
7345SeparatorCssClass());
7346 },
7347 getSeparatorCssClass: function() {
7348  return MenuCssClasses.Separator;
7349 },
7350 getAdaptiveMenuItemCssClass: function() {
7351  return MenuCssClasses.AdaptiveMenuItem;
7352 },
7353 getAdaptiveMenuItemSpacingCssClass: function() {
7354  return MenuCssClasses.AdaptiveMenuItemSpacing;
7355 },
7356 getAdaptiveMenuCssClass: function() {
7357  return MenuCssClasses.AdaptiveMenu;
7358 },
7359 IsItemInAdaptiveMenu: function(item) {
7360  return this.enableAdaptivity ? this.renderHelper.IsItemInAdaptiveMenu(item.index) : false;
7361 },
7362 HasVisibleItems: function(parent) {
7363  for(var i = 0; i < parent.GetItemCount() ; i++) {
7364   if(parent.GetItem(i).GetVisible())
7365    return true;
7366  }
7367  return false;
7368 },
7369 HasNextVisibleItems: function(parent, index, skipItemsInAdaptiveMenu) {
7370  for(var i = index + 1; i < parent.GetItemCount() ; i++) {
7371   var item = parent.GetItem(i);
7372   if(item.GetVisible() && (!skipItemsInAdaptiveMenu || !this.IsItemInAdaptiveMenu(item)))
7373    return true;
7374  }
7375  return false;
7376 },
7377 HasPrevVisibleItems: function(parent, index, skipItemsInAdaptiveMenu) {
7378  for(var i = index - 1; i >= 0; i--) {
7379   var item = parent.GetItem(i);
7380   if(item.GetVisible() && (!skipItemsInAdaptiveMenu || !this.IsItemInAdaptiveMenu(item)))
7381    return true;
7382  }
7383  return false;
7384 },
7385 NeedCollapseControlCore: function() {
7386  return this.enableAdaptivity || ASPxClientControl.prototype.NeedCollapseControlCore.call(this);
7387 },
7388 GetItemIndentElement: function(indexPath) {
7389  return ASPx.GetElementById(this.GetItemIndentElementId(indexPath));
7390 },
7391 GetItemSeparatorElement: function(indexPath) {
7392  return ASPx.GetElementById(this.GetItemSeparatorElementId(indexPath));
7393 },
7394 CreateItemClickEventArgs: function(processOnServer, item, htmlElement, htmlEvent) {
7395  return new ASPxClientMenuItemClickEventArgs(processOnServer, item, htmlElement, htmlEvent);
7396 },
7397 CreateItemMouseEventArgs: function(item, htmlElement) {
7398  return new ASPxClientMenuItemMouseEventArgs(item, htmlElement);
7399 },
7400 CreateItemEventArgs: function(item) {
7401  return new ASPxClientMenuItemEventArgs(item);
7402 },
7403 RaiseItemClick: function(indexPath, htmlEvent) {
7404  var processOnServer = this.autoPostBack || this.IsServerEventAssigned("ItemClick");
7405  if(!this.ItemClick.IsEmpty()) {
7406   var item = this.GetItemByIndexPath(indexPath);
7407   var htmlElement = this.GetItemElement(indexPath);
7408   var args = this.CreateItemClickEventArgs(processOnServer, item, htmlElement, htmlEvent);
7409   this.ItemClick.FireEvent(this, args);
7410   processOnServer = args.processOnServer;
7411  }
7412  return processOnServer;
7413 },
7414 RaiseItemMouseOver: function(indexPath) {
7415  if(!this.ItemMouseOver.IsEmpty()) {
7416   var item = this.GetItemByIndexPath(indexPath);
7417   var htmlElement = this.GetItemContentElement(indexPath);
7418   var args = this.CreateItemMouseEventArgs(item, htmlElement);
7419   this.ItemMouseOver.FireEvent(this, args);
7420  }
7421 },
7422 RaiseItemMouseOut: function(indexPath) {
7423  if(!this.ItemMouseOut.IsEmpty()) {
7424   var item = this.GetItemByIndexPath(indexPath);
7425   var htmlElement = this.GetItemContentElement(indexPath);
7426   var args = this.CreateItemMouseEventArgs(item, htmlElement);
7427   this.ItemMouseOut.FireEvent(this, args);
7428  }
7429 },
7430 RaisePopUp: function(indexPath) {
7431  var item = this.GetItemByIndexPath(indexPath);
7432  if(!this.PopUp.IsEmpty()) {
7433   var args = this.CreateItemEventArgs(item);
7434   this.inPopUpHandler = true;
7435   this.PopUp.FireEvent(this, args);
7436   this.inPopUpHandler = false;
7437   this.postponedSetItemVisible();
7438  }
7439 },
7440 RaiseCloseUp: function(indexPath) {
7441  var item = this.GetItemByIndexPath(indexPath);
7442  if(!this.CloseUp.IsEmpty()) {
7443   var args = this.CreateItemEventArgs(item);
7444   this.CloseUp.FireEvent(this, args);
7445  }
7446 },
7447 SetEnabled: function(enabled) {
7448  for(var i = this.GetItemCount() - 1; i >= 0; i--) {
7449   var item = this.GetItem(i);
7450   item.SetEnabled(enabled);
7451  }
7452 },
7453 SetVisible: function(visible) {
7454  ASPxClientControl.prototype.SetVisible.call(this, visible);
7455  if(visible && !this.HasVisibleItems(this))
7456   ASPx.SetElementDisplay(this.GetMainElement(), false);
7457 },
7458 GetItemCount: function() {
7459  return (this.rootItem != null) ? this.rootItem.GetItemCount() : 0;
7460 },
7461 GetItem: function(index) {
7462  return (this.rootItem != null) ? this.rootItem.GetItem(index) : null;
7463 },
7464 GetItemByName: function(name) {
7465  return (this.rootItem != null) ? this.rootItem.GetItemByName(name) : null;
7466 },
7467 GetSelectedItem: function() {
7468  var indexPath = this.GetSelectedItemIndexPath();
7469  if(indexPath != "")
7470   return this.GetItemByIndexPath(indexPath);
7471  return null;
7472 },
7473 SetSelectedItem: function(item) {
7474  var indexPath = (item != null) ? item.GetIndexPath() : "";
7475  this.SetSelectedItemInternal(indexPath, false);
7476 },
7477 GetRootItem: function() {
7478  return this.rootItem;
7479 }
7480});
7481ASPxClientMenuBase.GetMenuCollection = function() {
7482 return aspxGetMenuCollection();
7483};
7484var ASPxMenuKeyboardHelper = ASPx.CreateClass(null, {
7485 constructor: function(menu) {
7486  this.menu = menu;
7487  this.accessibilityCompliant = menu.accessibilityCompliant;
7488  this.isContextMenu = menu.isContextMenu;
7489  this.rtl = menu.rtl;
7490 },
7491 OnFocusedItemKeyDown: function(evt, focusedItem) {
7492  var indexPath = this.menu.GetItemIndexPathById(focusedItem.name);
7493  if(!this.IsAllowedItemAction(evt, focusedItem.enabled, indexPath))
7494   ASPx.Evt.PreventEventAndBubble(evt);
7495  else
7496   this.OnFocusedItemKeyDownInternal(evt, indexPath);
7497 },
7498 OnFocusedItemKeyDownInternal: function(evt, indexPath) {
7499  if(!indexPath)
7500   return;
7501  var keyCode = ASPx.Evt.GetKeyCode(evt);
7502  switch(keyCode) {
7503   case ASPx.Key.Tab:
7504    this.OnTab(indexPath, evt);
7505    break;
7506   case ASPx.Key.Down:
7507    this.OnArrowDown(indexPath, evt);
7508    break;
7509   case ASPx.Key.Up:
7510    this.OnArrowUp(indexPath, evt);
7511    break;
7512   case ASPx.Key.Left:
7513    if(this.rtl)
7514     this.OnArrowRight(indexPath, evt);
7515    else
7516     this.OnArrowLeft(indexPath, evt);
7517    break;
7518   case ASPx.Key.Right:
7519    if(this.rtl)
7520     this.OnArrowLeft(indexPath, evt);
7521    else
7522     this.OnArrowRight(indexPath, evt);
7523    break;
7524   case ASPx.Key.Esc:
7525    this.OnEscape(indexPath, evt);
7526    break;
7527   case ASPx.Key.Space: break;
7528   case ASPx.Key.Enter: break;
7529   case ASPx.Key.Shift: break;
7530   case ASPx.Key.Alt: break;
7531   case ASPx.Key.Ctrl: break;
7532   default:
7533    ASPx.Evt.PreventEventAndBubble(evt);
7534    break;
7535  }
7536 },
7537 OnTab: function(indexPath, evt) {
7538  var isRootItem = this.IsRootItem(indexPath);
7539  if(isRootItem && !this.accessibilityCompliant) return;
7540  if(this.IsLostFocus(indexPath, evt))
7541   this.menu.ProcessLostFocus(evt);
7542  else
7543   this.ProcessTab(indexPath, evt);
7544 },
7545 ProcessTab: function(indexPath, evt) {
7546  if(this.IsRootItem(indexPath))
7547   this.FocusRootItem(indexPath, evt);
7548  else
7549   this.FocusSubmenuItem(indexPath, evt);
7550 },
7551 OnArrowDown: function(indexPath, evt) {
7552  if(this.menu.IsVertical(indexPath))
7553   this.FocusNextItem(indexPath);
7554  else
7555   this.ShowSubMenuAccessible(indexPath);
7556  ASPx.Evt.PreventEventAndBubble(evt);
7557 },
7558 OnArrowUp: function(indexPath, evt) {
7559  if(this.menu.IsVertical(indexPath))
7560   this.FocusPrevItem(indexPath);
7561  else
7562   this.ShowSubMenuAccessible(indexPath);
7563  ASPx.Evt.PreventEventAndBubble(evt);
7564 },
7565 OnArrowLeft: function(indexPath, evt) {
7566  var isVertical = this.menu.IsVertical(indexPath);
7567  if(isVertical) {
7568   var isRootItem = this.IsRootItem(indexPath);
7569   if(isRootItem)
7570    this.FocusPrevItem(indexPath);
7571   else
7572    this.FocusItemByIndexPathAccessible(this.GetLeftParentIndexPath(indexPath));
7573  } else
7574   this.FocusPrevItem(indexPath);
7575  ASPx.Evt.PreventEventAndBubble(evt);
7576 },
7577 OnArrowRight: function(indexPath, evt) {
7578  var isVertical = this.menu.IsVertical(indexPath);
7579  if(isVertical) {
7580   var hasChildren = this.menu.HasChildren(indexPath);
7581   if(hasChildren)
7582    this.ShowSubMenuAccessible(indexPath);
7583   else
7584    this.FocusItemByIndexPathAccessible(this.GetRightRootParentIndexPath(indexPath));
7585  }
7586  else
7587   this.FocusNextItem(indexPath);
7588  ASPx.Evt.PreventEventAndBubble(evt);
7589 },
7590 OnEscape: function(indexPath, evt) {
7591  var needPreventEvent = true;
7592  if(this.IsRootItem(indexPath)) {
7593   aspxGetMenuCollection().DoHidePopupMenus(null, -1, this.name, false, "");
7594   this.menu.ProcessLostFocus(evt);
7595  }
7596  else {
7597   var parentIndexPath = this.menu.GetParentIndexPath(indexPath);
7598   this.FocusItemByIndexPathAccessible(parentIndexPath);
7599   var element = this.menu.GetMenuElement(parentIndexPath);
7600   if(element != null)
7601    this.menu.DoHidePopupMenu(null, element);
7602   else
7603    needPreventEvent = false;
7604  }
7605  if(needPreventEvent)
7606   ASPx.Evt.PreventEventAndBubble(evt);
7607 },
7608 IsLostFocus: function(indexPath, evt) {
7609  var keyCode = ASPx.Evt.GetKeyCode(evt);
7610  var isRootItem = this.IsRootItem(indexPath); 
7611  if(keyCode !== ASPx.Key.Tab || !isRootItem)
7612   return false;
7613  var canPrevItemGetFocus = evt.shiftKey && this.GetPrevSiblingIndexPath(indexPath);
7614  var canNextItemGetFocus = !evt.shiftKey && this.GetNextSiblingIndexPath(indexPath);
7615  return !canPrevItemGetFocus && !canNextItemGetFocus;
7616 },
7617 FocusRootItem: function(indexPath, evt) {
7618  if(evt.shiftKey)
7619   this.FocusPrevItem(indexPath, evt);
7620  else
7621   this.FocusNextItem(indexPath, evt);
7622  var isFocusElementChanged = ASPx.Evt.GetEventSource(evt) !== document.activeElement;
7623  if(isFocusElementChanged)
7624   ASPx.Evt.PreventEventAndBubble(evt);
7625 },
7626 FocusSubmenuItem: function(indexPath, evt) {
7627  if(evt.shiftKey)
7628   this.FocusPreviousSubmenuItem(indexPath, evt);
7629  else
7630   this.FocusNextSubmenuItem(indexPath, evt);
7631 },
7632 FocusPreviousSubmenuItem: function(indexPath, evt) {
7633  if(!this.GetPrevSiblingIndexPath(indexPath)) {
7634   var parentIndexPath = this.menu.GetParentIndexPath(indexPath);
7635   this.FocusItemByIndexPathAccessible(parentIndexPath);
7636  } else
7637   this.FocusPrevItem(indexPath);
7638  ASPx.Evt.PreventEventAndBubble(evt);
7639 },
7640 FocusNextSubmenuItem: function(indexPath, evt) {
7641  var nextIndexPath = this.GetNextIndexPath(indexPath);
7642  if(nextIndexPath) {
7643   var isLevelChanged = this.IsLevelChanged(indexPath, nextIndexPath);
7644   this.FocusItemCore(nextIndexPath, isLevelChanged); 
7645   ASPx.Evt.PreventEventAndBubble(evt);
7646  } else
7647   this.menu.ProcessLostFocus(evt);
7648 },
7649 GetNextIndexPath: function(indexPath) {
7650  var result = this.GetNextSiblingIndexPath(indexPath);
7651  if(!result) {
7652   var parentIndexPath = this.menu.GetParentIndexPath(indexPath);
7653   if(parentIndexPath)
7654    result = this.GetNextIndexPath(parentIndexPath);
7655  }
7656  return result;
7657 },
7658 GetRightRootParentIndexPath: function(indexPath) {
7659  var parentIndexPath = this.GetParentRootIndexPath(indexPath);
7660  return this.GetNextFocusableItemIndexPath(parentIndexPath);
7661 },
7662 GetLeftParentIndexPath: function(indexPath) {
7663  var parentIndexPath = this.menu.GetParentIndexPath(indexPath);
7664  if(!this.menu.IsVertical(parentIndexPath))
7665   parentIndexPath = this.GetPrevFocusableItemIndexPath(parentIndexPath);
7666  return parentIndexPath;
7667 },
7668 GetParentRootIndexPath: function(indexPath) {
7669  while(!this.IsRootItem(indexPath))
7670   indexPath = this.menu.GetParentIndexPath(indexPath);
7671  return indexPath;
7672 },
7673 ShowSubMenuAccessible: function(indexPath) {
7674  var newIndexPath = this.GetFirstChildIndexPath(indexPath),
7675   element = this.menu.GetMenuElement(indexPath);
7676  if(element && !this.menu.isSubMenuElementVisible(element))
7677   this.menu.ShowSubMenu(indexPath);
7678  if(!!newIndexPath)
7679   this.FocusItemByIndexPathAccessible(newIndexPath);
7680 },
7681 FocusItemByIndexPathAccessible: function(indexPath) {
7682  this.FocusItemCore(indexPath, true);
7683 },
7684 IsAllowedItemAction: function(evt, isEnabled, indexPath) {
7685  var isVertical = this.menu.IsVertical(indexPath);
7686  return !this.accessibilityCompliant ||
7687      isEnabled ||
7688      this.IsAllowedFocusMoving(evt) ||
7689      this.IsAllowedHorizontalFocusMoving(evt, isVertical) ||
7690      this.IsAllowedVerticalFocusMoving(evt, isVertical);
7691 },
7692 IsAllowedFocusMoving: function(evt) {
7693  return evt.keyCode == ASPx.Key.Tab || evt.keyCode == ASPx.Key.Esc;
7694 },
7695 IsAllowedHorizontalFocusMoving: function(evt, isVertical) {
7696  return !isVertical && (evt.keyCode == ASPx.Key.Left || evt.keyCode == ASPx.Key.Right);
7697 },
7698 IsAllowedVerticalFocusMoving: function(evt, isVertical) {
7699  return isVertical && (evt.keyCode == ASPx.Key.Up || evt.keyCode == ASPx.Key.Down);
7700 },
7701 FocusItemByIndexPath: function(indexPath) {
7702  var link = this.menu.GetLinkElementByIndexPath(indexPath);
7703  if(link != null) {
7704   if(this.accessibilityCompliant && !link.href)
7705    link.href = ASPx.AccessibilityEmptyUrl;
7706   ASPx.SetFocus(link);
7707  } else
7708   this.FocusTemplateItemActionElement(indexPath);
7709 },
7710 FocusTemplateItemActionElement: function(indexPath) {
7711  var element = this.menu.GetItemElement(indexPath);
7712  var focusableElement = ASPx.FindFirstChildActionElement(element);
7713  if(focusableElement)
7714   ASPx.SetFocus(focusableElement);
7715  else {
7716   var parentIndexPath = this.menu.GetParentIndexPath(indexPath);
7717   this.tryFocusColorPickerByIndexPath(parentIndexPath);
7718  }
7719 },
7720 tryFocusColorPickerByIndexPath: function(indexPath) {
7721  var colorPicker = this.getColorPickerByIndexPath(indexPath);
7722  if(colorPicker)
7723   colorPicker.Focus();
7724 },
7725 getColorPickerByIndexPath: function(indexPath) {
7726  var menuItem = this.menu.GetItemByIndexPath(indexPath);
7727  return menuItem.colorPicker;
7728 },
7729 PronounceItemDescription: function(indexPath) {
7730  var link = this.menu.GetLinkElementByIndexPath(indexPath);
7731  var span = ASPx.GetNodeByTagName(link, "SPAN", 0);
7732  if(!link) return;
7733  if(!!span && !span.id) {
7734   var spanID = this.GetAccessibilityTextSpanID(indexPath);
7735   span.id = spanID;
7736   ASPx.Attr.SetAttribute(link, "aria-describedby", spanID);
7737  }
7738  ASPx.Attr.SetAttribute(link, "aria-label", this.GetAccessibilityItemDescription(indexPath));
7739 },
7740 RemoveAccessibilityDescription: function(indexPath) {
7741  var link = this.menu.GetLinkElementByIndexPath(indexPath);
7742  if(link && ASPx.Attr.GetAttribute(link, "aria-label"))
7743   ASPx.Attr.RemoveAttribute(link, "aria-label");
7744 },
7745 GetAccessibilityTextSpanID: function(indexPath) {
7746  return this.name + Constants.ATSIdSuffix + indexPath;
7747 },
7748 GetAccessibilityItemDescription: function(indexPath) {
7749  var descriptionParts = [];
7750  descriptionParts.push(this.menu.IsVertical(indexPath) ? ASPx.AccessibilitySR.MenuVerticalText : ASPx.AccessibilitySR.MenuHorizontalText);
7751  descriptionParts.push(this.IsRootItem(indexPath) ? ASPx.AccessibilitySR.MenuBarText : ASPx.AccessibilitySR.MenuText);
7752  descriptionParts.push(this.menu.GetMenuLevel(indexPath));
7753  descriptionParts.push(ASPx.AccessibilitySR.MenuLevelText);
7754  return descriptionParts.join(' ');
7755 },
7756 FocusNextItem: function(indexPath) {
7757  var newIndexPath = this.GetNextFocusableItemIndexPath(indexPath);
7758  if(newIndexPath)
7759   this.FocusItemCore(newIndexPath, false);
7760 },
7761 FocusPrevItem: function(indexPath) {
7762  var newIndexPath = this.GetPrevFocusableItemIndexPath(indexPath);
7763  if(newIndexPath)
7764   this.FocusItemCore(newIndexPath, false);
7765 },
7766 FocusItemCore: function(indexPath, needDescription) {
7767  if(this.accessibilityCompliant) {
7768   if(needDescription)
7769    this.PronounceItemDescription(indexPath);
7770   else
7771    this.RemoveAccessibilityDescription(indexPath);
7772  }
7773  this.FocusItemByIndexPath(indexPath);
7774 },
7775 GetNextFocusableItemIndexPath: function(indexPath) {
7776  var newIndexPath = this.GetNextSiblingIndexPath(indexPath);
7777  if(newIndexPath == null)
7778   newIndexPath = this.GetFirstSiblingIndexPath(indexPath);
7779  if(indexPath != newIndexPath)
7780   return newIndexPath;
7781 },
7782 GetPrevFocusableItemIndexPath: function(indexPath) {
7783  var newIndexPath = this.GetPrevSiblingIndexPath(indexPath);
7784  if(newIndexPath == null)
7785   newIndexPath = this.GetLastSiblingIndexPath(indexPath);
7786  if(indexPath != newIndexPath)
7787   return newIndexPath;
7788 },
7789 GetFirstChildIndexPath: function(indexPath) {
7790  var indexes = this.menu.GetItemIndexes(indexPath);
7791  indexes[indexes.length] = 0;
7792  var newIndexPath = this.menu.GetItemIndexPath(indexes);
7793  return this.GetFirstSiblingIndexPath(newIndexPath);
7794 },
7795 GetFirstSiblingIndexPath: function(indexPath) {
7796  var indexes = this.menu.GetItemIndexes(indexPath);
7797  var i = 0;
7798  while(true) {
7799   indexes[indexes.length - 1] = i;
7800   var newIndexPath = this.menu.GetItemIndexPath(indexes);
7801   if(!this.IsItemExist(newIndexPath))
7802    return null;
7803   if(this.IsFocusableItem(newIndexPath))
7804    return newIndexPath;
7805   i++;
7806  }
7807  return null;
7808 },
7809 GetLastSiblingIndexPath: function(indexPath) {
7810  var indexes = this.menu.GetItemIndexes(indexPath);
7811  var parentItem = this.menu.GetItemByIndexPath(this.menu.GetParentIndexPath(indexPath));
7812  var i = parentItem ? parentItem.GetItemCount() - 1 : 0;
7813  while(true) {
7814   indexes[indexes.length - 1] = i;
7815   var newIndexPath = this.menu.GetItemIndexPath(indexes);
7816   if(!this.IsItemExist(newIndexPath))
7817    return null;
7818   if(this.IsFocusableItem(newIndexPath))
7819    return newIndexPath;
7820   i--;
7821  }
7822  return null;
7823 },
7824 GetNextSiblingIndexPath: function(indexPath) {
7825  if(this.menu.IsLastItem(indexPath)) return null;
7826  var indexes = this.menu.GetItemIndexes(indexPath);
7827  var i = indexes[indexes.length - 1] + 1;
7828  while(true) {
7829   indexes[indexes.length - 1] = i;
7830   var newIndexPath = this.menu.GetItemIndexPath(indexes);
7831   if(!this.IsItemExist(newIndexPath))
7832    return null;
7833   if(this.IsFocusableItem(newIndexPath))
7834    return newIndexPath;
7835   i++;
7836  }
7837  return null;
7838 },
7839 GetPrevSiblingIndexPath: function(indexPath) {
7840  if(this.menu.IsFirstItem(indexPath)) return null;
7841  var indexes = this.menu.GetItemIndexes(indexPath);
7842  var i = indexes[indexes.length - 1] - 1;
7843  while(true) {
7844   indexes[indexes.length - 1] = i;
7845   var newIndexPath = this.menu.GetItemIndexPath(indexes);
7846   if(!this.IsItemExist(newIndexPath))
7847    return null;
7848   if(this.IsFocusableItem(newIndexPath))
7849    return newIndexPath;
7850   i--;
7851  }
7852  return null;
7853 },
7854 IsItemExist: function(indexPath) {
7855  return !!this.menu.GetItemByIndexPath(indexPath);
7856 },
7857 IsItemVisible: function(indexPath) {
7858  var item = this.menu.GetItemByIndexPath(indexPath);
7859  return item ? item.GetVisible() : false;
7860 },
7861 IsFocusableItem: function(indexPath) {
7862  return this.IsItemVisible(indexPath) && (this.menu.IsItemEnabled(indexPath) || this.IsItemAccessibleEnabled(indexPath));
7863 },
7864 IsRootItem: function(indexPath) {
7865  return this.menu.IsRootItem(indexPath);
7866 },
7867 IsItemAccessibleEnabled: function(indexPath) {
7868  var item = this.menu.GetItemByIndexPath(indexPath);
7869  return this.accessibilityCompliant && item && item.enabled;
7870 },
7871 IsLevelChanged: function(firstIndexPath, secondIndexPath) {
7872  return this.menu.GetMenuLevel(firstIndexPath) !== this.menu.GetMenuLevel(secondIndexPath);
7873 }
7874});
7875var ASPxClientMenuCollection = ASPx.CreateClass(ASPxClientControlCollection, {
7876 constructor: function() {
7877  this.constructor.prototype.constructor.call(this);
7878  this.appearTimerID = -1;
7879  this.disappearTimerID = -1;
7880  this.currentShowingPopupMenuName = null;
7881  this.visibleSubMenusMenuName = "";
7882  this.visibleSubMenuIds = [];
7883  this.overXPos = -1;
7884  this.overYPos = -1;
7885 },
7886 GetCollectionType: function(){
7887  return "Menu";
7888 },
7889 Remove: function(element) {
7890  if(element.name === this.visibleSubMenusMenuName) {
7891   this.visibleSubMenusMenuName = "";
7892   this.visibleSubMenuIds = [ ];
7893  }
7894  ASPxClientControlCollection.prototype.Remove.call(this, element);
7895 },
7896 RegisterVisiblePopupMenu: function(name, id) {
7897  this.visibleSubMenuIds.push(id);
7898  this.visibleSubMenusMenuName = name;
7899 },
7900 UnregisterVisiblePopupMenu: function(name, id) {
7901  ASPx.Data.ArrayRemove(this.visibleSubMenuIds, id);
7902  if(this.visibleSubMenuIds.length == 0)
7903   this.visibleSubMenusMenuName = "";
7904 },
7905 IsSubMenuVisible: function(subMenuId) {
7906  for(var i = 0; i < this.visibleSubMenuIds.length; i++) {
7907   if(this.visibleSubMenuIds[i] == subMenuId)
7908    return true;
7909  }
7910  return false;
7911 },
7912 GetMenu: function(id) {
7913  return this.Get(this.GetMenuName(id));
7914 },
7915 GetMenuName: function(id) {
7916  return this.GetMenuNameBySuffixes(id, [Constants.MMIdSuffix, Constants.MIIdSuffix]);
7917 },
7918 GetMenuNameBySuffixes: function(id, idSuffixes) {
7919  for(var i = 0; i < idSuffixes.length; i++) {
7920   var pos = id.lastIndexOf(idSuffixes[i]);
7921   if(pos > -1)
7922    return id.substring(0, pos);
7923  }
7924  return id;
7925 },
7926 ClearCurrentShowingPopupMenuName: function() {
7927  this.SetCurrentShowingPopupMenuName(null);
7928 },
7929 SetCurrentShowingPopupMenuName: function(value) {
7930  this.currentShowingPopupMenuName = value;
7931 },
7932 NowPopupMenuIsShowing: function() {
7933  return this.currentShowingPopupMenuName != null;
7934 },
7935 GetMenuLevelById: function(id) {
7936  var indexPath = this.GetIndexPathById(id, Constants.MMIdSuffix);
7937  var menu = this.GetMenu(id);
7938  return menu.GetMenuLevel(indexPath);
7939 },
7940 GetIndexPathById: function(id, idSuffix) {
7941  var pos = id.lastIndexOf(idSuffix);
7942  if(pos > -1) {
7943   id = id.substring(pos + idSuffix.length);
7944   pos = id.lastIndexOf("_");
7945   if(pos > -1)
7946    return id.substring(0, pos);
7947  }
7948  return "";
7949 },
7950 GetItemIndexPath: function(indexes) {
7951  var indexPath = "";
7952  for(var i = 0; i < indexes.length; i++) {
7953   indexPath += indexes[i];
7954   if(i < indexes.length - 1)
7955    indexPath += ASPx.ItemIndexSeparator;
7956  }
7957  return indexPath;
7958 },
7959 GetItemIndexes: function(indexPath) {
7960  var indexes = indexPath.split(ASPx.ItemIndexSeparator);
7961  for(var i = 0; i < indexes.length; i++)
7962   indexes[i] = parseInt(indexes[i]);
7963  return indexes;
7964 },
7965 ClearAppearTimer: function() {
7966  this.appearTimerID = ASPx.Timer.ClearTimer(this.appearTimerID);
7967 },
7968 ClearDisappearTimer: function() {
7969  this.disappearTimerID = ASPx.Timer.ClearTimer(this.disappearTimerID);
7970 },
7971 IsAppearTimerActive: function() {
7972  return this.appearTimerID > -1;
7973 },
7974 IsDisappearTimerActive: function() {
7975  return this.disappearTimerID > -1;
7976 },
7977 SetAppearTimer: function(name, indexPath, timeout, preventSubMenu) {
7978  var menu = aspxGetMenuCollection().Get(name);
7979  if(menu && !menu.sideMenuModeOn)
7980   this.appearTimerID = window.setTimeout(function() {
7981    var menu = aspxGetMenuCollection().Get(name);
7982    if(menu != null) menu.OnItemOverTimer(indexPath, preventSubMenu);
7983   }, timeout);
7984 },
7985 SetDisappearTimer: function(name, timeout) {
7986  var menu = aspxGetMenuCollection().Get(name);
7987  if(menu && !menu.sideMenuModeOn)
7988   this.disappearTimerID = window.setTimeout(function() {
7989    var menu = aspxGetMenuCollection().Get(name);
7990    if(menu != null)
7991     menu.OnItemOutTimer();
7992   }, timeout);
7993 },
7994 GetMouseDownMenuLevel: function(evt) {
7995  var srcElement = ASPx.Evt.GetEventSource(evt);
7996  for(var i = this.visibleSubMenuIds.length - 1; i >= 0; i--) {
7997   var element = ASPx.GetParentById(srcElement, this.visibleSubMenuIds[i]);
7998   var menu = this.GetMenu(this.visibleSubMenuIds[i]); 
7999   if(element != null || srcElement == menu.mainElement)
8000    return this.GetMenuLevelById(this.visibleSubMenuIds[i]) + 1;
8001  }
8002  if(this.visibleSubMenusMenuName != "") {
8003   var element = ASPx.GetParentById(srcElement, this.visibleSubMenusMenuName);
8004   if(element != null) return 1;
8005  }
8006  if(ASPx.GetParentByClassName(srcElement, MenuCssClasses.AdaptiveMenuItem))
8007   return 1;
8008  return -1;
8009 },
8010 CheckFocusedElement: function() {
8011  var isValid = false;
8012  try {
8013   var activeElement = document.activeElement;
8014   if(activeElement != null) {
8015    for(var i = 0; i < this.visibleSubMenuIds.length; i++) {
8016     var menuElement = ASPx.GetElementById(this.visibleSubMenuIds[i]);
8017     if(menuElement != null && ASPx.GetIsParent(menuElement, activeElement)) {
8018      var tagName = activeElement.tagName;
8019      if(tagName != "A" || 
8020         !ASPx.ElementHasCssClass(activeElement, MenuCssClasses.ContentContainer) || 
8021         this.GetMenu(this.visibleSubMenusMenuName).accessibilityCompliant)
8022          isValid = true;
8023      break;
8024     }
8025    }
8026   }
8027  } catch (e) {
8028  }
8029  return isValid;
8030 },
8031 LockMenusVisibility: function() {
8032  this.visibilityLocked = true;
8033  this.visibilityLockedIds = [];
8034  for(var i = this.visibleSubMenuIds.length - 1; i >= 0 ; i--)
8035   this.visibilityLockedIds.push(this.visibleSubMenuIds[i]);
8036 },
8037 UnlockMenusVisibility: function() {
8038  this.visibilityLocked = false;
8039  this.visibilityLockedIds = [];
8040 },
8041 CanHideSubMenu: function(subMenuId) {
8042  return !this.visibilityLocked || this.visibilityLocked && this.visibilityLockedIds.indexOf(subMenuId) > -1;
8043 },
8044 DoHidePopupMenus: function(evt, level, name, leavePopups, exceptIds) {
8045  exceptIds = typeof exceptIds === 'string' ? [exceptIds] : (exceptIds || []);
8046  for(var i = this.visibleSubMenuIds.length - 1; i >= 0 ; i--) {
8047   var subMenuId = this.visibleSubMenuIds[i];
8048   if(this.CanHideSubMenu(subMenuId)) {
8049    var menu = this.GetMenu(subMenuId);
8050    if(menu != null && !menu.sideMenuModeOn) {
8051     var menuLevel = this.GetMenuLevelById(subMenuId);
8052     if((!leavePopups || menuLevel > 0) && ASPx.Data.ArrayIndexOf(exceptIds, subMenuId) === -1) {
8053      if(menuLevel > level || (menu.name != name && name != "")) {
8054       var element = ASPx.GetElementById(subMenuId);
8055       if(element != null)
8056        menu.DoHidePopupMenu(evt, element);
8057      }
8058     }
8059    }
8060   }
8061  }
8062 },
8063 DoShowAtCurrentPos: function(name, indexPath) {
8064  var pc = this.Get(name);
8065  var element = pc.GetMainElement();
8066  if(pc != null && !ASPx.GetElementDisplay(element))
8067   pc.DoShowPopupMenu(element, this.overXPos, this.overYPos, indexPath);
8068 },
8069 SaveCurrentMouseOverPos: function(evt, popupElement) {
8070  if(!this.NowPopupMenuIsShowing()) return;
8071  var currentShowingPopupMenu = this.Get(this.currentShowingPopupMenuName);
8072  if(currentShowingPopupMenu.popupElement == popupElement)
8073   if(!currentShowingPopupMenu.IsMenuVisible()) {
8074    this.overXPos = ASPx.Evt.GetEventX(evt);
8075    this.overYPos = ASPx.Evt.GetEventY(evt);
8076   }
8077 },
8078 OnMouseDown: function(evt) {
8079  var menuLevel = this.GetMouseDownMenuLevel(evt);
8080  this.DoHidePopupMenus(evt, menuLevel, "", false, "");
8081  if (ASPx.Browser.TouchUI && menuLevel == -1) 
8082   ASPx.SetHoverState(null);
8083 },
8084 RecalculateAll: function() {
8085  var visibleSubMenusLength = this.visibleSubMenuIds.length;
8086  for(var i = 0; i < visibleSubMenusLength; i++) {
8087   var menu = this.GetMenu(this.visibleSubMenuIds[i]);
8088   if(menu != null) {
8089    var element = ASPx.GetElementById(this.visibleSubMenuIds[i]);
8090    if(element != null) {
8091     var indexPath = this.GetIndexPathById(this.visibleSubMenuIds[i], Constants.MMIdSuffix);
8092     menu.CalculateSubMenuPosition(element, ASPx.InvalidPosition, ASPx.InvalidPosition, indexPath, false);
8093    }
8094   }
8095  }
8096 },
8097 HideAll: function() {
8098  this.DoHidePopupMenus(null, -1, "", false, "");
8099 },
8100 IsAnyMenuVisible: function() {
8101  return this.visibleSubMenuIds.length != 0;
8102 }
8103});
8104var menuCollection = null;
8105function aspxGetMenuCollection() {
8106 if(menuCollection == null)
8107  menuCollection = new ASPxClientMenuCollection();
8108 return menuCollection;
8109}
8110var ASPxClientMenuItem = ASPx.CreateClass(null, {
8111 constructor: function(menu, parent, index, name) {
8112  this.menu = menu;
8113  this.parent = parent;
8114  this.index = index;
8115  this.name = name;
8116  this.indexPath = "";
8117  this.text = "";
8118  this.imageUrl = "";
8119  this.imageClassName = "";
8120  this.tooltip = "";
8121  this.target = "";
8122  this.beginGroup = false;
8123  this.dropDownMode = false;
8124  if(parent) {
8125   this.indexPath = this.CreateItemIndexPath(parent);
8126  }
8127  this.enabled = true;
8128  this.clientEnabled = true;
8129  this.visible = true;
8130  this.clientVisible = true;
8131  this.items = [];
8132  this.colorPicker = null;
8133  this.checkedGroup = [];
8134  this.checked = false;
8135 },
8136 CreateItemIndexPath: function(parent) {
8137  return parent.indexPath ? parent.indexPath + ASPx.ItemIndexSeparator + this.index.toString() : this.index.toString();
8138 },
8139 ClearRenderedChildItems: function() {
8140  if(this.items.length > 0) {
8141   var parentNode = this.menu.GetItemElement(this.items[0].indexPath).parentNode;
8142   parentNode.innerHTML = "";
8143   this.items = [];
8144  }
8145 },
8146 CreateItems: function(itemsProperties) {
8147  for(var i = 0, len = itemsProperties.length; i < len; i++) {
8148   var itemProperties = itemsProperties[i],
8149    item = this.CreateItemInternal(itemProperties);
8150   if(itemProperties.items && itemProperties.items.length > 0)
8151    item.CreateItems(itemProperties.items);
8152  }
8153 },
8154 CreateItemInternal: function(itemProperties) {
8155  var itemName = itemProperties.name || "";
8156  var index = this.items.length;
8157  var itemType = this.menu.GetClientItemType();
8158  var item = new itemType(this.menu, this, index, itemName);
8159  if(ASPx.IsExists(itemProperties.text))
8160   item.text = itemProperties.text;
8161  if(ASPx.IsExists(itemProperties.imageUrl))
8162   item.imageUrl = itemProperties.imageUrl;
8163  if(ASPx.IsExists(itemProperties.imageHottrackSrc))
8164   item.imageHottrackSrc = itemProperties.imageHottrackSrc;
8165  if(ASPx.IsExists(itemProperties.imageClassName))
8166   item.imageClassName = itemProperties.imageClassName;
8167  if(ASPx.IsExists(itemProperties.navigateUrl))
8168   item.navigateUrl = itemProperties.navigateUrl;
8169  if(ASPx.IsExists(itemProperties.beginGroup))
8170   item.beginGroup = itemProperties.beginGroup;
8171  if(ASPx.IsExists(itemProperties.enabled) && !this.menu.NeedCreateItemsOnClientSide())
8172   item.enabled = itemProperties.enabled;
8173  if((ASPx.IsExists(itemProperties.clientEnabled) && !itemProperties.clientEnabled) || (ASPx.IsExists(itemProperties.enabled) && !itemProperties.enabled))
8174   item.clientEnabled = false;
8175  if(ASPx.IsExists(itemProperties.visible))
8176   item.visible = itemProperties.visible;
8177  if(ASPx.IsExists(itemProperties.clientVisible))
8178   item.clientVisible = itemProperties.clientVisible;
8179  if(ASPx.IsExists(itemProperties.groupName)) {
8180   this.menu.ProcessItemGroupName(item, itemProperties.groupName);
8181   item.checked = !!itemProperties.checked;
8182  }
8183  if(ASPx.IsExists(itemProperties.tooltip))
8184   item.tooltip = itemProperties.tooltip;
8185  if(ASPx.IsExists(itemProperties.target))
8186   item.target = itemProperties.target;
8187  if(ASPx.IsExists(itemProperties.dropDownMode))
8188   item.dropDownMode = itemProperties.dropDownMode;
8189  if(ASPx.IsExists(itemProperties.textTemplate))
8190   item.textTemplate = itemProperties.textTemplate;
8191  if(ASPx.IsExists(itemProperties.styles))
8192   item.styles = itemProperties.styles;
8193  if(ASPx.IsExists(itemProperties.isSvg))
8194   item.isSvg = itemProperties.isSvg;
8195  if(this.menu.NeedAppendToRenderData(item))
8196   this.menu.AppendToRenderData(this.indexPath, index);
8197  this.items.push(item);
8198  return item;
8199 },
8200 GetIndexPath: function() {
8201  return this.indexPath;
8202 },
8203 GetItemCount: function() {
8204  return this.items.length;
8205 },
8206 GetItem: function(index) {
8207  return (0 <= index && index < this.items.length) ? this.items[index] : null;
8208 },
8209 GetItemByName: function(name) {
8210  for(var i = 0; i < this.items.length; i++)
8211   if(this.items[i].name == name) return this.items[i];
8212  for(var i = 0; i < this.items.length; i++) {
8213   var item = this.items[i].GetItemByName(name);
8214   if(item != null) return item;
8215  }
8216  return null;
8217 },
8218 GetChecked: function() {
8219  var indexPath = this.GetIndexPath();
8220  return this.menu.IsCheckedItem(indexPath);
8221 },
8222 SetChecked: function(value) {
8223  var indexPath = this.GetIndexPath();
8224  this.menu.SetItemChecked(indexPath, value);
8225 },
8226 GetEnabled: function() {
8227  return this.enabled && this.clientEnabled;
8228 },
8229 SetEnabled: function(value) {
8230  if(this.clientEnabled != value) {
8231   this.clientEnabled = value;
8232   this.menu.SetItemEnabled(this.GetIndexPath(), value, false);
8233  }
8234 },
8235 GetImage: function() {
8236  return this.menu.GetItemImage(this.GetIndexPath());
8237 },
8238 GetImageUrl: function() {
8239  return this.menu.GetItemImageUrl(this.GetIndexPath());
8240 },
8241 SetImageUrl: function(value) {
8242  var indexPath = this.GetIndexPath();
8243  this.menu.SetItemImageUrl(indexPath, value);
8244 },
8245 GetNavigateUrl: function() {
8246  var indexPath = this.GetIndexPath();
8247  return this.menu.GetItemNavigateUrl(indexPath);
8248 },
8249 SetNavigateUrl: function(value) {
8250  var indexPath = this.GetIndexPath();
8251  this.menu.SetItemNavigateUrl(indexPath, value);
8252 },
8253 GetText: function() {
8254  var indexPath = this.GetIndexPath();
8255  return this.menu.GetItemText(indexPath);
8256 },
8257 SetText: function(value) {
8258  var indexPath = this.GetIndexPath();
8259  this.menu.SetItemText(indexPath, value);
8260 },
8261 GetVisible: function() {
8262  return this.visible && this.clientVisible;
8263 },
8264 SetVisible: function(value) {
8265  if(this.clientVisible != value) {
8266   this.setClientVisibleInternal(value);
8267   this.menu.SetItemVisible(this.GetIndexPath(), value, false);
8268  }
8269 },
8270 InitializeEnabledAndVisible: function(recursive) {
8271  this.menu.SetItemEnabled(this.GetIndexPath(), this.clientEnabled, true);
8272  this.menu.SetItemVisible(this.GetIndexPath(), this.clientVisible, true);
8273  if(recursive) {
8274   for(var i = 0; i < this.items.length; i++)
8275    this.items[i].InitializeEnabledAndVisible(recursive);
8276  }
8277 },
8278 setClientVisibleInternal: function(value) {
8279  this.menu.prepareSideMenuCssClasses(false);
8280  this.clientVisible = value;
8281  this.menu.prepareSideMenuCssClasses(true);
8282 },
8283 GetOwnProperties: function() {
8284  return {
8285   menuItem: this,
8286   focusableElement: this.GetFocusableElement()
8287  };
8288 },
8289 GetFocusableElement: function() {
8290  return this.menu.GetLinkElementByIndexPath(this.indexPath);
8291 }
8292});
8293var subMenuStack = function() {
8294 this.stack = [];
8295 this.hasItems = function() {
8296  return this.stack.length > 1;
8297 };
8298 this.count = function() {
8299  return this.stack.length;
8300 };
8301 this.last = function() {
8302  return this.stack[this.stack.length - 1].element;
8303 };
8304 this.push = function(element, text) {
8305  this.stack.push({element: element, text: text});
8306 };
8307 this.pop = function() {
8308  return this.stack.pop().element;
8309 };
8310 this.text = function() {
8311  return this.stack[this.stack.length - 1].text;
8312 };
8313};
8314var appearPanelAction = ASPx.CreateClass({
8315 constructor: function(menu) {
8316  this.menu = menu;
8317  this.expanded = false;
8318  this.cashedHtmlOverflow = '';
8319  this.bodyLeftMargin = 0;
8320  this.clearWidth = 0;
8321  this.animationInProgress = false;
8322  this.panel = this.menu.GetMainElement().parentNode;
8323  this.burgerButton = this.createBurgerButton();
8324  this.overlayPanel = this.createOverlayElement();
8325  this.afterCollapsePanel = new ASPxClientEvent();
8326  ASPx.Evt.AttachEventToElement(this.burgerButton, 'click', function() { this.toggleExpanded(); }.bind(this), true);
8327  ASPx.Evt.AttachEventToElement(this.overlayPanel, 'click', function() { this.toggleExpanded(); }.bind(this), true);
8328 },
8329 get isLeftPosition() {
8330  return this.menu.position == 'left';
8331 },
8332 createBurgerButton: function() {
8333  var button = document.createElement('DIV');
8334  button.className = BURGER_CLASS_NAME;
8335  if(!!this.menu.hamburgerClass)
8336   ASPx.AddClassNameToElement(button, this.menu.hamburgerClass);
8337  var line = document.createElement('DIV');
8338  button.appendChild(line);
8339  this.panel.parentNode.appendChild(button);
8340  return button;
8341 },
8342 createOverlayElement: function() {
8343  var panel = document.createElement('DIV');
8344  panel.className = OVERLAY_PANEL_CLASS_NAME;
8345  this.panel.parentNode.appendChild(panel);
8346  return panel;
8347 },
8348 toggleExpanded: function() {
8349  this.setExpanded(!this.getExpanded());
8350 },
8351 getExpanded: function() {
8352  return this.expanded;
8353 },
8354 setExpanded: function(value) {
8355  if(this.expanded != value && !this.isAnimationInProgress()) {
8356   this.expanded = value;
8357   this.setExpandedCore();
8358  }
8359 },
8360 setExpandedCore: function() {
8361  if(this.expanded) {
8362   this.prepareForAnimateIn();
8363   this.animateIn();
8364  }
8365  else
8366   this.animateOut();
8367 },
8368 collapse: function() {
8369  this.expanded = false;
8370  this.rollbackAfterAnimateOut();
8371 },
8372 isAnimationInProgress: function() {
8373  return !!this.animationInProgress;
8374 },
8375 prepareForAnimateIn: function() {
8376  this.prepareDocument();
8377  this.prepareOverlayPanel();
8378  this.prepareSlidePanel();
8379 },
8380 prepareDocument: function() {
8381  this.cashedHtmlOverflow = document.documentElement.style.overflow;
8382  document.documentElement.style.overflow = 'hidden';
8383 },
8384 prepareOverlayPanel: function() {
8385  ASPx.SetStyles(this.overlayPanel, {
8386   opacity: '0',
8387   zIndex: SIDE_MENU_ZINDEX_VALUE,
8388   display: 'block'
8389  });
8390  ASPx.SetStyles(this.overlayPanel, {
8391   marginLeft: -ASPx.GetAbsoluteX(this.overlayPanel),
8392   marginTop: -ASPx.GetAbsoluteY(this.overlayPanel),
8393  });
8394 },
8395 prepareSlidePanel: function() {
8396  ASPx.SetStyles(this.panel, { display: 'block', width: '100%', zIndex: SIDE_MENU_ZINDEX_VALUE + 1 });
8397  this.menu.AdjustControl();
8398  var size = this.menu.calculateMaxSize();
8399  this.clearWidth = size.width;
8400  var width = size.width;
8401  var overflowY = '';
8402  if(size.height > window.innerHeight) {
8403   overflowY = 'scroll';
8404   width = size.width + ASPx.GetVerticalScrollBarWidth();
8405  }
8406  ASPx.SetStyles(this.panel, { 
8407   className: this.panel.className + ' ' + SLIDE_PANEL_EXPANDED_CLASS_NAME,
8408   overflowY: overflowY,
8409   width: width
8410  });
8411 },
8412 createTransition: function(element, obj) {
8413  return transition = ASPx.AnimationHelper.createAnimationTransition(element, {
8414   property: obj.property, unit: obj.unit, duration: SLIDE_DURATION_VALUE, transition: ASPx.AnimationConstants.Transitions.POW_EASE_OUT, onComplete: obj.onComplete
8415  });
8416 },
8417 getInTransitions: function() {
8418  var arr = [];
8419  arr.push({
8420   trans: this.createTransition(this.panel, { property: this.isLeftPosition ? 'left' : 'right', unit: 'px' }),
8421   start: -this.panel.offsetWidth,
8422   end: 0
8423  });
8424  arr.push({
8425   trans: this.createTransition(this.overlayPanel, {
8426    property: 'opacity',
8427    onComplete: function() {
8428     this.animationInProgress = false;
8429    }.aspxBind(this)
8430   }),
8431   start: 0,
8432   end: 100
8433  });
8434  return arr;
8435 },
8436 getOutTransitions: function() {
8437  var arr = [];
8438  arr.push({
8439   trans: this.createTransition(this.panel, { property: this.isLeftPosition ? 'left' : 'right', unit: 'px' }),
8440   start: 0,
8441   end: -this.panel.offsetWidth
8442  });
8443  arr.push({
8444   trans: this.createTransition(this.overlayPanel, {
8445    property: 'opacity',
8446    onComplete: function() {
8447     window.setTimeout(function() {
8448      this.rollbackAfterAnimateOut();
8449      this.animationInProgress = false;
8450     }.aspxBind(this), 0);
8451    }.aspxBind(this)
8452   }),
8453   start: 100,
8454   end: 0
8455  });
8456  return arr;
8457 },
8458 animateIn: function() {
8459  this.animate(this.getInTransitions());
8460 },
8461 animateOut: function() {
8462  this.animate(this.getOutTransitions());
8463 },
8464 animate: function(transitions) {
8465  this.animationInProgress = true;
8466  for(var i = 0, obj; obj = transitions[i]; i++)
8467   obj.trans.Start(obj.start, obj.end);
8468 },
8469 resetPanelStyle: function() {
8470  ASPx.SetStyles(this.panel, {
8471   className: this.panel.className.replace(SLIDE_PANEL_EXPANDED_CLASS_NAME, ''),
8472   left: '', width: '', display: '', zIndex: ''
8473  });
8474 },
8475 resetOverlayPanelStyle: function() {
8476  ASPx.SetStyles(this.overlayPanel, {
8477   display: '',
8478   zIndex: '',
8479   marginLeft: 0,
8480   marginTop: 0
8481  });
8482 },
8483 rollbackAfterAnimateOut: function() {
8484  this.resetPanelStyle();
8485  this.resetOverlayPanelStyle();
8486  document.documentElement.style.overflow = this.cashedHtmlOverflow;
8487  this.afterCollapsePanel.FireEvent();
8488 }
8489});
8490var appearPanelWithShiftBodyAction = ASPx.CreateClass(appearPanelAction, {
8491 constructor: function(menu) {
8492  this.cashedBodyMargin = '';
8493  this.cashedBodyWidth = '';
8494  this.constructor.prototype.constructor.call(this, menu);
8495 },
8496 getInTransitions: function() {
8497  var arr = appearPanelAction.prototype.getInTransitions.call(this);
8498  arr.push({
8499   trans: this.createTransition(document.body, { property: 'marginLeft', unit: 'px' }),
8500   start: this.bodyLeftMargin,
8501   end: (this.isLeftPosition ? 1 : -1) * (this.bodyLeftMargin + this.panel.offsetWidth)
8502  });
8503  return arr;
8504 },
8505 getOutTransitions: function() {
8506  var arr = appearPanelAction.prototype.getOutTransitions.call(this);
8507  arr.push({
8508   trans: this.createTransition(document.body, { property: 'marginLeft', unit: 'px' }),
8509   start: (this.isLeftPosition ? 1 : -1) * (this.bodyLeftMargin + this.panel.offsetWidth),
8510   end: this.bodyLeftMargin
8511  });
8512  return arr;
8513 },
8514 prepareForAnimateIn: function() {
8515  this.bodyLeftMargin = ASPx.PxToInt(ASPx.GetCurrentStyle(document.body).marginLeft);
8516  this.cashedBodyWidth = document.body.style.width;
8517  this.cashedBodyMargin = document.body.style.marginLeft;
8518  document.body.style.width = document.body.offsetWidth + 'px';
8519  appearPanelAction.prototype.prepareForAnimateIn.call(this);
8520 },
8521 rollbackAfterAnimateOut: function() {
8522  document.body.style.width = this.cashedBodyWidth;
8523  document.body.style.marginLeft = this.cashedBodyMargin;
8524  appearPanelAction.prototype.rollbackAfterAnimateOut.call(this);
8525 }
8526});
8527var ASPxClientMenu = ASPx.CreateClass(ASPxClientMenuBase, {
8528 constructor: function(name) {
8529  this.constructor.prototype.constructor.call(this, name);
8530  this.isVertical = false;
8531  this.orientationChanged = false;
8532  this.firstSubMenuDirection = "Auto";
8533  this.enableSideMenu = false;
8534  this.sideMenuWindowInnerWidth = ASPx.MaxMobileWindowWidth;
8535  this.enableCollapseToIcons = false;
8536  this.collapseToIconsWindowInnerWidth = ASPx.MaxMobileWindowWidth;
8537  this.showPopOutImages = false;
8538  this.sideMenuModeOn = false;
8539  this.iconsViewModeOn = false;
8540  this.position = 'left'; 
8541  this.expandMode = 0; 
8542  this.direction = this.position == 'left' ? 1 : -1;
8543  this.appearAction = null;
8544  this.subMenuStack = null;
8545  this.breadCrumb = null;
8546 },
8547 InlineInitialize: function() {
8548  var mainElement = this.GetMainElement();
8549  if(this.enableSideMenu) {
8550   mainElement.parentNode.className += ' dxm-' + this.position;
8551   this.subMenuStack = new subMenuStack();
8552   this.subMenuStack.push(this.GetMainElement());
8553   this.appearAction = this.createAppearAction();
8554   this.breadCrumb = this.createBreadCrumbs();
8555   this.updateBreadCrumbsText('TEMP'); 
8556   this.switchMenuView(true);
8557  }
8558  this.switchBetweenTextAndIcons();
8559  this.renderHelper.ApplyItemsVerticalAlignment(mainElement);
8560  ASPxClientMenuBase.prototype.InlineInitialize.call(this);
8561 },
8562 BrowserWindowResizeSubscriber: function() {
8563  return ASPxClientMenuBase.prototype.BrowserWindowResizeSubscriber.call(this) || this.enableSideMenu || this.enableCollapseToIcons;
8564 },
8565 SetData: function(data){
8566  ASPxClientMenuBase.prototype.SetData.call(this, data);
8567  if(data.adaptiveModeData)
8568   this.SetAdaptiveMode(data.adaptiveModeData);
8569 },
8570 IsVertical: function(indexPath) {
8571  return this.isVertical || !this.IsRootItem(indexPath) || this.IsAdaptiveMenuItem(indexPath);
8572 },
8573 IsSidePanelExpanded: function() {
8574  return this.enableSideMenu && this.appearAction.getExpanded();
8575 },
8576 IsCorrectionDisableMethodRequired: function(indexPath) {
8577  return (indexPath.indexOf("i") == -1) && (this.firstSubMenuDirection == "RightOrBottom" || this.firstSubMenuDirection == "LeftOrTop");
8578 },
8579 SetAdaptiveMode: function(data) {
8580  this.enableAdaptivity = true;
8581  if(ASPx.Ident.IsArray(data))
8582   this.adaptiveItemsOrder = data;
8583  else
8584   for(var i = data - 1; i >= 0; i--)
8585    this.adaptiveItemsOrder.push(i.toString());
8586 }, 
8587 OnBrowserWindowResize: function(e) {
8588  if(e && e.virtualKeyboardShownOnAndroid) return;
8589  this.switchMenuView();
8590  this.switchBetweenTextAndIcons();
8591  this.AdjustControl();
8592 },
8593 AdjustControlCore: function() {
8594  this.CorrectVerticalAlignment(ASPx.ClearHeight, this.GetPopOutElements, "PopOut", true);
8595  this.CorrectVerticalAlignment(ASPx.ClearVerticalMargins, this.GetPopOutImages, "PopOutImg", true);
8596  if(this.orientationChanged){
8597   this.renderHelper.ChangeOrientaion(this.GetMainElement(), this.isVertical);
8598   this.orientationChanged = false;
8599  }
8600  else
8601   this.renderHelper.CalculateMenuControl(this.GetMainElement());
8602  this.CorrectVerticalAlignment(ASPx.AdjustHeight, this.GetPopOutElements, "PopOut", true);
8603  this.CorrectVerticalAlignment(ASPx.AdjustVerticalMargins, this.GetPopOutImages, "PopOutImg", true);
8604 },
8605 GetCorrectionDisabledResult: function(x, toLeftX) {
8606  switch (this.firstSubMenuDirection) {
8607   case "RightOrBottom": {
8608    this.popupToLeft = false;
8609    return x;
8610   }
8611   case "LeftOrTop": {
8612    this.popupToLeft = true;
8613    return toLeftX;
8614   }
8615  }
8616 },
8617 IsHorizontalSubmenuNeedInversion: function(subMenuBottom, docClientHeight, menuItemTop, subMenuHeight, itemHeight) {
8618  if(this.firstSubMenuDirection == "Auto")
8619   return ASPxClientMenuBase.prototype.IsHorizontalSubmenuNeedInversion.call(this, subMenuBottom, docClientHeight, menuItemTop, subMenuHeight, itemHeight);
8620  return this.firstSubMenuDirection == "LeftOrTop";
8621 },
8622 createAppearAction: function() {
8623  var appearAction = this.expandMode == 0 ? new appearPanelWithShiftBodyAction(this) : new appearPanelAction(this);
8624  appearAction.afterCollapsePanel.AddHandler(function() {
8625   while(this.subMenuStack.hasItems())
8626    this.performBack(true);
8627   ASPx.SetStyles(this.subMenuStack.last(), { left: '', opacity: '', display: '' });
8628   ASPx.RemoveElement(this.breadCrumb);
8629  }.aspxBind(this));
8630  return appearAction;
8631 },
8632 createBreadCrumbs: function() {
8633  var element = document.createElement('DIV');
8634  element.className = BREAD_CRUMBS_CLASS_NAME;
8635  ASPx.Evt.AttachEventToElement(element, 'click', function() { this.performBack(); }.bind(this), true);
8636  var breadCrumbsBackImage = document.createElement('IMG');
8637  breadCrumbsBackImage.src = ASPx.EmptyImageUrl;
8638  breadCrumbsBackImage.className = BACK_ICON_CLASS_NAME;
8639  element.appendChild(breadCrumbsBackImage);
8640  var breadCrumbsTitle = document.createElement('SPAN');
8641  element.appendChild(breadCrumbsTitle);
8642  return element;
8643 },
8644 updateBreadCrumbsText: function() {
8645  var text = this.subMenuStack.text();
8646  if(text)
8647   this.breadCrumb.children[1].innerHTML = this.subMenuStack.text();
8648 },
8649 calculateMaxSize: function() {
8650  var mainElement = this.GetMainElement();
8651  var cachedWidth = mainElement.style.width;
8652  mainElement.style.width = '';
8653  var size = { width: mainElement.offsetWidth, height: mainElement.offsetHeight };
8654  this.foreachSubMenus(function(item, element) {
8655   if(!element) return;
8656   element.className += ' ' + TEMPORARY_VISIBILITY_CLASS_NAME;
8657   if(element.offsetWidth > size.width)
8658    size.width = element.offsetWidth;
8659   if(element.offsetHeight > size.height)
8660    size.height = element.offsetHeight;
8661   element.className = element.className.replace(' ' + TEMPORARY_VISIBILITY_CLASS_NAME, '');
8662  }.bind(this));
8663  mainElement.style.width = cachedWidth;
8664  return size;
8665 },
8666 foreachSubMenus: function(menuItem, callback) {
8667  if(arguments.length == 1) {
8668   callback = menuItem;
8669   menuItem = this.GetRootItem();
8670  }
8671  for(var i = 0, item; item = menuItem.items[i]; i++)
8672   this.foreachSubMenus(item, callback);
8673  if(menuItem.indexPath && menuItem.items.length)
8674   callback(menuItem, this.GetMenuElement(menuItem.indexPath));
8675 },
8676 switchMenuView: function(force) {
8677  if(this.enableSideMenu) {
8678   aspxGetMenuCollection().DoHidePopupMenus(null, 0, this.name, true, "");
8679   var prevSideMenuOn = this.sideMenuModeOn;
8680   this.sideMenuModeOn = window.innerWidth < this.sideMenuWindowInnerWidth;
8681   if(this.sideMenuModeOn != prevSideMenuOn || force)
8682    this.switchMenuViewCore();
8683  }
8684 },
8685 switchBetweenTextAndIcons: function() {
8686  if(this.enableCollapseToIcons) {
8687   var newIconsViewModeOn = window.innerWidth <= this.collapseToIconsWindowInnerWidth;
8688   if(this.iconsViewModeOn != newIconsViewModeOn)
8689    this.ToggleRootItemsCollapsed();
8690  }
8691 },
8692 ToggleRootItemsCollapsed: function() {
8693  this.iconsViewModeOn = !this.iconsViewModeOn;
8694  ASPx.ToggleClassNameToElement(this.GetMainElement(), "dxm-onlyIcons", this.iconsViewModeOn);
8695  if(this.isInitialized) {
8696   this.renderHelper.ResetMinSize();
8697   this.renderHelper.CalculateMenuControl(this.GetMainElement(), true);
8698  }
8699 },
8700 switchMenuViewCore: function() {
8701  if(this.sideMenuModeOn)
8702   this.switchToSideMenuView();
8703  else
8704   this.switchToDefaultMenuView();
8705 },
8706 switchToSideMenuView: function() {
8707  this.SetOrientation('Vertical');
8708  this.switchSideMenuClass();
8709  if(!this.showPopOutImages) {
8710   var mainElement = this.GetMainElement();
8711   this.replacePopupOutImages(MenuCssClasses.ItemWithoutSubMenu, MenuCssClasses.ItemWithSubMenu);
8712   mainElement.className = mainElement.className.replace(NO_MAIN_POP_OUT_CLASS_NAME, '');
8713  }
8714 },
8715 switchToDefaultMenuView: function() {
8716  if(!this.showPopOutImages) {
8717   var mainElement = this.GetMainElement();
8718   this.replacePopupOutImages(MenuCssClasses.ItemWithSubMenu, MenuCssClasses.ItemWithoutSubMenu);
8719   if(mainElement.className.indexOf(NO_MAIN_POP_OUT_CLASS_NAME) == -1)
8720    mainElement.className += ' ' + NO_MAIN_POP_OUT_CLASS_NAME;
8721  }
8722  this.SetOrientation('Horizontal');
8723  this.switchSideMenuClass();
8724  this.appearAction.collapse();
8725 },
8726 switchSideMenuClass: function() {
8727  var rootElement = this.GetMainElement().parentNode.parentNode;
8728  if(this.sideMenuModeOn) {
8729   if(rootElement.className.indexOf(SIDE_MENU_CLASS_NAME) == -1)
8730    rootElement.className += ' ' + SIDE_MENU_CLASS_NAME;
8731  }
8732  else
8733   rootElement.className = rootElement.className.replace(' ' + SIDE_MENU_CLASS_NAME, '');
8734 },
8735 replacePopupOutImages: function(firstClass, secondClass) {
8736  var elements = this.renderHelper.GetItemElements(this.GetMainElement());
8737  for(var i = 0, item = null; item = elements[i]; i++) {
8738   if(item.className.indexOf(firstClass))
8739    item.className = item.className.replace(firstClass, secondClass);
8740  }
8741 },
8742 CalculateSubMenuPosition: function(element, x, y, indexPath, enableAnimation) {
8743  if(this.sideMenuModeOn)
8744   this.performForward(indexPath);
8745  else {
8746   this.setSubMenuOffset(element, '');
8747   ASPxClientMenuBase.prototype.CalculateSubMenuPosition.call(this, element, x, y, indexPath, enableAnimation);
8748  }
8749 },
8750 startPanelAnimation: function(element, props, onComplete) {
8751  ASPx.AnimationHelper.createMultipleAnimationTransition(element, {
8752   duration: SLIDE_DURATION_VALUE,
8753   transition: ASPx.AnimationConstants.Transitions.POW_EASE_OUT,
8754   onComplete: onComplete
8755  }).Start(props);
8756 },
8757 changeBreadCrumbsParent: function(parent) {
8758  if(this.subMenuStack.count() == 1 && !parent.querySelector('.' + BREAD_CRUMBS_CLASS_NAME))
8759   parent.appendChild(this.breadCrumb);
8760 },
8761 performForward: function(indexPath) {
8762  var element = this.GetMenuElement(indexPath);
8763  if(element != null) {
8764   var currentSubMenu = this.subMenuStack.last();
8765   var currentSubMenuWidth = currentSubMenu.offsetWidth;
8766   var nextSubMenu = this.GetMenuElement(indexPath);
8767   this.setSubMenuVisible(nextSubMenu);
8768   this.changeBreadCrumbsParent(nextSubMenu);
8769   this.subMenuStack.push(nextSubMenu, this.GetItemByIndexPath(indexPath).GetText());
8770   this.updateBreadCrumbsText();
8771   this.setSubMenuSize(indexPath, nextSubMenu);
8772   this.startPanelAnimation(currentSubMenu, {
8773    left: { from: 0, to: this.direction * -(currentSubMenuWidth / 3), unit: "px" },
8774    opacity: { from: 1, to: 0 }
8775   }, function(el) { el.style.display = 'none'; el.style.opacity = ''; });
8776   window.setTimeout(function() {
8777    this.startPanelAnimation(nextSubMenu, {
8778     left: { from: this.direction * currentSubMenuWidth, to: 0, unit: "px" },
8779     opacity: { from: 0, to: 1 }
8780    }, function(element) { this.onNextSubmenuAnimationEnd(element); }.bind(this));
8781   }.bind(this), SLIDE_DURATION_VALUE / 3);
8782  }
8783 },
8784 setSubMenuVisible: function(subMenu) {
8785  ASPx.SetStyles(subMenu, {
8786   top: '', display: '', visibility: '', opacity: 0
8787  });
8788 },
8789 setSubMenuSize: function(indexPath, subMenu) {
8790  var menuElement = this.GetMenuElement(indexPath);
8791  menuElement.style.width = this.appearAction.clearWidth + 'px';
8792  this.setSubMenuOffset(subMenu, this.breadCrumb.offsetHeight + 'px');
8793 },
8794 setSubMenuOffset: function(subMenu, offset) {
8795  subMenu.children[0].style.top = offset;
8796 },
8797 onNextSubmenuAnimationEnd: function(element) {
8798  if(element.children.length > 1)
8799   element.parentNode.appendChild(this.breadCrumb);
8800 },
8801 performBack: function(skipAnimation) {
8802  if(this.subMenuStack.hasItems()) {
8803   var currentSubMenu = this.subMenuStack.pop();
8804   var prevSubMenu = this.subMenuStack.last();
8805   if(skipAnimation)
8806    this.performBackWithoutAnimation(currentSubMenu, prevSubMenu);
8807   else
8808    this.performBackWithAnimation(currentSubMenu, prevSubMenu);
8809  }
8810 },
8811 performBackWithoutAnimation: function(currentSubMenu, prevSubMenu) {
8812  this.DoHidePopupMenu(null, currentSubMenu);
8813 },
8814 performBackWithAnimation: function(currentSubMenu, prevSubMenu) {
8815  this.updateBreadCrumbsText();
8816  this.changeBreadCrumbsParent(currentSubMenu);
8817  var width = currentSubMenu.offsetWidth;
8818  prevSubMenu.style.opacity = '0';
8819  prevSubMenu.style.display = '';
8820  this.startPanelAnimation(currentSubMenu, {
8821   left: { from: 0, to: this.direction * (width / 3), unit: "px" },
8822   opacity: { from: 1, to: 0 }
8823  }, function(el) { el.style.opacity = ''; el.style.display = 'none'; this.DoHidePopupMenu(null, el); }.bind(this));
8824  window.setTimeout(function() {
8825   this.startPanelAnimation(prevSubMenu, {
8826    left: { from: this.direction * -width, to: 0, unit: "px" },
8827    opacity: { from: 0, to: 1 }
8828   });
8829  }.bind(this), SLIDE_DURATION_VALUE / 3);
8830 },
8831 GetOrientation: function() {
8832  return this.isVertical ? "Vertical" : "Horizontal";
8833 },
8834 SetOrientation: function(orientation) {
8835  var isVertical = orientation === "Vertical";
8836  if(this.isVertical !== isVertical){
8837   this.isVertical = isVertical;
8838   this.orientationChanged = true;
8839   this.ResetControlAdjustment();
8840   this.AdjustControl();
8841  }
8842 },
8843 ToggleSideMenu: function() {
8844  if(this.sideMenuModeOn)
8845   this.appearAction.toggleExpanded();
8846 }
8847});
8848ASPx.Ident.scripts.ASPxClientMenu = true;
8849ASPxClientMenu.Cast = ASPxClientControl.Cast;
8850var ASPxClientMenuExt = ASPx.CreateClass(ASPxClientMenu, {
8851 constructor: function(name) {
8852  this.constructor.prototype.constructor.call(this, name);
8853 },
8854 NeedCreateItemsOnClientSide: function() {
8855  return true;
8856 }
8857});
8858var ASPxClientMenuItemEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
8859 constructor: function(item) {
8860  this.constructor.prototype.constructor.call(this);
8861  this.item = item;
8862 }
8863});
8864var ASPxClientMenuItemMouseEventArgs = ASPx.CreateClass(ASPxClientMenuItemEventArgs, {
8865 constructor: function(item, htmlElement) {
8866  this.constructor.prototype.constructor.call(this, item);
8867  this.htmlElement = htmlElement;
8868 }
8869});
8870var ASPxClientMenuItemClickEventArgs = ASPx.CreateClass(ASPxClientProcessingModeEventArgs, {
8871 constructor: function(processOnServer, item, htmlElement, htmlEvent) {
8872  this.constructor.prototype.constructor.call(this, processOnServer);
8873  this.item = item;
8874  this.htmlElement = htmlElement;
8875  this.htmlEvent = htmlEvent;
8876 }
8877});
8878ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseDownEventName, function(evt) {
8879 return aspxGetMenuCollection().OnMouseDown(evt);
8880});
8881function aspxAMIMOver(source, args) {
8882 var menu = aspxGetMenuCollection().GetMenu(args.item.name);
8883 if(menu != null) menu.OnAfterItemOver(args.item, args.element);
8884}
8885function aspxBMIMOver(source, args) {
8886 var menu = aspxGetMenuCollection().GetMenu(args.item.name);
8887 if(menu != null) menu.OnBeforeItemOver(args.item, args.element);
8888}
8889function aspxAMIMOut(source, args) {
8890 var menu = aspxGetMenuCollection().GetMenu(args.item.name);
8891 if(menu != null) menu.OnAfterItemOut(args.item, args.element, args.toElement);
8892}
8893function aspxMSBOver(source, args) {
8894 var menu = MenuScrollHelper.GetMenuByScrollButtonId(args.element.id);
8895 if(menu != null) menu.ClearDisappearTimer();
8896}
8897ASPx.AddAfterSetFocusedState(aspxAMIMOver);
8898ASPx.AddAfterClearFocusedState(aspxAMIMOut);
8899ASPx.AddAfterSetHoverState(aspxAMIMOver);
8900ASPx.AddAfterClearHoverState(aspxAMIMOut);
8901ASPx.AddBeforeSetFocusedState(aspxBMIMOver);
8902ASPx.AddBeforeSetHoverState(aspxBMIMOver);
8903ASPx.AddAfterSetHoverState(aspxMSBOver);
8904ASPx.AddAfterSetPressedState(aspxMSBOver);
8905ASPx.AddBeforeDisabled(function(source, args) {
8906 var menu = aspxGetMenuCollection().GetMenu(args.item.name);
8907 if(menu != null)
8908  menu.OnBeforeItemDisabled(args.item, args.element);
8909});
8910ASPx.AddFocusedItemKeyDown(function(source, args) {
8911 var menu = aspxGetMenuCollection().GetMenu(args.item.name);
8912 if(menu != null)
8913  menu.OnFocusedItemKeyDown(args.htmlEvent, args.item);
8914});
8915ASPx.AddAfterClearHoverState(function(source, args) {
8916 var menu = MenuScrollHelper.GetMenuByScrollButtonId(args.element.id);
8917 if(menu != null) menu.SetDisappearTimer();
8918});
8919ASPx.AddAfterSetPressedState(function(source, args) {
8920 var menu = MenuScrollHelper.GetMenuByScrollButtonId(args.element.id);
8921 if(menu) menu.StartScrolling(args.element.id, 1, 4);
8922});
8923ASPx.AddAfterClearPressedState(function(source, args) {
8924 var menu = MenuScrollHelper.GetMenuByScrollButtonId(args.element.id);
8925 if(menu) menu.StopScrolling(args.element.id);
8926});
8927if(!ASPx.Browser.TouchUI) {
8928 ASPx.AddAfterSetHoverState(function(source, args) {
8929  var menu = MenuScrollHelper.GetMenuByScrollButtonId(args.element.id);
8930  if(menu) menu.StartScrolling(args.element.id, 15, 1);
8931  if(!menu)
8932   menu = aspxGetMenuCollection().GetMenu(args.item.name);
8933  if(menu && menu.sideMenuModeOn && menu.IsItemElement(args.element)) {
8934   menu.hoverItemName = args.item.name;
8935   menu.MarkPrecedingItem(args.item.name, PRE_HOVERED_ELEMENT_CLASS_NAME, true);
8936  }
8937 });
8938 ASPx.AddAfterClearHoverState(function(source, args) {
8939  var menu = MenuScrollHelper.GetMenuByScrollButtonId(args.element.id);
8940  if(menu) menu.StopScrolling(args.element.id);
8941  if(!menu)
8942   menu = aspxGetMenuCollection().GetMenu(args.item.name);
8943  if(menu && menu.sideMenuModeOn && menu.IsItemElement(args.element)) {
8944   menu.hoverItemName = null;
8945   menu.UnmarkPrecedingItem(args.item.name, PRE_HOVERED_ELEMENT_CLASS_NAME, true);
8946  }
8947 });
8948}
8949ASPx.MIClick = function(evt, name, indexPath) {
8950 if(ASPx.TouchUIHelper.isMouseEventFromScrolling) return;
8951 var menu = aspxGetMenuCollection().Get(name);
8952 if(menu != null) menu.OnItemClick(indexPath, evt);
8953};
8954ASPx.MIDDClick = function(evt, name, indexPath) {
8955 var menu = aspxGetMenuCollection().Get(name);
8956 if(menu != null) menu.OnItemDropDownClick(indexPath, evt);
8957 if(!ASPx.Browser.NetscapeFamily)
8958  evt.cancelBubble = true;
8959};
8960ASPx.GetMenuCollection = aspxGetMenuCollection;
8961ASPx.MenuRenderHelper = MenuRenderHelper;
8962ASPx.MenuItemClasses = MenuCssClasses;
8963window.ASPxClientMenuBase = ASPxClientMenuBase;
8964window.ASPxClientMenuCollection = ASPxClientMenuCollection;
8965window.ASPxClientMenuItem = ASPxClientMenuItem;
8966window.ASPxClientMenu = ASPxClientMenu;
8967window.ASPxClientMenuExt = ASPxClientMenuExt;
8968window.ASPxClientMenuItemEventArgs = ASPxClientMenuItemEventArgs;
8969window.ASPxClientMenuItemMouseEventArgs = ASPxClientMenuItemMouseEventArgs;
8970window.ASPxClientMenuItemClickEventArgs = ASPxClientMenuItemClickEventArgs;
8971})();
8972
8973(function(dx) {
8974 var Interactions = ASPx.CreateClass(null, {
8975  onSwipeLeft: function(selector, func) {
8976  },
8977  onSwipeRight: function(selector, func) {
8978  }
8979 });
8980 var BootstrapCore = {};
8981 BootstrapCore.Interactions = new Interactions();
8982 BootstrapCore.BootstrapMode = 'Bootstrap5';
8983 BootstrapCore.IsBootstrap3 = BootstrapCore.BootstrapMode == "Bootstrap3";
8984 BootstrapCore.IsBootstrap4 = BootstrapCore.BootstrapMode == "Bootstrap4";
8985 BootstrapCore.IsBootstrap5 = BootstrapCore.BootstrapMode == "Bootstrap5";
8986 BootstrapCore.CheckReferences = 'true';
8987 BootstrapCore.zIndexCategories = {
8988  dropdown: 1000,
8989  sticky: 1020,
8990  fixed: 1030,
8991  modalBackdrop: 1040,
8992  modal: 1050,
8993  popover: 1060,
8994  tooltip: 1070
8995 };
8996 var bsCssClass = "dxbs-" + BootstrapCore.BootstrapMode.charAt(BootstrapCore.BootstrapMode.length - 1);
8997 if(document && document.documentElement)
8998  ASPx.AddClassNameToElement(document.documentElement, bsCssClass);
8999 var BootstrapCssSelectors = {};
9000 BootstrapCssSelectors.Table = "table";
9001 BootstrapCssSelectors.TableBordered = "table-bordered";
9002 BootstrapCssSelectors.TableSmall = BootstrapCore.IsBootstrap3 ? "table-condensed" : "table-sm";
9003 BootstrapCssSelectors.TableActive = BootstrapCore.IsBootstrap3 ? "" : "table-active";
9004 BootstrapCssSelectors.BackgroundLight = BootstrapCore.IsBootstrap3 ? "" : "bg-light";
9005 BootstrapCssSelectors.BackgroundPrimary = BootstrapCore.IsBootstrap3 ? "bg-primary" : "bg-primary text-white";
9006 BootstrapCssSelectors.BackgroundDanger = "bg-danger";
9007 BootstrapCssSelectors.Hidden = BootstrapCore.IsBootstrap3 ? "hidden" : "d-none";
9008 BootstrapCssSelectors.Row = "row";
9009 BootstrapCssSelectors.Column = "col";
9010 BootstrapCssSelectors.ColumnAuto = BootstrapCore.IsBootstrap3 ? "" : "col-auto";
9011 BootstrapCssSelectors.Panel = BootstrapCore.IsBootstrap3 ? "panel" : "card";
9012 BootstrapCssSelectors.PanelDefault = BootstrapCore.IsBootstrap3 ? "panel-default" : "";
9013 BootstrapCssSelectors.PanelHeading = BootstrapCore.IsBootstrap3 ? "panel-heading" : "card-header";
9014 BootstrapCssSelectors.PanelTitle = BootstrapCore.IsBootstrap3 ? "panel-title" : "card-title";
9015 BootstrapCssSelectors.PanelBody = BootstrapCore.IsBootstrap3 ? "panel-body" : "card-body";
9016 BootstrapCssSelectors.PanelFooter = BootstrapCore.IsBootstrap3 ? "panel-footer" : "card-footer";
9017 BootstrapCssSelectors.Radio = BootstrapCore.IsBootstrap3 ? "radio" : "form-check";
9018 BootstrapCssSelectors.CheckBox = BootstrapCore.IsBootstrap3 ? "checkbox" : "form-check";
9019 BootstrapCssSelectors.InlineCheckBox = BootstrapCore.IsBootstrap3 ? "checkbox-inline" : "form-check form-check-inline";
9020 BootstrapCssSelectors.CheckBoxLabel = BootstrapCore.IsBootstrap3 ? "" : "form-check-label";
9021 BootstrapCssSelectors.CheckBoxInput = BootstrapCore.IsBootstrap3 ? "" : "form-check-input";
9022 BootstrapCssSelectors.CustomCheckBox = BootstrapCore.IsBootstrap3 ? "" : "custom-control custom-checkbox";
9023 BootstrapCssSelectors.CustomInlineCheckBox = BootstrapCore.IsBootstrap3 ? "" : "custom-control custom-control-inline custom-checkbox";
9024 BootstrapCssSelectors.CustomRadioButton = BootstrapCore.IsBootstrap3 ? "" : "custom-control custom-radio";
9025 BootstrapCssSelectors.CustomInlineRadioButton = BootstrapCore.IsBootstrap3 ? "" : "custom-control custom-control-inline custom-radio";
9026 BootstrapCssSelectors.CustomCheckLabel = BootstrapCore.IsBootstrap3 ? "" : "custom-control-label";
9027 BootstrapCssSelectors.CustomCheckInput = BootstrapCore.IsBootstrap3 ? "" : "custom-control-input";
9028 BootstrapCssSelectors.ControlLabel = BootstrapCore.IsBootstrap3 ? "control-label" : "col-form-label";
9029 BootstrapCssSelectors.FormControlStatic = BootstrapCore.IsBootstrap3 ? "form-control-static" : "form-control-plaintext" ;
9030 BootstrapCssSelectors.HelpBlock = BootstrapCore.IsBootstrap3 ? "help-block" : "form-text";
9031 BootstrapCssSelectors.HasError = BootstrapCore.IsBootstrap3 ? "has-error" : "";
9032 BootstrapCssSelectors.FormControlFeedback = BootstrapCore.IsBootstrap3 ? "form-control-feedback" : "dxbs-feedback";
9033 BootstrapCssSelectors.InvalidFormControl = BootstrapCore.IsBootstrap3 ? "" : "is-invalid";
9034 BootstrapCssSelectors.InvalidFeedback = BootstrapCore.IsBootstrap3 ? "" : "invalid-feedback";
9035 BootstrapCssSelectors.InputGroup = "input-group";
9036 BootstrapCssSelectors.InputGroupAppendButton = BootstrapCore.IsBootstrap3 ? "input-group-btn" : "input-group-append";
9037 BootstrapCssSelectors.InputGroupPrependButton = BootstrapCore.IsBootstrap3 ? "input-group-btn" : "input-group-prepend";
9038 BootstrapCssSelectors.Divider = BootstrapCore.IsBootstrap3 ? "divider" : "dropdown-divider";
9039 BootstrapCssSelectors.NavItem = BootstrapCore.IsBootstrap3 ? "" : "nav-item";
9040 BootstrapCssSelectors.NavLink = BootstrapCore.IsBootstrap3 ? "" : "nav-link";
9041 BootstrapCssSelectors.DropDownMenu = "dropdown-menu";
9042 BootstrapCssSelectors.DropDownMenuItem = BootstrapCore.IsBootstrap3 ? "" : "dropdown-item";
9043 BootstrapCssSelectors.ListBoxItemLink = BootstrapCore.IsBootstrap3 ? "list-group-item" : "list-group-item list-group-item-action";
9044 BootstrapCssSelectors.ListGroupItem = selectClass("list-group-item");
9045 BootstrapCssSelectors.ListGroup = selectClass("list-group");
9046 BootstrapCssSelectors.Active = selectClass("active");
9047 BootstrapCssSelectors.Disabled = selectClass("disabled");
9048 BootstrapCssSelectors.HiddenLayout = "dxbs-hl";
9049 BootstrapCssSelectors.Breabcrumb = "breadcrumb";
9050 BootstrapCssSelectors.BreadcrumbItem = BootstrapCore.IsBootstrap3 ? "" : "breadcrumb-item";
9051 BootstrapCssSelectors.Toolbar = "btn-toolbar";
9052 BootstrapCssSelectors.Button = "btn";
9053 BootstrapCssSelectors.ButtonGroup = "btn-group";
9054 BootstrapCssSelectors.ButtonGroupVertical = "btn-group-vertical";
9055 BootstrapCssSelectors.DropDown = "dropdown";
9056 BootstrapCssSelectors.DropDownToggle = "dropdown-toggle";
9057 BootstrapCssSelectors.Modal = "modal";
9058 BootstrapCssSelectors.ModalContent = "modal-content";
9059 BootstrapCssSelectors.ModalBody = "modal-body";
9060 BootstrapCssSelectors.ModalHeader = "modal-header";
9061 BootstrapCssSelectors.ModalTitle = "modal-title";
9062 BootstrapCssSelectors.ModalFooter = "modal-footer";
9063 BootstrapCssSelectors.ModalBackdrop = "modal-backdrop " + (BootstrapCore.IsBootstrap3 ? "in" : "show");
9064 BootstrapCssSelectors.Label = BootstrapCore.IsBootstrap3 ? "label" : "badge";
9065 BootstrapCssSelectors.Alert = "alert";
9066 function selectClass() {
9067  var argsCount = arguments.length;
9068  if (argsCount === 1 || BootstrapCore.IsBootstrap3)
9069   return arguments[0];
9070  if (argsCount === 2 || BootstrapCore.IsBootstrap4)
9071   return arguments[1];
9072  return arguments[2];
9073 }
9074 BootstrapCssSelectors.Popover = selectClass("popover");
9075 BootstrapCssSelectors.PopoverArrow = selectClass("arrow", "arrow", "popover-arrow");
9076 BootstrapCssSelectors.PopoverBody = selectClass("popover-content", "popover-body");
9077 BootstrapCssSelectors.PopoverHeader = selectClass("popover-title", "popover-header");
9078 BootstrapCssSelectors.PopoverBottom = selectClass("bottom", "bs-popover-bottom");
9079 BootstrapCssSelectors.PopoverLeft = selectClass("left", "bs-popover-left");
9080 BootstrapCssSelectors.PopoverRight = selectClass("right", "bs-popover-right");
9081 BootstrapCssSelectors.PopoverTop = selectClass("top", "bs-popover-top");
9082 BootstrapCssSelectors.Tooltip = selectClass("tooltip");
9083 BootstrapCssSelectors.TooltipArrow = selectClass("tooltip-arrow", "arrow", "tooltip-arrow");
9084 BootstrapCssSelectors.TooltipContent = selectClass("tooltip-inner");
9085 BootstrapCssSelectors.TooltipBottom = selectClass("bottom", "bs-tooltip-bottom");
9086 BootstrapCssSelectors.TooltipLeft = selectClass("left", "bs-tooltip-left");
9087 BootstrapCssSelectors.TooltipRigth = selectClass("right", "bs-tooltip-right");
9088 BootstrapCssSelectors.TooltipTop = selectClass("top", "bs-tooltip-top");
9089 BootstrapCssSelectors.Border = selectClass("dxbs-border", "border");
9090 BootstrapCssSelectors.TableHeadLight = selectClass("", "thead-light", "");
9091 BootstrapCssSelectors.PanelHeadingTabs = selectClass("panel-heading-tabs", "card-header-tabs");
9092 BootstrapCssSelectors.Invisible = selectClass("invisible");
9093 BootstrapCssSelectors.TextCenter = "text-center";
9094 BootstrapCssSelectors.TextMuted = selectClass("text-muted");
9095 BootstrapCssSelectors.TextRight = selectClass("text-right", "text-right", "text-end");
9096 BootstrapCssSelectors.MarginStart = selectClass("", "ml", "ms");
9097 BootstrapCssSelectors.MarginEnd = selectClass("", "mr", "me");
9098 BootstrapCssSelectors.Badge = selectClass("badge");
9099 BootstrapCssSelectors.BadgePill = selectClass("", "badge-pill", "rounded-pill");
9100 BootstrapCssSelectors.BadgePrimary = selectClass("", "badge-primary", "bg-primary");
9101 BootstrapCssSelectors.BadgeSecondary = selectClass("", "badge-secondary", "bg-secondary");
9102 BootstrapCssSelectors.BadgeSuccess = selectClass("", "badge-success", "bg-success");
9103 BootstrapCssSelectors.BadgeDanger = selectClass("", "badge-danger", "bg-danger");
9104 BootstrapCssSelectors.BadgeWarning = selectClass("", "badge-warning", "bg-warning");
9105 BootstrapCssSelectors.BadgeInfo = selectClass("", "badge-info", "bg-info");
9106 BootstrapCssSelectors.BadgeLight = selectClass("", "badge-light", "bg-light");
9107 BootstrapCssSelectors.BadgeDark = selectClass("", "badge-dark", "bg-dark");
9108 BootstrapCssSelectors.TextPrimary = selectClass("text-primary");
9109 BootstrapCssSelectors.TextSecondary = selectClass("", "text-secondary");
9110 BootstrapCssSelectors.TextSuccess = selectClass("text-success");
9111 BootstrapCssSelectors.TextDanger = selectClass("text-danger");
9112 BootstrapCssSelectors.TextWarning = selectClass("text-warning");
9113 BootstrapCssSelectors.TextInfo = selectClass("text-info");
9114 BootstrapCssSelectors.TextLight = selectClass("", "text-light");
9115 BootstrapCssSelectors.TextDark = selectClass("", "text-dark");
9116 BootstrapCssSelectors.ButtonPrimary = selectClass("btn-primary");
9117 BootstrapCssSelectors.ButtonSecondary = selectClass("btn-default", "btn-secondary");
9118 BootstrapCssSelectors.ButtonSuccess = selectClass("btn-success");
9119 BootstrapCssSelectors.ButtonDanger = selectClass("btn-danger");
9120 BootstrapCssSelectors.ButtonWarning = selectClass("btn-warning");
9121 BootstrapCssSelectors.ButtonInfo = selectClass("btn-info");
9122 BootstrapCssSelectors.ButtonLight = selectClass("", "btn-light");
9123 BootstrapCssSelectors.ButtonDark = selectClass("", "btn-dark");
9124 BootstrapCssSelectors.ButtonLink = selectClass("btn-link");
9125 BootstrapCssSelectors.ButtonOutlineSecondary = selectClass("", "btn-outline-secondary");
9126 BootstrapCssSelectors.FormControl = selectClass("form-control");
9127 BootstrapCssSelectors.FormGroup = selectClass("form-group", "form-group", "");
9128 BootstrapCssSelectors.Pagination = selectClass("pagination");
9129 BootstrapCssSelectors.AccordionItem = selectClass("panel", "card", "accordion-item");
9130 BootstrapCssSelectors.AccordionHeader = selectClass("panel-heading", "card-header", "accordion-header");
9131 BootstrapCssSelectors.AccordionBody = selectClass("panel-body", "card-body", "accordion-body");
9132 var mediaQueryScreenSizesCache = {};
9133 function createCssRuleForScreenSizeMediaQuery(cssVarName, fallbackWidth, cssRule) {
9134  var cache = mediaQueryScreenSizesCache;
9135  var minWidth = cache[cssVarName] || (cache[cssVarName] = (ASPx.GetCurrentStyle(document.body).getPropertyValue(cssVarName) || fallbackWidth));
9136  if(minWidth) {
9137   var styleSheet = ASPx.GetCurrentStyleSheet();
9138   if(styleSheet)
9139    styleSheet.insertRule("@media (min-width: " + minWidth + ") {\n" + cssRule + "\n}\n", styleSheet.cssRules.length);
9140  }
9141 }
9142 BootstrapCore.createCssRuleForLargeScreen = function(cssRule) {
9143  createCssRuleForScreenSizeMediaQuery("--breakpoint-lg", "992px", cssRule);
9144 };
9145 function getTableCellStyleRuleCssText(cellElement, addBorders, addPaddings) {
9146  var cellStyleProperties = [];
9147  if(addBorders) {
9148   cellStyleProperties = cellStyleProperties.concat([
9149    "border", "border-left", "border-top", "border-right", "border-bottom",
9150    "border-left-width", "border-left-style", "border-left-color",
9151    "border-top-width", "border-top-style", "border-top-color",
9152    "border-right-width", "border-right-style", "border-right-color",
9153    "border-bottom-width", "border-bottom-style", "border-bottom-color"
9154   ]);
9155  }
9156  if(addPaddings)
9157   cellStyleProperties = cellStyleProperties.concat(["padding", "padding-left", "padding-top", "padding-right", "padding-bottom"]);
9158  return getStyleRuleCssText(ASPx.GetCurrentStyle(cellElement), cellStyleProperties);
9159 }
9160 function getStyleRuleCssText(currentStyle, styleProperties) {
9161  var rules = [];
9162  if(currentStyle) {
9163   for(var i = 0; i < styleProperties.length; i++) {
9164    var stylePropertyValue = ASPx.Str.Trim(currentStyle.getPropertyValue(styleProperties[i])) + "";
9165    if(stylePropertyValue)
9166     rules.push(styleProperties[i] + ": " + stylePropertyValue);
9167   }
9168  }
9169  return rules.join(";");
9170 }
9171 function updateTableCellStyleSheetRule(tableClassName, styleSheet, cssText, isHeaderCell, forceAdd) {
9172  if(!cssText || !cssText.length)
9173   return;
9174  var selector = "." + tableClassName + " tr > " + (isHeaderCell ? "th" : "td");
9175  updateStyleSheetRule(styleSheet, selector, cssText, forceAdd);
9176 }
9177 function updateStyleSheetRule(styleSheet, selector, cssText, forceAdd) {
9178  if(!forceAdd) {
9179   var rule = ASPx.GetStyleSheetRules(selector.substring(1));
9180   if(rule)
9181    rule.style.cssText = cssText;
9182   else
9183    forceAdd = true;
9184  }
9185  if(forceAdd)
9186   ASPx.AddStyleSheetRule(styleSheet, selector, cssText);
9187 }
9188 BootstrapCore.updateTableCellStyleSheetRules = function(forceAdd) {
9189  if(BootstrapCore.IsBootstrap3) {
9190   var styleSheet = ASPx.GetCurrentStyleSheet();
9191   if(styleSheet) {
9192    var container = createTestElement();
9193    var tableElement = document.createElement("table");
9194    var tableBody = document.createElement("tbody");
9195    tableElement.appendChild(tableBody);
9196    container.appendChild(tableElement);
9197    var row = document.createElement("tr");
9198    var cell = document.createElement("td");
9199    row.appendChild(cell);
9200    tableBody.appendChild(row);
9201    var rowWithHeaderCell = document.createElement("tr");
9202    var headerCell = document.createElement("th");
9203    rowWithHeaderCell.appendChild(headerCell);
9204    tableBody.appendChild(rowWithHeaderCell);
9205    document.body.appendChild(container);
9206    var tableClassName = BootstrapCssSelectors.Table;
9207    var tableBorderedClassName = BootstrapCssSelectors.TableBordered;
9208    var tableSmallClassName = BootstrapCssSelectors.TableSmall;
9209    tableElement.className = tableClassName;
9210    updateTableCellStyleSheetRule(tableClassName, styleSheet, getTableCellStyleRuleCssText(cell, true, true), true, forceAdd);
9211    updateTableCellStyleSheetRule(tableClassName, styleSheet, getTableCellStyleRuleCssText(headerCell, true, true), false, forceAdd);
9212    cell.className = ASPx.BootstrapCssSelectors.Active;
9213    var tableActiveCssClass = "dxbs-table-active";
9214    var tableActiveCssText = getStyleRuleCssText(ASPx.GetCurrentStyle(cell), ["background-color"]);
9215    updateStyleSheetRule(styleSheet, "." + tableActiveCssClass, tableActiveCssText, forceAdd);
9216    cell.className = "";
9217    tableElement.className = tableBorderedClassName;
9218    updateTableCellStyleSheetRule(tableBorderedClassName, styleSheet, getTableCellStyleRuleCssText(cell, true, false), true, forceAdd);
9219    updateTableCellStyleSheetRule(tableBorderedClassName, styleSheet, getTableCellStyleRuleCssText(headerCell, true, false), false, forceAdd);
9220    tableElement.className = tableSmallClassName;
9221    updateTableCellStyleSheetRule(tableSmallClassName, styleSheet, getTableCellStyleRuleCssText(cell, false, true), true, forceAdd);
9222    updateTableCellStyleSheetRule(tableSmallClassName, styleSheet, getTableCellStyleRuleCssText(headerCell, false, true), false, forceAdd);
9223    document.body.removeChild(container);
9224   }
9225  }
9226 };
9227 var existingColors = {};
9228 BootstrapCore.createColorItemsRules = function () {
9229  var colorElements = document.querySelectorAll("[data-color]");
9230  var cssText = "";
9231  for (var i = 0; i < colorElements.length; i++) {
9232   var colorElement = colorElements[i];
9233   var colorValue = ASPx.Attr.GetAttribute(colorElement, "data-color");
9234   if(existingColors[colorValue])
9235    continue;
9236   existingColors[colorValue] = true;
9237   cssText += "[data-color=\"" + colorValue + "\"],\n[data-item-color=\"" + colorValue + "\"]:before { background-color: " + colorValue + "; }\n";
9238  }
9239  if (cssText)
9240   BootstrapCore.createStylesBlock(cssText, "colors" + ASPx.CreateGuid());
9241 };
9242 BootstrapCore.createColorRule = function(c) {
9243  if(existingColors[c])
9244   return;
9245  existingColors[c] = true;
9246  ASPx.AddStyleSheetRule(ASPx.GetCurrentStyleSheet(), "[data-color=\"" + c + "\"],\n[data-item-color=\"" + c + "\"]:before", "background-color: " + c + ";");
9247 };
9248 BootstrapCore.getActualBgColor = function (el) {
9249  var color = ASPx.GetCurrentStyle(el).backgroundColor;
9250  var c = ASPx.Color.ColorToHexadecimal(color, true);
9251  if(c.a < 1) {
9252   var bgColor = ASPx.GetCurrentStyle(el.parentNode).backgroundColor;
9253   var bg;
9254   while(el.parentNode && el.parentNode.nodeType == 1 && (bg = ASPx.Color.ColorToHexadecimal(bgColor, true)).a === 0)
9255    bgColor = ASPx.GetCurrentStyle(el = el.parentNode).backgroundColor;
9256   c.r = Math.round(((1 - c.a) * bg.r) + (c.a * c.r));
9257   c.g = Math.round(((1 - c.a) * bg.g) + (c.a * c.g));
9258   c.b = Math.round(((1 - c.a) * bg.b) + (c.a * c.b));
9259  }
9260  return "rgb(" + c.r + "," + c.g + "," + c.b + ")";
9261 };
9262 var createdStylesBlockKeys = {};
9263 BootstrapCore.removeStylesBlock = function(key) {
9264  var stylesBlock = document.getElementById(key + "_styles");
9265  if(stylesBlock)
9266   ASPx.RemoveElement(stylesBlock);
9267 };
9268 BootstrapCore.createStylesBlock = function(cssText, key, container) {
9269  key = key + "_styles";
9270  var styleElement = null;
9271  if(key) {
9272   if(createdStylesBlockKeys[key]) {
9273    styleElement = document.getElementById(key);
9274    if(styleElement)
9275     ASPx.RemoveElement(styleElement);
9276   }
9277   createdStylesBlockKeys[key] = true;
9278  }
9279  styleElement = document.createElement("STYLE");
9280  styleElement.appendChild(document.createTextNode(cssText));
9281  if(container === undefined)
9282   container = ASPx.GetHeadElementOrCreateIfNotExist(document);
9283  container.appendChild(styleElement);
9284  styleElement.id = key;
9285 };
9286 BootstrapCore.initializeAccentColorRelatedSelectors = function(forceAddCssRule) {
9287  var linkEl = document.createElement("A");
9288  linkEl.href = ASPx.AccessibilityEmptyUrl;
9289  linkEl.className = ASPx.BootstrapCssSelectors.HiddenLayout;
9290  ASPx.DOM.ChangeDOM(function () {
9291   document.body.appendChild(linkEl);
9292   ASPx.DOM.CalculateStyles(function () {
9293    var accentColor = ASPx.Color.ColorToHexadecimal(ASPx.GetCurrentStyle(linkEl).color);
9294    ASPx.DOM.ChangeDOM(function() {
9295     updateStyleSheetRule(ASPx.GetCurrentStyleSheet(), ".dx-accent-color", "color: " + accentColor, forceAddCssRule);
9296     ASPx.RemoveElement(linkEl);
9297    });
9298   });
9299  });
9300 };
9301 function createBootstrapStateItemClass() {
9302  var stateClass = ASPx.CreateClass(ASPx.StateItem, {
9303   Clone: function() {
9304    return new stateClass(this.name, this.classNames, this.cssTexts, this.postfixes,
9305     this.imageObjs, this.imagePostfixes, this.kind, this.disableApplyingStyleToLink);
9306   },
9307   Apply: function(element) {
9308    this.changeState(element, true);
9309   },
9310   Cancel: function(element) {
9311    this.changeState(element, false);
9312   },
9313   changeState: function(element, condition) {
9314    if(!this.enabled) return;
9315    var elements = this.GetElements(element);
9316    for(var i = 0; i < elements.length; i++) {
9317     if(elements[i])
9318      this.changeClassName(elements[i], this.GetResultClassName(i), condition);
9319    }
9320   },
9321   changeClassName: function(el, className, condition) {
9322    if (!!className)
9323     ASPx.DOM.ToggleCssClass(el, className, condition);
9324   },
9325   ForceRedrawAppearance: function() { }
9326  });
9327  return stateClass;
9328 }
9329 var bootstrapStateItemClass;
9330 BootstrapCore.AddStateItems = function(callback) {
9331  ASPx.GetStateController().withCustomStateItemType(bootstrapStateItemClass || (bootstrapStateItemClass = createBootstrapStateItemClass()), callback);
9332 };
9333 ASPx.BootstrapCore = BootstrapCore;
9334 ASPx.BootstrapCssSelectors = BootstrapCssSelectors;
9335 ASPx.BuildBSCssClass = function() {
9336  return ASPx.Data.CollectionToArray(arguments)
9337   .map(function (c) { return BootstrapCssSelectors[c] || c; }).join(" ");
9338 };
9339 ASPx.CreatePatchedClass = function(baseClass, properties, patch) {
9340  var patchedBaseClass = ASPx.CreateClass(baseClass, patch);
9341  return ASPx.CreateClass(patchedBaseClass, properties || {});
9342 };
9343 if(BootstrapCore.CheckReferences)
9344  ASPx.attachToReady(detectBootstrapFramework);
9345 function detectBootstrapFramework() {
9346  var testElement = createTestElement();
9347  testElement.className = "input-group ms-1";
9348  document.body.appendChild(testElement);
9349  var style = ASPx.GetCurrentStyle(testElement);
9350  var exists = true;
9351  if (BootstrapCore.BootstrapMode === "Bootstrap3") {
9352   exists = style.display.indexOf("table") > -1;
9353  }
9354  else if (BootstrapCore.BootstrapMode === "Bootstrap4") {
9355   exists = style.display.indexOf("flex") > -1 &&
9356      style["margin-left"].indexOf("0") > -1;
9357  }
9358  else if (BootstrapCore.BootstrapMode === "Bootstrap5") {
9359   exists = style.display.indexOf("flex") > -1 &&
9360      style["margin-left"].indexOf("0") === -1;
9361  }
9362  document.body.removeChild(testElement);
9363  if (!exists) {
9364   var version = parseInt(ASPx.BootstrapCore.BootstrapMode.substr(9));
9365   console.error("Bootstrap " + version + " required by DevExpress Bootstrap controls is not linked to the page. Add a bootstrap.css link to the page for the controls to work properly.");
9366  }
9367 }
9368 function createTestElement() {
9369  var testElement = document.createElement("div");
9370  testElement.style.position = "absolute";
9371  testElement.style.top = ASPx.InvalidPosition + "px";
9372  testElement.style.left = ASPx.InvalidPosition + "px";
9373  return testElement;
9374 }
9375 ASPx.attachToLoad(function() {
9376  ASPx.BootstrapCore.updateTableCellStyleSheetRules(true);
9377  ASPx.BootstrapCore.initializeAccentColorRelatedSelectors(true);
9378 });
9379})(dx || (dx = {}));
9380
9381(function(dx) {
9382 (function (env) {
9383  var baseClass = env.CreateClass({
9384   constructor: function (args) {
9385    Object.defineProperty(this, '__dx__', { value: args, enumerable: false, configurable: false, writable: false });
9386    if(!args[1].getInstance)
9387     Object.defineProperty(args[1], 'getInstance', { value: args[2], enumerable: true, configurable: false, writable: false });
9388   },
9389   getType: function () { return this.__dx__[1]; },
9390   clone: function (env) { return create(this.__dx__[0], env, env ? null : this.getType()); }
9391  });
9392  function create(setupEnv, envObj, type, ret) {
9393   type = type || (type = env.CreateClass(baseClass, setupEnv(envObj || env)));
9394   return ret = new type([setupEnv, type, function () { return ret; }]);
9395  }
9396  env.CreateSingleton = create;
9397 })(ASPx);
9398 var BootstrapEventManager = {};
9399 var globalContainersStorage = {};
9400 function getEventAttachFunc(owner, key) {
9401  var cs = globalContainersStorage[owner.name];
9402  if(!cs || cs.checkSum !== owner.checkSum)
9403   cs = globalContainersStorage[owner.name] = { checkSum: (owner.checkSum = ASPx.CreateGuid()), c: {} };
9404  return cs.c[key] || (cs.c[key] = createEventHandlerContainer(
9405   owner.getEventContainers || function() { return [document.getElementById(owner.name)]; }, key));
9406 }
9407 function createEventHandlerContainer(getEventContainers, eventName) {
9408  var elements = getEventContainers();
9409  var queue = [], i = 0, order = [queue];
9410  function addToHierarchy(el, handler) {
9411   var foundQueue = queue;
9412   var detachIndex = foundQueue.length;
9413   foundQueue.push({ target: el, handler: handler });
9414   return function() { foundQueue.splice(detachIndex, 1); };
9415  }
9416  function handleEvent(e) {
9417   if(e.cancelBubble) return;
9418   var srcEl = ASPx.Evt.GetEventSource(e);
9419   for(var i = 0; !e.cancelBubble && i < order.length; i++) {
9420    var q = order[i];
9421    if(q && q.length) {
9422     for(var j = 0; !e.cancelBubble && j < q.length; j++) {
9423      if(ASPx.GetIsParent(q[j].target, srcEl)) {
9424       q[j].handler(e);
9425       break;
9426      }
9427     }
9428    }
9429   }
9430  }
9431  for(var i = 0; i < elements.length; i++) {
9432   ASPx.Evt.AttachEventToElement(elements[i], eventName, handleEvent);
9433  }
9434  return addToHierarchy;
9435 }
9436 BootstrapEventManager.attachEventToElement = function(owner, element, eventName, handler) {
9437  var detacherBagRef = element._detacherBagRef || (element._detacherBagRef = {});
9438  detacherBagRef[eventName] = getEventAttachFunc(owner, eventName)(element, handler);
9439 };
9440 BootstrapEventManager.detachEventFromElement = function(element, eventName, handler) {
9441  var detacherBagRef = element._detacherBagRef || (element._detacherBagRef = {});
9442  if(detacherBagRef[eventName])
9443   detacherBagRef[eventName]();
9444 };
9445 BootstrapEventManager.EventsHub = ASPx.CreateSingleton(function (ASPx) {
9446  var eventListenersAttachedToDOM = false, eventListenersBuffer = [], handleOnEventBubbling = true, emptyEventListener = { attach: function () { }, detach: function () { } };
9447  function ensureEventListenersActive() {
9448   if (eventListenersAttachedToDOM === true)
9449    return;
9450   eventListenersBuffer.forEach(function (f) { f(); });
9451   eventListenersBuffer = null;
9452   eventListenersAttachedToDOM = true;
9453  }
9454  function getEventListener(eventName, targetGetter) {
9455   targetGetter = targetGetter || function () { return document; };
9456   if (eventName === "mouseover" && ASPx.Browser.MobileUI)
9457    return emptyEventListener;
9458   var listeners = [];
9459   function getDepth(root, el) { return el !== root ? getDepth(root, el.parentNode) + 1 : 0; }
9460   function attachListenersToDOM() {
9461    ASPx.Evt.AttachEventToElement(targetGetter(), eventName, function (evt) {
9462     var evtSrc = ASPx.Evt.GetEventSource(evt);
9463     function invokeHandlerForListener(listener) { listener.handler(listener.el, evt, evtSrc, eventName); }
9464     function createListenerInfo(listener) {
9465      var p = ASPx.GetParentBySelector(evtSrc, listener.targetSelector);
9466      if (!p && !(listener.fallbackSelector && ASPx.ElementMatchesSelector(evtSrc, listener.fallbackSelector)))
9467       return null;
9468      return { isFallback: !p, handler: p ? listener.handler : listener.fallbackHandler, el: p || evtSrc, depth: p ? getDepth(p, evtSrc) : 0 };
9469     }
9470     function processRelatedListeners(relatedListeners, isFallback) {
9471      relatedListeners.filter(function (rl) { return rl.isFallback === isFallback; }).sort(function (a, b) { return a.depth < b.depth; }).forEach(invokeHandlerForListener);
9472     }
9473     var relatedListeners = listeners.map(createListenerInfo).filter(function (rl) { return !!rl; });
9474     processRelatedListeners(relatedListeners, false);
9475     processRelatedListeners(relatedListeners, true);
9476    }, handleOnEventBubbling);
9477   }
9478   function attach(eventListenerInfo) {
9479    var targetSelector, handler, fallbackSelector, fallbackHandler;
9480    for (var k in eventListenerInfo) {
9481     if (eventListenerInfo.hasOwnProperty(k)) {
9482      if (k === "*") {
9483       fallbackSelector = k;
9484       fallbackHandler = eventListenerInfo[k];
9485      } else {
9486       targetSelector = k;
9487       handler = eventListenerInfo[k];
9488      }
9489     }
9490    }
9491    listeners.push({ targetSelector: targetSelector, handler: handler, fallbackSelector: fallbackSelector, fallbackHandler: fallbackHandler, owner: eventListenerInfo });
9492   }
9493   function detach(eventListenerInfo) {
9494    listeners = listeners.filter(function (l) { return l.owner !== eventListenerInfo; });
9495   }
9496   eventListenersBuffer.push(attachListenersToDOM);
9497   return {
9498    attach: attach,
9499    detach: detach
9500   };
9501  }
9502  return {
9503   getEventListener: getEventListener,
9504   ensureEventListenersActive: ensureEventListenersActive
9505  };
9506 });
9507 ASPx.BootstrapEventManager = BootstrapEventManager;
9508 var BootstrapPopupManager = {};
9509 var visiblePopups;
9510 var popupInfo = function(elements, onHide){
9511  this.elements = elements;
9512  this.onHide = onHide;
9513 };
9514 BootstrapPopupManager.registerVisiblePopup = function(elements, onHide){
9515  if(!visiblePopups)
9516   visiblePopups = [];
9517  if(!ASPx.Ident.IsArray(elements))
9518   elements = [elements];
9519  visiblePopups.push(new popupInfo(elements, onHide));
9520  showPopup(elements);
9521 };
9522 BootstrapPopupManager.correctPopupPositionForClientWindow = function(elements, hAlign, hOffset, vAlign, vOffset) {
9523  correctPopupForClientWindow(ASPx.Ident.IsArray(elements) ? elements : [elements], hAlign, hOffset, vAlign, vOffset);
9524 };
9525 BootstrapPopupManager.unregisterVisiblePopup = function(elements){
9526  if(visiblePopups && visiblePopups.length && elements && elements.length) {
9527   var popupInfo = this.findPopupInfo(elements);
9528   if(popupInfo) {
9529    hidePopup(popupInfo.elements);
9530    ASPx.Data.ArrayRemove(visiblePopups, popupInfo);
9531    if(popupInfo.onHide)
9532     popupInfo.onHide();
9533   }
9534  }
9535 };
9536 BootstrapPopupManager.findPopupInfo = function(elements){ 
9537  for(var i = 0; i < visiblePopups.length; i++){
9538   if(ASPx.Data.ArrayEqual(visiblePopups[i].elements, elements))
9539    return visiblePopups[i];
9540  }
9541  return null;
9542 };
9543 BootstrapPopupManager.isPopupVisible = function(elements){ 
9544  return visiblePopups && visiblePopups.length && elements && elements.length && this.findPopupInfo(elements);
9545 };
9546 function showPopup(elements) {
9547  var originElement = getOriginElement(elements);
9548  var popupElement = getPopupElement(elements);
9549  var x = ASPx.GetAbsoluteX(originElement);
9550  var y = ASPx.GetAbsoluteY(originElement) + originElement.offsetHeight;
9551  ASPx.SetAbsoluteX(popupElement, x);
9552  ASPx.SetAbsoluteY(popupElement, y);
9553  ASPx.SetElementDisplay(popupElement, true);
9554 }
9555 function correctPopupForClientWindow(elements, hAlign, hOffset, vAlign, vOffset) {
9556  var originElement = getOriginElement(elements);
9557  var popupElement = getPopupElement(elements);
9558  ASPx.SetAbsoluteX(popupElement, correctPopupPositionToClientScreen(popupElement, originElement, true, hAlign, hOffset));
9559  ASPx.SetAbsoluteY(popupElement, correctPopupPositionToClientScreen(popupElement, originElement, false, vAlign, vOffset));
9560 }
9561 function hidePopup(elements){
9562  var popupElement = getPopupElement(elements);
9563  if(popupElement)
9564   ASPx.SetElementDisplay(popupElement, false);
9565 }
9566 function getPopupElement(elements){
9567  return elements && elements.length > 0 ? elements[0] : null;
9568 }
9569 function getOriginElement(elements){
9570  return elements && elements.length > 1 ? elements[1] : null;
9571 }
9572 function correctPopupPositionToClientScreen(popupElement, originElement, isX, align, offset) {
9573  var startPos = ASPx.InvalidPosition; 
9574  var startPosInit = isX ? ASPx.GetAbsoluteX(popupElement) : ASPx.GetAbsoluteY(popupElement);
9575  var popupPosition = isX ? ASPx.PopupUtils.GetPopupAbsoluteX(popupElement, originElement, align, offset, startPos, startPosInit, false, true)
9576   : ASPx.PopupUtils.GetPopupAbsoluteY(popupElement, originElement, align, offset, startPos, startPosInit, true, false);
9577  return popupPosition.position;
9578 }
9579 ASPx.Evt.AttachEventToDocument("mousedown", function(evt) {
9580  if(!visiblePopups || !visiblePopups.length) return;
9581  var eventSource = ASPx.Evt.GetEventSource(evt);
9582  if(typeof(ASPx.GetDropDownCollection) != "undefined") {
9583   var dropDownCollection = ASPx.GetDropDownCollection();
9584   var dropDownControl = dropDownCollection.GetDroppedDropDown();
9585   if(dropDownControl != null) {
9586    var modalWrapperElement = dropDownControl.GetMainElement().querySelector(".dxbs-ddmodal");
9587    var isEventFromModalWrapper = ASPx.GetIsParent(modalWrapperElement, eventSource);
9588    var isEventFromDropDownWindow = ASPx.GetIsParent(dropDownControl.GetDropDownWindow(), eventSource);
9589    if(!(isEventFromModalWrapper || isEventFromDropDownWindow)) {
9590     var isEventFromDropDownControl = !dropDownCollection.IsEventNotFromControlSelf(evt, dropDownControl);
9591     if(isEventFromDropDownControl)
9592      return;
9593    }
9594    var isEventOutFromModalDialog = isEventFromModalWrapper && !isEventFromDropDownWindow;
9595    if(isEventOutFromModalDialog) {
9596     dropDownControl.CloseDropDownByDocumentOrWindowEvent(false);
9597     return;
9598    }
9599    if(!dropDownControl.QueryCloseUp.IsEmpty())
9600     return;
9601   }
9602  }
9603  for(var i = visiblePopups.length - 1; i >= 0; i--) {
9604   var needHidePopup = true;
9605   var popupElements = visiblePopups[i].elements;
9606   for(var j = 0; j < popupElements.length; j++) {
9607    if(ASPx.GetIsParent(popupElements[j], eventSource))
9608     needHidePopup = false;
9609   }
9610   if(needHidePopup)
9611    BootstrapPopupManager.unregisterVisiblePopup(popupElements);
9612  }
9613 });
9614 BootstrapPopupManager.PopupZIndex = 500;
9615 BootstrapPopupManager.PopupModalZIndex = 1100;
9616 BootstrapPopupManager.PopupType = "bspopup";
9617 BootstrapPopupManager.PopupModalType = "modalbspopup";
9618 ASPx.BootstrapPopupManager = BootstrapPopupManager;
9619 var defaultDecorationStyles = { };
9620 var BootstrapEditorStyleDecoration = ASPx.CreateClass(ASPx.TextEditorStyleDecoration, {
9621  constructor: function(editor) {
9622   this.constructor.prototype.constructor.call(this, editor);
9623   if(editor.cssClasses && editor.cssClasses.nt)
9624    this.innerStyles["N"] = editor.cssClasses.nt;
9625  },
9626  InitializeNullTextClassName: function() {
9627   if(this.HasDecoration("N"))
9628    this.nullTextClassName = this.innerStyles["N"];
9629  },
9630  IsTimeEditDecorated: function() {
9631   return ASPx.Ident.IsASPxClientTimeEdit && ASPx.Ident.IsASPxClientTimeEdit(this.editor);
9632  },
9633  HasDecoration: function(key) {
9634   var editor = this.editor;
9635   var validationEnabled = editor.customValidationEnabled;
9636   var hasNullTextDecoration = key == "N" && (!!editor.nullText || this.IsTimeEditDecorated());
9637   var hasInvalidDecoration = key == "I" && validationEnabled;
9638   var hasFocusedDecoration = editor.needFocusedStyleDecoration && (key == "F" || key == "FI" && validationEnabled);
9639   var hasDecoration = hasNullTextDecoration || hasInvalidDecoration || hasFocusedDecoration;
9640   if(hasDecoration) { 
9641    var needUpdateDefaultDecoration = !defaultDecorationStyles[key] || !defaultDecorationStyles[key].isValid;
9642    if(needUpdateDefaultDecoration)
9643     BootstrapEditorStyleDecoration.UpdateDefaultDecorationStyles([key]);
9644    if(!this.innerStyles[key] && defaultDecorationStyles[key])
9645     this.innerStyles[key] = defaultDecorationStyles[key].className;
9646   }
9647   return hasDecoration;
9648  },
9649  CanApplyNullTextStyleToElement: function(element) {
9650   var needApplyNullTextClassName = this.editor.focused && this.IsTimeEditDecorated();
9651   return !needApplyNullTextClassName
9652    ? this.IsInputElement(element) && this.editor.GetInputElement() == element
9653    : false;
9654  },
9655  CanApplyFocusedStyleToElement: function(element) {
9656   var tabIndex = parseInt(ASPx.Attr.GetAttribute(element, "tabindex"));
9657   return !this.IsInputElement(element) 
9658    ? !isNaN(tabIndex) && tabIndex >= 0 || ASPx.ElementContainsCssClass(element, ASPx.BootstrapCssSelectors.FormControl)
9659    : false;
9660  },
9661  CanApplyInvalidStyleToElement: function(element) {
9662   var editor = this.editor;
9663   var isEditorInputElement = editor.GetInputElement() == element
9664    || editor.GetPasswordNullTextInputElement && editor.GetPasswordNullTextInputElement() == element;
9665   var isFormControlElement = isEditorInputElement || ASPx.ElementContainsCssClass(element, ASPx.BootstrapCssSelectors.FormControl);
9666   var isCheckInputElement = ASPx.ElementContainsCssClass(element, "form-check-input")
9667    || ASPx.ElementContainsCssClass(element, "custom-control-input");
9668   return (isFormControlElement || isCheckInputElement) != ASPx.BootstrapCore.IsBootstrap3;
9669  },
9670  ApplyFocusedStyle: function(element, inner) {
9671   var focusedInvalidStyleApplied = !this.editor.GetIsValid() && this.editor.focused && this.editor.customValidationEnabled;
9672   if(!focusedInvalidStyleApplied && this.CanApplyFocusedStyleToElement(element))
9673    ASPx.TextEditorStyleDecoration.prototype.ApplyFocusedStyle.call(this, element, true);
9674  },
9675  ApplyFocusedInvalidStyle: function(element) {
9676   if(this.CanApplyFocusedStyleToElement(element) && this.HasDecoration("FI"))
9677    this.ApplyDecoration("FI", element, true, this.editor.focused && !this.editor.GetIsValid());
9678  },
9679  ApplyInvalidStyle: function(element, inner) {
9680   if(this.CanApplyInvalidStyleToElement(element))
9681    ASPx.TextEditorStyleDecoration.prototype.ApplyInvalidStyle.call(this, element, true);
9682   this.ApplyFocusedInvalidStyle(element);
9683  },
9684  ApplyNullTextStyle: function(element, inner) {
9685   if(this.CanApplyNullTextStyleToElement(element))
9686    ASPx.TextEditorStyleDecoration.prototype.ApplyNullTextStyle.call(this, element, true);
9687  },
9688  ApplyNullTextClassName: function(active) {
9689   var nullTextClassName = this.GetNullTextClassName();
9690   var inputElement = this.editor.GetInputElement();
9691   if(active)
9692    ASPx.AddClassNameToElement(inputElement, nullTextClassName);
9693   else
9694    ASPx.RemoveClassNameFromElement(inputElement, nullTextClassName);
9695  },
9696  Update: function() {
9697   if(this.IsUpdateLocked())
9698    return;
9699   var mainElement = this.editor.GetMainElement();
9700   for(var i = 0; i < this.postfixList.length; i++) {
9701    var postfix = this.postfixList[i];
9702    var elements = postfix.length ? mainElement.querySelectorAll(postfix) : [ mainElement ];
9703    for(var j = 0; j < elements.length; j++)
9704     if(elements[j])
9705      this.ApplyStyles(elements[j], true);
9706   }
9707  },
9708  IsInputElement: function(element) {
9709   var tagName = element.tagName.toUpperCase();
9710   return tagName == "TEXTAREA" || tagName == "INPUT" || tagName == "SELECT";
9711  }
9712 });
9713 BootstrapEditorStyleDecoration.UpdateDefaultDecorationStyles = function(keys) {
9714  var container = document.createElement("DIV");
9715  ASPx.Attr.SetAttribute(container,
9716   "style", "overflow:hidden;position:fixed;z-index:10000;top:0;left:0;opacity:0;");
9717  document.body.appendChild(container);
9718  var inputElement = document.createElement("INPUT");
9719  inputElement.type = "text";
9720  ASPx.Attr.SetAttribute(inputElement,
9721   "style", "transition:none!important;-webkit-transition:none!important;-o-transition:none!important;");
9722  container.appendChild(inputElement);
9723  resetDefaultDecorationStyles(keys);
9724  if(!keys || !keys.length)
9725   keys = ["N", "I", "F", "FI"];
9726  for(var key, i = 0; key = keys[i]; i++)
9727   updateDefaultStyleDecoration(key, inputElement, container);
9728  document.body.removeChild(container);
9729 };
9730 function resetDefaultDecorationStyles(keys) {
9731  if(!keys || !keys.length)
9732   keys = ASPx.GetObjectKeys(defaultDecorationStyles);
9733  for(var key, i = 0; key = keys[i]; i++) {
9734   if(defaultDecorationStyles[key])
9735    defaultDecorationStyles[key].isValid = false;
9736  }
9737 }
9738 function updateDefaultStyleDecoration(key, input, inputContainer) {
9739  var defaultNullTextClassName = "text-muted";
9740  var defaultInvalidClassName = ASPx.BootstrapCore.IsBootstrap3 ? ASPx.BootstrapCssSelectors.HasError : ASPx.BootstrapCssSelectors.InvalidFormControl;
9741  switch(key) {
9742   case "N":
9743    if(ASPx.BootstrapCore.IsBootstrap3) {
9744     ASPx.SetClassName(input, defaultNullTextClassName);
9745     setDefaultStyleDecoration(key, "", getDecorationStyleRuleCssText(ASPx.GetCurrentStyle(input), ["color", "opacity", "text-shadow"]));
9746    }
9747    else
9748     setDefaultStyleDecoration(key, defaultNullTextClassName);
9749    break;
9750   case "I":
9751    setDefaultStyleDecoration(key, defaultInvalidClassName);
9752    break;
9753   case "F":
9754   case "FI":
9755    if(document.hasFocus()) {
9756     ASPx.SetClassName(input, ASPx.BootstrapCssSelectors.FormControl);
9757     if(key == "FI")
9758      ASPx.AddClassNameToElement(ASPx.BootstrapCore.IsBootstrap3 ? inputContainer : input, defaultInvalidClassName);
9759     setDefaultStyleDecoration(key, "", getEditorFocusedStyleRuleCssText(input));
9760    }
9761    break;
9762   default:
9763    break;
9764  }
9765 }
9766 function setDefaultStyleDecoration(key, cssClass, cssText) {
9767  if(defaultDecorationStyles[key]) {
9768   if(cssClass)
9769    defaultDecorationStyles[key].className = cssClass;
9770   else {
9771    var rule = ASPx.GetStyleSheetRules(defaultDecorationStyles[key].className);
9772    if(rule)
9773     rule.style.cssText = ASPx.CreateImportantCssText(cssText);
9774   }
9775   defaultDecorationStyles[key].isValid = true;
9776  }
9777  else {
9778   if(!cssClass && cssText)
9779    cssClass = ASPx.Str.Trim(ASPx.CreateImportantStyleRule(ASPx.GetCurrentStyleSheet(), cssText));
9780   defaultDecorationStyles[key] = createDefaultStyleDecoration(cssClass);
9781  }
9782 }
9783 function createDefaultStyleDecoration(cssClass) {
9784  return { className: cssClass, isValid: true };
9785 }
9786 function getEditorFocusedStyleRuleCssText(inputElement) {
9787  var focusedElement = ASPx.GetFocusedElement();
9788  inputElement.focus();
9789  var focusedStyle = ASPx.GetCurrentStyle(inputElement);
9790  var cssText = getDecorationStyleRuleCssText(focusedStyle, [
9791   "border-top-width", "border-top-style", "border-top-color",
9792   "border-left-width", "border-left-style", "border-left-color",
9793   "border-bottom-width", "border-bottom-style", "border-bottom-color",
9794   "border-right-width", "border-right-style", "border-right-color",
9795   "outline-width", "outline-style", "outline-color", "outline-offset",
9796   "box-shadow", "-webkit-box-shadow"
9797  ]);
9798  inputElement.blur();
9799  if(focusedElement)
9800   ASPx.SetFocus(focusedElement);
9801  return cssText;
9802 }
9803 function getDecorationStyleRuleCssText(currentStyle, styleProperties) {
9804  var rules = [ ];
9805  for(var i = 0; i < styleProperties.length; i++) {
9806   var stylePropertyValue = ASPx.Str.Trim(currentStyle.getPropertyValue(styleProperties[i])
9806) + "";
9807   if(stylePropertyValue)
9808    rules.push(styleProperties[i] + ": " + stylePropertyValue);
9809  }
9810  return rules.join(";");
9811 }
9812 ASPx.BootstrapEditorStyleDecoration = BootstrapEditorStyleDecoration;
9813 var styleUpdateListeners = [];
9814 BootstrapClientUtils = {};
9815 BootstrapClientUtils.UpdateDefaultStyles = function() {
9816  ASPx.BootstrapEditorStyleDecoration.UpdateDefaultDecorationStyles();
9817  ASPx.BootstrapCore.updateTableCellStyleSheetRules();
9818  ASPx.BootstrapCore.initializeAccentColorRelatedSelectors();
9819  for(var i = 0; i < styleUpdateListeners.length; i++)
9820   styleUpdateListeners[i].beginStyleUpdate();
9821  for(var i = 0; i < styleUpdateListeners.length; i++)
9822   styleUpdateListeners[i].updateStyle();
9823  for(var i = 0; i < styleUpdateListeners.length; i++)
9824   styleUpdateListeners[i].endStyleUpdate();
9825 };
9826 BootstrapClientUtils.attachToUpdateDefaultStylesRequest = function(styleUpdateListener) {
9827  styleUpdateListeners.push(styleUpdateListener);
9828 };
9829 BootstrapClientUtils.detachUpdateDefaultStylesRequestListener = function(styleUpdateListener) {
9830  ASPx.Data.ArrayRemove(styleUpdateListeners, styleUpdateListener);
9831 };
9832 BootstrapClientUtils.GetChangeButtonEnabledAttributesMethod = function(enabled) {
9833  return enabled
9834   ? function(element, className) {
9835    if(element.tagName == "BUTTON")
9836     ASPx.Attr.RemoveAttribute(element, "disabled");
9837    else
9838     ASPx.RemoveClassNameFromElement(element, className);
9839   }
9840   : function(element, className) {
9841    if(element.tagName == "BUTTON")
9842     ASPx.Attr.SetAttribute(element, "disabled", "disabled");
9843    else
9844     ASPx.AddClassNameToElement(element, className);
9845   };
9846 };
9847 var BootstrapEditFeedbackRenderHelper = ASPx.CreateClass(null, {
9848  constructor: function(editor) {
9849   this.editor = editor;
9850  },
9851  getErrorImage: function() {
9852   var editorElement = this.editor.GetMainElement();
9853   return editorElement && editorElement.querySelector("[data-error-image]");
9854  },
9855  getClearButton: function() {
9856   var editorElement = this.editor.GetMainElement();
9857   return editorElement && editorElement.querySelector(BootstrapEditFeedbackRenderHelper.FeedbackSelector + " > .dxbs-clear-btn");
9858  },
9859  getErrorTextElement: function() {
9860   var editorElement = this.editor.GetMainElement();
9861   return editorElement && editorElement.querySelector(".dxbs-edit-error-text");
9862  },
9863  setElementVisible: function(element, value) {
9864   if(element && ASPx.ElementHasCssClass(element, ASPx.BootstrapCssSelectors.Hidden) == value) {
9865    var action = value ? ASPx.RemoveClassNameFromElement : ASPx.AddClassNameToElement;
9866    action(element, ASPx.BootstrapCssSelectors.Hidden);
9867    this.updateInputRightPadding();
9868   }
9869  },
9870  setClearButtonVisible: function(value) {
9871   var clearButton = this.getClearButton();
9872   if(!clearButton)
9873    return;
9874   if(this.editor.clearButtonDisplayMode === 'Always' && ASPx.Attr.GetAttribute(clearButton, "role") == "button")
9875    this.editor.SetAccessibilityAnchorEnabled(clearButton, value);
9876   this.setElementVisible(clearButton, value);
9877  },
9878  setErrorControlVisible: function(value) {
9879   var errorTextElement = this.getErrorTextElement();
9880   if(errorTextElement)
9881    this.setElementVisible(errorTextElement, value);
9882   if(this.editor.errorDisplayMode == "i")
9883    this.setErrorImageVisible(value);
9884  },
9885  setErrorImageVisible: function(value) {
9886   var errorImage = this.getErrorImage();
9887   if(errorImage) {
9888    if(!this.getErrorTextElement() && !ASPx.BootstrapCore.IsBootstrap3) {
9889     var feedbackControl = this.editor.GetMainElement().querySelector(BootstrapEditFeedbackRenderHelper.FeedbackSelector);
9890     var action = value ? ASPx.AddClassNameToElement : ASPx.RemoveClassNameFromElement;
9891     action(feedbackControl || errorImage, ASPx.BootstrapCssSelectors.InvalidFeedback);
9892    }
9893    this.setElementVisible(errorImage, value);
9894    if(!value) {
9895     ASPx.Attr.RemoveAttribute(errorImage, "title");
9896     ASPx.Attr.RemoveAttribute(errorImage, "data-error-tooltip");
9897    }
9898    else
9899     this.updateErrorText();
9900   }
9901  },
9902  updateErrorText: function() {
9903   var errorText = this.editor.HtmlEncode(this.editor.errorText);
9904   var errorTextElement = this.getErrorTextElement();
9905   if(errorTextElement) {
9906    var textNode = ASPx.GetNormalizedTextNode(errorTextElement);
9907    if(textNode) {
9908     textNode.nodeValue = errorText;
9909     return;
9910    }
9911   }
9912   var errorImage = this.getErrorImage();
9913   if(errorImage) {
9914    ASPx.Attr.SetAttribute(errorImage, "title", errorText);
9915    if(ASPx.Browser.TouchUI) {
9916     var x = ASPx.GetAbsolutePositionX(errorImage);
9917     var docWidth = ASPx.Browser.WebKitTouchUI ? window.innerWidth : ASPx.GetDocumentClientWidth();       
9918     var availableWidth = this.editor.isASPxClientCheckEdit ? docWidth - x - errorImage.offsetWidth : x;
9919     if(availableWidth > 0) {
9920      var fontSize = ASPx.GetCurrentStyle(errorImage).fontSize;
9921      ASPx.Attr.SetAttribute(errorImage, "data-error-tooltip", this.formatErrorText(errorText, availableWidth, fontSize));
9922     }
9923    }
9924   }
9925  },
9926  formatErrorText: function(errorText, availableWidth, fontSize) {
9927   var errorTextSize = ASPx.GetSizeOfText(errorText, {
9928    fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif',
9929    fontSize: 'calc(0.75 * ' + fontSize + ')',
9930    fontWeight: "normal",
9931    letterSpacing: "normal",
9932    lineHeight: "2"
9933   }).width + 1.2 * ASPx.PxToInt(fontSize);
9934   if(errorTextSize > availableWidth) {
9935    var availableCharCount = Math.floor(errorText.length * availableWidth / errorTextSize);
9936    if(availableCharCount) {
9937     var errorTextRows = [];
9938     while(errorText && errorText.length) {
9939      var textRow = errorText.substr(0, availableCharCount);
9940      var spacesAtStart = /(^\s+)\S/.exec(textRow);
9941      if(spacesAtStart)
9942       textRow = errorText.substr(0, availableCharCount + spacesAtStart[1].length);
9943      var spacesAtEnd = /(\s+)\S{1,4}$/.exec(textRow);
9944      if(spacesAtEnd && spacesAtEnd.index)
9945       textRow = errorText.slice(0, spacesAtEnd.index + spacesAtEnd[1].length);
9946      errorTextRows.push(ASPx.Str.TrimStart(textRow));
9947      errorText = errorText.replace(textRow, "");
9948     }
9949     errorText = errorTextRows.join("\n");
9950    }
9951   }
9952   return errorText;
9953  },
9954  updateInputRightPadding: function() {
9955   if(this.editor.isASPxClientTextEdit) {
9956    var feedbackControl = this.editor.GetMainElement().querySelector(BootstrapEditFeedbackRenderHelper.FeedbackSelector);
9957    if(feedbackControl) {
9958     var feedbackWidth = feedbackControl.offsetWidth;
9959     var formControl = this.editor.GetFormControlElement ? this.editor.GetFormControlElement() : this.editor.GetInputElement();
9960     formControl.style["padding-right"] = feedbackWidth ? feedbackWidth + "px" : "";
9961     if(this.editor.UpdateDropDownOnFeedbackChanged)
9962      this.editor.UpdateDropDownOnFeedbackChanged();
9963    }
9964   }
9965  }
9966 });
9967 BootstrapEditFeedbackRenderHelper.FeedbackSelector = "." + ASPx.BootstrapCssSelectors.FormControlFeedback;
9968 ASPx.BootstrapEditFeedbackRenderHelper = BootstrapEditFeedbackRenderHelper;
9969 var BootstrapTextEditHelpText = ASPx.CreateClass(null, {
9970  constructor: function(editor, helpText, animationEnabled, isPopupDisplayMode) {
9971   this.editor = editor;
9972   this.isPopupDisplayMode = isPopupDisplayMode;
9973   this.animationEnabled = animationEnabled;
9974   this.createHelpTextElement(helpText);
9975  },
9976  createHelpTextElement: function(helpText) {
9977   var helpTextElement = document.createElement("SPAN");
9978   ASPx.SetClassName(helpTextElement, ASPx.BootstrapCssSelectors.HelpBlock);
9979   ASPx.Security.setInnerHtml(helpTextElement, helpText, ASPx.Security.DataType.Trusted);
9980   ASPx.InsertElementAfter(helpTextElement, this.editor.GetHelpTextElementPrevSibling());
9981   if(this.isPopupDisplayMode) {
9982    var parentNode = helpTextElement.parentNode;
9983    if(parentNode) {
9984     var parentStyle = ASPx.GetCurrentStyle(parentNode);
9985     if(parentStyle.position != "relative")
9986      parentNode.style.position = "relative";
9987    }
9988    ASPx.AddClassNameToElement(helpTextElement, "dxbs-popup-help-text mark");
9989    ASPx.SetElementDisplay(helpTextElement, false);
9990   }
9991   else {
9992    ASPx.SetElementDisplay(helpTextElement, this.editor.clientVisible);
9993    if(!ASPx.BootstrapCore.IsBootstrap3)
9994     ASPx.AddClassNameToElement(helpTextElement, "text-muted");
9995   }
9996   this.helpTextElement = helpTextElement;
9997  },
9998  show: function() {
9999   if(this.isPopupDisplayMode)
10000    this.showPopup();
10001   else
10002    ASPx.SetElementDisplay(this.helpTextElement, true);
10003  },
10004  hide: function() {
10005   if(this.isPopupDisplayMode)
10006    this.hidePopup();
10007   else
10008    ASPx.SetElementDisplay(this.helpTextElement, false);
10009  },
10010  showPopup: function() {
10011   ASPx.SetElementDisplay(this.helpTextElement, true);
10012   if(this.animationEnabled)
10013    ASPx.AnimationHelper.fadeIn(this.helpTextElement);
10014   else
10015    ASPx.AnimationHelper.setOpacity(this.helpTextElement, 1);
10016  },
10017  hidePopup: function() {
10018   var onHidePopupComplete = function() {
10019    ASPx.SetElementDisplay(this.helpTextElement, false);
10020   }.aspxBind(this);
10021   if(this.animationEnabled)
10022    ASPx.AnimationHelper.fadeOut(this.helpTextElement, onHidePopupComplete);
10023   else {
10024    ASPx.AnimationHelper.setOpacity(this.helpTextElement, 0);
10025    onHidePopupComplete();
10026   }    
10027  }
10028 });
10029 ASPx.BootstrapTextEditHelpText = BootstrapTextEditHelpText;
10030 var BootstrapCheckBoxInternal = ASPx.CreateClass(null, {
10031  constructor: function(mainElement, allowGrayed, allowGrayedByClick, storeValueInInput, inputName) {
10032   this.mainElement = mainElement;
10033   this.allowGrayed = allowGrayed;
10034   this.allowGrayedByClick = allowGrayedByClick;
10035   this.storeValueInInput = storeValueInInput;
10036   if(this.storeValueInInput)
10037    this.stateInput = this.createStateInput(inputName);
10038   this.mainInput = this.findMainInput();
10039   this.initializeSiblingLabelElement();
10040   this.initializeIndeterminateState();
10041   this.CheckedChanged = new ASPxClientEvent();
10042   this.Focus = new ASPxClientEvent();
10043   this.LostFocus = new ASPxClientEvent();
10044   this.attachHtmlEvents();
10045   this.updateState();
10046  },
10047  SetValue: function(value) { 
10048   this.setValueCore(value);
10049  },
10050  GetValue: function() {
10051   return this.getValueCore();
10052  },
10053  GetChecked: function() {
10054   return this.getValueCore() === true;
10055  },
10056  SetChecked: function(checked) {
10057   this.setValueCore(!!checked);
10058  },
10059  SetEnabled: function(enabled) {
10060   this.setEnabledCore(enabled);
10061  },
10062  GetEnabled: function() {
10063   return this.getEnabledCore();
10064  },
10065  GetReadOnly: function() {
10066   return false;
10067  },
10068  attachHtmlEvents: function() {
10069   var isMSBrowser = ASPx.Browser.Edge;
10070   ASPx.Evt.AttachEventToElement(this.mainInput, "change", function(evt) {
10071    if(this.allowGrayed && this.allowGrayedByClick && isMSBrowser) {
10072     ASPx.Evt.PreventEvent(evt);
10073     return false;
10074    }
10075    if(!this.correctNextValue())
10076     this.updateState();
10077    this.CheckedChanged.FireEvent(this, evt);
10078   }.bind(this));
10079   ASPx.Evt.AttachEventToElement(this.mainInput, "focus", function(evt) {
10080    this.Focus.FireEvent(this, null);
10081   }.bind(this));
10082   ASPx.Evt.AttachEventToElement(this.mainInput, "blur", function(evt) {
10083    this.LostFocus.FireEvent(this, null);
10084   }.bind(this));
10085   ASPx.Evt.AttachEventToElement(this.mainInput, "click", function(evt) {
10086    if (this.GetReadOnly()) {
10087     ASPx.Evt.PreventEvent(evt);
10088     return false;
10089    }
10090    if(this.allowGrayed && isMSBrowser) {
10091     var raiseCheckedChanged = false;
10092     if(this.allowGrayedByClick && this.lastValue) {
10093      this.setValueCore(false);
10094      raiseCheckedChanged = true;
10095     } 
10096     else if(this.correctNextValue()) {
10097      this.updateState();
10098      raiseCheckedChanged = true;
10099     }
10100     if(raiseCheckedChanged)
10101      this.CheckedChanged.FireEvent(this, evt);
10102    }
10103   }.bind(this));
10104  },
10105  invokeClick: function() {
10106   if(this.mainInput){
10107    this.mainInput.focus();
10108    this.mainInput.click();
10109   }
10110  },
10111  correctNextValue: function() {
10112   if(!this.allowGrayed)
10113    return;
10114   if(this.allowGrayedByClick && this.lastValue === false){
10115    this.setValueCore(null);
10116    return true;
10117   }
10118   if(this.lastValue === null) {
10119    this.setValueCore(true);
10120    return true;
10121   }
10122  },
10123  findMainInput: function() {
10124   return this.mainElement.querySelectorAll("[type=checkbox]")[0] || this.mainElement.querySelectorAll("[type=radio]")[0];
10125  },
10126  createStateInput: function (inputName) {
10127   var input = ASPx.CreateHiddenField(inputName, this.mainElement.id + "_S");
10128   this.mainElement.appendChild(input);
10129   return input;
10130  },
10131  initializeIndeterminateState: function() {
10132   if(ASPx.Attr.GetAttribute(this.mainInput, "data-value") === "indeterminate") {
10133    ASPx.Attr.RemoveAttribute(this.mainInput, "data-value");
10134    this.mainInput.indeterminate = true;
10135   }
10136  },
10137  initializeSiblingLabelElement: function() {
10138   if(this.mainInput && this.mainInput.id) {
10139    var siblingLabel = this.mainElement.querySelectorAll("[type=checkbox]+label, label+[type=checkbox], [type=radio]+label, label+[type=radio]")[0];
10140    if(siblingLabel)
10141     ASPx.Attr.SetAttribute(siblingLabel, "for", this.mainInput.id);
10142   }
10143  },
10144  setValueCore: function(value) {
10145   if(value === true || value === ASPx.CheckBoxInputKey.Checked) {
10146    this.mainInput.checked = true;
10147    this.mainInput.indeterminate = false;
10148    this.updateState(true);
10149   }
10150   else if(value === false || value === ASPx.CheckBoxInputKey.Unchecked) {
10151    this.mainInput.checked = false;
10152    this.mainInput.indeterminate = false;
10153    this.updateState(false);
10154   }
10155   else if(value === null || value === ASPx.CheckBoxInputKey.Indeterminate) {
10156    this.mainInput.indeterminate = true;
10157    this.updateState(null);
10158   }
10159  },
10160  getValueCore: function() {
10161   var mainInput = this.mainInput;
10162   if(mainInput.indeterminate)
10163    return null;
10164   return mainInput.checked;
10165  },
10166  setEnabledCore: function(enabled) {
10167   if(enabled) {
10168    ASPx.RemoveClassNameFromElement(this.mainElement, ASPx.BootstrapCssSelectors.Disabled);
10169    ASPx.Attr.RemoveAttribute(this.mainInput, "disabled");
10170    if(this.stateInput)
10171     ASPx.Attr.RemoveAttribute(this.stateInput, "disabled");
10172   }
10173   else {
10174    ASPx.AddClassNameToElement(this.mainElement, ASPx.BootstrapCssSelectors.Disabled);
10175    ASPx.Attr.SetAttribute(this.mainInput, "disabled", "disabled");
10176    if(this.stateInput)
10177     ASPx.Attr.SetAttribute(this.stateInput, "disabled", "disabled");
10178   }
10179  },
10180  getEnabledCore: function() {
10181   return !ASPx.Attr.GetAttribute(this.mainInput, "disabled");
10182  },
10183  updateState: function(value) {
10184   value = value === undefined ? this.getValueCore() : value;
10185   this.lastValue = value;
10186   var stateInput = this.stateInput;
10187   if(stateInput) {
10188    if(value === true)
10189     stateInput.value = ASPx.CheckBoxInputKey.Checked;
10190    else if(value === false)
10191     stateInput.value = ASPx.CheckBoxInputKey.Unchecked;
10192    else
10193     stateInput.value = ASPx.CheckBoxInputKey.Indeterminate;
10194   }
10195  }
10196 });
10197 var BootstrapCheckBoxInternalCollection = ASPx.CreateClass(ASPx.CollectionBase, {
10198  constructor: function(allowGrayed, allowGrayedByClick, storeValueInInput) {
10199   this.constructor.prototype.constructor.call(this);
10200   this.allowGrayed = !!allowGrayed;
10201   this.allowGrayedByClick = !!allowGrayedByClick;
10202   this.storeValueInInput = !!storeValueInInput;
10203  },
10204  Add: function(key, mainElement) {
10205   this.Remove(key);
10206   var checkBox = this.createInternalCheckBox(key, mainElement);
10207   ASPx.CollectionBase.prototype.Add.call(this, key, checkBox);
10208   return checkBox;
10209  },
10210  createInternalCheckBox: function(key, mainElement) {
10211   return new BootstrapCheckBoxInternal(mainElement, this.allowGrayed, this.allowGrayedByClick, this.storeValueInInput);
10212  }
10213 });
10214 ASPx.BootstrapCheckBoxInternal = BootstrapCheckBoxInternal;
10215 ASPx.BootstrapCheckBoxInternalCollection = BootstrapCheckBoxInternalCollection;
10216 var BootstrapLoadingPanelManager = {};
10217 var loadingPanels = {};
10218 var loadingDivs = {};
10219 BootstrapLoadingPanelManager.getLoadingPanel = function(name, settings, inline) {
10220  if(!settings) return null;
10221  var lpID = name + "_LP";
10222  if(!loadingPanels[lpID]){
10223   var lp = document.createElement("DIV");
10224   lp.id = lpID;
10225   ASPx.SetClassName(lp, ASPx.Str.Trim([
10226    "dxbs-lp" + (inline ? " dxbs-lp-inline" : ""),
10227    ASPx.HiddenChangable, ASPx.BootstrapCssSelectors.Panel, ASPx.BootstrapCssSelectors.PanelDefault
10228   ].join(" ")));
10229   var lpBody = document.createElement("DIV");
10230   ASPx.SetClassName(lpBody, ASPx.BootstrapCssSelectors.PanelBody);
10231   if(settings.showImage !== false) {
10232    var lpImg = document.createElement("SPAN");
10233    var imgCssClass = settings.imageCssClass ? settings.imageCssClass : "dxbs-icon dxbs-icon-refresh";
10234    ASPx.SetClassName(lpImg, "image " + imgCssClass);
10235    lpBody.appendChild(lpImg);
10236   }
10237   if(settings.text !== "") {
10238    var breakHtml = "";
10239    var textHtml = "<span>" + (settings.text || "Loading&hellip;") + "</span>";
10240    if(settings.imagePosition && (settings.imagePosition === "Top" || settings.imagePosition === "Bottom")) 
10241     breakHtml = "<br />";
10242    if(settings.imagePosition && (settings.imagePosition === "Right" || settings.imagePosition === "Bottom"))
10243     ASPx.Security.setInnerHtml(lpBody, textHtml + breakHtml + lpBody.innerHTML, ASPx.Security.DataType.Trusted);
10244    else
10245     ASPx.Security.setInnerHtml(lpBody, lpBody.innerHTML + breakHtml + textHtml, ASPx.Security.DataType.Trusted);
10246   }
10247   lp.appendChild(lpBody);
10248   loadingPanels[lpID] = lp;
10249  }
10250  return loadingPanels[lpID];
10251 };
10252 BootstrapLoadingPanelManager.getLoadingDiv = function(name, settings){
10253  if(!settings || settings.fade === false) return null;
10254  var ldID = name + "_LD";
10255  if(!loadingDivs[ldID]){
10256   var ld = document.createElement("DIV");
10257   ld.id = ldID;
10258   ASPx.SetClassName(ld, "dxbs-ld " + ASPx.HiddenChangable);
10259   loadingDivs[ldID] = ld;
10260  }
10261  return loadingDivs[ldID];
10262 };
10263 ASPx.BootstrapLoadingPanelManager = BootstrapLoadingPanelManager;
10264 var BootstrapOverlayManager = {};
10265 BootstrapOverlayManager.createOverlay = function(name, settings) {
10266  var overlay = document.createElement("DIV");
10267  overlay.id = name + "_OV";
10268  ASPx.SetClassName(overlay, ASPx.BootstrapCssSelectors.ModalBackdrop + " dxbs-modal-back" + (settings.cssClass ? " " + settings.cssClass : ""));
10269  return overlay;
10270 };
10271 ASPx.BootstrapOverlayManager = BootstrapOverlayManager;
10272 var BootstrapBadgeManager = ASPx.CreateClass(ASPx.BadgeManagerBase, {
10273  getBadgeClassName: function() {
10274   return ASPx.BootstrapCssSelectors.Badge;
10275  },
10276  getBadgeIconDefaultClassName: function() {
10277   return "image";
10278  },
10279  createBadgeForButton: function(button, toLeftSide) {
10280   var badge = this.createBadge();
10281   if(!ASPx.BootstrapCore.IsBootstrap3) {
10282    ASPx.AddClassNameToElement(badge, ASPx.BootstrapCssSelectors.BadgePill);
10283    if (ASPx.ElementHasCssClass(button, ASPx.BootstrapCssSelectors.ButtonDanger)) {
10284     ASPx.AddClassNameToElement(badge, ASPx.BootstrapCssSelectors.BadgeLight);
10285     ASPx.AddClassNameToElement(badge, ASPx.BootstrapCssSelectors.TextDanger);
10286    }
10287    else if(ASPx.ElementHasCssClass(button, ASPx.BootstrapCssSelectors.ButtonSecondary) || ASPx.ElementHasCssClass(button, ASPx.BootstrapCssSelectors.ButtonOutlineSecondary))
10288     ASPx.AddClassNameToElement(badge, ASPx.BootstrapCssSelectors.BadgeDark);
10289    else if(ASPx.ElementHasCssClass(button, ASPx.BootstrapCssSelectors.ButtonLink))
10290     ASPx.AddClassNameToElement(badge, ASPx.BootstrapCssSelectors.BadgePrimary);
10291    else
10292     ASPx.AddClassNameToElement(badge, ASPx.BootstrapCssSelectors.TextPrimary);
10293   }
10294   if(toLeftSide)
10295    button.insertBefore(badge, button.childNodes[0]);
10296   else
10297    button.appendChild(badge);
10298   return badge;
10299  },
10300  updateToolbarItemBadge: function(item, count) {
10301   var button = item.menu.IsEnabledAdaptivity() ? item.itemViewModel.getElement() : item.menu.GetItemContentElement(item.indexPath);
10302   var badge = this.findBadge(button);
10303   if(!badge)
10304    badge = this.createBadgeForButton(button);
10305   if(badge)
10306    this.setBadgeText(badge, count > 0 ? count : "");
10307  }
10308 });
10309 ASPx.BootstrapBadgeManager = new BootstrapBadgeManager();
10310 var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
10310+/=";
10311 var getBase64Char = function(index) {
10312  return BASE64_CHARS.charAt(index);
10313 };
10314 var getIndexOfBase64Char = function(char) {
10315  return BASE64_CHARS.indexOf(char);
10316 };
10317 var codeArrayToString = function(codes) {
10318  return codes.map(function(code) { return String.fromCharCode(code); }).join("");
10319 };
10320 var base64_encode = function(input) {
10321  var result = "";
10322  if (!$.isArray(input))
10323   input = stringToByteArray(String(input));
10324  for (var i = 0; i < input.length; i += 3) {
10325   var octet1 = input[i],
10326    octet2 = input[i + 1],
10327    octet3 = input[i + 2];
10328   result += $.map([octet1 >> 2, (3 & octet1) << 4 | octet2 >> 4, isNaN(octet2) ? 64 : (15 & octet2) << 2 | octet3 >> 6, isNaN(octet3) ? 64 : 63 & octet3], getBase64Char).join("");
10329  }
10330  return result;
10331 };
10332 var base64_decode = function(input) {
10333  var result = "";
10334  input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
10335  for (var i = 0; i < input.length; i += 4) {
10336   var bytes = [];
10337   var octet1 = getIndexOfBase64Char(input.charAt(i)),
10338    octet2 = getIndexOfBase64Char(input.charAt(i + 1)),
10339    octet3 = getIndexOfBase64Char(input.charAt(i + 2)),
10340    octet4 = getIndexOfBase64Char(input.charAt(i + 3));
10341   bytes.push((octet1 << 2) | (octet2 >> 4));
10342   if(octet3 != 64)
10343    bytes.push(((octet2 & 15) << 4) | (octet3 >> 2));
10344   if(octet4 != 64)
10345    bytes.push(((octet3 & 3) << 6) | octet4);
10346   result += codeArrayToString(bytes);
10347  }
10348  return decodeText(result);
10349 };
10350 var stringToByteArray = function(str) { 
10351  var bytes = [];
10352  var code = 0;
10353  for (var i = 0; i < str.length; i++) {
10354   code = str.charCodeAt(i);
10355   if (code < 128) {
10356    bytes.push(code);
10357   } else {
10358    if (code < 2048) {
10359     bytes.push(192 + (code >> 6), 128 + (63 & code));
10360    } else {
10361     if (code < 65536) {
10362      bytes.push(224 + (code >> 12), 128 + (code >> 6 & 63), 128 + (63 & code));
10363     } else {
10364      if (code < 2097152) {
10365       bytes.push(240 + (code >> 18), 128 + (code >> 12 & 63), 128 + (code >> 6 & 63), 128 + (63 & code));
10366      }
10367     }
10368    }
10369   }
10370  }
10371  return bytes;
10372 };
10373 var decodeText = function(codeText) {
10374  var bytes = [];
10375  var code = 0, 
10376   code2 = 0,
10377   code3 = 0;
10378  for (var i = 0; i < codeText.length; i++) {
10379   code = codeText.charCodeAt(i);
10380   if (code < 128) {
10381    bytes.push(code);
10382   } else {
10383    i += 1;
10384    code2 = codeText.charCodeAt(i);
10385    if((code > 191) && (code < 224)) {
10386     bytes.push(((code & 31) << 6) | (code2 & 63));
10387    } else {
10388     i += 1;
10389     code3 = codeText.charCodeAt(i);
10390     bytes.push(((code & 15) << 12) | ((code2 & 63) << 6) | (code3 & 63));
10391    }
10392   }
10393  }
10394  return codeArrayToString(bytes);
10395 };
10396 ASPx.Base64 = {};
10397 ASPx.Base64.Encode = base64_encode;
10398 ASPx.Base64.Decode = base64_decode;
10399 dx.BootstrapClientUtils = BootstrapClientUtils;
10400 ASPx.BootstrapDockManager = ASPx.CreateSingleton(function(ASPx) {
10401  var showCssClass = "show",
10402   matrixRegex = "\\s*matrix\\(\\s*" + ([0, 0, 0, 0, 0, 0].map(function() { return "(\\-?\\d+\\.?\\d*)"; }).join(",\\s*")) + "\\)\\s*";
10403  function parseTranslateInfo(styles) {
10404   var m = new RegExp(matrixRegex).exec(styles.transform);
10405   return m ? { left: parseInt(m[5]), top: parseInt(m[6]) } : { left: 0, top: 0 };
10406  }
10407  function getBoundingBox(x, y, w, h) { return { left: x, top: y, right: x + w, bottom: y + h, width: w, height: h }; }
10408  function getSafeBoundingBox(element, roundLT, roundRB) {
10409   var box = element.getBoundingClientRect();
10410   var safeBox = { left: roundLT(box.left), top: roundLT(box.top), right: roundRB(box.right), bottom: roundRB(box.bottom) };
10411   safeBox.width = safeBox.right - safeBox.left;
10412   safeBox.height = safeBox.bottom - safeBox.top;
10413   return safeBox;
10414  }
10415  function getOuterBoundingBox(element) {
10416   return getSafeBoundingBox(element, Math.floor, Math.ceil);
10417  }
10418  function getInnerBoundingBox(element) {
10419   return getSafeBoundingBox(element, Math.ceil, Math.floor);
10420  }
10421  var DockPoint = ASPx.CreateClass(null, {
10422   constructor: function (key, info) {
10423    this.key = key;
10424    this.info = info;
10425   },
10426   checkMargin: function () { return true; },
10427   allowScroll: function () { return this.info.size === "height"; },
10428   canApplyToElement: function(element) { return ASPx.GetClassName(element).indexOf("dxbs-align-" + this.key) > -1; },
10429   getRange: function (dockInfo) {
10430    var c1 = this.getTargetBox(dockInfo)[this.info.to];
10431    var c2 = c1 + this.info.sizeM * (dockInfo.elementBox[this.info.size] + (this.checkMargin() ? dockInfo.margin : 0));
10432    return { 
10433     from: Math.min(c1, c2), 
10434     to: Math.max(c1, c2), 
10435     windowOverflow: 0
10436    };
10437   },
10438   getTargetBox: function (dockInfo) { return null; },
10439   validate: function (range, windowInfo) {
10440    var windowSize = windowInfo[this.info.size];
10441    range.windowOverflow = Math.abs(Math.min(0, range.from - windowSize.from) + Math.min(0, windowSize.to - range.to));
10442    range.validTo = Math.min(range.to, windowSize.to);
10443    range.validFrom = Math.max(range.from, windowSize.from);
10444    return range.windowOverflow === 0;
10445   },
10446   applyRange: function (range, dockInfo) {
10447    dockInfo.appliedModifierKeys[this.info.size] = this.key;
10448    var side = this.info.size === "width" ? "left" : "top";
10449    var style = dockInfo.styles;
10450    var from = range.from;
10451    if (this.allowScroll() && range.windowOverflow > 0) {
10452     if (!dockInfo.limitBox.scroll.width) {
10453      dockInfo.limitBox.scroll.width = true;
10454      dockInfo.limitBox.width.to -= ASPx.GetVerticalScrollBarWidth();
10455     }
10456     if (dockInfo.isScrollable) {
10457      style["max-height"] = dockInfo.height - range.windowOverflow + "px";
10458      dockInfo.width += ASPx.GetVerticalScrollBarWidth();
10459      dockInfo.elementBox.width += ASPx.GetVerticalScrollBarWidth();
10460      from = range.validFrom;
10461     }
10462    }
10463    style.width = dockInfo.width + "px";
10464    if(this.checkMargin())
10465     from += Math.max(0, this.info.sizeM) * dockInfo.margin;
10466    dockInfo.elementBox[side] += from;
10467    style["transform"] = 
10468     "matrix(1, 0, 0, 1, " + dockInfo.elementBox.left + ", " + dockInfo.elementBox.top + ")";
10469   },
10470   dockElementToTarget: function (dockInfo) {
10471    var range1 = this.getRange(dockInfo);
10472    if (!this.dockElementToTargetInternal(range1, dockInfo))
10473     this.applyRange(range1, dockInfo);
10474   },
10475   dockElementToTargetInternal: function (range1, dockInfo) { }
10476  });
10477  var OuterDockPoint = ASPx.CreateClass(DockPoint, {
10478   constructor: function (name, info, oppositePointName) {
10479    this.constructor.prototype.constructor.apply(this, arguments);
10480    this.oppositePointName = oppositePointName || null;
10481   },
10482   getTargetBox: function (dockInfo) { return dockInfo.targetBox.outer; },
10483   getOppositePoint: function () {
10484    return this._oppositePoint || (this._oppositePoint = dockPoints.filter(function (d) {
10485     return d.key === this.oppositePointName;
10486    }.bind(this))[0]);
10487   },
10488   dockElementToTargetInternal: function (range1, dockInfo) {
10489    if (this.validate(range1, dockInfo.limitBox))
10490     this.applyRange(range1, dockInfo);
10491    else {
10492     var oppositePoint = this.getOppositePoint();
10493     var range2 = oppositePoint.getRange(dockInfo);
10494     if (oppositePoint.validate(range2, dockInfo.limitBox) || range2.windowOverflow < range1.windowOverflow)
10495      oppositePoint.applyRange(range2, dockInfo);
10496     else
10497      return false;
10498    }
10499    return true;
10500   }
10501  });
10502  var InnerDockPoint = ASPx.CreateClass(DockPoint, {
10503   checkMargin: function () { return false; },
10504   getTargetBox: function (dockInfo) { return dockInfo.targetBox.inner; },
10505   dockElementToTargetInternal: function (range1, dockInfo) {
10506    this.validate(range1, dockInfo.limitBox);
10507    return false;
10508   },
10509   validate: function (range, windowInfo) {
10510    var toOverflow = Math.min(range.from, Math.max(0, range.to - windowInfo[this.info.size].to));
10511    if (toOverflow > 0) {
10512     range.from -= toOverflow;
10513     range.to -= toOverflow;
10514    }
10515    return DockPoint.prototype.validate.call(this, range, windowInfo);
10516   }
10517  });
10518  var dockPoints = [
10519   new OuterDockPoint("above", { to: "top", from: "bottom", size: "height", sizeM: -1 }, "below"),
10520   new OuterDockPoint("below", { to: "bottom", from: "top", size: "height", sizeM: 1 }, "above"),
10521   new InnerDockPoint("top-sides", { to: "top", from: "top", size: "height", sizeM: 1 }),
10522   new InnerDockPoint("bottom-sides", { to: "bottom", from: "bottom", size: "height", sizeM: -1 }),
10523   new OuterDockPoint("outside-left", { to: "left", from: "right", size: "width", sizeM: -1 }, "outside-right"),
10524   new OuterDockPoint("outside-right", { to: "right", from: "left", size: "width", sizeM: 1 }, "outside-left"),
10525   new InnerDockPoint("left-sides", { to: "left", from: "left", size: "width", sizeM: 1 }),
10526   new InnerDockPoint("right-sides", { to: "right", from: "right", size: "width", sizeM: -1 })
10527  ];
10528  var defaultHorizontalItemDockPoints = [dockPoints[1], dockPoints[6]],
10529   defaultVerticalItemDockPoints = [dockPoints[2], dockPoints[5]];
10530  function getElementPopupInfo(element, targetElement, isVertical, settings) {
10531   var elementStyle = ASPx.GetCurrentStyle(element);
10532   var box = getOuterBoundingBox(element);
10533   var docEl = element.ownerDocument.documentElement;
10534   var result = {
10535    isScrollable: ASPx.ElementHasCssClass(element, "dxbs-scrollable"),
10536    specifiedOffsetModifiers: dockPoints.filter(function (m) { return m.canApplyToElement(element); }),
10537    margin: ASPx.PxToInt(elementStyle.marginTop),
10538    width: settings ? Math.max(settings.width, Math.ceil(element.offsetWidth)) : Math.ceil(element.offsetWidth),
10539    height: Math.ceil(element.offsetHeight),
10540    appliedModifierKeys: { height: null, width: null }
10541   };
10542   var styles = parseTranslateInfo(elementStyle);
10543   result.elementBox = getBoundingBox(styles.left - box.left, styles.top - box.top, box.width, box.height); 
10544   result.targetBox = { outer: getOuterBoundingBox(targetElement), inner: getInnerBoundingBox(targetElement) };
10545   result.limitBox = {
10546    scroll: { width: docEl.clientWidth < window.innerWidth, height: docEl.clientHeight < window.innerHeight },
10547    width: { from: 0, to: docEl.clientWidth },
10548    height: { from: 0, to: docEl.clientHeight }
10549   };
10550   result.styles = {};
10551   var highPriorityModifiersData = ASPx.Attr.GetAttribute(element, "data-popup-align") || settings && settings.align;
10552   if (highPriorityModifiersData) {
10553    var highPriorityModifiers = highPriorityModifiersData.split(/\s+/);
10554    result.offsetModifiers = dockPoints.filter(function (m) {
10555     return highPriorityModifiers.some(function (k) { return m.key === k; });
10556    });
10557   } else
10558    result.offsetModifiers = result.specifiedOffsetModifiers.filter(function (m) { return !isVertical; });
10559   if (result.offsetModifiers.length === 0)
10560    result.offsetModifiers = isVertical ? defaultVerticalItemDockPoints : defaultHorizontalItemDockPoints;
10561   return result;
10562  }
10563  function hide(element) {
10564   if (ASPx.ElementHasCssClass(element, showCssClass)) {
10565    if (element.isDockedElementHidden)
10566     delete element.isDockedElementHidden;
10567    ASPx.DOM.ClearStyles(element);
10568    ASPx.DOM.ToggleCssClass(element, showCssClass, false);
10569   } else if (element.isDockedElementHidden)
10570    delete element.isDockedElementHidden;
10571  }
10572  function show(element, targetElement, isVertical) {
10573   ASPx.DOM.ClearStyles(element);
10574   ASPx.DOM.ToggleCssClass(element, showCssClass, true);
10575   preparePosition(element, targetElement, isVertical, null, function () { });
10576  }
10577  function preparePosition(element, targetElement, isVertical, settings, onShow) {
10578   ASPx.DOM.CalculateStyles(function () {
10579    var dockInfo = getElementPopupInfo(element, targetElement, isVertical, settings);
10580    for (var i = 0; i < dockInfo.offsetModifiers.length; i++)
10581     dockInfo.offsetModifiers[i].dockElementToTarget(dockInfo);
10582    ASPx.DOM.ChangeDOM(function () { onShow(dockInfo); });
10583    ASPx.DOM.SetStyles(element, dockInfo.styles);
10584   }.bind(this));
10585  }
10586  return {
10587   getElementPopupInfo: getElementPopupInfo,
10588   hide: hide,
10589   show: show,
10590   preparePosition: preparePosition
10591  };
10592 });
10593 ASPx.DOM = ASPx.CreateSingleton(function (ASPx) {
10594  var FrameContext = ASPx.CreateClass(null, {
10595   constructor: function (requestFrame) {
10596    this.requestFrame = requestFrame;
10597    this.cache = [[]];
10598    this.isInFrame = false;
10599    this.isWaiting = false;
10600   },
10601   getBuffer: function (order) {
10602    if (!order) order = 0;
10603    if (this.cache.length <= order) this.cache[order] = [];
10604    return this.cache[order];
10605   },
10606   execute: function (callback, order) {
10607    if (!this.isInFrame)
10608     return false;
10609    var buffer = this.cache[order || 0];
10610    if (buffer === null)
10611     callback(requestFrameId);
10612    else
10613     (buffer = this.getBuffer(order)).push(callback);
10614    return true;
10615   },
10616   runAll: function () {
10617    this.isWaiting = false;
10618    this.isInFrame = true;
10619    for (var i = 0; i < this.cache.length; i++) {
10620     var buffer = this.cache[i];
10621     if (buffer) {
10622      this.cache[i] = null;
10623      while (buffer.length)
10624       buffer.shift()(requestFrameId);
10625     }
10626    }
10627    this.waitNextFrame();
10628   },
10629   waitNextFrame: function () {
10630    this.cache = [[]];
10631    this.isInFrame = false;
10632    this.isWaiting = false;
10633   },
10634   requestExecution: function (callback, order) {
10635    if (!this.execute(callback, order)) {
10636     this.getBuffer(order).push(callback);
10637     if (this.isWaiting === false) {
10638      this.isWaiting = true;
10639      this.requestFrame(this.runAll.bind(this));
10640     }
10641    }
10642   }
10643  });
10644  var requestFrameId = null;
10645  function requestAnimationFrame(callback) { return requestFrameId = ASPx.RequestAnimationFrame(callback); }
10646  function createAccumulator(requestFrame) {
10647   var context = new FrameContext(requestFrame);
10648   return context.requestExecution.bind(context);
10649  }
10650  var changeDom = createAccumulator(requestAnimationFrame);
10651  var calculateStyles = createAccumulator(function (callback) { changeDom(function () { setTimeout(callback); }); });
10652  var observers = [], minimumIntervalBetweenChecks = 50;
10653  function itemObserver(element, callback, width) {
10654   return function () {
10655    if (element.compareDocumentPosition(document.body) & Node.DOCUMENT_POSITION_DISCONNECTED)
10656     return false;
10657    var currentStyle = ASPx.GetCurrentStyle(element);
10658    if (currentStyle.width === "auto")
10659     return true;
10660    var w = ASPx.PxToInt(currentStyle.width) - ASPx.GetLeftRightBordersAndPaddingsSummaryValue(element);
10661    if (width !== w)
10662     callback(width = w);
10663    return true;
10664   };
10665  }
10666  function subscribeElementContentWidth(el, callback) {
10667   if (observers.length === 0) {
10668    observers.push(itemObserver(el, callback, -1));
10669    calculateStyles(updateTrackedElements);
10670   } else
10671    observers.push(itemObserver(el, callback, -1));
10672  }
10673  function elementSizeObserver(element, callback, size) {
10674   return function() {
10675    if(element.compareDocumentPosition(document.body) & Node.DOCUMENT_POSITION_DISCONNECTED)
10676     return false;
10677    var currentStyle = ASPx.GetCurrentStyle(element);
10678    if(currentStyle.width === "auto")
10679     return true;
10680    var elementWidth = ASPx.PxToInt(currentStyle.width) - ASPx.GetLeftRightBordersAndPaddingsSummaryValue(element);
10681    var elementHeight = ASPx.PxToInt(currentStyle.height) - ASPx.GetTopBottomBordersAndPaddingsSummaryValue(element);
10682    if(size.width !== elementWidth || size.height !== elementHeight) {
10683     size.width = elementWidth;
10684     size.height = elementHeight;
10685     callback(size);
10686    }
10687    return true;
10688   };
10689  }
10690  function subscribeElementContentSize(element, callback) {
10691   if(observers.length === 0) {
10692    observers.push(elementSizeObserver(element, callback, { width: -1, height: -1 }));
10693    calculateStyles(updateTrackedElements);
10694   } else
10695    observers.push(elementSizeObserver(element, callback, { width: -1, height: -1 }));
10696  }
10697  function updateTrackedElements() {
10698   observers = observers.filter(function (observer) { return observer(); });
10699   if (observers.length > 0) {
10700    setTimeout(function () {
10701     calculateStyles(updateTrackedElements);
10702    }, minimumIntervalBetweenChecks);
10703   }
10704  }
10705  function applyStyles(element, styles) {
10706   var stylesArr = [];
10707   for (var property in styles) {
10708    if (styles.hasOwnProperty(property))
10709     stylesArr.push({ attr: property, value: styles[property] });
10710   }
10711   if (stylesArr.length === 1) {
10712    element.style[stylesArr[0].attr] = stylesArr[0].value;
10713   } else {
10714    var cssText = "";
10715    if (element.style.cssText) {
10716     var oldStylesArr = element.style.cssText.split(';').map(function (nvp) { return nvp.trim().split(':'); });
10717     for (var i = 0; i < oldStylesArr.length; i++) {
10718      var oldStyleArr = oldStylesArr[i];
10719      if (oldStyleArr.length === 2 && styles[oldStyleArr[0]] === undefined)
10720       cssText += oldStyleArr[0] + ":" + oldStyleArr[1].trim() + ";";
10721     }
10722    }
10723    for (var i = 0; i < stylesArr.length; i++) {
10724     var style = stylesArr[i];
10725     if (style.value !== "")
10726      cssText += style.attr + ":" + style.value + ";";
10727    }
10728    ASPx.Attr.SetOrRemoveAttribute(element, "style", cssText);
10729   }
10730  }
10731  function applyStateToElement(element, state) {
10732   if (state.inlineStyles === null)
10733    ASPx.Attr.RemoveAttribute(element, "style");
10734   else
10735    applyStyles(element, state.inlineStyles);
10736   for (var attrName in state.attributes) {
10737    if (state.attributes.hasOwnProperty(attrName))
10738     ASPx.Attr.SetOrRemoveAttribute(element, attrName, state.attributes[attrName]);
10739   }
10740   var allCssClasses = ASPx.GetClassNameList(state);
10741   if (allCssClasses) {
10742    var toggleInfo = state.cssClassToggleInfo;
10743    var cssClasses = allCssClasses.filter(function (c) { return toggleInfo[c] !== false; });
10744    for (var c in toggleInfo) {
10745     if (toggleInfo.hasOwnProperty(c) && toggleInfo[c] && cssClasses.indexOf(c) === -1)
10746      cssClasses.push(c);
10747    }
10748    var cssClass = cssClasses.join(" ");
10749    if (cssClass)
10750     ASPx.SetClassName(element, cssClass);
10751    else
10752     ASPx.Attr.RemoveAttribute(element, "class");
10753   }
10754  }
10755  function createElementState(element) {
10756   return { inlineStyles: {}, cssClassToggleInfo: {}, className: ASPx.GetClassName(element), attributes: {} };
10757  }
10758  function updateElementState(elementOrCollection, callback) {
10759   if (elementOrCollection.length !== undefined) {
10760    for (var i = 0; i < elementOrCollection.length; i++)
10761     updateElementState(elementOrCollection[i], callback);
10762    return;
10763   }
10764   var element = elementOrCollection;
10765   if (!element._dxCurrentFrameElementStateInfo) {
10766    callback(element._dxCurrentFrameElementStateInfo = createElementState(element));
10767    changeDom(function () {
10768     applyStateToElement(element, element._dxCurrentFrameElementStateInfo);
10769     element._dxCurrentFrameElementStateInfo = null;
10770    }, 1);
10771   } else
10772    callback(element._dxCurrentFrameElementStateInfo);
10773  }
10774  function setStyles(el, styles) {
10775   updateElementState(el, function (state) {
10776    if (state.inlineStyles === null)
10777     state.inlineStyles = styles;
10778    else {
10779     for (var i in styles) {
10780      if (styles.hasOwnProperty(i))
10781       state.inlineStyles[i] = styles[i];
10782     }
10783    }
10784   });
10785  }
10786  function clearStyles(el) {
10787   updateElementState(el, function (state) {
10788    state.inlineStyles = null;
10789   });
10790  }
10791  function toggleCssClass(el, cssClass, condition) {
10792   updateElementState(el, function (state) {
10793    state.cssClassToggleInfo[cssClass] = condition;
10794   });
10795  }
10796  function setCssClassName(el, className) {
10797   updateElementState(el, function (state) {
10798    state.cssClassToggleInfo = {};
10799    state.className = className;
10800   });
10801  }
10802  function updateAttribute(el, attrName, attrValue) {
10803   updateElementState(el, function (state) {
10804    state.attributes[attrName] = attrValue;
10805   });
10806  }
10807  function nextChangeDOM(callback) {
10808   changeDom(callback, 2);
10809  }
10810  return {
10811   ChangeDOM: changeDom,
10812   NextChangeDOM: nextChangeDOM,
10813   CalculateStyles: calculateStyles,
10814   SubscribeElementContentWidth: subscribeElementContentWidth,
10815   SubscribeElementContentSize: subscribeElementContentSize,
10816   SetStyles: setStyles,
10817   ClearStyles: clearStyles,
10818   ToggleCssClass: toggleCssClass,
10819   SetCssClassName: setCssClassName,
10820   UpdateAttribute: updateAttribute
10821  };
10822 });
10823 ASPx.DefaultDisplayNoneSelectors = ASPx.DefaultDisplayNoneSelectors.concat([
10824  ASPx.BootstrapCssSelectors.Modal,
10825  ASPx.BootstrapCssSelectors.DropDownMenu,
10826  "dxbs-dropdown-area",
10827  ASPx.BootstrapCssSelectors.HiddenLayout
10828 ]);
10829 ASPx.DefaultDisplaySelectors = ASPx.DefaultDisplaySelectors.concat([
10830  "dxbs-modal"
10831 ]);
10832 ASPx.ProcessStyleSheetRules(".dropdown-item", function(name, style, rule) {
10833  if(name.indexOf(":hover") > -1 && style.backgroundColor) {
10834   var cssText = "background-color: " + style.backgroundColor + ";";
10835   if(style.color)
10836    cssText += "color: " + style.color + "; ";
10837   ASPx.AddStyleSheetRule(rule.parentStyleSheet, ".dxbs-item-hover", cssText);
10838   return true;
10839  }
10840 });
10841})(dx || (dx = {}));
10842
10843(function(dx) {
10844 var NAVBAR_CLASS = "nav navbar-nav dxbs-navbar",
10845  ITEM_IMAGE_CLASS = "image",
10846  ITEM_TEXT_CLASS = "text",
10847  ITEM_POPOUT_CLASS = "popout",
10848  SUBMENU_TEMPLATE_CLASS = "dxbs-submenu";
10849 var BootstrapMenuRenderHelper = ASPx.CreateClass(ASPx.MenuRenderHelper, {
10850  constructor: function(menu) {
10851   this.constructor.prototype.constructor.call(this, menu);
10852  },
10853  InlineInitializeElements: function() {
10854   ASPx.MenuRenderHelper.prototype.InlineInitializeElements.call(this);
10855   if(this.menu.IsStateControllerEnabled())
10856    this.InitializeStateControllerItems();
10857  },
10858  InitializeStateControllerItems: function() {
10859   if(!this.menu.enabled) return;
10860   var itemPostfixes = ['', 'T'];
10861   var disabledItemPostfixes = ['', 'T', 'P'];
10862   var itemActiveRootStyles = this.IsStateControllerItemOnRootItemElement() ? ['active'] : ['', 'active'];
10863   var itemActiveStyles = ASPx.BootstrapCore.IsBootstrap3 ? ['active'] : ['', 'active'];
10864   var itemDisabledRootStyles = this.IsStateControllerItemOnRootItemElement() ? ['disabled'] : ['', 'disabled'];
10865   var itemDisabledStyles = ASPx.BootstrapCore.IsBootstrap3 ? ['disabled'] : ['', 'disabled'];
10866   var itemCheckedStyles = ['checked'];
10867   var itemSuffixes = [];
10868   var menuSuffixes = [];
10869   for(var key in this.menu.renderData) {
10870    if(!this.menu.renderData.hasOwnProperty(key)) continue;
10871    var rootIndexPath = key;
10872    var rootItemData = this.menu.renderData[key];
10873    if(rootIndexPath !== "") {
10874     itemSuffixes.push("DXI" + rootIndexPath + "_");
10875     menuSuffixes.push("DXME" + rootIndexPath + "_");
10876    }
10877    for(var subKey in rootItemData) {
10878     if(!rootItemData.hasOwnProperty(subKey)) continue;
10879     var itemData = rootItemData[subKey];
10880     var indexPath = ASPx.Ident.IsArray(itemData) ? itemData[0] : itemData;
10881     if(rootIndexPath !== "")
10882      indexPath = rootIndexPath + "i" + indexPath;
10883     var itemSuffix = "DXI" + indexPath + "_";
10884     if(!ASPx.Data.ArrayContains(itemSuffixes, itemSuffix))
10885      itemSuffixes.push(itemSuffix);
10886    }
10887   }
10888   ASPx.BootstrapCore.AddStateItems(function() {
10889    var menu = this.menu;
10890    ASPx.AddHoverItems(this.menu.name, [[[''], [''], itemSuffixes, ['', 'P']], [[''], [''], menuSuffixes, ['']]], true);
10891    if(this.menu.allowSelectItem) {
10892     ASPx.AddSelectedItems(this.menu.name, [[itemActiveRootStyles, [''], itemSuffixes.filter(function(indexPath) { return menu.IsRootItem(indexPath); }), itemPostfixes]], true);
10893     ASPx.AddSelectedItems(this.menu.name, [[itemActiveStyles, [''], itemSuffixes.filter(function(indexPath) { return !menu.IsRootItem(indexPath); }), itemPostfixes]], true);
10894    }
10895    else {
10896     ASPx.AddSelectedItems(menu.name, [[this.menu.isPopupMenu ? itemCheckedStyles : itemActiveRootStyles, [''], itemSuffixes.filter(function(indexPath) { return menu.IsRootItem(indexPath); }), itemPostfixes]], true);
10897     ASPx.AddSelectedItems(menu.name, [[itemCheckedStyles, [''], itemSuffixes.filter(function(indexPath) { return !menu.IsRootItem(indexPath); }), itemPostfixes]], true);
10898    }
10899    ASPx.AddDisabledItems(this.menu.name, [[itemDisabledRootStyles, [''], itemSuffixes.filter(function(indexPath){ return menu.IsRootItem(indexPath); }), disabledItemPostfixes]], true);
10900    ASPx.AddDisabledItems(this.menu.name, [[itemDisabledStyles, [''], itemSuffixes.filter(function(indexPath) { return !menu.IsRootItem(indexPath); }), disabledItemPostfixes]], true);
10901    var menuElements = this.GetPopupMenuElements(menu.GetMainElement());
10902    var menuElementsSuffixes = [];
10903    for(var i = 0; i < menuElements.length; i++)
10904     menuElementsSuffixes.push(menuElements[i].id.replace(menu.name + "_", ""));
10905    ASPx.AddHoverItems(menu.name, [[[''], [''], menuElementsSuffixes, ['']], [[''], [''], [], ['']]], true);
10906   }.aspxBind(this));
10907  },
10908  IsStateControllerItemOnRootItemElement: function() {
10909   return ASPx.BootstrapCore.IsBootstrap3;
10910  },
10911  HasSubMenuTemplate: function(menuElement) {
10912   var contentElement = this.GetContentElement(menuElement);
10913   return (contentElement && contentElement.tagName !== "UL") || (menuElement && ASPx.ElementHasCssClass(menuElement, SUBMENU_TEMPLATE_CLASS));
10914  },
10915  GetSubMenuIndexPathByMenuParentElement: function(element) {
10916   return this.menu.GetItemIndexPathById(element.parentNode.id);
10917  },
10918  InlineInitializePopupMenuElements: function(parentElement) {
10919   var indexPath = this.GetSubMenuIndexPathByMenuParentElement(parentElement);
10920   this.InlineInitializePopupMenuMenuElement(parentElement, indexPath);
10921  },
10922  InlineInitializePopupMenuMenuElement: function(parentElement, indexPath) {
10923   if(indexPath !== "")
10924    parentElement.id = this.menu.GetMenuElementId(indexPath);
10925   this.InlineInitializePopupMenuContentElements(parentElement, parentElement, indexPath);
10926  },
10927  InlineInitializeItemElement: function(itemElement, parentIndexPath, visibleIndex) {
10928   ASPx.MenuRenderHelper.prototype.InlineInitializeItemElement.call(this, itemElement, parentIndexPath, visibleIndex);
10929   if(!this.IsItemDisabled(itemElement)) {
10930    var itemLink = ASPx.GetChildByTagName(itemElement, "A");
10931    if(itemLink && itemLink.href === "")
10932     itemLink.href = ASPx.AccessibilityEmptyUrl;
10933   }
10934   var links = ASPx.GetNodesByTagName(itemElement, "A");
10935   for(var i = 0; i < links.length; i++)
10936    this.attachAccessibilityEventsToLink(links[i]);
10937  },
10938  InlineInitializeItemPopOutElement: function(itemElement, indexPath) { },
10939  AssignItemOnClickToElement: function(element, itemLinkMode, method) {
10940   if(element && element.tagName !== "A")
10941    element = ASPx.GetNodeByTagName(element, "A");
10942   ASPx.MenuRenderHelper.prototype.AssignItemOnClickToElement.call(this, element, itemLinkMode, method);
10943  },
10944  IsItemDisabled: function(itemElement) {
10945   var element = ASPx.BootstrapCore.IsBootstrap3 ? itemElement : this.GetItemContentElement(itemElement);
10946   return ASPx.ElementContainsCssClass(element, ASPx.BootstrapCssSelectors.Disabled);
10947  },
10948  SetItemIconCssClass: function(itemElement, iconCssClass) {
10949   var iconElement = this.GetItemIconElement(itemElement);
10950   if(iconElement)
10951    ASPx.SetClassName(iconElement, ITEM_IMAGE_CLASS + (iconCssClass ? " " + iconCssClass : ""));
10952  },
10953  GetItemIconCssClass: function(itemElement) {
10954   var iconElement = this.GetItemIconElement(itemElement);
10955   var regEx = new RegExp("(?:^|\\s)" + ITEM_IMAGE_CLASS + "(?!\\S)");
10956   return iconElement ? ASPx.Str.Trim(ASPx.GetClassName(iconElement).replace(regEx, "")) : "";
10957  },
10958  ChangeItemLinkEnabledAttributes: function(hyperLink, itemElement, enabled, accessibilityCompliant) {
10959   ASPx.MenuRenderHelper.prototype.ChangeItemLinkEnabledAttributes.call(this, hyperLink, itemElement, enabled, accessibilityCompliant);
10960   if(!ASPx.BootstrapCore.IsBootstrap3) {
10961    var action = enabled ? ASPx.Attr.RemoveAttribute : ASPx.Attr.SetAttribute;
10962    action(hyperLink, "tabIndex", "-1");
10963   }
10964  },
10965  convertToNavBar: function(menuElement) {
10966   ASPx.RemoveClassNameFromElement(menuElement, ASPx.BootstrapCssSelectors.DropDownMenu);
10967   ASPx.AddClassNameToElement(menuElement, NAVBAR_CLASS);
10968   var itemElements = ASPx.GetChildNodesByTagName(menuElement, "LI");
10969   for(var i = 0; i < itemElements.length; i++) {
10970    ASPx.AddClassNameToElement(itemElements[i], ASPx.BootstrapCssSelectors.NavItem);
10971    var linkElement = ASPx.GetChildByTagName(itemElements[i], "A");
10972    if(linkElement) {
10973     ASPx.RemoveClassNameFromElement(linkElement, ASPx.BootstrapCssSelectors.DropDownMenuItem);
10974     ASPx.AddClassNameToElement(linkElement, ASPx.BootstrapCssSelectors.NavLink);
10975    }
10976   }
10977  },
10978  convertToMenu: function(menuElement) {
10979   ASPx.AddClassNameToElement(menuElement, ASPx.BootstrapCssSelectors.DropDownMenu);
10980   ASPx.RemoveClassNameFromElement(menuElement, NAVBAR_CLASS);
10981   var itemElements = ASPx.GetChildNodesByTagName(menuElement, "LI");
10982   for(var i = 0; i < itemElements.length; i++) {
10983    ASPx.RemoveClassNameFromElement(itemElements[i], ASPx.BootstrapCssSelectors.NavItem);
10984    var linkElement = ASPx.GetChildByTagName(itemElements[i], "A");
10985    if(linkElement) {
10986     ASPx.AddClassNameToElement(linkElement, ASPx.BootstrapCssSelectors.DropDownMenuItem);
10987     ASPx.RemoveClassNameFromElement(linkElement, ASPx.BootstrapCssSelectors.NavLink);
10988    }
10989   }
10990  },
10991  PrepareElementScrolling: function(element, excessTop, excessBottom) {
10992   if(excessTop > 0 || excessBottom > 0) {
10993    element.style.overflowY = "auto";
10994    element.style.overflowX = "hidden";
10995    var height = element.offsetHeight;
10996    if(excessTop > 0)
10997     height -= excessTop;
10998    if(excessBottom > 0)
10999     height -= excessBottom;
11000    element.style.height = (height - 8) + "px";
11001   }
11002  },
11003  ResetElementScrolling: function(element) {
11004   element.style.height = "auto";
11005   element.style.overflowX = "visible";
11006   element.style.overflowY = "visible";
11007  },
11008  createScrollableMenusContainer: function(className) {
11009   var container = document.createElement("DIV");
11010   ASPx.SetClassName(container, className);
11011   return container;
11012  },
11013  GetContentElement: function(menuElement) {
11014   return ASPx.CacheHelper.GetCachedElement(this, "contentElement",
11015    function() {
11016     if(menuElement.tagName === "UL")
11017      return menuElement;
11018     var contentElement = ASPx.GetNodeByTagName(menuElement, "UL");
11019     if(contentElement)
11020      return contentElement;
11021     return ASPx.GetNodeByTagName(menuElement, "DIV"); 
11022    }, menuElement);
11023  },
11024  GetItemElements: function(menuElement) {
11025   return ASPx.CacheHelper.GetCachedElements(this, "itemElements",
11026    function() {
11027     var contentElement = menuElement && !ASPx.ElementHasCssClass(menuElement, SUB
11027MENU_TEMPLATE_CLASS) ? this.GetContentElement(menuElement) : null;
11028     return contentElement ? ASPx.GetChildNodesByQuerySelector(contentElement, "li:not(.separator):not(." + ASPx.BootstrapCssSelectors.Divider + ")") : [];
11029    }, menuElement);
11030  },
11031  GetPopupMenuElements: function(menuElement) {
11032   return ASPx.CacheHelper.GetCachedElements(this, "popupMenuElements",
11033    function() {
11034     var contentElement = this.GetContentElement(menuElement);
11035     return contentElement ? ASPx.GetNodesByClassName(contentElement, "dxbs-dm") : null;
11036    }, menuElement);
11037  },
11038  GetItemContentElement: function(itemElement) {
11039   return ASPx.CacheHelper.GetCachedElement(this, "contentElement",
11040    function() {
11041     return ASPx.GetChildByTagName(itemElement, "A");
11042    }, itemElement);
11043  },
11044  GetItemPopOutElement: function(itemElement) {
11045   return ASPx.CacheHelper.GetCachedElement(this, "popOutElement",
11046    function() {
11047     return ASPx.GetNodeByClassName(itemElement, ITEM_POPOUT_CLASS);
11048    }, itemElement);
11049  },
11050  GetItemIconElement: function(itemElement) {
11051   return ASPx.CacheHelper.GetCachedElement(this, "iconElement",
11052    function() {
11053     var imageNodes = ASPx.GetNodesByClassName(itemElement, ITEM_IMAGE_CLASS);
11054     return imageNodes[imageNodes.length - 1];     
11055    }, itemElement);
11056  },
11057  getEventSyncObject: function() {
11058   if(!this.menu.getEventContainers)
11059    this.menu.getEventContainers = function() { return this.getEventContainersCore(); }.aspxBind(this.menu);
11060   return this.menu;
11061  }, 
11062  CalculateMenuControl: function(menuElement, recalculate) {
11063  },
11064  CalculateSubMenu: function(parentElement, recalculate) {
11065  },
11066  PrecalculateMenuPopOuts: function(menuElement) {
11067  },
11068  ApplyItemsVerticalAlignment: function() { },
11069  AssignItemOnClickToElementCore: function(element, handler) {
11070   ASPx.BootstrapEventManager.attachEventToElement(this.getEventSyncObject(), element, "click", handler);
11071  },
11072  attachAccessibilityEventsToLink: function(link) {
11073  }
11074 });
11075 var BootstrapClientMenuItem = ASPx.CreateClass(ASPxClientMenuItem, {
11076  constructor: function(menu, parent, index, name) {
11077   this.constructor.prototype.constructor.call(this, menu, parent, index, name);
11078  },
11079  GetFirstVisibleChild: function () {
11080   for (var i = 0; i < this.GetItemCount(); i++) {
11081    var child = this.GetItem(i);
11082    if (child.GetVisible())
11083     return child;
11084   }
11085   return null;
11086  },
11087  GetBadgeText: function() {
11088   var indexPath = this.GetIndexPath();
11089   return this.menu.GetItemBadgeText(indexPath);
11090  },
11091  SetBadgeText: function(text) {
11092   var indexPath = this.GetIndexPath();
11093   this.menu.SetItemBadgeText(indexPath, text);
11094  },
11095  GetBadgeIconCssClass: function() {
11096   var indexPath = this.GetIndexPath();
11097   return this.menu.GetItemBadgeIconCssClass(indexPath);
11098  },
11099  SetBadgeIconCssClass: function(cssClass) {
11100   var indexPath = this.GetIndexPath();
11101   this.menu.SetItemBadgeIconCssClass(indexPath, cssClass);
11102  },
11103  GetIconCssClass: function() {
11104   var indexPath = this.GetIndexPath();
11105   return this.menu.GetItemIconCssClass(indexPath);
11106  },
11107  SetIconCssClass: function(cssClass) {
11108   var indexPath = this.GetIndexPath();
11109   this.menu.SetItemIconCssClass(indexPath, cssClass);
11110  }
11111 });
11112 var BootstrapClientMenu = ASPx.CreateClass(ASPxClientMenu, {
11113  constructor: function(name) {
11114   this.constructor.prototype.constructor.call(this, name);
11115  },
11116  InlineInitialize: function() {
11117   ASPxClientMenu.prototype.InlineInitialize.call(this);
11118   this.enableAnimation = false;
11119  },
11120  CreateRenderHelper: function() {
11121   return new BootstrapMenuRenderHelper(this);
11122  },
11123  RenderSubMenuItem: function(indexPath) {
11124   var subMenuElement = this.CreateSubMenuElement(indexPath);
11125   var itemElement = this.GetItemElement(indexPath);
11126   if(itemElement) {
11127    var sampleList = ASPx.GetChildByTagName(itemElement, "UL");
11128    if(sampleList) itemElement.removeChild(sampleList);
11129    itemElement.appendChild(subMenuElement);
11130   }
11131   return subMenuElement;
11132  },
11133  GetMenuMainElement: function(element) {
11134   var indexPath = this.GetIndexPathById(element.id, true);
11135   return this.GetMenuElement(indexPath);
11136  },
11137  GetMenuListElement: function(indexPath) {
11138   var element = this.GetMenuElement(indexPath);
11139   if(element && element.tagName !== "UL")
11140    return ASPx.GetChildByTagName(element, "UL");
11141   return element;
11142  },
11143  GetItemSeparatorElement: function(indexPath) {
11144   var el = this.GetItemElement(indexPath);
11145   var separator = el && el.previousElementSibling;
11146   return separator && ASPx.ElementHasCssClass(separator, "separator") ? separator : null;
11147  },
11148  getSeparatorCssClass: function() {
11149   return "separator";
11150  },
11151  getScrollableMenusContainer: function() {
11152   if(!this.scrollableMenusContainer) {
11153    this.scrollableMenusContainer = this.renderHelper.createScrollableMenusContainer("dxbs-menu");
11154    this.GetMainElement().parentNode.appendChild(this.scrollableMenusContainer);
11155   }
11156   return this.scrollableMenusContainer;
11157  },
11158  getEventContainersCore: function() {
11159   var obj = [this.GetMainElement()];
11160   if(this.enableScrolling)
11161    obj.push(this.getScrollableMenusContainer());
11162   return obj;
11163  },
11164  DoShowPopupMenu: function(element, x, y, indexPath) {
11165   if(this.isNavBarModeActivated())
11166    this.convertMenuToNavBarMode(element);
11167   if(this.enableScrolling) {
11168    var menuParent = this.getScrollableMenusContainer();
11169    if(element.parentNode !== menuParent)
11170     menuParent.appendChild(element);
11171   }
11172   ASPxClientMenu.prototype.DoShowPopupMenu.call(this, element, x, y, indexPath);
11173   var itemLinkElement = this.GetLinkElementByIndexPath(indexPath);
11174   ASPx.Attr.Aria.SetExpanded(itemLinkElement, true);
11175  },
11176  GetScrollingCorrection: function(element, indexPath, clientY) {
11177   if(this.enableScrolling) {
11178    var yClientCorrection = this.GetScrollSubMenuYCorrection(element, null, clientY);
11179    if(yClientCorrection > 0)
11180     return yClientCorrection;
11181   }
11182   return 0;
11183  },
11184  DoHidePopupMenu: function(evt, element) {
11185   ASPxClientMenu.prototype.DoHidePopupMenu.call(this, evt, element);
11186   var indexPath = this.GetIndexPathById(element.id, true);
11187   var itemLinkElement = this.GetLinkElementByIndexPath(indexPath);
11188   ASPx.Attr.Aria.SetExpanded(itemLinkElement, false);
11189   if(this.navBarMode)
11190    this.restoreMenuFromNavBarMode(element);
11191  },
11192  DoResetScrolling: function(element, indexPath) {
11193   if(this.enableScrolling)
11194    this.renderHelper.ResetElementScrolling(element);
11195  },
11196  GetScrollHelper: function(indexPath) {
11197   return null;
11198  },
11199  PrepareScrolling: function(element, scrollHelper, excessTop, excessBottom) {
11200   if(this.enableScrolling)
11201    this.renderHelper.PrepareElementScrolling(element, excessTop, excessBottom);
11202  },
11203  OnItemClick: function(indexPath, evt) {
11204   var hideSubMenu = false, preventItemSelection = false;
11205   var menuElement = this.GetMenuElement(indexPath);
11206   if(menuElement && this.isNavBarModeActivated()) {
11207    if(ASPx.GetElementDisplay(menuElement))
11208     hideSubMenu = true;
11209    if(ASPx.ElementHasCssClass(ASPx.Evt.GetEventSource(evt), ITEM_POPOUT_CLASS)) {
11210     ASPx.Evt.PreventEvent(evt);
11211     preventItemSelection = true;
11212    }
11213   }
11214   if(preventItemSelection)
11215    this.DoItemClick(indexPath, false, evt);
11216   else
11217    ASPxClientMenu.prototype.OnItemClick.call(this, indexPath, evt);
11218   if(menuElement && hideSubMenu)
11219    this.DoHidePopupMenu(evt, menuElement);
11220  },
11221  CanCloseSubMenuOnClick: function(indexPath) {
11222   return !this.isNavBarModeActivated();
11223  },
11224  GetAppearAfter: function(indexPath) {
11225   if(this.isNavBarModeActivated())
11226    return 120000;
11227   return ASPxClientMenu.prototype.GetAppearAfter.call(this);
11228  },
11229  GetDisappearAfter: function() {
11230   if(this.isNavBarModeActivated())
11231    return 120000;
11232   return ASPxClientMenu.prototype.GetDisappearAfter.call(this);
11233  },
11234  isNavBarModeActivated: function(){
11235   if(!this.navBarMode) return false;
11236   var menuElement = this.GetMenuListElement("");
11237   if(ASPx.BootstrapCore.IsBootstrap3)
11238    return ASPx.GetCurrentStyle(menuElement).float === "none";
11239   return ASPx.GetCurrentStyle(menuElement).flexDirection === "column";
11240  },
11241  convertMenuToNavBarMode: function(menuElement){
11242   if(menuElement.navBarMode) return;
11243   this.renderHelper.convertToNavBar(menuElement);
11244   menuElement.navBarMode = true;
11245  },
11246  restoreMenuFromNavBarMode: function(menuElement){
11247   if(!menuElement.navBarMode) return;
11248   this.renderHelper.convertToMenu(menuElement);
11249   menuElement.navBarMode = false;
11250  },
11251  BrowserWindowResizeSubscriber: function () {
11252   return this.navBarMode;
11253  },
11254  OnBrowserWindowResize: function(e) {
11255   var isNavBarModeActivated = this.isNavBarModeActivated();
11256   if(!isNavBarModeActivated && this.savedIsNavBarModeActivated || isNavBarModeActivated && !this.savedIsNavBarModeActivated)
11257    ASPx.GetMenuCollection().DoHidePopupMenus(null, 0, this.name, true, "");
11258   this.savedIsNavBarModeActivated = isNavBarModeActivated;
11259  },
11260  AdjustControlCore: function() {
11261  },
11262  GetClientItemType: function() {
11263   return BootstrapClientMenuItem;
11264  },
11265  GetItemBadgeText: function(indexPath) {
11266   return ASPx.BootstrapBadgeManager.getBadgeText(this.GetItemContentElement(indexPath));
11267  },
11268  SetItemBadgeText: function(indexPath, text) {
11269   var badgeText = this.HtmlEncode(text);
11270   var contentElement = this.GetItemContentElement(indexPath);
11271   var badge = ASPx.BootstrapBadgeManager.findBadge(contentElement);
11272   if(badge)
11273    ASPx.BootstrapBadgeManager.setBadgeText(badge, badgeText);
11274   else
11275    this.AddBadgeToItemContentElement(contentElement, ASPx.BootstrapBadgeManager.createBadge(badgeText));
11276  },
11277  GetItemBadgeIconCssClass: function(indexPath) {
11278   return ASPx.BootstrapBadgeManager.getBadgeIconCssClass(this.GetItemContentElement(indexPath));
11279  },
11280  SetItemBadgeIconCssClass: function(indexPath, cssClass) {
11281   var contentElement = this.GetItemContentElement(indexPath);
11282   var badge = ASPx.BootstrapBadgeManager.findBadge(contentElement);
11283   if(badge)
11284    ASPx.BootstrapBadgeManager.setBadgeIconCssClass(badge, cssClass);
11285   else
11286    this.AddBadgeToItemContentElement(contentElement, ASPx.BootstrapBadgeManager.createBadge("", cssClass));
11287  },
11288  AddBadgeToItemContentElement: function(contentElement, badgeElement) {
11289   var popOutElement = this.renderHelper.GetItemPopOutElement(contentElement);
11290   if(popOutElement)
11291    contentElement.insertBefore(badgeElement, popOutElement);
11292   else
11293    contentElement.appendChild(badgeElement);
11294  },
11295  GetItemIconCssClass: function(indexPath) {
11296   return this.renderHelper.GetItemIconCssClass(this.GetItemContentElement(indexPath));
11297  },
11298  SetItemIconCssClass: function(indexPath, cssClass) {
11299   this.renderHelper.SetItemIconCssClass(this.GetItemContentElement(indexPath), cssClass);
11300  },
11301  CreateItemClickEventArgs: function(processOnServer, item, htmlElement, htmlEvent) {
11302   return new BootstrapClientMenuItemClickEventArgs(processOnServer, item, htmlElement, htmlEvent);
11303  },
11304  CreateItemMouseEventArgs: function(item, htmlElement) {
11305   return new BootstrapClientMenuItemMouseEventArgs(item, htmlElement);
11306  },
11307  CreateItemEventArgs: function(item) {
11308   return new BootstrapClientMenuItemEventArgs(item);
11309  },
11310  GetContentTextElement: function(contentElement) {
11311   return ASPx.GetChildByClassName(contentElement, ITEM_TEXT_CLASS, 0);
11312  },
11313 });
11314 var BootstrapClientMenuItemEventArgs = ASPx.CreateClass(ASPxClientMenuItemEventArgs, {
11315  constructor: function(item) {
11316   this.constructor.prototype.constructor.call(this, item);
11317  }
11318 });
11319 var BootstrapClientMenuItemMouseEventArgs = ASPx.CreateClass(BootstrapClientMenuItemEventArgs, {
11320  constructor: function(item, htmlElement) {
11321   this.constructor.prototype.constructor.call(this, item, htmlElement);
11322  }
11323 });
11324 var BootstrapClientMenuItemClickEventArgs = ASPx.CreateClass(ASPxClientMenuItemClickEventArgs, {
11325  constructor: function(processOnServer, item, htmlElement, htmlEvent) {
11326   this.constructor.prototype.constructor.call(this, processOnServer, item, htmlElement, htmlEvent);
11327  }
11328 });
11329 ASPx.BootstrapMenuRenderHelper = BootstrapMenuRenderHelper;
11330 dx.BootstrapClientMenu = BootstrapClientMenu;
11331 dx.BootstrapClientMenuItem = BootstrapClientMenuItem;
11332 dx.BootstrapClientMenuItemEventArgs = BootstrapClientMenuItemEventArgs;
11333 dx.BootstrapClientMenuItemMouseEventArgs = BootstrapClientMenuItemMouseEventArgs;
11334 dx.BootstrapClientMenuItemClickEventArgs = BootstrapClientMenuItemClickEventArgs;
11335})(dx || (dx = {}));
11336
11337(function () {
11338 var Constants = {
11339  TabAction: {
11340   CLICK: "Click",
11341   MOUSE_OVER: "MouseOver",
11342   MOUSE_DOWN: "MouseDown"
11343  },
11344  CssClassName: {
11345   MULTIROW: "dxtc-multiRow",
11346   INIT_STATE: "dxtc-init",
11347   STRIP_WRAPPER: "dxtc-wrapper",
11348   STRIP: "dxtc-strip",
11349   TAB_ROW: "dxtc-row",
11350   TAB: "dxtc-tab",
11351   ACTIVE_TAB: "dxtc-activeTab",
11352   TAB_LINK: "dxtc-link",
11353   TAB_IMAGE: "dxtc-img",
11354   TAB_SPACER: "dxtc-spacer",
11355   TAB_FILLER: "dxtc-filler",
11356   LEFT_INDENT: "dxtc-leftIndent",
11357   RIGHT_INDENT: "dxtc-rightIndent",
11358   INDENT_TEMPLATE: "dxtc-it",
11359   TABS_HOLDER: "dxtc-tabs",
11360   ACTIVE_ROW_ITEM: "dxtc-activeRowItem",
11361   PINNED_TAB_HEADERS: "dxtc-pth",
11362   PINNED_STRIP_ITEM: "dxtc-psi",
11363   LEAD_TAB: "dxtc-lead",
11364   LAST_TAB: "dxtc-last",
11365   NEW_LINE_START_TAB: "dxtc-n",
11366   NEW_LINE_END_TAB: "dxtc-l",
11367   RIBBON_FILE_TAB: "dxr-fileTab",
11368   CONTENT: "dxtc-content",
11369   AUTO_HEIGHT: "dxtc-autoHeight",
11370   TAB_CONTROL: "dxtcSys",
11371   DISABLED: "dxtcLiteDisabled"
11372  }
11373 };
11374 var TabControlRenderHelper = ASPx.CreateClass(null, {
11375  constructor: function(tabControl) {
11376   this.tabControl = tabControl;
11377  },
11378  InitializeControlElements: function () {
11379   var mainElement = this.tabControl.GetMainElement();
11380   this.PrepareMainElement(mainElement);
11381   this.PrepareTabStrip(mainElement);
11382   this.PrepareContentContainer(mainElement);
11383  },
11384  PrepareMainElement: function(mainElement) {
11385   if(this.IsPercentageSize(mainElement, "width"))
11386    mainElement.style.overflow = "visible";
11387  },
11388  PrepareTabStrip: function(mainElement) {
11389   var tabStrip = this.GetTabStripElement(mainElement);
11390   if(tabStrip) {
11391    tabStrip.id = this.GetID(this.tabControl.GetTabsCellID());
11392    var hasRibbonTab = ASPx.GetChildNodesByClassName(tabStrip, Constants.CssClassName.RIBBON_FILE_TAB).length > 0;
11393    var indexCorrection = hasRibbonTab ? 1 : 0;
11394    this.PrepareElements(tabStrip, this.GetTabElements, this.PrepareTabElement);
11395    this.PrepareElements(tabStrip, this.GetActiveTabElements, this.PrepareActiveTabElement, indexCorrection);
11396    this.PrepareElements(tabStrip, this.GetSpacerElements, this.PrepareSpacerElement);
11397    this.PrepareElements(tabStrip, this.GetTabLinkElements, this.PrepareTabLinkElement);
11398    this.PrepareElements(tabStrip, this.GetTabImageElements, this.PrepareTabImageElement);
11399   }
11400   else
11401    this.hasTabStrip = false;
11402   this.tabControl.layoutManager.prepareTabStripForImageLoading();
11403  },
11404  PrepareTabElement: function(index, element) {
11405   var tabIndex = this.FindTabIndexByElementIndex(index);
11406   element.id = this.GetID(this.tabControl.GetTabElementID(tabIndex, false));
11407   if(!this.IsTabDisabled(element))
11408    this.AssignTabActionToElement(element, this.tabControl.getTabActivationHtmlEventName().substring(2),
11409     this.GetTabElementAction(this.tabControl.name, element, tabIndex));
11410  },
11411  AssignTabActionToElement: function(element, eventName, action) {
11412   ASPx.Evt.AttachEventToElement(element, eventName, action);
11413  },
11414  GetTabElementAction: function(name, element, index, preventPostBack) {
11415   var tabControl = this.tabControl;
11416   var sendPostBackHandler = function() {
11417    tabControl.SendPostBack("CLICK:" + index);
11418   };
11419   var itemClickHandler = function(e) {
11420    ASPx.TCTClick(e, name, index);
11421   };
11422   var link = ASPx.GetNodeByTagName(element, "A");
11423   var handler = !preventPostBack && tabControl.autoPostBack && !tabControl.IsClientSideEventsAssigned() && (!link || link.href === "")
11424    ? sendPostBackHandler
11425    : itemClickHandler;
11426   return function(e) {
11427    if(!element.clientDisabled)
11428     handler(e);
11429   };
11430  },
11431  PrepareActiveTabElement: function(index, element, indexCorrection) {
11432   var tabIndex = this.FindActiveTabIndexByElementIndex(index, indexCorrection);
11433   element.id = this.GetID(this.tabControl.GetTabElementID(tabIndex, true));
11434   if(!this.IsTabDisabled(element) && !this.tabControl.TabClick.IsEmpty())
11435    ASPx.Evt.AttachEventToElement(element, this.tabControl.getTabActivationHtmlEventName().substring(2), 
11436     this.GetTabElementAction(this.tabControl.name, element, tabIndex));
11437  },
11438  PrepareSpacerElement: function(index, element) {
11439   var separatorIndex = this.FindSeparatorIndexByElementIndex(index);
11440   if(ASPx.IsExists(separatorIndex)) 
11441    element.id = this.GetID(this.tabControl.GetSeparatorElementID(separatorIndex));
11442  },
11443  PrepareTabLinkElement: function(index, element) { 
11444   element.id = element.parentNode.id + "T"; 
11445  },
11446  PrepareTabImageElement: function(index, element) { 
11447   element.id = element.parentNode.parentNode.id + "Img"; 
11448  },
11449  PrepareContentContainer: function(mainElement) {
11450   var contentContainer = this.GetContentContainerElement(mainElement);
11451   if(!contentContainer) return;
11452   this.tabControl.hasContent = true;
11453   contentContainer.id = this.GetID(this.tabControl.GetContentsCellID());
11454   this.PrepareElements(contentContainer, this.GetContentElements, this.PrepareContentElement);
11455   if(!this.tabControl.GetTabsCell() && contentContainer.style.cssText) 
11456    contentContainer.style.cssText = ASPx.CreateImportantCssText(contentContainer.style.cssText);
11457  },
11458  PrepareContentElement: function(index, element) {
11459   var contentIndex = this.FindContentIndexByElementIndex(index);
11460   element.id = this.GetID(this.tabControl.GetContentElementID(contentIndex));
11461  },
11462  PrepareElements: function(container, getElements, prepareElement, indexCorrection) {
11463   var elements = getElements.call(this, container);
11464   for(var i = 0; i < elements.length; i++) {
11465    prepareElement.call(this, i, elements[i], indexCorrection);
11466   }
11467  },
11468  GetID: function(suffix){
11469   return this.tabControl.name + suffix;
11470  },
11471  IsPercentageSize: function (element, dimension) {
11472   return ASPx.IsPercentageSize(element.style[dimension]);
11473  },
11474  IsTabDisabled: function (element) {
11475   return ASPx.ElementContainsCssClass(element, Constants.CssClassName.DISABLED);
11476  },
11477  FindTabIndexByElementIndex: function (elementIndex) {
11478   var tabIndex = -1;
11479   var tabs = this.tabControl.tabs;
11480   for(var i = 0; i < tabs.length; i++) {
11481    var tab = tabs[i];
11482    if(tab.visible)
11483     tabIndex++;
11484    if(!this.tabControl.useClientVisibility && tab.clientVisible && i == this.tabControl.activeTabIndex)
11485     tabIndex--;
11486    if(tabIndex == elementIndex)
11487     return i;
11488   }
11489  },
11490  FindActiveTabIndexByElementIndex: function (elementIndex, indexCorrection) {
11491   if(!this.tabControl.useClientVisibility)
11492    return this.tabControl.activeTabIndex;
11493   var tabs = this.tabControl.tabs;
11494   var tabIndex = -1;
11495   for(var i = indexCorrection; i < tabs.length; i++) {
11496    var tab = tabs[i];
11497    if(tab.visible && tab.enabled)
11498     tabIndex++;
11499    if(tabIndex == elementIndex)
11500     return i;
11501   }
11502  },
11503  FindSeparatorIndexByElementIndex: function(elementIndex) {
11504   var separatorIndex = -1;
11505   var tabs = this.tabControl.tabs;
11506   for(var i = 0; i < tabs.length; i++) {
11507    var nextIndex = this.tabControl.GetNextVisibleTabIndex(i, true);
11508    var tab = tabs[i];
11509    if(tab.visible && nextIndex > -1) {
11510     if(this.tabControl.IsMultiRow()) {
11511      var nextTabElement = this.tabControl.GetVisibleTabElement(nextIndex);
11512      if(!(this.tabControl.isTabElementStartsNewLine(nextTabElement) && !this.tabControl.previousInvisibleTabExist(nextIndex, nextTabElement)))
11513       separatorIndex++;
11514     }
11515     else
11516      separatorIndex++;
11517    }
11518    if(separatorIndex === elementIndex) {
11519     if(!this.tabControl.enableScrolling || nextIndex > -1)
11520      return i;
11521    }
11522   }
11523  },
11524  FindContentIndexByElementIndex: function (elementIndex) {
11525   if(!this.tabControl.useClientVisibility)
11526    return this.tabControl.activeTabIndex;
11527   var tabs = this.tabControl.tabs;
11528   var tabIndex = -1;
11529   for(var i = 0; i < tabs.length; i++) {
11530    var tab = tabs[i];
11531    if(tab.visible && tab.enabled)
11532     tabIndex++;
11533    if(tabIndex == elementIndex)
11534     return i;
11535   }
11536  },
11537  GetTabStripElement: function(mainElement){
11538   var tabStrip = null;
11539   var elements = ASPx.GetChildElementNodes(mainElement);
11540   var elementCount = elements.length;
11541   for(var i = 0; i < elementCount; i++) {
11542    var element = elements[i];
11543    if(element.tagName == "UL") {
11544     if(element.className.indexOf(Constants.CssClassName.STRIP_WRAPPER) == -1)
11545      tabStrip = element;
11546     else {
11547      element.id = this.GetID(this.tabControl.GetTabsCellWrapperID());
11548      tabStrip = ASPx.GetNodeByClassName(element, Constants.CssClassName.STRIP);
11549     }
11550     break;
11551    }
11552   }
11553   return tabStrip;
11554  },
11555  GetTabElements: function(container) {
11556   return ASPx.GetNodesByClassName(container, Constants.CssClassName.TAB);
11557  },
11558  GetActiveTabElements: function(container) {
11559   return ASPx.GetNodesByClassName(container, Constants.CssClassName.ACTIVE_TAB);
11560  },
11561  GetSpacerElements: function(container) {
11562   return ASPx.GetNodesByClassName(container, Constants.CssClassName.TAB_SPACER);
11563  },
11564  GetTabLinkElements: function(container) {
11565   return ASPx.GetNodesByClassName(container, Constants.CssClassName.TAB_LINK);
11566  },
11567  GetTabImageElements: function(container) {
11568   return ASPx.GetNodesByClassName(container, Constants.CssClassName.TAB_IMAGE);
11569  },
11570  GetContentContainerElement: function(mainElement) {
11571   return ASPx.GetChildByClassName(mainElement, Constants.CssClassName.CONTENT);
11572  },
11573  GetContentElements: function(container) {
11574   return ASPx.GetChildNodes(container, function (el) { return !!el.tagName; });
11575  }
11576 });
11577 var ASPxClientTabControlBase = ASPx.CreateClass(ASPxClientControl, {
11578  constructor: function (name) {
11579   this.constructor.prototype.constructor.call(this, name);
11580   this.activeTabIndex = 0;
11581   this.callbackCount = 0;
11582   this.cookieName = "";
11583   this.emptyHeight = false;
11584   this.emptyWidth = false;
11585   this.tabAlign = "Left";
11586   this.tabPosition = "Top";
11587   this.tabAction = Constants.TabAction.CLICK;
11588   this.tabs = [];
11589   this.tabsOrderInfo = null;
11590   this.tabsContentRequest = [];
11591   this.useClientVisibility = true;
11592   this.enableScrolling = !!this.GetScrollVisibleArea();
11593   this.hasScrollButtons = this.enableScrolling && !!this.GetScrollLeftButtonElement();
11594   this.firstShownTabIndex = 0;
11595   this.scrollManager = null;
11596   this.scrollingFillerElementWidth = 5000;
11597   this.scrollToActiveTab = true;
11598   this.handleClickOnWholeTab = true;
11599   this.deferredActions = [];
11600   this.layoutManager = null;
11601   this.hasTabStip = true;
11602   this.hasContent = false;
11603   this.renderHelper = this.CreateRenderHelper();
11604   this.isFullyInitializedInline = false;
11605   this.isFullyInitialized = false;
11606   this.initializationStepPassed = false;
11607   this.sizingConfig.correction = true;
11608   this.sizingConfig.adjustControl = true;
11609   this.flexEnabled = true;
11610   this.primaryDimension = "width";
11611   this.secondaryDimension = "height";
11612   this.adjustmentVars = { 
11613    stripLastSize: "",
11614    tabsLastSize: "",
11615    indentsSizes: { }, 
11616    scrolling: { },
11617    content: { },
11618    tabs: {
11619     lastSizes: { }
11620    }
11621   };
11622   this.tabStripImages = [];
11623   this.tabStripAdjustmentTimerID = -1;
11624   this.isLoadTabByCallback = false;
11625   this.isActiveTabChanged = false;
11626   this.shouldRaiseActiveTabChangedEvent = false;
11627   this.cacheEnabled = false;
11628   this.cacheDataFieldName = "aspxCache_CacheData";
11629   this.tabHeightManager = null;
11630   this.contentObserving = {
11631    enabled: false,
11632    canObserve: false,
11633    collapsingEnabled: false,
11634    collapsingTimerID: -1,
11635    collapsingTimeout: 500,
11636    collapsingShortTimeout: 100,
11637    sizeEqualityError: 3,
11638    timerID: -1,
11639    timeout: 500
11640   };
11641   this.minLeftIndentSizeLite = 0;
11642   this.minRightIndentSizeLite = 0;
11643   this.minScrollVisibleAreaSize = 50;
11644   this.TabClick = new ASPxClientEvent();
11645   this.ActiveTabChanged = new ASPxClientEvent();
11646   this.ActiveTabChanging = new ASPxClientEvent();
11647  },
11648  SetData: function(data){
11649   if(data.tabs)
11650    this.CreateTabs(data.tabs);
11651  },
11652  Initialize: function () {
11653   ASPxClientControl.prototype.Initialize.call(this);
11654   if(this.IsStateControllerEnabled())
11655    ASPxClientTabControlBase.PrepareStateController();
11656   if(this.IsControlVisible()) {
11657    this.layoutManager.updateTabStripImagesSizes();
11658    this.InitializeTabControl();
11659    this.UpdateLayout();
11660   }
11661   this.initializationStepPassed = true;
11662  },
11663  InlineInitialize: function () {
11664   ASPxClientControl.prototype.InlineInitialize.call(this);
11665   this.tabsOrderInfo = this.getTabsOrderInfo();
11666   this.initializeLayoutManager();
11667   this.InitializeControlElements();
11668   var tabsCell = this.GetTabsCell();
11669   if(tabsCell && this.IsStateControllerEnabled())
11670    ASPx.AssignAccessibilityEventsToChildrenLinks(tabsCell);
11671   this.InitializeAccessibleNavigation();
11672   this.UpdateAdjustmentFlags();
11673   this.initializeTabHeightManager();
11674   if(this.enableScrolling) {
11675    this.InitializeScrolling();
11676    if(!this.flexEnabled)
11677     this.initScrollingFixedLayout();
11678   }
11679   if(this.IsControlVisible())
11680    this.InitializeTabControlInline();
11681  },
11682  InitializeAccessibleNavigation: function() {
11683   if(this.accessibilityCompliant)
11684    ASPxClientTabControlBase.EnsureDocumentKeyDownHandler();
11685  },
11686  initializeLayoutManager: function() {
11687   this.layoutManager = this.flexEnabled ? new FlexLayoutManager(this) : new FixedLayoutManager(this);
11688  },
11689  createTabHeightManagerCore: function() {
11690   if(!(this.GetTabStripContainer() && this.IsTopBottomTabPosition()))
11691    return new FakeTabHeightManager();
11692   var elements = this.GetTabsElements(),
11693    elementCount = elements.length;
11694   for(var i = 0; i < elementCount; i++) {
11695    var element = elements[i];
11696    if(element.style.height)
11697     return new TabCustomHeightManager(this);
11698   }
11699   return new TabDefaultHeightManager(this);
11700  },
11701  initializeTabHeightManager: function() {
11702   this.tabHeightManager = this.layoutManager.createTabHeightManager();
11703  },
11704  initScrollingFixedLayout: function() {
11705   this.GetScrollableArea().style.position = "relative";
11706   var sva = this.GetScrollVisibleArea();
11707   sva.style.overflow = "hidden";
11708   sva.style.position = "relative";
11709   ASPx.SetElementFloat(sva, this.rtl ? "right" : "left");
11710  },
11711  InitializeTabControlInline: function () {
11712   this.layoutManager.inlineInitialize();
11713   this.InitializeEnabledAndVisible();
11714   this.InitializeTabControlCore();
11715   this.isFullyInitializedInline = true;
11716  },
11717  initFixedLayoutInline: function() {
11718   ASPx.RemoveClassNameFromElement(this.GetMainElement(), Constants.CssClassName.INIT_STATE);
11719   if(this.GetTabStripContainer()) {
11720    this.tabHeightManager.initialize();
11721    this.StoreInitialIndentsSize();
11722   }
11723   if(this.enableScrolling) {
11724    this.GetScrollVisibleArea().style.width = "1px";
11725    var tabStrip = this.GetTabsCell();
11726    var tabStripChilds = ASPx.GetChildNodesByTagName(tabStrip, "LI");
11727    var scrollFiller = tabStripChilds[tabStripChilds.length - 1];
11728    scrollFiller.style.width = this.scrollingFillerElementWidth + "px";
11729   }
11730  },
11731  InitializeTabControl: function () {
11732   if(!this.isFullyInitializedInline)
11733    this.InitializeTabControlInline();
11734   this.CalculateSizes();
11735   this.AdjustPageContents();
11736   this.SubsribeForDomObserver();
11737   this.isFullyInitialized = true;
11738  },
11739  SubsribeForDomObserver: function() {
11740   this.contentObserving.enabled = this.hasContent && this.layoutManager.isContentObservingEnabled();
11741   if(!this.contentObserving.enabled)
11742    return;
11743   this.contentObserving.collapsingEnabled = this.layoutManager.isCollapsingInObservingEnabled();
11744   this.EnableContentObservation();
11745   var callbackFunc = function(element) {
11746    this.OnContentSizeObserving(element);
11747   }.aspxBind(this);
11748   ASPx.GetDomObserver().subscribe(this.name + this.GetContentsCellID(), callbackFunc);
11749  },
11750  EnableContentObservation: function() {
11751   this.layoutManager.enableContentObservation();
11752   this.contentObserving.canObserve = true;
11753  },
11754  OnContentSizeObserving: function(element) {
11755   if(!this.contentObserving.canObserve || this.IsPartiallyInitialized() || !this.IsAdjustmentAllowed())
11756    return;
11757   if(this.contentObserving.collapsingEnabled)
11758    this.CollapseControl();
11759   if(this.checkAdjustmentRequired())
11760    this.layoutManager.adjustSizeOnContentModification();
11761   else if(this.contentObserving.collapsingEnabled)
11762    this.ExpandControl();
11763  },
11764  checkAdjustmentRequired: function() {
11765   var sizes = this.GetAdjustedSizes();
11766   var sizeChanged = this.layoutManager.isAdjustmenRequiredByNewSizes(this.adjustedSizes, sizes, this.contentObserving.sizeEqualityError);
11767   if(sizeChanged)
11768    this.adjustedSizes = sizes;
11769   return sizeChanged;
11770  },
11771  areEqualValues: function(val1, val2, error) {
11772   return val1 == val2 || Math.abs(val1 - val2) <= error;
11773  },
11774  SetObservationPaused: function(paused) {
11775   if(this.contentObserving.enabled) {
11776    var observer = ASPx.GetDomObserver(),
11777     contentContainer = this.GetContentsCell();
11778    if(paused)
11779     observer.pause(contentContainer, true);
11780    else
11781     observer.resume(contentContainer, true);
11782   }
11783  },
11784  IsPartiallyInitialized: function () {
11785   return !this.isFullyInitialized;
11786  },
11787  canUseOffsetSizes: function() {
11788   return this.isFullyInitialized && this.IsControlVisible();
11789  },
11790  EnsureControlInitialized: function () {
11791   if(this.IsPartiallyInitialized())
11792    this.InitializeTabControl();
11793  },
11794  UpdateStateObject: function(){
11795   this.UpdateStateObjectWithObject({ activeTabIndex: this.activeTabIndex });
11796  },
11797  BrowserWindowResizeSubscriber: function () {
11798   return this.widthValueSetInPercentage || this.heightValueSetInPercentage || this.IsControlCollapsed();
11799  },
11800  OnBrowserWindowResize: function (e) {
11801   if(!this.IsAdjustmentAllowed()) return;
11802   if(this.contentObserving.enabled) {
11803    if(this.contentObserving.timerID !== -1)
11804     window.clearTimeout(this.contentObserving.timerID);
11805    this.contentObserving.canObserve = false;
11806    var enableObservationFunc = function() { this.EnableContentObservation(); }.aspxBind(this);
11807    this.contentObserving.timerID = window.setTimeout(enableObservationFunc, this.contentObserving.timeout);
11808   }
11809   this.AdjustControlCore();
11810  },
11811  onFocusedTabKeyDown: function(e) {
11812   var decreaseKey = this.IsTopBottomTabPosition() ? ASPx.Key.Left : ASPx.Key.Up,
11813    increaseKey = this.IsTopBottomTabPosition() ? ASPx.Key.Right : ASPx.Key.Down,
11814    activeIndexDiff = e.keyCode === decreaseKey ? -1 : e.keyCode === increaseKey ? 1 : 0;
11815   this.switchActiveTab(activeIndexDiff);
11816  },
11817  switchActiveTab: function(activeIndexDiff) {
11818   if(activeIndexDiff === 0) return;
11819   var newActiveIndex = this.GetActiveTabIndex() + activeIndexDiff,
11820    tabCount = this.GetTabCount();
11821   if(newActiveIndex < 0)
11822    newActiveIndex = tabCount - 1;
11823   else if(newActiveIndex >= tabCount)
11824    newActiveIndex = 0;
11825   this.SetActiveTabIndex(newActiveIndex);
11826  },
11827  CanCauseReadjustment: function() {
11828   return false;
11829  },
11830  IsExpandableByAdjustment: function() {
11831   return true;
11832  },
11833  InitializeEnabledAndVisible: function () {
11834   for(var i = 0; i < this.tabs.length; i++) {
11835    this.SetTabVisibleCore(i, this.tabs[i].clientVisible, true);
11836    this.SetTabEnabled(i, this.tabs[i].clientEnabled, true);
11837   }
11838  },
11839  InitializeCallBackData: function () {
11840   var element = this.getActiveContentElement();
11841   if(element != null) element.loaded = true;
11842  },
11843  InitializeTabControlCore: function () {
11844   if(this.enableScrolling) {
11845    this.CalculateSizes();
11846    if(!this.flexEnabled)
11847     this.RecalculateTabStripWidthLite();
11848   }
11849   else
11850    this.AdjustTabControlSizeLite();
11851   if(this.IsMultiRow())
11852    this.PlaceActiveTabRowToBottom(this.activeTabIndex);
11853  },
11854  StoreInitialIndentsSize: function () {
11855   var leftIndent = this.GetLeftIndentLite(),
11856    rightIndent = this.GetRightIndentLite();
11857   if(leftIndent)
11858    this.minLeftIndentSizeLite = this.GetCachedElementSize(leftIndent);
11859   if(rightIndent)
11860    this.minRightIndentSizeLite = this.GetCachedElementSize(rightIndent);
11861   this.adjustmentVars.indentsSizes = {
11862    left: this.minLeftIndentSizeLite,
11863    right: this.minRightIndentSizeLite
11864   };
11865  },
11866  InitializeScrolling: function () {
11867   this.scrollManager = new TabControlScrollingManager(this, {
11868    scrollableArea: this.GetScrollableArea(),
11869    orientation: [1, 0],
11870    onBeforeScrolling: this.OnBeforeScrolling,
11871    onAfterScrolling: this.OnAfterScrolling.aspxBind(this),
11872    forseEmulation: true,
11873    mouseEventsElement: this.GetScrollVisibleArea(),
11874    useMarginForPosition: false,
11875    preventOuterScroll: true,
11876    handleMouseWheel: !this.scrollButtonsVisible
11877   });
11878   this.scrollManager.scrollSessionInterval = 5;
11879   this.scrollManager.animationAcceleration = 0.5;
11880   this.scrollManager.getValidNewScrollOffset = this.getValidNewScrollOffset.aspxBind(this);
11881   this.InitializeScrollButton(this.GetScrollLeftButtonElement());
11882   this.InitializeScrollButton(this.GetScrollRightButtonElement());
11883  },
11884  InitializeScrollButton: function (button) {
11885   if(!button || !button.id) return;
11886   var img = ASPx.GetNodeByTagName(button, "IMG", 0);
11887   if(!img) {
11888    img = ASPx.GetNodeByTagName(button, "svg", 0);
11889   }
11890   ASPx.Evt.PreventElementDrag(img);
11891   ASPx.Selection.SetElementSelectionEnabled(img, false);
11892   ASPx.Selection.SetElementSelectionEnabled(button, false);
11893   var manager = this.scrollManager;
11894   var dir = button.id.charAt(button.id.length - 1) == "R" ? 1 : -1;
11895   if(this.enabled) {
11896    ASPx.Evt.AttachEventToElement(button, ASPx.TouchUIHelper.touchMouseDownEventName, function (e) { manager.StartScrolling(dir, 5, 5); ASPx.Evt.PreventEvent(e); });
11897    ASPx.Evt.AttachEventToElement(button, ASPx.TouchUIHelper.touchMouseUpEventName, function (e) { manager.StopScrolling(); });
11898   }
11899  },
11900  setMouseScrollEnabled: function(enabled) {
11901   if(this.scrollManager)
11902    this.scrollManager.enableMouseScrollInternal = enabled;
11903  },
11904  getTabWithSeparatorWidth: function(index) {
11905   var tab = this.GetVisibleTabElement(index),
11906    separator = this.GetSeparatorElement(index);
11907   return this.GetCachedElementSize(tab) + this.GetCachedElementSize(separator);
11908  },
11909  ScrollToShowTab: function (tabIndex, doAnimation) {
11910   if(!this.GetVisibleTabElement(tabIndex))
11911    return;
11912   var startIndex = this.firstShownTabIndex;
11913   var endIndex = tabIndex;
11914   var scrollToRight = !this.rtl;
11915   if(tabIndex < this.firstShownTabIndex) {
11916    startIndex = tabIndex;
11917    endIndex = this.firstShownTabIndex - 1;
11918    scrollToRight = !scrollToRight;
11919   }
11920   var width = 0;
11921   var shift = 0;
11922   var tabCount = 0;
11923   var scrollVisibleAreaWidth = this.GetScrollVisibleArea().offsetWidth;
11924   for(var i = startIndex; i <= endIndex; i++)
11925    width += this.getTabWithSeparatorWidth(i);
11926   for(var i = startIndex; i <= endIndex; i++) {
11927    var diff = width - shift;
11928    if(diff > scrollVisibleAreaWidth || !(scrollToRight ^ this.rtl)) {
11929     shift += this.getTabWithSeparatorWidth(i);
11930     tabCount++;
11931    }
11932   }
11933   if(this.GetVisibleTabElement(tabIndex).offsetWidth >= scrollVisibleAreaWidth &&
11934      scrollToRight ^ this.rtl) {
11935    tabCount--;
11936    shift -= this.getTabWithSeparatorWidth(tabIndex);
11937   }
11938   if(shift <= 0) return;
11939   this.firstShownTabIndex += tabCount * (scrollToRight ^ this.rtl ? 1 : -1);
11940   if(doAnimation) {
11941    this.scrollManager.animationOffset = this.GetScrollAnimationOffset(this.firstShownTabIndex);
11942    this.scrollManager.PrepareForScrollAnimation();
11943    this.scrollManager.DoScrollSessionAnimation(scrollToRight ? -1 : 1);
11944   } else {
11945    this.scrollManager.SetScrolledAreaPosition(this.scrollManager.GetScrolledAreaPosition()
11946     + this.GetScrollAnimationOffset(this.firstShownTabIndex) * (scrollToRight ? -1 : 1));
11947   }
11948  },
11949  OnBeforeScrolling: function (manager, direction) {
11950   var tc = manager.owner;
11951   if(tc.IsFullyScrolledToLeft() && direction < 0 || tc.IsFullyScrolledToRight() && direction > 0) {
11952    manager.StopScrolling();
11953    return;
11954   }
11955   var diff = (direction > 0 ^ tc.rtl) ? 1 : -1;
11956   do {
11957    if(tc.firstShownTabIndex <= 0 && diff < 0
11958    || tc.firstShownTabIndex >= tc.tabs.length - 1 && diff > 0) break;
11959    tc.firstShownTabIndex += diff;
11960   } while(!tc.IsTabVisible(tc.firstShownTabIndex));
11961   manager.animationOffset = tc.GetScrollAnimationOffset(tc.firstShownTabIndex);
11962  },
11963  getValidNewScrollOffset: function(newOffset) {
11964   if(newOffset > 0 && !this.rtl || newOffset < 0 && this.rtl)
11965    newOffset = 0;
11966   var minOffset = this.getMaxVisibleOffset() - this.GetScrollableAreaWidth();
11967   if(!this.rtl && newOffset < minOffset)
11968    newOffset = minOffset;
11969   if(this.rtl && newOffset > Math.abs(minOffset))
11970    newOffset = Math.abs(minOffset);
11971   var hiddenWidth = Math.abs(newOffset),
11972    tabsWidth = 0;
11973   for(var i = 0; hiddenWidth >= tabsWidth && i < this.tabs.length - 1; i++)
11974    tabsWidth += this.getTabWithSeparatorWidth(i);
11975   this.firstShownTabIndex = i - 1;
11976   return newOffset;
11977  },
11978  getMaxVisibleOffset: function() {
11979   var visibleArea = this.GetScrollVisibleArea(),
11980    maxVisibleRightOffset = this.getRightTemplateOffset();
11981   for(var i = this.tabs.length - 1; i >= 0; i--) {
11982    var newWidth = maxVisibleRightOffset + this.getTabWithSeparatorWidth(i);
11983    if(newWidth > visibleArea.offsetWidth)
11984     break;
11985    maxVisibleRightOffset = newWidth;
11986   }
11987   return maxVisibleRightOffset;
11988  },
11989  getRightTemplateOffset: function() {
11990   return 0;
11991  },
11992  OnAfterScrolling: function(manager, direction) {
11993   this.focusActiveTab();
11994   manager.owner.UpdateScrollButtonsEnabled();
11995  },
11996  AdjustTabScrolling: function (scrollToActiveTab, doAnimation) {
11997   this.CalculateSizes();
11998   this.AdjustTabScrollingCore(scrollToActiveTab, doAnimation);
11999  },
12000  AfterInitialize: function() {
12001   ASPxClientControl.prototype.AfterInitialize.call(this);
12002   if(this.enableScrolling)
12003    this.AdjustTabScrollingCore(true, false);
12004  },
12005  AdjustTabScrollingCore: function(scrollToActiveTab, doAnimation) {
12006   if(!this.isInitialized || !this.GetMainElement()) return;
12007   this.adjustTabStripScrolling(scrollToActiveTab, doAnimation);
12008   this.AdjustPageContents();
12009  },
12010  adjustTabStripScrolling: function(scrollToActiveTab, doAnimation) {
12011   if(!this.enableScrolling) return;
12012   this.UpdateScrollButtonsVisible();
12013   if(scrollToActiveTab)
12014    this.ScrollToShowTab(this.activeTabIndex, doAnimation);
12015   if(this.enabled)
12016    this.UpdateScrollButtonsEnabled();
12017  },
12018  GetScrollAnimationOffset: function (newFirstShownTabIndex) {
12019   var newPos = 0;
12020   var i = this.GetNextVisibleTabIndex(-1);
12021   while(i < newFirstShownTabIndex && i > -1) {
12022    newPos += this.GetVisibleTabElement(i).offsetWidth;
12023    var separator = this.GetSeparatorElement(i);
12024    newPos += separator && separator.offsetWidth;
12025    i = this.GetNextVisibleTabIndex(i);
12026   }
12027   if(this.rtl)
12028    newPos = -newPos;
12029   return Math.abs(this.scrollManager.GetScrolledAreaPosition() + newPos);
12030  },
12031  AdjustScrollVisibleAreaWidth: function () {
12032   var sva = this.GetScrollVisibleArea();
12033   var mainElement = this.GetMainElement();
12034   if((mainElement.style.width == "" || mainElement.style.width == "0px") && !this.GetContentsCell()) {
12035    ASPx.SetOffsetWidth(sva, this.GetScrollableAreaWidth());
12036    return;
12037   }
12038   ASPx.SetOffsetWidth(sva, this.minScrollVisibleAreaSize);
12039   var scrollWrapper = this.GetTabsCellWrapperElement();
12040   var c = ASPx.GetChildElementNodes(scrollWrapper);
12041   var restWidth = 0;
12042   for(var i = 0; i < c.length; i++)
12043    restWidth += c[i].offsetWidth;
12044   restWidth = restWidth - sva.offsetWidth + this.GetStripContainerBordersPaddingsMarginsWidth();
12045   var svaWidth = this.adjustmentVars.controlSizes.primary - restWidth;
12046   ASPx.SetOffsetWidth(sva, svaWidth);
12047   var scrollWrapperWidth = restWidth + svaWidth;
12048   ASPx.SetOffsetWidth(scrollWrapper, scrollWrapperWidth);
12049   this.RecalculateTabStripWidthLite();
12050  },
12051  DoSafeScrollPositionOperation: function (func) {
12052   var lastScrollYPos = ASPx.GetDocumentScrollTop();
12053   var parent = this.GetMainElement().parentNode;
12054   var scrollParentYBefore = parent.scrollTop;
12055   func();
12056   if(scrollParentYBefore != parent.scrollTop)
12057    parent.scrollTop = scrollParentYBefore;
12058   var scrollY = ASPx.GetDocumentScrollTop();
12059   if(lastScrollYPos != scrollY)
12060    window.scrollTo(ASPx.GetDocumentScrollLeft(), lastScrollYPos);
12061  },
12062  UpdateScrollButtonsEnabled: function () {
12063   if(!this.IsStateControllerEnabled()) return;
12064   ASPx.GetStateController().SetElementEnabled(this.GetScrollLeftButtonElement(), !this.IsFullyScrolledToLeft());
12065   ASPx.GetStateController().SetElementEnabled(this.GetScrollRightButtonElement(), !this.IsFullyScrolledToRight());
12066  },
12067  UpdateScrollButtonsVisible: function () {
12068   this.layoutManager.adjustScrollVisibleAreaWidth();
12069   var svaWidth = this.GetScrollVisibleArea().offsetWidth;
12070   var scrollButtonsVisible = svaWidth < this.GetScrollableAreaWidth();
12071   if(this.hasScrollButtons) {
12072    ASPx.SetElementDisplay(this.GetScrollLeftButtonContainer(), scrollButtonsVisible);
12073    ASPx.SetElementDisplay(this.GetScrollRightButtonContainer(), scrollButtonsVisible);
12074   }
12075   if(!scrollButtonsVisible)
12076    this.ScrollToShowTab(0, true);
12077   this.layoutManager.adjustScrollVisibleAreaWidth();
12078  },
12079  GetScrollableAreaWidth: function () {
12080   return this.layoutManager.getScrollableAreaWidth();
12081  },
12082  getScrollableAreaWidthCore: function() {
12083   return this.GetScrollableArea().offsetWidth - this.scrollingFillerElementWidth;
12084  },
12085  IsFullyScrolledToLeft: function () {
12086   if(!this.rtl)
12087    return ASPx.PxToInt(this.GetScrollableArea().style.left) >= 0;
12088   var visibleWidth = this.GetScrollableAreaWidth() - ASPx.PxToInt(this.GetScrollableArea().style.left);
12089   return visibleWidth <= this.GetScrollVisibleArea().offsetWidth ||
12090     this.GetNextVisibleTabIndex(this.firstShownTabIndex) < 0;
12091  },
12092  IsFullyScrolledToRight: function () {
12093   if(this.rtl)
12094    return ASPx.PxToInt(this.GetScrollableArea().style.left) <= 0 || this.GetPrevVisibleTabIndex(this.firstShownTabIndex) < 0;
12095   var visibleWidth = this.GetScrollableAreaWidth() + ASPx.PxToInt(this.GetScrollableArea().style.left);
12096   return visibleWidth <= this.GetScrollVisibleArea().offsetWidth ||
12097     this.GetNextVisibleTabIndex(this.firstShownTabIndex) < 0;
12098  },
12099  CorrectTabHeightOnStateChanged: function (element) {
12100   this.tabHeightManager.correctTabHeightOnStateChanged(element);
12101  },
12102  CreateRenderHelper: function() {
12103   return new TabControlRenderHelper(this);
12104  },
12105  IsClientSideEventsAssigned: function() {
12106   return !this.TabClick.IsEmpty()
12107    || !this.ActiveTabChanging.IsEmpty()
12108    || !this.ActiveTabChanged.IsEmpty();
12109  },
12110  InitializeControlElements: function () {
12111   this.renderHelper.InitializeControlElements();
12112  },
12113  PrepareTabStripForImageLoading: function() {
12114   var stripContainer = this.GetTabStripContainer();
12115   if(stripContainer) {
12116    var images = ASPx.GetNodes(stripContainer, function(el) { return el.tagName == "IMG"; });
12117    for(var i = 0; i < images.length; i++) {
12118     var image = images[i];
12119     var imageInfo = {
12120      element: image,
12121      loaded: false,
12122      width: 0,
12123      height: 0
12124     };
12125     ASPx.Evt.AttachEventToElement(image, "load", this.GetTabStripImageLoadedHandler(imageInfo));
12126     this.tabStripImages.push(imageInfo);
12127    }
12128   }
12129  },
12130  GetTabStripImageLoadedHandler: function(imageInfo) {
12131   return function() {
12132    this.OnTabStripImageLoaded(imageInfo);
12133   }.aspxBind(this);
12134  },
12135  OnTabStripImageLoaded: function(imageInfo) {
12136   if(!(this.isInitialized && this.isFullyInitialized) || imageInfo.loaded) return;
12137   imageInfo.loaded = true;
12138   var imageWidth = imageInfo.element.offsetWidth,
12139    imageHeight = imageInfo.element.offsetHeight,
12140    imageSizeChanged = imageWidth !== imageInfo.width || imageHeight !== imageInfo.height;
12141   if(imageSizeChanged && this.tabStripAdjustmentTimerID === -1) {
12142    this.tabStripAdjustmentTimerID = window.setTimeout(function() {
12143     this.tabStripAdjustmentTimerID = -1;
12144     this.adjustControlInternal();
12145    }.aspxBind(this), 0);
12146   }
12147   imageInfo.width = imageWidth;
12148   imageInfo.height = imageHeight;
12149  },
12150  UpdateTabStripImagesSizes: function() {
12151   for(var i = 0; i < this.tabStripImages.length; i++) {
12152    var imageInfo = this.tabStripImages[i];
12153    imageInfo.width = imageInfo.element.offsetWidth;
12154    imageInfo.height = imageInfo.element.offsetHeight;
12155   }
12156  },
12157  AdjustTabContents: function() {
12158   this.CorrectWrappedText(this.GetTabLinkElements);
12159  },
12160  GetTabLinkElements: function () {
12161   var container = this.GetTabStripContainer();
12162   if(container)
12163    return ASPx.GetNodesByClassName(container, Constants.CssClassName.TAB_LINK);
12164   return null;
12165  },
12166  GetCachedBordersPaddingsMarginsWidth: function(element, dimension) {
12167   if(!dimension)
12168    dimension = this.primaryDimension;
12169   var cache = this.GetOrCreateElementCache(element);
12170   return dimension == "width" ? cache.horizontalBordersPaddingsMarginsWidth : cac
12170he.verticalBordersPaddingsMarginsWidth;
12171  },
12172  GetCachedBordersAndPaddingsWidth: function(element, dimension) {
12173   if(!dimension)
12174    dimension = this.primaryDimension;
12175   var cache = this.GetOrCreateElementCache(element);
12176   return dimension == "width" ? cache.horizontalBordersAndPaddingsWidth : cache.verticalBordersAndPaddingsWidth;
12177  },
12178  GetCachedVerticalBordersPaddingsMarginsWidth: function(element) {
12179   var cache = this.GetOrCreateElementCache(element);
12180   return cache.verticalBordersPaddingsMarginsWidth;
12181  },
12182  GetCachedHorizontalBordersPaddingsMarginsWidth: function(element) {
12183   var cache = this.GetOrCreateElementCache(element);
12184   return cache.horizontalBordersPaddingsMarginsWidth;
12185  },
12186  GetCachedVerticalBordersAndPaddingsWidth: function(element) {
12187   var cache = this.GetOrCreateElementCache(element);
12188   return cache.verticalBordersAndPaddingsWidth;
12189  },
12190  GetCachedHorizontalBordersAndPaddingsWidth: function(element) {
12191   var cache = this.GetOrCreateElementCache(element);
12192   return cache.horizontalBordersAndPaddingsWidth;
12193  },
12194  GetCachedElementInnerSize: function(element, dimension) {
12195   if(!element) return 0;
12196   if(!dimension)
12197    dimension = this.primaryDimension;
12198   var cache = this.GetOrCreateElementCache(element);
12199   return dimension === "width" ? cache.width : cache.height;
12200  },
12201  GetCachedElementSize: function(element, dimension) {
12202   if(!element) return 0;
12203   if(!dimension)
12204    dimension = this.primaryDimension;
12205   var cache = this.GetOrCreateElementCache(element);
12206   if(!cache.display)
12207    return 0;
12208   return dimension === "width" ? cache.outerWidth : cache.outerHeight;
12209  },
12210  GetElementCurrentStyle: function(element) {
12211   var style = element.currentStyle;
12212   if(style)
12213    return window.getComputedStyle ? window.getComputedStyle(element, null) : style;
12214   else
12215    return ASPx.GetCurrentStyle(element);
12216  },
12217  CacheElement: function(element) {
12218   var cache = { },
12219    style = this.GetElementCurrentStyle(element);
12220   var useOffsetSizes = style.height == "auto";
12221   cache.borderLeftWidth = style.borderLeftStyle != "none" ? ASPx.PxToFloat(style.borderLeftWidth) : 0;
12222   cache.borderRightWidth = style.borderRightStyle != "none" ? ASPx.PxToFloat(style.borderRightWidth) : 0;
12223   cache.borderTopWidth = style.borderTopStyle != "none" ? ASPx.PxToFloat(style.borderTopWidth) : 0;
12224   cache.borderBottomWidth = style.borderBottomStyle != "none" ? ASPx.PxToFloat(style.borderBottomWidth) : 0;
12225   cache.paddingLeft = ASPx.PxToFloat(style.paddingLeft);
12226   cache.paddingRight = ASPx.PxToFloat(style.paddingRight);
12227   cache.paddingTop = ASPx.PxToFloat(style.paddingTop);
12228   cache.paddingBottom = ASPx.PxToFloat(style.paddingBottom);
12229   cache.marginLeft = ASPx.PxToFloat(style.marginLeft);
12230   cache.marginRight = ASPx.PxToFloat(style.marginRight);
12231   cache.marginTop = ASPx.PxToFloat(style.marginTop);
12232   cache.marginBottom = ASPx.PxToFloat(style.marginBottom);
12233   cache.horizontalBordersAndPaddingsWidth = cache.borderLeftWidth + cache.borderRightWidth + cache.paddingLeft + cache.paddingRight;
12234   cache.verticalBordersAndPaddingsWidth = cache.borderTopWidth + cache.borderBottomWidth + cache.paddingTop + cache.paddingBottom;
12235   cache.horizontalMarginsWidth = cache.marginLeft + cache.marginRight;
12236   cache.verticalMarginsWidth = cache.marginTop + cache.marginBottom;
12237   cache.horizontalBordersPaddingsMarginsWidth = cache.horizontalBordersAndPaddingsWidth + cache.horizontalMarginsWidth;
12238   cache.verticalBordersPaddingsMarginsWidth = cache.verticalBordersAndPaddingsWidth + cache.verticalMarginsWidth;
12239   if(useOffsetSizes) {
12240    cache.width = element.offsetWidth - cache.horizontalBordersAndPaddingsWidth;
12241    cache.height = element.offsetHeight - cache.verticalBordersAndPaddingsWidth;
12242   }
12243   else {
12244    cache.width = ASPx.PxToFloat(style.width);
12245    cache.height = ASPx.PxToFloat(style.height);
12246   }
12247   cache.offsetWidth = cache.width + cache.horizontalBordersAndPaddingsWidth;
12248   cache.offsetHeight = cache.height + cache.verticalBordersAndPaddingsWidth;
12249   cache.outerWidth = cache.width + cache.horizontalBordersPaddingsMarginsWidth;
12250   cache.outerHeight = cache.height + cache.verticalBordersPaddingsMarginsWidth;
12251   cache.display = ASPx.GetElementDisplay(element);
12252   cache.needRefresh = !(ASPx.documentLoaded && cache.display);
12253   element[this.cacheDataFieldName] = cache;
12254  },
12255  GetElementCache: function(element) {
12256   return element[this.cacheDataFieldName];
12257  },
12258  GetOrCreateElementCache: function(element) {
12259   this.EnsureElementCached(element);
12260   return this.GetElementCache(element);
12261  },
12262  EnsureElementCached: function(element) {
12263   var cache = this.GetElementCache(element);
12264   if(!this.cacheEnabled || this.UseProportionalTabSizes() || !cache || cache.needRefresh)
12265    this.CacheElement(element);
12266  },
12267  ClearElementCache: function(element) {
12268   if(element)
12269    element[this.cacheDataFieldName] = null;
12270  },
12271  ClearTabElementsCache: function(index) {
12272   var activeTabElement = this.GetTabElement(index, true),
12273    tabElement = this.GetTabElement(index, false);
12274   if(activeTabElement)
12275    this.ClearElementCache(activeTabElement);
12276   if(tabElement)
12277    this.ClearElementCache(tabElement);
12278   this.tabHeightManager.requestAdjustment();
12279  },
12280  CollapseControl: function() {
12281   if(!this.NeedCollapseControlCore() || this.IsPartiallyInitialized()) return;
12282   this.isControlCollapsed = true;
12283   this.layoutManager.collapseTabStrip();
12284   if(this.adjustmentVars.content.needCollapsing) {
12285    this.SetObservationPaused(true);
12286    var contentHolder = this.getActiveContentHolder();
12287    if(contentHolder) {
12288     this.adjustmentVars.content.lastHeight = contentHolder.style.height;
12289     contentHolder.style.height = "";
12290    }
12291    this.SetObservationPaused(false);
12292   }
12293  },
12294  collapseTabStrip: function() {
12295   if(this.enableScrolling)
12296    this.CollapseTabScrolling();
12297   else
12298    this.CollapseControlCommon();
12299  },
12300  CollapseControlCommon: function() {
12301   var stripContainer = this.GetTabStripContainer(),
12302    leftIndent = this.GetLeftIndentLite(),
12303    rightIndent = this.GetRightIndentLite();
12304   if(!stripContainer) return;
12305   this.adjustmentVars.indentsSizes.leftLastSize = leftIndent.style[this.primaryDimension];
12306   this.adjustmentVars.indentsSizes.rightLastSize = rightIndent.style[this.primaryDimension];
12307   this.adjustmentVars.stripLastSize = stripContainer.style[this.primaryDimension];
12308   if(this.IsMultiRow()) {
12309    var tabsHolder = this.getTabsHolderElement();
12310    this.adjustmentVars.tabsLastSize = tabsHolder.style[this.primaryDimension];
12311   }
12312   if(this.UseProportionalTabSizes())
12313    this.CollapseTabSizes();
12314   this.SetCachedElementSize(leftIndent, this.minLeftIndentSizeLite);
12315   this.SetCachedElementSize(rightIndent, this.minRightIndentSizeLite);
12316   this.RecalculateTabStripWidthLite(this.GetStripSizeLite(), this.minLeftIndentSizeLite, this.minRightIndentSizeLite);
12317  },
12318  CollapseTabSizes: function() {
12319   this.adjustmentVars.tabs.lastSizes = { };
12320   var tabElements = this.GetTabsElements();
12321   for(var i = 0, count = tabElements.length; i < count; i++) {
12322    var tabElement = tabElements[i];
12323    this.adjustmentVars.tabs.lastSizes[tabElement.id] = tabElement.style.width;
12324    tabElement.style.width = "";
12325   }
12326  },
12327  CollapseTabScrolling: function() {
12328   var scrollWrapper = this.GetTabsCellWrapperElement(),
12329    sva = this.GetScrollVisibleArea();
12330   if(!scrollWrapper) return;
12331   this.adjustmentVars.scrolling.svaLastWidth = sva.style.width;
12332   this.adjustmentVars.scrolling.wrapperLastWidth = scrollWrapper.style.width;
12333   var mainElement = this.GetMainElement();
12334   if((mainElement.style.width == "" || mainElement.style.width == "0px") && !this.GetContentsCell()) {
12335    ASPx.SetOffsetWidth(sva, this.GetScrollableAreaWidth());
12336    return;
12337   }
12338   ASPx.SetOffsetWidth(sva, this.minScrollVisibleAreaSize);
12339   var c = ASPx.GetChildElementNodes(scrollWrapper),
12340    scrollWrapperWidth = 0;
12341   for(var i = 0; i < c.length; i++)
12342    scrollWrapperWidth += c[i].offsetWidth;
12343   scrollWrapper.style.width = scrollWrapperWidth + "px";
12344  },
12345  ExpandControl: function() {
12346   if(!this.NeedCollapseControlCore())
12347    return;
12348   this.isControlCollapsed = false;
12349   this.layoutManager.expandTabStrip();
12350   if(this.adjustmentVars.content.needCollapsing) {
12351    this.SetObservationPaused(true);
12352    var contentHolder = this.getActiveContentHolder();
12353    contentHolder.style.height = this.adjustmentVars.content.lastHeight;
12354    this.SetObservationPaused(false);
12355   }
12356  },
12357  expandTabStrip: function() {
12358   if(this.enableScrolling)
12359    this.ExpandTabScrolling();
12360   else
12361    this.ExpandControlCommon();
12362  },
12363  ExpandControlCommon: function() {
12364   var stripContainer = this.GetTabStripContainer();
12365   if(!stripContainer)
12366    return;
12367   var leftIndent = this.GetLeftIndentLite(),
12368    rightIndent = this.GetRightIndentLite();
12369   leftIndent.style[this.primaryDimension] = this.adjustmentVars.indentsSizes.leftLastSize;
12370   rightIndent.style[this.primaryDimension] = this.adjustmentVars.indentsSizes.rightLastSize;
12371   if(this.IsTopBottomTabPosition()) {
12372    stripContainer.style.width = this.adjustmentVars.stripLastSize;
12373    if(this.IsMultiRow()) {
12374     var tabsHolder = this.getTabsHolderElement();
12375     tabsHolder.style.width = this.adjustmentVars.tabsLastSize;
12376    }
12377    if(this.UseProportionalTabSizes())
12378     this.ExpandTabSizes();
12379   }
12380  },
12381  ExpandTabScrolling: function() {
12382   var sva = this.GetScrollVisibleArea(),
12383    scrollWrapper = this.GetTabsCellWrapperElement();
12384   if(!scrollWrapper) return;
12385   sva.style.width = this.adjustmentVars.scrolling.svaLastWidth;
12386   scrollWrapper.style.width = this.adjustmentVars.scrolling.wrapperLastWidth;
12387  },
12388  ExpandTabSizes: function() {
12389   var tabElements = this.GetTabsElements();
12390   for(var i = 0, count = tabElements.length; i < count; i++) {
12391    var tabElement = tabElements[i];
12392    tabElement.style.width = this.adjustmentVars.tabs.lastSizes[tabElement.id];
12393   }
12394  },
12395  NeedCollapseControlCore: function () {
12396   return this.layoutManager.needCollapseControl();
12397  },
12398  CalculateSizes: function() {
12399   this.layoutManager.calculateSizes();
12400  },
12401  calculateSizesCore: function () {
12402   this.updateContentAdjustmentFlags();
12403   this.tabHeightManager.adjustTabs();
12404   if(!this.isControlCollapsed)
12405    this.CollapseControl();
12406   this.isControlCollapsed = false;
12407   this.adjustmentVars.stripSizes = { };
12408   this.UpdateStripSizes(this.GetStripSizeLite(this.UseProportionalTabSizes()));
12409   this.AdjustTabStripHeight();
12410   this.calculateMainElementSizes();
12411   this.adjustmentVars.controlSizes = {};
12412   this.adjustmentVars.controlSizes.primary = this.GetMaxValueExtended(
12413    this.enableScrolling ? this.minScrollVisibleAreaSize : this.adjustmentVars.stripFullSize,
12414    this.adjustmentVars.mainElementSizes.primary);
12415   this.adjustmentVars.controlSizes.secondary = this.adjustmentVars.mainElementSizes.secondary;
12416   this.CalculateContentHeight();
12417  },
12418  AdjustTabStripHeight: function() {
12419   if(!this.tabHeightManager.needAdjustTabStrip())
12420    return;
12421   var stripContainer = this.GetTabStripContainer();
12422   var height = this.tabHeightManager.getTabStripHeight();
12423   this.adjustmentVars.stripSizes.secondary = height;
12424   height = this.GetPreparedSizeValue(height);
12425   height = height > 0 ? height : 0;
12426   stripContainer.style.height = height + "px";
12427  },
12428  calculateMainElementSizes: function() {
12429   var mainElement = this.GetMainElement();
12430   this.ClearElementCache(mainElement);
12431   var cache = this.GetOrCreateElementCache(mainElement);
12432   this.adjustmentVars.mainElementCache = cache;
12433   this.adjustmentVars.mainElementSizes = {
12434    primary: cache[this.primaryDimension],
12435    secondary: cache[this.secondaryDimension]
12436   };
12437  },
12438  updateContentAdjustmentFlags: function() {
12439   var contentInfo = this.adjustmentVars.content;
12440   contentInfo.needAdjustment = this.hasContent && this.layoutManager.isContentAdjustmentRequired();
12441   contentInfo.needCollapsing = contentInfo.needAdjustment && this.layoutManager.isContentCollapsingRequired();
12442  },
12443  CalculateContentHeight: function() {
12444   if(!this.adjustmentVars.content.needAdjustment) return;
12445   var mainElement = this.GetMainElement();
12446   var hasFixedHeight = !this.emptyHeight && !this.heightValueSetInPercentage;
12447   var contentHeight = 0,
12448    controlHeight = 0;
12449   if(hasFixedHeight)
12450    controlHeight = ASPx.PxToFloat(mainElement.style.height);
12451   else if(this.IsTopBottomTabPosition())
12452    controlHeight = this.adjustmentVars.controlSizes.secondary;
12453   else
12454    controlHeight = this.adjustmentVars.controlSizes.primary;
12455   if(this.IsTopBottomTabPosition()) {
12456    var stripContainer = this.GetTabStripContainer();
12457    var stripHeight = 0;
12458    if(stripContainer)
12459     stripHeight = this.adjustmentVars.stripSizes.secondary + this.GetCachedBordersPaddingsMarginsWidth(stripContainer, "height");
12460    contentHeight = controlHeight - stripHeight;
12461   }
12462   else
12463    contentHeight = controlHeight;
12464   this.adjustmentVars.content.height = contentHeight;
12465  },
12466  UpdateStripSizes: function(primarySize) {
12467   this.adjustmentVars.stripSizes.primary = primarySize;
12468   if(!this.enableScrolling)
12469    this.adjustmentVars.stripFullSize = this.adjustmentVars.stripSizes.primary + this.minLeftIndentSizeLite + this.minRightIndentSizeLite;
12470  },
12471  AdjustPageContents: function () {
12472   if(!(this.adjustmentVars.content.needAdjustment)) return;
12473   var contentContainer = this.GetContentsCell(),
12474    contentHolder = this.getActiveContentHolder();
12475   var contentInnerHeight = this.adjustmentVars.content.height - this.GetCachedVerticalBordersPaddingsMarginsWidth(contentContainer);
12476   if(contentHolder)
12477    contentHolder.style.height = contentInnerHeight + "px";
12478  },
12479  UpdateAdjustmentFlags: function () {
12480   var mainElement = this.GetMainElement();
12481   if(mainElement) {
12482    this.UpdatePercentSizeConfig([mainElement.style.width], [mainElement.style.height]);
12483    if(!this.IsTopBottomTabPosition()) {
12484     this.primaryDimension = "height";
12485     this.secondaryDimension = "width";
12486    }
12487   }
12488  },
12489  GetMaxValue: function (val1, val2) {
12490   return val1 > val2 ? val1 : val2;
12491  },
12492  GetMaxValueExtended: function (val1, val2, val3) {
12493   var ret = 0;
12494   for(var i = 0; i < arguments.length; i++) {
12495    if(arguments[i] > ret)
12496     ret = arguments[i];
12497   }
12498   return ret;
12499  },
12500  AdjustTabControlSizeLite: function() {
12501   this.layoutManager.adjustSize();
12502  },
12503  adjustTabControlSizeCore: function () {
12504   this.CalculateSizes();
12505   if(!this.GetTabsCell()) {
12506    this.AdjustPageContents();
12507    return;
12508   }
12509   var controlSize = this.adjustmentVars.controlSizes.primary;
12510   var tabsSize = this.adjustmentVars.stripSizes.primary;
12511   var indentsSize = controlSize - tabsSize - this.GetStripContainerBordersPaddingsMarginsWidth();
12512   this.ClearElementCache(this.GetLeftIndentLite());
12513   this.ClearElementCache(this.GetRightIndentLite());
12514   switch(this.tabAlign) {
12515    case "Left":
12516     var leftIndentSize = this.GetCachedElementSize(this.GetLeftIndentLite());
12517     indentsSize = indentsSize - leftIndentSize;
12518     this.adjustmentVars.indentsSizes = {
12519      left: leftIndentSize,
12520      right: this.GetMaxValue(indentsSize, this.minRightIndentSizeLite)
12521     };
12522     this.SetCachedElementSize(this.GetRightIndentLite(), this.adjustmentVars.indentsSizes.right);
12523     break;
12524    case "Right":
12525     var rightIndentSize = this.GetCachedElementSize(this.GetRightIndentLite());
12526     indentsSize = indentsSize - rightIndentSize;
12527     this.adjustmentVars.indentsSizes = {
12528      left: this.GetMaxValue(indentsSize, this.minLeftIndentSizeLite),
12529      right: rightIndentSize
12530     };
12531     this.SetCachedElementSize(this.GetLeftIndentLite(), this.adjustmentVars.indentsSizes.left);
12532     break;
12533    case "Center":
12534     indentsSize = Math.floor(indentsSize / 2);
12535     this.adjustmentVars.indentsSizes.left = this.GetMaxValue(indentsSize, this.minLeftIndentSizeLite);
12536     this.SetCachedElementSize(this.GetLeftIndentLite(), this.adjustmentVars.indentsSizes.left);
12537     indentsSize = controlSize - (tabsSize + indentsSize) - this.GetStripContainerBordersPaddingsMarginsWidth();
12538     this.adjustmentVars.indentsSizes.right = this.GetMaxValue(indentsSize, this.minRightIndentSizeLite);
12539     this.SetCachedElementSize(this.GetRightIndentLite(), this.adjustmentVars.indentsSizes.right);
12540     break;
12541    default:
12542     indentsSize = this.GetCachedElementSize(this.GetLeftIndentLite()) + this.GetCachedElementSize(this.GetRightIndentLite());
12543     tabsSize = controlSize - indentsSize;
12544   }
12545   if(this.UseProportionalTabSizes()) {
12546    this.SetStripSizeLite(tabsSize);
12547    this.UpdateStripSizes(tabsSize);
12548   }
12549   this.RecalculateTabStripWidthLite();
12550   this.AdjustPageContents();
12551  },
12552  GetStripContainerBordersPaddingsMarginsWidth: function() {
12553   if(this.IsTopBottomTabPosition() && !this.enableScrolling)
12554    return this.GetCachedHorizontalBordersPaddingsMarginsWidth(this.GetTabsCell());
12555   if(this.enableScrolling)
12556    return this.GetCachedHorizontalBordersPaddingsMarginsWidth(this.GetScrollVisibleArea().parentNode);
12557   return this.GetCachedVerticalBordersPaddingsMarginsWidth(this.GetTabsCell());
12558  },
12559  GetStripSizeLite: function (storeTabSizes) {
12560   if(!this.GetTabStripContainer())
12561    return 0;
12562   if(storeTabSizes) {
12563    this.adjustmentVars.tabSizes = {};
12564    this.adjustmentVars.tabSizesSums = {};
12565   }
12566   var size = 0,
12567    prevSize = 0,
12568    tab,
12569    rowIndex = this.IsMultiRow() ? -1 : 0;
12570   for(var i = 0; i < this.tabs.length; i++) {
12571    tab = this.GetVisibleTabElement(i);
12572    if(!tab)
12573     continue;
12574    if(this.isTabElementStartsNewLine(tab)) {
12575     rowIndex++;
12576     if(prevSize < size)
12577      prevSize = size;
12578     size = 0;
12579    }
12580    if(!this.GetTab(i).clientVisible)
12581     continue;
12582    var tabSize = this.GetCachedElementSize(tab, this.primaryDimension);
12583    if(storeTabSizes) {
12584     this.adjustmentVars.tabSizes[i] = tabSize;
12585     var tabSizesSums = this.adjustmentVars.tabSizesSums;
12586     if(!ASPx.IsExists(tabSizesSums[rowIndex]))
12587      tabSizesSums[rowIndex] = 0;
12588     tabSizesSums[rowIndex] += tabSize;
12589    }
12590    var separator = this.GetSeparatorElement(i);
12591    size += tabSize + this.GetCachedElementSize(separator, this.primaryDimension);
12592   }
12593   if(prevSize > size)
12594    size = prevSize;
12595   return size;
12596  },
12597  GetTabRows: function() {
12598   var rows = [],
12599    tabLines = this.getTabLines();
12600   for(var rowIndex = 0, tabLine; tabLine = tabLines[rowIndex]; rowIndex++) {
12601    var row = [];
12602    rows.push(row);
12603    for(var tabIndex = 0, tab; tab = tabLine[tabIndex]; tabIndex++) {
12604     if(tab.GetVisible())
12605      row.push(tab.index);
12606    }
12607   }
12608   return rows;
12609  },
12610  SetStripSizeLite: function (size) {
12611   var spacerSize = this.GetTabSpaceSizeLite(),
12612    rows = this.GetTabRows();
12613   for(var i = 0; i < rows.length; i++) {
12614    var row = rows[i],
12615     count = row.length,
12616     rowSize = size - spacerSize * (count - 1),
12617     newTabSizesSum = 0;
12618    for(var index = 0; index < count; index++) {
12619     var tabIndex = row[index],
12620      tabSize = this.adjustmentVars.tabSizes[tabIndex],
12621      newTabSizePrecise = rowSize * (tabSize / this.adjustmentVars.tabSizesSums[i]),
12622      newTabSize = this.GetPreparedSizeValue(newTabSizePrecise);
12623     newTabSizesSum += newTabSize;
12624     if(index == count - 1)
12625      newTabSize += rowSize - newTabSizesSum;
12626     var activeTabElement = this.GetTabElement(tabIndex, true),
12627      tabElement = this.GetTabElement(tabIndex, false);
12628     this.SetCachedElementSize(activeTabElement, newTabSize);
12629     this.SetCachedElementSize(tabElement, newTabSize);
12630     this.ClearElementCache(activeTabElement);
12631     this.ClearElementCache(tabElement);
12632    }
12633   }
12634  },
12635  getTabSpacerElement: function() {
12636   var spacerClassName = Constants.CssClassName.TAB_SPACER;
12637   if(this.IsMultiRow()) {
12638    var tabsHolder = this.getTabsHolderElement(),
12639     collection = ASPx.GetNodesByClassName(tabsHolder, spacerClassName);
12640    if(collection && collection.length > 0) {
12641     var len = collection.length;
12642     while(len--)
12643      if(ASPx.GetElementDisplay(collection[len]))
12644       return collection[len];
12645     return collection[0];
12646    }
12647    return null;
12648   }
12649   return ASPx.GetChildByClassName(this.GetTabsCell(), spacerClassName);
12650  },
12651  GetTabSpaceSizeLite: function() {
12652   var spacer = this.getTabSpacerElement();
12653   return spacer ? this.GetCachedElementSize(spacer) : 0;
12654  },
12655  RecalculateTabStripWidthLite: function(stripSize, leftIndentSize, rightIndentSize) {
12656   if(!this.IsTopBottomTabPosition())
12657    return;
12658   if(stripSize === undefined)
12659    stripSize = this.adjustmentVars.stripSizes.primary;
12660   if(leftIndentSize === undefined)
12661    leftIndentSize = this.adjustmentVars.indentsSizes.left;
12662   if(rightIndentSize === undefined)
12663    rightIndentSize = this.adjustmentVars.indentsSizes.right;
12664   if(this.IsMultiRow())
12665    stripSize = this.GetPreparedSizeValue(stripSize);
12666   var tabStrip = this.GetTabsCell(),
12667    tabStripActualWidth = stripSize + leftIndentSize + rightIndentSize;
12668   if(this.enableScrolling)
12669    tabStripActualWidth += this.scrollingFillerElementWidth;
12670   tabStripActualWidth = this.GetPreparedSizeValue(tabStripActualWidth, true);
12671   tabStrip.style.width = tabStripActualWidth + "px";
12672   if(this.IsMultiRow()) {
12673    var tabsHolder = this.getTabsHolderElement();
12674    tabsHolder.style.width = stripSize + "px";
12675   }
12676  },
12677  GetPreparedSizeValue: function(sizeValue, reserve) {
12678   if(!(ASPx.Browser.Chrome && ASPx.Browser.MajorVersion >= 45))
12679    return sizeValue;
12680   if(ASPx.Browser.Chrome)
12681    return +(Math.ceil(sizeValue + "e+2") + "e-2");
12682   if(ASPx.Browser.MajorVersion == 10 && reserve)
12683    return sizeValue + 0.1;
12684   var res = Math.floor(sizeValue);
12685   while(res < sizeValue)
12686    res += 0.1;
12687   return res;
12688  },
12689  SetCachedElementSize: function(element, size, dimension) {
12690   this.SetCachedElementSizeCore(element, size, dimension, "SetCachedElement");
12691  },
12692  SetCachedElementSizeCore: function(element, size, dimension, funcNamePrefix) {
12693   if(!element) return;
12694   if(!dimension)
12695    dimension = this.primaryDimension;
12696   var funcName = funcNamePrefix + (dimension == "width" ? "Width" : "Height");
12697   this[funcName](element, size);
12698  },
12699  SetCachedElementWidth: function(element, width) {
12700   var cache = this.GetOrCreateElementCache(element);
12701   this.SetElementSize(element, width, cache.horizontalBordersPaddingsMarginsWidth, "width");
12702  },
12703  SetCachedElementHeight: function(element, height) {
12704   var cache = this.GetOrCreateElementCache(element);
12705   this.SetElementSize(element, height, cache.verticalBordersPaddingsMarginsWidth, "height");
12706  },
12707  SetCachedElementOffsetSize: function(element, size, dimension) {
12708   this.SetCachedElementSizeCore(element, size, dimension, "SetCachedElementOffset");
12709  },
12710  SetCachedElementOffsetWidth: function(element, width) {
12711   var cache = this.GetOrCreateElementCache(element);
12712   this.SetElementSize(element, width, cache.horizontalBordersAndPaddingsWidth, "width");
12713  },
12714  SetCachedElementOffsetHeight: function(element, height) {
12715   var cache = this.GetOrCreateElementCache(element);
12716   this.SetElementSize(element, height, cache.verticalBordersAndPaddingsWidth, "height");
12717  },
12718  SetElementSize: function(element, value, correction, dimension) {
12719   value -= correction;
12720   if(value >= 0)
12721    element.style[dimension] = value + "px";
12722  },
12723  GetLeftIndentLite: function () {
12724   var container = this.GetTabStripContainer();
12725   return container
12726    ? ASPx.GetNodesByPartialClassName(container, Constants.CssClassName.LEFT_INDENT)[0]
12727    : null;
12728  },
12729  GetRightIndentLite: function () {
12730   var container = this.GetTabStripContainer();
12731   return container
12732    ? ASPx.GetNodesByPartialClassName(container, Constants.CssClassName.RIGHT_INDENT)[0]
12733    : null;
12734  },
12735  GetTabsCellID: function () {
12736   return "_TC";
12737  },
12738  GetTabsCell: function () {
12739   return this.GetChildElement(this.GetTabsCellID());
12740  },
12741  GetTabsCellWrapperID: function () {
12742   return "_WC";
12743  },
12744  GetTabsCellWrapperElement: function () {
12745   return this.GetChildElement(this.GetTabsCellWrapperID());
12746  },
12747  GetTabStripContainer: function () {
12748   return this.enableScrolling ? this.GetTabsCellWrapperElement() : this.GetTabsCell();
12749  },
12750  GetTabElementID: function (index, active) {
12751   return "_" + (active ? "A" : "") + "T" + index;
12752  },
12753  GetTabElement: function (index, active) {
12754   return this.GetChildElement(this.GetTabElementID(index, active));
12755  },
12756  GetTabsElements: function() {
12757   var tabsCell = this.GetTabsCell();
12758   if(!tabsCell)
12759    return [];
12760   var getNodesFunc = this.IsMultiRow() ? ASPx.GetNodes : ASPx.GetChildNodes;
12761   return getNodesFunc(tabsCell, function(el) {
12762    return el.tagName === "LI" && el.className && this.isTabElement(el);
12763   }.aspxBind(this));
12764  },
12765  GetTabInsideElement: function (index, isActive, insideClassName) {
12766   var tabElement = this.GetTabElement(index, isActive);
12767   if(!tabElement)
12768    return null;
12769   var c = ASPx.GetNodesByClassName(tabElement, insideClassName);
12770   return null || (c.length > 0 && c[0]);
12771  },
12772  GetTabLinkElement: function (index, active) {
12773   return this.GetTabInsideElement(index, active, Constants.CssClassName.TAB_LINK);
12774  },
12775  GetTabTextElement: function (index, active) {
12776   return this.GetTabLinkElement(index, active);
12777  },
12778  GetTabImageElement: function (index, active) {
12779   return this.GetTabInsideElement(index, active, Constants.CssClassName.TAB_IMAGE);
12780  },
12781  GetVisibleTabElement: function (index) {
12782   return this.GetChildElement(this.GetTabElementID(index, index == this.activeTabIndex));
12783  },
12784  GetContentsCellID: function () {
12785   return "_CC";
12786  },
12787  GetContentsCell: function () {
12788   return this.GetChildElement(this.GetContentsCellID());
12789  },
12790  GetContentElementID: function (index) {
12791   return "_C" + index;
12792  },
12793  GetContentElement: function (index) {
12794   return this.GetChildElement(this.GetContentElementID(index));
12795  },
12796  getActiveContentElement: function() {
12797   return this.GetContentElement(this.activeTabIndex);
12798  },
12799  GetContentHolder: function (index) {
12800   var contentElement = this.GetContentElement(index);
12801   if(!contentElement)
12802    return null;
12803   return ASPx.GetChildByTagName(contentElement, "DIV");
12804  },
12805  getActiveContentHolder: function() {
12806   return this.GetContentHolder(this.activeTabIndex);
12807  },
12808  GetSeparatorElementID: function (index) {
12809   return "_T" + index + "S";
12810  },
12811  GetSeparatorElement: function (index) {
12812   return this.GetChildElement(this.GetSeparatorElementID(index));
12813  },
12814  GetScrollVisibleAreaID: function () {
12815   return "_SVA";
12816  },
12817  GetScrollVisibleArea: function () {
12818   return this.GetChildElement(this.GetScrollVisibleAreaID());
12819  },
12820  GetScrollableArea: function () {
12821   return this.GetTabsCell();
12822  },
12823  GetScrollLeftButtonID: function () {
12824   return "_SBL";
12825  },
12826  GetScrollLeftButtonElement: function () {
12827   return this.GetChildElement(this.GetScrollLeftButtonID());
12828  },
12829  GetScrollLeftButtonContainer: function () {
12830   return this.GetScrollLeftButtonElement().parentNode;
12831  },
12832  GetScrollRightButtonID: function () {
12833   return "_SBR";
12834  },
12835  GetScrollRightButtonElement: function () {
12836   return this.GetChildElement(this.GetScrollRightButtonID());
12837  },
12838  GetScrollRightButtonContainer: function () {
12839   return this.GetScrollRightButtonElement().parentNode;
12840  },
12841  IsTopBottomTabPosition: function () {
12842   return (this.tabPosition == "Top" || this.tabPosition == "Bottom");
12843  },
12844  getAreAllTabsHidden: function() {
12845   return this.GetNextVisibleTabIndex(-1) === -1;
12846  },
12847  isInsideVisibleContainer: function() {
12848   return this.IsDisplayed() && !this.IsHidden();
12849  },
12850  IsControlVisible: function() {
12851   return this.clientVisible && !this.getAreAllTabsHidden() && this.isInsideVisibleContainer();
12852  },
12853  isTabElement: function(element) {
12854   return ASPx.ElementHasCssClass(element, Constants.CssClassName.TAB)
12855    || ASPx.ElementHasCssClass(element, Constants.CssClassName.ACTIVE_TAB);
12856  },
12857  isTemplateIndentElement: function(element) {
12858   return ASPx.ElementHasCssClass(element, Constants.CssClassName.INDENT_TEMPLATE);
12859  },
12860  isTabElementStartsNewLine: function(element) {
12861   return ASPx.ElementHasCssClass(element, Constants.CssClassName.NEW_LINE_START_TAB);
12862  },
12863  previousInvisibleTabExist: function(index, element){
12864   var parentElement = element.parentNode;
12865   if(parentElement.firstChild == element)
12866    return false;
12867   while(index--) {
12868    var tabElement = this.GetVisibleTabElement(index);
12869    if(tabElement && tabElement.parentNode == parentElement)
12870     return true;
12871   }
12872   return false;
12873  },
12874  FixControlSize: function () {
12875   this.FixElementSize(this.GetMainElement());
12876   var contentCell = this.GetContentsCell();
12877   if(!contentCell) return;
12878   var width = contentCell.offsetWidth;
12879   var height = contentCell.offsetHeight;
12880   width -= this.GetCachedHorizontalBordersAndPaddingsWidth(contentCell);
12881   height -= this.GetCachedVerticalBordersAndPaddingsWidth(contentCell);
12882   ASPx.Attr.ChangeStyleAttribute(contentCell, "width", width + "px");
12883   ASPx.Attr.ChangeStyleAttribute(contentCell, "height", height + "px");
12884  },
12885  UnfixControlSize: function () {
12886   this.UnfixElementSize(this.GetMainElement());
12887   this.UnfixElementSize(this.GetContentsCell());
12888  },
12889  FixElementSize: function (element) {
12890   if(element == null) return;
12891   var width = element.offsetWidth;
12892   var height = element.offsetHeight;
12893   ASPx.Attr.ChangeStyleAttribute(element, "width", width + "px");
12894   ASPx.Attr.ChangeStyleAttribute(element, "height", height + "px");
12895  },
12896  UnfixElementSize: function (element) {
12897   if(element == null) return;
12898   ASPx.Attr.RestoreStyleAttribute(element, "width");
12899   ASPx.Attr.RestoreStyleAttribute(element, "height");
12900  },
12901  AdjustSize: function () {
12902   this.adjustControlInternal();
12903  },
12904  adjustControlInternal: function() {
12905   this.AdjustControlCore();
12906   var cache = this.adjustmentVars.mainElementCache;
12907   var width = Math.ceil(cache.offsetWidth);
12908   var height = Math.ceil(cache.offsetHeight);
12909   this.adjustedSizes = { width: width, height: height };
12910  },
12911  AdjustControlCore: function () {
12912   ASPxClientControl.prototype.AdjustControlCore.call(this);
12913   this.EnsureControlInitialized();
12914   this.SetObservationPaused(true);
12915   this.UpdateLayout();
12916   this.ProcessDeferredActions();
12917   this.SetObservationPaused(false);
12918  },
12919  ProcessDeferredActions: function() {
12920   while(this.deferredActions.length > 0) {
12921    var action = this.deferredActions[0];
12922    try {
12923     this.SetTabVisibleCore(action.tabIndex, action.setVisible);
12924    }
12925    finally {
12926     ASPx.Data.ArrayRemoveAt(this.deferredActions, 0);
12927    }
12928   }
12929  },
12930  IsAdjustmentRequired: function() {
12931   if(this.deferredActions.length > 0)
12932    return true;
12933   return ASPxClientControl.prototype.IsAdjustmentRequired.call(this);
12934  },
12935  UpdateLayout: function () {
12936   if(!this.enableScrolling)
12937    this.AdjustTabControlSizeLite();
12938   else
12939    this.AdjustTabScrolling(this.scrollToActiveTab, false);
12940   this.AdjustTabContents();
12941  },
12942  AdjustAutoHeight: function () {
12943   if(!this.IsAdjustmentAllowed())
12944    return;
12945   this.EnsureControlInitialized();
12946   this.UpdateAutoHeight();
12947  },
12948  UpdateAutoHeight: function () {
12949   this.AdjustPageContents();
12950  },
12951  SetWidth: function(width) {
12952   var success = this.SetSizeInternal(width, "width");
12953   if(success && this.emptyWidth)
12954    this.emptyWidth = false;
12955  },
12956  SetHeight: function(height) {
12957   var success = this.SetSizeInternal(height, "height");
12958   if(success && this.emptyHeight)
12959    this.emptyHeight = false;
12960  },
12961  SetSizeInternal: function(value, dimension) {
12962   if(value < 0)
12963    return false;
12964   var mainElement = this.GetMainElement();
12965   var offsetSize = this.GetCachedElementInnerSize(mainElement, dimension) 
12966    + this.GetCachedBordersAndPaddingsWidth(mainElement, dimension);
12967   if(offsetSize === value)
12968    return false;
12969   this.SetCachedElementOffsetSize(mainElement, value, dimension);
12970   this.ClearElementCache(mainElement);
12971   this.ResetControlAdjustment();
12972   this.UpdateAdjustmentFlags();
12973   this.AdjustControl(true);
12974   return true;
12975  },
12976  CanLoadTabOnCallback: function (index) {
12977   return this.isLoadTabByCallback && ASPx.IsFunction(this.callBack);
12978  },
12979  finalizeChangeTabState: function () {},
12980  ChangeTabState: function (index, active) {
12981   var element = this.GetTabElement(index, true);
12982   if(element != null) this.SetElementDisplay(element, active);
12983   element = this.GetTabElement(index, false);
12984   if(element != null) this.SetElementDisplay(element, !active);
12985   element = this.GetContentElement(index);
12986   if(element != null) this.setContentDisplay(element, active);
12987   this.tabHeightManager.requestAdjustment();
12988  },
12989  setContentDisplay: function (element, active) {
12990   this.SetElementDisplay(element, active);
12991  },
12992  ChangeActiveTab: function (index, hasLink) {
12993   this.SetObservationPaused(true);
12994   var processingMode = this.RaiseActiveTabChanging(index);
12995   if(processingMode == "Client" || processingMode == "ClientWithReload") {
12996    var element = this.GetContentElement(index);
12997    if(this.CanLoadTabOnCallback(index) && element != null && (!element.loaded || processingMode == "ClientWithReload")) {
12998     if(this.callbackCount == 0)
12999      this.FixControlSize();
13000     this.DoChangeActiveTab(index);
13001     this.isActiveTabChanged = true;
13002     this.PerformCallbackInternal(index, element);
13003    }
13004    else {
13005     this.DoChangeActiveTab(index);
13006     if(this.GetMainElement()) {
13007      var activeContentElement = this.getActiveContentElement();
13008      if(activeContentElement) {
13009       window.setTimeout(function() {
13010        this.onActiveTabChangedTimeout(activeContentElement);
13011       }.aspxBind(this), 0);
13012      }
13013     }
13014     this.RaiseActiveTabChanged(index);
13015    }
13016   }
13017   else if(processingMode == "Server" && !hasLink)
13018    this.SendPostBack("ACTIVATE:" + index);
13019   this.SetObservationPaused(false);
13020  },
13021  onActiveTabChangedTimeout: function(activeContentElement) {
13022   this.DoSafeScrollPositionOperation(function() {
13023    this.onActiveTabChangedTimeoutCore(activeContentElement);
13024   }.aspxBind(this));
13025  },
13026  onActiveTabChangedTimeoutCore: function(activeContentElement) {
13027   this.SetObservationPaused(true);
13028   activeContentElement.style.position = "fixed";
13029   this.layoutManager.calculateSizes();
13030   activeContentElement.style.position = "";
13031   this.AdjustPageContents();
13032   ASPx.GetControlCollection().AdjustControlsCore(activeContentElement, true);
13033   this.adjustControlInternal();
13034   this.SetObservationPaused(false);
13035  },
13036  PerformCallbackInternal: function (tabIndex, tabContentElement, callbackArgument, handler) {
13037   if(typeof (callbackArgument) == "undefined")
13038    callbackArgument = tabIndex;
13039   if(!tabContentElement.loading) {
13040    this.callbackCount++;
13041    tabContentElement.loading = true;
13042    this.tabsContentRequest.push(tabIndex);
13043    this.ShowLoadingPanelInTabPage(tabIndex);
13044    this.CreateCallback(callbackArgument, null, handler);
13045   }
13046  },
13047  IsMultiRow: function () {
13048   if(!ASPx.IsExists(this.isMultiRow))
13049    this.isMultiRow = ASPx.ElementHasCssClass(this.GetMainElement(), Constants.CssClassName.MULTIROW);
13050   return this.isMultiRow;
13051  },
13052  UseProportionalTabSizes: function () {
13053   return this.IsMultiRow() || this.tabAlign == "Justify";
13054  },
13055  PlaceActiveTabRowToBottom: function(activeTabIndex) {
13056   var activeTabElement = this.GetVisibleTabElement(activeTabIndex);
13057   if(!activeTabElement) return;
13058   var newActiveRow = this.getTabRowByTabElement(activeTabElement);
13059   var currentActiveRow = this.getActiveTabRow();
13060   if(newActiveRow != currentActiveRow) {
13061    var tabsHolderElement = this.getTabsHolderElement();
13062    tabsHolderElement.insertBefore(currentActiveRow, newActiveRow);
13063    var refElement = this.tabPosition == "Top" ? null : tabsHolderElement.firstChild;
13064    tabsHolderElement.insertBefore(newActiveRow, refElement);
13065   }
13066   this.adjustTabRowsSpacing();
13067   this.replaceCssClassForChildren(currentActiveRow, Constants.CssClassName.ACTIVE_ROW_ITEM, "");
13068   this.replaceCssClassForChildren(newActiveRow, "", Constants.CssClassName.ACTIVE_ROW_ITEM);
13069  },
13070  getTabRowByTabElement: function(tabElement) {
13071   return tabElement.parentNode;
13072  },
13073  getTabsHolderElement: function() {
13074   var stripElement = this.GetTabsCell();
13075   return ASPx.GetChildByClassName(stripElement, Constants.CssClassName.TABS_HOLDER, 0);
13076  },
13077  getTabRows: function() {
13078   var tabsHolderElement = this.getTabsHolderElement();
13079   return ASPx.GetChildNodesByClassName(tabsHolderElement, Constants.CssClassName.TAB_ROW);
13080  },
13081  getActiveTabRow: function() {
13082   var tabRows = this.getTabRows();
13083   var rowIndex = this.getActiveTabRowIndex(tabRows);
13084   return tabRows[rowIndex];
13085  },
13086  getActiveTabRowIndex: function(tabRows) {
13087   return this.getActiveTabRowIndexCore(tabRows.length);
13088  },
13089  getActiveTabRowIndexCore: function(rowCount) {
13090   return this.tabPosition == "Top" ? rowCount - 1 : 0;
13091  },
13092  replaceCssClassForChildren: function(parentElement, className, newClassName) {
13093   var children = ASPx.GetChildElementNodes(parentElement);
13094   this.ReplaceCssClassLite(children, className, newClassName);
13095  },
13096  adjustTabRowsSpacing: function() {
13097   var tabSpace = this.GetTabSpaceSizeLite(); 
13098   var tabRows = this.getTabRows();
13099   var activeRowIndex = this.getActiveTabRowIndex(tabRows);
13100   var propName = "padding" + (this.tabPosition == "Top" ? "Bottom" : "Top");
13101   var paddingValue = tabSpace + "px";
13102   var nullPaddingValue = "0";
13103   for(var i = 0; i < tabRows.length; i++) {
13104    var tabRow = tabRows[i];
13105    var value = i == activeRowIndex ? nullPaddingValue : paddingValue;
13106    tabRow.style[propName] = value;
13107   }
13108  },
13109  ReplaceCssClassLite: function (collection, className, newClassName) {
13110   for(var i = 0; i < collection.length; i++) {
13111    if(!collection[i]) continue;
13112    var c = collection[i].className.replace(className, "");
13113    collection[i].className = ASPx.Str.Trim(c);
13114    if(newClassName != "")
13115     collection[i].className += " " + newClassName;
13116   }
13117  },
13118  needInvertedChange: function () {
13119   return ASPx.Browser.Firefox && ASPx.Browser.Version >= 3;
13120  },
13121  DoChangeActiveTab: function (index) {
13122   if(this.needInvertedChange()) { 
13123    var contentsCell = this.GetContentsCell();
13124    var isContentsCellExists = ASPx.IsExistsElement(contentsCell);
13125    if(isContentsCellExists)
13126     ASPx.SetElementVisibility(contentsCell, false);
13127    this.ChangeTabState(index, true);
13128    this.ChangeTabState(this.activeTabIndex, false);
13129    this.activeTabIndex = index;
13130    if(isContentsCellExists)
13131     ASPx.SetElementVisibility(contentsCell, true);
13132   } else {
13133    this.ChangeTabState(this.activeTabIndex, false);
13134    this.activeTabIndex = index;
13135    this.ChangeTabState(this.activeTabIndex, true);
13136   }
13137   this.finalizeChangeTabState();
13138   if(this.enableScrolling)
13139    this.AdjustTabScrolling(this.scrollToActiveTab, true);
13140   else
13141    this.AdjustTabControlSizeLite();
13142   if(this.IsMultiRow())
13143    this.PlaceActiveTabRowToBottom(index);
13144   this.AdjustTabContents();
13145   this.UpdateActiveTabIndexCookie();
13146   this.focusActiveTab();
13147  },
13148  focusActiveTab: function() {
13149   if(this.accessibilityCompliant && (!this.scrollManager || !this.scrollManager.IsInProgress())) {
13150    var linkEl = this.GetTabLinkElement(this.activeTabIndex, true);
13151    if(linkEl)
13152     linkEl.focus();
13153   }
13154  },
13155  SetActiveTabIndexInternal: function (index, hasLink) {
13156   if(this.activeTabIndex == index) return;
13157   this.DoSafeScrollPositionOperation(function () {
13158    this.ChangeActiveTab(index, hasLink);
13159   }.aspxBind(this));
13160   this.UpdateHoverState(index);
13161  },
13162  SwitchActiveTab: function(toNext) {
13163   var index = this.GetActiveTabIndex();
13164   if(toNext) index++;
13165   else index--;
13166   for (var i = index, tab; tab = this.tabs[i]; toNext ? i++ : i--) {
13167    if(tab.GetVisible()) {
13168     this.SetActiveTab(tab);
13169     return;
13170    }
13171   }
13172  },
13173  UpdateActiveTabIndexCookie: function () {
13174   if(this.cookieName == "") return;
13175   ASPx.Cookie.DelCookie(this.cookieName);
13176   ASPx.Cookie.SetCookie(this.cookieName, this.activeTabIndex);
13177  },
13178  UpdateHoverState: function (index) {
13179   if(!this.IsStateControllerEnabled()) return;
13180   var element = this.GetTabElement(index, true);
13181   if(element != null) ASPx.GetStateController().SetCurrentHoverElementBySrcElement(element);
13182  },
13183  OnTabClick: function (evt, index) {
13184   var processingMode = this.RaiseTabClick(index, evt);
13185   var clickedLinkElement = ASPx.GetParentByTagName(ASPx.Evt.GetEventSource(evt), "A");
13186   var isLinkClicked = (clickedLinkElement != null && !!clickedLinkElement.href && clickedLinkElement.href != ASPx.AccessibilityEmptyUrl);
13187   var element = this.GetTabElement(index, false);
13188   var linkElement = (element != null) ? ASPx.GetNodeByTagName(element, "A", 0) : null;
13189   if(linkElement != null && (!linkElement.href || linkElement.href == ASPx.AccessibilityEmptyUrl))
13190    linkElement = null;
13191   if(processingMode != "Handled") {
13192    var hasLink = isLinkClicked || linkElement != null;
13193    if(processingMode == "Server" && !hasLink)
13194     this.SendPostBack("CLICK:" + index);
13195    else {
13196     var clickWithHoldCtrlOnLink = hasLink && evt.ctrlKey;
13197     if(!clickWithHoldCtrlOnLink)
13198      this.SetActiveTabIndexInternal(index, hasLink);
13199    }
13200    var isMouseDownAction = this.tabAction == Constants.TabAction.MOUSE_DOWN;
13201    if(this.handleClickOnWholeTab && (!isLinkClicked || isMouseDownAction) && linkElement != null)
13202     ASPx.Url.NavigateByLink(linkElement);
13203   }
13204  },
13205  OnCallback: function (result) {
13206   this.OnCallbackInternal(result.html, result.index, false);
13207  },
13208  OnCallbackError: function (result, data) {
13209   this.OnCallbackInternal(result, data, true);
13210  },
13211  OnCallbackInternal: function (html, index, isError) {
13212   this.SetCallbackContent(html, index, isError);
13213   ASPx.Data.ArrayRemoveAt(this.tabsContentRequest, 0);
13214   if(!isError && this.isActiveTabChanged) {
13215    this.isActiveTabChanged = false;
13216    this.shouldRaiseActiveTabChangedEvent = true;
13217   }
13218   if(this.enableCallbackAnimation)
13219    ASPx.AnimationHelper.fadeIn(this.GetContentElement(index), function () { this.OnCallbackFinish(index); }.aspxBind(this));
13220  },
13221  OnCallbackFinish: function (index) {
13222   this.adjustControlInternal();
13223   if(this.shouldRaiseActiveTabChangedEvent) {
13224    this.shouldRaiseActiveTabChangedEvent = false;
13225    if(!ASPx.IsExists(index))
13226     index = this.GetActiveTabIndex();
13227    this.RaiseActiveTabChanged(index);
13228   }
13229  },
13230  OnCallbackFinalized: function () {
13231   if(!this.enableCallbackAnimation)
13232    this.OnCallbackFinish();
13233  },
13234  OnCallbackGeneralError: function (result) {
13235   var callbackTabIndex = (this.tabsContentRequest.length > 0) ? this.tabsContentRequest[0] : this.activeTabIndex;
13236   this.SetCallbackContent(result, callbackTabIndex, true);
13237   ASPx.Data.ArrayRemoveAt(this.tabsContentRequest, 0);
13238  },
13239  ShowLoadingPanelInTabPage: function (index) {
13240   if(this.lpDelay > 0)
13241    window.setTimeout(function () { this.ShowLoadingPanelInTabPageCore(index); }.aspxBind(this), this.lpDelay);
13242   else
13243    this.ShowLoadingPanelInTabPageCore(index);
13244  },
13245  ShowLoadingPanelInTabPageCore: function (index) {
13246   if(ASPx.Data.ArrayIndexOf(this.tabsContentRequest, index) < 0) return;
13247   var element = this.GetContentHolder(index);
13248   var hasContent = !!ASPx.Str.Trim(this.GetTabContentHTML(this.GetTab(index)));
13249   var loadingPanelElement = this.CreateLoadingPanelWithAbsolutePosition(element, this.GetContentsCell());
13250   if(!hasContent && loadingPanelElement)
13251    ASPx.AddClassNameToElement(loadingPanelElement, "dxlp-withoutBorders");
13252  },
13253  ShouldHideExistingLoadingElements: function () {
13254   return false;
13255  },
13256  SetCallbackContent: function (html, index, isError) {
13257   this.SetObservationPaused(true);
13258   var element = this.GetContentElement(index);
13259   if(element != null) {
13260    if(!isError)
13261     element.loaded = true;
13262    element.loading = false;
13263    ASPx.SetInnerHtml(this.GetContentHolder(index), html);
13264    this.callbackCount--;
13265    if(this.callbackCount == 0)
13266     this.UnfixControlSize();
13267   }
13268   this.SetObservationPaused(false);
13269  },
13270  GetClientTabType: function() {
13271   return ASPxClientTab;
13272  },
13273  CreateTabs: function (tabsProperties) {
13274   var tabType = this.GetClientTabType();
13275   for(var i = 0; i < tabsProperties.length; i++) {
13276    var tabName = tabsProperties[i][0] || "";
13277    var tab = new tabType(this, i, tabName);
13278    this.CreateTabProperties(tab, tabsProperties[i]);
13279    this.tabs.push(tab);
13280   }
13281  },
13282  CreateTabProperties: function (tab, tabProperties) {
13283   if(ASPx.IsExists(tabProperties[1]))
13284    tab.enabled = tabProperties[1];
13285   if(ASPx.IsExists(tabProperties[2]))
13286    tab.clientEnabled = tabProperties[2];
13287   if(ASPx.IsExists(tabProperties[3]))
13288    tab.visible = tabProperties[3];
13289   if(ASPx.IsExists(tabProperties[4]))
13290    tab.clientVisible = tabProperties[4];
13291   if(ASPx.IsExists(tabProperties[5]))
13292    tab.newLine = tabProperties[5];
13293  },
13294  CreateTabClickEventArgs: function(processOnServer, tab, htmlElement, htmlEvent) {
13295   return new ASPxClientTabControlTabClickEventArgs(processOnServer, tab, htmlElement, htmlEvent);
13296  },
13297  CreateTabEventArgs: function(tab) {
13298   return new ASPxClientTabControlTabEventArgs(tab);
13299  },
13300  CreateTabCancelEventArgs: function(processOnServer, tab) {
13301   return new ASPxClientTabControlTabCancelEventArgs(processOnServer, tab);
13302  },
13303  RaiseTabClick: function (index, htmlEvent) {
13304   var processingMode = this.autoPostBack || this.IsServerEventAssigned("TabClick") ? "Server" : "Client";
13305   if(!this.TabClick.IsEmpty()) {
13306    var htmlElement = this.GetTabElement(index, this.activeTabIndex == index);
13307    var args = this.CreateTabClickEventArgs(processingMode == "Server", this.GetTab(index), htmlElement, htmlEvent);
13308    this.TabClick.FireEvent(this, args);
13309    if(args.cancel)
13310     processingMode = "Handled";
13311    else
13312     processingMode = args.processOnServer ? "Server" : "Client";
13313   }
13314   return processingMode;
13315  },
13316  RaiseActiveTabChanged: function (index) {
13317   if(!this.ActiveTabChanged.IsEmpty()) {
13318    var args = this.CreateTabEventArgs(this.GetTab(index));
13319    this.ActiveTabChanged.FireEvent(this, args);
13320   }
13321  },
13322  RaiseActiveTabChanging: function (index) {
13323   var processingMode = this.autoPostBack ? "Server" : "Client";
13324   if(!this.ActiveTabChanging.IsEmpty()) {
13325    var args = this.CreateTabCancelEventArgs(processingMode == "Server", this.GetTab(index));
13326    this.ActiveTabChanging.FireEvent(this, args);
13327    if(args.cancel || (processingMode === "Server" && !args.processOnServer))
13328     processingMode = "Handled";
13329    else if(args.processOnServer)
13330     processingMode = "Server";
13331    else
13332     processingMode = args.reloadContentOnCallback ? "ClientWithReload" : "Client";
13333   }
13334   return processingMode;
13335  },
13336  SetEnabled: function (enabled) {
13337   for(var i = this.GetTabCount() - 1; i >= 0; i--) {
13338    var tab = this.GetTab(i);
13339    tab.SetEnabled(enabled, true );
13340   }
13341  },
13342  GetActiveTab: function () {
13343   return (this.activeTabIndex > -1) ? this.GetTab(this.activeTabIndex) : null;
13344  },
13345  SetActiveTab: function (tab) {
13346   if(this.IsTabVisible(tab.index))
13347    this.SetActiveTabIndexInternal(tab.index, false);
13348  },
13349  GetActiveTabIndex: function () {
13350   return this.activeTabIndex;
13351  },
13352  SetActiveTabIndex: function (index) {
13353   if(index < 0 || index >= this.tabs.length) return;
13354   if(this.IsTabVisible(index))
13355    this.SetActiveTabIndexInternal(index, false);
13356  },
13357  GetTabCount: function () {
13358   return this.tabs.length;
13359  },
13360  GetTab: function (index) {
13361   return (0 <= index && index < this.tabs.length) ? this.tabs[index] : null;
13362  },
13363  GetTabByName: function (name) {
13364   for(var i = 0; i < this.tabs.length; i++)
13365    if(this.tabs[i].name == name) return this.tabs[i];
13366   return null;
13367  },
13368  IsTabEnabled: function (index) {
13369   return this.tabs[index].GetEnabled();
13370  },
13371  SetTabEnabled: function (index, enabled, initialization, doNotChangeActiveTab) {
13372   if(!this.tabs[index].enabled) return;
13373   this.ClearTabElementsCache(index);
13374   if(!initialization || !enabled)
13375    this.ChangeTabEnabledStateItems(index, enabled);
13376   this.ChangeTabEnabledAttributes(index, enabled, doNotChangeActiveTab);
13377   if(!initialization && this.canUseOffsetSizes())
13378    this.adjustControlInternal();
13379  },
13380  ChangeTabEnabledAttributes: function (index, enabled, doNotChangeActiveTab) {
13381   if(enabled) {
13382    this.ChangeTabElementsEnabledAttributes(index, enabled, ASPx.Attr.RestoreAttribute, ASPx.Attr.RestoreStyleAttribute);
13383    var isActiveTabEnabled = this.activeTabIndex != -1 ? this.IsTabEnabled(this.activeTabIndex) : false;
13384    if(!doNotChangeActiveTab && !isActiveTabEnabled && this.IsTabVisible(index))
13385     this.SetActiveTabIndexInternal(index, false);
13386   }
13387   else {
13388    if(this.activeTabIndex == index && !doNotChangeActiveTab) {
13389     for(var i = 0; i < this.GetTabCount() ; i++) {
13390      if(this.IsTabVisible(i) && this.IsTabEnabled(i) && i != index) {
13391       this.SetActiveTabIndexInternal(i, false);
13392       break;
13393      }
13394     }
13395    }
13396    this.ChangeTabElementsEnabledAttributes(index, enabled, ASPx.Attr.ResetAttribute, ASPx.Attr.ResetStyleAttribute);
13397   }
13398  },
13399  ChangeTabElementsEnabledAttributes: function (index, enabled, method, styleMethod) {
13400   var eventName = this.getTabActivationHtmlEventName();
13401   var element = this.GetTabElement(index, false);
13402   if(element) {
13403    element.clientDisabled = !enabled;
13404    method(element, eventName);
13405    styleMethod(element, "cursor");
13406    var link = this.GetInternalHyperlinkElement(element, 0);
13407    if(link != null)
13408     this.ChangeTabLinkEnabledAttributes(link, enabled, method, styleMethod);
13409    link = this.GetInternalHyperlinkElement(element, 1);
13410    if(link != null) 
13411     this.ChangeTabLinkEnabledAttributes(link, enabled, method, styleMethod);
13412   }
13413   var activeElement = this.GetTabElement(index, true);
13414   if(activeElement) {
13415    method(activeElement, eventName);
13416    styleMethod(activeElement, "cursor");
13417   }
13418  },
13419  ChangeTabLinkEnabledAttributes: function (link, enabled, method, styleMethod) {
13420   method(link, "href");
13421   styleMethod(link, "cursor");
13422  },
13423  getTabActivationHtmlEventName: function() {
13424   switch(this.tabAction) {
13425    case Constants.TabAction.CLICK:
13426     return "onclick";
13427    case Constants.TabAction.MOUSE_OVER:
13428     return "onmouseover";
13429    case Constants.TabAction.MOUSE_DOWN:
13430     return ASPx.Browser.WebKitTouchUI ? "ontouchstart" : "onmousedown";
13431   }
13432   throw "This mode is not supported";
13433  },
13434  ChangeTabEnabledStateItems: function (index, enabled) {
13435   if(!this.IsStateControllerEnabled()) return;
13436   var element = this.GetTabElement(index, false);
13437   if(element != null) ASPx.GetStateController().SetElementEnabled(element, enabled);
13438   var activeElement = this.GetTabElement(index, true);
13439   if(activeElement != null) ASPx.GetStateController().SetElementEnabled(activeElement, enabled);
13440  },
13441  GetTabImageUrl: function (index, active) {
13442   var imgEl = this.GetTabImageElement(index, active);
13443   return imgEl ? imgEl.src : "";
13444  },
13445  SetTabImageUrl: function (index, active, url) {
13446   var imgEl = this.GetTabImageElement(index, active);
13447   if(imgEl) {
13448    imgEl.src = url;
13449    var tabEl = this.GetTabElement(index, active);
13450    this.ClearElementCache(tabEl);
13451    this.tabHeightManager.requestAdjustment();
13452    this.adjustControlInternal();
13453   }
13454  },
13455  GetTabNavigateUrl: function (index) {
13456   var linkEl = this.GetTabLinkElement(index, false);
13457   return linkEl ? (linkEl.href || ASPx.Attr.GetAttribute(linkEl, "savedhref")) : "";
13458  },
13459  SetTabNavigateUrl: function (index, url) {
13460   var linkEl = this.GetTabLinkElement(index, false);
13461   if(linkEl) {
13462    if(ASPx.Attr.IsExistsAttribute(linkEl, "savedhref"))
13463     ASPx.Attr.SetAttribute(linkEl, "savedhref", url);
13464    else if(ASPx.Attr.IsExistsAttribute(linkEl, "href"))
13465     linkEl.href = url;
13466   }
13467  },
13468  GetTabText: function (index) {
13469   var isActive = index == this.GetActiveTabIndex();
13470   var element = this.GetTabTextElement(index, isActive);
13471   if(element) {
13472    var textNode = ASPx.GetNormalizedTextNode(element);
13473    if(textNode != null)
13474     return ASPx.Str.Trim(textNode.nodeValue);
13475   }
13476   return "";
13477  },
13478  SetTabText: function (index, text) {
13479   this.SetTabTextInternal(index, false, text);
13480   this.SetTabTextInternal(index, true, text);
13481   this.ClearTabElementsCache(index);
13482   this.adjustControlInternal();
13483  },
13484  SetTabTextInternal: function (index, isActive, text) {
13485   var element = this.GetTabTextElement(index, isActive);
13486   if(element != null) {
13487    var textNode = ASPx.GetNormalizedTextNode(element);
13488    if(!textNode) {
13489     textNode = document.createTextNode("");
13490     element.appendChild(textNode);
13491    }
13492    textNode.nodeValue = text;
13493   }
13494  },
13495  IsTabVisible: function (index) {
13496   return this.tabs[index].GetVisible();
13497  },
13498  IsTabStartOutOfScrollArea: function (index) {
13499   var width = 0;
13500   for(var i = 0; i < index; i++) {
13501    width += this.GetVisibleTabElement(index).offsetWidth;
13502    var separator = this.GetSeparatorElement(index);
13503    if(separator)
13504     width += separator.offsetWidth;
13505   }
13506   return Math.abs(this.scrollManager.GetScrolledAreaPosition()) > width;
13507  },
13508  SetTabVisible: function(index, visible) {
13509   var needResetDisplay = this.clientVisible && this.getAreAllTabsHidden();
13510   var mainElement;
13511   if(needResetDisplay) {
13512    mainElement = this.GetMainElement();
13513    mainElement.style.display = "";
13514   }
13515   var controlVisible = this.clientVisible && this.isInsideVisibleContainer();
13516   if(needResetDisplay && (!controlVisible || this.isFullyInitialized))
13517    mainElement.style.display = "none";
13518   this.tabs[index].clientVisible = visible;
13519   if(controlVisible) {
13520    this.EnsureControlInitialized();
13521    this.SetTabVisibleCore(index, visible);
13522   }
13523   else {
13524    var action = { 
13525     tabIndex: index,
13526     setVisible: visible
13527    };
13528    this.deferredActions.push(action);
13529    if(needResetDisplay && visible)
13530     mainElement.style.display = "";
13531   }
13532  },
13533  SetTabVisibleCore: function(index, visible, initialization) {
13534   if(!this.tabs[index].visible || (visible && initialization))
13535    return;
13536   this.SetTabVisibleInternal(index, visible);
13537  },
13538  SetTabVisibleInternal: function(index, visible) {
13539   this.SetObservationPaused(true);
13540   var element = this.GetTabElement(index, false);
13541   var currentShiftWidth = 0,
13542    visibleTabElement = this.GetVisibleTabElement(index),
13543    separatorElement = this.GetSeparatorElement(index);
13544   if(visibleTabElement)
13545    currentShiftWidth = visibleTabElement.offsetWidth;
13546   if(separatorElement)
13547    currentShiftWidth += separatorElement.offsetWidth;
13548   var activeElement = this.GetTabElement(index, true);
13549   var contentElement = this.GetContentElement(index);
13550   if(this.IsMultiRow())
13551    this.setTabRowVisibility(index, visibleTabElement, visible);
13552   if(!visible) {
13553    if(this.activeTabIndex == index) {
13554     for(var i = 0; i < this.GetTabCount() ; i++) {
13555      if(this.IsTabVisible(i) && this.IsTabEnabled(i) && i != index) {
13556       this.SetActiveTabIndexInternal(i, false);
13557       break;
13558      }
13559     }
13560     for(var i = 0; i < this.GetTabCount() ; i++) {
13561      if(this.IsTabVisible(i) && i != index) {
13562       this.SetActiveTabIndexInternal(i, false);
13563       break;
13564      }
13565     }
13566     if(this.activeTabIndex == index) {
13567      this.activeTabIndex = -1;
13568      ASPx.SetElementDisplay(this.GetMainElement(), false);
13569     }
13570    }
13571    if(element != null)
13572     this.SetElementDisplay(element, false);
13573    if(activeElement != null)
13574     this.SetElementDisplay(activeElement, false);
13575    if(contentElement != null)
13576     this.setContentElementVisible(contentElement, false, index);
13577   }
13578   else {
13579    if(element != null)
13580     this.SetElementDisplay(element, this.activeTabIndex != index);
13581    if(activeElement != null)
13582     this.SetElementDisplay(activeElement, this.activeTabIndex == index);
13583    if(contentElement != null)
13584     this.setContentElementVisible(contentElement, this.activeTabIndex == index, index);
13585    if(this.activeTabIndex == -1) {
13586     ASPx.SetElementDisplay(this.GetMainElement(), true);
13587     this.SetActiveTabIndexInternal(index, false);
13588    }
13589    else if(!this.IsTabEnabled(this.activeTabIndex) && this.IsTabEnabled(index))
13590     this.SetActiveTabIndexInternal(index, false);
13591   }
13592   if(this.GetTabsCell())
13593    this.updateTabOrderCssMarkers();
13594   this.SetSeparatorsVisiblility();
13595   this.tabHeightManager.requestAdjustment();
13596   if(!this.enableScrolling)
13597    this.AdjustTabControlSizeLite();
13598   else {
13599    this.AdjustTabScrolling(false, false);
13600    if(this.IsTabStartOutOfScrollArea(index)) {
13601     currentShiftWidth = visible
13602      ? (this.GetVisibleTabElement(index).offsetWidth + this.GetSeparatorElement(index).offsetWidth) * (-1)
13603      : currentShiftWidth;
13604     this.CorrectScrollArea(currentShiftWidth);
13605    }
13606    if(this.firstShownTabIndex == index && !visible) {
13607     var newShownTabIndex = this.GetNextVisibleTabIndex(index);
13608     if(newShownTabIndex < 0) {
13609      newShownTabIndex = this.GetPrevVisibleTabIndex(index);
13610      if(newShownTabIndex < 0) return;
13611     }
13612     this.ScrollToShowTab(newShownTabIndex, true);
13613    }
13614   }
13615   this.SetObservationPaused(false);
13616  },
13617  setContentElementVisible: function (contentElement, value, index) {
13618   ASPx.SetElementDisplay(contentElement, value);
13619  },
13620  setTabRowVisibility: function(index, visibleTabElement, visible) {
13621   var tabRowContainer = this.GetVisibleTabElement(index).parentNode;
13622   if(!visible) {
13623    var areAllTabsInvisible = this.areAllTabsInRowInvisible(index);
13624    ASPx.SetElementDisplay(tabRowContainer, !areAllTabsInvisible);
13625   } else {
13626    ASPx.SetElementDisplay(tabRowContainer, true);
13627   }
13628  },
13629  areAllTabsInRowInvisible: function(index) {
13630   var visibleTabElement = this.GetVisibleTabElement(index),
13631    tabRowContainer = visibleTabElement.parentNode,
13632    tabIndices = [],
13633    findTargetContainer = false;
13634   for(var i = 0; i < this.GetTabCount() ; i++) {
13635    var tabElement = this.GetVisibleTabElement(i);
13636    if(tabElement) {
13637     var rowContainer = tabElement.parentNode;
13638     if(tabRowContainer == rowContainer) {
13639      tabIndices.push(i);
13640      findTargetContainer = true;
13641     } else {
13642      if(findTargetContainer)
13643       break;
13644     }
13645    }
13646   }
13647   var areAllTabsInvisible = true;
13648   if(tabIndices.length === 1) {
13649    areAllTabsInvisible = !this.IsTabVisible(index);
13650   } else {
13651    var len = tabIndices.length;
13652    while(len--)
13653     areAllTabsInvisible = areAllTabsInvisible && !this.IsTabVisible(tabIndices[len]);
13654   }
13655   return areAllTabsInvisible;
13656  },
13657  updateTabOrderCssMarkers: function() {
13658   var newTabsOrderInfo = this.getTabsOrderInfo();
13659   this.changeTabsOrderCssMarkers(this.tabsOrderInfo.leadTab, newTabsOrderInfo.leadTab, Constants.CssClassName.LEAD_TAB);
13660   this.changeTabsOrderCssMarkers(this.tabsOrderInfo.lastTab, newTabsOrderInfo.lastTab, Constants.CssClassName.LAST_TAB);
13661   if(this.IsMultiRow()) {
13662    for(var i = 0; i < this.tabsOrderInfo.lines.length; i++) {
13663     var oldLineInfo = this.tabsOrderInfo.lines[i];
13664     var newLineInfo = newTabsOrderInfo.lines[i];
13665     this.changeTabsOrderCssMarkers(oldLineInfo.startLineTab, newLineInfo.startLineTab, Constants.CssClassName.NEW_LINE_START_TAB);
13666     this.changeTabsOrderCssMarkers(oldLineInfo.endLineTab, newLineInfo.endLineTab, Constants.CssClassName.NEW_LINE_END_TAB);
13667    }
13668   }
13669   this.tabsOrderInfo = newTabsOrderInfo;
13670  },
13671  changeTabsOrderCssMarkers: function(oldTab, newTab, className) {
13672   if(oldTab !== newTab) {
13673    this.changeTabElementCssMarker(oldTab, className, false);
13674    this.changeTabElementCssMarker(newTab, className, true);
13675   }
13676  },
13677  changeTabElementCssMarker: function(tab, className, add) {
13678   if(!tab) return;
13679   var changeFunc = add ? this.addNewClassNameToElement : ASPx.RemoveClassNameFromElement;
13680   var tabElement = this.GetTabElement(tab.index, false);
13681   if(tabElement)
13682    changeFunc(tabElement, className);
13683   var activeTabElement = this.GetTabElement(tab.index, true);
13684   if(activeTabElement)
13685    changeFunc(activeTabElement, className);
13686  },
13687  addNewClassNameToElement: function(element, className) {
13688   element.className += " " + className;
13689  },
13690  getTabsOrderInfo: function() {
13691   var lines = this.getTabLines();
13692   var info = { lines: [] };
13693   for(var i = 0, line; line = lines[i]; i++) {
13694    var lineInfo = { };
13695    info.lines.push(lineInfo);
13696    for(var j = 0, tab; tab = line[j]; j++) {
13697     if(tab.GetVisible()) {
13698      if(i === 0)
13699       info.leadTab = tab;
13700      lineInfo.startLineTab = tab;
13701      break;
13702     }
13703    }
13704    for(var j = line.length - 1, tab; tab = line[j]; j--) {
13705     if(tab.GetVisible()) {
13706      if(i === lines.length - 1)
13707       info.lastTab = tab;
13708      lineInfo.endLineTab = tab;
13709      break;
13710     }
13711    }
13712   }
13713   return info;
13714  },
13715  getTabLines: function() {
13716   var line = [];
13717   var lines = [ line ];
13718   for(var i = 0, tab; tab = this.tabs[i]; i++) {
13719    if(tab.newLine) {
13720     line = [];
13721     lines.push(line);
13722    }
13723    line.push(tab);
13724   }
13725   return lines;
13726  },
13727  CorrectScrollArea: function (value) {
13728   var rtlCorrect = this.rtl ? -1 : 1;
13729   var newPostion = (this.scrollManager.GetScrolledAreaPosition() + value * rtlCorrect);
13730   this.scrollManager.SetScrolledAreaPosition((newPostion * rtlCorrect) <= 0 ? newPostion : 0);
13731  },
13732  SetSeparatorsVisiblility: function () {
13733   for(var i = 0; i < this.tabs.length; i++) {
13734    var nextVisibleTabIndex = this.GetNextVisibleTabIndex(i),
13735     nextVisibleTabElement = this.GetVisibleTabElement(nextVisibleTabIndex),
13736     separatorVisible = this.tabs[i].GetVisible() && nextVisibleTabIndex > -1 && !(this.IsMultiRow() && this.isTabElementStartsNewLine(nextVisibleTabElement)),
13737     separatorElement = this.GetSeparatorElement(i);
13738    if(separatorElement != null)
13739     ASPx.SetElementDisplay(separatorElement, separatorVisible);
13740   }
13741  },
13742  GetNextVisibleTabIndex: function (index, allowHidden) {
13743   for(var i = index + 1; i < this.tabs.length; i++) {
13744    if(allowHidden && this.tabs[i].visible || this.tabs[i].GetVisible())
13745     return i;
13746   }
13747   return -1;
13748  },
13749  GetPrevVisibleTabIndex: function (index) {
13750   for(var i = index - 1; i >= 0; i--) {
13751    if(this.tabs[i].GetVisible())
13752     return i;
13753   }
13754   return -1;
13755  },
13756  applyAccessibilityAttributes: function() {
13757   this.setAriaDescription("");
13758   this.setAriaDescription("tab");
13759   this.setAriaDescription("presentationElements");
13760  }
13761 });
13762 ASPxClientTabControlBase.FindOwnerTabControl = function(element) {
13763  var mainElement = ASPx.GetParentByClassName(element, Constants.CssClassName.TAB_CONTROL);
13764  if(mainElement)
13765   return ASPx.GetControlCollection().GetByName(mainElement.id);
13766  return null;
13767 };
13768 ASPxClientTabControlBase.HasDocumentKeyDownHandler = false;
13769 ASPxClientTabControlBase.EnsureDocumentKeyDownHandler = function() {
13770  if(!ASPxClientTabControlBase.HasDocumentKeyDownHandler) {
13771   ASPxClientTabControlBase.HasDocumentKeyDownHandler = true;
13772   ASPx.Evt.AttachEventToDocument("keydown", function(e) {
13773    var activeElement = document.activeElement;
13774    if(ASPx.ElementHasCssClass(activeElement, Constants.CssClassName.TAB_LINK)) {
13775     var tabControl = ASPxClientTabControlBase.FindOwnerTabControl(activeElement);
13776     if(tabControl)
13777      tabControl.onFocusedTabKeyDown(e);
13778    }
13779   });
13780  }
13781 };
13782 ASPxClientTabControlBase.TabChildElementIDRegExp = /^A?T\d+(T|Img)?$/;
13783 ASPxClientTabControlBase.IsTabChildElementID = function (id) {
13784  return ASPxClientTabControlBase.TabChildElementIDRegExp.test(id);
13785 };
13786 ASPxClientTabControlBase.PrepareStateController = function () {
13787  if(ASPxClientTabControlBase.IsStateControllerPrepared) return;
13788  ASPx.AddAfterSetHoverState(aspxTabStateChanged);
13789  ASPx.AddAfterClearHoverState(aspxTabStateChanged);
13790  ASPx.AddAfterSetPressedState(aspxTabStateChanged);
13791  ASPx.AddAfterClearPressedState(aspxTabStateChanged);
13792  ASPxClientTabControlBase.IsStateControllerPrepared = true;
13793 };
13794 var TabHeightManagerBase = ASPx.CreateClass(null, {
13795  constructor: function(tabControl) {
13796   this.tabControl = tabControl;
13797  },
13798  initialize: function() {
13799  },
13800  isMultiRow: function() {
13801   return this.tabControl.IsMultiRow();
13802  },
13803  correctTabHeightOnStateChanged: function(element) {
13804  },
13805  requestAdjustment: function() {
13806  },
13807  adjustTabs: function() {
13808  },
13809  needAdjustTabStrip: function() {
13810   return false;
13811  },
13812  getTabStripHeight: function() {
13813   return 0;
13814  }
13815 });
13816 var TabHeightManager = ASPx.CreateClass(TabHeightManagerBase, {
13817  constructor: function(tabControl) {
13818   this.constructor.prototype.constructor.call(this, tabControl);
13819   this.needCalculate = true;
13820   this.rowCount = 1;
13821   this.tabSpaceSize = 0;
13822   this.equalityError = 0.11;
13823  },
13824  initialize: function() {
13825   this.tabSpaceSize = this.tabControl.GetTabSpaceSizeLite();
13826   if(this.isMultiRow())
13827    this.rowCount = this.tabControl.getTabLines().length;
13828  },
13829  getTabStripElements: function() {
13830   return this.isMultiRow()
13831    ? this.getTabStripElementsMultirow()
13832    : this.getTabStripElementsCommon();
13833  },
13834  getTabStripElementsCommon: function() {
13835   var elements = ASPx.GetChildNodesByTagName(this.tabControl.GetTabStripContainer(), "LI");
13836   if(this.tabControl.enableScrolling) {
13837    var subElements = ASPx.GetChildNodesByTagName(this.tabControl.GetTabsCell(), "LI");
13838    elements.push.apply(elements, subElements);
13839   }
13840   return elements;
13841  },
13842  getTabStripElementsMultirow: function() {
13843   var elements = [];
13844   elements.push(this.tabControl.GetLeftIndentLite());
13845   elements.push(this.tabControl.GetRightIndentLite());
13846   var tabRows = this.tabControl.getTabRows();
13847   for(var i = 0, tabRow; tabRow = tabRows[i]; i++) {
13848    var subElements = ASPx.GetChildNodesByTagName(tabRow, "LI");
13849    elements.push.apply(elements, subElements);
13850   }
13851   return elements;
13852  },
13853  isSameValues: function(val1, val2) {
13854   if(!ASPx.IsExists(val1) || !ASPx.IsExists(val2))
13855    return false;
13856   return this.tabControl.areEqualValues(val1, val2, this.equalityError);
13857  },
13858  requestAdjustment: function() {
13859   this.needCalculate = true;
13860  },
13861  needAdjustTabStrip: function() {
13862   return true;
13863  },
13864  getTabStripHeight: function() {},
13865  adjustTabs: function() {
13866   this.needCalculate = this.tabControl.UseProportionalTabSizes() || this.needCalculate || !ASPx.documentLoaded;
13867   if(!this.needCalculate)
13868    return;
13869   var needAdjust = this.calculateTabs();
13870   if(needAdjust) {
13871    this.needCalculate = !this.tabControl.cacheEnabled;
13872    this.adjustTabStripElements();
13873   }
13874  },
13875  calculateTabs: function() {},
13876  adjustTabStripElements: function() {}
13877 });
13878 var TabCustomHeightManager = ASPx.CreateClass(TabHeightManager, {
13879  constructor: function(tabControl) {
13880   this.constructor.prototype.constructor.call(this, tabControl);
13881   this.rowHeightArray = null;
13882   this.updateInfo = null;
13883   this.margins = {};
13884  },
13885  initialize: function() {
13886   TabHeightManager.prototype.initialize.call(this);
13887   this.storeInitialTabMargins();
13888  },
13889  storeInitialTabMargins: function() {
13890   var elements = this.tabControl.GetTabsElements();
13891   var elementCount = elements.length;
13892   for(var i = 0; i < elementCount; i++) {
13893    var element = elements[i];
13894    var margin = ASPx.PxToFloat(ASPx.GetCurrentStyle(element)[this.getMarginStyleProperty()]);
13895    this.margins[element.id] = margin;
13896   }
13897  },
13898  setTabElementMargin: function(tabElement, margin) {
13899   var useImportant = !!this.getMarginById(tabElement.id);
13900   if(useImportant) {
13901    var styleProperty = 'margin-' + this.tabControl.tabPosition.toLowerCase();
13902    tabElement.style.cssText = this.createImportantAttribute(tabElement.style.cssText, styleProperty, margin + 'px');
13903   }
13904   else
13905    tabElement.style[this.getMarginStyleProperty()] = margin + 'px';
13906  },
13907  getMarginStyleProperty: function() {
13908   return this.tabControl.tabPosition === "Bottom" ? "marginBottom" : "marginTop";
13909  },
13910  createImportantAttribute: function(cssText, attribute, value) {
13911   var importantProperty = ' ' + attribute + ': ' + value + '!important';
13912   if(cssText.indexOf(attribute) == -1) {
13913    cssText += importantProperty;
13914    return cssText;
13915   }
13916   var attributes = cssText.split(";"); 
13917   var attributesLength = attributes.length;
13918   for(var i = 0; i < attributesLength; i++){
13919    if(attributes[i].indexOf(attribute) != -1) {
13920     attributes[i] = importantProperty;
13921     break;
13922    }
13923   }
13924   cssText = attributes.join(";");
13925   return cssText;
13926  },
13927  adjustTabStripElements: function() {
13928   var elementCount = this.updateInfo.length;
13929   for(var i = 0; i < elementCount; i++) {
13930    var correction = this.updateInfo[i];
13931    if(ASPx.IsExists(correction.margin))
13932     this.setTabElementMargin(correction.element, correction.margin);
13933    else
13934     correction.element.style.height = correction.height + 'px';
13935   }
13936  },
13937  getMarginById: function(tabId) {
13938   var margin = this.margins[tabId];
13939   if(!margin)
13940    return 0;
13941   return margin;
13942  },
13943  updateHeightByTab: function(element, rowIndex, cache) {
13944   this.updateHeightByElement(element, rowIndex, cache);
13945  },
13946  updateHeightByIndent: function(element, cache) {
13947   var rowIndex = this.getActiveTabRowIndexCore(this.rowCount);
13948   this.updateHeightByElement(element, rowIndex, cache);
13949  },
13950  updateHeightByElement: function(element, rowIndex, cache) {
13951   var rowHeight = this.rowHeightArray[rowIndex];
13952   var totalElementHeight = cache.height + cache.verticalBordersAndPaddingsWidth + this.getMarginById(element.id);
13953   this.rowHeightArray[rowIndex] = this.tabControl.GetMaxValue(totalElementHeight, rowHeight);
13954  },
13955  updateRowHeightArray: function(stripInfo) {
13956   for(var i = 0; i < this.rowCount; i++) {
13957    var rowLength = stripInfo[i].length;
13958    var rowInfo = stripInfo[i];
13959    for(var j = 0; j < rowLength; j++) {
13960     var element = rowInfo[j].element;
13961     if(this.tabControl.isTemplateIndentElement(element)) {
13962      var oldHeight = element.style.height;
13963      element.style.height = '';
13964      var cache = this.tabControl.GetOrCreateElementCache(element);
13965      rowInfo[j].cache = cache;
13966      this.updateHeightByIndent(element, cache);
13967      element.style.height = oldHeight;
13968     }
13969     else {
13970      var cache = this.tabControl.GetOrCreateElementCache(element);
13971      rowInfo[j].cache = cache;
13972      if(this.tabControl.isTabElement(element) && cache.display)
13973       this.updateHeightByTab(element, i, cache);
13974     }
13975    }  
13976   }
13977  },
13978  calculateTabs: function() {
13979   var info = this.createStripElementInfo();
13980   this.resetRowHeightArray();
13981   this.updateRowHeightArray(info);
13982   this.updateInfo = this.calculateUpdateInfo(info);
13983   return !!this.updateInfo;
13984  },
13985  createStripElementInfo: function() {
13986   if(this.isMultiRow())
13987    return this.createStripElementInfoMultirow();
13988   var tabStripElements = this.getTabStripElements();
13989   var rowElementsInfo = [];
13990   var stripElementInfo = [rowElementsInfo];
13991   for(var i = 0, element; element = tabStripElements[i]; i++) {
13992    var elementInfo = this.createElementInfo(element);
13993    rowElementsInfo.push(elementInfo);
13994   }
13995   return stripElementInfo;
13996  },
13997  createStripElementInfoMultirow: function() {
13998   var stripElementInfo = [];
13999   var tabLines = this.tabControl.getTabLines();
14000   for(var rowIndex = 0, tabLine; tabLine = tabLines[rowIndex]; rowIndex++) {
14001    var rowElementsInfo = [];
14002    stripElementInfo.push(rowElementsInfo);
14003    for(var tabIndex = 0, tab; tab = tabLine[tabIndex]; tabIndex++) {
14004     if(tab.GetVisible()) {
14005      var element = this.tabControl.GetVisibleTabElement(tab.index);
14006      var elementInfo = this.createElementInfo(element);
14007      rowElementsInfo.push(elementInfo);
14008     }
14009    }
14010   }
14011   var leftIndent = this.tabControl.GetLeftIndentLite();
14012   stripElementInfo.leftIndent = this.createElementInfo(leftIndent);
14013   var rightIndent = this.tabControl.GetRightIndentLite();
14014   stripElementInfo.rightIndent = this.createElementInfo(rightIndent);
14015   return stripElementInfo;
14016  },
14017  createElementInfo: function(element) {
14018   return { element: element, cache: null };
14019  },
14020  getActualTabStripHeight: function() {
14021   var result = 0;
14022   for(var i = 0; i < this.rowCount; i++)
14023    result += this.rowHeightArray[i];
14024   if(this.isMultiRow())
14025    result += (this.rowCount - 1) * this.tabSpaceSize;
14026   return result;
14027  },
14028  resetRowHeightArray: function() {
14029   if(this.rowHeightArray !== null)
14030    for(var i = 0; i < this.rowCount; i++)
14031     this.rowHeightArray[i] = 0;
14032   else {
14033    this.rowHeightArray = [];
14034    for(var i = 0; i < this.rowCount; i++)
14035     this.rowHeightArray.push(0);
14036   }
14037  },
14038  calculateUpdateInfo: function(stripInfo) {
14039   var updateInfo = [];
14040   for(var i = 0; i < this.rowCount; i++) {
14041    var rowHeight = this.rowHeightArray[i];
14042    var rowInfo = stripInfo[i];
14043    var rowLength = rowInfo.length;
14044    for(var j = 0; j < rowLength; j++)
14045     this.calcUpdateInfoForStripItem(updateInfo, rowInfo[j], rowHeight);
14046   }
14047   if(this.isMultiRow())
14048    this.calcUpdateInfoForIndents(updateInfo, stripInfo);
14049   return updateInfo.length > 0 ? updateInfo : null;
14050  },
14051  calcUpdateInfoForIndents: function(updateInfo, stripInfo) {
14052   var expectedHeignt = this.getActualTabStripHeight();
14053   this.calcUpdateInfoForStripItem(updateInfo, stripInfo.leftIndent, expectedHeignt);
14054   this.calcUpdateInfoForStripItem(updateInfo, stripInfo.rightIndent, expectedHeignt);
14055  },
14056  calcUpdateInfoForStripItem: function(updateInfo, stripItem, expectedHeight) {
14057   var element = stripItem.element,
14058    cache = stripItem.cache;
14059   var height = cache.height + cache.verticalBordersAndPaddingsWidth;
14060   if(!this.isSameValues(cache.outerHeight, expectedHeight)) {
14061    var updateItem = { element: element };
14062    if(this.tabControl.isTabElement(element))
14063     updateItem.margin = expectedHeight - height;
14064    else
14065     updateItem.height = expectedHeight - cache.verticalBordersAndPaddingsWidth;
14066    updateInfo.push(updateItem);
14067   }
14068  },
14069  correctTabHeightOnStateChanged: function(element) {
14070   this.adjustTabs();
14071   this.tabControl.AdjustTabStripHeight();
14072  },
14073  getTabStripHeight: function() {
14074   return this.getActualTabStripHeight();
14075  }
14076 });
14077 var TabDefaultHeightManager = ASPx.CreateClass(TabHeightManager, {
14078  constructor: function(tabControl) { 
14079   this.constructor.prototype.constructor.call(this, tabControl);
14080   this.lastValue = 0;
14081  },
14082  calculateTabs: function() {
14083   var height = this.getTabStripElementHeight();
14084   var lastTabHeight = this.lastValue;
14085   if(lastTabHeight && this.isSameValues(height, lastTabHeight))
14086    return false;
14087   this.lastValue = height;
14088   return true;
14089  },
14090  adjustTabStripElements: function() {
14091   var itemHeight = this.lastValue;
14092   var indentHeight = this.getTabStripHeight();
14093   var elements = this.getTabStripElements();
14094   for(var i = 0, element; element = elements[i]; i++) { 
14095    var useIndentHeight = this.isMultiRow() && 
14096     (ASPx.ElementHasCssClass(element, Constants.CssClassName.LEFT_INDENT) || 
14097     ASPx.ElementHasCssClass(element, Constants.CssClassName.RIGHT_INDENT));
14098    var height = useIndentHeight ? indentHeight : itemHeight;
14099    this.tabControl.SetCachedElementHeight(element, height);
14100   }
14101  },
14102  correctTabHeightOnStateChanged: function(element) {
14103   var tabElement = ASPx.GetParentByTagName(element, "LI");
14104   var height = this.lastValue;
14105   height -= this.tabControl.GetCachedVerticalBordersPaddingsMarginsWidth(tabElement);
14106   tabElement.style.height = height + "px";
14107  },
14108  getTabStripElementHeight: function () {
14109   var result = 0;
14110   var elements = this.getElementsForCalculation();
14111   var elementsLength = elements.length;
14112   for(var i = 0; i < elementsLength; i++) {
14113    var element = elements[i];
14114    var oldHeight = "";
14115    if(element.style.height) {
14116     oldHeight = element.style.height;
14117     element.style.height = "";
14118     if(this.isLayoutResetRequired())
14119      element.style.position = "relative";
14120    }
14121    var height = this.tabControl.GetCachedElementSize(element, "height");
14122    if(height > result)
14123     result = height;
14124    if(oldHeight) {
14125     element.style.height = oldHeight;
14126     if(this.isLayoutResetRequired())
14127      element.style.position = "";
14128    }
14129   }
14130   return result;
14131  },
14132  isLayoutResetRequired: function() {
14133   return ASPx.Browser.Firefox && ASPx.Browser.MajorVersion >= 41 && ASPx.Browser.MajorVersion < 43;
14134  },
14135  getElementsForCalculation: function() {
14136   var elements = this.getTabElements();
14137   if(!this.isMultiRow()) {
14138    var templateElements = this.getTemplateIndentElements();
14139    if(templateElements.length > 0)
14140     elements.push.apply(elements, templateElements);
14141   }
14142   return elements;
14143  },
14144  getTabElements: function() {
14145   var elements = [];
14146   var tabsLength = this.tabControl.tabs.length;
14147   for(var i = 0; i < tabsLength; i++) {
14148    if(this.tabControl.IsTabVisible(i)) {
14149     var element = this.tabControl.GetVisibleTabElement(i);
14150     if(element)
14151      elements.push(element);
14152    }
14153   }
14154   return elements;
14155  },
14156  getTemplateIndentElements: function() {
14157   var elements = [];
14158   var stripContainer = this.tabControl.GetTabStripContainer();
14159   var templateElements = ASPx.GetNodesByClassName(stripContainer, Constants.CssClassName.INDENT_TEMPLATE);
14160   var templateElementsLength = templateElements.length;
14161   for(var i = 0; i < templateElementsLength; i++) {
14162    var element = templateElements[i];
14163    if(element)
14164     elements.push(templateElements[i]);
14165   }
14166   return elements;
14167  },
14168  getTabStripHeight: function() {
14169   var result = this.lastValue * this.rowCount;
14170   if(this.isMultiRow())
14171    result += (this.rowCount - 1) * this.tabSpaceSize;
14172   return result;
14173  }
14174 });
14175 var FakeTabHeightManager = ASPx.CreateClass(TabHeightManager, {
14176  constructor: function() { 
14177   this.constructor.prototype.constructor.call(this);
14178  },
14179  initialize: function() {},
14180  adjustLineBreaks: function() {},
14181  adjustTabs: function() {},
14182  adjustTabStripElements: function() {},
14183  calculateTabs: function() {},
14184  correctTabHeightOnStateChanged: function() {},
14185  getTabStripElements: function() {},
14186  getTabStripHeight: function() {},
14187  isSameValues: function() {},
14188  needAdjustTabStrip: function() { return false; },
14189  requestAdjustment: function() {}
14190 });
14191 var FlexTabHeightManager = ASPx.CreateClass(TabHeightManagerBase, {
14192  constructor: function(tabControl) {
14193   this.constructor.prototype.constructor.call(this, tabControl);
14194  },
14195  correctTabHeightOnStateChanged: function(element) {
14196   this.adjustTabs();
14197  },
14198  adjustTabs: function() {
14199   var elements = this.getTabStripElements();
14200   var actualElements = [];
14201   for(var i = 0, element; element = elements[i]; i++) {
14202    if(element.style.display == "none")
14203     continue;
14204    actualElements.push(element);
14205    element.style.height = "";
14206    ASPx.RemoveClassNameFromElement(element, Constants.CssClassName.PINNED_STRIP_ITEM);
14207   }
14208   var heightArray = [];
14209   for(var i = 0, element; element = actualElements[i]; i++) {
14210    var height = this.tabControl.GetCachedElementInnerSize(element, "height");
14211    height = this.tabControl.GetPreparedSizeValue(height);
14212    heightArray.push(height);
14213   }
14214   for(var i = 0, element; element = actualElements[i]; i++) {
14215    var height = heightArray[i];
14216    element.style.height = height + "px";
14217    element.className += " " + Constants.CssClassName.PINNED_STRIP_ITEM;
14218   }
14219  },
14220  getTabStripElements: function() {
14221   var stripContainer = this.tabControl.GetTabStripContainer();
14222   return ASPx.GetNodes(stripContainer, function(el) { 
14223    return el.className &&
14224     (this.tabControl.isTabElement(el) ||
14225     this.tabControl.isTemplateIndentElement(el));
14226   }.aspxBind(this));
14227  }
14228 });
14229 var ASPxClientTabControl = ASPx.CreateClass(ASPxClientTabControlBase, {
14230  SetHeight: function (height) { }
14231 });
14232 ASPxClientTabControl.Cast = ASPxClientControl.Cast;
14233 var ASPxClientPageControl = ASPx.CreateClass(ASPxClientTabControlBase, {
14234  constructor: function (name) {
14235   this.constructor.prototype.constructor.call(this, name);
14236   this.handleClickOnWholeTab = false;
14237   this.sizingConfig.supportPercentHeight = true;
14238   this.sizingConfig.supportAutoHeight = true;
14239   getPageControlCollection().Add(this);
14240  },
14241  GetTabContentHTML: function (tab) {
14242   var element = this.GetContentHolder(tab.index);
14243   return (element != null) ? element.innerHTML : "";
14244  },
14245  SetTabContentHTML: function (tab, html, useAnimation) {
14246   var element = this.GetContentElement(tab.index);
14247   if(element != null) {
14248    ASPx.SetInnerHtml(this.GetContentHolder(tab.index), html);
14249    this.adjustControlInternal();
14250    if(useAnimation && typeof (ASPx.AnimationHelper) != "undefined")
14251     ASPx.AnimationHelper.fadeIn(element, function () { }.aspxBind(this));
14252   }
14253  },
14254  PerformCallback: function (parameter, onSuccess) {
14255   var index = this.GetActiveTabIndex();
14256   var element = this.GetContentElement(index);
14257   if(element != null) {
14258    var arg = index + "|" + parameter;
14259    this.PerformCallbackInternal(index, element, arg, onSuccess);
14260   }
14261  },
14262  onDocumentMouseDown: function(evt) {
14263   this.enableCollapsingExtended(evt);
14264  },
14265  onDocumentMouseUp: function(evt) {
14266   this.enableCollapsingExtended(evt);
14267  },
14268  onDocumentMouseMove: function(evt) {
14269   if(ASPx.Evt.IsLeftButtonPressed(evt))
14270    this.enableCollapsingExtended(evt);
14271  },
14272  onDocumentMouseClick: function(evt) {
14273   this.enableCollapsingExtended(evt);
14274  },
14275  onDocumentKeyDown: function(evt) {
14276   this.enableCollapsing(evt);
14277  },
14278  onDocumentKeyUp: function(evt) {
14279   this.enableCollapsing(evt);
14280  },
14281  onDocumentKeyPress: function(evt) {
14282   this.enableCollapsing(evt);
14283  },
14284  enableCollapsingExtended: function(evt) {
14285   var srcElement = ASPx.Evt.GetEventSource();
14286   var useShortTime = srcElement && ((src.tagName == "input" && (src.type == "text" || src.type == "password")) || scr.tagName == "textarea");
14287   this.enableCollapsing(evt, useShortTime);
14288  },
14289  enableCollapsing: function(evt, useShortTime) {
14290   this.contentObserving.collapsingEnabled = true;
14291   if(this.contentObserving.collapsingTimerID !== -1)
14292    window.clearTimeout(this.contentObserving.collapsingTimerID);
14293   this.contentObserving.collapsingTimerID = window.setTimeout(this.disableCollapsing.aspxBind(this), this.contentObserving.collapsingTimeout);
14294  },
14295  disableCollapsing: function() {
14296   this.contentObserving.collapsingTimerID = -1;
14297   this.contentObserving.collapsingEnabled = false;
14298  },
14299  applyAccessibilityAttributes: function() {
14300   ASPxClientTabControlBase.prototype.applyAccessibilityAttributes.call(this);
14301   this.setAriaDescription("tabPanel");
14302  }
14303 });
14304 ASPxClientPageControl.Cast = ASPxClientControl.Cast;
14305 var ASPxClientTab = ASPx.CreateClass(null, {
14306  constructor: function (tabControl, index, name) {
14307   this.tabControl = tabControl;
14308   this.index = index;
14309   this.name = name;
14310   this.enabled = true;
14311   this.clientEnabled = true;
14312   this.visible = true;
14313   this.clientVisible = true;
14314   this.newLine = false;
14315  },
14316  GetEnabled: function () {
14317   return this.enabled && this.clientEnabled;
14318  },
14319  SetEnabled: function (value, doNotChangeActiveTab) {
14320   if(this.clientEnabled != value) {
14321    this.clientEnabled = value;
14322    this.tabControl.SetTabEnabled(this.index, value, false, doNotChangeActiveTab);
14323   }
14324  },
14325  GetImageUrl: function (active) {
14326   return this.tabControl.GetTabImageUrl(this.index, active);
14327  },
14328  SetImageUrl: function (value, active) {
14329   this.tabControl.SetTabImageUrl(this.index, active, value);
14330  },
14331  GetActiveImageUrl: function () {
14332   return this.tabControl.GetTabImageUrl(this.index, true);
14333  },
14334  SetActiveImageUrl: function (value) {
14335   this.tabControl.SetTabImageUrl(this.index, true, value);
14336  },
14337  GetNavigateUrl: function () {
14338   return this.tabControl.GetTabNavigateUrl(this.index);
14339  },
14340  SetNavigateUrl: function (value) {
14341   this.tabControl.SetTabNavigateUrl(this.index, value);
14342  },
14343  GetText: function () {
14344   return this.tabControl.GetTabText(this.index);
14345  },
14346  SetText: function (value) {
14347   this.tabControl.SetTabText(this.index, value);
14348  },
14349  GetVisible: function () {
14350   return this.visible && this.clientVisible;
14351  },
14352  SetVisible: function (value) {
14353   if(this.clientVisible != value) {
14354    this.tabControl.SetTabVisible(this.index, value, false);
14355   }
14356  }
14357 });
14358 var ASPxClientTabControlTabEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
14359  constructor: function (tab, htmlElement, htmlEvent) {
14360   this.constructor.prototype.constructor.call(this);
14361   this.tab = tab;
14362  }
14363 });
14364 var ASPxClientTabControlTabCancelEventArgs = ASPx.CreateClass(ASPxClientProcessingModeCancelEventArgs, {
14365  constructor: function (processOnServer, tab) {
14366   this.constructor.prototype.constructor.call(this, processOnServer);
14367   this.tab = tab;
14368   this.reloadContentOnCallback = false;
14369  }
14370 });
14371 var ASPxClientTabControlTabClickEventArgs = ASPx.CreateClass(ASPxClientTabControlTabCancelEventArgs, {
14372  constructor: function (processOnServer, tab, htmlElement, htmlEvent) {
14373   this.constructor.prototype.constructor.call(this, processOnServer, tab);
14374   this.htmlElement = htmlElement;
14375   this.htmlEvent = htmlEvent;
14376  }
14377 });
14378 ASPx.TCTClick = function(evt, name, index) {
14379  var tc = ASPx.GetControlCollection().Get(name);
14380  if(tc != null) tc.OnTabClick(evt, index);
14381 };
14382 function aspxTabStateChanged(source, args) {
14383  var postfixIndex = args.item.name.lastIndexOf("_");
14384  var postfix = args.item.name.substring(postfixIndex + 1);
14385  if(!ASPxClientTabControlBase.IsTabChildElementID(postfix))
14386   return;
14387  var tcName = args.item.name.substring(0, postfixIndex);
14388  var tc = ASPx.GetControlCollection().Get(tcName);
14389  if(tc && tc.CorrectTabHeightOnStateChanged)
14390   tc.CorrectTabHeightOnStateChanged(args.element);
14391 }
14392 var TabControlScrollingManager = ASPx.CreateClass(ASPx.MouseScrollingManager, {
14393  setParentNodeOverflow: function() { }
14394 });
14395 var PageControlCollection = ASPx.CreateClass(ASPxClientControlCollection, {
14396  constructor: function() {
14397   this.constructor.prototype.constructor.call(this);
14398   this.initEvents();
14399  },
14400  GetCollectionType: function(){
14401   return "PageControl";
14402  },
14403  initEvents: function() {
14404   if(!(ASPx.Browser.IE && ASPx.Browser.MajorVersion == 10 && !ASPx.Browser.TouchUI)) return;
14405   ASPx.Evt.AttachEventToDocument("mousedown", this.onMouseDown.aspxBind(this));
14406   ASPx.Evt.AttachEventToDocument("mouseup", this.onMouseUp.aspxBind(this));
14407   ASPx.Evt.AttachEventToDocument("mousemove", this.onMouseMove.aspxBind(this));
14408   ASPx.Evt.AttachEventToDocument("mouseclick", this.onMouseClick.aspxBind(this));
14409   ASPx.Evt.AttachEventToDocument("keydown", this.onKeyDown.aspxBind(this));
14410   ASPx.Evt.AttachEventToDocument("keyup",  this.onKeyUp.aspxBind(this));
14411   ASPx.Evt.AttachEventToDocument("keypress", this.onKeyPress.aspxBind(this));
14412  },
14413  raiseEventHandler: function(handlerName, evt) {
14414   this.ForEachControl(function(control) {
14415    if(control.IsDOMInitialized())
14416     control[handlerName](evt);
14417   });
14418  },
14419  onMouseDown: function(evt) {
14420   this.raiseEventHandler("onDocumentMouseDown", evt);
14421  },
14422  onMouseUp: function(evt) {
14423   this.raiseEventHandler("onDocumentMouseUp", evt);
14424  },
14425  onMouseMove: function(evt) {
14426   this.raiseEventHandler("onDocumentMouseMove", evt);
14427  },
14428  onMouseClick: function(evt) {
14429   this.raiseEventHandler("onDocumentMouseClick", evt);
14430  },
14431  onKeyDown: function(evt) {
14432   this.raiseEventHandler("onDocumentKeyDown", evt);
14433  },
14434  onKeyUp: function(evt) {
14435   this.raiseEventHandler("onDocumentKeyUp", evt);
14436  },
14437  onKeyPress: function(evt) {
14438   this.raiseEventHandler("onDocumentKeyPress", evt);
14439  }
14440 });
14441 var pageControlCollection = null;
14442 function getPageControlCollection() {
14443  if(pageControlCollection == null)
14444   pageControlCollection  = new PageControlCollection();
14445  return pageControlCollection;
14446 }
14447 var LayoutManagerBase = ASPx.CreateClass(null, {
14448  constructor: function(tabControl) {
14449   this.tabControl = tabControl;
14450  },
14451  isContentObservingEnabled: function() {
14452   return false;
14453  },
14454  isCollapsingInObservingEnabled: function() {
14455   return false;
14456  },
14457  isContentAdjustmentRequired: function() {
14458   return false;
14459  },
14460  isContentCollapsingRequired: function() {
14461   return false;
14462  },
14463  isAdjustmenRequiredByNewSizes: function(sizes, newSizes, error) {
14464   return false;
14465  },
14466  needCollapseControl: function() {
14467   return false;
14468  },
14469  areEqualValues: function(val1, val2, error) {
14470   return this.tabControl.areEqualValues(val1, val2, error);
14471  },
14472  enableContentObservation: function() {
14473  },
14474  calculateSizes: function() {
14475  },
14476  adjustSize: function() {
14477  },
14478  collapseTabStrip: function() {
14479  },
14480  adjustSizeOnContentModification: function() {
14481  },
14482  expandTabStrip: function() {
14483  },
14484  getScrollableAreaWidth: function() {
14485   return 0;
14486  },
14487  updateTabStripImagesSizes: function() {
14488  },
14489  prepareTabStripForImageLoading: function() {
14490  },
14491  adjustScrollVisibleAreaWidth: function() {
14492  },
14493  createTabHeightManager: function() {
14494   return null;
14495  },
14496  inlineInitialize: function() {
14497  }
14498 });
14499 var FixedLayoutManager = ASPx.CreateClass(LayoutManagerBase, {
14500  constructor: function(tabControl) {
14501   this.constructor.prototype.constructor.call(this, tabControl);
14502  },
14503  isContentObservingEnabled: function() {
14504   return true;
14505  },
14506  isCollapsingInObservingEnabled: function() {
14507   return true;
14508  },
14509  isContentAdjustmentRequired: function() {
14510   return !!this.tabControl.GetMainElement().style.height;
14511  },
14512  isContentCollapsingRequired: function() {
14513   return this.isContentAdjustmentRequired();
14514  },
14515  isAdjustmenRequiredByNewSizes: function(sizes, newSizes, error) {
14516   var control = this.tabControl;
14517   var checkOnlyPrimarySize = control.emptyHeight && control.contentObserving.collapsingEnabled;
14518   return checkOnlyPrimarySize
14519    ? !this.areEqualValues(sizes[control.primaryDimension], newSizes[control.primaryDimension], error)
14520    : !(this.areEqualValues(sizes.width, newSizes.width, error) && this.areEqualValues(sizes.height, newSizes.height, error));
14521  },
14522  needCollapseControl: function() {
14523   return true;
14524  },
14525  enableContentObservation: function() {
14526   this.tabControl.adjustedSizes = this.tabControl.GetAdjustedSizes();
14527  },
14528  calculateSizes: function() {
14529   this.tabControl.calculateSizesCore();
14530  },
14531  adjustSizeOnContentModification: function() {
14532   var control = this.tabControl;
14533   control.DoSafeScrollPositionOperation(function() {
14534    control.adjustControlInternal();
14535   });
14536  },
14537  adjustSize: function() {
14538   this.tabControl.adjustTabControlSizeCore();
14539  },
14540  collapseTabStrip: function() {
14541   this.tabControl.collapseTabStrip();
14542  },
14543  expandTabStrip: function() {
14544   this.tabControl.expandTabStrip();
14545  },
14546  getScrollableAreaWidth: function() {
14547   return this.tabControl.getScrollableAreaWidthCore();
14548  },
14549  updateTabStripImagesSizes: function() {
14550   this.tabControl.UpdateTabStripImagesSizes();
14551  },
14552  prepareTabStripForImageLoading: function() {
14553   this.tabControl.PrepareTabStripForImageLoading();
14554  },
14555  adjustScrollVisibleAreaWidth: function() {
14556   this.tabControl.AdjustScrollVisibleAreaWidth();
14557  },
14558  createTabHeightManager: function() {
14559   return this.tabControl.createTabHeightManagerCore();
14560  },
14561  inlineInitialize: function() {
14562   this.tabControl.initFixedLayoutInline();
14563  }
14564 });
14565 var FlexLayoutManager = ASPx.CreateClass(LayoutManagerBase, {
14566  constructor: function(tabControl) {
14567   this.constructor.prototype.constructor.call(this, tabControl);
14568   this.tabHeightManager = null;
14569  },
14570  inlineInitialize: function() {
14571   var control = this.tabControl;
14572   if(!control.hasContent || control.IsTopBottomTabPosition() || control.heightValueSetInPercentage)
14573    return;
14574   var contentContainer = control.GetContentsCell();
14575   ASPx.AddClassNameToElement(contentContainer, Constants.CssClassName.AUTO_HEIGHT);
14576  },
14577  isContentObservingEnabled: function() {
14578   return this.isTabScrollingEnabled() || this.isCollapsingInObservingEnabled();
14579  },
14580  isCollapsingInObservingEnabled: function() {
14581   return this.needCollapseControl();
14582  },
14583  isContentAdjustmentRequired: function() {
14584   return this.needAdjustContentHeight();
14585  },
14586  isContentCollapsingRequired: function() {
14587   return this.needCollapseContent();
14588  },
14589  isAdjustmenRequiredByNewSizes: function(sizes, newSizes, error) {
14590   if(this.needRefreshTabStrip())
14591    return false;
14592   var dimension = this.isTabScrollingEnabled() ? "width" : "height";
14593   return !this.areEqualValues(sizes[dimension], newSizes[dimension], error);
14594  },
14595  needAdjustContentHeight: function() {
14596   var control = this.tabControl;
14597   return control.IsTopBottomTabPosition()
14598    ? !control.emptyHeight
14599    : !(control.emptyHeight || control.heightValueSetInPercentage);
14600  },
14601  needCollapseContent: function() {
14602   return this.tabControl.IsTopBottomTabPosition() && this.tabControl.heightValueSetInPercentage;
14603  },
14604  needRefreshTabStrip: function() {
14605   var control = this.tabControl;
14606   return ASPx.Browser.Edge && control.hasTabStip && !control.IsTopBottomTabPosition();
14607  },
14608  needCollapseControl: function() {
14609   return this.needCollapseContent() || this.needRefreshTabStrip();
14610  },
14611  isTabScrollingEnabled: function() {
14612   return this.tabControl.enableScrolling;
14613  },
14614  calculateSizes: function() {
14615   var tabControl = this.tabControl;
14616   tabControl.updateContentAdjustmentFlags();
14617   this.tabHeightManager.adjustTabs();
14618   if(!tabControl.isControlCollapsed)
14619    tabControl.CollapseControl();
14620   tabControl.isControlCollapsed = false;
14621   var stripSizes = { primary: 0, secondary: 0 },
14622    controlSizes = { };
14623   var stripContainer = this.tabControl.GetTabStripContainer();
14624   if(tabControl.IsTopBottomTabPosition() && !tabControl.emptyHeight)
14625    stripSizes.secondary = tabControl.GetCachedElementInnerSize(stripContainer, "height");
14626   tabControl.calculateMainElementSizes();
14627   controlSizes.primary = tabControl.adjustmentVars.mainElementSizes.primary;
14628   controlSizes.secondary = tabControl.adjustmentVars.mainElementSizes.secondary;
14629   tabControl.adjustmentVars.stripSizes = stripSizes;
14630   tabControl.adjustmentVars.controlSizes = controlSizes;
14631   tabControl.CalculateContentHeight();
14632   this.expandTabStrip();
14633  },
14634  adjustSize: function() {
14635   this.calculateSizes();
14636   this.tabControl.AdjustPageContents();
14637  },
14638  adjustSizeOnContentModification: function() {
14639   var control = this.tabControl;
14640   if(this.needCollapseContent())
14641    control.adjustControlInternal();
14642   else
14643    control.adjustTabStripScrolling(true);
14644  },
14645  collapseTabStrip: function() {
14646   if(this.needRefreshTabStrip()) {
14647    var stripContainer = this.tabControl.GetTabStripContainer();
14648    stripContainer.style.height = "auto";
14649   }
14650  },
14651  expandTabStrip: function() {
14652   if(this.needRefreshTabStrip()) {
14653    var stripContainer = this.tabControl.GetTabStripContainer();
14654    stripContainer.style.height = "";
14655   }
14656  },
14657  getScrollableAreaWidth: function() {
14658   var scrollableArea = this.tabControl.GetScrollableArea();
14659   var items = ASPx.GetChildElementNodes(scrollableArea);
14660   var width = 0;
14661   for(var i = 0, item; item = items[i]; i++) {
14662    if(item.className.indexOf(Constants.CssClassName.TAB_FILLER) == -1)
14663     width += this.tabControl.GetCachedElementSize(item);
14664   }
14665   return width;
14666  },
14667  createTabHeightManager: function() {
14668   var strip = this.tabControl.GetTabsCell();
14669   var useManager = this.tabControl.IsTopBottomTabPosition() && strip && strip.className.indexOf(Constants.CssClassName.PINNED_TAB_HEADERS) == -1;
14670   this.tabHeightManager = useManager ? new FlexTabHeightManager(this.tabControl) : new FakeTabHeightManager();
14671   return this.tabHeightManager;
14672  }
14673 });
14674 var ASPxClientRibbonTabControl = ASPx.CreateClass(ASPxClientTabControl, {
14675  getTabActivationHtmlEventName: function() {
14676   return ASPx.Browser.TouchUI ? "onclick" : "onmousedown";
14677  }
14678 });
14679 ASPx.GetPageControlCollection = getPageControlCollection;
14680 ASPx.TabControlRenderHelper = TabControlRenderHelper;
14681 ASPx.FakeTabHeightManager = FakeTabHeightManager;
14682 ASPx.LayoutManagerBase = LayoutManagerBase;
14683 window.ASPxClientTabControlBase = ASPxClientTabControlBase;
14684 window.ASPxClientPageControl = ASPxClientPageControl;
14685 window.ASPxClientTabControl = ASPxClientTabControl;
14686 window.ASPxClientTab = ASPxClientTab;
14687 window.ASPxClientTabControlTabClickEventArgs = ASPxClientTabControlTabClickEventArgs;
14688 window.ASPxClientTabControlTabCancelEventArgs = ASPxClientTabControlTabCancelEventArgs;
14689 window.ASPxClientTabControlTabEventArgs = ASPxClientTabControlTabEventArgs;
14690 window.ASPxClientRibbonTabControl = ASPxClientRibbonTabControl;
14691})();
14692
14693var dx;
14694(function(dx) {
14695 var LayoutEntity = ASPx.CreateClass(null, {
14696  constructor: function() {
14697   this.container = null;
14698  },
14699  getCache: function() { return this.owner ? this.owner.getCache() : (this.cache || (this.cache = {})); },
14700  getUniqueId: function() { return "l" + (LayoutEntity.layoutEntityUniqueIdCount++); },
14701  querySelector: function(selector) { return this.querySelectorAll(selector)[0]; },
14702  querySelectorAll: function(selector) { return this.querySelectorAllInternal(selector || ("#" + this.getContainer().id)); },
14703  registerRangeCssRule: function(selector, min, max, node) {
14704   var styles = "";
14705   if(min !== -1) styles += "min-width: " + min + "px;";
14706   if(max !== -1) styles += "max-width: " + max + "px;";
14707   this.registerCssRule(selector, styles, node);
14708  },
14709  registerCssRule: function(selector, styles, uniqueNode) {
14710   if(this.owner)
14711    this.owner.registerCssRule(selector, styles, uniqueNode);
14712   else
14713    this.registerCssRuleInternal(selector, styles, uniqueNode);
14714  },
14715  toggleClassName: function(el, className, condition) { return this.owner ? this.owner.toggleClassName(el, className, condition) : this.toggleClassNameInternal(el, className, condition); },
14716  toggleClassNameInternal: function(el, className, condition) { },
14717  registerCssRuleInternal: function(selector, styles, uniqueNode) { },
14718  querySelectorAllInternal: function(selector) { return this.owner ? this.owner.querySelectorAll(selector) : this.getNodes(selector); },
14719  getNodes: function(selector) {
14720   if(typeof selector === "function")
14721    return selector();
14722   if(typeof selector !== "string")
14723    throw new Error("custom selector is not implemented");
14724   var result = this.container.querySelectorAll(selector);
14725   if(!result.length) {
14726    selector = "#" + this.container.id + selector;
14727    result = this.container.parentNode.querySelectorAll(selector);
14728   }
14729   return result;
14730  },
14731  getContainer: function() { return this.owner ? this.owner.getContainer() : this.container; },
14732  createLayoutEntity: function() {
14733   return this.owner ? this.owner.createLayoutEntity.apply(this.owner, arguments) : this.createLayoutEntityInternal.apply(this, arguments);
14734  },
14735  getNodeWidth: function(node, skipMargins) {
14736   return Math.ceil(node.offsetWidth + (skipMargins ? 0 : this.getBoxOuterOffset(node))) + ASPx.GetHorizontalBordersWidth(node);
14737  },
14738  getBoxSize: function(el) {
14739   return Math.ceil(ASPx.GetElementOffsetWidth(el)) + this.getBoxOuterOffset(el);
14740  },
14741  getBoxInnerOffset: function(el) { return ASPx.GetLeftRightBordersAndPaddingsSummaryValue(el); },
14742  getBoxOuterOffset: function(el) { return ASPx.GetLeftRightMargins(el); },
14743  getBoxOffset: function(el) { return this.getBoxOuterOffset(el) + this.getBoxInnerOffset(el); },
14744  createLayoutEntityInternal: function(entityType, params) {
14745   var proxyClass = ASPx.CreateClass(this.resolveLayoutEntityType(entityType), {
14746    constructor: function(args) { this.constructor.prototype.constructor.apply(this, args); },
14747    owner: this
14748   });
14749   return new proxyClass(params || []);
14750  },
14751  resolveLayoutEntityType: function(t) { return t; },
14752  dispose: function() { }
14753 });
14754 LayoutEntity.layoutEntityUniqueIdCount = 0;
14755 dx.LayoutEntity = LayoutEntity;
14756 dx.LayoutBreakPointBuilderBase = ASPx.CreateClass(LayoutEntity, {
14757  constructor: function(name, selectorOrFunc) {
14758   this.name = name;
14759   this.selectorOrFunc = selectorOrFunc;
14760   this.onStateEnter = function(block) { };
14761   this.onStateLeave = function(block) { };
14762   this.prepareBlockFunc = function() { };
14763  },
14764  getBlockWidth: function(block) { return this.prepareBlockFunc(block); },
14765  findBlockElements: function(container) {
14766   if(typeof this.selectorOrFunc === "function")
14767    return this.selectorOrFunc(container);
14768   else if(typeof this.selectorOrFunc === "string")
14769    return ASPx.GetChildElementNodesByPredicate(container, function(n) { return ASPx.ElementMatchesSelector(n, this.selectorOrFunc); }.bind(this));
14770   return [];
14771  },
14772  setPrepareFunc: function(func) {
14773   this.prepareBlockFunc = func.bind(this);
14774   return this;
14775  },
14776  buildBlock: function(el, blocksContainer, isActive, expandableElementsSelector) {
14777   var block = this.createLayoutEntity(dx.LayoutBlock,
14778    [el, blocksContainer, this.name, isActive, expandableElementsSelector,
14779     function() { this.owner.domChanges.push(this.onStateEnter.bind(this, block)); }.aspxBind(this),
14780     function() { this.owner.domChanges.push(this.onStateLeave.bind(this, block)); }.aspxBind(this)
14781    ]);
14782   var widthRanges = this.prepareBlockFunc(block);
14783   block.widthRanges = widthRanges;
14784   return block;
14785  },
14786  onEnterState: function(callback) {
14787   this.onStateEnter = callback;
14788   return this;
14789  },
14790  onLeaveState: function(callback) {
14791   this.onStateLeave = callback;
14792   return this;
14793  },
14794  registerStateCssRule: function(selectors, minWidth, maxWidth, node) {
14795   var selectorArr = selectors.split(',') || [""];
14796   for(var i = 0; i < selectorArr.length; i++) {
14797    var selector = selectorArr[i];
14798    this.registerRangeCssRule("." + this.name + (selector ? " " + selector : ""), minWidth, maxWidth, node);
14799   }
14800  }
14801 });
14802 dx.LayoutBlock = ASPx.CreateClass(LayoutEntity, {
14803  constructor: function(node, blocksContainer, className, isActive, exp
14803andableElementsSelector, onEnter, onLeave) {
14804   this.onEnter = onEnter;
14805   this.onLeave = onLeave;
14806   this.prevBlock = null;
14807   this.nextBlock = null;
14808   if(node.block) {
14809    this.prevBlock = node.block;
14810    this.prevBlock.nextBlock = this;
14811   }
14812   node.block = this;
14813   this.hasPreview = false;
14814   this.isApplied = false;
14815   this.node = node;
14816   this.className = className;
14817   this.blocksContainer = blocksContainer;
14818   this.widthRanges = [];
14819   this.blocksContainerOffset = this.getBoxInnerOffset(blocksContainer);
14820   this.minContainerWidth = 0;
14821   this._isActive = isActive;
14822   if(ASPx.GetIsParent(blocksContainer, node.parentNode)) {
14823    while(node.parentNode != blocksContainer)
14824     this.blocksContainerOffset += this.getBoxInnerOffset(node = node.parentNode);
14825   }
14826   if(expandableElementsSelector) {
14827    var elements = this.blocksContainer.querySelectorAll(expandableElementsSelector);
14828    if(elements.length > 0) {
14829     for(var i = 0; i < elements.length; i++)
14830      this.minContainerWidth = Math.max(this.minContainerWidth, ASPx.GetElementOffsetWidth(elements[i]));
14831     return;
14832    }
14833   }
14834   this.minContainerWidth = this.node.offsetWidth;
14835   this.ownerGroup = null;
14836  },
14837  canBePushed: function() {
14838   return !this.isActive() && this.prevBlock && this.prevBlock.isActive();
14839  },
14840  canBePopped: function() {
14841   return this.isActive() && this.prevBlock;
14842  },
14843  push: function() {
14844   this._isActive = true;
14845   if(this.prevBlock)
14846    this.prevBlock._isActive = false;
14847  },
14848  pop: function() {
14849   this._isActive = false;
14850   if(this.prevBlock)
14851    this.prevBlock._isActive = true;
14852  },
14853  isActive: function() { return this._isActive; },
14854  getWidth: function(calcMax) { return calcMax ? this.widthRanges[0].maxWidth : this.widthRanges[0].minWidth; },
14855  applyLayout: function() {
14856   if(!this.isApplied && this.isActive()) {
14857    if(this.nextBlock)
14858     this.nextBlock.applyLayoutInternal(false);
14859    if(this.prevBlock)
14860     this.prevBlock.applyLayoutInternal(false);
14861    this.applyLayoutInternal(true);
14862   }
14863  },
14864  applyLayoutInternal: function(state) {
14865   if(this.isApplied !== state) {
14866    this.toggleClassName(this.node, this.className, state);
14867    if(state || this.ownerGroup.checkIsBlockLastActive(this))
14868     this.toggleClassName(this.blocksContainer, this.className, state);
14869    if(!state)
14870     this.onLeave();
14871    else
14872     this.onEnter();
14873   }
14874   this.isApplied = state;
14875  },
14876  dispose: function() {
14877   this.node.block = null;
14878   this.node = null;
14879   this.ownerGroup = null;
14880   this.blocksContainer = null;
14881  }
14882 });
14883 dx.LayoutState = ASPx.CreateClass(LayoutEntity, {
14884  constructor: function(buffer, name, prevState) {
14885   this.builders = buffer || [];
14886   this.name = name;
14887   this.index = prevState ? prevState.index + 1 : 0;
14888   this.prevState = prevState;
14889   this.nextState = null;
14890   this.canBeMixed = true;
14891   if(prevState)
14892    prevState.nextState = this;
14893  },
14894  for: function(selectorOrFunc) { return this.builders[this.builders.length] = this.createLayoutEntity(dx.LayoutBreakPointBuilderBase, [this.name, selectorOrFunc]); }
14895 });
14896 dx.LayoutBlockGroup = ASPx.CreateClass(LayoutEntity, {
14897  constructor: function(isDefault) {
14898   this.blocks = [];
14899   this.isDefault = isDefault;
14900  },
14901  isActive: function() { return this.blocks.some(function(b) { return b.isActive(); }); },
14902  addBlock: function(block) {
14903   block.ownerGroup = this;
14904   this.blocks.push(block);
14905  },
14906  applyLayout: function() {
14907   for(var i = 0; i < this.blocks.length; i++)
14908    this.blocks[i].applyLayout();
14909  },
14910  getWidth: function(calcMax) {
14911   var resultWidth = 0;
14912   var blocksContainer = null;
14913   var blocks = this.getOrderedBlocks();
14914   for(var i = 0; i < blocks.length; i++) {
14915    var block = blocks[i];
14916    if(this.isDefault && blocksContainer !== block.blocksContainer) {
14917     blocksContainer = block.blocksContainer;
14918     resultWidth += block.blocksContainerOffset;
14919    }
14920    resultWidth += block.getWidth(calcMax);
14921   }
14922   return resultWidth;
14923  },
14924  checkIsBlockLastActive: function(block) {
14925   if(!ASPx.ElementHasCssClass(block.node, "gallery-item"))
14926    return true;
14927   var activeBlocks = this.blocks.filter(function(b) { return b.isActive() && b.blocksContainer === block.blocksContainer; });
14928   return activeBlocks.length === 1 && activeBlocks[0] === block;
14929  },
14930  getOrderedBlocks: function() {
14931   return this.blocks;
14932  },
14933  shrink: function() {
14934   var blocks = this.getOrderedBlocks();
14935   for(var i = blocks.length - 1; i >= 0; i--) {
14936    var block = blocks[i];
14937    if(!block.canBePushed())
14938     continue;
14939    block.push();
14940    return true;
14941   }
14942   return false;
14943  },
14944  grow: function() {
14945   var blocks = this.getOrderedBlocks();
14946   for(var i = 0; i < blocks.length; i++) {
14947    var block = blocks[i];
14948    if(!block.canBePopped())
14949     continue;
14950    block.pop();
14951    return true;
14952   }
14953   return false;
14954  }
14955 });
14956 dx.LayoutBlocksContainerPreview = ASPx.CreateClass(LayoutEntity, {
14957  constructor: function(node, selector, allBlocks, onEnterState, onLeaveState) {
14958   this.onEnterState = onEnterState;
14959   this.onLeaveState = onLeaveState;
14960   this._isActive = false;
14961   this.isLayoutApplied = false;
14962   this.node = node;
14963   this.width = this.getNodeWidth(node);
14964   this.previewContentWidth = 0;
14965   while(!ASPx.ElementMatchesSelector(node = node.parentNode, selector))
14966    this.width += this.getBoxInnerOffset(node);
14967   this.container = node;
14968   var relatedBlocks = allBlocks.filter(function(b) { return b.blocksContainer == node; });
14969   for(var i = 0; i < relatedBlocks.length; i++)
14970    relatedBlocks[i].hasPreview = true;
14971   var blocks = relatedBlocks.filter(function(b) { return b.nextBlock === null; });
14972   var className = "";
14973   function getRange(min, max) { return { minWidth: min, maxWidth: max || min }; }
14974   function mergeRanges(r1, r2) { return { minWidth: r1.minWidth + r2.minWidth, maxWidth: r1.maxWidth + r2.maxWidth }; }
14975   function reduceRanges(p, c) { return mergeRanges(p, c.widthRanges[0]); }
14976   function selectNextTier(b) {
14977    if(b.nextBlock) className = b.nextBlock.className;
14978    return b.nextBlock || b;
14979   }
14980   function hasAnyNextTierBlock(b) { return !!b.nextBlock; }
14981   this.contentWidth = 0;
14982   if(blocks.length > 0) {
14983    if(ASPx.GetParentByClassName(this.container, ASPx.BootstrapCssSelectors.Active)) {
14984     var width = this.getNodeWidth(this.container);
14985     this.registerRangeCssRule(selector, width, width, this.container);
14986    }
14987    this.contentWidth = blocks.reduce(function(p, c) { return p + c.getWidth(); }, blocks[0].blocksContainerOffset);
14988    var tiers = relatedBlocks.filter(function(b) { return b.prevBlock === null; });
14989    className = tiers[0].className;
14990    var tierRange = null;
14991    while(tiers.length > 0) {
14992     tierRange = tiers.reduce(reduceRanges, getRange(tiers[0].blocksContainerOffset));
14993     if(className == "default")
14994      this.previewContentWidth = tierRange.maxWidth;
14995     this.registerRangeCssRule(selector + "." + className, tierRange.minWidth, tierRange.maxWidth, this.container);
14996     if(tiers.filter(hasAnyNextTierBlock).length === 0)
14997      break;
14998     tiers = tiers.map(selectNextTier);
14999    }
15000   } else
15001    this.contentWidth = node.offsetWidth;
15002   this.registerRangeCssRule(selector + ".preview", this.width, this.width, this.container);
15003  },
15004  isActive: function() { return this._isActive; },
15005  getWidth: function(calcMax) { return this.isActive() ? this.width : this.contentWidth; },
15006  shrink: function() { return !this.isActive() && (this._isActive = true); },
15007  grow: function() { return this.isActive() && !(this._isActive = false); },
15008  applyLayout: function() {
15009   if(this.isLayoutApplied != this.isActive()) {
15010    this.isLayoutApplied = this.isActive();
15011    if(!this.isLayoutApplied)
15012     this.onLeaveState(this.container);
15013    else
15014     this.onEnterState(this.container);
15015    this.toggleClassName(this.container, "preview", this.isActive());
15016   }
15017  }
15018 });
15019 dx.LayoutBlockGroupCollection = ASPx.CreateClass(LayoutEntity, {
15020  constructor: function(groupsContainer, selector) {
15021   this.groupsContainer = groupsContainer;
15022   this.groupsContainerOffset = this.getBoxInnerOffset(this.groupsContainer);
15023   this.selector = selector;
15024   this.expandableElementsSelector = "";
15025   this.currentWidth = -1;
15026   this.maxWidth = -1;
15027   this.minWidth = -1;
15028   this.blockGroups = [];
15029   this.previews = [];
15030   this.allBlocks = [];
15031   this.blocksWithoutPreview = [];
15032  },
15033  createBlockGroups: function() { },
15034  expandableElements: function(selector) {
15035   this.expandableElementsSelector = selector;
15036  },
15037  definePreviews: function(previewsSelector, onEnterState, onLeaveState) {
15038   var previewElements = this.groupsContainer.querySelectorAll(this.selector + " " + previewsSelector);
15039   for(var i = 0; i < previewElements.length; i++) {
15040    var p = this.createLayoutEntity(dx.LayoutBlocksContainerPreview, [previewElements[i], this.selector, this.allBlocks, onEnterState, onLeaveState]);
15041    this.previews.push(p);
15042   }
15043   this.blocksWithoutPreview = this.allBlocks.filter(function(b) { return !b.hasPreview; });
15044  },
15045  defineState: function(stateName, initializeStateFunc) {
15046   var builders = [];
15047   var layoutState = this.createLayoutEntity(dx.LayoutState, [builders, stateName]);
15048   initializeStateFunc(layoutState);
15049   var blocksContainers = this.getNodesOrContainerIfMatches(this.groupsContainer, this.selector);
15050   var blocksGroup = this.createBlockGroup();
15051   for(var i = 0; i < blocksContainers.length; i++) {
15052    var blocksContainer = blocksContainers[i];
15053    this.intializeBlocksContainer(blocksContainer);
15054    for(var j = 0; j < builders.length; j++) {
15055     var builder = builders[j];
15056     var blockElements = [];
15057     if(typeof builder.selectorOrFunc == "string")
15058      blockElements = this.getNodesOrContainerIfMatches(blocksContainer, builder.selectorOrFunc);
15059     else if(typeof builder.selectorOrFunc == "function")
15060      blockElements = builder.selectorOrFunc();
15061     for(var k = 0; k < blockElements.length; k++) {
15062      var block = builder.buildBlock(blockElements[k], blocksContainer, blocksGroup.isDefault, this.expandableElementsSelector);
15063      this.allBlocks.push(block);
15064      blocksGroup.addBlock(block);
15065     }
15066    }
15067   }
15068  },
15069  getNodesOrContainerIfMatches: function(container, selector) {
15070   var result = container.querySelectorAll(selector);
15071   if(result.length === 0 && ASPx.ElementMatchesSelector(container, selector))
15072    result = [container];
15073   return result;
15074  },
15075  intializeBlocksContainer: function(bc) {
15076   bc._dxMinWidth = 0;
15077   if(this.expandableElementsSelector) {
15078    var exElements = bc.querySelectorAll(this.expandableElementsSelector);
15079    for(var i = 0; i < exElements.length; i++) {
15080     var el = exElements[i];
15081     var w = ASPx.GetElementOffsetWidth(exElements[i])+ this.getBoxInnerOffset(bc);
15082     while(el.parentNode != bc)
15083      w += this.getBoxInnerOffset(el = el.parentNode);
15084     bc._dxMinWidth = Math.max(bc._dxMinWidth, w);
15085    }
15086   }
15087  },
15088  createBlockGroup: function(groupElement) {
15089   return this.blockGroups[this.blockGroups.length] = this.createLayoutEntity(dx.LayoutBlockGroup, [this.blockGroups.length === 0, groupElement]);
15090  },
15091  hasActivePreviews: function() { return this.previews.filter(function(p) { return p.isActive(); }).length > 0; },
15092  getWidth: function(calcMax) {
15093   var width = 0;
15094   if(!this.hasActivePreviews()) {
15095    width += this.groupsContainerOffset;
15096    var blocksContainer = null;
15097    var blockContainerWidth = 0;
15098    for(var i = 0; i < this.allBlocks.length; i++) {
15099     var block = this.allBlocks[i];
15100     if(block.isActive()) {
15101      if(blocksContainer !== block.blocksContainer && this.groupsContainer !== block.blocksContainer) {
15102       width += Math.max(blockContainerWidth, blocksContainer ? blocksContainer._dxMinWidth : 0);
15103       blockContainerWidth = 0;
15104       blocksContainer = block.blocksContainer;
15105       blockContainerWidth += block.blocksContainerOffset;
15106      }
15107      blockContainerWidth += block.getWidth(calcMax);
15108     }
15109    }
15110    width += Math.max(blockContainerWidth, blocksContainer ? blocksContainer._dxMinWidth : 0);
15111   } else {
15112    width += this.previews.reduce(function(p, c) { return p + c.getWidth(calcMax); }, 0);
15113    width += this.blocksWithoutPreview.reduce(function(p, c) { return p + c.getWidth(calcMax); }, 0);
15114   }
15115   return width;
15116  },
15117  shrink: function() {
15118   if(this.hasActivePreviews()) {
15119    for(var i = this.previews.length - 1; i >= 0; i--) {
15120     if(this.previews[i].shrink())
15121      return true;
15122    }
15123   } else {
15124    for(var i = 0; i < this.blockGroups.length; i++) {
15125     if(this.blockGroups[i].shrink())
15126      return true;
15127    }
15128    var lastPreview = this.previews[this.previews.length - 1];
15129    if(lastPreview)
15130     return lastPreview.shrink();
15131   }
15132   return false;
15133  },
15134  grow: function() {
15135   if(this.hasActivePreviews()) {
15136    for(var i = 0; i < this.previews.length; i++) {
15137     if(this.previews[i].grow())
15138      return true;
15139    }
15140   } else {
15141    for(var i = this.blockGroups.length - 1; i >= 0; i--) {
15142     if(this.blockGroups[i].grow())
15143      return true;
15144    }
15145   }
15146   return false;
15147  },
15148  applyLayout: function() {
15149   for(var i = 0; i < this.previews.length; i++)
15150    this.previews[i].applyLayout();
15151   for(var i = 0; i < this.blockGroups.length; i++)
15152    this.blockGroups[i].applyLayout();
15153  },
15154  adjust: function(w) {
15155   if(this.currentWidth > w) {
15156    while(this.getWidth() > w && this.shrink()) { }
15157    this.currentWidth = w;
15158    this.applyLayout();
15159   } else if(w > this.currentWidth) {
15160    while(w > this.getWidth() && this.grow()) {
15161     if(this.getWidth() > w) {
15162      this.shrink();
15163      break;
15164     }
15165    }
15166    this.currentWidth = w;
15167    this.applyLayout();
15168   }
15169  },
15170  initialize: function() {
15171   this.currentWidth = this.getWidth(false);
15172   this.minWidth = this.currentWidth;
15173   this.maxWidth = this.getWidth(true);
15174   this.owner.containerMaxWidth = Math.max(this.owner.containerMaxWidth, this.maxWidth);
15175  },
15176  dispose: function() {
15177   for(var i = 0; i < this.allBlocks.length; i++)
15178    this.allBlocks[i].dispose();
15179   this.allBlocks = [];
15180   this.groupsContainer = null;
15181   this.blockGroups = [];
15182   this.previews = [];
15183   this.blocksWithoutPreview = [];
15184  }
15185 });
15186 dx.LayoutBreakpointsBuilder = ASPx.CreateClass(LayoutEntity, {
15187  constructor: function(control, builderClass) {
15188   this.builderClass = builderClass;
15189   this.control = control;
15190   this.container = control.GetMainElement();
15191   this.containerOffsets = this.calculateContainerOffsets();
15192   this.blockGroupsArray = [];
15193   this.cssRulesCache = {};
15194   this.isReady = false;
15195   this.rebuildBreakpointsInfo = [];
15196   this.containerMaxWidth = -1;
15197   this.classesToApply = [];
15198   this.domChanges = [];
15199   dx.BootstrapClientUtils.attachToUpdateDefaultStylesRequest(this);
15200   this.cssSheetsToInsert = null;
15201   this.nextAdjustGroupWidth = null;
15202  },
15203  resolveLayoutEntityType: function(t) {
15204   if(t == dx.LayoutBreakPointBuilderBase)
15205    return this.builderClass;
15206   return t;
15207  },
15208  toggleClassNameInternal: function(el, className, condition) {
15209   this.getBatchCssUpdateCache(el)[className] = condition;
15210  },
15211  getBatchCssUpdateCache: function (el) {
15212   var cache = el._layoutBuilderCache;
15213   if (!cache) {
15214    cache = el._layoutBuilderCache = {};
15215    this.classesToApply.push(this.createBatchCssUpdateDelegate(el));
15216   }
15217   return cache;
15218  },
15219  createBatchCssUpdateDelegate: function (el) {
15220   return function () {
15221    var cache = el._layoutBuilderCache;
15222    if(!cache)
15223     return;
15224    delete el._layoutBuilderCache;
15225    for(var k in cache) {
15226     if(cache.hasOwnProperty(k))
15227      ASPx.ToggleClassNameToElement(el, k, cache[k]);
15228    }
15229   };
15230  },
15231  registerCssRuleInternal: function(rule, styles, uniqueNode) {
15232   if(uniqueNode) {
15233    var uniqueKey = ASPx.Attr.GetAttribute(uniqueNode, "data-rid");
15234    if(!uniqueKey)
15235     ASPx.Attr.SetAttribute(uniqueNode, "data-rid", uniqueKey = this.getUniqueId());
15236    rule = "[data-rid=" + uniqueKey + "]" + rule;
15237   }
15238   if(!this.cssRulesCache[rule])
15239    this.cssRulesCache[rule] = styles;
15240   else if(this.cssRulesCache[rule])
15241    this.cssRulesCache[rule] += styles;
15242  },
15243  createBlockGroups: function(selectorOrFunc, groupSelectorOrFunc, prepareFunc) {
15244   this.rebuildBreakpointsInfo.push({ selector: selectorOrFunc, groupSelector: groupSelectorOrFunc, prepareFunc: prepareFunc });
15245   var result = [];
15246   var containers = this.querySelectorAll(selectorOrFunc);
15247   for(var i = 0; i < containers.length; i++) {
15248    var container = containers[i];
15249    var blockGroupCollection = this.createLayoutEntity(dx.LayoutBlockGroupCollection, [container, groupSelectorOrFunc]);
15250    this.blockGroupsArray.push(blockGroupCollection);
15251    if(prepareFunc) {
15252     prepareFunc(blockGroupCollection);
15253    }
15254    blockGroupCollection.createBlockGroups();
15255    result.push(blockGroupCollection);
15256   }
15257   this.nextAdjustGroupWidth = this.getGroupsWidth();
15258   return result;
15259  },
15260  initialize: function() {
15261   for(var i = 0; i < this.blockGroupsArray.length; i++)
15262    this.blockGroupsArray[i].initialize();
15263   this.createCssRules();
15264   this.isReady = true;
15265   if(this.cssSheetsToInsert === null)
15266    this.adjust();
15267  },
15268  createCssRules: function() {
15269   var cssText = "";
15270   for(var k in this.cssRulesCache) {
15271    if(this.cssRulesCache.hasOwnProperty(k))
15272     cssText += "\n" + k + "{" + this.cssRulesCache[k] + "}";
15273   }
15274   this.insertCssRulesToDom(cssText, this.container.id);
15275  },
15276  insertCssRulesToDom: function(cssText, containerId) {
15277   if(this.cssSheetsToInsert !== null)
15278    this.cssSheetsToInsert.push({ cssText: cssText, containerId: containerId });
15279   else
15280    ASPx.BootstrapCore.createStylesBlock(cssText, containerId);
15281  },
15282  adjust: function(beforeUpdate) {
15283   if(this.isReady) {
15284    var prevCssChanges = this.classesToApply;
15285    var prevDomChanges = this.domChanges;
15286    var cssChanges = this.classesToApply = [];
15287    var domChanges = this.domChanges = [];
15288    var w = null;
15289    if (this.nextAdjustGroupWidth !== null) {
15290     w = this.nextAdjustGroupWidth;
15291     this.nextAdjustGroupWidth = null;
15292    } else
15293     w = this.getGroupsWidth();
15294    for(var i = 0; i < this.blockGroupsArray.length; i++)
15295     this.blockGroupsArray[i].adjust(w);
15296    if (beforeUpdate) 
15297     beforeUpdate(this, w);
15298    cssChanges = prevCssChanges.concat(cssChanges);
15299    domChanges = prevDomChanges.concat(domChanges);
15300    this.queueUpdates(function() {
15301     while(cssChanges.length) cssChanges.shift()();
15302     this.queueUpdates(function() {
15303      while(domChanges.length) domChanges.shift()();
15304     });
15305    }.aspxBind(this));
15306   }
15307  },
15308  queueUpdates: function(callback) {
15309   ASPx.RequestAnimationFrame(callback);
15310  },
15311  getGroupsWidth: function() {
15312   return this.getContainer().offsetWidth - this.containerOffsets;
15313  },
15314  isBatchStylesUpdatingSupported: function() { return !!this.control.cancelLayoutStateAppearance; },
15315  beginStyleUpdate: function() {
15316   if(this.isBatchStylesUpdatingSupported())
15317    dx.LayoutBreakpointsBuilder.registerControl(this.control);
15318  },
15319  updateStyle: function() {
15320   if(!this.isBatchStylesUpdatingSupported())
15321    this.rebuildBreakpoints();
15322  },
15323  endStyleUpdate: function() {
15324   if(this.isBatchStylesUpdatingSupported())
15325    dx.LayoutBreakpointsBuilder.reInitializeLayout(this.control);
15326  },
15327  rebuildBreakpoints: function() {
15328   var rebuildInfo = this.rebuildBreakpointsInfo;
15329   this.dispose();
15330   for(var i = 0; i < rebuildInfo.length; i++)
15331    this.createBlockGroups(rebuildInfo[i].selector, rebuildInfo[i].groupSelector, rebuildInfo[i].prepareFunc);
15332   ASPx.RequestAnimationFrame(this.initialize.aspxBind(this));
15333  },
15334  dispose: function() {
15335   dx.BootstrapClientUtils.detachUpdateDefaultStylesRequestListener(this);
15336   this.containerOffsets = this.calculateContainerOffsets();
15337   for(var i = 0; i < this.blockGroupsArray.length; i++)
15338    this.blockGroupsArray[i].dispose();
15339   this.blockGroupsArray = [];
15340   this.cssRulesCache = {};
15341   this.isReady = false;
15342   this.rebuildBreakpointsInfo = [];
15343  },
15344  calculateContainerOffsets: function() {
15345   return this.getBoxInnerOffset(this.container);
15346  }
15347 });
15348 var currentControlQueue = [];
15349 var currentControlQueueLock = 0;
15350 dx.LayoutBreakpointsBuilder.registerControl = function(control) {
15351  currentControlQueue.push(control);
15352  currentControlQueueLock++;
15353 };
15354 function initializeControls(controls) {
15355  var cssSheetsBuffer = [];
15356  controls.forEach(function (c) { ASPx.AddClassNameToElement(c.GetMainElement(), "dxbs-lb-process"); });
15357  ASPx.RequestAnimationFrame(function () {
15358   controls.forEach(function(c) {
15359    if(c.IsVisible()) {
15360     c.buildLayout();
15361     c.layoutBreakPoints.cssSheetsToInsert = cssSheetsBuffer;
15362    }
15363   });
15364   ASPx.RequestAnimationFrame(function () {
15365    controls.forEach(function(c) {
15366     if(c.IsVisible())
15367      ASPx.RemoveClassNameFromElement(c.GetMainElement(), "dxbs-lb-process");
15368    });
15369    controls.forEach(function(c) {
15370     if(c.IsVisible())
15371      c.applyLayoutStateAppearance();
15372    });
15373    var stylesFragment = document.createDocumentFragment();
15374    cssSheetsBuffer.forEach(function (ss) {
15375     ASPx.BootstrapCore.createStylesBlock(ss.cssText, ss.containerId, stylesFragment);
15376    });
15377    ASPx.GetHeadElementOrCreateIfNotExist(document).appendChild(stylesFragment);
15378    controls.forEach(function(c) {
15379     if(c.IsVisible()) {
15380      var lb = c.layoutBreakPoints;
15381      lb.cssSheetsToInsert = null;
15382      lb.adjust();
15383     }
15384    });
15385   });
15386  });
15387 }
15388 dx.LayoutBreakpointsBuilder.initializeLayout = function(control) {
15389  if(currentControlQueueLock > 0 && --currentControlQueueLock === 0) {
15390   var controlsQueue = currentControlQueue;
15391   currentControlQueue = [];
15392   initializeControls(controlsQueue);
15393  }
15394 };
15395 dx.LayoutBreakpointsBuilder.reInitializeLayout = function(control) {
15396  if(currentControlQueueLock > 0 && --currentControlQueueLock === 0) {
15397   var controlsQueue = currentControlQueue;
15398   currentControlQueue = [];
15399   controlsQueue.forEach(function(c) {
15400    c.cancelLayoutStateAppearance();
15401    ASPx.BootstrapCore.removeStylesBlock(c.layoutBreakPoints.container.id);
15402    c.layoutBreakPoints.dispose();
15403   });
15404   ASPx.RequestAnimationFrame(function() {
15405    initializeControls(controlsQueue);
15406   });
15407  }
15408 };
15409 var OneLineLayoutBlock = ASPx.CreateClass(dx.LayoutBlock, {
15410  constructor: function(group, element) {
15411   this.group = group;
15412   this.element = element;
15413   this.width = 0;
15414   this.isActiveValue = null;
15415   this.index = group.blocks.length;
15416   this.nextBlock = null;
15417   this.prevBlock = element.layoutBlockObj || null;
15418   element.layoutBlockObj = element.layoutBlockObj ? element.layoutBlockObj.nextBlock = this : this;
15419  },
15420  afterCreate: function(groupsCollection) {
15421   delete this.element.layoutBlockObj;
15422   groupsCollection.maxWidth += this.width;
15423   groupsCollection.minWidth += this.getMinWidth();
15424   if(this.owner.canMarkItemElements())
15425    this.toggleClassName(this.element, "block-i", true);
15426   if (this.width === 0)
15427    this.raiseVisibilityChange(false);
15428  },
15429  setActive: function(active) {
15430   if(this.isActiveValue === active) return;
15431   this.isActiveValue = active;
15432   this.group.activeBlock = active ? this : null;
15433   this.group.groupsCollection.lastGroup = this.group;
15434   if(this.owner.needPrevStateCssClasses()) { 
15435    if(this.group.state.prevState)
15436     this.toggleClassName(this.group.element.parentNode, this.group.state.prevState.name, this.isActiveValue);
15437    this.toggleClassName(this.element, this.group.state.name, this.isActiveValue);
15438   }
15439   this.toggleClassName(this.group.element, this.group.state.name, this.isActiveValue);
15440  },
15441  raiseVisibilityChange: function (isVisible) {
15442   var callback = isVisible ? this.element.onShow : this.element.onHide;
15443   if (callback)
15444    this.owner.domChanges.push(callback);
15445  },
15446  getMinWidth: function() { return this.nextBlock ? this.nextBlock.getMinWidth() : this.width; },
15447  getNextBlock: function(step) {
15448   var group = this.group;
15449   var block = group.blocks[this.index - step];
15450   if(!block && (group = group.groupsCollection.blockGroups[group.totalIndex + step]))
15451    block = group.blocks[Math.pow(group.blocks.length, step > 0) - 1];
15452   return block;
15453  }
15454 });
15455 var OneLineLayoutBlockGroup = ASPx.CreateClass(dx.LayoutBlockGroup, {
15456  constructor: function(groupsCollection, element, state, domIndex) {
15457   this.groupsCollection = groupsCollection;
15458   this.state = state;
15459   this.element = element;
15460   this.elementOffset = this.getBoxOffset(element);
15461   this.blocks = [];
15462   this.activeBlock = null;
15463   this.fullWidth = this.elementOffset;
15464   this.isSmallest = !state.nextState;
15465   this.isLargest = !state.prevState;
15466   this.domIndex = domIndex;
15467   this.totalIndex = this.groupsCollection.blockGroups.length;
15468   this.createBlocks(state.builders);
15469   if(!!state.prevState && (this.isSmallest || (element.layoutBlockGroupObj.isSmallest = this.blocks.length === 0)))
15470    delete element.layoutBlockGroupObj;
15471   else
15472    element.layoutBlockGroupObj = this;
15473  },
15474  afterCreate: function(groupsCollection) {
15475   this.blocks.forEach(function(b) { b.afterCreate(groupsCollection); });
15476   groupsCollection.groupsOffset += this.elementOffset;
15477   groupsCollection.groupBlocksLengthLookup[this.domIndex] = this.blocks.length;
15478   groupsCollection.lastGroup = this;
15479   if(this.owner.canMarkGroupElements())
15480    this.toggleClassName(this.element, "block-g", true);
15481  },
15482  setActive: function(isActive) {
15483   var index = 0;
15484   if(!this.isSmallest && this.isLargest) {
15485    index = this.blocks.length - 1;
15486   }
15487   this.blocks[index].setActive(isActive);
15488  },
15489  createBlocks: function(builders) {
15490   for(var i = 0; i < builders.length; i++) {
15491    var builder = builders[i];
15492    var blockElements = builder.findBlockElements(this.element);
15493    for(var j = 0; j < blockElements.length; j++) {
15494     var block = this.createLayoutEntity(dx.LayoutBlock, [this, blockElements[j]]);
15495     this.fullWidth += block.width = builder.getBlockWidth(block);
15496     this.blocks.push(block);
15497    }
15498   }
15499   if(this.isLargest)
15500    this.setActive(true);
15501  },
15502  calculateWidth: function(block) { return this !== block.group ? this.fullWidth : this.getActualBlocks(block).reduce(function(r, b) { return r + b.width; }, this.elementOffset); },
15503  getActualBlocks: function(block) { return this.blocks.map(function(b) { return this.state.canBeMixed && b.prevBlock && b.index < block.index ? b.prevBlock : b; }.bind(this)); }
15504 });
15505 var OneLineLayoutBlockGroupCollection = ASPx.CreateClass(dx.LayoutBlockGroupCollection, {
15506  constructor: function(groupsContainer, selector) {
15507   this.groupsContainer = groupsContainer;
15508   this.testElement = typeof selector === "function" ? selector : function(el) { return ASPx.ElementMatchesSelector(el, selector); };
15509   this.blockGroups = [];
15510   this.states = [];
15511   this.width = 0;
15512   this.groupsOffset = 0;
15513   this.maxWidth = 0;
15514   this.minWidth = 0;
15515   this.groupElementsCount = 0;
15516   this.currentLayoutElements = [];
15517   this.lastGroup = null;
15518   this.groupLookupMap = {};
15519   this.groupBlocksLengthLookup = {};
15520  },
15521  createBlockGroup: function(groupElement, state, domIndex) {
15522   var blockGroup = this.createLayoutEntity(dx.LayoutBlockGroup, [this, groupElement, state, domIndex]);
15523   blockGroup = blockGroup.blocks.length > 0 ? this.blockGroups[this.blockGroups.length] = blockGroup : null;
15524   if(blockGroup)
15525    (this.groupLookupMap[domIndex] || (this.groupLookupMap[domIndex] = [])).splice(0, 0, blockGroup.totalIndex);
15526   return blockGroup;
15527  },
15528  createBlockGroups: function() {
15529   var groupElements = this.owner.getGroupElements(this.groupsContainer);
15530   this.groupElementsCount = groupElements.length;
15531   for(var i = 0; i < this.states.length; i++) {
15532    for(var j = this.groupElementsCount - 1; j >= 0; j--) {
15533     var el = groupElements[j];
15534     if(el && (!this.testElement(el) || !this.createBlockGroup(el, this.states[i], j)))
15535      groupElements[j] = null;
15536    }
15537   }
15538   this.states = [];
15539   for(var i = 0; i < this.blockGroups.length; i++) {
15540    if(!this.blockGroups[i].isLargest) break;
15541    this.blockGroups[i].afterCreate(this);
15542   }
15543   this.minWidth += this.groupsOffset;
15544   this.maxWidth += this.groupsOffset;
15545   this.width = this.maxWidth;
15546   this.currentLayoutElements = this.findActiveBlocks();
15547  },
15548  defineState: function(stateName, initializeStateFunc) {
15549   var layoutState = this.createLayoutEntity(dx.LayoutState, [[], stateName, this.states[this.states.length - 1] || null]);
15550   this.states.push(layoutState);
15551   initializeStateFunc(layoutState);
15552  },
15553  initialize: function() { },
15554  applyLayout: function(layoutElements) {
15555   this.currentLayoutElements.forEach(function(le) { le.setActive(false); });
15556   this.currentLayoutElements = layoutElements;
15557   this.currentLayoutElements.forEach(function(le) { le.setActive(true); });
15558   this.detectBlockItemVisibilityChanges();
15559  },
15560  adjust: function(width) {
15561   if(width === this.width || width <= this.minWidth && this.width === this.minWidth || width >= this.maxWidth && this.width === this.maxWidth)
15562    return;
15563   var oldWidth = this.width;
15564   this.width = Math.max(this.minWidth, Math.min(this.maxWidth, width));
15565   if(this.width === this.maxWidth)
15566    return this.applyLayout(this.blockGroups.filter(function(g) { return g.isLargest; }));
15567   else if(this.width === this.minWidth)
15568    return this.applyLayout(this.blockGroups.filter(function(g) { return g.isSmallest; }));
15569   var delta = oldWidth - this.width;
15570   var sign = delta / Math.abs(delta);
15571   var block = this.findActiveBlocks()[0], prevBlock = block, currentBlock = block;
15572   while(block) {
15573    width = this.calculateWidth(block);
15574    if(sign > 0 && width <= this.width || sign < 0 && width >= this.width) {
15575     var blockToApply = sign < 0 ? prevBlock : block;
15576     if(blockToApply !== currentBlock)
15577      this.applyLayout([blockToApply]);
15578     break;
15579    }
15580    prevBlock = block;
15581    block = block.getNextBlock(sign);
15582   }
15583  },
15584  detectBlockItemVisibilityChanges: function() {
15585   var actualGroups = this.findActualBlockGroups();
15586   for(var i = 0; i < actualGroups.length; i++) {
15587    var group = actualGroups[i];
15588    var afterActiveBlock = false;
15589    for(var j = 0; j < group.blocks.length; j++) {
15590     var block = group.blocks[j];
15591     if(group === this.lastGroup && !(afterActiveBlock = (afterActiveBlock || block.isActiveValue)))
15592      block = block.prevBlock || block;
15593     block.raiseVisibilityChange(block.width > 0);
15594    }
15595   }
15596  },
15597  calculateWidth: function(block) {
15598   block = block || this.findActiveBlocks()[0];
15599   var groups = this.findActualBlockGroups(block.group);
15600   return groups.reduce(function(w, g) { return w + g.calculateWidth(block); }, 0);
15601  },
15602  findActualBlockGroups: function(activeGroup) {
15603   activeGroup = activeGroup || this.lastGroup;
15604   var groups = [];
15605   for(var i = 0; i < this.groupElementsCount; i++) {
15606    var groupIndices = this.groupLookupMap[i];
15607    for(var j = 0; j < groupIndices.length; j++) {
15608     var group = this.blockGroups[groupIndices[j]];
15609     if(i < activeGroup.domIndex ? group.state.index < activeGroup.state.index : group.state.index <= activeGroup.state.index) {
15610      groups.push(group);
15611      break;
15612     }
15613    }
15614   }
15615   return groups;
15616  },
15617  findActiveBlocks: function() { return this.lastGroup ? this.lastGroup.blocks.filter(function(b) { return b.isActiveValue; }) : null; },
15618  dispose: function() { }
15619 });
15620 var OneLineLayoutBreakPointBuilder = ASPx.CreateClass(dx.LayoutBreakPointBuilderBase, {
15621  setWidth: function() {
15622   return this.setPrepareFunc(function(block) {
15623    return this.getBoxSize(block.element);
15624   });
15625  },
15626  setHidden: function() {
15627   return this.setPrepareFunc(function(block) { return 0; });
15628  },
15629  setOnlyImageWidth: function() {
15630   return this.setPrepareFunc(function(block) {
15631    var width = this.getBoxSize(block.element);
15632    var imageElement = ASPx.GetChildByClassName(block.element, "image:not(.preview-image)");
15633    if(!imageElement) {
15634     imageElement = ASPx.GetChildByClassName(ASPx.GetChildByClassName(block.element, "dropdown-toggle"), "image:not(.preview-image)");
15635    }
15636    var previewImageElement = ASPx.GetChildByClassName(block.element, "preview-image");
15637    if(!previewImageElement) {
15638     previewImageElement = ASPx.GetChildByClassName(ASPx.GetChildByClassName(block.element, "dropdown-toggle"), "preview-image");
15639    }
15640    if(imageElement) {
15641     width = this.getBoxSize(imageElement) - this.getBoxOuterOffset(imageElement);
15642     if(previewImageElement) {
15643      var previewImageWidth = this.getBoxSize(previewImageElement) - this.getBoxOuterOffset(previewImageElement);
15644      width = Math.max(width, previewImageWidth);
15645     }
15646     var offset = this.getBoxOffset(block.element);
15647     var parent = imageElement.parentNode;
15648     while(parent !== block.element) {
15649      offset += this.getBoxOffset(parent);
15650      parent = parent.parentNode;
15651     }
15652     return width + offset;
15653    }
15654    return width;
15655   });
15656  },
15657  setNoTextWidth: function() {
15658   return this.setPrepareFunc(function(block) {
15659    var width = this.getBoxSize(block.element);
15660    if (ASPx.GetChildByClassName(block.element, "dxbs-toolbar-editor"))
15661     return width;
15662    var imageElement = ASPx.GetChildByClassName(block.element, "image");
15663    if(!imageElement)
15664     imageElement = ASPx.GetChildByClassName(ASPx.GetChildByClassName(block.element, ASPx.BootstrapCssSelectors.Button), "image");
15665    if(imageElement) {
15666     var textElement = imageElement.nextElementSibling;
15667     if(textElement && !ASPx.ElementHasCssClass(textElement, "popup")) {
15668      width -= this.getBoxSize(textElement);
15669      width -= this.getBoxOuterOffset(imageElement);
15670     }
15671    }
15672    return width;
15673   });
15674  }
15675 });
15676 dx.OneLineLayoutBreakpointsBuilderBase = ASPx.CreateClass(dx.LayoutBreakpointsBuilder, {
15677  resolveLayoutEntityType: function(t) {
15678   switch(t) {
15679    case dx.LayoutBreakPointBuilderBase: return OneLineLayoutBreakPointBuilder;
15680    case dx.LayoutBlockGroupCollection: return OneLineLayoutBlockGroupCollection;
15681    case dx.LayoutBlockGroup: return OneLineLayoutBlockGroup;
15682    case dx.LayoutBlock: return OneLineLayoutBlock;
15683   }
15684   return t;
15685  },
15686  getGroupElements: function(groupsContainer) { return ASPx.GetChildElementNodes(groupsContainer); },
15687  canMarkGroupElements: function() { throw new Error("implement"); },
15688  canMarkItemElements: function() { throw new Error("implement"); },
15689  needPrevStateCssClasses: function() { throw new Error("implement"); }
15690 });
15691 dx.OneLineLayoutBreakpointsBuilder = ASPx.CreateClass(dx.OneLineLayoutBreakpointsBuilderBase, {
15692  canMarkGroupElements: function() { return true; },
15693  canMarkItemElements: function() { return true; },
15694  needPrevStateCssClasses: function() { return true; },
15695  createBlockGroups: function() {
15696   dx.OneLineLayoutBreakpointsBuilderBase.prototype.createBlockGroups.call(this, ".dxbs-r-card-group > .dxbs-toolbar", ".dxbs-r-grp, .dxbs-r-grp-gallery", function(blockGroups) {
15697    blockGroups.defineState("item", function(state) {
15698     state.for(":not(.dxbs-r-ab)").setWidth();
15699     state.for(".dxbs-r-ab:not(.dxbs-r-atb)").setHidden();
15700     state.for(".dxbs-r-atb").setOnlyImageWidth();
15701    });
15702    blockGroups.defineState("item-text-h", function(state) {
15703     state.for(":not(.dxbs-r-ab):not(.gallery-item)").setNoTextWidth();
15704     state.for(".gallery-item").setWidth();
15705     state.for(".dxbs-r-ab:not(.dxbs-r-atb)").setHidden();
15706     state.for(".dxbs-r-atb").setOnlyImageWidth();
15707    });
15708    blockGroups.defineState("item-h", function(state) {
15709     state.for(":only-child:not(.dxbs-r-ab)").setWidth();
15710     state.for(":not(:only-child):not(.dxbs-r-ab)").setHidden();
15711     state.for(".dxbs-r-ab").setWidth();
15712    });
15713    blockGroups.defineState("item-a", function(state) {
15714     state.for(":only-child:not(.dxbs-r-ab)").setNoTextWidth();
15715     state.for(":not(:only-child):not(.dxbs-r-ab)").setHidden();
15716     state.for(".dxbs-r-ab").setNoTextWidth();
15717    });
15718   });
15719  },
15720  calculateContainerOffsets: function() {
15721   var result = this.getBoxInnerOffset(this.container);
15722   var offsetEl = this.container.querySelector(".dxbs-r-card-group.active > .dxbs-toolbar");
15723   while(offsetEl != this.container) {
15724    result += this.getBoxOffset(offsetEl);
15725    offsetEl = offsetEl.parentNode;
15726   }
15727   return result;
15728  }
15729 });
15730})(dx || (dx = {}));
15731(function(dx) {
15732 var ITEM_IMAGE_CLASS = "image";
15733 var SCROLL_CONTAINER_SELECTOR = ".dxbs-tabs-scrollable";
15734 var BootstrapTabControlRenderHelper = ASPx.CreateClass(ASPx.TabControlRenderHelper, {
15735  constructor: function(tabControl) {
15736   this.constructor.prototype.constructor.call(this, tabControl);
15737  },
15738  InitializeControlElements: function () {
15739   ASPx.TabControlRenderHelper.prototype.InitializeControlElements.call(this);
15740   if(this.tabControl.IsStateControllerEnabled())
15741    this.InitializeStateControllerItems();
15742  },
15743  InitializeStateControllerItems: function() {
15744   var tabPostFixes = ASPx.BootstrapCore.IsBootstrap3 ? [''] : ['', 'T'];
15745   var tabDisabledStyles = ASPx.BootstrapCore.IsBootstrap3 ? ['disabled'] : ['', 'disabled'];
15746   var tabSuffixes = [];
15747   var tabs = this.tabControl.tabs;
15748   for(var i = 0; i < tabs.length; i++) {
15749    tabSuffixes.push("T" + i);
15750    tabSuffixes.push("AT" + i);
15751   }
15752   ASPx.BootstrapCore.AddStateItems(function() {
15753    ASPx.AddDisabledItems(this.tabControl.name, [[tabDisabledStyles, [''], tabSuffixes, tabPostFixes]], true);
15754   }.bind(this));
15755  },
15756  AssignTabActionToElement: function(element, eventName, action) {
15757   if(element && element.tagName !== "A")
15758    element = ASPx.GetNodeByTagName(element, "A");
15759   if(element) {
15760    ASPx.TabControlRenderHelper.prototype.AssignTabActionToElement.call(this, element, eventName, action);
15761    if(element.href === "") 
15762     element.href = ASPx.AccessibilityEmptyUrl;
15763   }
15764  },
15765  IsTabDisabled: function(tabElement) {
15766   var element = ASPx.BootstrapCore.IsBootstrap3 ? tabElement : this.GetTabLinkElement(tabElement);
15767   var isDisabled = element && ASPx.ElementContainsCssClass(element, ASPx.BootstrapCssSelectors.Disabled);
15768   if(!ASPx.BootstrapCore.IsBootstrap3 && element)
15769    isDisabled &= element.tabIndex === -1;
15770   return isDisabled;
15771  },
15772  GetTabStripElement: function(mainElement) {
15773   if(!mainElement) return;
15774   return ASPx.GetChildByClassName(mainElement, "nav-tabs") || this.GetTabStripElement(this.tabControl.findScrollContainer());
15775  },
15776  GetTabElements: function(container) {
15777   var self = this;
15778   return ASPx.GetChildNodes(container, function(el) { 
15779    var element = ASPx.BootstrapCore.IsBootstrap3 ? el : self.GetTabLinkElement(el);
15780    return el.tagName === "LI" && !ASPx.ElementHasCssClass(element || el, ASPx.BootstrapCssSelectors.Active); 
15781   });
15782  },
15783  GetActiveTabElements: function(container) {
15784   var self = this;
15785   return ASPx.GetChildNodes(container, function(el) { 
15786    var element = ASPx.BootstrapCore.IsBootstrap3 ? el : self.GetTabLinkElement(el);
15787    return el.tagName === "LI" && ASPx.ElementHasCssClass(element || el, ASPx.BootstrapCssSelectors.Active); 
15788   });
15789  },
15790  GetSpacerElements: function(container) {
15791   return [];
15792  },
15793  GetTabLinkElements: function(container) {
15794   return ASPx.GetNodesByTagName(container, "A");
15795  },
15796  GetTabImageElements: function(container) {
15797   return [];
15798  },
15799  GetTabLinkElement: function(tabElement) {
15800   return ASPx.GetChildByTagName(tabElement, "A");
15801  },
15802  GetContentContainerElement: function(mainElement) {
15803   return ASPx.GetChildByClassName(mainElement, "tab-content");
15804  },
15805  GetContentElements: function(container) {
15806   return ASPx.GetChildNodes(container, function (el) { return el.tagName === "DIV" && ASPx.ElementHasCssClass(el, "tab-pane"); });
15807  },
15808  GetTabIconCssClass: function(iconElement) {
15809   var regEx = new RegExp("(?:^|\\s)" + ITEM_IMAGE_CLASS + "(?!\\S)");
15810   return iconElement ? ASPx.Str.Trim(ASPx.GetClassName(iconElement).replace(regEx, "")) : "";
15811  },
15812  SetTabIconCssClass: function(iconElement, cssClass) {
15813   if(iconElement)
15814    ASPx.SetClassName(iconElement, ITEM_IMAGE_CLASS + (cssClass ? " " + cssClass : ""));
15815  },
15816  SetElementBadge: function(element, text, iconCssClass) {
15817   var badge = ASPx.BootstrapBadgeManager.findBadge(element);
15818   if(badge) {
15819    if(text != undefined)
15820     ASPx.BootstrapBadgeManager.setBadgeText(badge, text);
15821    if(iconCssClass != undefined)
15822     ASPx.BootstrapBadgeManager.setBadgeIconCssClass(badge, iconCssClass);
15823   }
15824   else
15825    element.appendChild(ASPx.BootstrapBadgeManager.createBadge(text, iconCssClass));
15826  }
15827 });
15828 function getContentFrameRect(el) {
15829  var styles = ASPx.GetCurrentStyle(el);
15830  var rect = el.getBoundingClientRect();
15831  return {
15832   left: rect.left + ASPx.PxToInt(styles.paddingLeft) + ASPx.PxToInt(styles.borderLeftWidth),
15833   right: rect.right - ASPx.PxToInt(styles.paddingRight) - ASPx.PxToInt(styles.borderRightWidth),
15834   top: rect.top + ASPx.PxToInt(styles.paddingTop) + ASPx.PxToInt(styles.borderTopWidth),
15835   bottom: rect.bottom - ASPx.PxToInt(styles.paddingBottom) - ASPx.PxToInt(styles.borderBottomWidth)
15836  };
15837 }
15838 function animateNonStyleProperty(durationSeconds, propertySetter, calcStepValue) {
15839  function animate(value) { ASPx.RequestAnimationFrame(function() { propertySetter(value); }); }
15840  var steps = [];
15841  for(var i = 99; i >= 0; i--) {
15842   var step = calcStepValue(i);
15843   if(step !== steps[steps.length - 1])
15844    steps.push(step);
15845  }
15846  var freq = durationSeconds * 1000 / steps.length;
15847  var intervalId = setInterval(function() {
15848   if(steps.length)
15849    animate(steps.shift());
15850   else
15851    clearInterval(intervalId);
15852  }, freq);
15853 }
15854 function scrollTabIntoView(currentTab, prevTab, nextTab) {
15855  function ease(v) { return 1 - Math.pow(1 - v, 4); }
15856  var list = currentTab.parentNode;
15857  var tabRect = currentTab.getBoundingClientRect();
15858  var listRect = getContentFrameRect(list);
15859  var leftOffset = prevTab ? prevTab.getBoundingClientRect().left : tabRect.left;
15860  var rightOffset = nextTab ? nextTab.getBoundingClientRect().right : tabRect.right;
15861  var delta = -Math.max(listRect.left - leftOffset, 0) - Math.min(0, listRect.right - rightOffset);
15862  var from = list.scrollLeft;
15863  if(delta !== from)
15864   animateNonStyleProperty(0.2, function(v) { list.scrollLeft = v; }, function(i) { return Math.round(from + delta + (1 - delta) * ease(i / 100)); });
15865 }
15866 function applyPositionClass(container, newTarget, className) {
15867  var oldTarget = container.querySelector("." + className);
15868  if(oldTarget)
15869   ASPx.RemoveClassNameFromElement(oldTarget, className);
15870  ASPx.AddClassNameToElement(newTarget, className);
15871 }
15872 ASPx.RegisterMixin("BSTabControl", function(baseClass) {
15873  return {
15874   constructor: function(name) {
15875    this.constructor.prototype.constructor.call(this, name);
15876    this.layoutBreakPoints = null;
15877    this.scrollContentWidth = -1;
15878    this.prevActiveTabIndex = -1;
15879   },
15880   isElementVisible: function(el) {
15881    return ASPx.GetElementDisplay(el);
15882   },
15883   CreateRenderHelper: function() {
15884    return new BootstrapTabControlRenderHelper(this);
15885   },
15886   GetTabLinkElement: function(index, active) {
15887    return ASPx.GetChildByTagName(this.GetTabElement(index, active), "A");
15888   },
15889   GetTabTextElement: function(index, active) {
15890    return ASPx.GetChildNodes(this.GetTabLinkElement(index, active),
15891     function(el) {
15892      return el.tagName === "SPAN" && !ASPx.ElementHasCssClass(el, "image");
15893     })[0];
15894   },
15895   GetTabImageElement: function(index, active) {
15896    return ASPx.GetChildByClassName(this.GetTabLinkElement(index, active), "image");
15897   },
15898   GetClientTabType: function() {
15899    return BootstrapClientTab;
15900   },
15901   ChangeTabLinkEnabledAttributes: function(link, enabled, method, styleMethod) {
15902    baseClass.prototype.ChangeTabLinkEnabledAttributes.call(this, link, enabled, method, styleMethod);
15903    if(!ASPx.BootstrapCore.IsBootstrap3) {
15904     var action = enabled ? ASPx.Attr.RemoveAttribute : ASPx.Attr.SetAttribute;
15905     action(link, "tabIndex", "-1");
15906    }
15907   },
15908   DoSafeScrollPositionOperation: function(func) {
15909    func();
15910   },
15911   SetActiveTabIndexInternal: function(index, hasLink) {
15912    baseClass.prototype.SetActiveTabIndexInternal.call(this, index, hasLink);
15913    this.updateTabPositionClasses(index);
15914   },
15915   updateTabPositionClasses: function(index) {
15916    var container = this.GetTabsCell();
15917    if(!container)
15918     return;
15919    var currentTab = this.GetVisibleTabElement(index);
15920    var prevTab = this.GetVisibleTabElement(index - 1);
15921    var nextTab = this.GetVisibleTabElement(index + 1);
15922    ASPx.DOM.ChangeDOM(function() {
15923     applyPositionClass(container, currentTab, "dxbs-tab-current");
15924     applyPositionClass(container, prevTab, "dxbs-tab-prev");
15925     applyPositionClass(container, nextTab, "dxbs-tab-next");
15926    });
15927   },
15928   InlineInitialize: function() {
15929    baseClass.prototype.InlineInitialize.call(this);
15930    if(this.findScrollContainer())
15931     dx.LayoutBreakpointsBuilder.registerControl(this);
15932   },
15933   Initialize: function() {
15934    baseClass.prototype.Initialize.call(this);
15935    var scrollContainer = this.findScrollContainer();
15936    if(!scrollContainer)
15937     return;
15938    this.updateTabPositionClasses(this.GetActiveTabIndex());
15939    if(!ASPx.Browser.MobileUI) {
15940     ASPx.Evt.AttachEventToElement(this.GetTabsCell(), "scroll", this.updateOverflowState.aspxBind(this));
15941     ASPx.Evt.AttachEventToElement(this.getNextButton(), "click", this.scrollToNext.aspxBind(this));
15942     ASPx.Evt.AttachEventToElement(this.getPrevButton(), "click", this.scrollToPrev.aspxBind(this));
15943    }
15944    dx.LayoutBreakpointsBuilder.initializeLayout(this);
15945   },
15946   cancelLayoutStateAppearance: function() {
15947    ASPx.RemoveClassNameFromElement(this.findScrollContainer(), "dxbs-loaded");
15948   },
15949   applyLayoutStateAppearance: function() {
15950    this.layoutBreakPoints.initialize();
15951    ASPx.AddClassNameToElement(this.findScrollContainer(), "dxbs-loaded");
15952   },
15953   buildLayout: function() {
15954    this.layoutBreakPoints = this.layoutBreakPoints || this.createLayoutBreakPoints();
15955    var activeTabEl = ASPx.GetChildByTagName(this.GetVisibleTabElement(this.GetActiveTabIndex()), "A", 0);
15956    var activeTabElStyle = ASPx.GetCurrentStyle(activeTabEl);
15957    this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-tabs-scroll-btn.prev", "border-top-left-radius: " + activeTabElStyle.borderTopLeftRadius + "", null);
15958    this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-tabs-scroll-btn.next", "border-top-right-radius: " + activeTabElStyle.borderTopRightRadius + ";", null);
15959    this.layoutBreakPoints.registerCssRule(".dxbs-loaded .nav", "overflow-x: scroll;overflow-y: hidden;", this.findScrollContainer());
15960    this.layoutBreakPoints.createBlockGroups(SCROLL_CONTAINER_SELECTOR, SCROLL_CONTAINER_SELECTOR, function(blockGroupsCollection) {
15961     blockGroupsCollection.defineState("no-overflow", function(state) {
15962      state.for(SCROLL_CONTAINER_SELECTOR).fixTabsWidth();
15963     });
15964     blockGroupsCollection.defineState("has-overflow", function(state) {
15965      state.for(SCROLL_CONTAINER_SELECTOR)
15966       .setOverflow()
15967       .onEnterState(this.onEnterOverflowState.aspxBind(this))
15968       .onLeaveState(this.onLeaveOverflowState.aspxBind(this));
15969     }.aspxBind(this));
15970    }.aspxBind(this));
15971   },
15972   createLayoutBreakPoints: function() {
15973    return new dx.LayoutBreakpointsBuilder(this, RibbonToolbarBreakPointsBuilder);
15974   },
15975   getTabScrollOffsetElement: function() {
15976    return this.GetTabsCell();
15977   },
15978   getPrevButton: function() {
15979    return this.findScrollContainer().querySelector(".dxbs-tabs-scroll-btn.prev");
15980   },
15981   getNextButton: function() {
15982    return this.findScrollContainer().querySelector(".dxbs-tabs-scroll-btn.next");
15983   },
15984   finalizeChangeTabState: function() {
15985    this.scrollTabToView(this.GetActiveTabIndex());
15986   },
15987   onEnterOverflowState: function() {
15988    this.canTrackScroll = true;
15989    setTimeout(this.updateOverflowState.aspxBind(this));
15990   },
15991   onLeaveOverflowState: function() {
15992    this.canTrackScroll = false;
15993   },
15994   scrollToNext: function() {
15995    var indexTo = this.GetTabCount() - 1;
15996    var targetIndex = this.findExtremeTabItemIndex(0, indexTo);
15997    this.scrollTabToView(targetIndex);
15998   },
15999   scrollToPrev: function() {
16000    var indexFrom = this.GetTabCount() - 1;
16001    var targetIndex = this.findExtremeTabItemIndex(indexFrom, 0);
16002    this.scrollTabToView(targetIndex);
16003   },
16004   scrollTabToView: function(i) {
16005    if(i > -1 && !!this.GetTabsCell()) {
16006     var getVisibleSibling = function(el, getter) {
16007      return el && !this.isElementVisible(el) ? getVisibleSibling(getter(el), getter) : el;
16008     }.bind(this);
16009     var visibleTab = this.GetTabElement(i, false);
16010     if(!this.isElementVisible(visibleTab))
16011      visibleTab = this.GetTabElement(i, true);
16012     var nextTab = getVisibleSibling(visibleTab.nextElementSibling, function(el) { return el.nextElementSibling; });
16013     var prevTab = getVisibleSibling(visibleTab.previousElementSibling, function(el) { return el.previousElementSibling; });
16014     scrollTabIntoView(visibleTab, prevTab, nextTab);
16015    }
16016   },
16017   findExtremeTabItemIndex: function(from, to) {
16018    var step = (to - from) / Math.abs(to - from);
16019    var listRect = getContentFrameRect(this.GetTabsCell());
16020    var limit = to + step;
16021    for(; from !== limit; from += step) {
16022     var el = this.GetTabElement(from, false);
16023     if(this.isElementVisible(el) || this.isElementVisible(el = this.GetTabElement(from, true))) {
16024      var r = el.getBoundingClientRect();
16025      if((step == -1 && r.left < listRect.left) || (step == 1 && r.right > listRect.right))
16026       return from;
16027     }
16028    }
16029    return -1;
16030   },
16031   updateOverflowState: function(e) {
16032    if(!this.canTrackScroll)
16033     return;
16034    var el = this.findScrollContainer();
16035    var list = this.GetTabsCell();
16036    var scrollLeft = list.scrollLeft;
16037    var canScrollLeft = scrollLeft > 0;
16038    var canScrollRight = (list.scrollWidth - scrollLeft) !== list.clientWidth;
16039    var nextBtn = this.getNextButton();
16040    var prevBtn = this.getPrevButton();
16041    ASPx.DOM.ChangeDOM(function() {
16042     ASPx.ToggleClassNameToElement(el, "can-scroll-right", canScrollRight);
16043     ASPx.Attr.ToggleAttribute(nextBtn, "disabled", "", !canScrollRight);
16044     ASPx.ToggleClassNameToElement(el, "can-scroll-left", canScrollLeft);
16045     ASPx.Attr.ToggleAttribute(prevBtn, "disabled", "", !canScrollLeft);
16046    });
16047   },
16048   findScrollContainer: function() {
16049    if(this.scrollContainerElement === undefined) {
16050     var mainEl = this.GetMainElement();
16051     this.scrollContainerElement = ASPx.ElementMatchesSelector(mainEl, SCROLL_CONTAINER_SELECTOR) ? mainEl : mainEl.querySelector(SCROLL_CONTAINER_SELECTOR);
16052    }
16053    return this.scrollContainerElement;
16054   },
16055   InitializeTabControl: function() {
16056   },
16057   InitializeTabControlCore: function() {
16058   },
16059   InitializeTabControlInline: function() {
16060    this.InitializeEnabledAndVisible();
16061   },
16062   initializeLayoutManager: function() {
16063    this.layoutManager = new ASPx.LayoutManagerBase(this);
16064   },
16065   initializeTabHeightManager: function() {
16066    this.tabHeightManager = new ASPx.FakeTabHeightManager();
16067   },
16068   UpdateLayout: function() {
16069   },
16070   BrowserWindowResizeSubscriber: function() {
16071    return !!this.layoutBreakPoints;
16072   },
16073   OnBrowserWindowResize: function() {
16074    if(this.layoutBreakPoints)
16075     this.layoutBreakPoints.adjust();
16076   },
16077   AdjustTabControlSizeLite: function() {
16078   },
16079   AdjustPageContents: function() {
16080   },
16081   AdjustControlCore: function() {
16082    if(this.layoutBreakPoints)
16083     this.layoutBreakPoints.adjust();
16084   },
16085   adjustControlInternal: function() {
16086   },
16087   calculateSizes: function() {
16088   },
16089   CreateTabClickEventArgs: function(processOnServer, tab, htmlElement, htmlEvent) {
16090    return new BootstrapClientTabControlTabClickEventArgs(processOnServer, tab, htmlElement, htmlEvent);
16091   },
16092   CreateTabEventArgs: function(tab) {
16093    return new BootstrapClientTabControlTabEventArgs(tab);
16094   },
16095   CreateTabCancelEventArgs: function(processOnServer, tab) {
16096    return new BootstrapClientTabControlTabCancelEventArgs(processOnServer, tab);
16097   },
16098   GetTabIconCssClass: function(index, active) {
16099    return this.renderHelper.GetTabIconCssClass(this.GetTabImageElement(index, active));
16100   },
16101   SetTabIconCssClass: function(index, active, cssClass) {
16102    var iconElement = this.GetTabImageElement(index, active);
16103    if(iconElement)
16104     this.renderHelper.SetTabIconCssClass(iconElement, cssClass);
16105   },
16106   GetTabBadgeText: function(index) {
16107    return ASPx.BootstrapBadgeManager.getBadgeText(this.GetTabLinkElement(index, index == this.GetActiveTabIndex()));
16108   },
16109   SetTabBadgeText: function(index, text) {
16110    var badgeText = this.HtmlEncode(text);
16111    this.SetTabBadgeInternal(index, false, badgeText);
16112    this.SetTabBadgeInternal(index, true, badgeText);
16113   },
16114   GetTabBadgeIconCssClass: function(index) {
16115    return ASPx.BootstrapBadgeManager.getBadgeIconCssClass(this.GetTabLinkElement(index, index == this.GetActiveTabIndex()));
16116   },
16117   SetTabBadgeIconCssClass: function(index, cssClass) {
16118    this.SetTabBadgeInternal(index, false, undefined, cssClass);
16119    this.SetTabBadgeInternal(index, true, undefined, cssClass);
16120   },
16121   SetTabBadgeInternal: function(index, active, text, iconCssClass) {
16122    var tabLinkElement = this.GetTabLinkElement(index, active);
16123    this.renderHelper.SetElementBadge(tabLinkElement, text, iconCssClass);
16124   }
16125  };
16126 });
16127 var BootstrapClientTabControl = ASPx.CreateClass(ASPx.GetMixin("BSTabControl", ASPxClientTabControl), { });
16128 var BootstrapClientPageControl = ASPx.CreateClass(ASPx.GetMixin("BSTabControl", ASPxClientPageControl), {
16129  GetContentHolder: function (index) {
16130   return this.GetContentElement(index);
16131  },
16132  GetLoadingPanelElement: function(){
16133   return ASPx.BootstrapLoadingPanelManager.getLoadingPanel(this.name, this.loadingPanel);
16134  },
16135  GetLoadingDiv: function(){
16136   return ASPx.BootstrapLoadingPanelManager.getLoadingDiv(this.name, this.loadingPanel);
16137  }
16138 });
16139 var BootstrapClientTab = ASPx.CreateClass(ASPxClientTab, {
16140  constructor: function(tabControl, index, name) {
16141   this.constructor.prototype.constructor.call(this, tabControl, index, name);
16142  },
16143  GetBadgeText: function() {
16144   return this.tabControl.GetTabBadgeText(this.index);
16145  },
16146  SetBadgeText: function(text) {
16147   this.tabControl.SetTabBadgeText(this.index, text);
16148  },
16149  GetBadgeIconCssClass: function() {
16150   return this.tabControl.GetTabBadgeIconCssClass(this.index);
16151  },
16152  SetBadgeIconCssClass: function(cssClass) {
16153   this.tabControl.SetTabBadgeIconCssClass(this.index, cssClass);
16154  },
16155  GetIconCssClass: function(active) {
16156   return this.tabControl.GetTabIconCssClass(this.index, active);
16157  },
16158  SetIconCssClass: function(cssClass, active) {
16159   this.tabControl.SetTabIconCssClass(this.index, active, cssClass);
16160  },
16161  GetActiveIconCssClass: function() {
16162   return this.tabControl.GetTabIconCssClass(this.index, true);
16163  },
16164  SetActiveIconCssClass: function(cssClass) {
16165   this.tabControl.SetTabIconCssClass(this.index, true, cssClass);
16166  }
16167 });
16168 var BootstrapClientTabControlTabEventArgs = ASPx.CreateClass(ASPxClientTabControlTabEventArgs, {
16169  constructor: function(tab, htmlElement, htmlEvent) {
16170   this.constructor.prototype.constructor.call(this, tab, htmlElement, htmlEvent);
16171  }
16172 });
16173 var BootstrapClientTabControlTabCancelEventArgs = ASPx.CreateClass(ASPxClientTabControlTabCancelEventArgs, {
16174  constructor: function(processOnServer, tab) {
16175   this.constructor.prototype.constructor.call(this, processOnServer, tab);
16176  }
16177 });
16178 var BootstrapClientTabControlTabClickEventArgs = ASPx.CreateClass(BootstrapClientTabControlTabCancelEventArgs, {
16179  constructor: function(processOnServer, tab, htmlElement, htmlEvent) {
16180   this.constructor.prototype.constructor.call(this, processOnServer, tab);
16181   this.htmlElement = htmlElement;
16182   this.htmlEvent = htmlEvent;
16183  }
16184 });
16185 var BootstrapRibbonTabControlRenderHelper = ASPx.CreateClass(BootstrapTabControlRenderHelper, {
16186  GetTabStripElement: function(mainElement) { return mainElement.querySelector("." + ASPx.BootstrapCssSelectors.PanelHeadingTabs + ".nav"); },
16187  GetContentContainerElement: function(mainElement) {
16188   return ASPx.GetChildByClassName(mainElement, ASPx.BootstrapCssSelectors.PanelBody);
16189  },
16190  GetContentElements: function(container) {
16191   return container.querySelectorAll(".dxbs-r-card-group");
16192  }
16193 });
16194 var RibbonToolbarBreakPointsBuilder = ASPx.CreateClass(dx.LayoutBreakPointBuilderBase, {
16195  fixTabsWidth: function() {
16196   this.prepareBlockFunc = function(block) {
16197    var list = this.owner.control.GetTabsCell();
16198    var offset = ASPx.GetVerticalScrollBarWidth();
16199    var listStyle = ASPx.GetCurrentStyle(list);
16200    var parentStyle = ASPx.GetCurrentStyle(list.parentNode);
16201    this.registerCssRule(".nav:before", "border-bottom: " + listStyle.borderBottom + ";", list);
16202    this.registerCssRule(".nav > .nav-item > .nav-link:not(.active):after", "border-bottom: " + listStyle.borderBottom + ";", list);
16203    this.registerCssRule("", "margin-top: -" + offset + "px; transform: translateY(" + offset + "px); border-bottom: 0;", list);
16204    var marginBottom = -ASPx.PxToInt(parentStyle.paddingBottom);
16205    this.registerCssRule(" .dxbs-tabs-scroll-btn", "margin-bottom: " + marginBottom + "px;", list.parentNode);
16206    this.registerCssRule("", "margin-bottom: " + marginBottom + "px;", list);
16207    var minWidth = ASPx.GetLeftRightBordersAndPaddingsSummaryValue(list);
16208    var items = list.querySelectorAll("li");
16209    var itemSizes = [];
16210    var blockSize = { minWidth: 0, maxWidth: 0 };
16211    function updateBlockSize() {
16212     blockSize.minWidth = blockSize.maxWidth = itemSizes.filter(function(i) { return i.isActive; }).reduce(function(w, c) { return w + c.width; }, minWidth);
16213    }
16214    var visibleChangeCount = 0;
16215    function createItemSize(itemEl, itemWidth) {
16216     var itemSize = {
16217      width: itemWidth,
16218      isActive: block.owner.control.isElementVisible(itemEl)
16219     };
16220     itemEl.onVisibleChange = function(visible) {
16221      itemSize.isActive = visible;
16222      updateBlockSize();
16223      visibleChangeCount++;
16224      if(visibleChangeCount < 2)
16225       return;
16226      visibleChangeCount = 0;
16227      var lb = block.owner;
16228      lb.blockGroupsArray.forEach(function(g) { g.currentWidth = g.getWidth();});
16229      lb.adjust();
16230     };
16231     itemSizes.push(itemSize);
16232    }
16233    for(var i = 0; i < items.length; i++)
16234     createItemSize(items[i], this.getNodeWidth(items[i]));
16235    updateBlockSize();
16236    return [blockSize];
16237   };
16238   return this;
16239  },
16240  fixToolbarWidth: function() {
16241   this.prepareBlockFunc = function(block) {
16242    var width = ASPx.GetLeftRightBordersAndPaddingsSummaryValue(block.node) + ASPx.GetLeftRightMargins(block.node);
16243    var toolbarItems = ASPx.GetChildElementNodes(block.node);
16244    for(var i = 0; i < toolbarItems.length; i++) {
16245     var item = toolbarItems[i];
16246     width += ASPx.GetLeftRightMargins(item) + item.offsetWidth;
16247    }
16248    this.registerRangeCssRule("", width, width, block.node);
16249    return [{ minWidth: width, maxWidth: width }];
16250   };
16251   return this;
16252  },
16253  setOverflow: function() {
16254   this.prepareBlockFunc = function(block) {
16255    var minWidth = ASPx.GetLeftRightBordersAndPaddingsSummaryValue(block.node) + ASPx.GetLeftRightMargins(block.node);
16256    var toolbarItems = ASPx.GetChildElementNodes(block.node);
16257    var maxItemWidth = 0;
16258    for(var i = 0; i < toolbarItems.length; i++)
16259     maxItemWidth = Math.max(maxItemWidth, this.getNodeWidth(toolbarItems[i]));
16260    return [{ minWidth: minWidth + maxItemWidth, maxWidth: minWidth + maxItemWidth }];
16261   };
16262   return this;
16263  },
16264  hideItemsText: function() {
16265   this.prepareBlockFunc = function(block) {
16266    var width = ASPx.GetLeftRightBordersAndPaddingsSummaryValue(block.node) + ASPx.GetLeftRightMargins(block.node);
16267    var toolbarItems = ASPx.GetChildElementNodes(block.node);
16268    for(var i = 0; i < toolbarItems.length; i++) {
16269     var item = toolbarItems[i];
16270     width += ASPx.GetLeftRightMargins(item) + item.offsetWidth;
16271    }
16272    var texts = block.node.querySelectorAll(".btn > span:not(.image)");
16273    for(var i = 0; i < texts.length; i++)
16274     width -= texts[i].offsetWidth;
16275    this.registerRangeCssRule(".no-btn-text", width, width, block.node);
16276    return [{ minWidth: width, maxWidth: width }];
16277   };
16278   return this;
16279  }
16280 });
16281 var BootstrapClientRibbonPageControl = ASPx.CreateClass(BootstrapClientPageControl, {
16282  constructor: function () {
16283   this.constructor.prototype.constructor.apply(this, arguments);
16284   this.measureCardElement = null;
16285   this.measureFooterElement = null;
16286   this.measureBodyElement = null;
16287  },
16288  isElementVisible: function(el) {
16289   return !ASPx.ElementHasCssClass(el, ASPx.BootstrapCssSelectors.HiddenLayout);
16290  },
16291  SetElementDisplay: function(element, value) {
16292   ASPx.DOM.ChangeDOM(function() {
16293    ASPx.ToggleClassNameToElement(element, ASPx.BootstrapCssSelectors.HiddenLayout, !value);
16294   });
16295   if(element.onVisibleChange)
16296    element.onVisibleChange(value);
16297  },
16298  InlineInitialize: function() {
16299   BootstrapClientPageControl.prototype.InlineInitialize.call(this);
16300   var tabCount = this.GetTabCount();
16301   if(tabCount > 0) {
16302    var contentCell = this.GetContentsCell();
16303    var card = contentCell.querySelector(".dxbs-r-card-group > ." + ASPx.BootstrapCssSelectors.Panel + ":first-child");
16304    if(!card)
16305     return;
16306    this.measureCardElement = card.cloneNode(false);
16307    this.measureCardElement.id = "";
16308    ASPx.AddClassNameToElement(this.measureCardElement, "dxbs-r-hidden");
16309    this.measureBodyElement = document.createElement("DIV");
16310    ASPx.AddClassNamesToElement(this.measureBodyElement, [ASPx.BootstrapCssSelectors.PanelBody, "dxbs-r-gc"]);
16311    for (var i = 0; i < 3; i++) {
16312     var fakeEl = document.createElement("BUTTON");
16313     ASPx.AddClassNamesToElement(fakeEl, [ASPx.BootstrapCssSelectors.Button, ASPx.BootstrapCssSelectors.ButtonSecondary]);
16314     this.measureBodyElement.appendChild(fakeEl);
16315    }
16316    this.measureFooterElement = document.createElement("DIV");
16317    this.measureFooterElement.className = ASPx.BuildBSCssClass("PanelFooter");
16318    this.measureCardElement.appendChild(this.measureBodyElement);
16319    this.measureCardElement.appendChild(this.measureFooterElement);
16320    for(var i = 0; i < tabCount; i++) {
16321     var contentEl = this.GetContentElement(i);
16322     if(contentEl) {
16323      contentEl.appendChild(this.measureCardElement);
16324      break;
16325     }
16326    }
16327    if(!this.GetContentVisible())
16328     this.transformTabs(true);
16329   }
16330  },
16331  cancelLayoutStateAppearance: function() {
16332   BootstrapClientPageControl.prototype.cancelLayoutStateAppearance.call(this);
16333   if(this.measureCardElement)
16334    ASPx.SetElementDisplay(this.measureCardElement, true);
16335  },
16336  applyLayoutStateAppearance: function() {
16337   BootstrapClientPageControl.prototype.applyLayoutStateAppearance.call(this);
16338   ASPx.DOM.ChangeDOM(function() {
16339    if(this.measureCardElement)
16340     ASPx.SetElementDisplay(this.measureCardElement, false);
16341   }.bind(this));
16342  },
16343  buildLayout: function() {
16344   this.layoutBreakPoints = this.layoutBreakPoints || this.createLayoutBreakPoints();
16345   if(this.measureBodyElement) {
16346    var footerMaxHeight = Math.ceil(this.measureFooterElement.offsetHeight);
16347    var contentMaxHeight = Math.ceil(this.measureBodyElement.offsetHeight);
16348    var maxHeight = contentMaxHeight + footerMaxHeight + ASPx.GetTopBottomBordersAndPaddingsSummaryValue(this.measureCardElement);
16349    this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-r-collapse", "max-height: " + maxHeight + "px; height: " + maxHeight + "px;", null);
16350    this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-r-card-group", "max-height: " + maxHeight + "px; height: " + maxHeight + "px;", null);
16351    this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-r-gc", "height: " + contentMaxHeight + "px;", null);
16352    this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-ribbon-group > ." + ASPx.BootstrapCssSelectors.PanelFooter, "height: " + footerMaxHeight + "px;", null);
16353   } else {
16354    var contentsCell = this.GetContentsCell();
16355    this.layoutBreakPoints.registerCssRule("#" + contentsCell.id + "." + ASPx.BootstrapCssSelectors.PanelBody, "min-height: " + Math.ceil(contentsCell.offsetHeight) + "px;", null);
16356   }
16357   var activeTabEl = ASPx.GetChildByTagName(this.GetVisibleTabElement(this.GetActiveTabIndex()), "A", 0);
16358   var activeTabElStyle = ASPx.GetCurrentStyle(activeTabEl);
16359   this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-tabs-scroll-btn.prev", "border-top-left-radius: " + activeTabElStyle.borderTopLeftRadius + "", null);
16360   this.layoutBreakPoints.registerCssRule("#" + this.name + " .dxbs-tabs-scroll-btn.next", "border-top-right-radius: " + activeTabElStyle.borderTopRightRadius + ";", null);
16361   this.layoutBreakPoints.registerCssRule(".dxbs-loaded .nav", "overflow-x: scroll;overflow-y: hidden;", this.findScrollContainer());
16362   this.layoutBreakPoints.createBlockGroups(SCROLL_CONTAINER_SELECTOR, SCROLL_CONTAINER_SELECTOR, function(blockGroupsCollection) {
16363    blockGroupsCollection.defineState("no-overflow", function(state) {
16364     state.for("." + ASPx.BootstrapCssSelectors.PanelHeadingTabs + ".nav").fixTabsWidth();
16365     state.for("." + ASPx.BootstrapCssSelectors.PanelHeadingTabs + ".dxbs-r-toolbar").fixToolbarWidth();
16366    });
16367    blockGroupsCollection.defineState("has-overflow", function(state) {
16368     state.for("." + ASPx.BootstrapCssSelectors.PanelHeadingTabs + ".nav")
16369      .setOverflow()
16370      .onEnterState(this.onEnterOverflowState.aspxBind(this))
16371      .onLeaveState(this.onLeaveOverflowState.aspxBind(this));
16372    }.aspxBind(this));
16373    blockGroupsCollection.defineState("no-btn-text", function(state) {
16374     state.for("." + ASPx.BootstrapCssSelectors.PanelHeadingTabs + ".dxbs-r-toolbar").hideItemsText();
16375    }.aspxBind(this));
16376   }.aspxBind(this));
16377  },
16378  createLayoutBreakPoints: function() {
16379   return new dx.LayoutBreakpointsBuilder(this, RibbonToolbarBreakPointsBuilder);
16380  },
16381  getTabScrollOffsetElement: function() {
16382   return ASPx.GetParentByClassName(this.GetTabsCell(), ASPx.BuildBSCssClass("PanelHeading"));
16383  },
16384  CreateRenderHelper: function () { return new BootstrapRibbonTabControlRenderHelper(this); },
16385  GetContentVisible: function () {
16386   return !ASPx.ElementHasCssClass(this.GetContentsCell(), "dxbs-r-h");
16387  },
16388  SetContentVisible: function(visible, isContentPinned) {
16389   var el = this.GetContentsCell();
16390   ASPx.ToggleClassNameToElement(el, "dxbs-r-pin", isContentPinned);
16391   ASPx.ToggleClassNameToElement(el, "dxbs-r-h", !visible);
16392   this.transformTabs(!visible);
16393  },
16394  transformTabs: function (isCollapsed) {
16395   var nav = this.GetTabStripContainer();
16396   var navTabsCssClass = ASPx.BuildBSCssClass("nav-tabs");
16397   if (ASPx.ElementHasCssClass(nav, navTabsCssClass) === isCollapsed) {
16398    ASPx.ToggleClassNameToElement(nav, navTabsCssClass, !isCollapsed);
16399    ASPx.ToggleClassNameToElement(nav, ASPx.BuildBSCssClass("nav-pills"), isCollapsed);
16400    ASPx.ToggleClassNameToElement(ASPx.GetParentByClassName(nav, ASPx.BuildBSCssClass("PanelHeading")), ASPx.BuildBSCssClass("border-bottom-0"), isCollapsed);
16401    this.SetElementDisplay(this.GetTabElement(this.GetActiveTabIndex(), isCollapsed), false);
16402    this.SetElementDisplay(this.GetTabElement(this.GetActiveTabIndex(), !isCollapsed), true);
16403   }
16404  },
16405  setContentDisplay: function (element, visible) {
16406   ASPx.ToggleClassNameToElement(element, ASPx.BootstrapCssSelectors.Active, visible);
16407  },
16408  onActiveTabChangedTimeoutCore: function () { },
16409  DoChangeActiveTab: function(indexToShow) {
16410   var indexToHide = this.GetActiveTabIndex();
16411   var fromRight = indexToHide < indexToShow;
16412   var elToShow = this.GetContentElement(indexToShow);
16413   var elToHide = this.GetContentElement(indexToHide);
16414   this.updateShiftCssClasses(elToShow, elToHide, "from", fromRight);
16415   this.updateShiftCssClasses(elToHide, elToShow, "to", !fromRight);
16416   BootstrapClientPageControl.prototype.DoChangeActiveTab.call(this, indexToShow);
16417  },
16418  updateShiftCssClasses: function(el, nextEl, typeToUpdate, fromRight) {
16419   this.toggleSwitchClasses(el, "shift-" + typeToUpdate + "-left", !fromRight, nextEl);
16420   this.toggleSwitchClasses(el, "shift-" + typeToUpdate + "-right", fromRight, nextEl);
16421   var typeToRemove = typeToUpdate == "to" ? "from" : "to";
16422   this.toggleSwitchClasses(el, "shift-" + typeToRemove + "-left", false, nextEl);
16423   this.toggleSwitchClasses(el, "shift-" + typeToRemove + "-right", false, nextEl);
16424  },
16425  toggleSwitchClasses: function(el, cssClass, condition, nextEl) {
16426   var key = cssClass + "ElRef";
16427   if(this[key] && (this[key] !== el && this[key] !== nextEl))
16428    ASPx.RemoveClassNameFromElement(this[key], cssClass);
16429   this[key] = el;
16430   ASPx.ToggleClassNameToElement(el, cssClass, condition);
16431  },
16432  finalizeChangeTabState: function() {
16433   BootstrapClientPageControl.prototype.finalizeChangeTabState.call(this);
16434   var el = this.GetContentsCell();
16435   ASPx.ToggleClassNameToElement(el, "dxbs-r-tabchanging", false);
16436   void el.offsetWidth;
16437   ASPx.ToggleClassNameToElement(el, "dxbs-r-tabchanging", true);
16438  },
16439  needInvertedChange: function() { return false; },
16440  setContentElementVisible: function(contentElement, value, index) {
16441   ASPx.ToggleClassNameToElement(contentElement, ASPx.BootstrapCssSelectors.Active, value);
16442  }
16443 });
16444 dx.BootstrapClientRibbonPageControl = BootstrapClientRibbonPageControl;
16445 dx.BootstrapClientTabControl = BootstrapClientTabControl;
16446 dx.BootstrapClientPageControl = BootstrapClientPageControl;
16447 dx.BootstrapClientTab = BootstrapClientTab;
16448 dx.BootstrapClientTabControlTabEventArgs = BootstrapClientTabControlTabEventArgs;
16449 dx.BootstrapClientTabControlTabCancelEventArgs = BootstrapClientTabControlTabCancelEventArgs;
16450 dx.BootstrapClientTabControlTabClickEventArgs = BootstrapClientTabControlTabClickEventArgs;
16451})(dx || (dx = {}));
16452
16453(function() {
16454ASPx.currentDragHelper = null;
16455var currentCursorTargets = null;
16456var DragHelper = ASPx.CreateClass(null, {
16457 constructor: function(e, root, clone){
16458  if(ASPx.currentDragHelper != null) ASPx.currentDragHelper.cancelDrag();
16459  this.dragArea = 5;
16460  this.clickX = ASPx.Evt.GetEventX(e);
16461  this.clickY = ASPx.Evt.GetEventY(e);
16462  this.centerClone = false;
16463  this.cachedCloneWidth = -1;
16464  this.cachedCloneHeight = -1;
16465  this.cachedOriginalX = -1;
16466  this.cachedOriginalY = -1;
16467  this.canDrag = true; 
16468  if(typeof(root) == "string") 
16469   root = ASPx.GetParentByTagName(ASPx.Evt.GetEventSource(e), root);
16470  this.source = e ? ASPx.Evt.GetEventSource(e) : null;
16471  this.obj = root && root != null ? root : ASPx.Evt.GetEventSource(e);
16472  this.clone = clone;
16473  this.dragObj = null; 
16474  this.additionalObj = null;
16475  this.onDoClick = null;
16476  this.onEndDrag = null;
16477  this.onCancelDrag = null;
16478  this.onDragDivCreating = null;
16479  this.onDragDivCreated = null;
16480  this.onCloneCreating = null;
16481  this.onCloneCreated = null;
16482  this.dragDiv = null;
16483  ASPx.currentDragHelper = this;
16484  this.clearSelectionOnce = false;
16485  this.PreventContextMenuOnLongTap();
16486  ASPx.TouchUIHelper.startPreventingTouchMove();
16487 }, 
16488 drag: function(e) {
16489  if(!this.canDrag) return;
16490  ASPx.Selection.Clear();
16491  if(!this.isDragging()) {
16492   if(!this.isOutOfDragArea(e)) 
16493    return;
16494   this.startDragCore(e);
16495  }
16496  ASPx.Selection.SetElementSelectionEnabled(document.body, false);
16497  this.dragCore(e);
16498 },
16499 startDragCore: function(e) {  
16500  this.dragObj = this.clone != true ? this.obj : this.createClone(e);
16501 },
16502 dragCore: function(e) { 
16503  this.updateDragDivPosition(e);
16504 },
16505 endDrag: function(e) { 
16506  if(!this.isDragging() && !this.isOutOfDragArea(e)) {
16507   if(this.onDoClick)
16508    this.onDoClick(this, e);
16509  } else {
16510   if(this.onEndDrag)
16511    this.onEndDrag(this, e);
16512  }
16513  this.cancelDrag();
16514 },
16515 cancel: function(){
16516  this.cancelDrag();
16517 },
16518 cancelDrag: function() {
16519  ASPx.TouchUIHelper.stopPreventingTouchMove();
16520  if(this.dragDiv != null) {
16521   document.body.removeChild(this.dragDiv);
16522   this.dragDiv = null;
16523  }
16524  if(this.onCancelDrag)
16525   this.onCancelDrag(this);
16526  ASPx.currentDragHelper = null;
16527  ASPx.Selection.SetElementSelectionEnabled(document.body, true);
16528 },
16529 isDragging: function() {    
16530  return this.dragObj != null;
16531 },
16532 updateDragDivPosition: function(e) {
16533  if(this.centerClone) {
16534   this.dragDiv.style.left = ASPx.Evt.GetEventX(e) - this.cachedCloneWidth / 2 + "px";
16535   ASPx.SetAbsoluteY(this.dragDiv, ASPx.Evt.GetEventY(e) - this.cachedCloneHeight / 2);
16536  } else {
16537   this.dragDiv.style.left = this.cachedOriginalX + ASPx.Evt.GetEventX(e) - this.clickX + "px";
16538   ASPx.SetAbsoluteY(this.dragDiv, this.cachedOriginalY + ASPx.Evt.GetEventY(e) - this.clickY);
16539  }
16540 },
16541 createClone: function(e) {
16542  this.dragDiv = document.createElement("div");
16543  if(this.onDragDivCreating)
16544   this.onDragDivCreating(this, this.dragDiv);
16545  var clone = this.creatingClone();  
16546  this.dragDiv.appendChild(clone);
16547  document.body.appendChild(this.dragDiv);
16548  this.dragDiv.style.position = "absolute";
16549  this.dragDiv.style.top = "0";
16550  this.dragDiv.style.left = "0";
16551  this.dragDiv.style.cursor = "move";
16552  this.dragDiv.style.borderStyle = "none";
16553  this.dragDiv.style.padding = "0";
16554  this.dragDiv.style.margin = "0";
16555  this.dragDiv.style.backgroundColor = "transparent";
16556  this.dragDiv.style.zIndex = 20000; 
16557  if(this.onCloneCreated)
16558   this.onCloneCreated(clone);
16559  this.cachedCloneWidth = clone.offsetWidth;
16560  this.cachedCloneHeight = clone.offsetHeight;
16561  if(!this.centerClone) {  
16562   this.cachedOriginalX = ASPx.GetAbsoluteX(this.obj);
16563   this.cachedOriginalY = ASPx.GetAbsoluteY(this.obj);
16564  }
16565  this.dragDiv.style.width = this.cachedCloneWidth + "px";
16566  this.dragDiv.style.height = this.cachedCloneHeight + "px";
16567  if(this.onDragDivCreated)
16568   this.onDragDivCreated(this, this.dragDiv);
16569  this.updateDragDivPosition(e);
16570  return this.dragDiv;
16571 },
16572 creatingClone: function() {
16573  var clone = this.obj.cloneNode(true);
16574  var scripts = ASPx.GetNodesByTagName(clone, "SCRIPT");
16575  for(var i = scripts.length - 1; i >= 0; i--)
16576   ASPx.RemoveElement(scripts[i]);
16577  ASPx.RippleHelper.RemoveRippleContainer(clone);
16578  if(!this.onCloneCreating) return clone;
16579  return this.onCloneCreating(clone);
16580 },
16581 addElementToDragDiv: function(element) {
16582  if(this.dragDiv == null) return;
16583  this.additionalObj = element.cloneNode(true);
16584  this.additionalObj.style.visibility = "visible";
16585  this.additionalObj.style.display = "";
16586  this.additionalObj.style.top = "";
16587  this.dragDiv.appendChild(this.additionalObj);
16588 },
16589 removeElementFromDragDiv: function() {
16590  if(this.additionalObj == null || this.dragDiv == null) return;
16591  this.dragDiv.removeChild(this.additionalObj);
16592  this.additionalObj = null;
16593 },
16594 isOutOfDragArea: function(e) {
16595  return Math.max(
16596   Math.abs(ASPx.Evt.GetEventX(e) - this.clickX), 
16597   Math.abs(ASPx.Evt.GetEventY(e) - this.clickY)
16598  ) >= this.dragArea;
16599 },
16600 PreventContextMenuOnLongTap: function() {
16601  if(!ASPx.DragUtils.RequirePreventContextMenuOnLongTap(this.obj))
16602   return;
16603  this.contextMenuHandler = function(e) {
16604   ASPx.Evt.DetachEventFromElement(this.obj, "contextmenu", this.contextMenuHandler);
16605   ASPx.Evt.PreventEvent(e);
16606  }.bind(this);
16607  ASPx.Evt.AttachEventToElement(this.obj, "contextmenu", this.contextMenuHandler);
16608 }
16609});
16610var DragUtils = {
16611 PreventContextMenuOnLongTapMarker: "dxPCM",
16612 RequirePreventContextMenuOnLongTap: function(element) {
16613  return element && ASPx.ElementHasCssClass(element, this.PreventContextMenuOnLongTapMarker);
16614 },
16615 PreventContextMenuOnLongTap: function(element) {
16616  if(element && ASPx.Browser.Edge && ASPx.Browser.MSTouchUI) {
16617   ASPx.AddClassNameToElement(element, this.PreventContextMenuOnLongTapMarker);
16618  }
16619 }
16620};
16621var CursorTargetTag = { Right: 0, Left: 1, Top: 2, Bottom: 3 };
16622var CursorTargets = ASPx.CreateClass(null, {
16623 constructor: function(control) {
16624  this.control = control;
16625  this.list = [];
16626  this.oldtargetElement = null;
16627  this.oldtargetTag = CursorTargetTag.Right;
16628  this.targetElement = null;
16629  this.targetTag = CursorTargetTag.Right;
16630  this.x = 0;
16631  this.y = 0;
16632  this.onTargetCreated = null;
16633  this.onTargetChanging = null;
16634  this.onTargetChanged = null;
16635  this.onTargetAdding = null;
16636  this.onTargetAllowed = null;
16637  currentCursorTargets = this;
16638  this.treeLine = null;
16639  this.initialScrollOffsetInfo = this.GetParentElementsScrollOffsetInfo();
16640 },
16641 addElement: function(element) {
16642  if(!this.canAddElement(element)) return null;
16643  var target = new CursorTarget(element);
16644  if (this.onTargetCreated)
16645   this.onTargetCreated(this, target);
16646  this.list.push(target);
16647  return target;
16648 },
16649 removeElement: function(element) {
16650  for(var i = 0; i < this.list.length; i++) {
16651   if(this.list[i].element == element) {
16652    this.list.splice(i, 1);
16653    return;
16654   }
16655  }
16656 },
16657 addParentElement: function(parent, child) {
16658  var target = this.addElement(parent);
16659  if(target != null) {
16660   target.targetElement = child;
16661  }
16662  return target;
16663 },
16664 RegisterTargets: function(element, idPrefixArray) {
16665  this.addFunc = this.addElement;
16666  this.RegisterTargetsCore(element, idPrefixArray);
16667 },
16668 UnregisterTargets: function(element, idPrefixArray) {
16669  this.addFunc = this.removeElement;
16670  this.RegisterTargetsCore(element, idPrefixArray);
16671 },
16672 RegisterTargetsCore: function(element, idPrefixArray) {
16673  if(element == null) return;
16674  for(var i = 0; i < idPrefixArray.length; i++)
16675   this.RegisterTargetCore(element, idPrefixArray[i]);
16676 },
16677 RegisterTargetCore: function(element, idPrefix) {
16678  if(!ASPx.IsExists(element.id)) return;
16679  if(element.id.indexOf(idPrefix) > -1)
16680   this.addFunc(element);
16681  for(var i = 0; i < element.childNodes.length; i++)
16682   this.RegisterTargetCore(element.childNodes[i], idPrefix);
16683 },
16684 canAddElement: function(element) {
16685  if(element == null || !ASPx.GetElementDisplay(element))
16686   return false;
16687  for(var i = 0; i < this.list.length; i++) {
16688   if(this.list[i].targetElement == element) return false;
16689  }
16690  if(this.onTargetAdding != null && !this.onTargetAdding(this, element)) return false;
16691  return element.style.visibility != "hidden";
16692 },
16693 getTarget: function(x, y) {
16694  for(var i = 0; i < this.list.length; i++) {
16695   var record = this.list[i];
16696   if(record.contains(x, y)) {
16697    if(!this.onTargetAllowed || this.onTargetAllowed(record.targetElement, x, y))
16698     return record.targetElement;
16699   }
16700  }
16701  return null;
16702 },
16703 targetChanged: function(element, tag) {
16704  this.targetElement = element;
16705  this.targetTag = ASPx.IsExists(tag) ? tag : ASPx.CursorTargetTag.Right;
16706  if(this.onTargetChanging)
16707   this.onTargetChanging(this);
16708  if(this.oldtargetElement != this.targetElement || this.oldtargetTag != this.targetTag) {
16709   if(this.onTargetChanged)
16710    this.onTargetChanged(this);
16711   this.oldtargetElement = this.targetElement;
16712   this.oldtargetTag = this.targetTag;
16713  }
16714 },
16715 cancelChanging: function() {
16716  this.targetElement = this.oldtargetElement;
16717  this.targetTag = this.oldtargetTag;
16718 },
16719 refreshTargetTag: function(allowVerticalTags){
16720  this.targetTag = this.calculateTargetTag(allowVerticalTags);
16721 },
16722 calculateTargetTag: function(allowVerticalTags){
16723  if(allowVerticalTags && this.isCenterPartOfElement())
16724   return this.isTopPartOfElement() ? CursorTargetTag.Top : CursorTargetTag.Bottom;
16725  return this.isLeftPartOfElement() ? CursorTargetTag.Left : CursorTargetTag.Right;
16726 },
16727 isCenterPartOfElement: function(){
16728  if(!this.targetElement) return false;
16729  var coordinate = this.y - this.targetElementY();
16730  return coordinate < this.targetElement.offsetHeight / 3 || coordinate >  2 * this.targetElement.offsetHeight / 3;
16731 },
16732 isLeftPartOfElement: function() {
16733  if(!this.targetElement) return true;
16734  var left = this.x - this.targetElementX();
16735  return left < this.targetElement.offsetWidth / 2;
16736 },
16737 isTopPartOfElement: function() {
16738  if(!this.targetElement) return true;
16739  var top = this.y - this.targetElementY();
16740  return top < this.targetElement.offsetHeight / 2;
16741 },
16742 targetElementX: function() {
16743  return this.targetElement != null ? ASPx.GetAbsoluteX(this.targetElement) : 0;
16744 },
16745 targetElementY: function() {
16746  return this.targetElement != null ? ASPx.GetAbsoluteY(this.targetElement) : 0;
16747 },
16748 onmousemove: function(e) {
16749  this.doTargetChanged(e);
16750 },
16751 onmouseup: function(e) {
16752  this.doTargetChanged(e);
16753  currentCursorTargets = null;
16754 },
16755 doTargetChanged: function(e) {
16756  this.x = ASPx.Evt.GetEventX(e);
16757  this.y = ASPx.Evt.GetEventY(e);
16758  var coords = this.GetScrollOffsetCoordinates(this.x, this.y);
16759  this.targetChanged(this.getTarget(coords.x, coords.y), 0);
16760 },
16761 GetScrollOffsetCoordinates: function(x, y) {
16762  var scrollOffsetInfo = this.GetParentElementsScrollOffsetInfo();
16763  var dx = scrollOffsetInfo.left - this.initialScrollOffsetInfo.left;
16764  var dy = scrollOffsetInfo.top - this.initialScrollOffsetInfo.top;
16765  return {
16766   x : x + dx,
16767   y : y + dy
16768  };
16769 },
16770 GetParentElementsScrollOffsetInfo: function() {
16771  var result = { top : 0, left : 0 };
16772  var treeLine = this.GetScrollableElementsTreeLine();
16773  for(var i = 0; i < treeLine.length; i++) {
16774   result.top += treeLine[i].scrollTop;
16775   result.left += treeLine[i].scrollLeft;
16776  }
16777  return result;
16778 },
16779 GetScrollableElementsTreeLine: function() {
16780  if(!this.treeLine)
16781   this.treeLine = ASPx.GetElementTreeLine(this.control.GetMainElement().parentNode).filter(function(el) { 
16782    return ASPx.IsScrollableElement(el); 
16783   });
16784  return this.treeLine;
16785 }
16786});
16787var CursorTarget = ASPx.CreateClass(null, {
16788 constructor: function(element) {
16789  this.element = element;
16790  this.targetElement = element;
16791  this.UpdatePosition();
16792 },
16793 contains: function(x, y) {
16794  return x >= this.absoluteX && x <= this.absoluteX + this.GetElementWidth() &&
16795   y >= this.absoluteY && y <= this.absoluteY + this.GetElementHeight();
16796 },
16797 GetElementWidth: function() {
16798  return this.element.offsetWidth;
16799 },
16800 GetElementHeight: function() {
16801  return this.element.offsetHeight;
16802 },
16803 UpdatePosition: function() {
16804  this.absoluteX = ASPx.GetAbsoluteX(this.element);
16805  this.absoluteY = ASPx.GetAbsoluteY(this.element);
16806 }
16807});
16808if(ASPx.Browser.MSTouchUI)
16809 ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.pointerCancelEventName, function(e) {
16810  if(ASPx.currentDragHelper != null) {
16811   ASPx.currentDragHelper.cancel(e);
16812   return true;
16813  }
16814 });
16815ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseUpEventName, function(e) {
16816  if(ASPx.currentDragHelper != null) {
16817   ASPx.currentDragHelper.endDrag(e);
16818   return true;
16819  }
16820});
16821ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseMoveEventName, function(e) {
16822 if(ASPx.currentDragHelper != null && !(ASPx.Browser.WebKitTouchUI && ASPx.TouchUIHelper.isGesture)) {
16823  ASPx.currentDragHelper.drag(e);
16824  if(ASPx.TouchUIHelper.isTouchEvent(e) && ASPx.currentDragHelper.canDrag) {
16825   ASPx.Evt.PreventEvent(e);
16826   ASPx.TouchUIHelper.preventScrollOnEvent(e);
16827  }
16828  return true;
16829 }
16830});
16831ASPx.Evt.AttachEventToDocument("keydown", function(e) {
16832 if(!ASPx.currentDragHelper) return;
16833 if(e.keyCode == ASPx.Key.Esc)
16834  ASPx.currentDragHelper.cancelDrag();
16835 return true;
16836});
16837ASPx.Evt.AttachEventToDocument("keyup", function(e) {
16838 if (!ASPx.currentDragHelper) return;
16839 if(e.keyCode == ASPx.Key.Esc && ASPx.Browser.WebKitFamily)
16840  ASPx.currentDragHelper.cancelDrag();
16841 return true;
16842});
16843ASPx.Evt.AttachEventToDocument("selectstart", function(e) {
16844 var drag = ASPx.currentDragHelper;
16845 if(drag && (drag.canDrag || drag.clearSelectionOnce)) {
16846  ASPx.Selection.Clear();
16847  drag.clearSelectionOnce = false;
16848  ASPx.Evt.PreventEvent(e);
16849  return false;
16850 }
16851});
16852ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseUpEventName, function(e) { 
16853 if(currentCursorTargets != null) {
16854  currentCursorTargets.onmouseup(e);
16855  return true;
16856 }
16857});
16858ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseMoveEventName, function(e) {
16859 if(currentCursorTargets != null) {
16860  currentCursorTargets.onmousemove(e);
16861  return true;
16862 }
16863});
16864ASPx.DragHelper = DragHelper;
16865ASPx.CursorTargets = CursorTargets;
16866ASPx.CursorTarget = CursorTarget;
16867ASPx.CursorTargetTag = CursorTargetTag;
16868ASPx.DragUtils = DragUtils;
16869})();
16870
16871(function() {
16872var GridDragHelperBase = ASPx.CreateClass(null, {
16873 maxRepeatScrollTimeout : 30,
16874 updateTargetPositionTimeout: 50,
16875 scrollingStep: 1,
16876 constructor: function() {
16877  this.isHorzDrag = false;
16878  this.savedPositions = { };
16879  this.rect = null;
16880 },
16881 GetActiveTargets: function() { return [ ]; },
16882 GetScrollHelper: function() { return null; },
16883 GetExtraCellWidth: function() { return 0; },
16884 GetCustomizationWindowElement: function() { return null; },
16885 GetScrollableControl: function() { 
16886  var helper = this.GetScrollHelper();
16887  return this.isHorzDrag ? helper.GetHorzScrollableControl() : helper.GetVertScrollableControl();
16888 },
16889 OnDragCreated: function(isHorzDrag) {
16890  if(this.NeedScrollOnDrag(isHorzDrag))
16891   this.InitializeDragScrolling(isHorzDrag);
16892 },
16893 InitializeDragScrolling: function(isHorzDrag) {
16894  this.isHorzDrag = isHorzDrag;
16895  this.SaveControlDimensions();
16896  this.mouseMoveHandler = function(e) { this.OnMouseMove(e); }.aspxBind(this);
16897  ASPx.Evt.AttachEventToDocument("mousemove", this.mouseMoveHandler);
16898 },
16899 SaveControlDimensions: function() {
16900  var scrollableControl = this.GetScrollableControl();
16901  var visibility = ASPx.GetElementDisplay(scrollableControl);
16902  ASPx.SetElementDisplay(scrollableControl, true);
16903  var scrollDivX = ASPx.GetAbsoluteX(scrollableControl);
16904  var scrollDivY = ASPx.GetAbsoluteY(scrollableControl);
16905  var width = scrollableControl.offsetWidth;
16906  var height = scrollableControl.offsetHeight;
16907  ASPx.SetElementDisplay(scrollableControl, visibility);
16908  this.SaveControlDimensionsCore(scrollDivX, width, scrollDivY, height);
16909 },
16910 SaveControlDimensionsCore: function(scrollDivX, width, scrollDivY, height) {
16911  this.rect = { 
16912   left: scrollDivX, 
16913   right: scrollDivX + width - this.GetExtraCellWidth(),
16914   top: scrollDivY,
16915   bottom: scrollDivY + height
16916  };
16917 },
16918 NeedScrollOnDrag: function(isHorzDrag) {
16919  var helper = this.GetScrollHelper();
16920  if(!helper || (isHorzDrag && !helper.HasHorzScroll()) || !isHorzDrag && !helper.HasVertScroll())
16921   return false;
16922  return ASPx.Browser.Firefox || helper.HasVertScroll();
16923 },
16924 OnMouseMove: function(e) {
16925  var pos = this.isHorzDrag ? ASPx.Evt.GetEventX(e) : ASPx.Evt.GetEventY(e);
16926  if(pos === this.savedPositions[this.isHorzDrag])
16927   return;
16928  var line = { 
16929   start:  this.isHorzDrag ? this.rect.left  : this.rect.top,
16930   end: this.isHorzDrag ? this.rect.right : this.rect.bottom
16931  };
16932  var isLeft = pos < line.start;
16933  var diff = isLeft ? line.start - pos : pos - line.end;
16934  if(diff <= 0) {
16935   this.CancelScrolling();
16936   return;
16937  }
16938  this.repeatScrollTimeout = diff < this.maxRepeatScrollTimeout ? this.maxRepeatScrollTimeout - diff : 1;
16939  this.scrollInc = this.scrollingStep * (isLeft ? -1 : 1);
16940  this.savedPositions[this.isHorzDrag] = pos;
16941  this.StartScrolling(this.isHorzDrag);
16942 },
16943 StartScrolling: function() {
16944  if(this.scrollingProcessing)
16945   return;
16946  this.scrollingProcessing = true;
16947  this.scrollHandler = this.RepeatScrolling();
16948 },
16949 CancelDrag: function() {
16950  if(this.mouseMoveHandler)
16951   ASPx.Evt.DetachEventFromDocument("mousemove", this.mouseMoveHandler);
16952  this.CancelScrolling();
16953 },
16954 CancelScrolling: function() {
16955  this.scrollingProcessing = false;
16956  this.scrollHandler = ASPx.Timer.ClearTimer(this.scrollHandler);
16957 },
16958 RepeatScrolling: function() {
16959  var scrollableControl = this.GetScrollableControl();
16960  if(this.isHorzDrag)
16961   scrollableControl.scrollLeft += this.scrollInc;
16962  else
16963   scrollableControl.scrollTop += this.scrollInc;
16964  return window.setTimeout(function() { this.scrollHandler = this.RepeatScrolling(); }.aspxBind(this), this.repeatScrollTimeout);
16965 },
16966 UpdateTargetPositionPostponed: function() {
16967  if(!this.GetActiveTargets().length)
16968   return;
16969  this.updateTargetPositionTimerID = ASPx.Timer.ClearTimer(this.updateTargetPositionTimerID);
16970  this.updateTargetPositionTimerID = window.setTimeout(function() { this.UpdateTargetPosition(); }.aspxBind(this), this.updateTargetPositionTimeout);
16971 },
16972 UpdateTargetPosition: function() { 
16973  var targets = this.GetActiveTargets();
16974  for(var i = 0; i < targets.length; i++)
16975   targets[i].UpdatePosition();
16976 },
16977 OnHeaderTargetAllowed: function(targetElement, x, y) {
16978  if(!this.rect)
16979   return true;
16980  var custWin = this.GetCustomizationWindowElement();
16981  var inRect = x >= this.rect.left && x <= this.rect.right;
16982  return inRect || custWin === targetElement;
16983 },
16984 UpdateScrollableControlsOnDrag: function(src) {
16985  this.UpdateTargetPositionPostponed();
16986  var helper = this.GetScrollHelper();
16987  var contentScrollDiv = helper.GetScrollDiv(helper.GetContentTable());
16988  if(contentScrollDiv === src && helper.HasVertScroll()) {
16989   var scrollDivs = [ helper.GetScrollDiv(helper.GetHeaderTable()), helper.GetScrollDiv(helper.GetFooterTable()) ];
16990   for(var i = 0; i < scrollDivs.length; i++)
16991    if(scrollDivs[i])
16992     scrollDivs[i].scrollLeft = src.scrollLeft;
16993  }
16994 }
16995});
16996var BatchEditApi = ASPx.CreateClass(null, {
16997 constructor: function(owner) {
16998  this.owner = owner;
16999 },
17000 GetHelper: function() { return this.owner.GetBatchEditHelper(); },
17001 GetColumnIndex: function(column) {  },
17002 CreateControlCellInfo: function(key, column) { },
17003 SetCellValueCore: function(key, column, value, displayText, cancelCellHighlighting) {
17004  var helper = this.GetHelper();
17005  var columnIndex = this.GetColumnIndex(column);
17006  if(!helper || columnIndex === null) 
17007   return;
17008  if(!helper.IsValidRecord(key) || !helper.IsEditableColumn(columnIndex))
17009   return;
17010  if(helper.IsEditingCell(key, columnIndex))
17011   return;
17012  if(!ASPx.IsExists(displayText))
17013   displayText = helper.GetColumnDisplayTextByEditor(value, columnIndex);
17014  if(helper.IsCheckColumn(columnIndex))
17015   displayText = helper.GetCheckColumnDisplayText(value, columnIndex);
17016  if(helper.IsColorEditColumn(columnIndex))
17017   displayText = helper.GetColorEditColumnDisplayText(value, columnIndex);
17018  helper.SetCellValue(key, columnIndex, value, displayText, cancelCellHighlighting);
17019  helper.ResetCellValidationState(key, columnIndex);
17020  helper.UpdateSyncInput(); 
17021  helper.UpdateItem(key, [columnIndex], false, false, true);
17022  helper.UpdateCommandButtonsEnabled();
17023  helper.RemoveRecordErrorIfHasNoChanges(key);
17024 },
17025 GetColumnDisplayText: function(column, value) {
17026  var helper = this.GetHelper();
17027  var columnIndex = this.GetColumnIndex(column);
17028  if(!helper || columnIndex === null) 
17029   return;
17030  return helper.GetColumnDisplayTextByEditor(value, columnIndex);
17031 },
17032 GetCellValueCore: function(key, column, initial) {
17033  var helper = this.GetHelper();
17034  var columnIndex = this.GetColumnIndex(column);
17035  if(!helper || columnIndex === null) return;
17036  return helper.GetCellValue(key, columnIndex, initial);
17037 },
17038 GetCellTextContainerCore: function(key, column) {
17039  var helper = this.GetHelper();
17040  var columnIndex = this.GetColumnIndex(column);
17041  if(!helper || columnIndex === null) return;
17042  return helper.GetCellTextContainer(key, columnIndex);
17043 },
17044 HasChangesCore: function(key, column) {
17045  var helper = this.GetHelper();
17046  if(!helper) return false;
17047  var columnIndex = this.GetColumnIndex(column);
17048  return helper.HasChanges(key, columnIndex);
17049 },
17050 ResetChangesCore: function(key, columnIndex) {
17051  var helper = this.GetHelper();
17052  if(!helper) return;
17053  helper.ResetChanges(key, columnIndex);
17054  helper.UpdateCommandButtonsEnabled();
17055 },
17056 StartEditCore: function(key, columnIndex) {
17057  var helper = this.GetHelper();
17058  if(!helper) return;
17059  helper.StartEdit(key, columnIndex);
17060 },
17061 EndEdit: function() {
17062  var helper = this.GetHelper();
17063  if(!helper || helper.GetFocusHelper().lockUserEndEdit) 
17064   return;
17065  helper.EndEdit();
17066 },
17067 MoveFocusBackward: function() {
17068  var helper = this.GetHelper();
17069  if(!helper) return;
17070  return helper.GetFocusHelper().MoveFocusPrev();
17071 },
17072 MoveFocusForward: function() {
17073  var helper = this.GetHelper();
17074  if(!helper) return;
17075  return helper.GetFocusHelper().MoveFocusNext();
17076 },
17077 IsColumnEdited: function(column) {
17078  var helper = this.GetHelper();
17079  if(!helper || !column) return false;
17080  return helper.IsColumnEdited(this.GetColumIndex(column));
17081 },
17082 ValidateItems: function(validateOnlyModified, validateOnCurrentPageOnly) {
17083  var helper = this.GetHelper();
17084  if(!helper) return false;
17085  return !!helper.UserValidateItems(null, validateOnlyModified, validateOnCurrentPageOnly).isValid;
17086 },
17087 ValidateRecordCore: function(key) {
17088  var helper = this.GetHelper();
17089  if(!helper) return false;
17090  return !!helper.UserValidateItems(key).isValid;
17091 }, 
17092 IsDeletedRecordCore: function(key) {
17093  var helper = this.GetHelper();
17094  return helper ? helper.IsDeletedRecord(key) : false;
17095 },
17096 IsNewRecordCore: function(key) {
17097  var helper = this.GetHelper();
17098  if(!helper) return false;
17099  return helper.IsNewRecord(key);
17100 },
17101 GetEditCellInfo: function() {
17102  var helper = this.GetHelper();
17103  if(!helper || !helper.IsEditing()) 
17104   return null;
17105  var column = helper.GetFocusedColumn();  
17106  if(column && !helper.IsColumnEditing(column.index))
17107   column = null;
17108  return this.CreateControlCellInfo(helper.GetEditingRecordKey(), column);
17109 },
17110 AddNewRecordCore: function(parentRecordKey) {
17111  var helper = this.GetHelper();
17112  if(helper)
17113   helper.AddNewRecord(parentRecordKey);
17114 },
17115 DeleteRecordCore: function(key) {
17116  var helper = this.GetHelper();
17117  if(helper)
17118   helper.DeleteItem(key);
17119 },
17120 RecoverRecordCore: function(key) {
17121  var helper = this.GetHelper();
17122  if(helper)
17123   helper.RecoverRecord(key);
17124 },
17125 GetRecordKeys: function(includeDeleted) {
17126  var helper = this.GetHelper();
17127  if(!helper) return [ ];
17128  return helper.GetRecordKeys(!includeDeleted);
17129 },
17130 GetInsertedRecordKeys: function() {
17131  var helper = this.GetHelper();
17132  if(!helper) return [ ];
17133  var indices = helper.GetInsertedRecordKeys();
17134  if(helper.IsNewItemOnTop())
17135   indices.reverse();
17136  return indices;
17137 },
17138 GetDeletedRecordKeys: function() {
17139  var helper = this.GetHelper();
17140  if(!helper) return [ ];
17141  return helper.deletedItemKeys.slice();
17142 },
17143 GetUpdatedRecordKeys: function() {
17144  var helper = this.GetHelper();
17145  if(!helper) return [ ];
17146  return ASPx.GetObjectKeys(helper.updatedValues);
17147 },
17148 GetUnsavedChanges: function() {
17149  var helper = this.GetHelper();
17150  if(!helper) return { };
17151  return helper.GetChangedValuesInfo();
17152 }
17153});
17154var GridStyleHelperBase = ASPx.CreateClass(null, {
17155 ClearItemStyleKey: "items",
17156 ErrorItemHtmlKey: "ei",
17157 BatchEditCellKey: "bec",
17158 BatchEditModifiedCellKey: "bemc",
17159 BatchEditMergedModifiedCellKey: "bemergmc",
17160 BatchEditDeletedItemKey: "bedi",
17161 FocusedCellKey: "fc",
17162 SelectedCellKey: "sc",
17163 InitCellStyleKey: "initial",
17164 AppliedBatchEditCellStylKey: "batchEdit",
17165 AppliedFocusedCellStyleKey: "focused",
17166 AppliedSelectedCellStyleKey: "selected",
17167 GetStyles: function() { return null; },
17168 GetStyleInfo: function(styleKey, columnIndex) {
17169  var info = this.GetStyleInfoCore(styleKey, columnIndex);
17170  if(info)
17171   info.styleKey = styleKey;
17172  return info;
17173 },
17174 GetStyleInfoCore: function(styleKey, keyPostFix) {
17175  var styles = this.GetStyles();
17176  if(!styles)
17177   return null;
17178  if(ASPx.IsExists(keyPostFix)) {
17179   var key = styleKey + keyPostFix;
17180   if(styles.hasOwnProperty(key))
17181    return styles[key];
17182  }
17183  return styles[styleKey];
17184 },
17185 GetCellStyleKeys: function() {
17186  var result = [];
17187  result.push(this.AppliedBatchEditCellStylKey);
17188  result.push(this.AppliedFocusedCellStyleKey);
17189  result.push(this.AppliedSelectedCellStyleKey);
17190  return result;
17191 },
17192 UpdateCellBatchEditStyle: function(style, cell) { this.UpdateCellStyle(this.AppliedBatchEditCellStylKey, style, cell); },
17193 UpdateCellFocusedStyle: function(style, cell) { this.UpdateCellStyle(this.AppliedFocusedCellStyleKey, style, cell); },
17194 UpdateCellSelectedStyle: function(style, cell) { this.UpdateCellStyle(this.AppliedSelectedCellStyleKey, style, cell); },
17195 UpdateCellStyle: function(styleKey, style, cell) {
17196  if(!cell) return;
17197  this.EnsureCellStyles(cell);
17198  cell.appliedStyles[styleKey] = this.GetCellStyleToApply(style);
17199  this.ApplyCellStyles(cell);
17200 },
17201 EnsureCellStyles: function(cell) {
17202  if(cell.appliedStyles)
17203   return;
17204  cell.appliedStyles = { }; 
17205  cell.appliedStyles[this.InitCellStyleKey] = this.CreateEmptyCellStyle(cell.className, cell.style.cssText);
17206  var keys = this.GetCellStyleKeys();
17207  for(var i = 0; i < keys.length; i++)
17208   cell.appliedStyles[keys[i]] = this.CreateEmptyCellStyle();
17209 },
17210 CreateEmptyCellStyle: function(className, cssText) {  
17211  className = className || "";
17212  cssText = cssText || "";
17213  return { className: className, cssText: cssText};
17214 },
17215 GetCellStyleToApply: function(style) {
17216  var result = this.CreateEmptyCellStyle();
17217  if(style) {
17218   result.className = style.className || "";
17219   result.cssText = style.cssText || "";
17220  }
17221  return result;
17222 },
17223 ApplyCellStyles: function(cell) {
17224  var className = "";
17225  var cssText = "";
17226  for(var key in cell.appliedStyles) {
17227   if(!cell.appliedStyles.hasOwnProperty(key)) continue;
17228   var style = cell.appliedStyles[key];
17229   if(!style) continue;
17230   if(style.className)
17231    className += " " + style.className;
17232   if(style.cssText)
17233    cssText += ";" + style.cssText;
17234  }
17235  cell.className = className;
17236  cell.style.cssText = cssText;
17237 },
17238 AddToBatchEditStyle: function(cell, styles, classNames) { this.AddToCellStyleCore(cell, this.Ap
17238pliedBatchEditCellStylKey, styles, classNames); },
17239 AddToInitialStyle: function(cell, styles, classNames) { this.AddToCellStyleCore(cell, this.InitCellStyleKey, styles, classNames); },
17240 AddToCellStyleCore: function(cell, styleKey, styles, classNames) {
17241  if((!styles && !classNames) || !cell) return;
17242  this.EnsureCellStyles(cell);
17243  var style = cell.appliedStyles[styleKey];
17244  if(!style) return;
17245  if(classNames)
17246   style.className += " " + classNames.join(' ');
17247  if(styles) {
17248   var fakeCell = document.createElement("TD");
17249   fakeCell.style.cssText = style.cssText || "";
17250   for(var property in styles) {
17251    if(styles.hasOwnProperty(property)) {
17252     var value = styles[property];
17253     fakeCell.style[property] = value + (typeof (value) == "number" ? "px" : "");
17254    }
17255   }   
17256   style.cssText = fakeCell.style.cssText;
17257  }  
17258  this.ApplyCellStyles(cell);
17259 },
17260 ChangeCellInitialClass: function(cell, className, add, preventApply) {
17261  if(!cell || !cell.appliedStyles)
17262   return;
17263  var hasClass = cell.appliedStyles.initial.className.indexOf(className) > -1;
17264  if(hasClass && !add)
17265    cell.appliedStyles.initial.className =  cell.appliedStyles.initial.className.replace(className, "");
17266  if(!hasClass && add)
17267    cell.appliedStyles.initial.className += " " + className;
17268  if(!preventApply)
17269   this.ApplyCellStyles(cell);
17270 },
17271 GetEmptyCellStyle: function() { return this.CreateEmptyCellStyle(); },
17272 GetBatchEditCellStyle: function() { return this.GetStyleInfo(this.BatchEditCellKey); },
17273 GetBatchEditModifiedCellStyle: function(columnIndex) { return this.GetStyleInfo(this.BatchEditModifiedCellKey, columnIndex); },
17274 GetBatchEditMergedModifiedCellStyle: function() { return this.GetStyleInfo(this.BatchEditMergedModifiedCellKey); },
17275 GetFocusedCellStyle: function(style) { return this.GetStyleInfo(this.FocusedCellKey); },
17276 GetSelectedCellStyle: function(style) { return this.GetStyleInfo(this.SelectedCellKey); },
17277 IsBatchEditCellStyle: function(style) { return this.CheckStyleInfoByKey(style, this.BatchEditCellKey); },
17278 IsBatchEditModifiedCellStyle: function(style) { return this.CheckStyleInfoByKey(style, this.BatchEditModifiedCellKey); },
17279 IsBatchEditMergedModifiedCellStyle: function(style) { return this.CheckStyleInfoByKey(style, this.BatchEditMergedModifiedCellKey); },
17280 IsFocusedCellStyle: function(style) { return this.CheckStyleInfoByKey(style, this.FocusedCellKey); },
17281 GetClearItemStyle: function() { return this.GetStyleInfo(this.ClearItemStyleKey); },
17282 GetBatchEditDeletedItemStyle: function() { return this.GetStyleInfo(this.BatchEditDeletedItemKey); },
17283 IsClearItemStyle: function(style) { return this.CheckStyleInfoByKey(style, this.ClearItemStyleKey); },   
17284 IsBatchEditDeletedItemStyle: function(style) { return this.CheckStyleInfoByKey(style, this.BatchEditDeletedItemKey); },   
17285 CheckStyleInfoByKey: function(styleInfo, key) {
17286  if(!styleInfo)
17287   return false;
17288  return styleInfo.styleKey == key;
17289 },
17290 ApplyElementStyle: function(element, styleInfo, skipInitialStyle){
17291  if(!element) return;
17292  if(!skipInitialStyle) {
17293   if(!ASPx.IsExists(element.initialClassName))
17294    element.initialClassName = element.className;
17295   if(!ASPx.IsExists(element.initialCssText))
17296    element.initialCssText = element.style.cssText;
17297   element.className = element.initialClassName;
17298   element.style.cssText = element.initialCssText;
17299  }
17300  if(styleInfo) {
17301   element.className += " " + styleInfo.className;
17302   element.style.cssText += " " + styleInfo.cssText;
17303  }
17304 },
17305 AddClassToElement: function(element, className){
17306  if(!element) return;
17307  ASPx.AddClassNameToElement(element, className);
17308  this.ChangeElementInitialClass(element, className, true);
17309 },
17310 RemoveClassFromElement: function(element, className){
17311  if(!element) return;
17312  ASPx.RemoveClassNameFromElement(element, className);
17313  this.ChangeElementInitialClass(element, className);
17314 },
17315 ChangeElementInitialClass: function(element, className, add) {
17316  if(!element) return;
17317  if(!ASPx.IsExists(element.initialClassName))
17318   element.initialClassName = element.className;  
17319  var hasClass = element.initialClassName.indexOf(className) > -1;
17320  if(hasClass && !add)
17321    element.initialClassName =  element.initialClassName.replace(className, "");
17322  if(!hasClass && add)
17323    element.initialClassName += " " + className;
17324 },
17325 AddStyleToElementInitialCssText: function(element, style) {
17326  this.EnsureElementInitialCssTextFromServer(element);
17327  var fakeElement = document.createElement("DIV");
17328  for(var property in style) {
17329   if(!style.hasOwnProperty(property)) continue;
17330   var value = style[property];
17331   fakeElement.style[property] = value + (typeof (value) === "number" ? "px" : "");
17332  }  
17333  element.initialCssText = element.initialCssTextFromServer + ";" + fakeElement.style.cssText;
17334 },
17335 ResetElementInitialCssText: function(element) {
17336  if(element.initialCssTextFromServer)
17337   element.initialCssText = element.initialCssTextFromServer;
17338 },
17339 EnsureElementInitialCssTextFromServer: function(element) {
17340  if(!element.initialCssTextFromServer)
17341   element.initialCssTextFromServer = element.initialCssText;
17342 },
17343 GetErrorItemHtml: function() {
17344  var styles = this.GetStyles();
17345  if(!styles)
17346   return null;
17347  return styles[this.ErrorItemHtmlKey];
17348 }
17349});
17350var GridCommonUtils = {
17351 BacthEditLockFocusEventsTriggerTimeout: 50,
17352 NeedSaveActiveElement: function (control) { return ASPx.Browser.WindowsPhonePlatform && ASPx.Browser.Edge; },
17353 IsBatchEditMode: function (control) { return control.GetBatchEditHelper && !!control.GetBatchEditHelper(); },
17354 IsInput: function (element) {
17355  if (!element) return false;
17356  return element.tagName == "INPUT" || element.tagName == "TEXTAREA";
17357 },
17358 SaveActiveElement: function (control) {
17359  if (!this.NeedSaveActiveElement(control)) return;
17360  var activeElement = ASPx.GetActiveElement();
17361  var isBatchEditing = this.IsBatchEditMode(control);
17362  var isInput = this.IsInput(activeElement);
17363  if (!activeElement || !isInput && !isBatchEditing || !ASPx.GetIsParent(control.GetMainElement(), activeElement))
17364   return;
17365  control.activeElementSettings = { activeElement: activeElement };
17366  if (isInput)
17367   control.activeElementSettings.selInfo = ASPx.Selection.GetInfo(activeElement);
17368  if (isBatchEditing)
17369   this.LockBatchEditFocusEvents(control);
17370 },
17371 RestoreActiveElement: function (control) {
17372  var settings = control.activeElementSettings;
17373  if (!settings) return;
17374  var oldElement = settings.activeElement;
17375  if (ASPx.IsExistsElement(oldElement) && oldElement !== ASPx.GetActiveElement()) {
17376   oldElement.focus();
17377   if (settings.selInfo)
17378    ASPx.Selection.Set(oldElement, settings.selInfo.startPos, settings.selInfo.endPos);
17379  }
17380  delete control.activeElementSettings;
17381  this.UnLockBatchEditFocusEvents(control);
17382 },
17383 LockBatchEditFocusEvents: function (control) { control.BatchEditFocusEventsLocked = true; },
17384 UnLockBatchEditFocusEvents: function (control) {
17385  ASPx.Timer.ClearTimer(control.bacthEditLockFocusEventsTriggerID);
17386  if (control.BatchEditFocusEventsLocked)
17387   control.bacthEditLockFocusEventsTriggerID = window.setTimeout(function () { delete control.BatchEditFocusEventsLocked; }, this.BacthEditLockFocusEventsTriggerTimeout);
17388 },
17389 IsBatchEditFocusEventsLocked: function (control) { return !!control.BatchEditFocusEventsLocked; }
17390};
17391ASPx.GridDragHelperBase = GridDragHelperBase;
17392ASPx.BatchEditApi = BatchEditApi;
17393ASPx.GridStyleHelperBase = GridStyleHelperBase;
17394ASPx.GridCommonUtils = GridCommonUtils;
17395})();
17396
17397(function() {
17398var GridHeaderFilterMode = { List: 1, CheckedList: 2, DateRangePicker: 3, DateRangeCalendar: 4, NumericRangePicker: 5 };
17399var GridFilterHelper = ASPx.CreateClass(null, {
17400 constructor: function(grid) {
17401  this.grid = grid;
17402  this.activeElement = null;
17403  this.lockFilter = true;
17404  this.searchFilterTimer = -1;
17405  this.searchEditorInitialValue = undefined;
17406  this.savedSearchEditorValue_beforeCallback = undefined;
17407  this.searchEditorLastClientValue = undefined;
17408  this.searchEditorValueChangedOnCallbackWaiting = false;
17409  this.initialHeaderFilterPopupMinWidth = null;
17410  this.headerFilterPopupWithButtonPanelMinWidth = null;
17411  this.headerFilterPopupRelatedColumn = null;
17412  this.headerFilterPopupDimensions = { };
17413  this.headerFilterColumnIndicesToInitialize = [ ];
17414  this.initialHeaderFilterState = { };
17415  this.SearchEditorKeyDownHandler = this.OnSearchEditorKeyDown.bind(this);
17416  this.SearchEditorValueChangedHandler = this.OnSearchEditorValueChanged.bind(this);
17417  this.SearchEditorUserInputHandler = this.OnSearchEditorUserInput.bind(this);
17418  this.HeaderFilterPopup_PopUpHandler = this.OnHeaderFilterPopup_PopUp.bind(this);
17419  this.HeaderFilterPopup_CloseUpHandler = this.OnHeaderFilterPopup_CloseUp.bind(this);
17420  this.HeaderFilterPopup_ResizeHandler = this.OnHeaderFilterPopup_Resize.bind(this);
17421  ASPx.GetControlCollection().ControlsInitialized.AddHandler(this.OnControlsInitialized, this);
17422 },
17423 Reset: function() {
17424  this.initialHeaderFilterState = { };
17425 },
17426 IsFilterLocked: function() { return this.lockFilter; },
17427 LockFilter: function() { this.lockFilter = true; },
17428 UnlockFilter: function() { this.lockFilter = false; },
17429 GetActiveElement: function() { return this.activeElement; },
17430 ResetActiveElement: function() { this.activeElement = null; },
17431 IsValidInstance: function() { return this.grid.IsValidInstance(); },
17432 GetAllowSearchFilterTimer: function() { return this.grid.allowSearchFilterTimer; },
17433 GetSearchFilterDelay: function() { return this.grid.searchFilterDelay; },
17434 GetEnableAccessibility: function() { return this.grid.accessibilityCompliant; },
17435 ResolveColumnIndex: function(id) { return this.grid.getColumnIndex(id); },
17436 GetSearchEditor: function() { return this.grid.GetSearchEditor(); },
17437 GetCustomSearchPanelEditor: function() { return this.grid.GetCustomSearchPanelEditor(); },
17438 GetSearchPanelFilter: function() { return this.grid.searchPanelFilter; },
17439 ApplySearchPanelFilter: function(value) { this.grid.ApplySearchPanelFilter(value, true); },
17440 GetContentTable: function() { return this.grid.GetMainTable(); },
17441 OnInit: function() {
17442  this.LockFilter();
17443  window.setTimeout(function() { this.UnlockFilter(); }.bind(this), 0);
17444  this.EnsureSearchEditor();
17445  window.setTimeout(function() { this.SaveFilterEditorsState(); }.bind(this), 0);
17446  window.setTimeout(this.InitializeHeaderFilterPopup.bind(this), 0);
17447 },
17448 OnAfterCallback: function() {
17449  this.LockFilter();
17450  window.setTimeout(function() { this.UnlockFilter(); }.bind(this), 0);
17451  this.EnsureSearchEditor();
17452  window.setTimeout(function() { this.SaveFilterEditorsState(); }.bind(this), 0);
17453  window.setTimeout(this.InitializeHeaderFilterPopup.bind(this), 0);
17454 },
17455 OnBeforeCallback: function() {
17456  this.LockFilter();
17457  this.UnloadHeaderFilterPopup();
17458  var edit = this.GetSearchEditor();
17459  if(edit)
17460   this.savedSearchEditorValue_beforeCallback = this.GetEditorStringValue(edit);
17461 },
17462 OnCancelCallbackCore: function() {
17463  this.UnlockFilter();
17464  this.InitializeHeaderFilterPopup();
17465 },
17466 SaveFilterEditorsState: function() { },
17467 ClearFilterEditorsState: function() { },
17468 OnDispose: function() {
17469  ASPx.GetControlCollection().ControlsInitialized.RemoveHandler(this.OnControlsInitialized, this);
17470 },
17471 LoadSearchEditorValueOnCallback: function() {
17472  var edit = this.GetSearchEditor();
17473  if(edit) {
17474   var value = this.GetEditorStringValue(edit);
17475   this.searchEditorValueChangedOnCallbackWaiting = value !== this.savedSearchEditorValue_beforeCallback;
17476   this.searchEditorLastClientValue = value;
17477   this.savedSearchEditorValue_beforeCallback = undefined;
17478  }
17479 },
17480 SetSearchPanelCustomEditor: function(editor) {
17481  if(!ASPx.Ident.IsASPxClientEdit(editor) || !editor.GetMainElement())
17482   return;
17483  if(this.grid.customSearchPanelEditorID === editor.name)
17484   return;
17485  this.RemoveSearchEditorEvents(this.GetSearchEditor());
17486  this.grid.customSearchPanelEditorID = editor.name;
17487  this.EnsureSearchEditor();
17488 },
17489 AssignSearchEditorEvents: function(edit) {
17490  if(edit.dxgvFilterHelper === this)
17491   return;
17492  if(edit.KeyDown)
17493   edit.KeyDown.AddHandler(this.SearchEditorKeyDownHandler);
17494  if(edit.ValueChanged)
17495   edit.ValueChanged.AddHandler(this.SearchEditorValueChangedHandler);
17496  if(edit.UserInput)
17497   edit.UserInput.AddHandler(this.SearchEditorUserInputHandler);
17498  edit.dxgvFilterHelper = this;
17499 },
17500 RemoveSearchEditorEvents: function(edit) {
17501  if(!edit || edit.dxgvFilterHelper !== this)
17502   return;
17503  if(edit.KeyDown)
17504   edit.KeyDown.RemoveHandler(this.SearchEditorKeyDownHandler);
17505  if(edit.ValueChanged)
17506   edit.ValueChanged.RemoveHandler(this.SearchEditorValueChangedHandler);
17507  if(edit.UserInput)
17508   edit.UserInput.RemoveHandler(this.SearchEditorUserInputHandler);
17509  delete edit.dxgvFilterHelper;
17510 },
17511 EnsureSearchEditor: function() {
17512  var edit = this.GetSearchEditor();
17513  if(!edit) return;
17514  this.AssignSearchEditorEvents(edit);
17515  var isCustomEditor = edit === this.GetCustomSearchPanelEditor();
17516  this.searchEditorInitialValue = isCustomEditor ? this.GetSearchPanelFilter() : this.GetEditorStringValue(edit);
17517  var applySearchValueOnCallback = this.searchEditorValueChangedOnCallbackWaiting && this.searchEditorInitialValue !== this.searchEditorLastClientValue;
17518  if(applySearchValueOnCallback) {
17519   window.setTimeout(function() {
17520    edit.SetValue(this.searchEditorLastClientValue);
17521    this.ApplySearchFilterFromEditor(edit);
17522   }.bind(this), 0);
17523  }  else {
17524   if(isCustomEditor)
17525    window.setTimeout(function() { edit.SetValue(this.GetSearchPanelFilter()); }.bind(this), 0);
17526  }
17527  this.searchEditorValueChangedOnCallbackWaiting = false;
17528 },
17529 GetEditorStringValue: function(edit) {
17530  var value = edit.GetValueString();
17531  return ASPx.IsExists(value) ? value : "";
17532 },
17533 OnSearchEditorKeyDown: function(s, e) {
17534  if(!e.htmlEvent || !this.IsValidInstance())
17535   return;
17536  e = e.htmlEvent;
17537  var clearEditor = e.keyCode == ASPx.Key.Delete && e.ctrlKey;
17538  if(e.keyCode == ASPx.Key.Enter || clearEditor) {
17539   if(clearEditor)
17540    s.SetValue(null);
17541   this.ApplySearchFilterFromEditor(s);
17542   ASPx.Evt.PreventEventAndBubble(e);
17543   return;
17544  }
17545  this.CreateSearchFilterTimer(s);
17546 },
17547 OnSearchEditorUserInput: function(s, e) {
17548  if(!this.IsValidInstance() || this.IsSearchFilterTimerActive())
17549   return;
17550  this.OnSearchEditorOnPaste(s);
17551 },
17552 OnSearchEditorOnPaste: function(editor) {
17553  this.EnsureEditorRawValue(editor);
17554  this.CreateSearchFilterTimer(editor);
17555 },
17556 OnSearchEditorValueChanged: function(s, e) {
17557  if(!this.IsValidInstance())
17558   return;
17559  window.setTimeout(function() { this.ApplySearchFilterFromEditor(s);  }.bind(this), 0);
17560 },
17561 IsSearchFilterTimerActive: function() {
17562  return this.searchFilterTimer !== -1;
17563 },
17564 CreateSearchFilterTimer: function(editor) {
17565  if(!this.GetAllowSearchFilterTimer()) return;
17566  this.ClearSearchFilterTimer();
17567  this.searchFilterTimer = window.setTimeout(function() { this.ApplySearchFilterFromEditor(editor);  }.bind(this), this.GetSearchFilterDelay());
17568 },
17569 ClearSearchFilterTimer: function() {
17570  this.searchFilterTimer = ASPx.Timer.ClearTimer(this.searchFilterTimer);
17571 },
17572 ApplySearchFilterFromEditor: function(edit) {
17573  this.ClearSearchFilterTimer();
17574  if(this.IsFilterLocked()) return;
17575  if(!edit || !this.GetContentTable())
17576   return;
17577  edit.Validate();
17578  if(!edit.GetIsValid()) 
17579   return;
17580  var value = this.GetEditorStringValue(edit);
17581  if(value === this.searchEditorInitialValue)
17582   return;
17583  this.SaveFilterEditorActiveElement(edit);
17584  this.ApplySearchPanelFilter(value);
17585 },
17586 EnsureEditorRawValue: function(edit) {
17587  if(ASPx.GetFocusedEditor() === edit && edit.SyncRawValueIfHasTextDecorators) {
17588   edit.SyncRawValueIfHasTextDecorators();
17589  }
17590 },
17591 SaveFilterEditorActiveElement: function(editor) {
17592  if(!editor) return;
17593  var columnIndex = this.ResolveColumnIndex(editor.name);
17594  if(columnIndex < 0 && editor !== this.GetSearchEditor())
17595   return;
17596  this.activeElement = this.GetFilterEditorInputElement(editor);
17597 },
17598 GetFilterEditorInputElement: function(editor) {
17599  if(document.activeElement && !ASPx.Browser.VirtualKeyboardSupported) 
17600   return document.activeElement;
17601  if(editor.GetInputElement) 
17602   return editor.GetInputElement();
17603  return null;
17604 },
17605 GetHeaderFilterPopup: function() { return this.grid.GetHeaderFilterPopup(); },
17606 GetEnableCallbackAnimation: function() { return this.grid.enableCallbackAnimation; },
17607 GetEnableHeaderFilterCaching: function() { return this.grid.enableHeaderFilterCaching; },
17608 GetHeaderFilterIconClassName: function() { return this.grid.HeaderFilterButtonClassName; }, 
17609 GetColumnHeaders: function(columnIndex) { return [ this.grid.GetHeader(columnIndex, false), this.grid.GetHeader(columnIndex, true) ]; },
17610 GetColumn: function(columnIndex) { return this.grid._getColumn(columnIndex); },
17611 GetColumnCount: function() { return this.grid.GetColumnsCount(); },
17612 ApplyHeaderFilter: function() { this.grid.ApplyHeaderFilterByColumn(); },
17613 GetCustomizationWindow: function() { return this.grid.GetCustomizationWindow(); },
17614 ShowLoadingPanelInsideHeaderFilterPopup: function() { this.grid.ShowLoadingPanelInsideHeaderFilterPopup(); },
17615 GetListBox: function(columnIndex) { 
17616  var listBox = ASPx.GetControlCollection().Get(this.grid.name + "_HFListBox" + columnIndex); 
17617  return listBox && !listBox.IsDOMDisposed() ? listBox : null;
17618 },
17619 GetSelectAllCheckBox: function(columnIndex) { 
17620  var checkBox = ASPx.GetControlCollection().Get(this.grid.name + "_HFSACheckBox" + columnIndex); 
17621  return checkBox && !checkBox.IsDOMDisposed() ? checkBox : null;
17622 },
17623 GetDateEdit_From: function(columnIndex) {
17624  var dateEdit = ASPx.GetControlCollection().Get(this.grid.name + "_HFFDE" + columnIndex); 
17625  return dateEdit && !dateEdit.IsDOMDisposed() ? dateEdit : null;
17626 },
17627 GetDateEdit_To: function(columnIndex) { 
17628  var dateEdit = ASPx.GetControlCollection().Get(this.grid.name + "_HFTDE" + columnIndex); 
17629  return dateEdit && !dateEdit.IsDOMDisposed() ? dateEdit : null;
17630 },
17631 GetCalendar: function(columnIndex){ 
17632  var calendar = ASPx.GetControlCollection().Get(this.grid.name + "_HFC" + columnIndex); 
17633  return calendar && !calendar.IsDOMDisposed() ? calendar: null;
17634 },
17635 GetSpinEdit_From: function(columnIndex) {
17636  var spinEdit = ASPx.GetControlCollection().Get(this.grid.name + "_HFFSE" + columnIndex);
17637  return spinEdit && !spinEdit.IsDOMDisposed() ? spinEdit : null;
17638 },
17639 GetSpinEdit_To: function(columnIndex) {
17640  var spinEdit = ASPx.GetControlCollection().Get(this.grid.name + "_HFTSE" + columnIndex);
17641  return spinEdit && !spinEdit.IsDOMDisposed() ? spinEdit : null;
17642 },
17643 GetRangeTrackBar: function(columnIndex) {
17644  var rangeTrackBar = ASPx.GetControlCollection().Get(this.grid.name + "_HFTB" + columnIndex);
17645  return rangeTrackBar && !rangeTrackBar.IsDOMDisposed() ? rangeTrackBar : null;
17646 },
17647 GetHeaderFilterPopupRelatedColumn: function() { return this.headerFilterPopupRelatedColumn; },
17648 GetHeaderFilterButton: function(isCancelButton) {
17649  var popup = this.GetHeaderFilterPopup();
17650  if(popup)
17651   return ASPx.GetControlCollection().Get(isCancelButton ? popup.cpCancelButtonID : popup.cpOkButtonID);
17652  return null;
17653 },
17654 SendHeaderFilterCallback: function(columnIndex, shiftKey) {
17655  this.grid.gridFuncCallBack([ ASPxClientGridViewCallbackCommand.FilterPopup, this.grid.name, columnIndex, shiftKey ? "T" : ""], this.OnHeaderFilterCallback);
17656 },
17657 OnHeaderFilterCallback: function(values) {
17658  var grid = ASPx.GetControlCollection().Get(values[0]);
17659  if(grid)
17660   grid.GetFilterHelper().ProcessHeaderFilterCallback(values[1], values[2]);
17661 },
17662 GetHeaderFilterState: function(columnIndex) {
17663  var listBoxSelectedIndices = [ ];
17664  var pickerRange = null;
17665  var calendarDates = null;
17666  var listBox = this.GetListBox(columnIndex);
17667  if(listBox)
17668   listBoxSelectedIndices = listBox.GetSelectedIndices();
17669  var column = this.GetColumn(columnIndex);
17670  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangePicker) {
17671   var dateEditFrom = this.GetDateEdit_From(columnIndex);
17672   var dateEditTo = this.GetDateEdit_To(columnIndex);
17673   if(dateEditFrom && dateEditTo)
17674    pickerRange = { start: dateEditFrom.GetValue(), end: dateEditTo.GetValue() };
17675  }
17676  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangeCalendar) {
17677   var calendar = this.GetCalendar(columnIndex);
17678   if(calendar)
17679    calendarDates = calendar.GetSelectedDates();
17680  }
17681  if(column.HFMode === ASPx.GridHeaderFilterMode.NumericRangePicker) {
17682   var rangeTrackBar = this.GetRangeTrackBar(columnIndex);
17683   if(rangeTrackBar)
17684    pickerRange = { start: rangeTrackBar.GetPositionStart(), end: rangeTrackBar.GetPositionEnd() };
17685   var spinEdit_From = this.GetSpinEdit_From(columnIndex);
17686   if(spinEdit_From) {
17687    if(pickerRange) pickerRange.start = spinEdit_From.GetValue();
17688    else pickerRange = { start: spinEdit_From.GetValue() };
17689   }
17690   var spinEdit_To = this.GetSpinEdit_To(columnIndex);
17691   if(spinEdit_To) {
17692    if(pickerRange) pickerRange.end = spinEdit_To.GetValue();
17693    else pickerRange = { end: spinEdit_To.GetValue() };
17694   }
17695  }
17696  return { listBoxSelectedIndices: listBoxSelectedIndices, pickerRange: pickerRange, calendarDates: calendarDates };
17697 },
17698 IsHeaderFilterChanged: function(columnIndex) {
17699  var initialState = this.initialHeaderFilterState[columnIndex];
17700  var currentState = this.GetHeaderFilterState(columnIndex);
17701  if(!initialState || !currentState)
17702   return false;
17703  if(!ASPx.Data.ArrayEqual(initialState.listBoxSelectedIndices, currentState.listBoxSelectedIndices))
17704   return true;
17705  var column = this.GetColumn(columnIndex);
17706  if((column.HFMode === ASPx.GridHeaderFilterMode.DateRangePicker || column.HFMode === ASPx.GridHeaderFilterMode.NumericRangePicker) && currentState.pickerRange)
17707   return initialState.pickerRange.start !== currentState.pickerRange.start || initialState.pickerRange.end !== currentState.pickerRange.end;
17708  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangeCalendar && currentState.calendarDates)
17709   return !ASPx.Data.ArrayEqual(initialState.calendarDates, currentState.calendarDates);
17710  return false;
17711 },
17712 GetHeaderFilterCallbackState: function(columnIndex) {
17713  var result = [ ];
17714  var listBox = this.GetListBox(columnIndex);
17715  if(listBox)
17716   result = result.concat(listBox.GetSelectedValues());
17717  var currentState = this.GetHeaderFilterState(columnIndex);
17718  if(currentState.calendarDates && currentState.calendarDates.length > 0)
17719   result.push("(Calendar)|" + this.CalcDateRanges(currentState.calendarDates, false).join("|"));
17720  if(currentState.pickerRange && (ASPx.IsExists(currentState.pickerRange.start) || ASPx.IsExists(currentState.pickerRange.end))) {
17721   var column = this.GetColumn(columnIndex);
17722   var pickerType;
17723   var range;
17724   if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangePicker) {
17725    pickerType = "(DateRangePicker)";
17726    range = [
17727     currentState.pickerRange.start && ASPx.DateUtils.GetInvariantDateString(currentState.pickerRange.start) || "",
17728     currentState.pickerRange.end   && ASPx.DateUtils.GetInvariantDateString(currentState.pickerRange.end) || ""
17729    ];
17730   }
17731   if(column.HFMode === ASPx.GridHeaderFilterMode.NumericRangePicker) {
17732    pickerType = "(NumericRangePicker)";
17733    var start = ASPx.IsExists(currentState.pickerRange.start) ? parseFloat(currentState.pickerRange.start) : NaN;
17734    var end = ASPx.IsExists(currentState.pickerRange.end) ? parseFloat(currentState.pickerRange.end) : NaN;
17735    range = [
17736     !isNaN(start) ? start : "",
17737     !isNaN(end) ? end : "",
17738    ];
17739   }
17740   result.push(pickerType + "|" + range.join("|"));
17741  }
17742  return result;
17743 },
17744 ProcessHeaderFilterCallback: function(columnIndex, htmlObj) {
17745  this.headerFilterColumnIndicesToInitialize.push(parseInt(columnIndex));
17746  this.SetHeaderFilterPopupHtml(htmlObj, columnIndex);
17747 },
17748 SetHeaderFilterPopupHtml: function(htmlObj, columnIndex) {
17749  this.GetHeaderFilterPopup().SetContentHtml(htmlObj, this.GetEnableCallbackAnimation());
17750 },
17751 OnControlsInitialized: function() {
17752  for(var i = 0; i < this.headerFilterColumnIndicesToInitialize.length; i++)
17753   this.InitHeaderFilter(this.headerFilterColumnIndicesToInitialize[i]);
17754  this.headerFilterColumnIndicesToInitialize = [ ];
17755 },
17756 InitHeaderFilter: function(columnIndex) {
17757  this.initialHeaderFilterState[columnIndex] = this.GetHeaderFilterState(columnIndex);
17758  var column = this.GetColumn(columnIndex);
17759  this.headerFilterPopupRelatedColumn = column;
17760  this.InitializeListBox(column);
17761  if(column.HFMode === ASPx.GridHeaderFilterMode.CheckedList)
17762   this.InitializeSelectAllCheckBox(column);
17763  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangePicker)
17764   this.InitializeDateRangePicker(column);
17765  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangeCalendar)
17766   this.InitializeCalendar(column);
17767  if(column.HFMode === ASPx.GridHeaderFilterMode.NumericRangePicker)
17768   this.InitializeNumericRangeEditors(column);
17769  if(this.GetEnableAccessibility())
17770   this.InitializeAccessibility(column);
17771 },
17772 InitializeListBox: function(column) {
17773  var listBox = this.GetListBox(column.index);
17774  if(!listBox) return;
17775  if(column.HFMode === ASPx.GridHeaderFilterMode.List && this.GetEnableAccessibility())
17776   listBox.ItemClick.AddHandler(this.OnListBoxSelectionChanged.bind(this));
17777  else {
17778   listBox.SelectedIndexChanged.AddHandler(this.OnListBoxSelectionChanged.bind(this));
17779   listBox.KeyDown.AddHandler(this.ProcessHeaderFilterKeyDown.bind(this));
17780  }
17781  var element = listBox.GetListTable ? listBox.GetListTable() : listBox.GetMainElement();
17782  ASPx.Evt.AttachEventToElement(element, "mousedown", function() { window.setTimeout(ASPx.Selection.Clear, 0); });
17783  listBox.gvColumn = column;
17784  if(listBox.cpFSI && listBox.cpFSI.length > 0)
17785   this.PrepareSeparators(listBox);
17786  if(this.IsListBoxHasScrolling())
17787   this.AdjustHeaderFilterListBox(column);
17788 },
17789 ProcessHeaderFilterKeyDown: function(listbox, args) {
17790  this.LockHeaderFilterApply();
17791  var evt = args.htmlEvent;
17792  if(evt.keyCode == ASPx.Key.Enter) {
17793   this.UnlockHeaderFilterApply();
17794   this.OnListBoxSelectionChanged(listbox);
17795  }
17796  window.setTimeout(this.UnlockHeaderFilterApply.bind(this), 100);
17797 },
17798 LockHeaderFilterApply: function() {
17799  this.lockHeaderFilterApply = true;
17800 },
17801 UnlockHeaderFilterApply: function() {
17802  this.lockHeaderFilterApply = false;
17803 },
17804 IsHeaderFilterApplyLocked: function() {
17805  return !!this.lockHeaderFilterApply;
17806 },
17807 AdjustHeaderFilterListBox: function(column) {
17808  var listBox = this.GetListBox(column.index);
17809  if(listBox && listBox.GetMainElement() && this.RequireShowHeaderFilterListBoxScrollbar(column)) {
17810   ASPx.SetStyles(listBox.GetMainElement(), { minHeight: this.GetHeaderFilterPopupScrollableElement().offsetHeight });
17811   listBox.AdjustControl();
17812  }
17813 },
17814 InitializeSelectAllCheckBox: function(column) {
17815  var checkBox = this.GetSelectAllCheckBox(column.index);
17816  if(!checkBox) return;
17817  checkBox.CheckedChanged.AddHandler(function(s) { this.OnSelectAllCheckedChanged(s); }.bind(this));
17818  checkBox.gvColumn = column;
17819 },
17820 InitializeDateRangePicker: function(column) {
17821  var dateEdit_From = this.GetDateEdit_From(column.index);
17822  var dateEdit_To = this.GetDateEdit_To(column.index);
17823  if(!dateEdit_From || !dateEdit_To)
17824   return;
17825  dateEdit_From.gvColumn = dateEdit_To.gvColumn = column;
17826  dateEdit_From.ValueChanged.AddHandler(this.OnEditChanged.bind(this));
17827  dateEdit_To.ValueChanged.AddHandler(this.OnEditChanged.bind(this));
17828  this.AdjustRangePicker(dateEdit_From, dateEdit_To);
17829 },
17830 InitializeNumericRangeEditors: function(column) {
17831  var spinEdit_From = this.GetSpinEdit_From(column.index);
17832  var spinEdit_To = this.GetSpinEdit_To(column.index);
17833  var rangeTrackBar = this.GetRangeTrackBar(column.index);
17834  if(spinEdit_From) {
17835   spinEdit_From.gvColumn = column;
17836   spinEdit_From.ValueChanged.AddHandler(function (s, e) {
17837    if(rangeTrackBar) rangeTrackBar.SetPositionStart(s.GetValue());
17838    this.OnEditChanged(s);
17839   }.bind(this));
17840  }
17841  if(spinEdit_To) {
17842   spinEdit_To.gvColumn = column;
17843   spinEdit_To.ValueChanged.AddHandler(function (s, e) {
17844    if(rangeTrackBar) rangeTrackBar.SetPositionEnd(s.GetValue());
17845    this.OnEditChanged(s);
17846   }.bind(this));
17847  }
17848  if(rangeTrackBar) {
17849   rangeTrackBar.gvColumn = column;
17850   rangeTrackBar.ValueChanged.AddHandler(function (s, e) {
17851    if(spinEdit_From) spinEdit_From.SetValue(s.GetPositionStart());
17852    if(spinEdit_To) spinEdit_To.SetValue(s.GetPositionEnd());
17853    this.OnEditChanged(s);
17854   }.bind(this));
17855  }
17856  if(!spinEdit_From || !spinEdit_To)
17857   return;
17858  this.AdjustRangePicker(spinEdit_From, spinEdit_To);
17859 },
17860 AdjustRangePicker: function(editor_From, editor_To) {
17861  var firstCaptionCell = editor_From.GetCaptionCell();
17862  var secondCaptionCell = editor_To.GetCaptionCell();
17863  var width = Math.max(ASPx.GetClearClientWidth(firstCaptionCell), ASPx.GetClearClientWidth(secondCaptionCell));
17864  ASPx.SetStyles(firstCaptionCell, { minWidth: width });
17865  ASPx.SetStyles(secondCaptionCell, { minWidth: width });
17866 },
17867 InitializeCalendar: function(column) {
17868  var calendar = this.GetCalendar(column.index);
17869  calendar.SelectionChanged.AddHandler(this.OnEditChanged.bind(this));
17870  calendar.gvColumn = column;
17871 },
17872 OnListBoxSelectionChanged: function(listBox) {
17873  if(!listBox) return;
17874  var column = listBox.gvColumn;
17875  if(this.RequireApplyHeaderFilterNow(column.HFMode, column.index))
17876   this.ApplyHeaderFilter();
17877  else {
17878   if(column.HFMode === ASPx.GridHeaderFilterMode.CheckedList)
17879    this.UpdateSelectAllCheckState(column.index);
17880   this.UpdateOkButtonEnabledState(column.index);
17881  }
17882 },
17883 OnSelectAllCheckedChanged: function(checkBox) {
17884  var columnIndex = checkBox.gvColumn.index;
17885  var listBox = this.GetListBox(columnIndex);
17886  if(checkBox.GetChecked())
17887   listBox.SelectAll();
17888  else
17889   listBox.UnselectAll();
17890  this.UpdateOkButtonEnabledState(columnIndex);
17891 },
17892 OnEditChanged: function(editor) {
17893  this.UpdateOkButtonEnabledState(editor.gvColumn.index);
17894 },
17895 RequireApplyHeaderFilterNow: function(mode, columnIndex) {
17896  return mode === ASPx.GridHeaderFilterMode.List && this.IsHeaderFilterChanged(columnIndex) && !this.IsHeaderFilterApplyLocked();
17897 },
17898 UpdateSelectAllCheckState: function(columnIndex) {
17899  var checkBox = this.GetSelectAllCheckBox(columnIndex);
17900  var listBox = this.GetListBox(columnIndex);
17901  if(!checkBox || !listBox) 
17902   return;
17903  var selectedItemCount = listBox.GetSelectedIndices().length;
17904  var checkState = ASPx.CheckBoxCheckState.Indeterminate;
17905  if(selectedItemCount === 0)
17906   checkState = ASPx.CheckBoxCheckState.Unchecked;
17907  else if(selectedItemCount === listBox.GetItemCount())
17908   checkState = ASPx.CheckBoxCheckState.Checked;
17909  checkBox.SetCheckState(checkState);
17910 },
17911 UpdateOkButtonEnabledState: function(columnIndex) {
17912  if(this.GetColumn(columnIndex).HFMode !== ASPx.GridHeaderFilterMode.List)
17913   this.SetHFOkButtonEnabled(this.IsHeaderFilterChanged(columnIndex));
17914 },
17915 ApplyHeaderFilterInitialState: function(columnIndex) {
17916  var state = this.initialHeaderFilterState[columnIndex];
17917  if(!state) return;
17918  var column = this.GetColumn(columnIndex);
17919  var listBox = this.GetListBox(columnIndex);
17920  if(listBox) {
17921   if(column.HFMode === ASPx.GridHeaderFilterMode.List) {
17922    if(this.GetEnableAccessibility() && state.listBoxSelectedIndices.length > 0)
17923     listBox.SelectIndex(state.listBoxSelectedIndices[0]);
17924   } else {
17925    listBox.UnselectAll();
17926    listBox.SelectIndices(state.listBoxSelectedIndices);
17927   }
17928  }
17929  if(column.HFMode === ASPx.GridHeaderFilterMode.CheckedList)
17930   this.UpdateSelectAllCheckState(columnIndex);
17931  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangePicker) {
17932   this.GetDateEdit_From(columnIndex).SetValue(state.pickerRange.start);
17933   this.GetDateEdit_To(columnIndex).SetValue(state.pickerRange.end);
17934  }
17935  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangeCalendar) {
17936   var calendar = this.GetCalendar(columnIndex);
17937   calendar.SetValue(null);
17938   var dates = state.calendarDates || [ ];
17939   for(var i = 0; i < dates.length; i++)
17940    calendar.SelectDate(dates[i]);
17941  }
17942  if(column.HFMode === ASPx.GridHeaderFilterMode.NumericRangePicker) {
17943   var rangeTrackBar = this.GetRangeTrackBar(columnIndex);
17944   if(rangeTrackBar) {
17945    rangeTrackBar.SetPositionStart(state.pickerRange.start);
17946    rangeTrackBar.SetPositionEnd(state.pickerRange.end);
17947   }
17948   var spinEdit_From = this.GetSpinEdit_From(columnIndex);
17949   if(spinEdit_From)
17950    spinEdit_From.SetValue(state.pickerRange.start);
17951   var spinEdit_To = this.GetSpinEdit_To(columnIndex);
17952   if(spinEdit_To)
17953    spinEdit_To.SetValue(state.pickerRange.end);
17954  }
17955  this.SetHFOkButtonEnabled(false);
17956 },
17957 IsListBoxHasScrolling: function() { return true; }, 
17958 RequireShowHeaderFilterListBoxScrollbar: function(column) { return this.IsListBoxHasScrolling() && column && (column.HFMode === ASPx.GridHeaderFilterMode.List || column.HFMode === ASPx.GridHeaderFilterMode.CheckedList); },
17959 GetHeaderFilterPopupScrollableElement: function() { return this.GetHeaderFilterPopup().GetWindowContentElement(-1); },
17960 InitializeHeaderFilterPopup: function() {
17961  var popup = this.GetHeaderFilterPopup();
17962  if(!popup || !popup.GetWindowElement(-1))
17963   return;
17964  this.initialHeaderFilterPopupMinWidth = popup.GetWindowMinWidth();
17965  popup.PopUp.AddHandler(this.HeaderFilterPopup_PopUpHandler);
17966  popup.CloseUp.AddHandler(this.HeaderFilterPopup_CloseUpHandler);
17967  popup.Resize.AddHandler(this.HeaderFilterPopup_ResizeHandler);
17968  if(this.IsListBoxHasScrolling()) {
17969   popup.AfterResizing.AddHandler(this.OnHeaderFilter_AfterResizing.bind(this));
17970   ASPx.Evt.AttachEventToElement(this.GetHeaderFilterPopupScrollableElement(), "scroll", this.OnHeaderFilterPopup_Scroll.bind(this));
17971  }
17972  this.InitializeHeaderFilterButtons();
17973 },
17974 OnHeaderFilterPopup_PopUp: function(popup) {
17975  var columnIndex = this.FindColumnIndexByHeaderChild(popup.GetCurrentPopupElement());
17976  var column = this.GetColumn(columnIndex);
17977  if(!column) return;
17978  var shiftKey = popup.GetPopUpReasonMouseEvent().shiftKey;
17979  var callbackWaiting = this.LoadHeaderFilterPopupData(popup, column, shiftKey);
17980  if(callbackWaiting) {
17981   var size = this.GetHeaderFilterPopupSize(columnIndex);
17982   this.SetHFButtonPanelVisibility(popup, this.RequireButtonPanel(column));
17983   this.AssignHeaderFilterPopupMinWidth(column);
17984   if(size) {
17985    popup.SetSize(size[0], size[1]);
17986    if(ASPx.Browser.Firefox)
17987     popup.Shown.AddHandler(function(s) { window.setTimeout(function() { s.SetSize(size[0], size[1]); }, 0); }); 
17988   }
17989   this.ShowLoadingPanelInsideHeaderFilterPopup();
17990  }
17991  if(this.IsListBoxHasScrolling())
17992   window.setTimeout(this.UpdateHeaderFilterPopupScroll.bind(this), popup.fadeAnimationDuration);
17993 },
17994 LoadHeaderFilterPopupData: function(popup, column, shiftKey) {
17995  if(column === this.GetHeaderFilterPopupRelatedColumn() && this.UseHeaderFilterContentCaching(column.index) && popup.savedShiftKey === shiftKey) {
17996   this.ApplyHeaderFilterInitialState(column.index);
17997  } else {
17998   this.SendHeaderFilterCallback(column.index, shiftKey);
17999   popup.SetContentHtml("");
18000   this.headerFilterPopupRelatedColumn = null;
18001   popup.savedShiftKey = shiftKey;
18002   return true;
18003  }
18004 },
18005 UpdateHeaderFilterPopupScroll: function() {
18006  var column = this.GetHeaderFilterPopupRelatedColumn();
18007  var disablePopupScroll = this.RequireShowHeaderFilterListBoxScrollbar(column) && this.GetHeaderFilterPopup().IsVisible();
18008  ASPx.SetStyles(this.GetHeaderFilterPopupScrollableElement(), { overflowY: disablePopupScroll ? "hidden" : "auto" });
18009 },
18010 OnHeaderFilterPopup_CloseUp: function(popup) {
18011  var column = this.GetHeaderFilterPopupRelatedColumn();
18012  if(column && !this.UseHeaderFilterContentCaching(column.index))
18013   window.setTimeout(function() { popup.SetContentHtml(""); }, 0);
18014  this.UpdateHeaderFilterPopupScroll();
18015 },
18016 OnHeaderFilterPopup_Resize: function(popup) {
18017  var columnIndex = this.FindColumnIndexByHeaderChild(popup.GetCurrentPopupElement());
18018  if(this.GetColumn(columnIndex))
18019   this.SetHeaderFilterPopupSize(columnIndex, popup.GetWidth(), popup.GetHeight());
18020 },
18021 OnHeaderFilter_AfterResizing: function(popup) {
18022  var column = this.GetHeaderFilterPopupRelatedColumn();
18023  if(column) {
18024   this.AdjustHeaderFilterListBox(column);
18025   var rangeTrackBar = this.GetRangeTrackBar(column.index);
18026   if(rangeTrackBar)
18027    rangeTrackBar.AdjustControl();
18028  }
18029 },
18030 OnHeaderFilterPopup_Scroll: function(e) {
18031  var column = this.GetHeaderFilterPopupRelatedColumn();
18032  if(this.RequireShowHeaderFilterListBoxScrollbar(column))
18033   this.GetHeaderFilterPopupScrollableElement().scrollTop = 0;
18034 },
18035 InitializeHeaderFilterButtons: function() {
18036  var popup = this.GetHeaderFilterPopup();
18037  if(!popup) return;
18038  var buttons = this.GetHeaderFilterButtons();
18039  for(var i = 0; i < buttons.length; i++) {
18040   popup.AddPopupElement(buttons[i]);
18041   if(this.GetEnableAccessibility())
18042    ASPx.Evt.AttachEventToElement(buttons[i], "keydown", GridFilterHelper.HeaderFilterButtonKeyDownHandler);
18043  }
18044 },
18045 UnloadHeaderFilterPopup: function() {
18046  var popup = this.GetHeaderFilterPopup();
18047  if(!popup) return;
18048  popup.PopUp.RemoveHandler(this.HeaderFilterPopup_PopUpHandler);
18049  popup.CloseUp.RemoveHandler(this.HeaderFilterPopup_CloseUpHandler);
18050  popup.Resize.RemoveHandler(this.HeaderFilterPopup_ResizeHandler);
18051  popup.RemoveAllPopupElements();
18052  popup.Hide();
18053  if(this.GetEnableAccessibility()) {
18054   var buttons = this.GetHeaderFilterButtons();
18055   for(var i = 0; i < buttons.length; i++)
18056    ASPx.Evt.DetachEventFromElement(buttons[i], "keydown", GridFilterHelper.HeaderFilterButtonKeyDownHandler);
18057  }
18058 },
18059 GetHeaderFilterButtons: function() {
18060  var buttons = [ ];
18061  var visibleIndices = this.GetVisibleColumnIndices();
18062  for(var i = 0; i < visibleIndices.length; i++) {
18063   var index = visibleIndices[i];
18064   var headers = this.GetColumnHeaders(index);
18065   for(var j = 0; j < headers.length; j++)
18066    this.PopulateHeaderFilterButtons(headers[j], buttons);
18067  }
18068  var custWindow = this.GetCustomizationWindow();
18069  if(custWindow)
18070   this.PopulateHeaderFilterButtons(custWindow.GetWindowClientTable(-1), buttons);
18071  return buttons;
18072 },
18073 GetVisibleColumnIndices: function() {
18074  var indices = [ ];
18075  for(var i = 0; i < this.GetColumnCount(); i++) {
18076   if(this.GetColumn(i).visible)
18077    indices.push(this.GetColumn(i).index);
18078  }
18079  return indices;
18080 },
18081 PopulateHeaderFilterButtons: function(container, buttons) {
18082  if(!container) return;
18083  var images = container.getElementsByTagName("IMG");
18084  for(var i = 0; i < images.length; i++) {
18085   var button = ASPx.getSpriteMainElement(images[i]);
18086   if(ASPx.ElementContainsCssClass(button, this.GetHeaderFilterIconClassName()))
18087    buttons.push(button);
18088  }
18089 },
18090 RequireButtonPanel: function(column) {
18091  return column.HFMode !== ASPx.GridHeaderFilterMode.List;
18092 },
18093 SetHFButtonPanelVisibility: function(popup, visible) {
18094  var buttonPanel = this.GetHeaderFilterPopupButtonPanelElement();
18095  if(buttonPanel) {
18096   ASPx.SetElementDisplay(buttonPanel, visible);
18097   this.SetHFOkButtonEnabled(false);
18098   var okButton = this.GetHeaderFilterButton(false);
18099   var cancelButton = this.GetHeaderFilterButton(true);
18100   if(okButton && cancelButton && okButton.GetWidth() != cancelButton.GetWidth())
18101    ASPx.MakeEqualControlsWidth(popup.cpOkButtonID, popup.cpCancelButtonID);
18102  }
18103 },
18104 SetHFOkButtonEnabled: function(enabled) {
18105  var button = this.GetHeaderFilterButton(false);
18106  if(button)
18107   button.SetEnabled(enabled);
18108 },
18109 GetHeaderFilterPopupSize: function(key) {
18110  var size = this.headerFilterPopupDimensions[key];
18111  if(size) return size;
18112  if(!this.headerFilterPopupDimensions["Default"]) {
18113   var popup = this.GetHeaderFilterPopup();
18114   this.SetHeaderFilterPopupSize("Default", popup.GetWidth(), popup.GetHeight());
18115  }
18116  return this.headerFilterPopupDimensions["Default"];
18117 },
18118 SetHeaderFilterPopupSize: function(key, width, height) {
18119  this.headerFilterPopupDimensions[key] = [ width, height ];
18120 },
18121 AssignHeaderFilterPopupMinWidth: function(column) {
18122  var popup = this.GetHeaderFilterPopup();
18123  popup.minWidth = this.GetHeaderFilterPopupMinWidth(column);
18124 },
18125 GetHeaderFilterPopupMinWidth: function(column) {
18126  if(this.RequireButtonPanel(column))
18127   return this.GetHeaderFilterPopupWithButtonPanelMinWidth();
18128  return this.initialHeaderFilterPopupMinWidth;
18129 },
18130 GetHeaderFilterPopupWithButtonPanelMinWidth: function() {
18131  if(!ASPx.IsExists(this.headerFilterPopupWithButtonPanelMinWidth))
18132   this.headerFilterPopupWithButtonPanelMinWidth = this.CalculateHeaderFilterPopupWithButtonPanelMinWidth();
18133  return this.headerFilterPopupWithButtonPanelMinWidth;
18134 },
18135 CalculateHeaderFilterPopupWithButtonPanelMinWidth: function() {
18136  var popup = this.GetHeaderFilterPopup();
18137  var minWidth = popup.GetWidth();
18138  var buttonPanel = this.GetHeaderFilterPopupButtonPanelElement();
18139  if(buttonPanel) {
18140   var footerElement = buttonPanel.parentNode;
18141   var excess = buttonPanel.offsetWidth - ASPx.GetClearClientWidth(footerElement);
18142   minWidth += excess;
18143  }
18144  minWidth = Math.max(minWidth, this.initialHeaderFilterPopupMinWidth);
18145  return minWidth;
18146 },
18147 GetHeaderFilterPopupButtonPanelElement: function() {
18148  var popup = this.GetHeaderFilterPopup();
18149  return document.getElementById(popup.cpButtonPanelID);
18150 },
18151 FindColumnIndexByHeaderChild: function(element) {
18152  if(!element) 
18153   return -1;
18154  var level = 0;
18155  while(level < 6) {
18156   var index = this.ResolveColumnIndex(element.id);
18157   if(index > -1)
18158    return index;
18159   element = element.parentNode;
18160   level++;
18161  }
18162  return -1;
18163 },
18164 UseHeaderFilterContentCaching: function(columnIndex) {
18165  if(!this.GetEnableHeaderFilterCaching())
18166   return false;
18167  var listBox = this.GetListBox(columnIndex);
18168  return listBox && listBox.GetMainElement() && listBox.GetItemCount() < 1000; 
18169 },
18170 CalcDateRanges: function(dates) { 
18171  var result = [ ];
18172  dates.sort(function(a, b) { return a - b; });
18173  var range = { start: null, end: null };
18174  for(var i = 0; i < dates.length; i++) {
18175   var date = dates[i];
18176   if(!range.start || !range.end)
18177    range.start = range.end = date;
18178   var isLastDate = dates.length === i + 1;
18179   var nextDate = ASPxClientCalendar.AddDays(date, 1);
18180   if(!isLastDate && ASPx.DateUtils.AreDatesEqualExact(nextDate, dates[i + 1])) {
18181    range.end = nextDate;
18182   } else {
18183    result.push(ASPx.DateUtils.GetInvariantDateString(range.start));
18184    result.push(ASPx.DateUtils.GetInvariantDateString(range.end));
18185    range.start = range.end = null;
18186   }
18187  }
18188  return result;
18189 },
18190 InitializeAccessibility: function(column) {
18191  var listBox = this.GetListBox(column.index);
18192  if(listBox) {
18193   listBox.SelectedIndexChanged.AddHandler(function() { this.MakeListBoxSelectedItemVisible(column); }.bind(this));
18194   this.MakeListBoxSelectedItemVisible(column);
18195  }
18196  var popup = this.GetHeaderFilterPopup();
18197  if(popup && !popup.gvAccessibilityEventsAssigned) {
18198   popup.Shown.AddHandler(function() { this.MakeListBoxSelectedItemVisible(this.GetHeaderFilterPopupRelatedColumn()); }.bind(this));
18199   ASPx.Evt.AttachEventToElement(popup.GetCurrentWindowElement(), "keydown", this.ProcessAccessibleHeaderFilterPopupKeyDown.bind(this));
18200   popup.gvAccessibilityEventsAssigned = true;
18201  }
18202 },
18203 MakeListBoxSelectedItemVisible: function(column) {
18204  if(!column || column.HFMode !== ASPx.GridHeaderFilterMode.List)
18205   return;
18206  var listBox = this.GetListBox(column.index);
18207  var itemIndex = listBox.GetSelectedIndex();
18208  var div = this.GetHeaderFilterPopupScrollableElement();
18209  var item = listBox.GetItemElement(itemIndex);
18210  if(!div || !item)
18211   return;
18212  var itemHeight = item.offsetHeight;
18213  var divHeight = parseInt(ASPx.GetCurrentStyle(div).height);
18214  var itemStart = item.offsetTop;
18215  var itemEnd = itemStart + itemHeight;
18216  var divStart = div.scrollTop;
18217  var divEnd = divStart + divHeight;
18218  var scrollTop = divStart;
18219  var isItemAbove = itemStart < divStart;
18220  var isItemBelow = itemEnd > divEnd;
18221  if(isItemAbove)
18222   scrollTop = itemStart;
18223  else if(isItemBelow)
18224   scrollTop = itemEnd - divHeight;
18225  if(div.scrollTop !== scrollTop)
18226   div.scrollTop = scrollTop;
18227 },
18228 ProcessAccessibleHeaderFilterPopupKeyDown: function(e) {
18229  var keyCode = ASPx.Evt.GetKeyCode(e);
18230  if(keyCode !== ASPx.Key.Enter) 
18231   return;
18232  var handled = true;
18233  var column = this.GetHeaderFilterPopupRelatedColumn();
18234  if(column.HFMode === ASPx.GridHeaderFilterMode.List) {
18235   this.OnListBoxSelectionChanged(this.GetListBox(column.index));
18236  } else {
18237   var applyFilterOnEnter = this.IsHeaderFilterChanged(column.index) && !this.IsCancelButtonEventSource(e) && !this.IsDateEditorDroppedDown(column);
18238   if(applyFilterOnEnter)
18239    this.ApplyHeaderFilter();
18240   else
18241    handled = false;
18242  }
18243  if(handled)
18244   ASPx.Evt.PreventEventAndBubble(e);
18245 },
18246 IsCancelButtonEventSource: function(evt) {
18247  return ASPx.GetIsParent(this.GetHeaderFilterButton(true).GetMainElement(), ASPx.Evt.GetEventSource(evt));
18248 },
18249 IsDateEditorDroppedDown: function(column) {
18250  if(column.HFMode === ASPx.GridHeaderFilterMode.DateRangePicker)
18251   return this.GetDateEdit_From(column.index).droppedDown || this.GetDateEdit_To(column.index).droppedDown;
18252  return false;
18253 },
18254 PrepareSeparators: function(listBox) {
18255  if(typeof(ASPxClientListBox) != "undefined" && listBox instanceof ASPxClientListBox)
18256   GridHFListBoxWrapper.Initialize(listBox);
18257  for(var i = 0; i < listBox.cpFSI.length; i++) {
18258   var separatorIndex = listBox.cpFSI[i];
18259   var item = listBox.GetItemElement(separatorIndex);
18260   if(ASPx.IsExists(item)) {
18261    var tr = ASPx.GetParentByTagName(item, "TR");
18262    this.AppendSeparatorRow(tr);
18263   }
18264  }
18265 },
18266 AppendSeparatorRow: function(targetRow){
18267  var newTr = document.createElement("TR");
18268  ASPx.InsertElementAfter(newTr, targetRow);
18269  var td = document.createElement("TD");
18270  var colSpan = this.GetColSpanSum(targetRow);
18271  if(colSpan > 1)
18272   td.colSpan = colSpan;
18273  newTr.appendChild(td);
18274  var separatorDiv = document.createElement("DIV");
18275  separatorDiv.className = this.GetFilterValuesSeparatorClassName();
18276  td.appendChild(separatorDiv);
18277 },
18278 GetColSpanSum: function(tableRow){
18279  var colSpan = 0;
18280  var cells = ASPx.GetChildNodesByTagName(tableRow, "TD");
18281  for(var i = 0; i < cells.length; i++)
18282   colSpan += cells[i].colSpan;
18283  return colSpan;
18284 },
18285 GetFilterValuesSeparatorClassName: function() { return this.grid.GetCssClassNamePrefix() + "HFSD"; },
18286});
18287var GridHFListBoxWrapper = {
18288 Initialize: function(listBox){
18289  listBox.GetItemRow = GridHFListBoxWrapper.GetItemRow;
18290  listBox.GetItemCount = GridHFListBoxWrapper.GetItemCount;
18291  listBox.OnItemClickCore = listBox.OnItemClick;
18292  listBox.OnItemClick = GridHFListBoxWrapper.OnItemClick;
18293  listBox.FindInternalCheckBoxIndexCore = listBox.FindInternalCheckBoxIndex;
18294  listBox.FindInternalCheckBoxIndex = GridHFListBoxWrapper.FindInternalCheckBoxIndex;
18295 },
18296 GetItemRow: function(index){
18297  var itemRows = GridHFListBoxWrapper.GetItemRows(this);
18298  if(index >= 0)
18299   return itemRows[index] || null;
18300  return null;
18301 },
18302 OnItemClick: function(index, evt){
18303  var correctIndex = GridHFListBoxWrapper.GetCorrectItemIndex(this, index);
18304  this.OnItemClickCore(correctIndex, evt);
18305 },
18306 FindInternalCheckBoxIndex: function(element){
18307  var index = this.FindInternalCheckBoxIndexCore(element);
18308  return GridHFListBoxWrapper.GetCorrectItemIndex(this, index);
18309 },
18310 GetItemCount: function(){
18311  return GridHFListBoxWrapper.GetItemRows(this).length;
18312 },
18313 GetCorrectItemIndex: function(listBox, index){
18314  for(var i = 0; i < listBox.cpFSI.length; i++) {
18315   if(listBox.cpFSI[i] < index)
18316    index--;
18317  }
18318  return index;
18319 },
18320 GetItemRows: function(listBox){
18321  var itemRows = [];
18322  var listTable = listBox.GetListTable();
18323  var rows = listTable ? listTable.rows : null;
18324  for(var i = 0; rows && i < rows.length; i++){
18325   if(ASPx.ElementContainsCssClass(rows[i], "dxeListBoxItemRow"))
18326    itemRows.push(rows[i]);
18327  }
18328  return itemRows;
18329 }
18330};
18331GridFilterHelper.HeaderFilterButtonKeyDownHandler = function(evt) { ASPx.Evt.InvokeMouseClickByKeyDown(evt, ASPx.PopupElementMouseEvent); };
18332ASPx.GridHeaderFilterMode = GridHeaderFilterMode;
18333ASPx.GridFilterHelper = GridFilterHelper;
18334})();
18335
18336(function() {
18337var GridKbdHelper = ASPx.CreateClass(ASPx.KbdHelper, {
18338 constructor: function(grid) {
18339  this.constructor.prototype.constructor.call(this, grid);
18340  this.grid = grid;
18341 },
18342 CanFocus: function(e) {
18343  var source = ASPx.Evt.GetEventSource(e);
18344  if(source.tagName === "A")
18345   return true;
18346  return ASPx.KbdHelper.prototype.CanFocus.call(this, e);
18347 },
18348 HandleNoFocusAction: function(e, actionName) {
18349  this.HandleKbdEvent(e, actionName);
18350 },
18351 HandleKeyDown: function(e) {
18352  return this.HandleKbdEvent(e, "HandleKeyDown");
18353 },
18354 HandleKeyPress: function(e) {
18355  return this.HandleKbdEvent(e, "HandleKeyPress");
18356 },
18357 HandleKeyUp: function(e) {
18358  return this.HandleKbdEvent(e, "HandleKeyUp");
18359 },
18360 HandleKbdEvent: function(e, actionName) {
18361  var action = actionName.replace(/^Handle*/g, "Raise");
18362  var handled = this.grid[action](e);
18363  if(handled)
18364   ASPx.Evt.PreventEventAndBubble(e);
18365  return handled;
18366 }
18367});
18368var ASPxClientGridKeyboardEvent = ASPx.CreateClass(ASPxClientEvent, {
18369 constructor: function(kbdHelperOwner) {
18370  this.constructor.prototype.constructor.call(this);
18371  this.kbdHelperOwner = kbdHelperOwner;
18372 },
18373 AddHandler: function(handler, executionContext) {
18374  ASPxClientEvent.prototype.AddHandler.call(this, handler, executionContext);
18375  this.kbdHelperOwner.OnKbdEventChanged();
18376 },
18377 RemoveHandler: function(handler, executionContext) {
18378  ASPxClientEvent.prototype.RemoveHandler.call(this, handler, executionContext);
18379  this.kbdHelperOwner.OnKbdEventChanged();
18380 },
18381 ClearHandlers: function() {
18382  ASPxClientEvent.prototype.ClearHandlers.call(this);
18383  this.kbdHelperOwner.OnKbdEventChanged();
18384 }
18385});
18386var ASPxClientGridKeyboardEventArgsBase = ASPx.CreateClass(ASPxClientEventArgs, {
18387 constructor: function(htmlEvent) {
18388  this.constructor.prototype.constructor.call(this);
18389  this.htmlEvent = htmlEvent;
18390  this.handled = false;
18391  this.isCtrlPressed = htmlEvent.ctrlKey;
18392  this.isAltPressed = htmlEvent.altKey;
18393  this.isShiftPressed = htmlEvent.shiftKey;
18394  this.keyCode = ASPx.Evt.GetKeyCode(htmlEvent);
18395 }
18396});
18397ASPx.GridKbdHelper = GridKbdHelper;
18398ASPx.ASPxClientGridKeyboardEvent = ASPxClientGridKeyboardEvent;
18399ASPx.ASPxClientGridKeyboardEventArgsBase = ASPxClientGridKeyboardEventArgsBase;
18400})();
18401
18402(function() {
18403var GridExportItemType = {
18404 ExportToPdf: "ExportToPdf",
18405 ExportToDocx: "ExportToDocx",
18406 ExportToRtf: "ExportToRtf",
18407 ExportToCsv: "ExportToCsv",
18408 ExportToXls: "ExportToXls",
18409 ExportToXlsx: "ExportToXlsx"
18410};
18411var TOOLBAR_CLIENT_STATE_KEY = "toolbar";
18412var CHECKED_CLIENT_STATE_KEY = "checked";
18413var CLICKED_CLIENT_STATE_KEY = "clicked";
18414var GridCommandMenuHelper = ASPx.CreateClass(null, {
18415 constructor: function(exportFormat) {
18416  this.exportFormat = exportFormat;
18417 },
18418 GetItemCommand: function(item) {
18419  return item.menu.cpItemsProps.commands[item.indexPath];
18420 },
18421 IsExportItem: function(itemType) {
18422  return itemType == GridExportItemType.ExportToPdf
18423   || itemType == GridExportItemType.ExportToDocx
18424   || itemType == GridExportItemType.ExportToRtf
18425   || itemType == GridExportItemType.ExportToCsv
18426   || itemType == GridExportItemType.ExportToXls
18427   || itemType == GridExportItemType.ExportToXlsx;
18428 },
18429 GetExportFormat: function(exportCommand) {
18430  var exportFormat = this.exportFormat;
18431  switch(exportCommand) {
18432   case GridExportItemType.ExportToPdf:
18433    return exportFormat.Pdf;
18434   case GridExportItemType.ExportToDocx:
18435    return exportFormat.Docx;
18436   case GridExportItemType.ExportToRtf:
18437    return exportFormat.Rtf;
18438   case GridExportItemType.ExportToCsv:
18439    return exportFormat.Csv;
18440   case GridExportItemType.ExportToXls:
18441    return exportFormat.Xls;
18442   case GridExportItemType.ExportToXlsx:
18443    return exportFormat.Xlsx;
18444  }
18445  return null;
18446 }
18447});
18448var CommandToolbarHelper = ASPx.CreateClass(GridCommandMenuHelper, {
18449 constructor: function(control, exportFormat) {
18450  this.constructor.prototype.constructor.call(this, exportFormat);
18451  this.control = control;
18452  this.ResetState();
18453 },
18454 GetCallbackState: function() {
18455  var state = { };
18456  if(this.clickedToolbarIndex >= 0 && this.clickedToolbarMenuItem)
18457   state[CLICKED_CLIENT_STATE_KEY] = [this.clickedToolbarIndex, this.clickedToolbarMenuItem.indexPath];
18458  var checkedState = this.GetCheckedItemsState();
18459  if(checkedState.length > 0)
18460   state[CHECKED_CLIENT_STATE_KEY] = checkedState;
18461  return ASPx.Json.ToJson(state);
18462 },
18463 GetCheckedItemsState: function() {
18464  var result = [ ];
18465  this.ForEachToolbar(function(toolbar, toolbarIndex) {
18466   if(toolbar.allowCheckItems)
18467    result.push([toolbarIndex, toolbar.GetCheckedState()]);
18468  }.bind(this));
18469  return result;
18470 },
18471 ResetState: function() {
18472  this.clickedToolbarIndex = -1;
18473  this.clickedToolbarMenuItem = null;
18474  this.SetClientStateValue(null);
18475 },
18476 SaveClientState: function() {
18477  this.SetClientStateValue(this.GetCallbackState());
18478 },
18479 SetClientStateValue: function(value) {
18480  this.control.stateObject[TOOLBAR_CLIENT_STATE_KEY] = value;
18481 },
18482 GetToolbarSettings: function() {
18483  return this.control.toolbars;
18484 },
18485 GetToolbarByIndex: function(index) {
18486  return this.control.GetToolbar(index);
18487 },
18488 GetToolbarByName: function(name) {
18489  var settings = this.GetToolbarSettings();
18490  var foundToolbars = settings.filter(function(t) { return t.name === name; });
18491  if(foundToolbars.length < 1)
18492   return null;
18493  return this.GetToolbarByIndex(foundToolbars[0].index);
18494 },
18495 GetToolbarNameByIndex: function(index) {
18496  var settings = this.GetToolbarSettings(),
18497   foundToolbars = settings.filter(function(t) { return t.index === index; });
18498  return (foundToolbars.length > 0) ? foundToolbars[0].name : null;
18499 },
18500 GetToolbarIndexByName: function(name) {
18501  var index = -1;
18502  var success = false;
18503  var n = name.length - 1;
18504  while(n >= 0 && !isNaN(parseInt(name.substr(n), 10))) {
18505   index = parseInt(name.substr(n), 10);
18506   success = true;
18507   n--;
18508  }
18509  return success ? index: -1;
18510 },
18511 InitializeCustomizationWindowHandlers: function() {
18512  var custWindow = this.GetCustomizationWindow();
18513  if(custWindow) {
18514   custWindow.PopUp.AddHandler(function() {
18515    this.SetCheckedItemsState(this.IsShowCustomizationWindowItem.bind(this), true);
18516   }.aspxBind(this));
18517   custWindow.CloseUp.AddHandler(function() {
18518    this.SetCheckedItemsState(this.IsShowCustomizationWindowItem.bind(this), false);
18519   }.aspxBind(this));
18520  }
18521 },
18522 OnInit: function() {
18523  this.InitializeCustomizationWindowHandlers();
18524 },
18525 OnBeforeCallback: function() {
18526  this.SaveClientState();
18527 },
18528 OnAfterCallback: function() {
18529  this.ResetState();
18530  this.InitializeCustomizationWindowHandlers();
18531  this.RefreshItemsState();
18532 },
18533 RefreshItemsState: function() {
18534  this.ForEachItem(null, this.RefreshItemState.aspxBind(this));
18535 },
18536 SetCheckedItemsState: function(filterFunc, checked) {
18537  var setCheckedFunc = function(item) { item.SetChecked(checked); };
18538  this.ForEachItem(filterFunc, setCheckedFunc);
18539 },
18540 OnBatchEditItemsStateChanged: function(state) {
18541  this.OnUpdateEditEnabledChanged(state.enabled);
18542 },
18543 OnUpdateEditEnabledChanged: function(enabled) {
18544  var setEnabledFunc = function(item) { item.SetEnabled(enabled); };
18545  this.ForEachItem(this.IsUpdateEditItem.aspxBind(this), setEnabledFunc);
18546 },
18547 RefreshItemState: function(item) {
18548  this.RefreshItemBadge(item);
18549  this.RefreshItemEnabled(item);
18550 },
18551 RefreshSelectionBasedItemBadge: function(item, count) {
18552  this.UpdateItemBadge(item, count > 1 ? count : 0);
18553 },
18554 UpdateItemBadge: function(item, count) {
18555  var menu = item.menu;
18556  var itemElement = menu.GetItemElement(item.GetIndexPath());
18557  var badge = ASPx.BadgeManager.findBadge(itemElement);
18558  if(!badge)
18559   badge = ASPx.BadgeManager.createBadgeForToolbar(item);
18560  if(badge) {
18561   var badgeText = count > 0 ? count : "";
18562   if(ASPx.BadgeManager.getBadgeText(itemElement) != badgeText) {
18563    ASPx.BadgeManager.setBadgeText(badge, badgeText);
18564    menu.renderHelper.CalculateItemMinSize(itemElement, true);
18565    menu.AdjustControl();
18566   }
18567  }
18568 },
18569 RefreshItemEnabled: function(item) {
18570  var itemEnabled = this.GetToolbarItemEnabled(item);
18571  if(itemEnabled !== null)
18572   item.SetEnabled(itemEnabled);
18573 },
18574 ForEachToolbar: function(actionFunc) {
18575  var settings = this.GetToolbarSettings();
18576  for(var i = 0; i < settings.length; i++) {
18577   var toolbarIndex = settings[i].index;
18578   var menu = this.GetToolbarByIndex(toolbarIndex);
18579   actionFunc(menu, toolbarIndex);
18580  }
18581 },
18582 ForEachAdaptiveToolbar: function(actionFunc) {
18583  this.ForEachToolbar(function(menu) {
18584   if(menu.IsEnabledAdaptivity())
18585    actionFunc(menu);
18586  });
18587 },
18588 ForEachItem: function(filterFunc, actionFunc) {
18589  this.ForEachToolbar(function(menu) {
18590   this.ForEachItemInternal(menu, filterFunc, actionFunc);
18591  }.bind(this));
18592 },
18593 ForEachItemInternal: function(itemsOwner, filterFunc, actionFunc) {
18594  if(!itemsOwner) return;
18595  for(var i = 0; i < itemsOwner.GetItemCount(); i++){
18596   var item = itemsOwner.GetItem(i);
18597   if(!filterFunc || filterFunc(item))
18598    actionFunc(item);
18599   this.ForEachItemInternal(item, filterFunc, actionFunc);
18600  }
18601 },
18602 RefreshItemBadge: function(item) {
18603 },
18604 GetToolbarItemEnabled: function(item){
18605  return null;
18606 },
18607 IsUpdateEditItem: function(item) {
18608  return false;
18609 },
18610 GetCustomizationWindow: function() {
18611  return null;
18612 },
18613 IsShowCustomizationWindowItem: function(item) {
18614  return false;
18615 },
18616 GetSelectedGridItemCount: function() {
18617  return 0;
18618 },
18619 GetSelectedVisibleGridItemCount: function() {
18620  return 0;
18621 },
18622 OnToolbarMenuItemClick: function(toolbar, e) {
18623  this.clickedToolbarIndex = this.GetToolbarIndexByName(toolbar.name);
18624  this.clickedToolbarMenuItem = e.item;
18625  this.SaveClientState();
18626  var clickedToolbarInfo = { index: this.clickedToolbarIndex, name: this.GetToolbarNameByIndex(this.clickedToolbarIndex) },
18627   handled = this.control.RaiseToolbarItemClick(clickedToolbarInfo, e.item);
18628  if(!handled)
18629   this.ProcessToolbarItemClick(e);
18630  this.ResetState();
18631 },
18632 ProcessToolbarItemClick: function(e) {
18633  var item = e.item,
18634   command = this.GetItemCommand(item);
18635  if(this.IsExportItem(command))
18636   this.ToolbarExport(command);
18637 },
18638 ToolbarExport: function(exportCommand) {
18639  var exportFormat = this.GetExportFormat(exportCommand);
18640  this.control.ExportTo(exportFormat);
18641 },
18642 ProcessCustomToolbarItemClickOnServer: function(usePostBack) {
18643 }
18644});
18645var GridToolbarHelper = ASPx.CreateClass(CommandToolbarHelper, {
18646 constructor: function(grid) {
18647  this.constructor.prototype.constructor.call(this, grid, ASPx.ASPxClientGridExportFormat);
18648  this.grid = grid;
18649 },
18650 OnAfterCallback: function() {
18651  CommandToolbarHelper.prototype.OnAfterCallback.call(this);
18652  if(this.grid.IsLastCallbackProcessedAsEndless())
18653   this.OnUpdateEditEnabledChanged(this.IsUpdateEditItemEnabled());
18654 },
18655 ProcessCustomToolbarItemClickOnServer: function(usePostBack) {
18656  var args = [ "" ];
18657  if(usePostBack)
18658   this.SendToolbarPostback(args);
18659  else
18660   this.SendToolbarCallback(args);
18661 },
18662 OnBatchEditItemsStateChanged: function(state) {
18663  ASPx.CommandToolbarHelper.prototype.OnBatchEditItemsStateChanged.call(this, state);
18664  this.ForEachItem(null, function(item) {
18665   this.UpdateBatchPreviewItemsState(item, state);
18666  }.bind(this));
18667 },
18668 UpdateBatchPreviewItemsState: function(item, state) { },
18669 SendToolbarCallback: function(args) {
18670  this.grid.gridCallBack([ ASPxClientGridViewCallbackCommand.Toolbar ].concat(args));
18671 },
18672 SendToolbarPostback: function(toolbarCommand) {
18673  this.grid.gridPostBack([ASPxClientGridViewCallbackCommand.Toolbar, toolbarCommand]);
18674 },
18675 ToolbarStartEdit: function() {
18676  if(this.IsBatchEditMode()) {
18677   var visibleIndex = 0;
18678   var columnIndex = 0;
18679   var cellInfo = this.GetFocusedCellInfo();
18680   if(cellInfo) {
18681    visibleIndex = this.grid.ConvertKeyToVisibleIndex(cellInfo.recordKey);
18682    columnIndex = cellInfo.columnIndex;
18683   }
18684   this.grid.batchEditApi.StartEdit(visibleIndex, columnIndex);
18685  }
18686  else
18687   this.grid.StartEditItem(this.GetFocusedItemIndex());
18688 },
18689 ToolbarDeleteItem: function() {
18690  var focusedItemIndex = this.GetFocusedItemIndex();
18691  if(focusedItemIndex == -1 && this.IsBatchEditMode()) {
18692   var cellInfo = this.GetFocusedCellInfo();
18693   if(cellInfo)
18694    focusedItemIndex = this.grid.ConvertKeyToVisibleIndex(cellInfo.recordKey);
18695  }
18696  this.grid.DeleteGridItem(focusedItemIndex);
18697 },
18698 ToolbarDeleteSelectedVisibleItems: function() {
18699  this.ToolbarDeleteSelectedItemsInternal("DeleteSelectedVisible");
18700 },
18701 ToolbarDeleteSelectedItemsInternal: function(commandName) {
18702  if(!this.grid.ConfirmDeleteGridItem())
18703   return;
18704  if(this.IsBatchEditMode()) {
18705   var keys = this.grid.GetSelectedKeysOnPage();
18706   for(var i = 0, key; key = keys[i]; i++)
18707    this.grid.DeleteItemByKey(key);
18708  }
18709  else
18710   this.SendToolbarCallback([ commandName ]);
18711 },
18712 GetFocusedItemIndex: function(){
18713  return this.control._getFocusedItemIndex();
18714 },
18715 GetFocusedCellInfo: function() {
18716  var helper = this.control.GetCellFocusHelper();
18717  return helper ? helper.GetFocusedCellInfo() : null;
18718 },
18719 GetSelectedGridItemCount: function() {
18720  return this.control._getSelectedRowCount();
18721 },
18722 GetSelectedVisibleGridItemCount: function() {
18723  return this.control._getSelectedRowCountOnPage();
18724 },
18725 GetCustomizationWindow: function() {
18726  return this.grid.GetCustomizationWindow();
18727 },
18728 IsUpdateEditItemEnabled: function() {
18729  if(this.IsBatchEditMode())
18730   return this.grid.batchEditApi.HasChanges();
18731  return this.grid.allowEdit && this.grid.IsEditing();
18732 },
18733 IsEditingItem: function(visibleIndex){
18734  return this.control.IsEditingItem(visibleIndex);
18735 },
18736 GetBatchEditHelper: function() {
18737  return this.control.GetBatchEditHelper();
18738 },
18739 IsBatchEditMode: function(){
18740  return !!this.GetBatchEditHelper();
18741 },
18742 HasBatchEditFocusedCell: function() {
18743  return this.IsBatchEditMode() && this.GetFocusedCellInfo();
18744 }
18745});
18746ASPx.GridExportItemType = GridExportItemType;
18747ASPx.GridCommandMenuHelper = GridCommandMenuHelper;
18748ASPx.CommandToolbarHelper = CommandToolbarHelper;
18749ASPx.GridToolbarHelper = GridToolbarHelper;
18750})();
18751(function() {
18752var GridBaseEndlessPagingHelper = ASPx.CreateClass(null, {
18753 constructor: function(grid) {
18754  this.grid = grid;
18755  this.showLoadingPanelAtBottom = false;
18756  this.focusedRowIndexInfo =  { 
18757   beforeCallback: -1,
18758   underCallback: -1,
18759   afterCallback: -1
18760  };
18761  this.endlessCallbackComplete = false;
18762 },
18763 GetItemsContainer: function(){ return this.grid.GetMainTable(); },
18764 GetItemElements: function(){ 
18765  var container = this.GetItemsContainer();
18766  return container.tagName == "TABLE" ? container.rows : container.childNodes; 
18767 },
18768 GetEditingItemElements: function(){
18769  var elements = [ ];
18770  var row = this.grid.GetEditingRow();
18771  if(row)
18772   elements.push(row);
18773  return elements;
18774 },
18775 OnBeforeCallback: function(command) {
18776  this.endlessCallbackComplete = false;
18777  this.showLoadingPanelAtBottom = command === ASPxClientGridViewCallbackCommand.NextPage;
18778  this.focusedRowIndexInfo.beforeCallback = this.focusedRowIndexInfo.underCallback = this.GetFocusedItemIndex();
18779  this.focusedRowIndexInfo.afterCallback = -1;
18780  this.ResetActiveElement();
18781 },
18782 OnAfterCallback: function() {
18783  var grid = this.grid;
18784  var lpContainer = grid.GetEndlessPagingLPContainer();
18785  if(lpContainer)
18786   ASPx.SetElementDisplay(lpContainer, grid.pageIndex + 1 != grid.pageCount);
18787  this.CorrectItemIDs();
18788  this.focusedRowIndexInfo.afterCallback = this.GetFocusedItemIndex();
18789  this.CheckFocusedItemIndexChangedOnCallback();
18790  grid.UpdateItemsStyle();
18791 },
18792 GetFocusedItemIndex: function(){
18793  return -1;
18794 },
18795 ResetActiveElement: function() {
18796  var activeElement = ASPx.GetActiveElement();
18797  if(activeElement && ASPx.GetIsParent(this.GetItemsContainer(), activeElement)) {
18798   try { activeElement.blur(); } catch(e) { }
18799  }
18800 },
18801 CheckFocusedItemIndexChangedOnCallback: function() {
18802  var info = this.focusedRowIndexInfo;
18803  if(info.beforeCallback === info.underCallback && info.underCallback === info.afterCallback)
18804   return;
18805  if(info.beforeCallback !== info.afterCallback) {
18806   this.grid.ChangeFocusedItemStyle(info.beforeCallback, false);
18807   this.grid.ChangeFocusedItemStyle(info.underCallback, false);
18808  } else if(info.beforeCallback !== info.underCallback) {
18809   this.grid.ChangeFocusedItemStyle(info.beforeCallback, false);
18810   this.grid.ChangeFocusedItemStyle(info.underCallback, true);
18811   this.grid.focusedRowIndex = info.underCallback;
18812  }
18813  this.grid._setFocusedItemInputValue();
18814 },
18815 OnGridFocusedItemChanged: function() { 
18816  if(this.grid.InCallback())
18817   this.focusedRowIndexInfo.underCallback = this.GetFocusedItemIndex();
18818 },
18819 CorrectItemIDs: function() {
18820  var grid = this.grid;
18821  var itemElements = this.GetItemElements();
18822  if(itemElements.length == 0) return;
18823  var index = -1;
18824  var editingElements = this.GetEditingItemElements();
18825  for(var i = 0; i < itemElements.length; i++) {
18826   var item = itemElements[i];
18827   var id = item.id;
18828   if(!id) continue;
18829   var editingItemIndex = editingElements.indexOf(item);
18830   if(editingItemIndex > -1 && !this.IsEditRowHasDisplayedDataRow() && !grid.IsNewItemEditing()) {
18831    if(editingItemIndex == 0)
18832     index++;
18833    continue;
18834   }
18835   index = this.CorrectDataItemID(item, index);
18836  }
18837  ASPx.CacheHelper.DropCache(grid);
18838 },
18839 CorrectDataItemID: function(item, prevVisibleIndex){
18840  var supposedVisibleIndex = prevVisibleIndex;
18841  var regEx = this.grid.GetItemVisibleIndexRegExp();
18842  var matches = regEx.exec(item.id);
18843  if(matches && matches.length == 3) {
18844   var visibleIndex = parseInt(matches[2]);
18845   if(this.IsNewRecord(visibleIndex))
18846    return supposedVisibleIndex;
18847   if(this.IsDataItem(item))
18848    supposedVisibleIndex++;
18849   if(visibleIndex != supposedVisibleIndex)
18850    item.id = item.id.replace(regEx, "$1" + supposedVisibleIndex);
18851  }
18852  return supposedVisibleIndex;
18853 },
18854 IsEditRowHasDisplayedDataRow: function() { return false; },
18855 IsDataItemID: function(id){
18856  return false;
18857 },
18858 IsDataItem: function(element) {
18859  if(element)
18860   return this.IsDataItemID(element.id);
18861  return false;
18862 },
18863 IsBatchEditMode: function() {
18864  return ASPx.GridCommonUtils.IsBatchEditMode(this.grid);
18865 },
18866 IsNewRecord: function(key) {
18867  return this.IsBatchEditMode() && this.grid.GetBatchEditHelper().IsNewRecord(key);
18868 },
18869 NeedShowLoadingPanelAtBottom: function(){
18870  return this.showLoadingPanelAtBottom && this.grid.GetEndlessPagingLPContainer();
18871 },
18872 OnCallback: function(str) {
18873  if(!this.grid.GetMainElement())
18874   return;
18875  var result = eval(str.slice(str.indexOf("|") + 1));
18876  this.UpdateKeyValues(result.pageKeys);
18877  this.UpdateGroupState(result.groupState);
18878  this.UpdateCellMergingState(result.cellMergeState);
18879  this.UpdateGroupLevelState(result.groupLevelState);
18880  if(result.removeEditForm)
18881   this.RemoveEditFormRow();
18882  if(result.html)
18883   ASPx.SetInnerHtml(this.grid.GetEndlessPagingUpdatableContainer(), result.html);
18884  this.UpdateDataItems(result.dataTableInfo);
18885  this.grid.cButtonIDs = result.cButtonIDs;
18886  this.endlessCallbackComplete = true;
18887 },
18888 UpdateDataItems: function(updateInfo) {
18889  if(!updateInfo || updateInfo.length == 0)
18890   return;
18891  for(var i = 0; i < updateInfo.length; i++)
18892   this.UpdateDataItemsCore(updateInfo[i]);
18893 },
18894 UpdateDataItemsCore: function(updateInfo) {
18895  if(!updateInfo) 
18896   return;
18897  var removeIndex = updateInfo[0];
18898  var removeCount = updateInfo[1];
18899  var addIndex = updateInfo[2];
18900  var html = updateInfo[3];
18901  this.RemoveDataItems(removeIndex, removeCount);
18902  if(addIndex < 0 || !html)
18903   return;
18904  var startItem = null;
18905  var visibleIndex = addIndex;
18906  do {
18907   startItem = this.grid.GetItem(visibleIndex);
18908  } while(!startItem && ++visibleIndex < this.grid.pageRowCount);
18909  var itemElements = this.GetItemElements();
18910  var startRowIndex = startItem ? ASPx.Data.ArrayIndexOf(itemElements, startItem) : itemElements.length;
18911  this.InsertItems(this.GetItemsContainer(), html, startRowIndex);
18912 },
18913 RemoveDataItems: function(removeIndex, removeCount) {
18914  if(removeIndex < 0 || removeCount <= 0)
18915   return;
18916  var startItem = this.grid.GetItem(removeIndex);
18917  if(!startItem) {
18918   startItem = this.grid.GetItem(++removeIndex);
18919   removeCount--;
18920  }
18921  var endItem = null;
18922  var visibleIndex = removeIndex + removeCount;
18923  do {
18924   endItem = this.grid.GetItem(visibleIndex);
18925  } while(!endItem && ++visibleIndex < this.grid.pageRowCount);
18926  var itemElements = this.GetItemElements();
18927  var startRowIndex = ASPx.Data.ArrayIndexOf(itemElements, startItem);
18928  var endRowIndex = endItem ? ASPx.Data.ArrayIndexOf(itemElements, endItem) : itemElements.length;
18929  for(var i = endRowIndex - 1; i >= startRowIndex && startRowIndex >= 0; i--)
18930   this.RemoveItemFromLayout(itemElements[i]);
18931 },
18932 InsertItems: function(container, rowsHtml, index) {
18933  if(!container || container.tagName != "TABLE")
18934   return;
18935  ASPx.InsertRowsBefore(container, rowsHtml, index);
18936 },
18937 RemoveEditFormRow: function() {
18938  var editingElements = this.GetEditingItemElements();
18939  for(var i = 0; i < editingElements.length; i++)
18940   this.RemoveItemFromLayout(editingElements[i]);
18941  ASPx.RemoveElement(this.grid.GetEditingErrorItem());
18942 },
18943 RemoveItemFromLayout: function(itemElement) {
18944  ASPx.RemoveElement(itemElement);
18945 },
18946 UpdateKeyValues: function(updateInfo) {
18947  this.UpdateArray(this.grid.keys, updateInfo);
18948  this.grid.stateObject.keys = this.grid.keys;
18949  this.grid.EnsureRowKeys();
18950 },
18951 UpdateGroupState: function(updateInfo) {
18952  this.UpdateArray(this.grid.stateObject.endlessPagingGroupState, updateInfo);
18953 },
18954 UpdateCellMergingState: function(cellMergeState){ },
18955 UpdateGroupLevelState: function(groupLevelState) { },
18956 UpdateArray: function(array, updateInfo) {
18957  if(!updateInfo)
18958   return;
18959  var removeIndex = updateInfo[0];
18960  var removeCount = updateInfo[1];
18961  var addIndex = updateInfo[2];
18962  var newArray = updateInfo[3];
18963  for(var i = 0; i < removeCount; i++)
18964   ASPx.Data.ArrayRemoveAt(array, removeIndex);
18965  for(var i = 0; i < newArray.length; i++)
18966   ASPx.Data.ArrayInsert(array, newArray[i], addIndex + i);
18967 }
18968});
18969var CardViewEndlessPagingHelper = ASPx.CreateClass(GridBaseEndlessPagingHelper, {
18970 constructor: function(grid){
18971  this.constructor.prototype.constructor.call(this, grid);
18972  grid.FocusedCardChanged.AddHandler(function() { this.OnGridFocusedItemChanged(); }.aspxBind(this));
18973 },
18974 IsFlowLayout: function(){
18975  var mainElement = this.grid.GetMainTable();
18976  return mainElement && ASPx.ElementHasCssClass(mainElement, "dxcvFT");
18977 },
18978 IsBreakpointsLayout: function() {
18979  var mainElement = this.grid.GetMainTable();
18980  return mainElement && ASPx.ElementHasCssClass(mainElement, "dxcvBPT");
18981 },
18982 IsTableLayout: function() {
18983  return !this.IsFlowLayout() && !this.IsBreakpointsLayout();
18984 },
18985 GetBreakpointsLayoutItemContainer: function(itemElement) {
18986  if(this.IsBreakpointsLayoutContainer(itemElement.parentNode))
18987   return itemElement.parentNode;
18988  return itemElement;
18989 },
18990 GetItemsContainer: function(){
18991  if(this.IsTableLayout())
18992   return GridBaseEndlessPagingHelper.prototype.GetItemsContainer.call(this);
18993  return this.grid.GetMainTable().rows[0].cells[0];
18994 },
18995 GetItemElements: function(){ 
18996    if(this.IsFlowLayout())
18997     return GridBaseEndlessPagingHelper.prototype.GetItemElements.call(this);
18998  if(this.IsBreakpointsLayout())
18999   return this.GetBreakpointsLayoutItemElements();
19000  return this.GetDataCardCells();
19001 },
19002 GetBreakpointsLayoutItemElements: function() {
19003  var itemElements = GridBaseEndlessPagingHelper.prototype.GetItemElements.call(this),
19004   result = [];
19005  for(var i = 0; i < itemElements.length; i++) {
19006   var element = itemElements[i];
19007   if(this.IsLayoutItem(element))
19008    result.push(element);
19009   else if(this.IsBreakpointsLayoutContainer(element)) {
19010    var innerDataItemsElements = Array.prototype.slice.call(element.children).filter(this.IsLayoutItem.bind(this));
19011    result = result.concat(innerDataItemsElements);
19012   }
19013  }
19014  return result;
19015 },
19016 GetDataCardCells: function(){
19017  return ASPx.GetNodesByPartialClassName(this.grid.GetMainTable(), "dxcvCard");
19018 },
19019 RemoveItemFromLayout: function(itemElement) {
19020  var element = itemElement;
19021  if(this.IsBreakpointsLayout() && this.IsLayoutItem(itemElement))
19022   element = this.GetBreakpointsLayoutItemContainer(itemElement);
19023  GridBaseEndlessPagingHelper.prototype.RemoveItemFromLayout.call(this, element);
19024 },
19025 RemoveDataItems: function(removeIndex, removeCount){
19026  GridBaseEndlessPagingHelper.prototype.RemoveDataItems.call(this, removeIndex, removeCount);
19027  if(this.IsTableLayout())
19028   this.UpdateTableLayout(this.GetDataCardCells());
19029 },
19030 InsertItems: function(container, itemsHtml, index){
19031  if(this.IsTableLayout()) {
19032   var cells = this.GetDataCardCells();
19033   this.UpdateTableLayout(this.InsertDataCellsHtml(cells, itemsHtml, index));
19034  }
19035  else
19036   this.InsertDivBasedItems(container, itemsHtml, index);
19037 },
19038 InsertDivBasedItems: function(container, itemsHtml, index){
19039  var item;
19040  if(index >= 0 && index < container.children.length)
19041   item = container.children[index];
19042  if(item)
19043   item.insertAdjacentHTML("beforeBegin", itemsHtml);
19044  else
19045   container.insertAdjacentHTML("beforeEnd", itemsHtml);
19046 }, 
19047 InsertDataCellsHtml: function(cells, cellsHtml, index){
19048  if(!cellsHtml)
19049   return cells;
19050  var table = this.grid.GetMainTable();
19051  var tbody = table.tBodies[0];
19052  var row = document.createElement("TR");
19053  var cell = document.createElement("TD");
19054  cell.innerHTML = "<table><tbody> <tr>" + cellsHtml + "</tr></tbody></table>";
19055  tbody.appendChild(row);
19056  row.appendChild(cell);
19057  var newTable = ASPx.GetNodeByTagName(cell, "TABLE", 0);
19058  var newCells = Array.prototype.slice.call(newTable.rows[0].cells);
19059  ASPx.RemoveElement(row);
19060  return this.InsertRange(cells, newCells, index);
19061 },
19062 InsertRange: function(items, newItems, index) {
19063  var left = items.slice(0, index);
19064  var middle = newItems;
19065  var right = items.slice(index);
19066  return left.concat(middle.concat(right));
19067 },
19068 UpdateTableLayout: function(cells){
19069  if(!cells) return;
19070  var table = this.grid.GetMainTable();
19071  var tbody = ASPx.GetChildByTagName(table, "TBODY");
19072  while(tbody.firstChild)
19073   ASPx.RemoveElement(tbody.firstChild);
19074  var colCount = this.grid.colCount * 2 - 1;
19075  var row;
19076  for(var i = 0; i < cells.length; i++) {
19077   if(!row || row.cells.length >= colCount) {
19078    if(i > 0) 
19079     tbody.appendChild(this.GetSeparatorRow());
19080    row = document.createElement("TR");
19081    tbody.appendChild(row);
19082   }
19083   var cell = cells[i];
19084   row.appendChild(cell);
19085   if(row.cells.length < colCount)
19086    row.appendChild(this.GetSeparatorCell());
19087   if(this.IsNewCard(cell))
19088    this.FillRowByEmptyCells(row, colCount);
19089  }
19090  this.FillRowByEmptyCells(row, colCount);
19091 },
19092 FillRowByEmptyCells: function(row, requireCellCount) { 
19093  if(!row) return;
19094  var startIndex = row.cells.length;
19095  for(var i = startIndex; i < requireCellCount; i++) {
19096   var cell = i % 2 == 0 ? this.GetEmptyHiddenCard() : this.GetSeparatorCell();
19097   row.appendChild(cell);
19098    }
19099 },
19100 GetEmptyHiddenCard: function() { return this.grid.GetEtalonEmptyHiddenCard().cloneNode(true); },
19101 GetSeparatorCell: function() { return this.grid.GetEtalonSeparatorCell().cloneNode(true); },
19102 GetSeparatorRow: function() { return this.grid.GetEtalonSeparatorRow().cloneNode(true); },
19103 IsCardID: function(id) { return id.indexOf(this.grid.CardID) > 0; },
19104 IsGroupRowID: function(id) { return id.indexOf(this.grid.GroupRowID) > 0; },
19105 IsEditCardID: function(id) { return id.indexOf(this.grid.EditingCardID) > 0; },
19106 IsDataItemID: function(id) { return this.IsCardID(id) || this.IsGroupRowID(id); },
19107 IsLayoutItemID: function(id) { return this.IsDataItemID(id) || this.IsEditCardID(id); },
19108 IsLayoutItem: function(element) {
19109  if(element)
19110   return this.IsLayoutItemID(element.id);
19111  return false;
19112 },
19113 IsNewCard: function(card) {
19114  var grid = this.grid;
19115  var newCardLayoutID = grid.name + "_" + grid.CardLayoutID + grid.NewCardVisibleIndex;
19116  return card.firstChild && card.firstChild.id == newCardLayoutID;
19117 },
19118 IsBreakpointsLayoutContainer: function(element) {
19119  var breakpointsHelper = ASPx.BreakpointsLayoutCssHelper;
19120  if(breakpointsHelper)
19121   return ASPx.ElementHasCssClass(element, breakpointsHelper.BreakpointsLayoutMarkerClass);
19122  return false;
19123 },
19124 GetFocusedItemIndex: function(){
19125  return this.grid.GetFocusedCardIndex();
19126 }
19127});
19128var GridViewEndlessPagingHelper = ASPx.CreateClass(GridBaseEndlessPagingHelper, {
19129 constructor: function(grid){
19130  this.constructor.prototype.constructor.call(this, grid);
19131  grid.FocusedRowChanged.AddHandler(function() { this.OnGridFocusedItemChanged(); }.aspxBind(this));
19132 },
19133 GetFocusedItemIndex: function(){
19134  return this.grid.GetFocusedRowIndex();
19135 },
19136 IsEditRowHasDisplayedDataRow: function() { return this.grid.IsEditRowHasDisplayedDataRow(); },
19137 IsDataItemID: function(id){
19138  return id.indexOf(ASPx.GridViewConsts.GroupRowID) > 0 || id.indexOf(ASPx.GridViewConsts.DataRowID) > 0;
19139 },
19140 GetItemElements: function() {
19141  if(this.IsBatchEditMode()) {
19142   var helper = this.grid.GetBatchEditHelper();
19143   if(helper && helper.IsChangesViewVisible())
19144    return helper.GetSavedDataRowsLayout();
19145  }
19146  return GridBaseEndlessPagingHelper.prototype.GetItemElements.call(this);
19147 },
19148 GetEditingItemElements: function(){
19149  return this.grid.GetEditingRowElements();
19150 },
19151 UpdateCellMergingState: function(cellMergeState) { 
19152  if(!cellMergeState || cellMergeState.length !== 3) 
19153   return;
19154  var serverInfo = cellMergeState[0];
19155  var splittedColumnIndices = cellMergeState[1];
19156  var prevRowVisibleIndex = cellMergeState[2];
19157  var layoutHelper = this.grid.GetLayoutHelper();
19158  var prevState = layoutHelper.GetMergedCellServerInfo();
19159  if(Object.keys(prevState).length === 0) {
19160   layoutHelper.SetMergedCellServerInfo(serverInfo);
19161   return;
19162  }
19163  for(var columnIndex in prevState) {
19164   if(!prevState.hasOwnProperty(columnIndex)) continue;
19165   columnIndex = parseInt(columnIndex);
19166   var oldColumnIntervals = prevState[columnIndex];
19167   var newColumnIntervals = serverInfo[columnIndex];
19168   if(!newColumnIntervals || newColumnIntervals.length === 0)
19169    continue;
19170   var lastOldInterval = oldColumnIntervals[oldColumnIntervals.length - 1];
19171   var requireMergeIntervals = splittedColumnIndices.indexOf(columnIndex) > -1 && lastOldInterval[1] === prevRowVisibleIndex;
19172   for(var i = 0; i < newColumnIntervals.length; i++) {
19173    var newInterval = newColumnIntervals[i];
19174    if(i === 0) {
19175     if(requireMergeIntervals) {
19176      newInterval[0] = lastOldInterval[0];
19177      ASPx.Data.ArrayRemove(oldColumnIntervals, lastOldInterval);
19178     }
19179     var cell = layoutHelper.GetCell(newInterval[0], columnIndex, ASPx.GridView
19179RowType.Data);
19180     var newRowSpan = newInterval[1] - newInterval[0] + 1;
19181     ASPx.Attr.ChangeCellSpanCount(cell, newRowSpan);
19182    }
19183    oldColumnIntervals.push(newInterval);
19184   }
19185  }
19186 },
19187 UpdateGroupLevelState: function(groupLevelState) { 
19188  if(!groupLevelState) return;
19189  var layoutHelper = this.grid.GetLayoutHelper();
19190  var prevState = layoutHelper.GetGroupLevelServerInfo();
19191  if(Object.keys(prevState).length === 0) {
19192   layoutHelper.SetGroupLevelServerInfo(groupLevelState);
19193   return;
19194  }
19195  for(var level in groupLevelState) {
19196   if(!groupLevelState.hasOwnProperty(level)) continue;
19197   level = parseInt(level);
19198   var oldIntervals = prevState[level];
19199   var newIntervals = groupLevelState[level];
19200   if(!oldIntervals || oldIntervals.length === 0) {
19201    prevState[level] = newIntervals;
19202    continue;
19203   }
19204   var firstNewInterval = newIntervals[0];
19205   var firstIntervalStart = firstNewInterval[0];
19206   var result = [ ];
19207   for(var i = 0; i < oldIntervals.length; i++) {
19208    var interval = oldIntervals[i];
19209    var start = interval[0];
19210    var end = interval[1];
19211    if(end < firstIntervalStart) {
19212     result.push(interval);
19213    } else {
19214     firstNewInterval[0] = Math.min(start, firstIntervalStart);
19215     break;
19216    }
19217   }
19218   prevState[level] = result.concat(newIntervals);
19219  }
19220  layoutHelper.SetGroupLevelServerInfo(prevState);
19221 },
19222 CorrectDataItemID: function(item, prevVisibleIndex){
19223  if(!this.grid.IsBandedDataRowID(item.id))
19224   return GridBaseEndlessPagingHelper.prototype.CorrectDataItemID.call(this, item, prevVisibleIndex);
19225  var supposedVisibleIndex = prevVisibleIndex;
19226  var regEx = this.grid.GetItemVisibleIndexRegExp();
19227  var matches = regEx.exec(item.id);
19228  if(matches && matches.length == 3) {
19229   var visibleIndex = parseInt(matches[2]);
19230   var level = this.grid.GetBandedDataRowLevelByID(item.id);
19231   if(level < 1)
19232    supposedVisibleIndex++;
19233   if(visibleIndex != supposedVisibleIndex)
19234    item.id = item.id.replace(regEx, "$1" + supposedVisibleIndex + "_" + level);
19235  }
19236  return supposedVisibleIndex;
19237 },
19238 RemoveItemFromLayout: function(itemElement) {
19239  if(this.IsBatchEditMode()) {
19240   var helper = this.grid.GetBatchEditHelper();
19241   var recordKey = helper.owner.GetRecordKeyByElement(itemElement);
19242   helper.MoveEditorsFromDeletingItem(recordKey);
19243  }
19244  GridBaseEndlessPagingHelper.prototype.RemoveItemFromLayout.call(this, itemElement);
19245 },
19246 RemoveDataItems: function(removeIndex, removeCount) { 
19247  GridBaseEndlessPagingHelper.prototype.RemoveDataItems.call(this, removeIndex, removeCount);
19248  if(this.grid.hasDetailRows && removeIndex >= 0 && removeCount > 0) {
19249   var indices = ASPx.Data.Range(removeCount, removeIndex);
19250   for(var i = 0; i < indices.length; i++)
19251    ASPx.RemoveElement(this.grid.GetDetailRow(indices[i]));
19252  }
19253 }
19254});
19255ASPx.GridViewEndlessPagingHelper = GridViewEndlessPagingHelper;
19256ASPx.CardViewEndlessPagingHelper = CardViewEndlessPagingHelper;
19257})();
19258
19259(function() {
19260var GridSortOrder = { None: 0, Ascending: 1, Descending: 2 };
19261var ASPxClientGridColumnMovingTargetPosition = {
19262 Right: 0,
19263 Left: 1,
19264 Top: 2,
19265 Bottom: 3
19266};
19267var ASPxClientGridBase = ASPx.CreateClass(ASPxClientControl, {
19268 MainTableID: "DXMainTable",
19269 CustomizationWindowSuffix: "_custwindow",
19270 EditingRowID: "_DXEditingRow",
19271 EditingErrorItemID: "DXEditingErrorItem", 
19272 EmptyHeaderSuffix: "_emptyheader",
19273 PagerBottomID: "DXPagerBottom",
19274 PagerTopID: "DXPagerTop",
19275 SearchEditorID: "DXSE",
19276 SelectButtonID: "DXSelBtn",
19277 HeaderFilterButtonClassName: "dxgv__hfb",
19278 CommandColumnItemClassName: "dxgv__cci",
19279 DetailGridSuffix: "dxdt",
19280 FixedColumnsDivID: "DXFixedColumnsDiv",
19281 FixedColumnsContentDivID: "DXFixedColumnsContentDiv",
19282 ProgressBarDisplayControlIDFormat: "PBc{0}i{1}",
19283 AccessibleFilterRowButtonID: "AFRB",
19284 RequireKeyFieldNameText: "Error while trying to perform a CRUD operation with an incorrect or unspecified KeyFieldName property value.",
19285 EtalonBatchRecordPostFix: "dxgbeEtalonRecord",
19286 InvalidItemIndex: -23061988,
19287 constructor: function(name){
19288  this.constructor.prototype.constructor.call(this, name);
19289  this.callBacksEnabled = true;
19290  this.custwindowLeft = null;
19291  this.custwindowTop = null;
19292  this.custwindowVisible = null;
19293  this.userChangedSelection = false;
19294  this.confirmDelete = "";
19295  this.editorIDList = [ ];
19296  this.keys = [ ];
19297  this.lastMultiSelectIndex = -1;
19298  this.mainTableClickData = {
19299   processing: false,
19300   focusChanged: false,
19301   selectionChanged: false
19302  };
19303  this.afterCallbackRequired = false;
19304  this.enableHeaderFilterCaching = true;
19305  this.supportGestures = true;
19306  this.checkBoxImageProperties = null;
19307  this.internalCheckBoxCollection = null;
19308  this.sizingConfig.adjustControl = true;
19309  this.lookupBehavior = false;
19310  this.isAccessibleRowEditing = false;
19311  this.batchEditApi = this.CreateBatchEditApi();
19312  this.CustomButtonClick = new ASPxClientEvent();
19313  this.SelectionChanged = new ASPxClientEvent();
19314  this.ColumnSorting = new ASPxClientEvent();
19315  this.ColumnGrouping = new ASPxClientEvent();
19316  this.CustomizationWindowCloseUp = new ASPxClientEvent();
19317  this.InternalCheckBoxClick = new ASPxClientEvent();
19318  this.KeyDown = new ASPx.ASPxClientGridKeyboardEvent(this);
19319  this.KeyPress = new ASPx.ASPxClientGridKeyboardEvent(this);
19320  this.KeyUp = new ASPx.ASPxClientGridKeyboardEvent(this);
19321  this.BatchEditStartEditing = new ASPxClientEvent();
19322  this.BatchEditEndEditing = new ASPxClientEvent();
19323  this.BatchEditConfirmShowing = new ASPxClientEvent();
19324  this.BatchEditTemplateCellFocused = new ASPxClientEvent();
19325  this.BatchEditChangesSaving = new ASPxClientEvent();
19326  this.BatchEditChangesCanceling = new ASPxClientEvent();
19327  this.BatchEditSummaryDisplayText = new ASPxClientEvent();
19328  this.FocusedCellChanging = new ASPxClientEvent();
19329  this.CellSelectionChanging = new ASPxClientEvent();
19330  this.ClipboardCellPasting = new ASPxClientEvent();
19331  this.ToolbarItemClick = new ASPxClientEvent();
19332  this.pendingCommands = [ ];
19333  this.pageRowCount = 0;
19334  this.pageRowSize = 0;
19335  this.pageIndex = 0;
19336  this.pageCount = 1;
19337  this.allowDelete = false;
19338  this.allowEdit = false;
19339  this.allowInsert = false;
19340  this.allowFocusedRow = false;
19341  this.allowFocusedCell = false;
19342  this.allowSelectionCell = false;
19343  this.allowSelectByItemClick = false;
19344  this.allowSelectSingleRowOnly = false;
19345  this.allowMultiColumnAutoFilter = false;
19346  this.focusedRowIndex = -1;
19347  this.selectedWithoutPageRowCount = 0;
19348  this.selectAllSettings = [ ];
19349  this.selectAllBtnStateWithoutPage = null;
19350  this.visibleStartIndex = 0;
19351  this.columns = [ ];
19352  this.columnResizeMode = ASPx.ColumnResizeMode.None;
19353  this.horzScroll = ASPx.ScrollBarMode.Hidden;
19354  this.vertScroll = ASPx.ScrollBarMode.Hidden;
19355  this.scrollToRowIndex = -1;
19356  this.useEndlessPaging = false;
19357  this.allowBatchEditing = false;
19358  this.batchEditClientState = { };
19359  this.resetScrollTop = false;
19360  this.callbackOnFocusedRowChanged = false;
19361  this.callbackOnSelectionChanged = false;
19362  this.autoFilterDelay = 1200;
19363  this.searchFilterDelay = 1200;
19364  this.allowSearchFilterTimer = true;
19365  this.editState = 0;
19366  this.kbdHelper = null;
19367  this.enableKeyboard = false;
19368  this.keyboardLock = false;
19369  this.accessKey = null;
19370  this.customKbdHelperName = null;
19371  this.endlessPagingHelper = null;
19372  this.toolbarHelper = null;
19373  this.icbFocusedStyle = null;
19374  this.pendingEvents = [ ];
19375  this.customSearchPanelEditorID = null;
19376  this.searchPanelFilter = null;
19377  this.isDetailGrid = null;
19378  this.rowHotTrackStyle = null;
19379  this.updateButtonName = "";
19380  this.cancelButtonName = "";
19381  this.isAccessibleFilterRowMenu = false;
19382  this.userHandledCallbackError = false;
19383 },
19384 HasHorzScroll: function() { return this.horzScroll != ASPx.ScrollBarMode.Hidden; },
19385 HasVertScroll: function() { return this.vertScroll != ASPx.ScrollBarMode.Hidden; },
19386 HasScrolling: function() { return this.HasHorzScroll() || this.HasVertScroll(); },
19387 AllowResizing: function() { return this.columnResizeMode != ASPx.ColumnResizeMode.None && this.showColumnHeaders; },
19388 GetGridTD: function() { 
19389  var table = this.GetMainElement();
19390  if(!table) return null;
19391  return table.rows[0].cells[0];
19392 },
19393 GetArrowDragDownImage: function() { return this.GetChildElement("IADD"); },
19394 GetArrowDragUpImage: function() { return this.GetChildElement("IADU"); },
19395 GetArrowDragLeftImage: function() { return this.GetChildElement("IADL"); },
19396 GetArrowDragRightImage: function() { return this.GetChildElement("IADR"); },
19397 GetArrowDragFieldImage: function() { return this.GetChildElement("IDHF"); },
19398 GetEndlessPagingUpdatableContainer: function() { return this.GetChildElement("DXEPUC"); },
19399 GetEndlessPagingLPContainer: function() { return this.GetChildElement("DXEPLPC"); },
19400 GetBatchEditorsContainer: function() { return this.GetChildElement("DXBEsC"); },
19401 GetBatchEditorContainer: function(columnIndex) { return this.GetChildElement("DXBEC" + columnIndex); }, 
19402 GetLoadingPanelDiv: function() {  return this.GetChildElement("LPD"); },
19403 GetFixedColumnsDiv: function() {  return this.GetChildElement(this.FixedColumnsDivID); },
19404 GettItem: function(visibleIndex) { return null; },
19405 GetDataItemIDPrefix: function() { },
19406 GetEmptyDataItemIDPostfix: function() { },
19407 GetEmptyDataItem: function() { return this.GetChildElement(this.GetEmptyDataItemIDPostfix()); },
19408 GetDataRowSelBtnIDPrefix: function() { return "_" + this.SelectButtonID; },
19409 GetDataRowSelBtn: function(index) { return this.FindSelectButton(this.GetItem(index), this.GetDataRowSelBtnIDPrefix(index)); },
19410 FindSelectButton: function(container, idPrefix) { return container && container.querySelector("input[id^='" + this.name + idPrefix + "']"); },
19411 GetSelectAllBtn: function(index) { return this.GetChildElement("DXSelAllBtn" + index); },
19412 GetMainTable: function() { return this.GetChildElement(this.MainTableID); },
19413 GetLoadingPanelContainer: function() { return this.GetChildElement("DXLPContainer"); },
19414 GetStatusBar: function() { return this.GetChildElement("DXStatus"); },
19415 GetGroupPanel: function() { return this.GetChildElement("grouppanel"); },
19416 GetHeader: function(columnIndex, inGroupPanel) { 
19417  var id = "col" + columnIndex;
19418  if(inGroupPanel)
19419   id = "group" + id;
19420  return this.GetChildElement(id); 
19421 },
19422 GetHeaderRow: function(index) {
19423  return ASPx.GetElementById(this.name + "_" + ASPx.GridViewConsts.HeaderRowID + index);
19424 },
19425 GetEditingRow: function(obj) { return ASPx.GetElementById((obj ? obj.name : this.name) + this.EditingRowID); },
19426 GetEditingErrorItem: function(obj, visibleIndex) { 
19427  var id = (obj ? obj.name : this.name) + "_" + this.EditingErrorItemID;
19428  if(ASPx.IsExists(visibleIndex))
19429   id = id + visibleIndex;
19430  return ASPx.GetElementById(id); 
19431 },
19432 GetEditFormTable: function() { return ASPx.GetElementById(this.name + "_DXEFT"); },
19433 GetCustomizationWindow: function() { return ASPx.GetControlCollection().Get(this.name + this.CustomizationWindowSuffix); },
19434 GetCustomizationWindowElement: function() {
19435  var win = this.GetCustomizationWindow();
19436  return win ? win.GetWindowElement(-1) : null;  
19437 },
19438 GetParentRowsWindow: function() { return ASPx.GetControlCollection().Get(this.name + "_DXparentrowswindow"); },
19439 GetEditorPrefix: function() { return "DXEditor"; },
19440 GetPopupEditForm: function() { return ASPx.GetControlCollection().Get(this.name  + "_DXPEForm"); },
19441 GetFilterRowMenu: function() { return ASPx.GetControlCollection().Get(this.name + "_DXFilterRowMenu"); },
19442 GetFilterRow: function() { return ASPx.GetControlCollection().Get(this.name + "_DXFilterRow"); },
19443 GetFilterControlPopup: function() { return ASPx.GetControlCollection().Get(this.name + "_DXPFCForm"); },
19444 GetFilterControl: function() { return ASPx.GetControlCollection().Get(this.name +  "_DXPFCForm_DXPFC"); }, 
19445 GetHeaderFilterPopup: function() { return ASPx.GetControlCollection().Get(this.name + "_DXHFP"); },
19446 GetToolbarByName: function(name){
19447  return this.GetToolbarHelper().GetToolbarByName(name);
19448 },
19449 GetToolbar: function(index){
19450  return ASPx.GetControlCollection().Get(this.name + "_DXCTMenu" + index);
19451 },
19452 IsBatchEditDeletedItem: function(visibleIndex) {
19453  var helper = this.GetBatchEditHelper();
19454  return helper && helper.IsDeletedRecord(this.ConvertVisibleIndexToKey(visibleIndex));
19455 },
19456 IsEmptyHeaderID: function(id) { return false; },
19457 IsDataItem: function(visibleIndex) { return !!this.GetItem(visibleIndex); },
19458 GetSearchEditor: function() { 
19459  var editor = this.GetCustomSearchPanelEditor() || this.GetGridSearchEditor();
19460  if(editor && editor.GetMainElement())
19461   return editor;
19462  return null;
19463 },
19464 GetGridSearchEditor: function() { return ASPx.GetControlCollection().Get(this.name + "_" + this.SearchEditorID); },
19465 GetCustomSearchPanelEditor: function() { return ASPx.GetControlCollection().Get(this.customSearchPanelEditorID); },
19466 SetSearchPanelCustomEditor: function(editor) { this.GetFilterHelper().SetSearchPanelCustomEditor(editor); },
19467 GetEditorByColumnIndex: function(colIndex) {
19468  var list = this._getEditors();
19469  for(var i = 0; i < list.length; i++) {
19470   if(this.tryGetNumberFromEndOfString(list[i].name).value === colIndex)
19471    return list[i];
19472  }
19473  return null;
19474 },
19475 GetProgressBarControlID: function(visibleIndex, columnIndex) { return ASPx.Str.ApplyReplacement(this.ProgressBarDisplayControlIDFormat, [["{0}", columnIndex], ["{1}", visibleIndex]]); },
19476 GetProgressBarControl: function(visibleIndex, columnIndex) { return ASPx.GetControlCollection().Get(this.name + "_" + this.GetProgressBarControlID(visibleIndex, columnIndex)); },
19477 CreateBatchEditApi: function() { },
19478 SetProperties: function(properties, obj) {
19479  ASPxClientControl.prototype.SetProperties.call(this, properties, obj);
19480  this.CreateColumns();
19481  this.CreateToolbars();
19482  this.Invalidate();
19483 },
19484 CreateColumns: function() {
19485  this.columns = [ ];
19486  for(var i = 0; i < this.columnProp.length; i++)
19487   this.columns.push(this.CreateColumn(this.columnProp[i]));
19488 },
19489 CreateToolbars: function(){
19490  this.toolbars = [ ];
19491  for(var i = 0; this.toolbarsProp && i < this.toolbarsProp.length; i++){
19492   var toolbarInfo = { index: this.toolbarsProp[i][0], name: this.toolbarsProp[i][1] };
19493   if(this.GetToolbar(toolbarInfo.index))
19494    this.toolbars.push(toolbarInfo);
19495  }
19496 },
19497 CreateColumn: function(prop) { },
19498 IsFilterLocked: function() { return this.GetFilterHelper().IsFilterLocked(); },
19499 LockFilter: function() { this.GetFilterHelper().LockFilter(); },
19500 UnlockFilter: function() { this.GetFilterHelper().UnlockFilter(); },
19501 InlineInitialize: function() {
19502  ASPxClientControl.prototype.InlineInitialize.call(this);
19503  this.InitializeBubbleEvents();
19504 },
19505 InitializeBubbleEvents: function() {
19506  this.AttachMainTableClickEvents();
19507 },
19508 Initialize: function() {
19509  ASPxClientControl.prototype.Initialize.call(this);
19510  this.GetFilterHelper().OnInit();
19511  this.GetToolbarHelper().OnInit();
19512  if(this.enabled)
19513   this.SetHeadersClientEvents();
19514  this.EnsureRowKeys();
19515  this._setFocusedItemInputValue();
19516  this.InitializeAccessibilityEvents();
19517  this.InitializeCommandColumnHeaderLinkEvents();
19518  this.EnsureRowHotTrackItems();
19519  if(this.checkBoxImageProperties){
19520   this.CreateInternalCheckBoxCollection();
19521   this.UpdateSelectAllCheckboxesState();
19522  }
19523  this.CheckPendingEvents();
19524  this.CheckEndlessPagingLoadNextPage();
19525  this.PrepareCommandButtons();
19526  var batchEditHelper = this.GetBatchEditHelper();
19527  if(batchEditHelper)
19528   batchEditHelper.Init();
19529  var cellSelectionHelper = this.GetCellSelectionHelper();
19530  if(cellSelectionHelper)
19531   cellSelectionHelper.Update();
19532  var cellFocusHelper = this.GetCellFocusHelper();
19533  if(cellFocusHelper)
19534   cellFocusHelper.Update();
19535  var clipboardHelper = this.GetClipboardHelper();
19536  if(clipboardHelper)
19537   clipboardHelper.Initialize();
19538  this.InitKbdHelper();
19539  window.setTimeout(this.scrollToElementAsignedFromServer.bind(this), 0);
19540 },
19541 scrollToElementAsignedFromServer: function () {
19542  if(this.shouldScrollToNewRow) {
19543   this.GetScrollHelper().MakeRowVisible(this.GetEditingRow());
19544   this.shouldScrollToNewRow = false;
19545  }
19546  if(this.scrollToRowIndex >= 0) {
19547   this.MakeRowVisible(this.scrollToRowIndex);
19548   this.scrollToRowIndex = -1;
19549  }
19550 },
19551 AttachEventToEditor: function(columnIndex, eventName, handler) {
19552  var editor = this.GetEditorByColumnIndex(columnIndex);
19553  if(!ASPx.Ident.IsASPxClientEdit(editor))
19554   return;
19555  var attachKeyDownToInput = eventName === "KeyDown" && this.IsCheckEditor(editor);
19556  if(!editor[eventName] && !attachKeyDownToInput)
19557   return;
19558  var duplicateAttachLocker = "dxgv" + eventName + "Assigned";
19559  if(editor[duplicateAttachLocker]) 
19560   return;
19561  if(attachKeyDownToInput)
19562   ASPx.Evt.AttachEventToElement(editor.GetFocusableInputElement(), "keydown", function(e) { handler(editor, { htmlEvent: e }); });
19563  else
19564   editor[eventName].AddHandler(handler);
19565  editor.dxgvColumnIndex = columnIndex;
19566  editor[duplicateAttachLocker] = true;
19567 },
19568 IsCheckEditor: function(editor) {
19569  return ASPx.Ident.IsASPxClientCheckEdit && ASPx.Ident.IsASPxClientCheckEdit(editor);
19570 },
19571 IsStaticBinaryImageEditor: function(editor) {
19572  return ASPx.Ident.IsStaticASPxClientBinaryImage && ASPx.Ident.IsStaticASPxClientBinaryImage(editor);
19573 },
19574 IsDetailGrid: function() { 
19575  if(this.isDetailGrid !== null)
19576   return this.isDetailGrid;
19577  var regTest = new RegExp(this.DetailGridSuffix + "[0-9]");
19578  this.isDetailGrid = regTest.test(this.name);
19579  if(this.isDetailGrid)
19580   return true;
19581  var mainElement = this.GetMainElement();
19582  var parent = mainElement.parentNode;
19583  while(parent && parent.tagName !== "BODY") {
19584   this.isDetailGrid = regTest.test(parent.id);
19585   if(this.isDetailGrid) return true;
19586   parent = parent.parentNode;
19587  }
19588  return false;
19589 },
19590 PrepareCommandButtons: function(){
19591  if(!this.cButtonIDs || this.cButtonIDs.length == 0) return;
19592  for(var i = 0; i < this.cButtonIDs.length; i++){
19593   var name = this.cButtonIDs[i];
19594   var element = ASPx.GetElementById(name);
19595   if(!element) continue;
19596   var button = new ASPxClientButton(name);
19597   var buttonMainElement = button.GetMainElement();
19598   element.cpGVCommandButtonInitialized = true;
19599   button.cpGVName = this.name;
19600   button.useSubmitBehavior = false;
19601   button.causesValidation = false;
19602   button.isNative = !!eval(ASPx.Attr.GetAttribute(buttonMainElement, "data-isNative"));
19603   button.isImage = !!eval(ASPx.Attr.GetAttribute(buttonMainElement, "data-isImage"));
19604   button.encodeHtml = !!eval(ASPx.Attr.GetAttribute(buttonMainElement, "data-encodeHtml"));
19605   button.enabled = !ASPx.ElementContainsCssClass(buttonMainElement, "dxbDisabled");
19606   button.clientVisible = ASPx.GetElementDisplay(buttonMainElement);
19607   button.accessibilityCompliant = this.accessibilityCompliant;
19608   button.Click.AddHandler(this.OnCommandButtonClick.aspxBind(this));
19609   button.InlineInitialize();
19610   this.PrepareCommandButton(button);
19611  }
19612  delete this.cButtonIDs;
19613 },
19614 PrepareCommandButton: function(button) {  
19615  if(this.allowBatchEditing && ASPx.GetIsParent(this.GetStatusBar(), button.GetMainElement())) { 
19616   this.EnsureCommandButtonClickArgs(button);
19617   var commandName = button.gvClickArgs && button.gvClickArgs[0][0];
19618   if(commandName === "UpdateEdit")
19619    this.updateButtonName = button.name;
19620   if(commandName === "CancelEdit")
19621    this.cancelButtonName = button.name;
19622   if(commandName === "PreviewChanges")
19623    this.previewChangesButtonName = button.name;
19624   if(commandName === "HidePreview")
19625    this.hidePreviewButtonName = button.name;
19626   if(commandName === "UpdateSummaries")
19627    this.updateSummariesButtonName = button.name;
19628  }
19629 },
19630 GetBatchEditCommandButtons: function() {
19631  var buttons = { };
19632  buttons.updateButton = ASPx.GetControlCollection().Get(this.updateButtonName);
19633  buttons.cancelButton = ASPx.GetControlCollection().Get(this.cancelButtonName);
19634  buttons.previewChangesButton = ASPx.GetControlCollection().Get(this.previewChangesButtonName);
19635  buttons.hidePreviewButton = ASPx.GetControlCollection().Get(this.hidePreviewButtonName);
19636  buttons.updateSummariesButton = ASPx.GetControlCollection().Get(this.updateSummariesButtonName);
19637  return buttons;
19638 },
19639 PrepareCommandButtonsIDList: function(container) {
19640  if(!this.cButtonIDs)
19641   this.cButtonIDs = [ ];
19642  var initButtonIndex = this.GetInitCommandButtonIndex();
19643  var elementList = container.getElementsByTagName("*");
19644  for(var i = 0; i < elementList.length; i++) {
19645   var element = elementList[i];
19646   var comandButtonIDPattern = /%DXItemIndex\d+%$/g; 
19647   if(element.id && comandButtonIDPattern.test(element.id)) {
19648    var patternID = element.id;
19649    var buttonID = patternID.replace(comandButtonIDPattern, initButtonIndex--);
19650    ASPx.SetInnerHtml(element.parentNode, element.parentNode.innerHTML.replace(new RegExp(patternID, "g"), buttonID));
19651    this.cButtonIDs.push(buttonID);
19652   }
19653  }
19654 },
19655 GetInitCommandButtonIndex: function() {
19656  var index = 0;
19657  var disposedControls = [];
19658  ASPx.GetControlCollection().ForEachControl(function(control) {
19659   if(control.cpGVName !== this.name)
19660    return;
19661   if(!control.GetMainElement()) { 
19662    disposedControls.push(control);
19663    return;
19664   }
19665   var matches = control.name.match(/_DXCBtn(-?\d+)/);
19666   if(matches && matches.length > 1) {
19667    var buttonIndex = parseInt(matches[1]);
19668    index = Math.min(index, buttonIndex);
19669   }
19670  }, this);
19671  for(var i = 0; i < disposedControls.length; i++)
19672   ASPx.GetControlCollection().Remove(disposedControls[i]);
19673  return index - 1;
19674 },
19675 EnsureCommandButtonClickArgs: function(button) {
19676  if(!button.gvClickArgs)
19677   button.gvClickArgs = eval(ASPx.Attr.GetAttribute(button.GetMainElement(), "data-args"));
19678 },
19679 OnCommandButtonClick: function(s, e){
19680  var mainElement = s.GetMainElement();
19681  if(!s.gvClickArgs)
19682   s.gvClickArgs = eval(ASPx.Attr.GetAttribute(mainElement, "data-args"));
19683  this.EnsureCommandButtonClickArgs(s);
19684  if(s.gvClickArgs && s.gvClickArgs.length > 1)
19685   this.ScheduleUserCommand(s.gvClickArgs[0], s.gvClickArgs[1], mainElement);
19686 },
19687 GetCommandButtonsInContainer: function(container) {
19688  var buttons = [];   
19689  ASPx.GetControlCollection().ProcessControlsInContainer(container, function(control){
19690   var isCommandButton = control.cpGVName === this.name && control.name.indexOf("DXCBtn") > -1;
19691   if(isCommandButton)
19692    buttons.push(control);
19693  }.bind(this));
19694  return buttons;
19695 },
19696 FindCommandButtonByChildElement: function(element) {
19697  if(!element) return null;
19698  var mainElement = ASPx.GetParentByPartialClassName(element, this.CommandColumnItemClassName);
19699  var buttonId = mainElement && mainElement.id;
19700  return buttonId ? ASPx.GetControlCollection().GetByName(buttonId) : null;
19701 },
19702 IsNewButton: function(button) { return this.CheckButtonByCommandName(button, "AddNew"); },
19703 IsEditButton: function(button) { return this.CheckButtonByCommandName(button, "StartEdit"); },
19704 IsDeleteButton: function(button) { return this.CheckButtonByCommandName(button, "Delete"); },
19705 IsRecoverButton: function(button) { return this.CheckButtonByCommandName(button, "Recover"); },
19706 IsCancelButton: function(button) { return this.CheckButtonByCommandName(button, "CancelEdit"); },
19707 IsSelectButton: function(button) { return this.CheckButtonByCommandName(button, "Select"); },
19708 IsCustomButton: function(button) { return this.CheckButtonByCommandName(button, "CustomButton"); },
19709 CheckButtonByCommandName: function (button, commandName) {
19710  if(!button) return false;
19711  this.EnsureCommandButtonClickArgs(button);
19712  return button.gvClickArgs[0] && button.gvClickArgs[0][0] === commandName ;
19713 },
19714 CheckEndlessPagingLoadNextPage: function() {
19715  window.setTimeout(function() {
19716   var scrollHelper = this.GetScrollHelper();
19717   if(this.useEndlessPaging && scrollHelper)
19718    scrollHelper.CheckEndlessPagingLoadNextPage();
19719  }.aspxBind(this), 0);
19720 },
19721 EnsureRowKeys: function() {
19722  if(ASPx.IsExists(this.stateObject.keys))
19723   this.keys = this.stateObject.keys;
19724  if(!this.keys)
19725   this.keys = [ ];
19726 }, 
19727 CheckPendingEvents: function() {
19728  if(this.pendingEvents.length < 1)
19729   return;
19730  for(var i = 0; i < this.pendingEvents.length; i++)
19731   this.ScheduleRaisingEvent(this.pendingEvents[i]);
19732  this.pendingEvents.length = 0;
19733 },
19734 ScheduleRaisingEvent: function(eventName) {
19735  window.setTimeout(function() { this[eventName](); }.aspxBind(this), 0);
19736 },
19737 CreateInternalCheckBoxCollection: function() {
19738  if(!this.internalCheckBoxCollection)
19739   this.internalCheckBoxCollection = new ASPx.CheckBoxInternalCollection(this.checkBoxImageProperties, true, undefined, undefined, undefined, this.accessibilityCompliant);
19740  else
19741   this.internalCheckBoxCollection.SetImageProperties(this.checkBoxImageProperties);
19742  this.CompleteInternalCheckBoxCollection();
19743 },
19744 CompleteInternalCheckBoxCollection: function() {
19745  if(!this.IsLastCallbackProcessedAsEndless()){
19746   this.internalCheckBoxCollection.Clear();
19747   for(var i = 0; i < this.selectAllSettings.length; i++){
19748    var selectAllSettings = this.selectAllSettings[i];
19749    if(selectAllSettings === null)
19750     continue;
19751    var icbSelectAllElement = this.GetSelectAllBtn(selectAllSettings.index);
19752    if(ASPx.IsExistsElement(icbSelectAllElement))
19753     this.AddInternalCheckBoxToCollection(icbSelectAllElement, -(selectAllSettings.index + 1), !this.IsCheckBoxDisabled(icbSelectAllElement));
19754   }
19755  }
19756  for(var i = 0; i < this.pageRowCount; i ++) {
19757   var index = i + this.visibleStartIndex;
19758   var icbInputElement = this.GetDataRowSelBtn(index);
19759   if(icbInputElement) {
19760    var enabled = !this.IsCheckBoxDisabled(icbInputElement);
19761    this.AddInternalCheckBoxToCollection(icbInputElement, index, enabled);
19762   }
19763  }
19764 },
19765 IsCheckBoxDisabled: function(icbInputElement) {
19766  var icbMainElement = ASPx.CheckableElementHelper.Instance.GetICBMainElementByInput(icbInputElement);
19767  return icbMainElement.className.indexOf(this.GetDisabledCheckboxClassName()) != -1;
19768 },
19769 GetCssClassNamePrefix: function() { return ""; },
19770 GetDisabledCheckboxClassName: function() { return this.GetCssClassNamePrefix() + "_cd"; },
19771 AddInternalCheckBoxToCollection: function (icbInputElement, visibleIndex, enabled) {
19772  var internalCheckBox = null;
19773  if(this.IsLastCallbackProcessedAsEndless())
19774   internalCheckBox = this.internalCheckBoxCollection.Get(icbInputElement.id);
19775  if(internalCheckBox && internalCheckBox.inputElement != icbInputElement){
19776   this.internalCheckBoxCollection.Remove(icbInputElement.id);
19777   internalCheckBox = null;
19778  }
19779  if(!internalCheckBox)
19780   internalCheckBox = this.internalCheckBoxCollection.Add(icbInputElement.id, icbInputElement);
19781  internalCheckBox.CreateFocusDecoration(this.icbFocusedStyle);
19782  internalCheckBox.SetEnabled(enabled && this.GetEnabled());
19783  internalCheckBox.readOnly = this.readOnly;
19784  internalCheckBox.autoSwitchEnabled = !this.allowSelectSingleRowOnly;
19785  var grid = this;
19786  function OnCheckedChanged(s, e){
19787   if(!s.autoSwitchEnabled && s.GetValue() == ASPx.CheckBoxInputKey.Unchecked){
19788    var value = s.stateController.GetNextCheckBoxValue(s.GetValue(), s.allowGrayedByClick && s.allowGrayed);
19789    s.SetValue(value);
19790   }
19791   var rowCheckBox = grid.GetDataRowSelBtn(visibleIndex);
19792   if(grid.allowSelectSingleRowOnly)
19793    grid._selectAllSelBtn(false, rowCheckBox.id);
19794   if(!grid.RaiseInternalCheckBoxClick(visibleIndex)){
19795    grid.ScheduleCommand(function() { grid.SelectItem(visibleIndex, s.GetChecked()); }, true);
19796    grid.mainTableClickCore(e, true);
19797   }
19798  }
19799  function OnSelectAllCheckedChanged(s, e) {
19800   grid.ScheduleCommand(function() { this.ProcessSelectAllCheckBoxCheckedChanged(s); }.bind(grid), true);
19801   grid.mainTableClickCore(e, true);
19802  }
19803  var checkedChangedHandler = visibleIndex < 0 ? OnSelectAllCheckedChanged : OnCheckedChanged;
19804  internalCheckBox.CheckedChanged.AddHandler(checkedChangedHandler);
19805 },
19806 ProcessSelectAllCheckBoxCheckedChanged: function(checkBox, e) {
19807  var index = this.tryGetNumberFromEndOfString(checkBox.inputElement.id).value;
19808  var columnSelectAllSettings = this.GetColumnSelectAllSettings(index);
19809  if(!columnSelectAllSettings)
19810   return;
19811  switch(columnSelectAllSettings.mode){
19812   case 1:
19813    if(checkBox.GetChecked())
19814     this.SelectAllItemsOnPage();
19815    else 
19816     this.UnselectAllItemsOnPage();
19817    break;
19818   case 2:
19819    if(checkBox.GetChecked())
19820     this.SelectItemsCore(null, true, true);
19821    else 
19822     this.UnselectFilteredItemsCore(true);
19823    break;
19824  }
19825  this.UpdateSelectAllCheckboxesState();
19826 },
19827 GetColumnSelectAllSettings: function(index){
19828  for(var i = 0; i < this.selectAllSettings.length; i++){
19829   if(this.selectAllSettings[i].index == index)
19830    return this.selectAllSettings[i];
19831  }
19832 },
19833 SelectItemsCore: function(visibleIndices, selected, changedBySelectAll){
19834  if(!ASPx.IsExists(selected)) selected = true;
19835  if(!ASPx.IsExists(visibleIndices)) {
19836   selected = selected ? "all" : "unall";
19837   changedBySelectAll = ASPx.IsExists(changedBySelectAll) ? changedBySelectAll : false;
19838   visibleIndices = [ ];
19839  } else {
19840   changedBySelectAll = false;
19841   if(visibleIndices.constructor != Array)
19842    visibleIndices = [visibleIndices];
19843  }
19844  this.gridCallBack([ASPxClientGridViewCallbackCommand.SelectRows, selected, changedBySelectAll].concat(visibleIndices));
19845 },
19846 UnselectFilteredItemsCore: function(changedBySelectAll){
19847  if(!ASPx.IsExists(changedBySelectAll))
19848   changedBySelectAll = false;
19849  this.gridCallBack([ASPxClientGridViewCallbackCommand.SelectRows, "unallf", changedBySelectAll]);
19850 },
19851 AdjustControlCore: function() {
19852  ASPxClientControl.prototype.AdjustControlCore.call(this);
19853  this.UpdateScrollableControls();
19854  this.ApplyPostBackSyncData();
19855  this.AdjustPagerControls();
19856  this.UpdateBatchEditActiveElements();
19857  this.InvalidateLayout();
19858 },
19859 UpdateBatchEditActiveElements: function () {
19860  var cellFocusHelper = this.GetCellFocusHelper();
19861  if(cellFocusHelper)
19862   cellFocusHelper.LoadUnfocusableAreaElements();
19863  var batchEditHelper = this.GetBatchEditHelper();
19864  if(batchEditHelper)
19865   batchEditHelper.UpdateAllRecordActiveElements();
19866 },
19867 NeedCollapseControlCore: function() {
19868  return this.HasScrolling();
19869 },
19870 CollapseControl: function () {
19871  ASPx.GridCommonUtils.SaveActiveElement(this);
19872  ASPxClientControl.prototype.CollapseControl.call(this);
19873 },
19874 ExpandControl: function () {
19875  ASPxClientControl.prototype.ExpandControl.call(this);
19876  ASPx.GridCommonUtils.RestoreActiveElement(this);
19877 },
19878 InRegularCallback: function() {
19879  return this.InCallback() && !this.GetCallbackHelper().HasWaitedFuncCallbacks();
19880 },
19881 gridCallBack: function (args, callbackHandler) {
19882  this.GetCallbackHelper().SendRequest(args, callbackHandler);
19883 },
19884 gridPostBack: function(args) { 
19885  this.GetCallbackHelper().SendPostback(args); 
19886 },
19887 gridFuncCallBack: function(args, onCallBack) {
19888  this.GetCallbackHelper().SendFuncCallback(args, onCallBack);
19889 },
19890 OnCallback: function (result) {
19891  var html = result.html;
19892  this.HideFilterControlPopup();
19893  var isFuncCallback = html.indexOf("FB|") == 0;
19894  this.afterCallbackRequired = !isFuncCallback; 
19895  if(isFuncCallback)
19896   this.OnFunctionalCallback(html);
19897  else
19898   this.OnGeneralCallback(result);
19899 },
19900 OnGeneralCallback: function(result) {
19901  var html = result.html;
19902  this.UpdateStateObjectWithObject(result.stateObject);
19903  this.GetFilterHelper().LoadSearchEditorValueOnCallback();
19904  if(this.RequirePartialUpdate(html))
19905   this.ProcessPartialCallbackResult(html);
19906  else
19907   this.ProcessFullCallbackResult(html);
19908 },
19909 RequirePartialUpdate: function(html) {
19910  var helper = this.GetEndlessPagingHelper();
19911  return html.indexOf("EP|") == 0 && helper;
19912 },
19913 ProcessPartialCallbackResult: function(result) {
19914  var helper = this.GetEndlessPagingHelper();
19915  helper.OnCallback(result);
19916 },
19917 ProcessFullCallbackResult: function(result) {
19918  var rootTD = this.GetGridTD();
19919  if(rootTD)
19920   ASPx.SetInnerHtml(rootTD, result);
19921 },
19922 OnFunctionalCallback: function(result){
19923  this.PreventCallbackAnimation();
19924  var result = this.ParseFuncCallbackResult(result.substr(3));
19925  if(!result) return;
19926  if(this.IsHeaderFilterFuncCallback(result.callback))
19927   this.OnFuncCallback(result);
19928  else 
19929   window.setTimeout(function() { this.OnFuncCallback(result); }.aspxBind(this), 0);
19930 },
19931 OnCallbackFinalized: function() {
19932  if(this.afterCallbackRequired)
19933   this.OnAfterCallback();
19934 },
19935 IsHeaderFilterFuncCallback: function(callback) {
19936  return callback === this.GetFilterHelper().OnHeaderFilterCallback;
19937 },
19938 ParseFuncCallbackResult: function(result) {
19939  var pos = result.indexOf("|");
19940  if(pos < 0) return;
19941  var index = parseInt(result.substr(0, pos), 10);
19942  var info = this.GetCallbackHelper().GetFuncCallBackInfo(index);
19943  if(info && info.callback)
19944   return { callback: info.callback, params: result.substr(pos + 1) };
19945 },
19946 OnFuncCallback: function(result) {
19947  if(result && result.callback)
19948   result.callback(eval("(" + result.params + ")"));
19949 },
19950 OnCallbackErrorAfterUserHandle: function(errorMessage, data) {
19951  this.SetCallbackErrorData(errorMessage, data, true);
19952 },
19953 OnCallbackError: function(result, data){
19954  this.SetCallbackErrorData(result, data, false);
19955  this.SetAfterCallbackRequired();
19956 },
19957 SetAfterCallbackRequired: function() {
19958  if(this.GetGridTD())
19959   this.afterCallbackRequired = true;
19960 },
19961 SetCallbackErrorData: function(errorMessage, data, userHandled) {
19962  this.showingError = errorMessage;
19963  this.errorData = data;
19964  this.userHandledCallbackError = userHandled;
19965 },
19966 ShowCallbackError: function(errorText, errorData) {
19967  var batchEditHelper = this.GetBatchEditHelper();
19968  if(batchEditHelper && batchEditHelper.ShowCallbackError(errorText, errorData))
19969   return;
19970  var displayIn = this;
19971  var popupForm = this.GetPopupEditForm();
19972  if(popupForm) {
19973   displayIn = popupForm;
19974   this.ShowPopupEditForm();
19975  }
19976  this.ShowCallbackErrorCore(displayIn, errorText);
19977 },
19978 ShowCallbackErrorCore: function(displayIn, errorText) {
19979  var errorTextContainer = this.GetErrorTextContainer(displayIn);
19980  if(errorTextContainer)
19981   errorTextContainer.innerHTML = errorText;
19982  else
19983   ASPx.ShowErrorAlert(errorText);
19984 },
19985 GetErrorTextContainer: function(displayIn) { },
19986 CreateEditingErrorItem: function(visibleIndex) { },
19987 CancelCallbackCore: function() {
19988  this.RestoreCallbackSettings();
19989  this.InitializeAccessibilityEvents();
19990  this.InitializeCommandColumnHeaderLinkEvents();
19991  this.ResetGestureElementPosition();
19992  this.GetFilterHelper().OnCancelCallbackCore();
19993  this.keyboardLock = false;
19994 },
19995 ResetGestureElementPosition: function() {  
19996  if(!ASPx.GesturesHelper) return;
19997  var handler = ASPx.GesturesHelper.handlers[this.name];
19998  if(handler)
19999   handler.ResetGestureElementPosition();
20000 },
20001 OnBeforeCallbackOrPostBack: function() {
20002  this.GetFilterHelper().LockFilter();
20003  this.HidePopupEditForm();
20004  ASPxClientGridBase.SaveActiveElementSettings(this);
20005 },
20006 OnBeforeCallback: function(command) {
20007  this.GetFilterHelper().OnBeforeCallback();
20008  this.GetToolbarHelper().OnBeforeCallback();
20009  this.keyboardLock = true;
20010  var endlessPagingHelper = this.GetEndlessPagingHelper();
20011  if(endlessPagingHelper)
20012   endlessPagingHelper.OnBeforeCallback(command);
20013  var scrollHelper = this.GetScrollHelper();
20014  if(scrollHelper)
20015   scrollHelper.OnBeforeCallback(command);
20016  var cellFocusHelper = this.GetCellFocusHelper();
20017  if(cellFocusHelper)
20018   cellFocusHelper.OnBeforeCallback();
20019  var batchEditHelper = this.GetBatchEditHelper();
20020  if(batchEditHelper)
20021   batchEditHelper.OnBeforeCallback();
20022  this.ShowLoadingElements();
20023  this.SaveCallbackSettings();
20024  if(this.accessibilityCompliant)
20025   this.isAccessibleRowEditing = this.IsRowEditingCommand(command);
20026 },
20027 IsRowEditingCommand: function(command) {
20028  return command == ASPxClientGridViewCallbackCommand.AddNewRow || 
20029      command == ASPxClientGridViewCallbackCommand.StartEdit;
20030 },
20031 OnAfterCallback: function() {
20032  this.InitializeBubbleEvents();
20033  this.GetFilterHelper().OnAfterCallback();
20034  this.GetToolbarHelper().OnAfterCallback();
20035  var endlessPagingHelper = this.GetEndlessPagingHelper();
20036  if(endlessPagingHelper)
20037   endlessPagingHelper.OnAfterCallback();
20038  var checkBoxCollectionReinitializeRequired = !this.HasCallbackError(); 
20039  this.ProcessGridCallbackError();
20040  this.pendingCommands = [ ];
20041  try {
20042   this._setFocusedItemInputValue();
20043   this.EnsureRowKeys();
20044   this.SetHeadersClientEvents();
20045   this.RestoreCallbackSettings();
20046   this.InitializeAccessibilityEvents();
20047   this.InitializeCommandColumnHeaderLinkEvents();
20048   this.EnsureRowHotTrackItems();
20049   if(this.kbdHelper && !this.useEndlessPaging)
20050    this.kbdHelper.EnsureFocusedRowVisible();
20051  }
20052  finally {
20053   this.keyboardLock = false;
20054  }
20055  this.CheckPendingEvents();
20056  this.PrepareCommandButtons();
20057  if(this.checkBoxImageProperties && checkBoxCollectionReinitializeRequired){
20058   this.CreateInternalCheckBoxCollection();
20059   this.UpdateSelectAllCheckboxesState();
20060  }
20061  var batchEditHelper = this.GetBatchEditHelper();
20062  if(batchEditHelper)
20063   batchEditHelper.OnAfterCallback();
20064  var cellSelectionHelper = this.GetCellSelectionHelper();
20065  if(cellSelectionHelper)
20066   cellSelectionHelper.OnAfterCallback();
20067  var cellFocusHelper = this.GetCellFocusHelper();
20068  if(cellFocusHelper)
20069   cellFocusHelper.OnAfterCallback();
20070  this.CheckEndlessPagingLoadNextPage();
20071  window.setTimeout(this.scrollToElementAsignedFromServer.bind(this), 0);
20072  if(this.isAccessibleRowEditing)
20073   this.HandleAccessibleFocusForEditingRow();
20074 },
20075 HasCallbackError: function() { return !!this.showingError; },
20076 ProcessGridCallbackError: function() {
20077  if(!this.HasCallbackError()) return;
20078  var batchEditHelper = this.GetBatchEditHelper();
20079  if(batchEditHelper)
20080   batchEditHelper.ProcessGridCallbackError();
20081  if(this.userHandledCallbackError)
20082   this.ProcessCallbackErrorAfterUserHandle();
20083  else
20084   this.ShowCallbackError(this.showingError, this.errorData);
20085  this.SetCallbackErrorData(null, null, false);
20086 },
20087 ProcessCallbackErrorAfterUserHandle: function() {
20088  this.ShowPopupEditForm();
20089 },
20090 SaveCallbackSettings: function() {
20091  this.SaveCustWindowScroll();
20092 },
20093 RestoreCallbackSettings: function() {
20094  this.RestoreCustWindowScroll();
20095  this.ApplyPostBackSyncData();
20096  this.ResetControlAdjustment(); 
20097  ASPxClientGridBase.RestoreActiveElementSettings(this); 
20098 },
20099 SaveCustWindowScroll: function() {
20100  var custWindow = this.GetCustomizationWindow();
20101  var contentContainer = custWindow && custWindow.IsVisible() && custWindow.GetContentContainer(-1);
20102  if(contentContainer)
20103   this.savedCustWindowScroll = { left: contentContainer.scrollLeft, top: contentContainer.scrollTop };
20104 },
20105 RestoreCustWindowScroll: function() {   
20106  var custWindow = this.GetCustomizationWindow();
20107  var contentContainer = custWindow && custWindow.IsVisible() && custWindow.GetContentContainer(-1);
20108  if(contentContainer && ASPx.IsExists(this.savedCustWindowScroll)) {
20109   contentContainer.scrollLeft = this.savedCustWindowScroll.left;
20110   contentContainer.scrollTop = this.savedCustWindowScroll.top;
20111  }
20112 },
20113 ShowPopupEditForm: function() {
20114  var popupForm = this.GetPopupEditForm();
20115  if(popupForm && !popupForm.IsVisible())
20116   popupForm.Show();
20117 },
20118 HidePopupEditForm: function() {
20119  var popup = this.GetPopupEditForm();
20120  if(popup)
20121   popup.Hide();
20122 },
20123 OnPopupEditFormInit: function(popup) {
20124  if(this.HasHorzScroll() && this.GetVisibleItemsOnPage() > 0) {
20125   var popupHorzOffset = popup.GetPopupHorizontalOffset();
20126   popup.SetPopupHorizontalOffset(popupHorzOffset - this.GetPopupEditFormHorzOffsetCorrection(popup));
20127  }
20128  popup.Show();
20129 },
20130 GetPopupEditFormHorzOffsetCorrection: function(popup) {
20131  return 0;
20132 },
20133 HandleAccessibleFocusForEditingRow: function() {
20134  var editingRow = this.GetEditingRow();
20135  if(!editingRow || !this.accessibilityFocusTreeLine)
20136   return;
20137  var focusElement = ASPx.FindFirstChildActionElement(editingRow, function(element) {
20138   return !this.IsCommandColumnItem(element);
20139  }.aspxBind(this));
20140  this.accessibilityFocusTreeLine = ASPx.RestoreFocusHelper.getTreeLineCore(this.GetMainElement(), focusElement);
20141  this.isAccessibleRowEditing = false;
20142 },
20143 _isRowSelected: function(visibleIndex) {
20144  if(!ASPx.IsExists(this.stateObject.selection)) return false;
20145  var index = this._getItemIndexOnPage(visibleIndex);
20146  return this._isTrueInCheckList(this.stateObject.selection, index);
20147 },
20148 _isTrueInCheckList: function(checkList, index) {
20149  if(index < 0 ||  index >= checkList.length) return false;
20150  return checkList.charAt(index) == "T";
20151 },
20152 _getSelectedRowCount: function() {
20153  var count = this.selectedWithoutPageRowCount + this._getSelectedRowCountOnPage();
20154  if(this.allowSelectSingleRowOnly)
20155   count = Math.min(count, 1);
20156  return count;
20157 },
20158 _getSelectedRowCountOnPage: function(){
20159  if(!ASPx.IsExists(this.stateObject.selection))
20160   return 0;
20161  var checkList = this.stateObject.selection;
20162  var selCount = 0;
20163  for(var i = 0; i < checkList.length; i++) {
20164   if(checkList.charAt(i) == "T") selCount ++;
20165  }
20166  return selCount;
20167 },
20168 _selectAllRowsOnPage: function(checked) {
20169  if(checked && this.allowSelectSingleRowOnly) {
20170   this.SelectItem(0, true);
20171   return;
20172  }
20173  if(!ASPx.IsExists(this.stateObject.selection)) return;
20174  this._selectAllSelBtn(checked);
20175  var prevSelectedRowCount = 0;
20176  var isTrueInCheckList = false;
20177  for(var i = 0; i < this.pageRowCount; i ++) {
20178   isTrueInCheckList = this._isTrueInCheckList(this.stateObject.selection, i);
20179   if(isTrueInCheckList) prevSelectedRowCount++; 
20180   if(isTrueInCheckList != checked)
20181    this.ChangeItemStyle(i + this.visibleStartIndex, this.GetSelectedItemStyle(checked));
20182  }
20183  if (prevSelectedRowCount == 0 && !checked) return;
20184  var selValue = "";
20185  if(checked) {
20186   for(var i = 0; i < this.pageRowCount; i ++)
20187    selValue += this.IsDataItem(this.visibleStartIndex + i ) ? "T" : "F";
20188  }
20189  if(selValue != this.stateObject.selection) {
20190   this.userChangedSelection = true;
20191   if(selValue == "") selValue = "U";
20192   this.stateObject.selection = selValue;
20193  }
20194  this.DoSelectionChanged(-1, checked, true);
20195  this.UpdateSelectAllCheckboxesState();
20196 },
20197 SelectAllItemsOnPage: function(selected) {
20198  if(!ASPx.IsExists(selected)) selected = true;
20199  this._selectAllRowsOnPage(selected);
20200 },
20201 UnselectAllItemsOnPage: function() {
20202  this.SelectAllItemsOnPage(false);
20203 },
20204 ConfirmDeleteGridItem: function() {
20205  return this.confirmDelete == "" || confirm(this.confirmDelete);
20206 },
20207 DeleteGridItem: function(visibleIndex) {
20208  if(!this.allowDelete || !this.ConfirmDeleteGridItem())
20209   return;
20210  this.DeleteItem(visibleIndex);
20211 },
20212 _selectAllSelBtn: function(checked, exceptName) {
20213  if(!this.checkBoxImageProperties) return;
20214  this.internalCheckBoxCollection.elementsMap.forEachEntry(function(key, checkBox) {
20215   if(key !== exceptName && checkBox.SetValue)
20216    checkBox.SetValue(checked ? ASPx.CheckBoxInputKey.Checked : ASPx.CheckBoxInputKey.Unchecked);
20217  });
20218 },
20219 doRowMultiSelect: function(row, rowIndex, evt) {
20220  var ctrlKey = evt.ctrlKey || evt.metaKey,
20221   shiftKey = evt.shiftKey;
20222  if(ctrlKey || shiftKey)
20223   ASPx.Selection.Clear();
20224  if(this.allowSelectSingleRowOnly)
20225   shiftKey = false;
20226  if(!ctrlKey && !shiftKey) {
20227   if(this._getSelectedRowCountOnPage() === 1 && this._isRowSelected(rowIndex))
20228    return;
20229   this._selectAllRowsOnPage(false);
20230   this.SelectItem(rowIndex, true);
20231   this.lastMultiSelectIndex = rowIndex;
20232  } else {
20233   if(ctrlKey) {
20234    this.SelectItem(rowIndex, !this._isRowSelected(rowIndex));
20235    this.lastMultiSelectIndex = rowIndex;
20236   } else {
20237    var startIndex = rowIndex > this.lastMultiSelectIndex ? this.lastMultiSelectIndex + 1 : rowIndex;
20238    var endIndex = rowIndex > this.lastMultiSelectIndex ? rowIndex : this.lastMultiSelectIndex - 1;
20239    for(var i = this.visibleStartIndex; i < this.pageRowCount + this.visibleStartIndex; i ++) {
20240     if(i == this.lastMultiSelectIndex) 
20241      continue;
20242     this.SelectItem(i, i >= startIndex && i <= endIndex);
20243    }
20244   }
20245  }
20246  this.UpdatePostBackSyncInput();
20247 },
20248 InitializeAccessibilityEvents: function() {
20249  if(!this.accessibilityCompliant)
20250   return;
20251  if(this.isAccessibleFilterRowMenu)
20252   this.AddKeyDownFilterRowButtonHandler();
20253  this.PreventMouseDownHeaderCaptionLinkEvent();
20254 },
20255 AddKeyDownFilterRowButtonHandler: function() {
20256  var filterRow = this.GetFilterRow();
20257  if(!filterRow)
20258   return;
20259  var buttons = [];
20260  ASPx.GetNodesByPartialId(filterRow, this.AccessibleFilterRowButtonID, buttons);
20261  var handler = { "keydown": ASPx.Evt.InvokeMouseClickByKeyDown };
20262  for(var i = 0; i < buttons.length; i++)
20263   this.AttachEventsToElement(buttons[i], handler);
20264 },
20265 PreventMouseDownHeaderCaptionLinkEvent: function () {
20266  var headerCaptionLinkSelector = "a[id^='" + this.name + "'][id$='_l']";
20267  var headerCaptionLinks = this.GetMainElement().querySelectorAll(headerCaptionLinkSelector);
20268  this.PreventMouseDownHeaderLinkEvent(headerCaptionLinks);
20269 },
20270 InitializeCommandColumnHeaderLinkEvents: function () { },
20271 PreventMouseDownHeaderLinkEvent: function(headerLinks) {
20272  var handler = {
20273   "mousedown": function (e) {
20274    ASPx.Evt.GetEventSource(e).focus();
20275    ASPx.Evt.PreventEvent(e);
20276   }
20277  };
20278  for(var i = 0; i < headerLinks.length; i++)
20279   this.AttachEventsToElement(headerLinks[i], handler, true);
20280 },
20281 SelectItemsByKey: function(keys, selected){
20282  if(!ASPx.IsExists(selected)) selected = true;
20283  if(!ASPx.IsExists(keys)) return;
20284  if(keys.constructor != Array)
20285   keys = [keys];
20286  this.gridCallBack([ASPxClientGridViewCallbackCommand.SelectRowsKey, selected].concat(keys));
20287 },
20288 SelectItem: function(visibleIndex, checked, fromCheckBox) {
20289  if(!this.IsPossibleSelectItem(visibleIndex, checked)) return;
20290  if(ASPx.IsExists(fromCheckBox)) fromCheckBox = false;
20291  var index = this._getItemIndexOnPage(visibleIndex);
20292  if(index < 0) return;
20293  if(checked && this.allowSelectSingleRowOnly)
20294   this._selectAllRowsOnPage(false);
20295  if(ASPx.IsExists(this.stateObject.selection)) {
20296   this.userChangedSelection = true;
20297   var checkList = this.stateObject.selection;
20298   if(index >= checkList.length) {
20299    if(!checked) return;
20300    for(var i = checkList.length; i <= index; i ++)
20301     checkList += "F";
20302   }
20303   checkList = checkList.substr(0, index) + (checked ? "T" : "F") + checkList.substr(index + 1, checkList.length - index - 1);
20304   if(checkList.indexOf("T") < 0) checkList = "U";
20305   this.stateObject.selection = checkList;
20306  }
20307  this.selectItemCheckbox(visibleIndex, checked);
20308  this.UpdateSelectAllCheckboxesState();
20309  this.ChangeItemStyle(visibleIndex, this.GetSelectedItemStyle(checked));
20310  this.DoSelectionChanged(visibleIndex, checked, false);
20311 },
20312 selectItemCheckbox: function(visibleIndex, checked) {
20313  var checkBox = this.GetDataRowSelBtn(visibleIndex);
20314  if(checkBox) {
20315   var internalCheckBox = this.internalCheckBoxCollection && this.internalCheckBoxCollection.Get(checkBox.id);
20316   if(internalCheckBox)
20317    internalCheckBox.SetValue(checked ? ASPx.CheckBoxInputKey.Checked : ASPx.CheckBoxInputKey.Unchecked);
20318  }
20319 },
20320 IsPossibleSelectItem: function(visibleIndex, newSelectedValue){
20321  if(this.IsBatchEditDeletedItem(visibleIndex))
20322   return false;
20323  return visibleIndex > -1 && this._isRowSelected(visibleIndex) != newSelectedValue;
20324 },
20325 UpdateSelectAllCheckboxesState: function(){
20326  if(!this.selectAllSettings)
20327   return;
20328  for(var i = 0; i < this.selectAllSettings.length; i++){
20329   var columnSelectAllSettings = this.selectAllSettings[i];
20330   if(columnSelectAllSettings === null)
20331    continue;
20332   var selectAllButtonInput = this.GetSelectAllBtn(columnSelectAllSettings.index);
20333   if(selectAllButtonInput && !this.IsCheckBoxDisabled(selectAllButtonInput))
20334    this.UpdateSelectAllCheckboxStateCore(selectAllButtonInput, columnSelectAllSettings.mode);
20335  }
20336 },
20337 UpdateSelectAllCheckboxStateCore: function(selectAllButtonInput, selectMode){
20338  var value = ASPx.CheckBoxInputKey.Indeterminate;
20339  var selectedRowCountOnPage = this.GetSelectedKeysOnPage().length;
20340  var considerSelectionOnPages = selectMode == 2 && this.selectAllBtnStateWithoutPage !== null;
20341  if(this.GetDataItemCountOnPage() == selectedRowCountOnPage && (!considerSelectionOnPages || this.selectAllBtnStateWithoutPage == ASPx.CheckBoxInputKey.Checked))
20342   value = ASPx.CheckBoxInputKey.Checked;
20343  else if(selectedRowCountOnPage == 0 && (!considerSelectionOnPages || this.selectAllBtnStateWithoutPage == ASPx.CheckBoxInputKey.Unchecked))
20344   value = ASPx.CheckBoxInputKey.Unchecked;
20345  var selectAllCheckBoxInst = this.internalCheckBoxCollection.Get(selectAllButtonInput.id);
20346  selectAllCheckBoxInst.SetValue(value);
20347 },
20348 GetDataItemCountOnPage: function(){
20349  return this.pageRowCount;
20350 },
20351 ScheduleUserCommand: function(args, postponed, eventSource) {
20352  if(!args || args.length == 0) 
20353   return;
20354  var commandName = args[0];
20355  var rowCommands = this.GetUserCommandNamesForRow();
20356  if((this.useEndlessPaging || this.allowBatchEditing) && ASPx.Data.ArrayIndexOf(rowCommands, commandName) > -1)
20357   args[args.length - 1] = this.FindParentRowVisibleIndex(eventSource, true);
20358  postponed &= this.IsMainTableChildElement(eventSource);
20359  this.ScheduleCommand(args, postponed);
20360 },
20361 GetUserCommandNamesForRow: function() { return [ "CustomButton", "Select", "StartEdit", "Delete", "Recover", "CancelEdit" ]; },
20362 IsMainTableChildElement: function(src) { return true; },
20363 FindParentRowVisibleIndex: function(element, dataAndGroupOnly) {
20364  var regEx = this.GetItemVisibleIndexRegExp(dataAndGroupOnly);
20365  var editingRow = this.GetEditingRow();
20366  while(element) {
20367   if(element.tagName === "BODY" || element.id == this.name)
20368    return this.InvalidItemIndex;
20369   var matches = regEx.exec(element.id);
20370   if(matches && matches.length == 3)
20371    return parseInt(matches[2]);
20372   if(element === editingRow)
20373    return this.editItemVisibleIndex;
20374   element = element.parentNode;
20375  }
20376  return this.InvalidItemIndex;
20377 },
20378 GetItemVisibleIndexRegExp: function(dataAndGroupOnly) {
20379  return this.GetItemVisibleIndexRegExpByIdParts();
20380 },
20381 GetItemVisibleIndexRegExpByIdParts: function(idParts){
20382  if(!idParts) idParts = [ ];
20383  return new RegExp("^(" + this.name + "_(?:" + idParts.join("|") + "))(-?\\d+)(?:_\\d+)?$");
20384 },
20385 ScheduleCommand: function(args, postponed) {
20386  if(postponed)
20387   this.pendingCommands.push(args);
20388  else 
20389   this.PerformScheduledCommand(args);
20390 },
20391 PerformScheduledCommand: function(args) {
20392  if(ASPx.IsFunction(args)) {
20393   args(); 
20394   return;
20395  }
20396  if(args && args.length > 0) {
20397   var commandName = "UA_" + args[0];
20398   if(this[commandName])
20399    this[commandName].apply(this, args.slice(1));
20400  }
20401 },
20402 PerformPendingCommands: function() {
20403  var commandCount = this.pendingCommands.length;
20404  for(var i = 0; i < commandCount; i++)
20405   this.PerformScheduledCommand(this.pendingCommands.pop());
20406 },
20407 getItemByHtmlEvent: function(evt) { return null; },
20408 getItemByHtmlEventCore: function(evt, partialID) {
20409  var item = ASPx.GetParentByPartialId(ASPx.Evt.GetEventSource(evt), partialID);
20410  if(item && item.id.indexOf(this.name) > -1)
20411   return item;
20412  return null;
20413 },
20414 NeedProcessTableClick: function(evt) {
20415  var source = ASPx.Evt.GetEventSource(evt);
20416  var handlingControl = this.GetTableClickHandlingControl(source);
20417  return handlingControl && this === handlingControl;
20418 },
20419 GetTableClickHandlingControl: function(source) {
20420  var treeLine = ASPx.GetElementTreeLine(source);
20421  for(var i = 0; i < treeLine.length; i++) {
20422   var control = ASPx.GetControlCollection().GetByName(treeLine[i].id);
20423   if(control && control instanceof ASPxClientGridBase)
20424    return control;
20425  }
20426  return null;
20427 },
20428 mainTableClick: function(evt) { this.mainTableClickCore(evt); },
20429 mainTableDblClick: function(evt) { 
20430  var item = this.getItemByHtmlEvent(evt);
20431  if(!item) return;
20432  var forceItemDblClickEvent = true;
20433  var itemIndex = this.getItemIndex(item.id);
20434  var batchEditHelper = this.GetBatchEditHelper();
20435  if(batchEditHelper){
20436   batchEditHelper.ProcessTableClick(item, ASPx.Evt.GetEventSource(evt), evt, true);
20437   forceItemDblClickEvent = batchEditHelper.GetEditingRecordKey() !== this.ConvertVisibleIndexToKey(itemIndex);
20438  }
20439  if(forceItemDblClickEvent)
20440   this.RaiseItemDblClick(itemIndex, evt);
20441 },
20442 mainTableClickCore: function(evt, fromCheckBox) {
20443  if(this.kbdHelper) {
20444   this.kbdHelper.preventBrowserScrollOnFocus = fromCheckBox;
20445   this.kbdHelper.HandleClick(evt);
20446   this.kbdHelper.preventBrowserScrollOnFocus = false;
20447  }
20448  var sendNotificationCallback = true;
20449  this.mainTableClickData.processing = true;
20450  try {
20451   this.ProcessTableClick(evt, fromCheckBox);
20452   var callbackHelper = this.GetCallbackHelper();
20453   var savedRequestCount = callbackHelper.GetTotalRequestCount();
20454   this.PerformPendingCommands();
20455   var currentRequestCount = callbackHelper.GetTotalRequestCount();
20456   sendNotificationCallback = currentRequestCount === savedRequestCount;
20457  } finally {
20458   if(sendNotificationCallback)
20459    if(this.mainTableClickData.focusChanged && !this.mainTableClickData.selectionChanged) {
20460     this.gridCallBack([ASPxClientGridViewCallbackCommand.FocusedRow]);
20461    } else if(this.mainTableClickData.selectionChanged) {
20462     this.gridCallBack([ASPxClientGridViewCallbackCommand.Selection]);
20463    }
20464   this.mainTableClickData.processing = false;
20465   this.mainTableClickData.focusChanged = false;
20466   this.mainTableClickData.selectionChanged = false;
20467  }
20468 },
20469 ProcessTableClick: function(evt, fromCheckBox) {
20470  var source = ASPx.Evt.GetEventSource(evt);
20471  var item = this.getItemByHtmlEvent(evt);
20472  if(item) {
20473   var itemIndex = this.getItemIndex(item.id);
20474   var isCommandColumnItem = this.IsCommandColumnItem(source);
20475   if(!isCommandColumnItem && !fromCheckBox) {
20476    var batchEditHelper = this.GetBatchEditHelper();
20477    if(batchEditHelper && batchEditHelper.ProcessTableClick(item, source, evt))
20478     return;
20479    if(this.RaiseItemClick(itemIndex, evt)) 
20480     return;
20481   }
20482   var prevFocusedItemIndex = this._getFocusedItemIndex();
20483   if(this.CanTryFocusItemOnTableClick())
20484    this.TryFocusItem(itemIndex, evt);
20485   if(this.allowSelectByItemClick) {
20486    if(!this.testActionElement(source) && !isCommandColumnItem && !fromCheckBox) {
20487     if(this.lookupBehavior) {
20488      var checked = this.allowSelectSingleRowOnly || !this._isRowSelected(itemIndex);
20489      this.SelectItem(itemIndex, checked);
20490     } else {
20491      if(!fromCheckBox && !evt.shiftKey && this.RequireProcessTableClickLikeCheckBoxClick(source, itemIndex)) { 
20492       var newSelected = this.allowSelectSingleRowOnly || !this._isRowSelected(itemIndex);
20493       this.SelectItem(itemIndex, newSelected);
20494       return;
20495      }
20496      var indexCorrection = 0;
20497      if(this.lastMultiSelectIndex < 0 && prevFocusedItemIndex > -1) {
20498       if(evt.shiftKey && itemIndex != prevFocusedItemIndex && !this._isRowSelected(prevFocusedItemIndex))
20499        indexCorrection = itemIndex > prevFocusedItemIndex ? -1 : 1;
20500       this.lastMultiSelectIndex = prevFocusedItemIndex + indexCorrection;
20501      }
20502      this.doRowMultiSelect(item, itemIndex, evt);
20503      this.lastMultiSelectIndex -= indexCorrection;
20504     }
20505    }
20506   } else {
20507    this.lastMultiSelectIndex = itemIndex;
20508   }
20509  }
20510 },
20511 testActionElement: function(element) {
20512  return element && element.tagName.match(/input|select|textarea|^a$/i);
20513 },
20514 IsCommandColumnItem: function(element) {
20515  if(!element) return false;
20516  if(ASPx.ElementHasCssClass(element, this.CommandColumnItemClassName))
20517   return true;
20518  return ASPx.GetIsParent(this.GetMainElement(), ASPx.GetParentByPartialId(element, "DXCBtn"));
20519 },
20520 RequireProcessTableClickLikeCheckBoxClick: function(tableClickSource, visibleIndex) { return false; },
20521 OnBeforeFocusedCellChanging: function(cellInfo, htmlEvent) {
20522  var visibleIndex = this.ConvertKeyToVisibleIndex(cellInfo.recordKey);
20523  if(this.allowFocusedRow && visibleIndex >= 0 && visibleIndex !== this.focusedRowIndex && !this.IsBatchEditDeletedItem(visibleIndex)) 
20524   return this.RaiseItemFocusing(visibleIndex, htmlEvent);
20525  return false;
20526 },
20527 OnFocusedCellChanged: function(cellInfo, htmlEvent) {
20528  this._setFocusedItemIndex(this.ConvertKeyToVisibleIndex(cellInfo.recordKey));
20529  var cellSelectionHelper = this.GetCellSelectionHelper();
20530  if(cellSelectionHelper)
20531   cellSelectionHelper.OnFocusedCellChanged(cellInfo, htmlEvent);
20532  if(!this.allowFocusedRow)
20533   this.ChangeToolbarItemsEnabling();
20534 },
20535 CanTryFocusItemOnTableClick: function() { return !this.GetCellFocusHelper(); },
20536 TryFocusItem: function(visibleIndex, htmlEvent) {
20537  if(this.allowFocusedRow && visibleIndex >= 0 && visibleIndex !== this.focusedRowIndex && !this.IsBatchEditDeletedItem(visibleIndex)) {
20538   var isCanceledByUser = this.RaiseItemFocusing(visibleIndex, htmlEvent);
20539   if(!isCanceledByUser) {
20540    this._setFocusedItemIndex(visibleIndex);
20541    return true;
20542   }
20543  }
20544  return false;
20545 },
20546 _setFocusedItemIndex: function(visibleIndex) {
20547  if(visibleIndex < 0) 
20548   visibleIndex = -1;
20549  if(!this.IsPossibleFocusItem(visibleIndex)) 
20550   return;
20551  var oldIndex = this.focusedRowIndex;
20552  this.focusedRowIndex = visibleIndex;
20553  this.ChangeFocusedItemStyle(oldIndex, false);
20554  this.ChangeFocusedItemStyle(this.focusedRowIndex, true);
20555  this._setFocusedItemInputValue();
20556  if(this.callbackOnFocusedRowChanged) {
20557   this.UpdatePostBackSyncInput(true);
20558   if(!this.mainTableClickData.processing) {
20559    this.gridCallBack([ASPxClientGridViewCallbackCommand.FocusedRow]);
20560   } else {
20561    this.mainTableClickData.focusChanged = true;
20562   }
20563   return;
20564  }
20565  this.ChangeToolbarItemsEnabling();
20566  this.RaiseFocusedItemChanged();
20567 },
20568 IsPossibleFocusItem: function(visibleIndex) { return this.allowFocusedRow && visibleIndex !== this.focusedRowIndex && !this.IsBatchEditDeletedItem(visibleIndex); },
20569 ChangeToolbarItemsEnabling: function(){
20570  var helper = this.GetToolbarHelper();
20571  helper.RefreshItemsState();
20572 },
20573 ChangeToolbarBatchEditItemsState: function(state) {
20574  var helper = this.GetToolbarHelper();
20575  if(helper)
20576   helper.OnBatchEditItemsStateChanged(state);
20577 },
20578 ChangeFocusedItemStyle: function(visibleIndex, focused) {
20579  if(visibleIndex < 0) return;
20580  var itemStyle = this.GetFocusedItemStyle(visibleIndex, focused);
20581  this.ChangeItemStyle(visibleIndex, itemStyle);
20582 },
20583 GetFocusedItemStyle: function(visibleIndex, focused){
20584  if(focused)
20585   return this.GetStyleHelper().GetFocusedItemStyle();
20586  return this.GetSelectedItemStyle(this._isRowSelected(visibleIndex));
20587 },
20588 GetFocusedCell: function() {
20589  var cellFocusHelper = this.GetCellFocusHelper();
20590  if(cellFocusHelper && cellFocusHelper.IsCellFocused()) {
20591   var info = cellFocusHelper.GetFocusedCellInfo();
20592   if(info)
20593    return this.CreateUserCellInfo(this.ConvertKeyToVisibleIndex(info.recordKey), this.GetColumn(info.columnIndex), info.recordKey);
20594  }
20595  return null;
20596 },
20597 SetFocusedCell: function(itemIndex, columnIndex) { this.SetFocusedCellByKey(this.ConvertVisibleIndexToKey(itemIndex), columnIndex); },
20598 SetFocusedCellByKey: function(key, columnIndex) {
20599  var cellFocusHelper = this.GetCellFocusHelper();
20600  if(cellFocusHelper)
20601   cellFocusHelper.SetFocusedCell(key, columnIndex);
20602 },
20603 _setFocusedItemInputValue: function() {
20604  if(ASPx.IsExists(this.stateObject.focusedRow)) 
20605   this.stateObject.focusedRow = this.focusedRowIndex;
20606 },
20607 _getFocusedItemIndex: function() {
20608  if(!this.allowFocusedRow) return -1;
20609  return this.focusedRowIndex;
20610 },
20611 getItemIndex: function(rowId) {   
20612  return this.tryGetNumberFromEndOfString(rowId).value;
20613 },
20614 tryGetNumberFromEndOfString: function(str) {
20615  var value = -1;
20616  var success = false;
20617  var n = str.length - 1;
20618  while(n >= 0 && !isNaN(parseInt(str.substr(n), 10))) {
20619   value = parseInt(str.substr(n), 10);
20620   success = true;
20621   n--;
20622  }
20623  return { success: success, value: value };
20624 },
20625 GetSelectedCells: function() {
20626  var result = [];
20627  var cellSelectionHelper = this.GetCellSelectionHelper();
20628  if(cellSelectionHelper) {
20629   var cellsInfo = cellSelectionHelper.GetSelectedCells();
20630   if(cellsInfo && cellsInfo.length > 0) {
20631    result = cellsInfo.map(function(info) {
20632     return this.CreateUserCellInfo(this.ConvertKeyToVisibleIndex(info.recordKey), this.GetColumn(info.columnIndex), info.recordKey);
20633    }.bind(this));
20634   }
20635  }
20636  return result;
20637 },
20638 SetCellSelection: function(key, columnIndex, isSelect) {
20639  var cellSelectionHelper = this.GetCellSelectionHelper();
20640  if(cellSelectionHelper) {
20641   var action = isSelect ? cellSelectionHelper.SelectCell : cellSelectionHelper.UnselectCell;
20642   action.call(cellSelectionHelper, cellSelectionHelper.CreateCellInfo(key, columnIndex));
20643  }
20644 },
20645 GetSelectedState: function() {
20646  if(!this.userChangedSelection) return null;
20647  if(!ASPx.IsExists(this.stateObject.selection)) return null;
20648  return this.stateObject.selection;
20649 },
20650 GetKeyValues: function() {
20651  return ASPx.Json.ToJson(this.stateObject.keys);
20652 },
20653 UpdateItemsStyle: function() {
20654  var start = this.GetTopVisibleIndex();
20655  var end = start + this.GetVisibleItemsOnPage();
20656  for(var i = start; i < end; i++) 
20657   this.UpdateItemStyle(i, this.GetItemStyle(i));
20658 },
20659 UpdateItemStyle: function(visibleIndex) {
20660  this.ChangeItemStyle(visibleIndex, this.GetItemStyle(visibleIndex));
20661 },
20662 GetSelectedItemStyle: function(selected) {
20663  var helper = this.GetStyleHelper();
20664  return selected ? helper.GetSelectedItemStyle() : helper.GetClearItemStyle();
20665 },
20666 GetItemStyle: function(visibleIndex){
20667  var helper = this.GetStyleHelper();
20668  var style = helper.GetClearItemStyle();
20669  if(this.IsBatchEditDeletedItem(visibleIndex))
20670   style = helper.GetBatchEditDeletedItemStyle();
20671  else if(this.allowFocusedRow && this._getFocusedItemIndex() == visibleIndex)
20672   style = helper.GetFocusedItemStyle();
20673  else if(this._isRowSelected(visibleIndex))
20674   style = helper.GetSelectedItemStyle();
20675  return style;
20676 },
20677 ChangeItemStyle: function(visibleIndex, rowStyle) {
20678  if(!this.RequireChangeItemStyle(visibleIndex, rowStyle))
20679   return;
20680  this.ApplyItemStyle(visibleIndex, rowStyle);
20681  var batchEditHelper = this.GetBatchEditHelper();
20682  if(batchEditHelper)
20683   batchEditHelper.OnItemStyleChanged(this.GetItemKey(visibleIndex), rowStyle);
20684 },
20685 ApplyItemStyle: function(visibleIndex, styleInfo) {
20686  var item = this.GetItem(visibleIndex);
20687  this.ApplyElementStyle(item, styleInfo);
20688 },
20689 ApplyElementStyle: function(element, styleInfo) {  
20690  this.GetStyleHelper().ApplyElementStyle(element, styleInfo);
20691 },
20692 RequireChangeItemStyle: function(visibleIndex, itemStyle){
20693  var focusedIndex = this._getFocusedItemIndex();
20694  var helper = this.GetStyleHelper();
20695  if(focusedIndex > -1 && focusedIndex == visibleIndex && !helper.IsFocusedItemStyle(itemStyle))
20696   return false;
20697  return !!this.GetItem(visibleIndex);
20698 },
20699 _getItemIndexOnPage: function(visibleIndex) { 
20700  return visibleIndex - this.visibleStartIndex; 
20701 },
20702 getColumnIndex: function(colId) {
20703  if(this.IsEmptyHeaderID(colId))
20704   return -1;
20705  var index = this.tryGetNumberFromEndOfString(colId).value;
20706  var postfix = "col" + index;
20707  if(colId.lastIndexOf(postfix) == colId.length - postfix.length)
20708   return index;
20709  return -1;
20710 },
20711 getColumnObject: function(colId) {
20712  var index = this.getColumnIndex(colId);
20713  return index > -1 ? this._getColumn(index) : null;
20714 },
20715 _getColumnIndexByColumnArgs: function(column) {
20716  column = this._getColumnObjectByArg(column);
20717  if(!column) return null;
20718  return column.index;
20719 },
20720 _getColumnObjectByArg: function(arg) {
20721  if(!ASPx.IsExists(arg)) return null;
20722  if(typeof(arg) == "number") return this._getColumn(arg);
20723  if(ASPx.IsExists(arg.index)) return arg;
20724  var column = this._getColumnById(arg);
20725  if(column) return column;
20726  return this._getColumnByField(arg);  
20727 },
20728 _getColumnCount: function() { return this.columns.length; },
20729 _getColumn: function(index) {
20730  for(var i = 0; i < this.columns.length; i++){
20731   if(this.columns[i].index == index) return this.columns[i];
20732  }
20733  return null;
20734 },
20735 _getColumnById: function(id) {
20736  if(!ASPx.IsExists(id)) return null;
20737  for(var i = 0; i < this.columns.length; i++) {
20738   if(this.columns[i].id == id) return this.columns[i];
20739  }
20740  return null;
20741 },
20742 _getColumnByField: function(fieldName) {
20743  if(!ASPx.IsExists(fieldName)) return null;
20744  for(var i = 0; i < this.columns.length; i++) {
20745   if(this.columns[i].fieldName == fieldName) return this.columns[i];
20746  }
20747  return null;
20748 },
20749 DoSelectionChanged: function(index, isSelected, isSelectAllOnPage){
20750  if(this.callbackOnSelectionChanged) {
20751   this.UpdatePostBackSyncInput(true);
20752   if(!this.mainTableClickData.processing) {
20753    this.gridCallBack([ASPxClientGridViewCallbackCommand.Selection]);
20754   } else {
20755    this.mainTableClickData.selectionChanged = true;
20756   }
20757   return;
20758  }
20759  this.ChangeToolbarItemsEnabling();
20760  this.RaiseSelectionChanged(index, isSelected, isSelectAllOnPage, false);
20761 },
20762 CommandCustomButton:function(id, index) {
20763  var processOnServer = true;
20764  if(!this.CustomButtonClick.IsEmpty()) {
20765   var e = this.CreateCommandCustomButtonEventArgs(index, id);
20766   this.CustomButtonClick.FireEvent(this, e);
20767   processOnServer = e.processOnServer;
20768  }
20769  if(processOnServer)
20770   this.gridCallBack([ASPxClientGridViewCallbackCommand.CustomButton, id, index]);
20771 },
20772 CreateCommandCustomButtonEventArgs: function(index, id){
20773  return null;
20774 },
20775 HeaderMouseDown: function(element, e){
20776  if(!ASPx.Evt.IsLeftButtonPressed(e)) 
20777   return;
20778  var source = ASPx.Evt.GetEventSource(e);
20779  if(this.isHeaderFilterButton(source))
20780   return;
20781  if(this.TryStartColumnResizing(e, element))
20782   return;
20783  var canDrag = this.canDragColumn(element) && source.tagName != "IMG";
20784  var dragHelper = this.GetDragHelper();
20785  var drag = dragHelper.CreateDrag(e, element, canDrag);
20786  if(!canDrag && (e.shiftKey || e.ctrlKey))
20787   drag.clearSelectionOnce = true;
20788  dragHelper.CreateTargets(drag, e);
20789 },
20790 isHeaderFilterButton: function(el) {
20791  return ASPx.ElementContainsCssClass(ASPx.getSpriteMainElement(el), this.HeaderFilterButtonClassName);
20792 },
20793 TryStartColumnResizing: function(e, headerCell) {
20794  return false;
20795 }, 
20796 OnParentRowMouseEnter: function(element) {
20797  if(this.GetParentRowsWindow() == null) return;
20798  if(this.GetParentRowsWindow().IsWindowVisible()) return;
20799  this.ParentRowsTimerId = window.setTimeout(function() {
20800   var gv = ASPx.GetControlCollection().Get(this.name);
20801   if(gv)
20802    gv.OnParentRowsTimer(element.id);
20803  }.aspxBind(this), 500);
20804 },
20805 OnParentRowsTimer: function(rowId) {
20806  var element = ASPx.GetElementById(rowId);
20807  if(element)
20808   this.ShowParentRows(element);
20809 },
20810 OnParentRowMouseLeave: function(evt) {
20811  ASPx.Timer.ClearTimer(this.ParentRowsTimerId);
20812  if(this.GetParentRowsWindow() == null) return;
20813  if(evt && evt.toElement) {
20814   if(ASPx.GetParentByPartialId(evt.toElement, this.GetParentRowsWindow().name) != null)
20815    return;
20816  }
20817  this.HideParentRows();
20818 },
20819 ShowParentRows: function(element) {
20820  this.ParentRowsTimerId = null;
20821  if(this.GetParentRowsWindow() != null) {
20822   this.GetParentRowsWindow().ShowAtElement(element);
20823  }
20824 },
20825 HideParentRows: function() {
20826  this.ParentRowsTimerId = null;
20827  if(this.GetParentRowsWindow() != null) {
20828   this.GetParentRowsWindow().Hide();
20829  }
20830 }, 
20831 canSortByColumn: function(headerElement) {
20832  return this.getColumnObject(headerElement.id).allowSort;
20833 },
20834 canGroupByColumn: function(column) {
20835  return false;
20836 },
20837 canHideColumn: function(column) {
20838  return false;
20839 },
20840 canDragColumn: function(headerElement) {
20841  return false;
20842 },
20843 doPagerOnClick: function(id) {
20844  if(!ASPx.IsExists(id)) return;
20845  this.gridCallBack([ASPxClientGridViewCallbackCommand.PagerOnClick, id]);
20846 },
20847 CanHandleGesture: function(evt) {
20848  var source = ASPx.Evt.GetEventSource(evt);
20849  var table = this.GetMainTable();
20850  if(!table) return false;
20851  if(ASPx.GetIsParent(table, source))
20852   return !this.NeedPreventGestures(source, table);
20853  if(table.parentNode.tagName == "DIV" && ASPx.GetIsParent(table.parentNode, source))
20854   return ASPx.Browser.TouchUI || evt.offsetX < table.parentNode.clientWidth;
20855  return false;
20856 },
20857 AllowStartGesture: function() {
20858  return ASPxClientControl.prototype.AllowStartGesture.call(this) && 
20859   (this.AllowExecutePagerGesture(this.pageIndex, this.pageCount, 1) || this.AllowExecutePagerGesture(this.pageIndex, this.pageCount, -1));
20860 },
20861 AllowExecuteGesture: function(value) {
20862  return this.AllowExecutePagerGesture(this.pageIndex, this.pageCount, value);
20863 },
20864 ExecuteGesture: function(value, count) {
20865  this.ExecutePagerGesture(this.pageIndex, this.pageCount, value, count, function(arg) { this.doPagerOnClick(arg); }.aspxBind(this));
20866 },
20867 ApplySearchPanelFilter: function(value, isInternalCall) {
20868  if(!ASPx.IsExists(value))
20869   value = "";
20870  var edit = this.GetSearchEditor();
20871  if(edit && !isInternalCall)
20872   edit.SetText(value);
20873  var scrollHelper = this.GetScrollHelper();
20874  if(scrollHelper)
20875   scrollHelper.ResetScrollTop();
20876  this.gridCallBack([ASPxClientGridViewCallbackCommand.ApplySearchPanelFilter, value]);
20877 },
20878 NeedShowLoadingPanelInsideEndlessPagingContainer: function() {
20879  var endlessPagingHelper = this.GetEndlessPagingHelper();
20880  return endlessPagingHelper && endlessPagingHelper.NeedShowLoadingPanelAtBottom();
20881 },
20882 ShowLoadingPanel: function() {
20883  var gridMainCell = this.GetGridTD();
20884  if(!gridMainCell)
20885   return;
20886  if(this.NeedShowLoadingPanelInsideEndlessPagingContainer()) {
20887   var container = this.GetEndlessPagingLPContainer();
20888   ASPx.SetElementDisplay(container, true);
20889   this.CreateLoadingPanelWithoutBordersInsideContainer(container);
20890   return;
20891  }
20892  var lpContainer = this.GetLoadingPanelContainer();
20893  if(lpContainer)
20894   this.CreateLoadingPanelInline(lpContainer);
20895  else
20896   this.CreateLoadingPanelWithAbsolutePosition(gridMainCell, this.GetLoadingPanelOffsetElement(gridM
20896ainCell));
20897 },
20898 ShowLoadingDiv: function () {
20899  if(!this.NeedShowLoadingPanelInsideEndlessPagingContainer())
20900   this.CreateLoadingDiv(this.GetGridTD());
20901 },
20902 ShowLoadingPanelInsideHeaderFilterPopup: function() {
20903  this.CreateLoadingPanelWithoutBordersInsideContainer(this.GetHeaderFilterPopup().GetContentContainer(-1));
20904 },
20905 GetCallbackAnimationElement: function() {
20906  var table = this.GetMainTable();
20907  if(table && table.parentNode && table.parentNode.tagName == "DIV")
20908   return table.parentNode;
20909  return table;
20910 },
20911 NeedPreventTouchUIMouseScrolling: function(element) {
20912  return this.NeedPreventGestures(element);
20913 },
20914 NeedPreventGestures: function(element, mainElement) {
20915  if(!ASPx.IsExists(mainElement)) {
20916   mainElement = this.GetMainElement();
20917   if(!ASPx.IsExists(mainElement) || !ASPx.GetIsParent(mainElement, element))
20918    return false;
20919  }
20920  var preventElement = this.IsHeaderChild(element) || this.IsActionElement(mainElement, element);
20921  if(preventElement)
20922   return true;
20923  return this.pageCount <= 1 ? !ASPx.Browser.MSTouchUI : false;
20924 },
20925 IsHeaderChild: function(source) {
20926  return false;
20927 },
20928 IsActionElement: function(mainElement, source) {
20929  return false;
20930 },
20931 _updateEdit: function() {
20932  var batchEditHelper = this.GetBatchEditHelper();
20933  if(batchEditHelper && !batchEditHelper.CanUpdate())
20934   return;
20935  if(!batchEditHelper && !this._validateEditors())
20936   return;
20937  if(batchEditHelper)
20938   batchEditHelper.OnUpdate();
20939  this.gridCallBack([ASPxClientGridViewCallbackCommand.UpdateEdit]);
20940 },
20941 _validateEditors: function() {
20942  var editors = this._getEditors();
20943  var isValid = true;
20944  if(editors.length > 0)
20945   isValid &= this._validate(editors);
20946  if(window.ASPxClientEdit)
20947   isValid &= ASPxClientEdit.ValidateEditorsInContainer(this.GetEditFormTable(), this.name);
20948  return isValid;
20949 },
20950 _validate: function(list) {
20951  var isValid = true;
20952  var firstInvalid = null;
20953  var edit;
20954  for(var i = 0; i < list.length; i ++) {
20955   edit = list[i];
20956   edit.Validate();
20957   isValid = edit.GetIsValid() && isValid;
20958   if(firstInvalid == null && edit.setFocusOnError && !edit.GetIsValid())
20959    firstInvalid = edit;
20960  }
20961  if (firstInvalid != null)
20962   firstInvalid.Focus();
20963  return isValid;
20964 },
20965 _getEditors: function() {
20966  var list = [ ];
20967  for(var i = 0; i < this.editorIDList.length; i++) {
20968   var editor = ASPx.GetControlCollection().Get(this.editorIDList[i]);
20969   if(editor && editor.enabled && editor.GetMainElement && ASPx.IsExistsElement(editor.GetMainElement())) {
20970    if(!editor.Validate || this.IsStaticBinaryImageEditor(editor)) 
20971     continue; 
20972    list.push(editor);
20973   }
20974  }
20975  return list;
20976 },
20977 GetEditorValues: function() {
20978  if(this.allowBatchEditing) return null;
20979  var list = this._getEditors();
20980  if(list.length == 0) return null;
20981  var res = list.length + ";";
20982  for(var i = 0; i < list.length; i ++) {
20983   res += this.GetEditorValue(list[i]);
20984  }
20985  return res;
20986 },
20987 GetEditorValue: function(editor) {
20988  var value = editor.GetValueString();
20989  var valueLength = -1;
20990  if(!ASPx.IsExists(value)) {
20991   value = "";
20992  } else {
20993   value = value.toString();
20994   valueLength = value.length;
20995  }
20996  return this.GetEditorIndex(editor.name) + "," + valueLength + "," + value + ";";
20997 },
20998 GetEditorIndex: function(editorId) {
20999  var i = editorId.lastIndexOf(this.GetEditorPrefix());
21000  if(i < 0) return -1;
21001  var result = editorId.substr(i + this.GetEditorPrefix().length);
21002  i = result.indexOf('_'); 
21003  return i > 0
21004   ? result.substr(0, i)
21005   : result;
21006 },
21007 GetBatchEditHelper: function() {
21008  if(!this.allowBatchEditing) return null;
21009  if(!this.batchEditHelper)
21010   this.batchEditHelper = this.CreateBatchEditHelper(this.GetBatchEditHelperOwner());
21011  return this.batchEditHelper;
21012 },
21013 GetBatchEditHelperOwner: function() {
21014  if(!this.allowBatchEditing) return null;
21015  if(!this.batchEditHelperOwner)
21016   this.batchEditHelperOwner = this.CreateBatchEditHelperOwner();
21017  return this.batchEditHelperOwner;
21018 },
21019 CreateBatchEditHelper: function(owner) { return new ASPx.GridBatchEditHelper(owner); },
21020 CreateBatchEditHelperOwner: function() { },
21021 GetScrollHelper: function() { return null; },
21022 GetDragHelper: function() {
21023  if(!this.dragHelper)
21024   this.dragHelper = new GridViewDragHelper(this);
21025  return this.dragHelper;
21026 },
21027 GetEndlessPagingHelper: function() {
21028  if(!this.useEndlessPaging) return null;
21029  if(!this.endlessPagingHelper)
21030   this.endlessPagingHelper = this.CreateEndlessPagingHelper();
21031  return this.endlessPagingHelper;
21032 },
21033 CreateEndlessPagingHelper: function() { return null; },
21034 GetCellFocusHelper: function() {
21035  if(!this.allowFocusedCell) return null;
21036  if(!this.cellFocusHelper)
21037   this.cellFocusHelper = this.CreateCellFocusHelper();
21038  return this.cellFocusHelper;
21039 },
21040 CreateCellFocusHelper: function() { return null; },
21041 GetCellSelectionHelper: function() {
21042  if(!this.allowSelectionCell) return null;
21043  if(!this.cellSelectionHelper)
21044   this.cellSelectionHelper = this.CreateCellSelectionHelper();
21045  return this.cellSelectionHelper;
21046 },
21047 CreateCellSelectionHelper: function() { return null; },
21048 GetClipboardHelper: function() {
21049  if(!this.allowFocusedCell) return null;
21050  if(!this.clipboardHelper)
21051   this.clipboardHelper = this.CreateClipboardHelper();
21052  return this.clipboardHelper;
21053 },
21054 CreateClipboardHelper: function() { return null; },
21055 GetStyleHelper: function() {
21056  if(!this.styleHelper)
21057   this.styleHelper = this.CreateStyleHelper(this);
21058  return this.styleHelper;
21059 },
21060 CreateStyleHelper: function() { return new GridStyleHelper(this); },
21061 GetLayoutHelper: function() {
21062  if(!this.layoutHelper)
21063   this.layoutHelper = this.CreateLayoutHelper();
21064  return this.layoutHelper;
21065 },
21066 CreateLayoutHelper: function() { return new GridLayoutHelper(this); },
21067 GetNavigationHelper: function() {
21068  if(!this.navigationHelper)
21069   this.navigationHelper = this.CreateNavigationHelper();
21070  return this.navigationHelper;
21071 },
21072 CreateNavigationHelper: function() { },
21073 GetCallbackHelper: function() {
21074  if(!this.callbackHelper)
21075   this.callbackHelper = this.CreateCallbackHelper();
21076  return this.callbackHelper;
21077 },
21078 CreateCallbackHelper: function() { return new GridCallbackHelper(this); },
21079 GetFilterHelper: function() {
21080  if(!this.filterHelper)
21081   this.filterHelper = this.CreateFilterHelper();
21082  return this.filterHelper;
21083 },
21084 CreateFilterHelper: function() { return new ASPx.GridFilterHelper(this); },
21085 GetToolbarHelper: function() {
21086  if(!this.toolbarHelper)
21087   this.toolbarHelper = this.CreateToolbarHelper();
21088  return this.toolbarHelper;
21089 },
21090 CreateToolbarHelper: function() { return new ASPx.GridToolbarHelper(this); },
21091 CreateKbdHelper: function() {
21092  return new ASPx.GridKbdHelper(this);
21093 },
21094 InitKbdHelper: function() {
21095  if(!this.kbdHelper && this.IsKbdHelperRequired())
21096   this.kbdHelper = this.CreateKbdHelper();
21097  if(this.kbdHelper) {
21098   if(this.IsKbdHelperRequired()) {
21099    this.kbdHelper.Init();
21100    ASPx.KbdHelper.RegisterAccessKey(this);
21101   }
21102   else
21103    this.kbdHelper.Dispose();
21104  }
21105 },
21106 OnKbdEventChanged: function() {
21107  this.InitKbdHelper();
21108 },
21109 IsKbdHelperRequired: function() {
21110  return !this.KeyDown.IsEmpty() || !this.KeyPress.IsEmpty() || !this.KeyUp.IsEmpty();
21111 },
21112 Invalidate: function() {
21113  this.InvalidateLayout();
21114 },
21115 InvalidateLayout: function() {
21116  this.GetLayoutHelper().Invalidate();
21117  var navigationHelper = this.GetNavigationHelper();
21118  if(navigationHelper)
21119   navigationHelper.Invalidate();
21120  this.serverVisibleIndicesHash = null;
21121 },
21122 IsLastCallbackProcessedAsEndless: function() {
21123  var helper = this.GetEndlessPagingHelper();
21124  return helper && helper.endlessCallbackComplete;
21125 },
21126 UpdateScrollableControls: function() {
21127  var helper = this.GetScrollHelper();
21128  if(helper)
21129   helper.Update();
21130 },
21131 SetHeight: function(height) {
21132  var mainElemnt = this.GetMainElement();
21133  if(!ASPx.IsExistsElement(mainElemnt)) return;
21134  var scrollHelper = this.GetScrollHelper();
21135  if(scrollHelper)
21136   scrollHelper.SetHeight(height);
21137 },
21138 AttachTableClickEvents: function(table) {
21139  var handlers = {
21140   "click": function(e) { ASPx.GTableClick(this.name, e); }.bind(this),
21141   "dblclick": function(e) { ASPx.GVTableDblClick(this.name, e); }.bind(this)
21142  };
21143  this.AttachEventsToElement(table, handlers, true);
21144 },
21145 AttachEventsToElement: function(element, handlers, useCapturing) {
21146  for(var eventName in handlers) {
21147   if(!handlers.hasOwnProperty(eventName))
21148    continue;
21149   var duplicateAttachLocker = "dxg" + eventName;
21150   if(element[duplicateAttachLocker])
21151    continue;
21152   ASPx.Evt.AttachEventToElement(element, eventName, handlers[eventName], useCapturing);
21153   element[duplicateAttachLocker] = true;
21154  }
21155 },
21156 AttachMainTableClickEvents: function() {
21157  var mainTable = this.GetMainTable();
21158  if(mainTable)
21159   this.AttachTableClickEvents(mainTable);
21160 },
21161 SetHeadersClientEvents: function() {
21162  var grid = this;
21163  var attachMouseDown = function(headerCell) { 
21164   ASPx.Evt.AttachEventToElement(headerCell, ASPx.TouchUIHelper.touchMouseDownEventName, function(e) { 
21165    grid.HeaderMouseDown(headerCell, e);
21166   }, true);
21167  };
21168  this.AttachEventToHeaderCells(attachMouseDown, false);
21169  this.AttachEventToHeaderCells(attachMouseDown, true);
21170  this.AttachEventToCustomizationWindowHeaderCells(attachMouseDown);
21171 },
21172 AttachEventToCustomizationWindowHeaderCells: function(attachFunc) {
21173  var custWindow = this.GetCustomizationWindowElement();
21174  if(!custWindow) return;
21175  var headers = this.GetCustomizationWindowHeaders();
21176  for(var i = 0; i < headers.length; i++)
21177   attachFunc(headers[i]);
21178 },
21179 AttachEventToHeaderCells: function(attachFunc, inGroupPanel) {
21180  for(var i = 0; i < this.columns.length; i++) {
21181   var header = this.GetHeader(this.columns[i].index, inGroupPanel);
21182   if(header) 
21183    attachFunc(header);
21184  }
21185 },
21186 GetCustomizationWindowHeaders: function() {
21187  return ASPx.GetNodesByPartialClassName(this.GetCustomizationWindowElement(), ASPx.GridViewConsts.HeaderCellCssClass);
21188 },
21189 UpdatePostBackSyncInput: function(isChangedNotification) {
21190  if(!ASPx.IsExists(this.stateObject.lastMultiSelectIndex)) return;
21191  var selectedIndex = isChangedNotification ? -1 : this.lastMultiSelectIndex; 
21192  this.stateObject.lastMultiSelectIndex = selectedIndex;
21193 },
21194 ApplyPostBackSyncData: function() {
21195  if(!ASPx.IsExists(this.stateObject.lastMultiSelectIndex)) return;
21196  this.lastMultiSelectIndex = this.stateObject.lastMultiSelectIndex;
21197 },
21198 shouldPreventFocusRestoringOnCallback: function () {
21199  return this.scrollToRowIndex !== -1 || this.shouldScrollToNewRow;
21200 },
21201 MakeRowVisible: function(visibleIndex) { },
21202 IsRowHotTrackEnabled: function() {
21203  return this.rowHotTrackStyle !== null;
21204 },
21205 EnsureRowHotTrackItems: function() {
21206  if(!this.IsRowHotTrackEnabled())
21207   return;
21208  var list = [ ];
21209  var rowIndices = this.GetRowHotTrackItemsRowIndices();
21210  for(var i = rowIndices.start; i < rowIndices.start + rowIndices.end; i++)
21211   list.push(this.GetDataItemIDPrefix() + i);
21212  if(list.length > 0)
21213   ASPx.AddHoverItems(this.name, [ [ [this.rowHotTrackStyle[0]], [this.rowHotTrackStyle[1]],  list, this.GetHotTrackItemPostfixes() ] ]);
21214 },
21215 GetHotTrackItemPostfixes: function(){ return null; },
21216 GetRowHotTrackItemsRowIndices: function() {
21217  return {
21218   start: this.visibleStartIndex,
21219   end: this.pageRowCount
21220  };
21221 },
21222 GetFooterCellIndex: function(element) {
21223  element = this.GetFooterCellElement(element, ASPx.GridViewConsts.FooterRowID);
21224  if(element == null)
21225   return -1;
21226  var matrix = this.GetHeaderMatrix();
21227  var leafIndex = element.cellIndex - this.GetFooterIndentCount(element.parentNode);
21228  var index = matrix.GetLeafIndices()[leafIndex];
21229  return ASPx.IsExists(index) ? index : -1;
21230 },
21231 GetGroupFooterCellIndex: function(element) {
21232  element = this.GetFooterCellElement(element, ASPx.GridViewConsts.GroupFooterRowID);
21233  return element != null ? this.GetColumnIndexByDataCell(element) : -1;
21234 },
21235 GetColumnIndexByDataCell: function(element) {
21236  return -1;
21237 },
21238 GetFooterCellElement: function(element, footerRowID) {
21239  var footerRowName = this.name + "_" + footerRowID;
21240  while(element.parentNode.id.indexOf(footerRowName) === -1) {
21241   if(element.tagName == "BODY")
21242    return null;
21243   element = element.parentElement;
21244  }
21245  return element;
21246 },
21247 GetFooterIndentCount: function(footerElement) {
21248  return ASPx.GetChildNodesByClassName(footerElement, "dxgvIndentCell").length;
21249 },
21250 Focus: function() {
21251  if(this.kbdHelper)
21252   this.kbdHelper.Focus();
21253 },
21254 PerformCallback: function(args, onSuccess){
21255  if(!ASPx.IsExists(args)) args = "";
21256  this.gridCallBack([ASPxClientGridViewCallbackCommand.CustomCallback, args], onSuccess);
21257 },
21258 GetValuesOnCustomCallback: function(args, onCallBack) {
21259  this.gridFuncCallBack([ASPxClientGridViewCallbackCommand.CustomValues, args], onCallBack);
21260 },
21261 GotoPage: function(pageIndex){
21262  if(this.useEndlessPaging)
21263   return;
21264  this.gridCallBack([ASPxClientGridViewCallbackCommand.GotoPage, pageIndex]);
21265 },
21266 GetPageIndex: function(){
21267  return this.pageIndex;
21268 },
21269 GetPageCount: function(){
21270  return this.pageCount;
21271 },
21272 NextPage: function(){
21273  this.gridCallBack([ASPxClientGridViewCallbackCommand.NextPage]);
21274 },
21275 PrevPage: function(focusBottomRow){
21276  if(!this.useEndlessPaging)
21277   this.gridCallBack([ASPxClientGridViewCallbackCommand.PreviousPage, focusBottomRow ? "T" : "F"]);
21278 },
21279 IsLastPage: function() {
21280  return this.pageIndex === this.pageCount - 1;
21281 },
21282 GetItemKey: function(visibleIndex) {
21283  var arrayIndex = visibleIndex - this.visibleStartIndex;
21284  if(arrayIndex < 0 || arrayIndex > this.keys.length - 1) 
21285   return null;
21286  var key = this.keys[arrayIndex];
21287  if(key == "/^DXN")
21288   key = null;
21289  return key;
21290 },   
21291 GetDataItemVisibleIndices: function(includeDeleted, fromAPI) {
21292  var helper = this.GetBatchEditHelper();
21293  if(helper) {
21294   includeDeleted |= helper.GetHighlightDeletedItems() && !fromAPI;
21295   var keys = helper.GetRecordKeys(!includeDeleted);
21296   return keys.map(function(key) { return this.ConvertKeyToVisibleIndex(key); }.bind(this));
21297  }
21298  return this.GetDataItemVisibleIndicesCore();
21299 },
21300 GetDataItemVisibleIndicesCore: function() {
21301  var indices = this.GetCurrentPageIndices();
21302  return indices.filter(function(index) { return this.GetDataItem(index); }.bind(this)); 
21303 },
21304 GetRecordKeys: function(includeDeleted) { 
21305  var indices = this.GetDataItemVisibleIndices(includeDeleted);
21306  return indices.map(this.ConvertVisibleIndexToKey.bind(this));
21307 },
21308 ConvertVisibleIndexToKey: function(visibleIndex) { 
21309  if(!ASPx.IsExists(visibleIndex))
21310   return null;
21311  if(visibleIndex < 0)
21312   return visibleIndex;
21313  var key = this.GetItemKey(visibleIndex);
21314  if(ASPx.IsExists(key))
21315   return key;
21316  var helper = this.GetBatchEditHelper();
21317  return helper && helper.GetSavedKeyByVisibleIndex(visibleIndex);
21318 },
21319 ConvertKeyToVisibleIndex: function(key) {
21320  var helper = this.GetBatchEditHelper();
21321  if(helper && helper.IsNewRecord(key))
21322   return parseInt(key);  
21323  this.EnsureServerVisibleIndicesHash();
21324  if(ASPx.IsExists(this.serverVisibleIndicesHash[key]))
21325   return this.serverVisibleIndicesHash[key];
21326  return helper ? helper.GetSavedVisibleIndexByKey(key) : null;
21327 },
21328 EnsureServerVisibleIndicesHash: function() {
21329  if(this.serverVisibleIndicesHash)
21330   return;
21331  this.serverVisibleIndicesHash = { };
21332  var indices = this.GetCurrentPageIndices();
21333  for(var i = 0; i < indices.length; i++) {
21334   var visibleIndex = indices[i];
21335   var key = this.GetItemKey(visibleIndex);
21336   this.serverVisibleIndicesHash[key] = visibleIndex;
21337  }
21338 },
21339 GetCurrentPageIndices: function() {
21340  var indices = [ ];
21341  var startIndex = this.GetTopVisibleIndex();
21342  var endIndex = startIndex + this.pageRowCount;
21343  for(var i = startIndex; i < endIndex; i++)
21344   indices.push(i);
21345  return indices;
21346 },
21347 StartEditItem: function(visibleIndex, columnIndex) {
21348  this.StartEditItemByKey(this.ConvertVisibleIndexToKey(visibleIndex), columnIndex);
21349 },
21350 StartEditItemByKey: function(key, columnIndex) {
21351  if(!this.HasKeyField() || key === null) 
21352   return;
21353  var batchEditHelper = this.GetBatchEditHelper();
21354  if(batchEditHelper)
21355   batchEditHelper.StartEditCell(key, columnIndex);
21356  else
21357   this.gridCallBack([ASPxClientGridViewCallbackCommand.StartEdit, key]);
21358 },
21359 IsEditing: function() { return this.editState > 0; },
21360 IsNewItemEditing: function() { return this.editState > 1; },
21361 IsEditingItem: function(visibleIndex) { return this.editItemVisibleIndex === visibleIndex; },
21362 IsNewRowAtBottom: function() { return this.editState == 3; },
21363 UpdateEdit: function(){
21364  this._updateEdit();
21365 },
21366 CancelEdit: function(visibleIndex) {
21367  var batchEditHelper = this.GetBatchEditHelper();
21368  if(batchEditHelper) {
21369   var recordKey = ASPx.IsExists(visibleIndex) && visibleIndex !== this.InvalidItemIndex ? this.ConvertVisibleIndexToKey(visibleIndex) : null;
21370   batchEditHelper.CancelEdit(recordKey);
21371  } else
21372   this.gridCallBack([ASPxClientGridViewCallbackCommand.CancelEdit]);
21373 },
21374 AddNewItem: function() {
21375  if(this.allowBatchEditing)
21376   this.batchEditApi.AddNewItem();
21377  else 
21378   this.AddNewItemOnServer();
21379 },
21380 AddNewItemOnServer: function() {
21381  if(!this.HasKeyField()) return;
21382  this.gridCallBack([ASPxClientGridViewCallbackCommand.AddNewRow]);
21383 },
21384 DeleteItem: function(visibleIndex) {
21385  if(this.allowBatchEditing)
21386   this.batchEditApi.DeleteItem(visibleIndex);  
21387  else
21388   this.DeleteItemByKey(this.GetItemKey(visibleIndex));
21389 },
21390 RecoverItem: function(visibleIndex){
21391  if(this.allowBatchEditing)
21392   this.batchEditApi.RecoverItem(visibleIndex);  
21393 },
21394 DeleteItemByKey: function(key) {
21395  if(this.allowBatchEditing)
21396   this.batchEditApi.DeleteItemByKey(key);
21397  else
21398   this.DeleteItemByKeyOnServer(key);
21399 },
21400 DeleteItemByKeyOnServer: function(key) {
21401  if(!this.HasKeyField() || key === null) 
21402   return;
21403  this.gridCallBack([ASPxClientGridViewCallbackCommand.DeleteRow, key]);
21404 },
21405 HasKeyField: function() {
21406  var result = this.keys.length > 0 || this.pageRowCount === 0;
21407  if(!result)
21408   alert(this.RequireKeyFieldNameText);
21409  return result;
21410 },
21411 Refresh: function(){
21412  var batchEditHelper = this.GetBatchEditHelper();
21413  if(batchEditHelper)
21414   batchEditHelper.CancelEdit();
21415  this.gridCallBack([ASPxClientGridViewCallbackCommand.Refresh]);
21416 },
21417 CopyToClipboard: function() {
21418  var clipboardHelper = this.GetClipboardHelper();
21419  if(clipboardHelper)
21420   clipboardHelper.CopyToClipboard();
21421 },
21422 PasteFromClipboard: function() {
21423  var clipboardHelper = this.GetClipboardHelper();
21424  if(clipboardHelper)
21425   clipboardHelper.PasteFromClipboard();
21426 },
21427 UpdateSummaries: function() {
21428  if(this.allowBatchEditing)
21429   this.gridFuncCallBack([ASPxClientGridViewCallbackCommand.UpdateSummaries], this.ProcessUpdateSummariesInfo.bind(this));
21430 },
21431 ProcessUpdateSummariesInfo: function(summaryInfo) {
21432  var batchEditHelper = this.GetBatchEditHelper();
21433  if(batchEditHelper)
21434   batchEditHelper.UpdateSummaries(summaryInfo);
21435 },
21436 ApplyFilter: function(expression){
21437  expression = expression || "";
21438  this.gridCallBack([ASPxClientGridViewCallbackCommand.ApplyFilter, expression]);
21439 },
21440 ClearFilter: function () {
21441  this.GetFilterHelper().ClearFilterEditorsState();
21442  this.ApplyFilter();
21443 },
21444 GetAutoFilterEditor: function(column) { 
21445  var index = this._getColumnIndexByColumnArgs(column);
21446  if(!ASPx.IsExists(index)) return null;
21447  return ASPx.GetControlCollection().Get(this.name + "_DXFREditorcol" + index);
21448 },
21449 AutoFilterByColumn: function(column, val){
21450  var index = this._getColumnIndexByColumnArgs(column);
21451  if(!ASPx.IsExists(index)) return;
21452  if(!ASPx.IsExists(val)) val = "";  
21453  this.gridCallBack([ASPxClientGridViewCallbackCommand.ApplyColumnFilter, index, val]);
21454 },
21455 ApplyHeaderFilterByColumn: function() {
21456  var popup = this.GetHeaderFilterPopup();
21457  popup.Hide();
21458  var helper = this.GetFilterHelper();
21459  var column = helper.GetHeaderFilterPopupRelatedColumn();
21460  if(column) {
21461   var state = helper.GetHeaderFilterCallbackState(column.index);
21462   this.gridCallBack([ASPxClientGridViewCallbackCommand.ApplyHeaderColumnFilter, column.index, ASPx.Json.ToJson(state)]);
21463  }
21464 },
21465 SortBy: function(column, sortOrder, reset, sortIndex){
21466  if(this.RaiseColumnSorting(this._getColumnObjectByArg(column))) return;
21467  column = this._getColumnIndexByColumnArgs(column);
21468  if(!ASPx.IsExists(sortIndex)) sortIndex = "";
21469  if(!ASPx.IsExists(sortOrder)) sortOrder = "";
21470  if(!ASPx.IsExists(reset)) reset = true;
21471  this.gridCallBack([ASPxClientGridViewCallbackCommand.Sort, column, sortIndex, sortOrder, reset]);
21472 },
21473 GroupBy: function(column, groupIndex, sortOrder){
21474  var columnObj = this._getColumnObjectByArg(column);
21475  if(!this.canGroupByColumn(columnObj)) return;
21476  if(this.RaiseColumnGrouping(columnObj)) return;
21477  column = this._getColumnIndexByColumnArgs(column);
21478  if(!ASPx.IsExists(groupIndex)) groupIndex = "";
21479  if(!ASPx.IsExists(sortOrder)) sortOrder = "ASC";
21480  this.gridCallBack([ASPxClientGridViewCallbackCommand.Group, column, groupIndex, sortOrder]);
21481 },
21482 Ungroup: function(column){
21483  column = this._getColumnIndexByColumnArgs(column);
21484  this.gridCallBack([ ASPxClientGridViewCallbackCommand.UnGroup, column ]);
21485 },
21486 ExpandAll: function(){
21487  this.gridCallBack([ASPxClientGridViewCallbackCommand.ExpandAll]);
21488 },
21489 CollapseAll: function(){
21490  this.gridCallBack([ASPxClientGridViewCallbackCommand.CollapseAll]);
21491 },
21492 MoveColumn: function(column, columnMoveTo, direction, moveToGroup, moveFromGroup){
21493  if(!ASPx.IsExists(column)) return;
21494  if(!ASPx.IsExists(columnMoveTo)) columnMoveTo = -1;
21495  if(!ASPx.IsExists(moveToGroup)) moveToGroup = false;
21496  if(!ASPx.IsExists(moveFromGroup)) moveFromGroup = false;
21497  if(moveToGroup) {
21498   if(this.RaiseColumnGrouping(this._getColumnObjectByArg(column))) return;
21499  }
21500  direction = this.getColumnMoveDirection(direction);
21501  column = this._getColumnIndexByColumnArgs(column);
21502  this.MoveColumnCore(column, columnMoveTo, direction, moveToGroup, moveFromGroup);
21503 },
21504 MoveColumnCore: function(sourceIndex, targetIndex, direction, moveToGroup, moveFromGroup) {
21505  this.gridCallBack([ASPxClientGridViewCallbackCommand.ColumnMove, sourceIndex, targetIndex, direction, moveToGroup, moveFromGroup]);
21506 },
21507 getColumnMoveDirection: function(direction){
21508  if(!ASPx.IsExists(direction))
21509   return ASPxClientGridColumnMovingTargetPosition.Left;
21510  if(direction === false)
21511   return ASPxClientGridColumnMovingTargetPosition.Left;
21512  if(direction === true)
21513   return ASPxClientGridColumnMovingTargetPosition.Right;
21514  if(ASPx.IsNumber(direction))
21515   return direction;
21516  return ASPxClientGridColumnMovingTargetPosition.Left;
21517 },
21518 IsCustomizationWindowVisible: function(){
21519  var custWindow = this.GetCustomizationWindow();
21520  return custWindow != null && custWindow.IsVisible();
21521 },
21522 ShowCustomizationWindow: function(showAtElement, accessibleFocusElement){
21523  var custWindow = this.GetCustomizationWindow();
21524  if(!custWindow) return;
21525  if(!showAtElement) showAtElement = this.GetMainElement();
21526  if(this.accessibilityCompliant && accessibleFocusElement)
21527   custWindow.accessibleFocusElement = accessibleFocusElement;
21528  custWindow.ShowAtElement(showAtElement);
21529 },
21530 HideCustomizationWindow: function(){
21531  var custWindow = this.GetCustomizationWindow();
21532  if(custWindow != null) custWindow.Hide();
21533 },
21534 ShowCustomizationDialog: function() { },
21535 ExportTo: function(format) {
21536  this.gridPostBack([ASPxClientGridViewCallbackCommand.Export, format]);
21537 },
21538 GetSelectedFieldValues: function(fieldNames, onCallBack) {
21539  this.gridFuncCallBack([ASPxClientGridViewCallbackCommand.SelFieldValues, fieldNames], onCallBack);
21540 },
21541 GetSelectedKeysOnPage: function() {
21542  var keys = [];
21543  for(var i = 0; i < this.pageRowCount; i++) {
21544   if(this._isRowSelected(this.visibleStartIndex + i))
21545    keys.push(this.keys[i]);
21546  }
21547  return keys; 
21548 },
21549 GetItemValues: function(visibleIndex, fieldNames, onCallBack) {
21550  this.gridFuncCallBack([ASPxClientGridViewCallbackCommand.RowValues, visibleIndex, fieldNames], onCallBack);
21551 },
21552 GetPageItemValues: function(fieldNames, onCallBack) {
21553  this.gridFuncCallBack([ASPxClientGridViewCallbackCommand.PageRowValues, fieldNames], onCallBack);
21554 },
21555 GetVisibleItemsOnPage: function() {
21556  var batchEditHelper = this.GetBatchEditHelper();
21557  if(batchEditHelper)
21558   return batchEditHelper.GetVisibleRecordsOnPageCount();
21559  return this.pageRowCount;
21560 },
21561 GetTopVisibleIndex: function() {
21562  return this.visibleStartIndex;
21563 },
21564 GetColumnsCount: function() {
21565  return this.GetColumnCount();
21566 },
21567 GetColumnCount: function() {
21568  return this._getColumnCount();
21569 },
21570 GetColumn: function(index) {
21571  return this._getColumn(index);
21572 },
21573 GetColumnById: function(id) {
21574  return this._getColumnById(id);
21575 },
21576 GetColumnByField: function(fieldName) {
21577  return this._getColumnByField(fieldName);
21578 },
21579 GetEditor: function(column) {
21580  var columnObject = this._getColumnObjectByArg(column);
21581  return columnObject != null ? this.GetEditorByColumnIndex(columnObject.index) : null;
21582 },
21583 FocusEditor: function(column) {
21584  var editor = this.GetEditor(column);
21585  if(editor && editor.SetFocus) {
21586   editor.SetFocus();  
21587  }
21588 },
21589 GetEditValue: function(column) {
21590  var editor = this.GetEditor(column);
21591  return editor != null && editor.enabled ? editor.GetValue() : null;
21592 },
21593 SetEditValue: function(column, value) {
21594  var editor = this.GetEditor(column);
21595  if(editor != null && editor.enabled)
21596   editor.SetValue(value);
21597 },
21598 ShowFilterControl: function() {
21599  this.PreventCallbackAnimation();
21600  this.gridCallBack([ASPxClientGridViewCallbackCommand.ShowFilterControl]);
21601 },
21602 CloseFilterControl: function() {
21603  this.PreventCallbackAnimation();
21604  this.HideFilterControlPopup();
21605  this.gridCallBack([ASPxClientGridViewCallbackCommand.CloseFilterControl]);
21606 },
21607 HideFilterControlPopup: function() {
21608  var popup = this.GetFilterControlPopup();
21609  if(popup) {
21610   popup.Hide();
21611   if(this.accessibilityCompliant) {
21612    var needToStoreFocusTreeLine = !this.accessibilityFocusTreeLine && ASPx.GetIsParent(this.GetMainElement(), ASPx.GetActiveElement());
21613    if(needToStoreFocusTreeLine)
21614     this.accessibilityFocusTreeLine = ASPx.RestoreFocusHelper.getFocusTreeLine(this);
21615   }
21616  }
21617 },
21618 ApplyFilterControl: function() {
21619  this.PreventCallbackAnimation();
21620  var fc = this.GetFilterControl();
21621  if(fc == null) return;
21622  if(!this.callBacksEnabled)
21623   this.HideFilterControlPopup();
21624  if(!fc.isApplied)
21625   fc.Apply(this);
21626 },
21627 SetFilterEnabled: function(isFilterEnabled) {
21628  this.gridCallBack([ASPxClientGridViewCallbackCommand.SetFilterEnabled, isFilterEnabled]);
21629 },
21630 GetVerticalScrollPosition: function() { return 0; },
21631 SetVerticalScrollPosition: function(value) { },
21632 RaiseSelectionChangedOutOfServer: function() {
21633  this.RaiseSelectionChanged(-1, false, false, true);
21634 },
21635 RaiseSelectionChanged: function(visibleIndex, isSelected, isAllRecordsOnPage, isChangedOnServer) {
21636  if(!this.SelectionChanged.IsEmpty()){
21637   var args = this.CreateSelectionEventArgs(visibleIndex, isSelected, isAllRecordsOnPage, isChangedOnServer);
21638   this.SelectionChanged.FireEvent(this, args);
21639   if(args.processOnServer) {
21640    this.gridCallBack([ASPxClientGridViewCallbackCommand.Selection]);
21641   }
21642  }
21643  return false; 
21644 },
21645 CreateSelectionEventArgs: function(visibleIndex, isSelected, isAllRecordsOnPage, isChangedOnServer){
21646  return null;
21647 },
21648 RaiseFocusedItemChangedOutOfServer: function() { 
21649  this.RaiseFocusedItemChanged(true); 
21650 },
21651 RaiseFocusedItemChanged: function(isChangedOnServer) { return false; },
21652 RaiseItemFocusing: function(visibleIndex, htmlEvent) { return false; },
21653 RaiseColumnSorting: function(column) {
21654  if(!this.ColumnSorting.IsEmpty()){
21655   var args = this.CreateColumnCancelEventArgs(column);
21656   this.ColumnSorting.FireEvent(this, args);
21657   return args.cancel;
21658  }
21659  return false; 
21660 },
21661 CreateColumnCancelEventArgs: function(column){
21662  return null;
21663 },
21664 RaiseColumnGrouping: function(column) {
21665  if(!this.ColumnGrouping.IsEmpty()){
21666   var args = this.CreateColumnCancelEventArgs(column);
21667   this.ColumnGrouping.FireEvent(this, args);
21668   return args.cancel;
21669  }
21670  return false; 
21671 },
21672 RaiseItemClick: function(visibleIndex, htmlEvent) {
21673  return false; 
21674 },
21675 RaiseItemDblClick: function(visibleIndex, htmlEvent) {
21676  return false; 
21677 },
21678 RaiseCustomizationWindowCloseUp: function() {
21679  if(!this.CustomizationWindowCloseUp.IsEmpty()){
21680   var args = new ASPxClientEventArgs();
21681   this.CustomizationWindowCloseUp.FireEvent(this, args);
21682  }
21683  return false; 
21684 },
21685 RaiseColumnMoving: function(targets) {
21686  return false;
21687 },
21688 RaiseToolbarItemClick: function(toolbarInfo, item) {
21689  if(this.ToolbarItemClick.IsEmpty())
21690   return false;
21691  var args = new ASPxClientGridToolbarItemClickEventArgs(toolbarInfo.index, toolbarInfo.name, item, false);
21692  this.ToolbarItemClick.FireEvent(this, args);
21693  if(!args.handled && args.processOnServer) {
21694   this.GetToolbarHelper().ProcessCustomToolbarItemClickOnServer(args.usePostBack);
21695   return true;
21696  }
21697  return args.handled;
21698 },
21699 RaiseKeyDown: function(evt) {
21700  if(this.KeyDown.IsEmpty())
21701   return false;
21702  var args = new ASPxClientGridKeyboardEventArgs(evt);
21703  this.KeyDown.FireEvent(this, args);
21704  return args.handled;
21705 },
21706 RaiseKeyPress: function(evt) {
21707  if(this.KeyPress.IsEmpty())
21708   return false;
21709  var args = new ASPxClientGridKeyboardEventArgs(evt);
21710  this.KeyPress.FireEvent(this, args);
21711  return args.handled;
21712 },
21713 RaiseKeyUp: function(evt) {
21714  if(this.KeyUp.IsEmpty())
21715   return false;
21716  var args = new ASPxClientGridKeyboardEventArgs(evt);
21717  this.KeyUp.FireEvent(this, args);
21718  return args.handled;
21719 },
21720 RaiseBatchEditSummaryDisplayText: function(summaryInfo, text, groupRowVisibleIndex) {
21721  if(!this.BatchEditSummaryDisplayText.IsEmpty()) {
21722   var args = new ASPxClientGridBatchEditSummaryDisplayTextEventArgs(summaryInfo, text, groupRowVisibleIndex);
21723   this.BatchEditSummaryDisplayText.FireEvent(this, args);
21724   return args.displayText;
21725  }
21726  return text;
21727 },
21728 RaiseBatchEditStartEditing: function(visibleIndex, column, rowValues) { return null; },
21729 RaiseBatchEditEndEditing: function(visibleIndex, focusedColumn, rowValues) { return null; },
21730 RaiseBatchEditItemChangesCanceling: function(visibleIndex, rowValues) { return null; },
21731 RaiseBatchEditItemValidating: function(visibleIndex, validationInfo) { return null; },
21732 RaiseBatchEditConfirmShowing: function(requestTriggerID) { return false; },
21733 RaiseBatchEditTemplateCellFocused: function(columnIndex) { return false; },
21734 RaiseBatchEditChangesSaving: function(valuesInfo) { return false; },
21735 RaiseBatchEditChangesCanceling: function(valuesInfo) { return false; },
21736 RaiseBatchEditItemInserting: function(visibleIndex) { return false; },
21737 RaiseBatchEditItemDeleting: function(visibleIndex, itemValues) { return false; },
21738 RaiseBatchEditItemRecovering: function(visibleIndex, itemValues) { return false; },
21739 RaiseClipboardCellPasting: function(info, oldValueInfo, newValueInfo) {
21740  var cellInfo = this.CreateUserCellInfo(this.ConvertKeyToVisibleIndex(info.recordKey), this.GetColumn(info.columnIndex), info.recordKey);
21741  var args = this.CreateClipboardCellPastingArgs(cellInfo, oldValueInfo, newValueInfo);
21742  if(!this.ClipboardCellPasting.IsEmpty())
21743   this.ClipboardCellPasting.FireEvent(this, args);
21744  return args;
21745 },
21746 CreateClipboardCellPastingArgs: function(cellInfo, originalValueInfo, valueInfo) { return null; },
21747 RaiseCellSelectionChanging: function(info, isSelected) {
21748  if(!this.CellSelectionChanging.IsEmpty()) {
21749   var key = info.recordKey;
21750   var cellInfo = this.CreateUserCellInfo(this.ConvertKeyToVisibleIndex(key), this.GetColumn(info.columnIndex), key);
21751   var newSelectionState = isSelected ? ASPxClientGridSelectionState.Selected : ASPxClientGridSelectionState.Unselected;
21752   var args = this.CreateCellSelectionChangingArgs(cellInfo, newSelectionState);
21753   this.CellSelectionChanging.FireEvent(this, args);
21754   return args.cancel;
21755  }
21756 },
21757 CreateCellSelectionChangingArgs: function(cellInfo, newSelectionState) { return null; },
21758 RaiseFocusedCellChanging: function(info) {
21759  if(!this.FocusedCellChanging.IsEmpty()){   
21760   var key = info.recordKey;
21761   var cellInfo = this.CreateUserCellInfo(this.ConvertKeyToVisibleIndex(key), this.GetColumn(info.columnIndex), key);
21762   var args = this.CreateFocusedCellChangingArgs(cellInfo);
21763   this.FocusedCellChanging.FireEvent(this, args);
21764   return args.cancel;
21765  }
21766  return false;   
21767 },
21768 CreateUserCellInfo: function(visibleIndex, column, key) { return null; },
21769 CreateFocusedCellChangingArgs: function(cellInfo) { return null; },
21770 RaiseInternalCheckBoxClick: function(visibleIndex) {
21771  if(!this.InternalCheckBoxClick.IsEmpty()){
21772   var args = {"visibleIndex": visibleIndex, cancel: false};
21773   this.InternalCheckBoxClick.FireEvent(this, args);
21774   return args.cancel;
21775  }
21776  return false;
21777 },
21778 UA_AddNew: function() {
21779  this.AddNewItem();
21780 },
21781 UA_StartEdit: function(visibleIndex) {
21782  this.StartEditItem(visibleIndex);
21783 },
21784 UA_Delete: function(visibleIndex) {
21785  this.DeleteGridItem(visibleIndex);
21786 },
21787 UA_Recover: function(visibleIndex) {
21788  this.RecoverItem(visibleIndex);
21789 },
21790 UA_UpdateEdit: function() {
21791  this.UpdateEdit();
21792 },
21793 UA_CancelEdit: function(visibleIndex) {
21794  this.CancelEdit(visibleIndex);
21795 },
21796 UA_CustomButton: function(id, visibleIndex) {
21797  this.CommandCustomButton(id, visibleIndex);
21798 },
21799 UA_Select: function(visibleIndex) {
21800  if(!this.lookupBehavior || this.allowSelectByItemClick){
21801   var selected = this.allowSelectSingleRowOnly || !this._isRowSelected(visibleIndex);
21802   this.SelectItem(visibleIndex, selected);
21803  }
21804 },
21805 UA_ClearFilter: function() {
21806  this.ClearFilter();
21807 },
21808 UA_ApplySearchFilter: function() {
21809  this.ApplySearchFilterFromEditor();
21810 },
21811 UA_ClearSearchFilter: function() {
21812  var editor = this.GetSearchEditor();
21813  if(editor)
21814   editor.SetValue(null);
21815  this.ApplySearchFilterFromEditor();
21816 },
21817 UA_UpdateSummaries: function() {
21818  this.UpdateSummaries();
21819 },
21820 ApplySearchFilterFromEditor: function() {
21821  this.GetFilterHelper().ApplySearchFilterFromEditor(this.GetSearchEditor());
21822 },
21823 ChangeCellInitialClass: function(cell, className, add) { this.GetStyleHelper().ChangeCellInitialClass(cell, className, add); },
21824 OnDispose: function() { 
21825  if(this.filterHelper)
21826   this.filterHelper.OnDispose();
21827  ASPxClientControl.prototype.OnDispose.call(this);
21828 },
21829 GetEditFormLayout: function() {
21830  if(this.GetPopupEditForm())
21831   return ASPx.GetControlCollection().Get(this.name + "_DXPEForm" + this.GetEditFormLayoutIDPostfix());
21832  return ASPx.GetControlCollection().Get(this.name + this.GetEditFormLayoutIDPostfix());
21833 },
21834 GetEditFormLayoutIDPostfix: function() { return ""; },
21835 GetEditFormLayoutItemByColumn: function(column) {
21836  var editFormLayout = this.GetEditFormLayout();
21837  var columnObject = this._getColumnObjectByArg(column);
21838  if(!editFormLayout || !columnObject)
21839   return null;
21840  return this.getEditFormLayoutItemByColumnCore(editFormLayout, columnObject);
21841 },
21842 getEditFormLayoutItemByColumnCore: function(editFormLayout, columnObject) {
21843  var findByColumnNamePredicate = function(item) {
21844   if(!item.columnProperties)
21845    return false;
21846   return columnObject.name && columnObject.name == item.columnProperties.name;
21847  };
21848  var findByColumnFieldNamePredicate = function(item) {
21849   if(!item.columnProperties)
21850    return false;
21851   return columnObject.fieldName && columnObject.fieldName == item.columnProperties.fieldName;
21852  };
21853  return editFormLayout.getItemByPredicate(findByColumnNamePredicate) || editFormLayout.getItemByPredicate(findByColumnFieldNamePredicate);
21854 },
21855 GetEditFormLayoutItemOrGroup: function(name) {
21856  var editFormLayout = this.GetEditFormLayout();
21857  return editFormLayout ? editFormLayout.GetItemByName(name) : null;
21858 }
21859});
21860ASPxClientGridBase.Cast = ASPxClientControl.Cast;
21861var GridCallbackHelper = ASPx.CreateClass(null, {
21862 constructor: function(grid) {
21863  this.grid = grid;
21864  this.funcCallbackInfoList = [ ];
21865  this.postbackRequestCount = 0;
21866 },
21867 GetAllowDelete: function() { return this.grid.allowDelete; },
21868 GetAllowEdit: function() { return this.grid.allowEdit; },
21869 GetAllowInsert: function() { return this.grid.allowInsert; },
21870 CanSendCallback: function() { return this.grid.callBack && this.grid.callBacksEnabled; },
21871 GetEditorValues: function() { return this.grid.GetEditorValues(); },
21872 GetSelectionState: function() { return this.grid.GetSelectedState(); },
21873 GetKeyValues: function() { return this.grid.GetKeyValues(); },
21874 GetFocusedRowState: function() { return this.grid.stateObject.focusedRow; },
21875 GetToolbarState: function() { return this.grid.GetToolbarHelper().GetCallbackState(); },
21876 GetRequestCount: function() { return this.grid.requestCount; },
21877 ResetUserChangedSelection: function() { 
21878  this.grid.userChangedSelection = false; 
21879 },
21880 GetTotalRequestCount: function() { return this.GetRequestCount() + this.postbackRequestCount; },
21881 CreateGridCallback: function(command, args, callbackHandler) {
21882  this.grid.CreateCallback(args, command, callbackHandler);
21883 },
21884 CreateGridPostback: function(args, preventConvertToUpdatePanelCallback) {
21885  this.grid.SendPostBack(args, preventConvertToUpdatePanelCallback);
21886 },
21887 OnBeforeCallbackOrPostBack: function() {
21888  this.grid.OnBeforeCallbackOrPostBack(); 
21889 },
21890 OnBeforeCallback: function(command) { this.grid.OnBeforeCallback(command); },
21891 SendRequest: function(args, callbackHandler) {
21892  var command = this.GetCorrectedCommand(args);
21893  if(!this.ValidateCommand(command))
21894   return;
21895  this.OnBeforeCallbackOrPostBack();
21896  if(this.CanSendCallback())
21897   this.SendCallback(command, args, callbackHandler);
21898  else
21899   this.SendPostback(args);
21900 },
21901 SendCallback: function(command, args, callbackHandler) {
21902  this.OnBeforeCallback(command);
21903  var callbackState = this.GetGridCallbackState();
21904  this.ResetUserChangedSelection();
21905  this.SendCallbackCore(command, args, callbackState, callbackHandler);
21906 },
21907 SendFuncCallback: function(args, onCallBack) {
21908  var callbackState = this.GetGridCallbackState();
21909  callbackState.push([ "FB", this.GetFuncCallBackIndex(onCallBack) ]);
21910  this.SendCallbackCore("FUNCTION", args, callbackState);
21911 },
21912 SendCallbackCore: function(command, commandArgs, callbackState, callbackHandler) {
21913  callbackState.push([ "GB", this.SerializeCallbackArgs(commandArgs) ]);
21914  this.CreateGridCallback(command, this.FormatCallbackState(callbackState), callbackHandler);
21915 },
21916 SendPostback: function(args) {
21917  this.postbackRequestCount++;
21918  this.CreateGridPostback(this.SerializeCallbackArgs(args), this.IsExportPostback(args));
21919 },
21920 ValidateCommand: function(command) {
21921  if(command === ASPxClientGridViewCallbackCommand.DeleteRow && !this.GetAllowDelete())
21922   return false;
21923  if(command === ASPxClientGridViewCallbackCommand.StartEdit && !this.GetAllowEdit())
21924   return false;
21925  if(command === ASPxClientGridViewCallbackCommand.AddNewRow && !this.GetAllowInsert()
21925)
21926   return false;
21927  return true;
21928 },
21929 GetCorrectedCommand: function(args) {
21930  if(args.length === 0) return "";
21931  var command = args[0];
21932  if(args.length > 1 && command === ASPxClientGridViewCallbackCommand.ColumnMove) {
21933   if(args[args.length - 1])
21934    command = ASPxClientGridViewCallbackCommand.UnGroup;
21935   if(args[args.length - 2])
21936    command = ASPxClientGridViewCallbackCommand.Group;
21937  }
21938  return command;
21939 },
21940 IsExportPostback: function(args) {
21941  if(!ASPx.Ident.IsArray(args) || args.length === 0)
21942   return false;
21943  return args[0] == ASPxClientGridViewCallbackCommand.Export || args[1] == ASPxClientGridViewCallbackCommand.Export;
21944 },
21945 GetGridCallbackState: function() {
21946  return [
21947   [ "EV", this.GetEditorValues() ],
21948   [ "SR", this.GetSelectionState() ],
21949   [ "KV", this.GetKeyValues() ],
21950   [ "FR", this.GetFocusedRowState() ],
21951   [ "CT", this.GetToolbarState() ]
21952  ];
21953 },
21954 GetFuncCallBackIndex: function(onCallBack) {
21955  var info = { date: new Date(), callback: onCallBack };
21956  for(var i = 0; i < this.funcCallbackInfoList.length; i ++) {
21957   if(this.funcCallbackInfoList[i] === null) {
21958    this.funcCallbackInfoList[i] = info;
21959    return i;
21960   }
21961  }
21962  this.funcCallbackInfoList.push(info);
21963  return this.funcCallbackInfoList.length - 1;
21964 },
21965 GetFuncCallBackInfo: function(index) {
21966  if(index < 0 || index >= this.funcCallbackInfoList.length) 
21967   return null;
21968  var result = this.funcCallbackInfoList[index];
21969  this.funcCallbackInfoList[index] = null;
21970  return result;
21971 },
21972 HasWaitedFuncCallbacks: function() {
21973  return this.funcCallbackInfoList.filter(function(i) { return i !== null; }).length > 0;
21974 },
21975 HasWaitedFuncCallbacksFromInterval: function(timeout) {
21976  var date = new Date();
21977  for(var i = 0; i < this.funcCallbackInfoList.length; i++) {
21978   var info = this.funcCallbackInfoList[i];
21979   if(info && (date - info.date) < timeout)
21980    return true;
21981  }
21982  return false;
21983 },
21984 FormatCallbackState: function(callbackState) {
21985  var result = [ ];
21986  for(var i = 0; i < callbackState.length; i++) {
21987   var stateItem = callbackState[i];
21988   if(!stateItem || stateItem.length !== 2)
21989    continue;
21990   var stateKey = stateItem[0];
21991   var stateValue = stateItem[1];
21992   if(ASPx.IsExists(stateValue) && stateValue !== "") {
21993    var stateValueString = stateValue.toString();
21994    result.push(stateKey);
21995    result.push("|");
21996    result.push(stateValueString.length);
21997    result.push(";");
21998    result.push(stateValueString);
21999    result.push(";");
22000   }
22001  }
22002  return result.join("");
22003 },
22004 SerializeCallbackArgs: function(args) {
22005  if(!ASPx.Ident.IsArray(args) || args.length === 0)
22006   return "";
22007  var result = [ ];
22008  for(var i = 0; i < args.length; i++) {
22009   var item = args[i].toString();
22010   result.push(item.length);
22011   result.push("|");
22012   result.push(item);
22013  }
22014  return result.join("");
22015 }
22016});
22017var GridStyleHelper = ASPx.CreateClass(ASPx.GridStyleHelperBase, {
22018 SelectedItemKey: "sel",
22019 FocusedItemKey: "fi",
22020 constructor: function(grid) {
22021  this.grid = grid;
22022 },
22023 GetStyles: function() { return this.grid.styleInfo; },
22024 GetSelectedItemStyle: function() { return this.GetStyleInfo(this.SelectedItemKey); },
22025 GetFocusedItemStyle: function() { return this.GetStyleInfo(this.FocusedItemKey); },
22026 IsSelectedItemStyle: function(style) { return this.CheckStyleInfoByKey(style, this.SelectedItemKey); },
22027 IsFocusedItemStyle: function(style) { return this.CheckStyleInfoByKey(style, this.FocusedItemKey); },
22028});
22029var ASPxClientGridColumnBase = ASPx.CreateClass(null, {
22030 constructor: function(prop) {
22031  this.index =   ASPx.IsExists(prop[0]) ? prop[0] : -1;
22032  this.visible =    ASPx.IsExists(prop[1]) ?  !!prop[1] : true;
22033  this.name =    ASPx.IsExists(prop[2]) ? prop[2] : "";
22034  this.fieldName =  ASPx.IsExists(prop[3]) ? prop[3] : "";
22035  this.allowSort =  ASPx.IsExists(prop[4]) ?  !!prop[4] : true;
22036  this.HFMode =     ASPx.IsExists(prop[5]) ? prop[5] : 1;
22037  this.sortIndex =  ASPx.IsExists(prop[6]) ? prop[6] : -1;
22038  this.sortOrder =  ASPx.IsExists(prop[7]) ? prop[7] : ASPx.GridSortOrder.None;
22039  this.id = this.name;
22040 }
22041});
22042var GridLayoutHelper = ASPx.CreateClass(null, { 
22043 constructor: function(grid) {
22044  this.grid = grid;
22045 },
22046 GetDataItemVisibleIndices: function(includeDeleted) { return this.grid.GetDataItemVisibleIndices(includeDeleted); },
22047 Invalidate: function() { 
22048 },
22049});
22050var GridViewDragHelper = ASPx.CreateClass(ASPx.GridDragHelperBase, {
22051 constructor: function(grid) {
22052  this.grid = grid;
22053  this.targets = null;
22054  this.constructor.prototype.constructor.call(this);
22055 },
22056 CreateDrag: function(e, element, canDrag) {
22057  var drag = new ASPx.DragHelper(e, element, true);
22058  drag.centerClone = true;
22059  drag.canDrag = canDrag;  
22060  drag.grid = this.grid;
22061  drag.ctrl = e.ctrlKey;
22062  drag.shift = e.shiftKey;
22063  drag.onDragDivCreating = this.OnDragDivCreating;
22064  drag.onDoClick = this.OnDoClick;
22065  drag.onCloneCreating = this.OnCloneCreating;
22066  drag.onEndDrag = this.OnEndDrag;
22067  drag.onCancelDrag = this.OnCancelDrag;
22068  this.OnDragCreated(true);
22069  return drag;
22070 },
22071 GetActiveTargets: function() { 
22072  if(this.targets && this.targets.list)
22073   return this.targets.list;
22074  return [ ];
22075 },
22076 GetScrollHelper: function() { return this.grid.GetScrollHelper(); },
22077 GetCustomizationWindowElement: function() { return this.grid.GetCustomizationWindowElement(); },
22078 GetHeaderLeaf: function(columnIndex, isLeft){ return this.grid.GetHeaderMatrix().GetLeaf(columnIndex, isLeft, false); },
22079 GetHeaderLevel: function(columnIndex){ return this.grid.GetHeaderMatrix().GetColumnLevel(columnIndex); },
22080 NeedScrollOnDrag: function(isHorzDrag) { 
22081  var hasFixedColumns = this.grid.GetFixedColumnsHelper && this.grid.GetFixedColumnsHelper();
22082  return ASPx.GridDragHelperBase.prototype.NeedScrollOnDrag.call(this, isHorzDrag) || hasFixedColumns; 
22083 },
22084 PrepareTargetHeightFunc: function() {
22085  GridViewDragHelper.Target_GetElementHeight = null;
22086  if(this.grid.allowChangeColumnHierarchy)
22087   return;
22088  var headerRowCount = this.grid.GetHeaderMatrix().GetRowCount();
22089  if(headerRowCount > 0) {
22090   var row = this.grid.GetHeaderRow(headerRowCount - 1);
22091   var headerBottom = ASPx.GetAbsoluteY(row) + row.offsetHeight;
22092   GridViewDragHelper.Target_GetElementHeight = function() {
22093    return headerBottom - this.absoluteY;
22094   };
22095  }
22096 },
22097 CreateTargets: function(drag, e) {
22098  if(!drag.canDrag) return;
22099  var grid = this.grid;
22100  this.PrepareTargetHeightFunc();
22101  var targets = new ASPx.CursorTargets(grid);
22102  targets.obj = drag.obj;
22103  targets.onTargetCreated = this.OnTargetCreated;
22104  targets.onTargetChanging = this.OnTargetChanging;
22105  targets.onTargetChanged = this.OnTargetChanged;
22106  targets.onTargetAllowed = this.OnHeaderTargetAllowed.aspxBind(this);
22107  this.targets = targets;
22108  var scrollLeft = null, scrollRight;
22109  var scrollHelper = grid.GetScrollHelper();
22110  var scrollableControl = scrollHelper && scrollHelper.GetHorzScrollableControl();
22111  if(scrollableControl) {
22112   scrollLeft = ASPx.GetAbsoluteX(scrollableControl);
22113   scrollRight = scrollLeft + scrollableControl.offsetWidth;
22114  }
22115  var sourceColumn = grid.getColumnObject(drag.obj.id);
22116  var win = grid.GetCustomizationWindow();
22117  if(win && !sourceColumn.inCustWindow)
22118   this.AddDragDropTarget(targets, win.GetWindowClientTable(-1));
22119  for(var i = 0; i < grid.columns.length; i++) {
22120   var column = grid.columns[i];
22121   for(var grouped = 0; grouped <= 1; grouped++) {
22122    var targetElement = grid.GetHeader(column.index, !!grouped);
22123    if(!targetElement)
22124     continue;
22125    if(this.IsValidColumnDragDropTarget(drag.obj, targetElement, sourceColumn, column))
22126     this.AddDragDropTarget(targets, targetElement);  
22127   }
22128  }
22129  this.AddAdaptivePanelTarget(targets, grid.GetAdaptiveHeaderPanel());
22130  this.AddAdaptivePanelTarget(targets, grid.GetAdaptiveGroupPanel());
22131  this.AddDragDropTarget(targets, grid.GetGroupPanel());
22132  this.AddDragDropTarget(targets, ASPx.GetElementById(grid.name + this.grid.EmptyHeaderSuffix));
22133 },
22134 IsValidColumnDragDropTarget: function(sourceElement, targetElement, sourceColumn, targetColumn) {
22135  if(sourceColumn == targetColumn)
22136   return false;
22137  if(this.grid.allowChangeColumnHierarchy)
22138   return true;
22139  if(sourceColumn.parentIndex == targetColumn.parentIndex)
22140   return true;
22141  if(sourceColumn.parentIndex == targetColumn.index) {
22142   return (sourceColumn.inCustWindow || this.IsGroupingTarget(sourceElement))
22143    && this.grid.GetHeaderMatrix().IsLeaf(targetColumn.index);
22144  }
22145  if(this.IsParentColumn(sourceColumn.index, targetColumn.index))
22146   return (sourceColumn.inCustWindow || this.IsGroupingTarget(sourceElement));
22147  if(this.IsGroupingTarget(targetElement))
22148   return true;
22149  if(this.IsValidAdaptiveTarget(sourceElement, targetElement, sourceColumn, targetColumn))
22150   return true;
22151  return false;
22152 },
22153 AddAdaptivePanelTarget: function(targets, panel) {
22154  if(!panel) return;
22155  this.AppendAdaptivePanelDragAreas(targets, panel);
22156  this.AddDragDropTarget(targets, panel);
22157 },
22158 AppendAdaptivePanelDragAreas: function(targets, panel) {
22159  panel.dragAreas = [ ];
22160  var headers = this.GetAdaptivePanelHeaders(panel);
22161  if(headers.length === 0) 
22162   return;
22163  var rows = [ ];
22164  var row = [ headers[0] ];
22165  rows.push(row);
22166  for(var i = 0; i < headers.length - 1; i++) {
22167   var currentHeader = headers[i];
22168   var nextHeader = headers[i + 1];
22169   if(ASPx.GetAbsoluteY(currentHeader) !== ASPx.GetAbsoluteY(nextHeader)) {
22170    row = [ ];
22171    rows.push(row);
22172   }
22173   row.push(nextHeader);
22174  }
22175  for(var i = 0; i < rows.length; i++) {
22176   var row = rows[i];
22177   this.CreateDragArea(panel, row[0], targets, true);
22178   this.CreateDragArea(panel, row[row.length - 1], targets,  false);
22179  }
22180 },
22181 GetAdaptivePanelHeaders: function(panel) {
22182  return ASPx.GetNodesByPartialClassName(panel, ASPx.GridViewConsts.HeaderCellCssClass);
22183 },
22184 CreateDragArea: function(panel, target, targets, isLeft) {
22185  if(!this.ContainsTarget(targets, target)) 
22186   return; 
22187  var targetTop = ASPx.GetAbsolutePositionY(target);
22188  var area = { 
22189   target: target,
22190   isLeft: isLeft,
22191   top: targetTop,
22192   bottom: targetTop + target.offsetHeight,
22193   left: isLeft ? ASPx.GetAbsolutePositionX(panel) : ASPx.GetAbsolutePositionX(target) + target.offsetWidth,
22194   right: isLeft ? ASPx.GetAbsolutePositionX(target) :  ASPx.GetAbsolutePositionX(panel) + panel.offsetWidth
22195  };
22196  panel.dragAreas.push(area);
22197 },
22198 ContainsTarget: function(targets, target) {
22199  for(var i = 0; i < targets.list.length; i++) {
22200   if(targets.list[i].element == target)
22201    return true;
22202  }
22203  return false;
22204 },
22205 IsValidAdaptiveTarget: function(sourceElement, targetElement, sourceColumn, targetColumn) {
22206  this.EnsureAdaptiveTargetInfo(sourceElement, targetElement, sourceColumn, targetColumn);
22207  return !!targetElement.adaptiveInfo;
22208 },
22209 EnsureAdaptiveTargetInfo: function(sourceElement, targetElement, sourceColumn, targetColumn) {
22210  if(!this.IsAdaptiveHeaderTarget(targetElement))
22211   return;
22212  var sourceLevel = this.GetHeaderLevel(sourceColumn.index);
22213  var targetLevel = this.GetHeaderLevel(targetColumn.index);
22214  targetElement.adaptiveInfo = null;
22215  if(targetLevel < 0 || sourceLevel >= targetLevel)
22216   return;
22217  var brother = this.FindColumnBrother(sourceColumn, targetColumn);
22218  if(!brother) 
22219   return;
22220  var leftLeaf = this.GetHeaderLeaf(brother.index, true);
22221  var rightLeaf = this.GetHeaderLeaf(brother.index, false);  
22222  if(targetColumn.index === leftLeaf || targetColumn.index === rightLeaf)
22223   targetElement.adaptiveInfo = { brotherIndex : brother.index, brotherHasOnlyOneLeaf: leftLeaf == rightLeaf, isLeftLeaf: targetColumn.index == leftLeaf };
22224 },
22225 FindColumnBrother: function(sourceColumn, targetColumn) {
22226  while(targetColumn && targetColumn.parentIndex !== sourceColumn.parentIndex)
22227   targetColumn = this.grid.GetColumn(targetColumn.parentIndex);
22228  return targetColumn;
22229 },
22230 AddDragDropTarget: function(targets, element) {
22231  if(element)
22232   targets.addElement(element);
22233 },
22234 IsAdaptiveHeaderPanelVisible: function() { return ASPx.IsElementDisplayed(this.grid.GetAdaptiveHeaderPanel()); },
22235 IsAdaptiveGroupPanelVisible: function() { return ASPx.IsElementDisplayed(this.grid.GetAdaptiveGroupPanel()); },
22236 IsDataHeaderTarget: function(element) { return element && element.i
22236d.indexOf(this.grid.name + "_col") == 0; },
22237 IsAdaptiveHeaderTarget: function(element) { return this.IsAdaptiveHeaderPanelVisible() && this.IsDataHeaderTarget(element) && element.adaptiveMoved; },
22238 IsAdaptivePanelTarget: function(element) { return element && (element == this.grid.GetAdaptiveHeaderPanel() || element == this.grid.GetAdaptiveGroupPanel()); },
22239 IsAdaptiveGroupHeaderTarget: function(element) { return this.IsAdaptiveGroupPanelVisible() && this.IsGroupHeaderTarget(element) && element.adaptiveMoved; },
22240 IsGroupHeaderTarget: function(element) {
22241  if(!element || !element.id)
22242   return false;
22243  return element.id.indexOf(this.grid.name + "_groupcol") == 0;
22244 },
22245 IsGroupingTarget: function(element) { 
22246  return element == this.grid.GetGroupPanel() || this.IsGroupHeaderTarget(element) || element ==  this.grid.GetAdaptiveGroupPanel();
22247 },
22248 IsCustWindowTarget: function(element) {
22249  var win = this.grid.GetCustomizationWindow();
22250  return win && element == win.GetWindowClientTable(-1); 
22251 },
22252 AllowVerticalTargetTags: function(element){
22253  return this.grid.allowChangeColumnHierarchy && !this.IsGroupingTarget(element) && !this.IsCustWindowTarget(element);
22254 },
22255 OnDragDivCreating: function(drag, dragDiv) {
22256  var rootTable = drag.grid.GetMainElement();
22257  if(!dragDiv || !rootTable) return;
22258  dragDiv.className = rootTable.className;
22259  dragDiv.style.cssText = rootTable.style.cssText;
22260 },
22261 OnDoClick: function(drag) {
22262  window.setTimeout(function() {
22263   var grid = drag.grid;
22264   var contextMenuHelper = grid.GetContextMenuHelper && grid.GetContextMenuHelper(); 
22265   if(contextMenuHelper && contextMenuHelper.contextMenuActivating) {
22266    contextMenuHelper.contextMenuActivating = false;
22267    return;
22268   }
22269   if(!grid.canSortByColumn(drag.obj) || grid.InRegularCallback()) 
22270    return;
22271   grid.SortBy(grid.getColumnIndex(drag.obj.id), drag.ctrl ? "NONE" : "", !drag.shift && !drag.ctrl);
22272  }, 0);
22273 },
22274 OnCancelDrag: function(drag) {
22275  drag.grid.dragHelper.DisplayTargetImages(false);
22276  drag.grid.dragHelper.CancelDrag();
22277 },
22278 OnEndDrag: function(drag) {
22279  if(!drag.targetElement)
22280   return;
22281  var grid = drag.grid;
22282  var sourceElement = drag.obj;
22283  var targetElement = drag.targetElement;
22284  var sourceIndex = grid.getColumnIndex(sourceElement.id);
22285  var targetIndex =  grid.getColumnIndex(targetElement.id);
22286  var direction = drag.targetTag;
22287  if(grid.IsEmptyHeaderID(targetElement.id) || targetElement == grid.GetAdaptiveHeaderPanel())
22288   targetIndex = 0;
22289  if(grid.dragHelper.IsAdaptiveHeaderTarget(targetElement) && targetElement.adaptiveInfo) {
22290   targetIndex = targetElement.adaptiveInfo.brotherIndex;
22291   var isLeft = !targetElement.adaptiveInfo.brotherHasOnlyOneLeaf ? targetElement.adaptiveInfo.isLeftLeaf : isLeft;
22292   direction = isLeft ? ASPx.CursorTargetTag.Left : ASPx.CursorTargetTag.Right;
22293  }
22294  if(grid.rtl && direction < 2)
22295   direction = direction == ASPx.CursorTargetTag.Left ? ASPx.CursorTargetTag.Right : ASPx.CursorTargetTag.Left;
22296  grid.MoveColumn(
22297   sourceIndex,
22298   targetIndex,
22299   direction,
22300   grid.dragHelper.IsGroupingTarget(targetElement),
22301   grid.dragHelper.IsGroupingTarget(sourceElement)
22302  );
22303 },
22304 OnCloneCreating: function(clone) {
22305  var table = document.createElement("table");
22306  table.cellSpacing = 0;
22307  if(this.obj.offsetWidth > 0)
22308   table.style.width = Math.min(200, this.obj.offsetWidth) + "px";
22309  if(this.obj.offsetHeight > 0)
22310   table.style.height = this.obj.offsetHeight + "px";
22311  var row = table.insertRow(-1);
22312  clone.style.borderLeftWidth = "";
22313  clone.style.borderTopWidth = "";
22314  clone.style.borderRightWidth = "";
22315  row.appendChild(clone);
22316  table.style.opacity = 0.80;
22317  table.style.filter = "alpha(opacity=80)"; 
22318  if(ASPx.IsElementRightToLeft(this.obj))
22319   table.dir = "rtl";
22320  return table;
22321 },
22322 OnTargetCreated: function(targets, targetObj) {
22323  var f = GridViewDragHelper.Target_GetElementHeight;
22324  var h = targets.control.dragHelper;
22325  var el = targetObj.element;
22326  if(f && !h.IsCustWindowTarget(el) && !h.IsGroupingTarget(el) && !h.IsAdaptiveHeaderTarget(el) && !h.IsAdaptivePanelTarget(el))
22327   targetObj.GetElementHeight = f;
22328 },
22329 OnTargetChanging: function(targets) {
22330  if(!targets.targetElement)
22331   return;
22332  var grid = targets.control;
22333  var allowVerticalTags = grid.dragHelper.AllowVerticalTargetTags(targets.targetElement);
22334  targets.refreshTargetTag(allowVerticalTags);
22335  if(allowVerticalTags)
22336   grid.dragHelper.CorrectTargetTagOnMovingColumnFromCustWindow(targets);
22337  var grouping = false;
22338  if(targets.targetElement == grid.GetGroupPanel() || targets.targetElement == grid.GetAdaptiveGroupPanel()) {
22339   targets.targetTag = ASPx.CursorTargetTag.Left;
22340   grouping = true;
22341  }  
22342  if(grid.dragHelper.IsGroupHeaderTarget(targets.targetElement)) {
22343   grouping = true;
22344  }
22345  var column = grid.getColumnObject(targets.obj.id);
22346  if(grouping && !grid.canGroupByColumn(column))
22347   targets.targetElement = null;
22348  if(targets.targetElement == grid.GetCustomizationWindowElement() && !grid.canHideColumn(column))
22349   targets.targetElement = null;
22350  if(grid.dragHelper.IsAdaptivePanelTarget(targets.targetElement)) {
22351   var info = grid.dragHelper.GetAdaptivePanelTargetInfo(targets, targets.targetElement);
22352   targets.targetTag = info.isLeftSide ? ASPx.CursorTargetTag.Left : ASPx.CursorTargetTag.Right;
22353   targets.targetElement = info.targetElement;
22354   targets.skipNeighbor = true;
22355  }
22356  if(targets.targetElement)
22357   grid.RaiseColumnMoving(targets);
22358 },
22359 CorrectTargetTagOnMovingColumnFromCustWindow: function(targets){
22360  if(!ASPx.currentDragHelper || !ASPx.currentDragHelper.obj || !targets.targetElement)
22361   return;
22362  var grid = targets.control;
22363  var sourceColumn = grid.getColumnObject(ASPx.currentDragHelper.obj.id);
22364  if(!sourceColumn || !sourceColumn.inCustWindow || !grid.GetColumnHelper().HasColumnChildren(sourceColumn.index))
22365   return;
22366  var sourceColumn = grid.getColumnObject(ASPx.currentDragHelper.obj.id);
22367  var targetColumn = grid.getColumnObject(targets.targetElement.id);
22368  if(targets.targetTag == ASPx.CursorTargetTag.Top || targets.targetTag == ASPx.CursorTargetTag.Bottom && grid.GetColumnHelper().HasColumnChildren(targetColumn.index))
22369   targets.refreshTargetTag(false);
22370 },
22371 GetAdaptivePanelTargetInfo: function(targets, panel) {
22372  var x = targets.x;
22373  var y = targets.y;
22374  for(var i = 0; i < panel.dragAreas.length; i++) {
22375   var dragArea = panel.dragAreas[i];
22376   if(x >= dragArea.left && x <= dragArea.right && y >= dragArea.top && y <= dragArea.bottom)
22377    return { targetElement: dragArea.target, isLeftSide: dragArea.isLeft };
22378  }
22379  return { targetElement: panel.children.length == 0 ? panel : null, isLeftSide: true };
22380 },
22381 OnTargetChanged: function(targets) {
22382  if(ASPx.currentDragHelper == null)
22383   return;
22384  var element = targets.targetElement;
22385  if(element == ASPx.currentDragHelper.obj)
22386   return;
22387  var grid = targets.control;
22388  grid.dragHelper.DisplayTargetImages(false);
22389  if(!element) {
22390   ASPx.currentDragHelper.targetElement = null;
22391   return;
22392  }
22393  ASPx.currentDragHelper.targetElement = element;
22394  ASPx.currentDragHelper.targetTag = targets.targetTag;
22395  var moveToCustWindow = grid.dragHelper.IsCustWindowTarget(element);
22396  if(moveToCustWindow) {
22397   ASPx.currentDragHelper.addElementToDragDiv(grid.GetArrowDragFieldImage());
22398   return;
22399  }
22400  var moveToGroup = grid.dragHelper.IsGroupingTarget(element);
22401  var info = grid.dragHelper.CreateTargetImagesInfo(targets, moveToGroup);
22402  if(!info) {
22403   ASPx.currentDragHelper.targetElement = null;
22404   return;
22405  }
22406  if(targets.skipNeighbor)
22407   info.neighbor = null;
22408  var position = grid.dragHelper.CreateTargetImagesPosition(element, info);
22409  grid.dragHelper.DisplayTargetImages(true, position);
22410 },
22411 CreateTargetImagesPosition: function(targetElement, info){
22412  if(info.side == ASPx.CursorTargetTag.Top || info.side == ASPx.CursorTargetTag.Bottom)
22413   return this.CreateVerticalTargetImagesPosition(targetElement, info);
22414  return this.CreateHorizontalTargetImagesPosition(targetElement, info);
22415 },
22416 CreateHorizontalTargetImagesPosition: function(targetElement, info){
22417  var left = ASPx.GetAbsoluteX(targetElement);
22418  var isRightSide = info.side == ASPx.CursorTargetTag.Right;
22419  if(targetElement == this.grid.GetGroupPanel() || targetElement == this.grid.GetAdaptiveHeaderPanel() || targetElement == this.grid.GetAdaptiveGroupPanel()) {
22420   if(this.grid.rtl)
22421    left += targetElement.offsetWidth;
22422  } else {
22423   if(isRightSide) {
22424    if(info.neighbor)
22425     left = ASPx.GetAbsoluteX(info.neighbor);
22426    else
22427     left += targetElement.offsetWidth;
22428   }
22429  }
22430  var top = ASPx.GetAbsoluteY(targetElement);
22431  var bottomElement = targetElement;
22432  var moveToGroup = this.IsGroupingTarget(targetElement);
22433  if(!moveToGroup && info.targetColumnIndex > -1)
22434   bottomElement = this.grid.GetHeader(this.GetHeaderLeaf(info.targetColumnIndex, !isRightSide));
22435  var bottom = ASPx.GetAbsoluteY(bottomElement) + bottomElement.offsetHeight;
22436  return { top: top, bottom: bottom, left: left, right: left };
22437 },
22438 CreateVerticalTargetImagesPosition: function(targetElement, info){
22439  var left = ASPx.GetAbsoluteX(targetElement);
22440  var right = left + targetElement.offsetWidth;
22441  var top = ASPx.GetAbsoluteY(targetElement);
22442  if(info.side == ASPx.CursorTargetTag.Bottom)
22443   top += targetElement.offsetHeight;
22444  return { top: top, bottom: top, left: left, right: right };
22445 },
22446 GetChildHeaderElement: function(parentIndex, childIndex, left){
22447  var grid = this.grid;
22448  var childColumnIndex = childIndex;
22449  var currentColumnIndex = childIndex;
22450  var getNextNeighborHeaderMatrixMethodName = "Get" + (left ? "Left" : "Right") + "Neighbor";
22451  while(ASPx.IsExists(currentColumnIndex) && this.IsParentColumn(parentIndex, currentColumnIndex)){
22452   childColumnIndex = currentColumnIndex; 
22453   currentColumnIndex = grid.GetHeaderMatrix()[getNextNeighborHeaderMatrixMethodName](childColumnIndex);
22454  }
22455  return grid.GetHeader(childColumnIndex);
22456 },
22457 IsParentColumn: function(parentIndex, columnIndex){
22458  var index = columnIndex;
22459  while(index >= 0 && index != parentIndex)
22460   index = this.grid.GetColumn(index).parentIndex;
22461  return index >= 0;
22462 },
22463 CreateTargetImagesInfo: function(targets, moveToGroup){
22464  if(moveToGroup)
22465   return this.CreateGroupPanelTargetImagesInfo(targets);
22466  var grid = targets.control;
22467  var targetElement = targets.targetElement;
22468  var info = {
22469   targetColumnIndex: grid.getColumnIndex(targetElement.id),
22470   side: targets.targetTag,
22471   neighbor: null
22472  };
22473  var isAdaptiveHeader = grid.dragHelper.IsAdaptiveHeaderTarget(targetElement);
22474  if(!isAdaptiveHeader && info.targetColumnIndex < 0)
22475   return info;
22476  if(isAdaptiveHeader && targetElement.adaptiveInfo) {
22477   info.targetColumnIndex = targetElement.adaptiveInfo.brotherIndex;
22478   if(!targetElement.adaptiveInfo.brotherHasOnlyOneLeaf)
22479    info.side = targetElement.adaptiveInfo.isLeftLeaf ? ASPx.CursorTargetTag.Left : ASPx.CursorTargetTag.Right;
22480  }
22481  var neighborIndex = this.FindHeaderNeighborIndexByHorizontal(info.side, info.targetColumnIndex, isAdaptiveHeader);
22482  if(neighborIndex == null)
22483   info = null;
22484  else if(neighborIndex > -1)
22485   info.neighbor = grid.GetHeader(neighborIndex);
22486  return info;
22487 },
22488 CreateGroupPanelTargetImagesInfo: function(targets){
22489  var grid = targets.control;
22490  var isRightSide = targets.targetTag == ASPx.CursorTargetTag.Right;
22491  var method = isRightSide ^ grid.rtl ? "nextSibling" : "previousSibling";
22492  var neighbor = grid.dragHelper.GetGroupNodeNeighbor(targets.targetElement, method);
22493  if(neighbor && neighbor.id == ASPx.currentDragHelper.obj.id)
22494   return null;
22495  return {
22496   targetColumnIndex: grid.getColumnIndex(targets.targetElement.id),
22497   side: targets.targetTag,
22498   neighbor: neighbor
22499  };
22500 },
22501 FindHeaderNeighborIndexByHorizontal: function(side, targetColumnIndex, isAdaptiveHeader){
22502  if(side == ASPx.CursorTargetTag.Top || side == ASPx.CursorTargetTag.Bottom)
22503   return targetColumnIndex;
22504  var grid = this.grid;
22505  var isRightSide = side == ASPx.CursorTargetTag.Right;
22506  var matrix =  grid.GetHeaderMatrix();
22507  var method = isRightSide ^ grid.rtl ? "GetRightNeighbor" : "GetLeftNeighbor";
22508  var neighborIndex = matrix[method](targetColumnIndex, !isAdaptiveHeader);
22509  var sourceColumn = grid.getColumnObject(ASPx.currentDragHelper.obj.id);
22510  if(neighborIndex == sourceColumn.index && !sourceColumn.inCustWindow && !this.IsGroupHeaderTarget(ASPx.currentDragHelper.obj))
22511   return sourceColumn.parentIndex != grid.GetColumn(targetColumnIndex).parentIndex ? -1 : null;
22512  if(!isNaN(neighborIndex)){
22513   if(isAdaptiveHeader && !matrix.IsLeaf(neighborIndex))
22514    neighborIndex = matrix.GetLeaf(neighborIndex, isRightSide);
22515  } else
22516   neighborIndex = -1;
22517  return neighborIndex;
22518 },
22519 GetGroupNodeNeighbor: function(element, method) {
22520  if(this.IsAdaptiveGroupHeaderTarget(element)) 
22521   return this.GetAdaptiveGroupNodeNeighbor(element, method);
22522  return this.GetGroupNodeNeighborCore(element, method, 2);
22523 },
22524 GetAdaptiveGroupNodeNeighbor: function(element, method) {   
22525  var headers = ASPx.GetNodesByPartialClassName(this.grid.GetAdaptiveGroupPanel(), ASPx.GridViewConsts.HeaderCellCssClass);
22526  var index = ASPx.Data.ArrayIndexOf(headers, element);
22527  if(index < 0) return null;   
22528  return method == "nextSibling" ? headers[index + 1] : headers[index - 1];
22529 },
22530 GetGroupNodeNeighborCore: function(element, method, distance) {
22531  var neighbor = element[method];
22532  if(neighbor && neighbor.nodeType == 1) {
22533   if(this.IsGroupingTarget(neighbor)) 
22534    return neighbor;
22535   if(distance > 1)
22536    return this.GetGroupNodeNeighborCore(neighbor, method, --distance);
22537  }
22538  return null;
22539 },
22540 DisplayTargetImages: function(visible, position){
22541  var downImage = this.grid.GetArrowDragDownImage();
22542  if(downImage){
22543   var showImage = visible && position.left == position.right;
22544   if(showImage) {
22545    ASPx.SetAbsoluteX(downImage, position.left - downImage.offsetWidth / 2);
22546    ASPx.SetAbsoluteY(downImage, position.top - downImage.offsetHeight);
22547   }
22548   ASPx.SetElementVisibility(downImage, showImage);
22549  }
22550  var upImage = this.grid.GetArrowDragUpImage();
22551  if(upImage){
22552   var showImage = visible && position.left == position.right;
22553   if(showImage) {
22554    ASPx.SetAbsoluteX(upImage, position.left - upImage.offsetWidth / 2);
22555    ASPx.SetAbsoluteY(upImage, position.bottom);
22556   }
22557   ASPx.SetElementVisibility(upImage, showImage);
22558  }
22559  var rightImage = this.grid.GetArrowDragRightImage();
22560  if(rightImage){
22561   var showImage = visible && position.left != position.right;
22562   if(showImage) {
22563    ASPx.SetAbsoluteX(rightImage, position.left - rightImage.offsetWidth);
22564    ASPx.SetAbsoluteY(rightImage, position.top - rightImage.offsetHeight / 2);
22565   }
22566   ASPx.SetElementVisibility(rightImage, showImage);
22567  }
22568  var leftImage = this.grid.GetArrowDragLeftImage();
22569  if(leftImage){
22570   var showImage = visible && position.left != position.right;
22571   if(showImage) {
22572    ASPx.SetAbsoluteX(leftImage, position.right);
22573    ASPx.SetAbsoluteY(leftImage, position.top - rightImage.offsetHeight / 2);
22574   }
22575   ASPx.SetElementVisibility(leftImage, showImage);
22576  }
22577 }
22578});
22579GridViewDragHelper.Target_GetElementHeight = null;
22580ASPx.GridViewDragHelper = GridViewDragHelper;
22581ASPxClientGridBase.SelectStartHandler = function(e) {
22582 if(ASPx.Evt.GetEventSource(e).tagName.match(/input|select|textarea/i))
22583  return;
22584 if(e.ctrlKey || e.shiftKey) {
22585  ASPx.Selection.Clear();
22586  ASPx.Evt.PreventEventAndBubble(e);
22587 }
22588};
22589ASPxClientGridBase.SaveActiveElementSettings = function(grid) {
22590 var element = grid.GetFilterHelper().GetActiveElement();
22591 grid.GetFilterHelper().ResetActiveElement();
22592 ASPxClientGridBase.activeElementData = null;
22593 if (!element || !element.id || element.tagName != "INPUT" || !(ASPx.GetIsParent(grid.GetMainElement(), element) || element.id.indexOf(grid.name + "_") == 0))
22594  return;  
22595 ASPxClientGridBase.activeElementData = [ grid.name, element.id, ASPx.Selection.GetInfo(element).endPos ];
22596 if(typeof(Sys) != "undefined" && typeof(Sys.Application) != "undefined") {
22597  if(!ASPxClientGridBase.MsAjaxActiveElementHandlerAdded) {
22598   Sys.Application.add_load(function() { ASPxClientGridBase.RestoreActiveElementSettings(); } );
22599   ASPxClientGridBase.MsAjaxActiveElementHandlerAdded = true;
22600  }
22601 } 
22602};
22603ASPxClientGridBase.RestoreActiveElementSettings = function(grid) {
22604 var data = ASPxClientGridBase.activeElementData;
22605 if(!data || grid && data[0] != grid.name) return;
22606 var element = ASPx.GetElementById(data[1]);
22607 if(element) {
22608  window.setTimeout(function() {
22609   element.focus();
22610   ASPx.Selection.Set(element, data[2], data[2]);
22611  }, 0);
22612 }
22613 ASPxClientGridBase.activeElementData = null;
22614};
22615var ASPxClientGridViewCallbackCommand = {
22616 NextPage: "NEXTPAGE",
22617 PreviousPage: "PREVPAGE",
22618 GotoPage: "GOTOPAGE",
22619 SelectRows: "SELECTROWS",
22620 SelectRowsKey: "SELECTROWSKEY",
22621 Selection: "SELECTION",
22622 FocusedRow: "FOCUSEDROW",
22623 Group: "GROUP",
22624 UnGroup: "UNGROUP",
22625 Sort: "SORT",
22626 ColumnMove: "COLUMNMOVE",
22627 CollapseAll: "COLLAPSEALL",
22628 ExpandAll: "EXPANDALL",
22629 ExpandRow: "EXPANDROW",
22630 CollapseRow: "COLLAPSEROW",
22631 HideAllDetail: "HIDEALLDETAIL",
22632 ShowAllDetail: "SHOWALLDETAIL",
22633 ShowDetailRow: "SHOWDETAILROW",
22634 HideDetailRow: "HIDEDETAILROW",
22635 PagerOnClick: "PAGERONCLICK",
22636 ApplyFilter: "APPLYFILTER",
22637 ApplyColumnFilter: "APPLYCOLUMNFILTER",
22638 ApplyMultiColumnFilter: "APPLYMULTICOLUMNFILTER",
22639 ApplyHeaderColumnFilter: "APPLYHEADERCOLUMNFILTER",
22640 ApplySearchPanelFilter: "APPLYSEARCHPANELFILTER",
22641 ApplyCustomizationDialogChanges: "APPLYCUSTOMIZATIONDIALOGCHANGES",
22642 FilterRowMenu: "FILTERROWMENU",
22643 StartEdit: "STARTEDIT",
22644 CancelEdit: "CANCELEDIT",
22645 UpdateEdit: "UPDATEEDIT",
22646 UpdateSummaries: "UPDATESUMMARIES",
22647 AddNewRow: "ADDNEWROW",
22648 DeleteRow: "DELETEROW",
22649 CustomButton: "CUSTOMBUTTON",
22650 CustomCallback: "CUSTOMCALLBACK",
22651 ShowFilterControl: "SHOWFILTERCONTROL",
22652 CloseFilterControl: "CLOSEFILTERCONTROL",
22653 SetFilterEnabled: "SETFILTERENABLED",
22654 Refresh: "REFRESH",
22655 SelFieldValues: "SELFIELDVALUES",
22656 RowValues: "ROWVALUES",
22657 PageRowValues: "PAGEROWVALUES",
22658 FilterPopup: "FILTERPOPUP",
22659 ContextMenu: "CONTEXTMENU",
22660 Toolbar: "TOOLBAR",
22661 Export: "EXPORT",
22662 CustomValues: "CUSTOMVALUES"
22663};
22664var ASPxClientGridExportFormat = {
22665 Pdf: "Pdf",
22666 Docx: "Docx",
22667 Rtf: "Rtf",
22668 Csv: "Csv",
22669 Xls: "Xls",
22670 Xlsx: "Xlsx"
22671};
22672var ASPxClientGridBatchEditStartEditingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22673 constructor: function(visibleIndex, focusedColumn, itemValues) {
22674  this.constructor.prototype.constructor.call(this);
22675  this.visibleIndex = visibleIndex;
22676  this.focusedColumn = focusedColumn;
22677  this.itemValues = ASPx.CloneObject(itemValues);
22678 }
22679});
22680var ASPxClientGridBatchEditEndEditingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22681 constructor: function(visibleIndex, focusedColumn, itemValues) {
22682  this.constructor.prototype.constructor.call(this);
22683  this.visibleIndex = visibleIndex;
22684  this.focusedColumn = focusedColumn;
22685  this.itemValues = ASPx.CloneObject(itemValues);
22686 }
22687});
22688var ASPxClientGridBatchEditItemChangesCancelingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22689 constructor: function(visibleIndex, itemValues) {
22690  this.constructor.prototype.constructor.call(this);
22691  this.visibleIndex = visibleIndex;
22692  this.itemValues = ASPx.CloneObject(itemValues);
22693 }
22694});
22695var ASPxClientGridBatchEditItemValidatingEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
22696 constructor: function(visibleIndex, validationInfo) {
22697  this.constructor.prototype.constructor.call(this);
22698  this.visibleIndex = visibleIndex;
22699  this.validationInfo = ASPx.CloneObject(validationInfo);
22700 }
22701});
22702var ASPxClientGridBatchEditConfirmShowingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22703 constructor: function(requestTriggerID) {
22704  this.constructor.prototype.constructor.call(this);
22705  this.requestTriggerID = requestTriggerID;
22706 }
22707});
22708var ASPxClientGridBatchEditTemplateCellFocusedEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
22709 constructor: function(column) {
22710  this.constructor.prototype.constructor.call(this);
22711  this.column = column;
22712  this.handled = false;
22713 }
22714});
22715var ASPxClientGridBatchEditClientChangesEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22716 constructor: function(insertedValues, deletedValues, updatedValues) {
22717  this.constructor.prototype.constructor.call(this);
22718  this.insertedValues = insertedValues;
22719  this.deletedValues = deletedValues;
22720  this.updatedValues = updatedValues;
22721 }
22722});
22723var ASPxClientGridBatchEditItemInsertingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22724 constructor: function(visibleIndex) {
22725  this.constructor.prototype.constructor.call(this);
22726  this.visibleIndex = visibleIndex;
22727 }
22728});
22729var ASPxClientGridBatchEditItemDeletingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22730 constructor: function(visibleIndex, itemValues) {
22731  this.constructor.prototype.constructor.call(this);
22732  this.visibleIndex = visibleIndex;
22733  this.itemValues = itemValues;
22734 }
22735});
22736var ASPxClientGridClipboardCellPastingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22737 constructor: function(cellInfo, oldValueInfo, newValueInfo) {
22738  this.constructor.prototype.constructor.call(this);
22739  this.cellInfo = cellInfo;
22740  this.oldText = oldValueInfo.text;
22741  this.oldValue = oldValueInfo.value;
22742  this.newText = newValueInfo.text;
22743  this.newValue = newValueInfo.value;
22744 }
22745});
22746var ASPxClientGridCellSelectionChangingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22747 constructor: function(cellInfo, newSelectionState) {
22748  this.constructor.prototype.constructor.call(this);
22749  this.cellInfo = cellInfo;
22750  this.newSelectionState = newSelectionState;
22751 }
22752});
22753var ASPxClientGridSelectionState = {
22754 Unselected: 0,
22755 Selected: 1
22756};
22757var ASPxClientGridFocusedCellChangingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
22758 constructor: function(cellInfo) {
22759  this.constructor.prototype.constructor.call(this);
22760  this.cellInfo = cellInfo;
22761 }
22762});
22763var ASPxClientGridBatchEditApi = ASPx.CreateClass(ASPx.BatchEditApi, {
22764 constructor: function(owner) {
22765  this.constructor.prototype.constructor.call(this, owner);
22766  this.grid = owner;
22767 },
22768 GetColumnIndex: function(column) { return this.grid._getColumnIndexByColumnArgs(column); },
22769 ConvertVisibleIndexToKey: function(visibleIndex) { return this.grid.ConvertVisibleIndexToKey(visibleIndex); },
22770 ConvertKeyToVisibleIndex: function(key) { return this.grid.ConvertKeyToVisibleIndex(key); },
22771 CreateControlCellInfo: function(key, column) {
22772  var visibleIndex = this.grid.ConvertKeyToVisibleIndex(key);
22773  return this.grid.CreateUserCellInfo(visibleIndex, column, key);
22774 },
22775 SetCellValue: function(visibleIndex, column, value, displayText, cancelCellHighlighting) { 
22776  return this.SetCellValueByKey(this.ConvertVisibleIndexToKey(visibleIndex), column, value, displayText, cancelCellHighlighting);
22777 },
22778 SetCellValueByKey: function(key, column, value, displayText, cancelCellHighlighting) {
22779  return this.SetCellValueCore(key, column, value, displayText, cancelCellHighlighting);
22780 },
22781 GetCellValue: function(visibleIndex, column, initial) { return this.GetCellValueByKey(this.ConvertVisibleIndexToKey(visibleIndex), column, initial); },
22782 GetCellValueByKey: function(key, column, initial) { return this.GetCellValueCore(key, column, initial); },
22783 GetCellTextContainer: function(visibleIndex, column) { return this.GetCellTextContainerByKey(this.ConvertVisibleIndexToKey(visibleIndex), column); },
22784 GetCellTextContainerByKey: function(key, column) { return this.GetCellTextContainerCore(key, column); },
22785 HasChanges: function(visibleIndex, column) { return this.HasChangesByKey(this.ConvertVisibleIndexToKey(visibleIndex), column); },
22786 HasChangesByKey: function(key, column) { return this.HasChangesCore(key, column); },
22787 ResetChanges: function(visibleIndex, columnIndex) { this.ResetChangesByKey(this.ConvertVisibleIndexToKey(visibleIndex), columnIndex); },
22788 ResetChangesByKey: function(key, columnIndex) { this.ResetChangesCore(key, columnIndex); },
22789 StartEdit: function(visibleIndex, columnIndex) { this.StartEditByKey(this.ConvertVisibleIndexToKey(visibleIndex), columnIndex); },
22790 StartEditByKey: function(key, columnIndex) { this.StartEditCore(key, columnIndex); },
22791 ValidateItem: function(visibleIndex) { return this.ValidateItemByKey(this.ConvertVisibleIndexToKey(visibleIndex)); },
22792 ValidateItemByKey: function(key) { return this.ValidateRecordCore(key); },
22793 IsDeletedItem: function(visibleIndex) { return this.IsDeletedItemByKey(this.ConvertVisibleIndexToKey(visibleIndex)); },
22794 IsDeletedItemByKey: function(key) { return this.IsDeletedRecordCore(key); },
22795 IsNewItem: function(visibleIndex) { return this.IsNewRecordCore(this.ConvertVisibleIndexToKey(visibleIndex)); },
22796 AddNewItem: function() { this.AddNewRecordCore(); }, 
22797 DeleteItem: function(visibleIndex) { this.DeleteItemByKey(this.ConvertVisibleIndexToKey(visibleIndex)); },
22798 DeleteItemByKey: function(key) { this.DeleteRecordCore(key); },
22799 RecoverItem: function(visibleIndex) { this.RecoverItemByKey(this.ConvertVisibleIndexToKey(visibleIndex)); },
22800 RecoverItemByKey: function(key) { this.RecoverRecordCore(key); },
22801 GetItemVisibleIndices: function(includeDeleted) { 
22802  var currentPageKeys = this.FilterCurrentPageKeys(this.GetRecordKeys(includeDeleted));
22803  return currentPageKeys.map(function(key) { return this.ConvertKeyToVisibleIndex(key); }.bind(this)); 
22804 },
22805 GetInsertedItemVisibleIndices: function() { return this.FilterCurrentPageKeys(this.GetInsertedRecordKeys()); },
22806 GetDeletedItemVisibleIndices: function() {
22807  var deletedIndices = [];
22808  var currentPageDeletedKeys = this.FilterCurrentPageKeys(this.GetDeletedRecordKeys());
22809  ASPx.Data.ForEach(currentPageDeletedKeys, function(key){  
22810   var visibleIndex = this.ConvertKeyToVisibleIndex(key);
22811   if(visibleIndex > -1) deletedIndices.push(visibleIndex);
22812  }.aspxBind(this));
22813  return deletedIndices;
22814 },
22815 GetUpdatedItemVisibleIndices: function() { 
22816  var keys = this.FilterCurrentPageKeys(this.GetUpdatedRecordKeys());
22817  return keys.map(function(key) { return this.ConvertKeyToVisibleIndex(key); }.bind(this));
22818 },
22819 IsCurrentPageRecord: function(key) {
22820  var helper = this.GetHelper();
22821  return !!helper && helper.IsCurrentPageRecord(key);
22822 },
22823 FilterCurrentPageKeys: function(keys) { return keys.filter(function (key) { return this.IsCurrentPageRecord(key); }.bind(this)); },
22824 GetTotalSummaryValue: function(summary) {
22825  var helper = this.GetHelper();
22826  if(!helper)
22827   return null;
22828  var summaryItemIndex = summary;
22829  if(typeof(summary) == "string")
22830   summaryItemIndex = helper.GetTotalSummaryByFieldName(summary);
22831  return helper.GetTotalSummaryValue(summaryItemIndex);
22832 },
22833 GetGroupSummaryValue: function(groupRowVisibleIndex, summary) {
22834  var helper = this.GetHelper();
22835  if(!helper)
22836   return null;
22837  var summaryItemIndex = summary;
22838  if(typeof(summary) == "string")
22839   summaryItemIndex = helper.GetGroupSummaryByFieldName(summary);
22840  return helper.GetGroupSummaryValue(groupRowVisibleIndex, summaryItemIndex);
22841 }
22842});
22843var ASPxClientGridCellInfo = ASPx.CreateClass(null, {
22844 constructor: function(itemIndex, column) {
22845  this.itemVisibleIndex = itemIndex;
22846  this.column = column;
22847 }
22848});
22849var ASPxClientGridToolbarItemClickEventArgs = ASPx.CreateClass(ASPxClientProcessingModeEventArgs, {
22850 constructor: function(toolbarIndex, toolbarName, item, processOnServer) {
22851  this.constructor.prototype.constructor.call(this, processOnServer);
22852  this.toolbarIndex = toolbarIndex;
22853  this.toolbarName = toolbarName;
22854  this.item = item;
22855  this.usePostBack = false;
22856  this.handled = false;
22857 }
22858});
22859var ASPxClientGridBatchEditSummaryDisplayTextEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
22860 constructor: function(summaryInfo, text, groupRowVisibleIndex) {
22861  this.constructor.prototype.constructor.call(this);
22862  this.isGroupSummary = summaryInfo.isGroupSummary;
22863  this.isTotalSummary = !summaryInfo.isGroupSummary;
22864  this.summaryItemIndex = summaryInfo.summaryIndex;
22865  this.summaryType = summaryInfo.summaryType;
22866  this.summaryFieldName = summaryInfo.summaryFieldName;
22867  this.serverValue = summaryInfo.serverValue;
22868  this.value = summaryInfo.value;
22869  this.summaryElement = summaryInfo.summaryElement;
22870  this.displayText = text;
22871  this.groupRowVisibleIndex = groupRowVisibleIndex;
22872 }
22873});
22874var ASPxClientGridKeyboardEventArgs = ASPx.CreateClass(ASPx.ASPxClientGridKeyboardEventArgsBase, { });
22875var ASPxClientSummaryItemType = {
22876 Sum: 0,
22877 Min: 1,
22878 Max: 2,
22879 Count: 3,
22880 Average: 4,
22881 Custom: 5,
22882 None: 6
22883};
22884ASPxClientGridBase.PostponeInitialize = function(name, info){
22885 var grid = ASPx.GetControlCollection().Get(name);
22886 if(grid) {
22887  grid.styleInfo = info.styleInfo;
22888  grid.cButtonIDs = info.commandButtonIDs;
22889  if(grid.batchEditClientState) {
22890   grid.batchEditClientState.extraCommandButtonsInfo = info.extraCommandButtonsInfo;
22891  }
22892  grid.EnsureRowKeys();
22893  grid.UpdateItemsStyle();
22894 }
22895};
22896ASPx.GHeaderMouseDown = function(name, element, e) {
22897 var grid = ASPx.GetControlCollection().Get(name);
22898 if(grid != null) 
22899  grid.HeaderMouseDown(element, e);
22900};
22901ASPx.GSort = function(name, columnIndex) {
22902 var grid = ASPx.GetControlCollection().Get(name);
22903 if(grid != null)  
22904  grid.SortBy(columnIndex);
22905};
22906ASPx.GVPopupEditFormOnInit = function(name, popup) {
22907 var gv = ASPx.GetControlCollection().Get(name);
22908 if(gv != null)
22909  window.setTimeout(function() { gv.OnPopupEditFormInit(popup); }, 0);
22910};
22911ASPx.GVPagerOnClick = function(name, value) {
22912 var gv = ASPx.GetControlCollection().Get(name);
22913 if(gv != null) 
22914  gv.doPagerOnClick(value);
22915};
22916ASPx.GVFilterKeyPress = function(name, element, e) {
22917 var gv = ASPx.GetControlCollection().Get(name);
22918 if(gv != null) 
22919  gv.GetFilterHelper().OnColumnFilterInputKeyPress(element, e);
22920};
22921ASPx.GVFilterSpecKeyPress = function(name, element, e) {
22922 var gv = ASPx.GetControlCollection().Get(name);
22923 if(gv != null) 
22924  gv.GetFilterHelper().OnColumnFilterInputSpecKeyPress(element, e);
22925};
22926ASPx.GVFilterChanged = function(name, element) {
22927 window.setTimeout(function() {
22928  var gv = ASPx.GetControlCollection().Get(name);
22929  var el = ASPx.GetControlCollection().Get(element.name);
22930  if(gv != null && el != null) 
22931   gv.GetFilterHelper().OnColumnFilterInputChanged(el);
22932 }, 0);
22933};
22934ASPx.GVFilterUserInput = function(name, element) {
22935 var gv = ASPx.GetControlCollection().Get(name);
22936 if(gv != null)
22937  gv.GetFilterHelper().OnColumnFilterUserInput(element);
22938};
22939ASPx.GVShowParentRows = function(name, evt, element) {
22940 var gv = ASPx.GetControlCollection().Get(name);
22941 if(gv != null) {
22942  if(element)
22943   gv.OnParentRowMouseEnter(element);  
22944  else 
22945   gv.OnParentRowMouseLeave(evt);
22946 }
22947};
22948ASPx.GTableClick = function(name, evt) {
22949 var g = ASPx.GetControlCollection().Get(name);
22950 if(g != null && g.NeedProcessTableClick(evt))
22951  g.mainTableClick(evt);
22952};
22953ASPx.GVTableDblClick = function(name, evt) {
22954 var gv = ASPx.GetControlCollection().Get(name);
22955 if(gv != null && gv.NeedProcessTableClick(evt))
22956  gv.mainTableDblClick(evt);
22957};
22958ASPx.GVCustWindowCloseUp = function(name) {
22959 var gv = ASPx.GetControlCollection().Get(name);
22960 if(gv != null) {
22961  gv.RaiseCustomizationWindowCloseUp();
22962 }
22963};
22964ASPx.GVApplyFilterPopup = function(name) {
22965 var gv = ASPx.GetControlCollection().Get(name);
22966 if(gv != null)
22967  gv.ApplyHeaderFilterByColumn();
22968};
22969ASPx.GVShowFilterControl = function(name) {
22970 var gv = ASPx.GetControlCollection().Get(name);
22971 if(gv != null) {
22972  gv.ShowFilterControl();
22973 }
22974};
22975ASPx.GVCloseFilterControl = function(name) {
22976 var gv = ASPx.GetControlCollection().Get(name);
22977 if(gv != null) {
22978  gv.CloseFilterControl();
22979 }
22980};
22981ASPx.GVSetFilterEnabled = function(name, value) {
22982 var gv = ASPx.GetControlCollection().Get(name);
22983 if(gv != null) {
22984  gv.SetFilterEnabled(value);
22985 }
22986};
22987ASPx.GVApplyFilterControl = function(name) {
22988 var gv = ASPx.GetControlCollection().Get(name);
22989 if(gv != null)
22990  gv.ApplyFilterControl();
22991};
22992ASPx.GVFilterRowMenu = function(name, columnIndex, element) {
22993 var gv = ASPx.GetControlCollection().Get(name);
22994 if(gv != null)
22995  gv.GetFilterHelper().FilterRowMenuButtonClick(columnIndex, element);
22996};
22997ASPx.GVFilterRowMenuClick = function(name, e) {
22998 var gv = ASPx.GetControlCollection().Get(name);
22999 if(gv != null)
23000  gv.GetFilterHelper().FilterRowMenuItemClick(e.item);
23001};
23002ASPx.GCmdToolbarMenuItemClick = function(name, toolbar, e) {
23003 var gv = ASPx.GetControlCollection().Get(name);
23004 if(gv != null)
23005  gv.GetToolbarHelper().OnToolbarMenuItemClick(toolbar, e);
23006};
23007ASPx.GVScheduleCommand = function(name, commandArgs, postponed, event) {
23008 var gv = ASPx.GetControlCollection().Get(name);
23009 if(gv != null)
23010  gv.ScheduleUserCommand(commandArgs, postponed, ASPx.Evt.GetEventSource(event));
23011};
23012ASPx.GVHFCancelButtonClick = function(name) {
23013 var gv = ASPx.GetControlCollection().Get(name);
23014 if(gv != null)
23015  gv.GetHeaderFilterPopup().Hide();
23016};
23017ASPx.GridStyleHelper = GridStyleHelper;
23018ASPx.GridLayoutHelper = GridLayoutHelper;
23019ASPx.GridViewDragHelper = GridViewDragHelper;
23020ASPx.GridCallbackHelper = GridCallbackHelper;
23021ASPx.GridSortOrder = GridSortOrder;
23022ASPx.ASPxClientGridExportFormat = ASPxClientGridExportFormat;
23023window.ASPxClientGridBase = ASPxClientGridBase;
23024window.ASPxClientGridColumnBase = ASPxClientGridColumnBase;
23025window.ASPxClientGridViewCallbackCommand = ASPxClientGridViewCallbackCommand;
23026window.ASPxClientGridKeyboardEventArgs = ASPxClientGridKeyboardEventArgs;
23027window.ASPxClientGridBatchEditStartEditingEventArgs = ASPxClientGridBatchEditStartEditingEventArgs;
23028window.ASPxClientGridBatchEditEndEditingEventArgs = ASPxClientGridBatchEditEndEditingEventArgs;
23029window.ASPxClientGridBatchEditItemChangesCancelingEventArgs = ASPxClientGridBatchEditItemChangesCancelingEventArgs;
23030window.ASPxClientGridBatchEditItemValidatingEventArgs = ASPxClientGridBatchEditItemValidatingEventArgs;
23031window.ASPxClientGridBatchEditConfirmShowingEventArgs = ASPxClientGridBatchEditConfirmShowingEventArgs;
23032window.ASPxClientGridBatchEditTemplateCellFocusedEventArgs = ASPxClientGridBatchEditTemplateCellFocusedEventArgs;
23033window.ASPxClientGridBatchEditClientChangesEventArgs = ASPxClientGridBatchEditClientChangesEventArgs;
23034window.ASPxClientGridBatchEditItemInsertingEventArgs = ASPxClientGridBatchEditItemInsertingEventArgs;
23035window.ASPxClientGridBatchEditItemDeletingEventArgs = ASPxClientGridBatchEditItemDeletingEventArgs;
23036window.ASPxClientGridClipboardCellPastingEventArgs = ASPxClientGridClipboardCellPastingEventArgs;
23037window.ASPxClientGridCellSelectionChangingEventArgs = ASPxClientGridCellSelectionChangingEventArgs;
23038window.ASPxClientGridFocusedCellChangingEventArgs = ASPxClientGridFocusedCellChangingEventArgs;
23039window.ASPxClientGridBatchEditApi = ASPxClientGridBatchEditApi;
23040window.ASPxClientGridCellInfo = ASPxClientGridCellInfo;
23041window.ASPxClientGridColumnMovingTargetPosition = ASPxClientGridColumnMovingTargetPosition;
23042window.ASPxClientGridToolbarItemClickEventArgs = ASPxClientGridToolbarItemClickEventArgs;
23043window.ASPxClientSummaryItemType = ASPxClientSummaryItemType;
23044window.ASPxClientGridSelectionState = ASPxClientGridSelectionState;
23045})();
23046
23047(function() {
23048var CardViewToolbarCommandType = {
23049 ClearSorting: "ClearSorting",
23050 FullExpand: "FullExpand",
23051 FullCollapse: "FullCollapse",
23052 ShowHeaderPanel: "ShowHeaderPanel",
23053 ShowFilterBuilder: "ShowFilterEditor",
23054 ClearFilter: "ClearFilter",
23055 ShowSearchPanel: "ShowSearchPanel",
23056 ShowSummaryPanel: "ShowSummaryPanel",
23057 ShowCustomizationWindow: "ShowCustomizationWindow",
23058 ShowCardHeader: "ShowCardHeader",
23059 ShowCardFooter: "ShowCardFooter",
23060 New: "New",
23061 Edit: "Edit",
23062 Delete: "Delete",
23063 DeleteSelectedCardsOnPage: "DeleteSelectedCardsOnPage",
23064 Refresh: "Refresh",
23065 Update: "Update",
23066 Cancel: "Cancel",
23067 UpdateSummaries: "UpdateSummaries"
23068};
23069var CardViewToolbarHelper = ASPx.CreateClass(ASPx.GridToolbarHelper, {
23070 constructor: function(grid) {
23071  this.constructor.prototype.constructor.call(this, grid);
23072 },
23073 ProcessToolbarItemClick: function(e) {
23074  var item = e.item,
23075   command = this.GetItemCommand(item);
23076  switch(command) {
23077   case CardViewToolbarCommandType.ShowHeaderPanel:
23078    this.ToolbarShowHeaderPanel(item.GetChecked());
23079    break;
23080   case CardViewToolbarCommandType.ClearSorting:
23081    this.ToolbarClearSorting();
23082    break;
23083   case CardViewToolbarCommandType.FullExpand:
23084    this.grid.ExpandAll();
23085    break;
23086   case CardViewToolbarCommandType.FullCollapse:
23087    this.grid.CollapseAll();
23088    break;
23089   case CardViewToolbarCommandType.ShowFilterBuilder:
23090    this.grid.ShowFilterControl();
23091    break;
23092   case CardViewToolbarCommandType.ClearFilter:
23093    this.grid.ClearFilter();
23094    break;
23095   case CardViewToolbarCommandType.ShowSearchPanel:
23096    this.ToolbarShowSearchPanel(item.GetChecked());
23097    break;
23098   case CardViewToolbarCommandType.ShowSummaryPanel:
23099    this.ToolbarShowSummaryPanel(item.GetChecked());
23100    break;
23101   case CardViewToolbarCommandType.ShowCustomizationWindow:
23102    if(!this.grid.IsCustomizationWindowVisible())
23103     this.grid.ShowCustomizationWindow();
23104    else
23105     this.grid.HideCustomizationWindow();
23106    break;
23107   case CardViewToolbarCommandType.ShowCardHeader:
23108    this.ToolbarShowCardHeader(item.GetChecked());
23109    break;
23110   case CardViewToolbarCommandType.ShowCardFooter:
23111    this.ToolbarShowCardFooter(item.GetChecked());
23112    break;
23113   case CardViewToolbarCommandType.New:
23114    this.grid.AddNewCard();
23115    break;
23116   case CardViewToolbarCommandType.Edit:
23117    this.ToolbarStartEdit();
23118    break;
23119   case CardViewToolbarCommandType.Delete:
23120    this.ToolbarDeleteItem();
23121    break;
23122   case CardViewToolbarCommandType.DeleteSelectedCardsOnPage:
23123    this.ToolbarDeleteSelectedVisibleItems();
23124    break;
23125   case CardViewToolbarCommandType.Refresh:
23126    this.grid.Refresh();
23127    break;
23128   case CardViewToolbarCommandType.Update:
23129    this.grid.UpdateEdit();
23130    break;
23131   case CardViewToolbarCommandType.Cancel:
23132    this.grid.CancelEdit();
23133    break;
23134   case CardViewToolbarCommandType.UpdateSummaries:
23135    this.grid.UpdateSummaries();
23136    break;
23137   default:
23138    ASPx.GridToolbarHelper.prototype.ProcessToolbarItemClick.call(this, e);
23139    break;
23140  }
23141 },
23142 UpdateBatchPreviewItemsState: function(item, state) {
23143  var command = this.GetItemCommand(item);
23144  if(command === CardViewToolbarCommandType.UpdateSummaries)
23145   item.SetVisible(state.updateSummariesButtonVisible);
23146 },
23147 ToolbarShowHeaderPanel: function(show) {
23148  this.SendToolbarCallback([ "ShowHeaderPanel", show ? 1 : 0 ]);
23149 },
23150 ToolbarShowSearchPanel: function(show) {
23151  this.SendToolbarCallback([ "ShowSearchPanel", show ? 1 : 0 ]);
23152 },
23153 ToolbarShowSummaryPanel: function(show) {
23154  this.SendToolbarCallback([ "ShowSummaryPanel", show ? 1 : 0 ]);
23155 },
23156 ToolbarShowCardHeader: function(show) {
23157  this.SendToolbarCallback([ "ShowCardHeader", show ? 1 : 0 ]);
23158 },
23159 ToolbarShowCardFooter: function(show) {
23160  this.SendToolbarCallback([ "ShowCardFooter", show ? 1 : 0 ]);
23161 },
23162 ToolbarClearSorting: function() {
23163  this.SendToolbarCallback([ "ClearSorting" ]);
23164 },
23165 IsUpdateEditItem: function(item) {
23166  var command = this.GetItemCommand(item);
23167  switch(command) {
23168   case CardViewToolbarCommandType.Update:
23169   case CardViewToolbarCommandType.Cancel:
23170    return true;
23171  }
23172  return false;
23173 },
23174 IsShowCustomizationWindowItem: function(item) {
23175  return this.GetItemCommand(item) === CardViewToolbarCommandType.ShowCustomizationWindow;
23176 },
23177 RefreshItemBadge: function(item) {
23178  if(this.GetItemCommand(item) === CardViewToolbarCommandType.DeleteSelectedCardsOnPage)
23179   this.RefreshSelectionBasedItemBadge(item, this.GetSelectedVisibleGridItemCount());
23180 },
23181 GetToolbarItemEnabled: function(item){
23182  var command = this.GetItemCommand(item);
23183  switch(command) {
23184   case CardViewToolbarCommandType.Edit:
23185    return this.GetEditItemEnabled();
23186   case CardViewToolbarCommandType.Delete:
23187    return this.GetDeleteItemEnabled();
23188   case CardViewToolbarCommandType.DeleteSelectedCardsOnPage:
23189    return this.GetDeleteSelectedCardsOnPageItemEnabled();
23190  }
23191  return null;
23192 },
23193 GetEditItemEnabled: function(){
23194  var focusedIndex = this.GetFocusedItemIndex();
23195  return this.grid.allowEdit && (this.HasBatchEditFocusedCell() || !this.IsEditingItem(focusedIndex));
23196 },
23197 GetDeleteItemEnabled: function(){
23198  var focusedIndex = this.GetFocusedItemIndex();
23199  return this.grid.allowDelete && (this.HasBatchEditFocusedCell() || !this.IsEditingItem(focusedIndex));
23200 },
23201 GetDeleteSelectedCardsItemEnabled: function() {
23202  return this.grid.allowDelete && this.GetSelectedGridItemCount() > 0;
23203 },
23204 GetDeleteSelectedCardsOnPageItemEnabled: function() {
23205  return this.grid.allowDelete && this.GetSelectedVisibleGridItemCount() > 0;
23206 }
23207});
23208ASPx.CardViewToolbarHelper = CardViewToolbarHelper;
23209})();
23210(function(){
23211var ASPxClientCardView = ASPx.CreateClass(ASPxClientGridBase, {
23212 CardID: "DXDataCard",
23213 EditingCardID: "DXEditingCard",
23214 EmptyCardID: "DXEmptyCard",
23215 CardLayoutID: "DXCardLayout",
23216 GroupRowID: "DXGroupRow",
23217 EndlessPagingEtalonElementsTable: "EPEET",
23218 EndlessPagingMoreButtonContainer: "EPMBC",
23219 EndlessPagingMoreButtonDivID: "EPMBD",
23220 GroupSelectorID: "GroupSelector",
23221 ErrorCardContentWrapperClassName: "dxcvECCW",
23222 ErrorCardErrorContainerClassName: "dxcvECEC",
23223 FlowCardClassNamePrefix: "dxcvFlowCard",
23224 BreakpointsCardClassNamePrefix: "dxcvBreakpointsCard",
23225 DefaultEndlessPagingScrollDelta: 70,
23226 NewCardVisibleIndex: -2147483647,
23227 EtalonCardPostfix: "Etalon",
23228 constructor: function(name) {
23229  this.constructor.prototype.constructor.call(this, name);
23230  this.layoutMode = 0;
23231  this.GroupRowExpanding  = new ASPxClientEvent();
23232  this.GroupRowCollapsing  = new ASPxClientEvent();
23233  this.BatchEditCardValidating = new ASPxClientEvent();
23234  this.BatchEditCardInserting = new ASPxClientEvent();
23235  this.BatchEditCardDeleting = new ASPxClientEvent();
23236  this.BatchEditCardRecovering = new ASPxClientEvent();
23237  this.BatchEditCardChangesCanceling = new ASPxClientEvent();
23238  this.CardClick = new ASPxClientEvent();
23239  this.CardDblClick = new ASPxClientEvent();
23240  this.FocusedCardChanged = new ASPxClientEvent();
23241  this.CardFocusing = new ASPxClientEvent();
23242 },
23243 CreateBatchEditApi: function() { return new ASPxClientCardViewBatchEditApi(this); },
23244 CreateColumn: function(prop) { return new ASPxClientCardViewColumn(prop); },
23245 Initialize: function() {
23246  ASPxClientGridBase.prototype.Initialize.call(this);
23247  this.windowScrollHandler = this.CheckEndlessPagingLoadNextPage.bind(this);
23248  ASPx.Evt.AttachEventToElement(window, "scroll", this.windowScrollHandler);
23249  this.CheckEndlessPagingLoadNextPage();
23250 },
23251 InlineInitialize: function() {
23252  ASPxClientGridBase.prototype.InlineInitialize.call(this);
23253  if(this.IsBreakpointsLayoutMode())
23254   ASPx.BreakpointsLayoutCssHelper.Update();
23255 },
23256 OnDispose: function() {
23257  ASPxClientGridBase.prototype.OnDispose.call(this);
23258  if(this.windowScrollHandler)
23259   ASPx.Evt.DetachEventFromElement(window, "scroll", this.windowScrollHandler);
23260 },
23261 applyAccessibilityAttributes: function() {
23262  var argList = [];
23263  for(var i = 0; i < this.pageRowCount; i++)
23264   argList.push([["{0}", this.visibleStartIndex + i + 1], ["{1}", this.getItemCount()]]);
23265  this.setAriaDescription("card", argList);
23266  this.setAriaDescription("layoutDiv", [[]]);
23267  this.setAriaDescription("image", [[]]);
23268  this.setAriaDescription("layoutTables", [[]]);
23269 },
23270 canGroupByColumn: function(column) {
23271  return column.allowGroup;
23272 },
23273 getItemCount: function() { return this.totalCardCount; },
23274 IsOnClickEndlessPagingMode: function() { return this.useEndlessPaging && this.endlessPagingMode === 0; },
23275 IsTableLayoutMode: function() { return this.layoutMode === 0; },
23276 IsFlowLayoutMode: function() { return this.layoutMode === 1; },
23277 IsBreakpointsLayoutMode: function() { return this.layoutMode === 2; },
23278 GetBreakpointsLayoutSettings: function() {
23279  return ASPx.BreakpointsLayoutCssHelper.GetBreakpointsLayoutSettings(this.breakpointsCardsPerRow, this.breakpointsInfo);
23280 },
23281 GetCardLayoutControl: function(visibleIndex) { return ASPx.GetControlCollection().Get(this.name + "_" + this.CardLayoutID + visibleIndex); },
23282 GetEditingRow: function(obj) { return ASPx.GetElementById((obj ? obj.name : this.name) + "_" + this.EditingCardID); },
23283 GetEtalonElementsTable: function() { return this.GetChildElement(this.EndlessPagingEtalonElementsTable); },
23284 HasEndlessPagingEtalonElements: function() { return this.useEndlessPaging && !!this.GetEtalonElementsTable(); },
23285 GetEtalonEmptyHiddenCard: function() { return this.HasEndlessPagingEtalonElements() ? this.GetEtalonElementsTable().rows[0].cells[0] : document.createElement("TD"); },
23286 GetEtalonSeparatorCell: function() { return this.HasEndlessPagingEtalonElements() ? this.GetEtalonElementsTable().rows[1].cells[0] : document.createElement("TD"); },
23287 GetEtalonSeparatorRow: function() { return this.HasEndlessPagingEtalonElements() ? this.GetEtalonElementsTable().rows[2] : document.createElement("TR"); }, 
23288 GetItem: function(visibleIndex) {
23289  var result = this.GetCard(visibleIndex);
23290  if(result == null) result = this.GetGroupRow(visibleIndex);
23291  return result;
23292 },
23293 GetDataItem: function(visibleIndex) {return this.GetItem(visibleIndex); },
23294 GetDataItemIDPrefix: function() { return this.CardID; },
23295 GetCard: function(visibleIndex) { return this.GetChildElement(this.CardID + visibleIndex); },
23296 GetGroupRow: function(visibleIndex) {
23297  var element = this.GetChildElement(this.GroupRowID + visibleIndex);
23298  if(!element)
23299   element = this.GetExpandedGroupRow(visibleIndex);
23300  return element; 
23301 },
23302 GetExpandedGroupRow: function(visibleIndex) { return this.GetChildElement(this.GroupRowID + "Exp" + visibleIndex); },
23303 CreateNavigationHelper: function() { 
23304  return typeof(ASPx.CardViewNavigationHelper) != "undefined" ? new ASPx.CardViewNavigationHelper(this) : null;
23305 },
23306 GetEmptyDataItemIDPostfix: function() { return this.EmptyCardID; },
23307 GetCssClassNamePrefix: function() { return "dxcv"; },
23308 GetDataRowSelBtnIDPrefix: function(visibleIndex) { return "_" + this.CardLayoutID + visibleIndex + "_" + this.SelectButtonID; },
23309 getItemByHtmlEvent: function(evt) {
23310  return this.getItemByHtmlEventCore(evt, this.CardID);
23311 },
23312 GetEndlessPagingMoreButtonContainer: function() { return this.GetChildElement(this.EndlessPagingMoreButtonContainer); },
23313 GetEndlessPagingMoreButtonDiv: function() { return this.GetChildElement(this.EndlessPagingMoreButtonDivID); },
23314 GetScrollHelper: function() {
23315  if(!this.HasScrolling()) return null;
23316  if(!this.scrollableHelper)
23317   this.scrollableHelper = new ASPx.CardViewTableScrollHelper(this);
23318  return this.scrollableHelper;
23319 },
23320 GetVerticalScrollPosition: function() {
23321  if(this.GetScrollHelper())
23322   return this.GetScrollHelper().GetSavedVertScrollPosition();
23323  return ASPxClientGridBase.prototype.GetVerticalScrollPosition.call(this);
23324 },
23325 SetVerticalScrollPosition: function(value) {
23326  ASPxClientGridBase.prototype.SetVerticalScrollPosition.call(this, value);
23327  if(this.GetScrollHelper()) 
23328   this.GetScrollHelper().SetVertScrollPosition(value);
23329  else
23330   ASPxClientGridBase.prototype.SetVerticalScrollPosition.call(this, value);
23331 },
23332 MakeRowVisible: function(visibleIndex) {
23333  var helper = this.GetScrollHelper();
23334  var card = this.GetItem(visibleIndex);
23335  if(helper && card)
23336   helper.MakeRowVisible(card);
23337 },
23338 GetProgressBarControl: function(visibleIndex, columnIndex) { 
23339  var pbName = this.name + "_" + this.CardLayoutID + visibleIndex + "_" + this.GetProgressBarControlID(visibleIndex, columnIndex);
23340  return ASPx.GetControlCollection().Get(pbName); 
23341 },
23342 GetGroupSelectorControl: function() { return ASPx.GetControlCollection().Get(this.name + "_" + this.GroupSelectorID); },
23343 CreateEndlessPagingHelper: function() { return new ASPx.CardViewEndlessPagingHelper(this); },
23344 CreateBatchEditHelperOwner: function() { return new ASPx.CardViewBatchEditHelperOwner(this); },
23345 CreateCellFocusHelper: function() { return new ASPx.CardViewCellFocusHelper(this); },
23346 CreateToolbarHelper: function() { return new ASPx.CardViewToolbarHelper(this); },
23347 GetItemVisibleIndexRegExp: function(dataAndGroupOnly) {
23348  return this.GetItemVisibleIndexRegExpByIdParts([ this.CardID, this.GroupRowID + "(?:Exp)?" ]);
23349 },
23350 GetFocusableLayoutItemsList: function() { return this.focusableLayoutItemsList; },
23351 GetFocusableLayoutItemPaths: function() { return this.GetFocusableLayoutItemsList().map(function(item) { return item.path; }); },
23352 GetLayoutItemPaths: function() { return this.layoutItemPaths; },
23353 GetVisibleColumnIndices: function() { return this.GetFocusableLayoutItemsList().map(function(item) { return item.index; }); },
23354 GetColumnIndexByDataCell: function(cell) { return this.GetColumnIndexByItemPath(this.GetItemPathByCell(cell)); },
23355 GetColumnIndexByItemPath: function(path) {
23356  var list = this.GetFocusableLayoutItemsList();
23357  var itemIndex = ASPx.Data.ArrayIndexOf(list, path, function(item, itemPath) { return item && item.path == itemPath; });
23358  return list[itemIndex] ? list[itemIndex].index : -1;
23359 },
23360 GetItemPathByColumnIndex: function(columnIndex) {
23361  var list = this.GetFocusableLayoutItemsList();
23362  var itemIndex = ASPx.Data.ArrayIndexOf(list, columnIndex, function(item, columnIndex) { return item.index == columnIndex; });
23363  return list[itemIndex] && list[itemIndex].path;
23364 },
23365 GetItemPathByCell: function(dataCell) {
23366  if(!dataCell) return null;
23367  if(!dataCell.layoutItem) {
23368    var card = ASPx.GetParentByPartialId(dataCell, this.CardID);
23369    if(!card) return null;
23370    var visibleIndex = this.getItemIndex(card.id);
23371    this.EnsureDataItemClientInfo(visibleIndex);
23372  }
23373  return dataCell.layoutItem && dataCell.layoutItem.path;
23374 },
23375 EnsureDataItemClientInfo: function(visibleIndex) {
23376  var layoutControl = this.GetCardLayoutControl(visibleIndex);
23377  if(layoutControl && layoutControl.GetMainElement())
23378   this.EnsureLayoutControlItems(layoutControl);
23379 },
23380 EnsureLayoutControlItems: function(layoutControl) {
23381  if(layoutControl.GetMainElement().dxgvItemsProcessed) 
23382   return;
23383  var itemPaths = this.GetLayoutItemPaths();
23384  for(var i = 0; i < itemPaths.length; i++) {
23385   var path = itemPaths[i];
23386   var item = layoutControl.GetItemByPath(path);
23387   var itemElement = layoutControl.GetHTMLElementByItem(item);
23388   if(item && itemElement)
23389    itemElement.layoutItem = item;
23390  }
23391  layoutControl.GetMainElement().dxgvItemsProcessed = true;
23392 },
23393 GetFormLayoutNestedControlCell: function(visibleIndex, columnIndex) { 
23394  this.EnsureDataItemClientInfo(visibleIndex);
23395  var containerCell = this.GetFormLayoutItemCell(visibleIndex, columnIndex);
23396  if(!containerCell) return;
23397  var layoutItem = containerCell.layoutItem;
23398  return layoutItem && layoutItem.formLayout.getNestedControlCell(layoutItem); 
23399 },
23400 GetFormLayoutItemCell: function(visibleIndex, columnIndex) { 
23401  return this.GetFormLayoutItemCellByPath(visibleIndex, this.GetItemPathByColumnIndex(columnIndex));
23402 },
23403 GetFormLayoutItemCellByPath: function(visibleIndex, path) {
23404  var layoutControl = this.GetCardLayoutControl(visibleIndex);
23405  if(!layoutControl || !layoutControl.GetMainElement() || !ASPx.IsExists(path))
23406   return;
23407  var item = layoutControl.GetItemByPath(path);
23408  return layoutControl.GetHTMLElementByItem(item);
23409 },
23410 GetFormLayoutItemCellByChild: function(element) { 
23411  var cell = ASPx.GetParentByPartialClassName(element, ASPx.FormLayoutConsts.GROUP_CELL_PARTIAL_CLASS_NAME);
23412  if(cell && cell.tagName === "DIV") 
23413   cell = cell.parentNode;
23414  return cell;
23415 },
23416 GetErrorTextContainer: function(displayIn) { 
23417  var errorItem = this.GetEditingErrorItem(displayIn); 
23418  if(!errorItem) {
23419   var editCard = this.GetEditingRow(displayIn);
23420   if(editCard) {
23421    errorItem = this.CreateEditingErrorItem();
23422    errorItem.id = editCard.id.replace(this.EditingCardID, this.EditingErrorItemID);
23423    var errorItemContainer = this.GetErrorItemContainer(editCard);
23424    errorItemContainer.appendChild(errorItem);
23425   }
23426  }
23427  return errorItem;
23428 },
23429 CreateEditingErrorItem: function() {
23430  var wrapper = document.createElement("div");
23431  var helper = this.GetStyleHelper();
23432  wrapper.innerHTML = helper.GetErrorItemHtml();
23433  return ASPx.GetChildByTagName(wrapper, "DIV", 0);
23434 },
23435 GetErrorItemContainer: function(card) {
23436  var container = ASPx.GetNodeByClassName(card, this.ErrorCardErrorContainerClassName);
23437  if(!container) {
23438   this.WrapErrorCard(card);
23439   container = ASPx.GetNodeByClassName(card, this.ErrorCardErrorContainerClassName);
23440  }
23441  return container;
23442 },
23443 WrapErrorCard: function(card) {
23444  var cardContent = document.createDocumentFragment();
23445  while(card.firstChild)
23446   cardContent.appendChild(card.firstChild);
23447  var wrapper = document.createElement("DIV");
23448  ASPx.AddClassNameToElement(wrapper, this.ErrorCardContentWrapperClassName);
23449  card.appendChild(wrapper);
23450  var createCell = function(table) { 
23451   var row = table.appendChild(document.createElement("DIV"));
23452   return row.appendChild(document.createElement("DIV")); 
23453  }; 
23454  var contentContainer = createCell(wrapper);
23455  contentContainer.appendChild(cardContent);
23456  var errorContainer = createCell(wrapper);
23457  ASPx.AddClassNameToElement(errorContainer, this.ErrorCardErrorContainerClassName);
23458 },
23459 RestoreCallbackSettings: function(){
23460  this.UpdateScrollableControls();
23461  ASPxClientGridBase.prototype.RestoreCallbackSettings.call(this);
23462 },
23463 OnBrowserWindowResize: function(e) {
23464  ASPxClientGridBase.prototype.OnBrowserWindowResize.call(this);
23465  this.CheckEndlessPagingLoadNextPage();
23466  this.InvalidateLayout();
23467 },
23468 CheckEndlessPagingLoadNextPage: function() {
23469  if(!this.IsVisible() || !this.useEndlessPaging || this.IsOnClickEndlessPagingMode() || this.HasScrolling()) 
23470   return;
23471  if(this.pageIndex + 1 === this.pageCount || this.pageCount === 0 || this.InCallback())
23472   return;
23473  var windowHeight = ASPxClientUtils.iOSPlatform ? window.innerHeight : ASPxClientUtils.GetDocumentClientHeight(); 
23474  var mainTable = this.GetMainTable();
23475  var mainTableBottomY = ASPx.GetAbsolutePositionY(mainTable) + mainTable.clientHeight;
23476  var scrollTop = ASPxClientUtils.GetDocumentScrollTop();
23477  var scrollDelta = mainTableBottomY - windowHeight - scrollTop;
23478  if(scrollDelta <= this.GetEndlessPagingMinScrollDelta())
23479   this.NextPage();
23480 },
23481 HasEmptySpaceInLastCardLine: function() {
23482  if(this.IsTableLayoutMode())
23483   return false;
23484  var cards = this.GetEndlessPagingHelper().GetItemElements();
23485  if(cards.length === 0)
23486   return false;
23487  var mainTable = this.GetMainTable();
23488  var lastCard = cards[cards.length - 1];
23489  var mainTableRightPos = ASPx.GetAbsoluteX(mainTable) + mainTable.offsetWidth;
23490  var lastCardRightPos = ASPx.GetAbsoluteX(lastCard) + lastCard.offsetWidth;
23491  return mainTableRightPos - lastCardRightPos >= lastCard.offsetWidth;
23492 },
23493 GetEndlessPagingMinScrollDelta: function() {
23494  var result = this.DefaultEndlessPagingScrollDelta;
23495  if(this.HasEmptySpaceInLastCardLine()) {
23496   var card = this.GetEndlessPagingHelper().GetItemElements()[0];
23497   result += card.offsetHeight;
23498  }
23499  return result;
23500 },
23501 OnAfterCallback: function() {
23502  ASPxClientGridBase.prototype.OnAfterCallback.call(this);
23503  this.CheckEndlessPagingMoreButtonVisibility();
23504  if(this.accessibilityCompliant)
23505   this.applyAccessibilityAttributes();
23506 },
23507 CheckEndlessPagingMoreButtonVisibility: function() {
23508  if(this.IsOnClickEndlessPagingMode()) {
23509   var container = this.GetEndlessPagingMoreButtonContainer();
23510   var show = this.pageCount > -1 && this.pageIndex < this.pageCount - 1;
23511   ASPx.SetElementDisplay(container, show);
23512   if(this.GetEndlessPagingLPContainer()) {   
23513    ASPx.Attr.RestoreStyleAttribute(container, "min-height");
23514    ASPx.Attr.RestoreStyleAttribute(container, "padding");
23515    ASPx.SetElementDisplay(this.GetEndlessPagingMoreButtonDiv(), true);
23516   }
23517  }
23518 },
23519 ShowLoadingPanel: function() {
23520  if(this.IsOnClickEndlessPagingMode() && this.NeedShowLoadingPanelInsideEndlessPagingContainer()){
23521   var container = this.GetEndlessPagingMoreButtonContainer();
23522   ASPx.Attr.ChangeStyleAttribute(container, "min-height",container.offsetHeight + "px"); 
23523   ASPx.Attr.ChangeStyleAttribute(container, "padding","0px");
23524   ASPx.SetElementDisplay(this.GetEndlessPagingMoreButtonDiv(), false);
23525  }
23526  ASPxClientGridBase.prototype.ShowLoadingPanel.call(this);
23527 },
23528 SortBy: function(column, sortOrder, reset, sortIndex){
23529    ASPxClientGridBase.prototype.SortBy.call(this, column, sortOrder, reset, sortIndex);
23530 },
23531 GroupBy: function(column, groupIndex, sortOrder){
23532  ASPxClientGridBase.prototype.GroupBy.call(this, column, groupIndex, sortOrder);
23533 },
23534 OnGroupSelectorValueChanged: function() {
23535  var groupSelector = this.GetGroupSelectorControl();
23536  var groupSelectorValue = groupSelector.GetValue() || "";
23537  this.gridCallBack([ASPxClientCardViewCallbackCommand.GroupBySelectorValue, groupSelectorValue]);
23538 },
23539 Ungroup: function(column){
23540  ASPxClientGridBase.prototype.Ungroup.call(this, column);
23541 },
23542 MoveColumn: function(column, columnMoveTo, moveBefore){
23543  ASPxClientGridBase.prototype.MoveColumn.call(this, column, columnMoveTo, moveBefore);
23544 },
23545 GetCardKey: function(visibleIndex) {
23546  return this.GetItemKey(visibleIndex);
23547 },
23548 StartEditCard: function(visibleIndex) {
23549    this.StartEditItem(visibleIndex);
23550 },
23551 StartEditCardByKey: function(key) {
23552  this.StartEditItemByKey(key);
23553 },
23554 IsNewCardEditing: function() {
23555  return this.IsNewItemEditing();
23556 },
23557 AddNewCard: function(){
23558    this.AddNewItem();
23559 },
23560 DeleteCard: function(visibleIndex){
23561  this.DeleteItem(visibleIndex);
23562 },
23563 DeleteCardByKey: function(key) {
23564  this.DeleteItemByKey(key);
23565 },
23566 GetFocusedCardIndex: function() {
23567  return this._getFocusedItemIndex();
23568 },
23569 SetFocusedCardIndex: function(visibleIndex) {
23570  return this._setFocusedItemIndex(visibleIndex);
23571 },
23572 SelectCards: function(visibleIndices, selected){
23573  this.SelectItemsCore(visibleIndices, selected, false);
23574 },
23575 SelectCardsByKey: function(keys, selected){
23576  this.SelectItemsByKey(keys, selected);
23577 },
23578 UnselectCardsByKey: function(keys){
23579  this.SelectCardsByKey(keys, false);
23580 },
23581 UnselectCards: function(visibleIndices){
23582  this.SelectCards(visibleIndices, false);
23583 },
23584 UnselectFilteredCards: function() {
23585  this.UnselectFilteredItemsCore();
23586 },
23587 SelectCardOnPage: function(visibleIndex, selected){
23588  if(!ASPx.IsExists(selected)) selected = true;
23589  this.SelectItem(visibleIndex, selected);
23590 },
23591 UnselectCardOnPage: function(visibleIndex){
23592  this.SelectCardOnPage(visibleIndex, false);
23593 },
23594 SelectAllCardsOnPage: function(selected){
23595  this.SelectAllItemsOnPage(selected);
23596 },
23597 UnselectAllCardsOnPage: function(){
23598  this.UnselectAllItemsOnPage();
23599 },
23600 GetSelectedCardCount: function() {
23601  return this._getSelectedRowCount();
23602 },
23603 IsCardSelectedOnPage: function(visibleIndex) {
23604  return this._isRowSelected(visibleIndex);
23605 },
23606 ExpandGroupRow: function(visibleIndex){
23607  if(visibleIndex === undefined)
23608   throw new Error("No parameter is passed to the function");
23609  if(this.RaiseGroupRowExpanding(visibleIndex)) return;
23610  this.gridCallBack([ASPxClientGridViewCallbackCommand.ExpandRow, visibleIndex, false]);
23611 },
23612 CollapseGroupRow: function(visibleIndex){
23613  if(visibleIndex === undefined)
23614   throw new Error("No parameter is passed to the function");
23615  if(this.RaiseGroupRowCollapsing(visibleIndex)) return;
23616  this.gridCallBack([ASPxClientGridViewCallbackCommand.CollapseRow, visibleIndex, false]);
23617 },
23618 ExpandAll: function(){
23619  ASPxClientGridBase.prototype.ExpandAll.call(this);
23620 },
23621 CollapseAll: function(){
23622  ASPxClientGridBase.prototype.CollapseAll.call(this);
23623 },
23624 ExportTo: function(format) {
23625  ASPxClientGridBase.prototype.ExportTo.call(this, format);
23626 },
23627 RaiseGroupRowExpanding: function(visibleIndex) {
23628  if(!this.GroupRowExpanding.IsEmpty()){
23629   var args = new ASPxClientCardViewGroupCancelEventArgs(visibleIndex);
23630   this.GroupRowExpanding.FireEvent(this, args);
23631   return args.cancel;
23632  }
23633  return false; 
23634 },
23635 RaiseGroupRowCollapsing: function(visibleIndex) {
23636  if(!this.GroupRowCollapsing.IsEmpty()){
23637   var args = new ASPxClientCardViewGroupCancelEventArgs(visibleIndex);
23638   this.GroupRowCollapsing.FireEvent(this, args);
23639   return args.cancel;
23640  }
23641  return false; 
23642 },
23643 RaiseFocusedItemChanged: function(isChangedOnServer) {
23644  if(!this.FocusedCardChanged.IsEmpty()){
23645   var args = new ASPxClientCardViewFocusEventArgs(isChangedOnServer);
23646   this.FocusedCardChanged.FireEvent(this, args);
23647   if(args.processOnServer)
23648    this.gridCallBack([ASPxClientGridViewCallbackCommand.FocusedRow]);
23649  }
23650  return false; 
23651 },
23652 RaiseItemFocusing: function(visibleIndex, htmlEvent) { 
23653  if(!this.CardFocusing.IsEmpty()){
23654   var args = new ASPxClientCardViewCardFocusingEventArgs(visibleIndex, htmlEvent);
23655   this.CardFocusing.FireEvent(this, args);
23656   return args.cancel;
23657  }
23658  return false; 
23659 },
23660 RaiseItemClick: function(visibleIndex, htmlEvent) {
23661  if(!this.CardClick.IsEmpty()){
23662   var args = new ASPxClientCardViewCardClickEventArgs(visibleIndex, htmlEvent);
23663   this.CardClick.FireEvent(this, args);
23664   return args.cancel;
23665  }
23666  return false; 
23667 },
23668 RaiseItemDblClick: function(visibleIndex, htmlEvent) {
23669  if(!this.CardDblClick.IsEmpty()){
23670   ASPx.Selection.Clear(); 
23671   var args = new ASPxClientCardViewCardClickEventArgs(visibleIndex, htmlEvent);
23672   this.CardDblClick.FireEvent(this, args);
23673   return args.cancel;
23674  }
23675  return false; 
23676 },
23677 CreateCommandCustomButtonEventArgs: function(index, id){
23678  return new ASPxClientCardViewCustomButtonEventArgs(index, id);
23679 },
23680 CreateSelectionEventArgs: function(visibleIndex, isSelected, isAllRecordsOnPage, isChangedOnServer){
23681  return new ASPxClientCardViewSelectionEventArgs(visibleIndex, isSelected, isAllRecordsOnPage, isChangedOnServer);
23682 },
23683 CreateColumnCancelEventArgs: function(column){
23684  return new ASPxClientCardViewColumnCancelEventArgs(column);
23685 },
23686 UA_EndlessShowMore: function() {
23687  this.NextPage();
23688 },
23689 GetCardValues: function(visibleIndex, fieldNames, onCallBack) {
23690  this.GetItemValues(visibleIndex, fieldNames, onCallBack);
23691 },
23692 GetPageCardValues: function(fieldNames, onCallBack) {
23693  this.GetPageItemValues(fieldNames, onCallBack);
23694 },
23695 GetVisibleCardsOnPage: function() {
23696  return this.GetVisibleItemsOnPage();
23697 },
23698 GetCustomizationWindowHeaders: function() {
23699  return ASPx.GetNodesByPartialClassName(this.GetCustomizationWindowElement(), "dxcvHeader");
23700 },
23701 RaiseBatchEditStartEditing: function(visibleIndex, column, rowValues) {
23702  var args = new ASPxClientCardViewBatchEditStartEditingEventArgs(visibleIndex, column, rowValues);
23703  if(!this.BatchEditStartEditing.IsEmpty())
23704   this.BatchEditStartEditing.FireEvent(this, args);
23705  return args;
23706 },
23707 RaiseBatchEditEndEditing: function(visibleIndex, focusedColumn, rowValues) {
23708  var args = new ASPxClientCardViewBatchEditEndEditingEventArgs(visibleIndex, rowValues, focusedColumn);
23709  if(!this.BatchEditEndEditing.IsEmpty())
23710   this.BatchEditEndEditing.FireEvent(this, args);
23711  return args;
23712 },
23713 RaiseBatchEditItemChangesCanceling: function(visibleIndex, rowValues) {
23714  var args = new ASPxClientCardViewBatchEditCardChangesCancelingEventArgs(visibleIndex, rowValues);
23715  if(!this.BatchEditCardChangesCanceling.IsEmpty())
23716   this.BatchEditCardChangesCanceling.FireEvent(this, args);
23717  return args;
23718 },
23719 RaiseBatchEditItemValidating: function(visibleIndex, validationInfo) {
23720  var args = new ASPxClientCardViewBatchEditCardValidatingEventArgs(visibleIndex, validationInfo);
23721  if(!this.BatchEditCardValidating.IsEmpty())
23722   this.BatchEditCardValidating.FireEvent(this, args);
23723  return args.validationInfo;
23724 },
23725 RaiseBatchEditConfirmShowing: function(requestTriggerID) {
23726  if(!this.BatchEditConfirmShowing.IsEmpty()) {
23727   var args = new ASPxClientCardViewBatchEditConfirmShowingEventArgs(requestTriggerID);
23728   this.BatchEditConfirmShowing.FireEvent(this, args);
23729   return args.cancel;
23730  }
23731  return false;
23732 },
23733 RaiseBatchEditTemplateCellFocused: function(columnIndex) {
23734  var column = this._getColumn(columnIndex);
23735  if(!column) return false;
23736  var args = new ASPxClientCardViewBatchEditTemplateCellFocusedEventArgs(column);
23737  if(!this.BatchEditTemplateCellFocused.IsEmpty())
23738   this.BatchEditTemplateCellFocused.FireEvent(this, args);
23739  return args.handled;
23740 },
23741 RaiseBatchEditChangesSaving: function(valuesInfo) { 
23742  if(!this.BatchEditChangesSaving.IsEmpty()){
23743   var args = new ASPxClientCardViewBatchEditChangesSavingEventArgs(valuesInfo.insertedValues, valuesInfo.deletedValues, valuesInfo.updatedValues);
23744   this.BatchEditChangesSaving.FireEvent(this, args);
23745   return args.cancel;
23746  }
23747  return false; 
23748 },
23749 RaiseBatchEditChangesCanceling: function(valuesInfo) { 
23750  if(!this.BatchEditChangesCanceling.IsEmpty()){
23751   var args = new ASPxClientCardViewBatchEditChangesCancelingEventArgs(valuesInfo.insertedValues, valuesInfo.deletedValues, valuesInfo.updatedValues);
23752   this.BatchEditChangesCanceling.FireEvent(this, args);
23753   return args.cancel;
23754  }
23755  return false; 
23756 },
23757 RaiseBatchEditItemInserting: function(visibleIndex) { 
23758  if(!this.BatchEditCardInserting.IsEmpty()){
23759   var args = new ASPxClientCardViewBatchEditCardInsertingEventArgs(visibleIndex);
23760   this.BatchEditCardInserting.FireEvent(this, args);
23761   return args.cancel;
23762  }
23763  return false; 
23764 },
23765 RaiseBatchEditItemDeleting: function(visibleIndex, itemValues) { 
23766  if(!this.BatchEditCardDeleting.IsEmpty()){
23767   var args = new ASPxClientCardViewBatchEditCardDeletingEventArgs(visibleIndex, itemValues);
23768   this.BatchEditCardDeleting.FireEvent(this, args);
23769   return args.cancel;
23770  }
23771  return false; 
23772 },
23773 RaiseBatchEditItemRecovering: function(visibleIndex, itemValues) { 
23774  if(!this.BatchEditCardRecovering.IsEmpty()){
23775   var args = new ASPxClientCardViewBatchEditCardRecoveringEventArgs(visibleIndex, itemValues);
23776   this.BatchEditCardRecovering.FireEvent(this, args);
23777   return args.cancel;
23778  }
23779  return false; 
23780 },
23781 CreateUserCellInfo: function(visibleIndex, column) { return new ASPxClientCardViewCellInfo(visibleIndex, column); },
23782 CreateFocusedCellChangingArgs: function(cellInfo) { return new ASPxClientCardViewFocusedCellChangingEventArgs(cellInfo); },
23783 GetEditFormLayoutIDPostfix: function() {
23784  return "_DXCardLayout" + this.editItemVisibleIndex;
23785 }
23786});
23787ASPxClientCardView.Cast = ASPxClientGridBase.Cast;
23788var ASPxClientCardViewColumn = ASPx.CreateClass(ASPxClientGridColumnBase, {
23789 constructor: function(prop){
23790  this.constructor.prototype.constructor.call(this, prop);
23791  this.groupIndex = ASPx.IsExists(prop[8]) ? prop[8] : -1;
23792  this.allowGroup = ASPx.IsExists(prop[9]) ? !!prop[9] : true;
23793 }
23794});
23795var ASPxClientCardViewColumnCancelEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
23796 constructor: function(column){
23797  this.constructor.prototype.constructor.call(this);
23798  this.column = column;
23799 }
23800});
23801var ASPxClientCardViewCardFocusingEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
23802 constructor: function(visibleIndex, htmlEvent) {
23803  this.constructor.prototype.constructor.call(this, visibleIndex);
23804  this.visibleIndex = visibleIndex;
23805  this.htmlEvent = htmlEvent;
23806 }
23807});
23808var ASPxClientCardViewCardClickEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
23809 constructor: function(visibleIndex, htmlEvent){
23810  this.constructor.prototype.constructor.call(this, visibleIndex);
23811  this.visibleIndex = visibleIndex;
23812  this.htmlEvent = htmlEvent;
23813 }
23814});
23815var ASPxClientCardViewGroupCancelEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
23816 constructor: function(visibleIndex){
23817  this.constructor.prototype.constructor.call(this);
23818  this.visibleIndex = visibleIndex;
23819 }
23820});
23821var ASPxClientCardViewCustomButtonEventArgs = ASPx.CreateClass(ASPxClientProcessingModeEventArgs, {
23822 constructor: function(visibleIndex, buttonID) {
23823  this.constructor.prototype.constructor.call(this, false);
23824  this.visibleIndex = visibleIndex;
23825  this.buttonID = buttonID;
23826 } 
23827});
23828var ASPxClientCardViewSelectionEventArgs = ASPx.CreateClass(ASPxClientProcessingModeEventArgs, {
23829 constructor: function(visibleIndex, isSelected, isAllRecordsOnPage, isChangedOnServer){
23830  this.constructor.prototype.constructor.call(this, false);
23831  this.visibleIndex = visibleIndex;
23832  this.isSelected = isSelected;
23833  this.isAllRecordsOnPage = isAllRecordsOnPage;
23834  this.isChangedOnServer = !!isChangedOnServer;
23835 }
23836});
23837var ASPxClientCardViewFocusEventArgs = ASPx.CreateClass(ASPxClientProcessingModeEventArgs, {
23838 constructor: function(isChangedOnServer){
23839  this.constructor.prototype.constructor.call(this, false);
23840  this.isChangedOnServer = !!isChangedOnServer;
23841 }
23842});
23843var ASPxClientCardViewBatchEditStartEditingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditStartEditingEventArgs, {
23844 constructor: function(visibleIndex, focusedColumn, itemValues) {
23845  this.constructor.prototype.constructor.call(this, visibleIndex, focusedColumn, itemValues);
23846  this.cardValues = this.itemValues;
23847 }
23848});
23849var ASPxClientCardViewBatchEditEndEditingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditEndEditingEventArgs, {
23850 constructor: function(visibleIndex, itemValues, focusedColumn) {
23851  this.constructor.prototype.constructor.call(this, visibleIndex, focusedColumn, itemValues);
23852  this.cardValues = this.itemValues;
23853 }
23854});
23855var ASPxClientCardViewBatchEditCardChangesCancelingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditItemChangesCancelingEventArgs, {
23856 constructor: function(visibleIndex, itemValues) {
23857  this.constructor.prototype.constructor.call(this, visibleIndex, itemValues);
23858  this.cardValues = this.itemValues;
23859 }
23860});
23861var ASPxClientCardViewBatchEditCardValidatingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditItemValidatingEventArgs, {
23862 constructor: function(visibleIndex, validationInfo) {
23863  this.constructor.prototype.constructor.call(this, visibleIndex, validationInfo);
23864 }
23865});
23866var ASPxClientCardViewBatchEditConfirmShowingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditConfirmShowingEventArgs, {
23867 constructor: function(requestTriggerID) {
23868  this.constructor.prototype.constructor.call(this, requestTriggerID);
23869 }
23870});
23871var ASPxClientCardViewBatchEditTemplateCellFocusedEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditTemplateCellFocusedEventArgs, {
23872 constructor: function(column) {
23873  this.constructor.prototype.constructor.call(this, column);
23874 }
23875});
23876var ASPxClientCardViewBatchEditChangesSavingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditClientChangesEventArgs, {
23877 constructor: function(insertedValues, deletedValues, updatedValues) {
23878  this.constructor.prototype.constructor.call(this, insertedValues, deletedValues, updatedValues);
23879 }
23880});
23881var ASPxClientCardViewBatchEditChangesCancelingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditClientChangesEventArgs, {
23882 constructor: function(insertedValues, deletedValues, updatedValues) {
23883  this.constructor.prototype.constructor.call(this, insertedValues, deletedValues, updatedValues);
23884 }
23885});
23886var ASPxClientCardViewBatchEditCardInsertingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditItemInsertingEventArgs, {
23887 constructor: function(visibleIndex) {
23888  this.constructor.prototype.constructor.call(this, visibleIndex);
23889 }
23890});
23891var ASPxClientCardViewBatchEditCardDeletingEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditItemDeletingEventArgs, {
23892 constructor: function(visibleIndex, itemValues) {
23893  this.constructor.prototype.constructor.call(this, visibleIndex, itemValues);  
23894  this.cardValues = this.itemValues;  
23895 }
23896});
23897var ASPxClientCardViewBatchEditCardRecoveringEventArgs = ASPx.CreateClass(ASPxClientGridBatchEditItemDeletingEventArgs, {
23898 constructor: function(visibleIndex, itemValues) {
23899  this.constructor.prototype.constructor.call(this, visibleIndex, itemValues);  
23900  this.cardValues = this.itemValues;  
23901 }
23902});
23903var ASPxClientCardViewFocusedCellChangingEventArgs = ASPx.CreateClass(ASPxClientGridFocusedCellChangingEventArgs, {
23904 constructor: function(cellInfo) {
23905  this.constructor.prototype.constructor.call(this, cellInfo);
23906 }
23907});
23908ASPx.CVToogleCustWindow = function(name) {
23909 var gv = ASPx.GetControlCollection().Get(name);
23910 if(gv != null)
23911  gv.ShowCustomizationWindow();
23912};
23913ASPx.CVExpandGroupRow = function(name, visibleIndex, event) {
23914 var gv = ASPx.GetControlCollection().Get(name);
23915 if(gv != null) {
23916  if(gv.useEndlessPaging && event)
23917   visibleIndex = gv.FindParentRowVisibleIndex(ASPx.Evt.GetEventSource(event), true);
23918  gv.ExpandGroupRow(visibleIndex);
23919 }
23920};
23921ASPx.CVCollapseGroupRow = function(name, visibleIndex, event) {
23922 var gv = ASPx.GetControlCollection().Get(name);
23923 if(gv != null) {
23924  if(gv.useEndlessPaging && event)
23925   visibleIndex = gv.FindParentRowVisibleIndex(ASPx.Evt.GetEventSource(event), true);
23926  gv.CollapseGroupRow(visibleIndex);
23927 }
23928};
23929ASPx.GVGroupSelectorValueChanged = function(name) {
23930 var cv = ASPx.GetControlCollection().Get(name);
23931 if(cv != null) {
23932  cv.OnGroupSelectorValueChanged();
23933 }
23934};
23935var ASPxClientCardViewBatchEditApi = ASPx.CreateClass(ASPxClientGridBatchEditApi, {
23936 constructor: function(grid) {
23937  this.constructor.prototype.constructor.call(this, grid);
23938 },
23939 ValidateCards: function(validateOnlyModified) { return this.ValidateItems(validateOnlyModified); },
23940 ValidateCard: function(visibleIndex) { return this.ValidateItem(visibleIndex); },
23941 GetCardVisibleIndices: function(includeDeleted) { return this.GetItemVisibleIndices(includeDeleted); },
23942 GetDeletedCardIndices: function() { return this.GetDeletedItemVisibleIndices(); },
23943 GetInsertedCardIndices: function() { return this.GetInsertedItemVisibleIndices(); },
23944 GetUpdatedCardIndices: function() { return this.GetUpdatedItemVisibleIndices(); },
23945 IsDeletedCard: function(visibleIndex) { return this.IsDeletedItem(visibleIndex); },
23946 IsNewCard: function(visibleIndex) { return this.IsNewItem(visibleIndex); },
23947 AddNewCard: function() { this.AddNewItem(); },
23948 DeleteCard: function(visibleIndex) { this.DeleteItem(visibleIndex); },
23949 DeleteCardByKey: function(key) { this.DeleteItemByKey(key); },
23950 RecoverCard: function(visibleIndex) { this.RecoverItem(visibleIndex); },
23951 RecoverCardByKey: function(key) { this.RecoverItemByKey(key); },
23952 GetFocusedCell: function() { return this.grid.GetFocusedCell(); },
23953 SetFocusedCell: function(cardVisibleIndex, columnIndex) { this.grid.SetFocusedCell(cardVisibleIndex, columnIndex); }
23954});
23955var ASPxClientCardViewCellInfo = ASPx.CreateClass(ASPxClientGridCellInfo, {
23956 constructor: function(visibleIndex, column) {
23957  this.constructor.prototype.constructor.call(this, visibleIndex, column);
23958  this.cardVisibleIndex = this.itemVisibleIndex;
23959 }
23960});
23961var ASPxClientCardViewCallbackCommand = {
23962 GroupBySelectorValue: "GROUPBYSELECTORVALUE"
23963};
23964window.ASPxClientCardView = ASPxClientCardView;
23965window.ASPxClientCardViewColumn = ASPxClientCardViewColumn;
23966window.ASPxClientCardViewColumnCancelEventArgs = ASPxClientCardViewColumnCancelEventArgs;
23967window.ASPxClientCardViewCardClickEventArgs = ASPxClientCardViewCardClickEventArgs;
23968window.ASPxClientCardViewGroupCancelEventArgs = ASPxClientCardViewGroupCancelEventArgs;
23969window.ASPxClientCardViewCustomButtonEventArgs = ASPxClientCardViewCustomButtonEventArgs;
23970window.ASPxClientCardViewSelectionEventArgs = ASPxClientCardViewSelectionEventArgs;
23971window.ASPxClientCardViewBatchEditStartEditingEventArgs = ASPxClientCardViewBatchEditStartEditingEventArgs;
23972window.ASPxClientCardViewBatchEditEndEditingEventArgs = ASPxClientCardViewBatchEditEndEditingEventArgs;
23973window.ASPxClientCardViewBatchEditCardChangesCancelingEventArgs = ASPxClientCardViewBatchEditCardChangesCancelingEventArgs;
23974window.ASPxClientCardViewBatchEditCardValidatingEventArgs = ASPxClientCardViewBatchEditCardValidatingEventArgs;
23975window.ASPxClientCardViewBatchEditConfirmShowingEventArgs = ASPxClientCardViewBatchEditConfirmShowingEventArgs;
23976window.ASPxClientCardViewBatchEditTemplateCellFocusedEventArgs = ASPxClientCardViewBatchEditTemplateCellFocusedEventArgs;
23977window.ASPxClientCardViewBatchEditChangesSavingEventArgs = ASPxClientCardViewBatchEditChangesSavingEventArgs;
23978window.ASPxClientCardViewBatchEditChangesCancelingEventArgs = ASPxClientCardViewBatchEditChangesCancelingEventArgs;
23979window.ASPxClientCardViewBatchEditCardInsertingEventArgs = ASPxClientCardViewBatchEditCardInsertingEventArgs;
23980window.ASPxClientCardViewBatchEditCardDeletingEventArgs = ASPxClientCardViewBatchEditCardDeletingEventArgs;
23981window.ASPxClientCardViewBatchEditCardRecoveringEventArgs = ASPxClientCardViewBatchEditCardRecoveringEventArgs;
23982window.ASPxClientCardViewFocusedCellChangingEventArgs = ASPxClientCardViewFocusedCellChangingEventArgs;
23983window.ASPxClientCardViewBatchEditApi = ASPxClientCardViewBatchEditApi;
23984window.ASPxClientCardViewCellInfo = ASPxClientCardViewCellInfo;
23985window.ASPxClientCardViewCallbackCommand = ASPxClientCardViewCallbackCommand;
23986window.ASPxClientCardViewExportFormat = ASPx.ASPxClientGridExportFormat;
23987})();
23988
23989(function(dx) {
23990 var BootstrapClientCardView = ASPx.CreateClass(ASPxClientCardView, {
23991  constructor: function(name) {
23992   this.constructor.prototype.constructor.call(this, name);
23993   this.HeaderFilterButtonClassName = FILTER_BUTTON_CLASS;
23994   this.checkBoxImageProperties = {};
23995   this.accessibilityCompliant = true;
23996  },
23997  Initialize: function() {
23998   ASPxClientCardView.prototype.Initialize.call(this);
23999   this.attachHtmlHandlers();
24000  },
24001  InitializeAdjustment: function() {
24002   ASPxClientCardView.prototype.InitializeAdjustment.call(this);
24003   this.initializeCardImagesAdjustment();
24004  },
24005  attachHtmlHandlers: function() {
24006   this.attachHeaderHandlers();
24007   this.attachMainContentHandlers();
24008   this.attachDataItemHandlers();
24009  },
24010  detachHtmlHandlers: function() {
24011  },
24012  attachHeaderHandlers: function() {
24013   var columnCount = this.columns.length;
24014   for(var i = 0; i < columnCount; i++)
24015    this.attachHeaderHandler(this.columns[i]);
24016  },
24017  attachHeaderHandler: function(column) {
24018   var headerElement = this.GetHeader(column.index, false) || this.GetHeader(column.index, true);
24019   if(headerElement) this.attachHeaderHandlerOnElement(headerElement);
24020  },
24021  attachHeaderHandlerOnElement: function(headerElement) {
24022   ASPx.Evt.AttachEventToElement(headerElement, "mousedown", function(evt) {
24023    this.HeaderMouseDown(headerElement, evt);
24024   }.bind(this));
24025   var links = headerElement.querySelectorAll("a");
24026   for(var i = 0, link; link = links[i]; i++)
24027    link.ondragstart = function() { return false; };
24028   var sortElements = headerElement.querySelectorAll(SELECTORS.HEADER_SORT);
24029   for(var i = 0, sortEl; sortEl = sortElements[i]; i++)
24030    this.attachHeaderSortHandler(sortEl, headerElement);
24031  },
24032  attachHeaderSortHandler: function(el, headerElement) {
24033   ASPx.Evt.AttachEventToElement(el, "click", function(evt) {
24034    window.setTimeout(function() {
24035     if(this.contextMenuActivating) {
24036      this.contextMenuActivating = false;
24037      return;
24038     }
24039     if(!this.canSortByColumn(headerElement) || this.InRegularCallback())
24040      return;
24041     this.SortBy(this.getColumnIndex(headerElement.id), evt.ctrlKey ? "NONE" : "", !evt.shiftKey && !evt.ctrlKey);
24042    }.bind(this), 0);
24043    return ASPx.Evt.PreventEvent(evt);
24044   }.bind(this));
24045  },
24046  InitializeBubbleEvents: function() { },
24047  attachMainContentHandlers: function () {
24048   var mainTable = this.GetMainTable();
24049   ASPx.Evt.AttachEventToElement(mainTable, "click", function (evt) {
24050    if(this.NeedProcessTableClick(evt))
24051     this.mainTableClick(evt);
24052   }.bind(this), true);
24053   ASPx.Evt.AttachEventToElement(mainTable, "dblclick", function (evt) {
24054    if(this.NeedProcessTableClick(evt))
24055     this.mainTableDblClick(evt);
24056   }.bind(this), true);
24057  },
24058  attachDataItemHandlers: function() {
24059   if(!this.allowBatchEditing) return;
24060   var datachecks = this.GetMainElement().querySelectorAll(SELECTORS.BATCHEDIT_DATACHECK);
24061   for (var i = 0, check; check = datachecks[i]; i++) {
24062    if (!this.isCurrentCardViewElement(check)) continue;
24063    if (!check.disabled)
24064     this.attachDataCellCheckHandler(check);
24065   }
24066   var list = this.GetFocusableLayoutItemsList();
24067   for(var i = 0; i < this.pageRowCount; i++) {
24068    var rowIndex = i + this.visibleStartIndex;
24069    var row = this.GetDataItem(rowIndex);
24070    if(row) {
24071     for(var j = 0; j < list.length; j++) {
24072      var itemPath = list[j].path;
24073      var itemElement = this.GetFormLayoutItemCellByPath(rowIndex, itemPath);
24074      if(itemElement) {
24075       var dataElement = this.getDataElement(itemElement);
24076       if(dataElement) dataElement.tabIndex = 0;
24077      }
24078     }
24079    }
24080   }
24081   var batchEditHelperOwner = this.GetBatchEditHelperOwner();
24082   if(batchEditHelperOwner) {
24083    var etalonItem = batchEditHelperOwner.GetEtalonNewItem();
24084    if(etalonItem) {
24085     for(var j = 0; j < list.length; j++) {
24086      var itemPath = list[j].path;
24087      var itemElement = this.GetFormLayoutItemCellByPath(this.EtalonBatchRecordPostFix, itemPath);
24088      if(itemElement) {
24089       var dataElement = this.getDataElement(itemElement);
24090       if(dataElement) dataElement.tabIndex = 0;
24091      }
24092     }
24093    }
24094   }
24095  },
24096  attachDataCellCheckHandler: function (check) {
24097   ASPx.Evt.AttachEventToElement(check, "click", function (evt) {
24098    this.ProcessTableClick(evt, false);
24099   }.bind(this));
24100  },
24101  prepareBatchEditors: function() {
24102   var container = this.GetChildElement("DXBEsC");
24103   var editorsContainers = container.querySelectorAll("[data-dxci]");
24104   for(var i = editorsContainers.length - 1; i >= 0; i--) {
24105    editorsContainers[i].id = this.name + "_" + "DXBEC" + ASPx.Attr.GetAttribute(editorsContainers[i], "data-dxci");
24106   }
24107  },
24108  GetGridTD: function() {
24109   return this.GetMainElement();
24110  },
24111  GetMainTable: function() { 
24112   return ASPx.GetNodeByClassName(this.GetMainElement(), "dxbs-content");
24113  },
24114  IsMainTableChildElement: function(src) {
24115   if(!src) return true;
24116   return ASPx.GetIsParent(this.GetMainTable(), src);
24117  },
24118  GetFormLayoutItemCellByChild: function(element) { 
24119   var cell = ASPx.GetParentByClassName(element, "form-group");
24120   return cell ? cell.parentNode : null;
24121  },
24122  GetLoadingPanelElement: function(){
24123   return ASPx.BootstrapLoadingPanelManager.getLoadingPanel(this.name, this.loadingPanel);
24124  },
24125  GetLoadingDiv: function(){
24126   return ASPx.BootstrapLoadingPanelManager.getLoadingDiv(this.name, this.loadingPanel);
24127  },
24128  IsRecoverButton: function(button) {
24129   return ASPx.Attr.GetAttribute(button, "data-toggle") === DATA_TOGGLES.ROW_RECOVER;
24130  },
24131  getDataElement: function(itemElement){
24132   var element = ASPx.GetNodeByClassName(itemElement, ASPx.BootstrapCssSelectors.FormControlStatic);
24133   if(!element)
24134    element = ASPx.GetNodeByClassName(itemElement, "form-group");
24135   return element;
24136  },
24137  ShowLoadingPanelInsideHeaderFilterPopup: function() {
24138   var popup = this.GetHeaderFilterPopup();
24139   var container = popup.GetContentContainer(-1);
24140   var lp = ASPx.BootstrapLoadingPanelManager.getLoadingPanel(this.name + "_HF", this.loadingPanel, true);
24141   if(lp) {
24142    ASPx.Security.setInnerHtml(container, "", ASPx.Security.DataType.Trusted);
24143    container.appendChild(lp);
24144    popup.AfterSetWindowContentHtml(-1, container);
24145   }
24146  },
24147  CreateLoadingPanelInline: function(parentElement, centerInParent){
24148   var lp = ASPxClientGridView.prototype.CreateLoadingPanelInline.call(this, parentElement, centerInParent);
24149   if(lp) lp.style.opacity = 1;
24150  },
24151  ProcessFullCallbackResult: function(result) {
24152   this.needAttachHtmlHandler = true;
24153   this.detachHtmlHandlers();
24154   ASPxClientCardView.prototype.ProcessFullCallbackResult.call(this, result);
24155  },
24156  OnCallbackFinalized: function() {
24157   if(this.needAttachHtmlHandler) {
24158    this.needAttachHtmlHandler = false;
24159    this.attachHtmlHandlers();
24160   }
24161   this.calculateCardsHeight();
24162   this.initializeCardImagesAdjustment();
24163   ASPxClientCardView.prototype.OnCallbackFinalized.call(this);
24164  },
24165  allowRestoreFocusOnCallbacks: function(){
24166   return true;
24167  },
24168  OnPopupEditFormInit: function(popup) {
24169   popup.CloseUp.AddHandler(function(s, e) {
24170    if (e.closeReason === ASPxClientPopupControlCloseReason.Escape || e.closeReason === ASPxClientPopupControlCloseReason.CloseButton)
24171     this.ScheduleUserCommand(['CancelEdit', -1], false);
24172   }.bind(this));
24173   ASPxClientCardView.prototype.OnPopupEditFormInit.call(this, popup);
24174  },
24175  CreateBatchEditHelper: function() { return new ASPx.BootstrapCardViewBatchEditHelper(this.CreateBatchEditHelperOwner()); },
24176  CreateBatchEditHelperOwner: function() { return new ASPx.BootstrapCardViewBatchEditHelperOwner(this); },
24177  CreateCellFocusHelper: function() { return new ASPx.BootstrapCardViewCellFocusHelper(this); },
24178  CreateFilterHelper: function() { return new ASPx.BootstrapCardViewFilterHelper(this); },
24179  CreateCallbackHelper: function () { return new BootstrapCardViewCallbackHelper(this); },
24180  CreateToolbarHelper: function() { return new ASPx.BootstrapCardViewToolbarHelper(this); },
24181  CreateNavigationHelper: function() { 
24182   return typeof(ASPx.BootstrapCardViewNavigationHelper) != "undefined" ? new ASPx.BootstrapCardViewNavigationHelper(this) : null;
24183  },
24184  CreateStyleHelper: function() { return new BootstrapCardViewStyleHelper(this); },
24185  CreateEndlessPagingHelper: function() { return new ASPx.BootstrapCardViewEndlessPagingHelper(this); },
24186  ApplyItemStyle: function(visibleIndex, styleInfo) {
24187   var item = this.GetItem(visibleIndex);
24188   var cardContent = ASPx.GetChildByClassName(item, CARD_CLASS);
24189   this.ApplyElementStyle(cardContent || item, styleInfo);
24190  },
24191  CreateEditingErrorItem: function() {
24192   return document.createElement("div");
24193  },
24194  WrapErrorCard: function(card) {
24195   var errorContainer = document.createElement("DIV");
24196   ASPx.AddClassNameToElement(errorContainer, this.ErrorCardErrorContainerClassName);
24197   ASPx.AddClassNameToElement(errorContainer, ASPx.BootstrapCssSelectors.BackgroundDanger);
24198   var cardContent = ASPx.GetChildByClassName(card, ASPx.BootstrapCssSelectors.Panel);
24199   var cardBody = ASPx.GetChildByClassName(cardContent, ASPx.BootstrapCssSelectors.PanelBody);
24200   cardContent.insertBefore(errorContainer, cardBody);
24201  },
24202  PrepareCommandButtons: function() {
24203   var mainElement = this.GetMainElement();
24204   var buttons = mainElement.querySelectorAll("[data-toggle]");
24205   for(var btn, i = 0; btn = buttons[i]; i++) {
24206    var dataToggle = ASPx.Attr.GetAttribute(btn, "data-toggle");
24207    if(!COMMANDS[dataToggle] || !this.isCurrentCardViewElement(btn) || btn.hasHandler) continue;
24208    ASPx.Evt.AttachEventToElement(btn, "click", this.OnCommandButtonClick.bind(this, btn, dataToggle));
24209    btn.hasHandler = true;
24210   }
24211  },
24212  OnCommandButtonClick: function(btn, dataToggle) {
24213   if(this.accessibilityCompliant && ASPx.Attr.IsExistsAttribute(btn, ASPx.Attr.Aria.disabled))
24214    return;
24215   var commandInfo = COMMANDS[dataToggle];
24216   if(!commandInfo.hasIndex)
24217    this.ScheduleUserCommand([commandInfo.method], commandInfo.postponed, btn);
24218   else if (commandInfo.hasArgs) {
24219    var visibleIndex = this.tryFindParentCardIndex(btn);
24220    var args = ASPx.Attr.GetAttribute(btn, "data-args");
24221    this.ScheduleUserCommand([commandInfo.method, args, visibleIndex >= 0 ? visibleIndex : INT32_MINVALUE], commandInfo.postponed, btn);
24222   }
24223   else {
24224    var visibleIndex = this.tryFindParentCardIndex(btn);
24225    this.ScheduleUserCommand([commandInfo.method, visibleIndex >= 0 ? visibleIndex : INT32_MINVALUE], commandInfo.postponed, btn);
24226   }
24227  },
24228  IsCancelButton: function(button) {
24229   return ASPx.Attr.GetAttribute(button, "data-toggle") === "cardview-cancelchanges";
24230  },
24231  GetBatchEditCommandButtons: function() {
24232   var mainElement = this.GetMainElement();
24233   var buttons = mainElement.querySelectorAll(SELECTORS.BATCHEDIT_SAVECHANGES + "," + SELECTORS.BATCHEDIT_CANCELCHANGES + "," + SELECTORS.BATCHEDIT_UPDATESUMMARIES);
24234   var arr = [];
24235   for(var btn, i = 0; btn = buttons[i]; i++) {
24236    if(!this.isCurrentCardViewElement(btn)) continue;
24237    arr.push(btn);
24238   }
24239   return arr;
24240  },
24241  isCurrentCardViewElement: function(element) {
24242   return ASPx.GetParentByClassName(element, CARDVIEW_CLASS) === this.GetMainElement();
24243  },
24244  tryFindParentCardIndex: function(element) {
24245   var regEx = this.GetItemVisibleIndexRegExp();
24246   var cardEl = ASPx.GetParentByClassName(element, CARD_CLASS);
24247   if(cardEl) {
24248    var matches = regEx.exec(cardEl.parentNode.id);
24249    if(matches && matches.length == 3)
24250     return parseInt(matches[2]);
24251   }
24252   return -1;
24253  },
24254  isHeaderFilterButton: function(el) {
24255   return ASPx.Attr.GetAttribute(el, "data-toggle") === DATA_TOGGLES.FILTER_POPUP ||
24256    ASPx.Attr.GetAttribute(el.parentNode, "data-toggle") === DATA_TOGGLES.FILTER_POPUP;
24257  },
24258  CreateInternalCheckBoxCollection: function() {
24259   if(!this.internalCheckBoxCollection)
24260    this.internalCheckBoxCollection = new ASPx.BootstrapCheckBoxInternalCollection(true, false, false);
24261   this.CompleteInternalCheckBoxCollection();
24262  },
24263  IsNativeCheckBoxes: function() {
24264   return false;
24265  },
24266  IsCheckBoxDisabled: function(icbInputElement) {
24267   return false;
24268  },
24269  AddInternalCheckBoxToCollection: function(icbMainElement, visibleIndex, enabled) {
24270   var internalCheckBox = null;
24271   if(this.IsLastCallbackProcessedAsEndless())
24272    internalCheckBox = this.internalCheckBoxCollection.Get(icbMainElement.id);
24273   if(internalCheckBox && internalCheckBox.mainElement != icbMainElement) {
24274    this.internalCheckBoxCollection.Remove(icbMainElement.id);
24275    internalCheckBox = null;
24276   }
24277   if(!internalCheckBox) {
24278    internalCheckBox = this.internalCheckBoxCollection.Add(icbMainElement.id, icbMainElement);
24279    if(visibleIndex >= 0) {
24280     internalCheckBox.CheckedChanged.AddHandler(function(s, e) {
24281      var rowCheckBox = this.GetDataRowSelBtn(visibleIndex);
24282      if(this.allowSelectSingleRowOnly)
24283       this._selectAllSelBtn(false, rowCheckBox.id);
24284      if(!this.RaiseInternalCheckBoxClick(visibleIndex)) {
24285       this.ScheduleCommand(function() { this.SelectItem(visibleIndex, s.GetChecked()); }.bind(this), true);
24286       this.mainTableClickCore(e, true);
24287      }
24288     }.bind(this));
24289    }
24290    else {
24291     internalCheckBox.CheckedChanged.AddHandler(function(s, e) {
24292      this.ScheduleCommand(function() {
24293       var index = this.tryGetNumberFromEndOfString(s.mainElement.id).value;
24294       var columnSelectAllSettings = this.GetColumnSelectAllSettings(index);
24295       if(!columnSelectAllSettings)
24296        return;
24297       switch(columnSelectAllSettings.mode) {
24298        case 1:
24299         if(s.GetChecked())
24300          this.SelectAllRowsOnPage();
24301         else
24302          this.UnselectAllRowsOnPage();
24303         break;
24304        case 2:
24305         if(s.GetChecked())
24306          this.SelectItemsCore(null, true, true);
24307         else
24308          this.UnselectFilteredItemsCore(true);
24309         break;
24310       }
24311       this.UpdateSelectAllCheckboxesState();
24312      }.bind(this), true);
24313      this.mainTableClickCore(e, true);
24314     }.bind(this));
24315    }
24316   }
24317  },
24318  selectItemCheckbox: function(visibleIndex, checked) {
24319   var checkBox = this.GetDataRowSelBtn(visibleIndex);
24320   if(checkBox) {
24321    var internalCheckBox = this.internalCheckBoxCollection.Get(checkBox.id);
24322    if(internalCheckBox)
24323     internalCheckBox.SetValue(!!checked);
24324   }
24325  },
24326  GetDataRowSelBtn: function(index) {
24327   var item = this.GetItem(index);
24328   return item && item.querySelector(SELECTORS.ROW_SELECT_CHECKBOX);
24329  },
24330  calculateCardsHeight: function() {
24331   var cards = this.GetMainTable().querySelectorAll("." + CARD_CLASS + " > ." + ASPx.BootstrapCssSelectors.PanelBody);
24332   var height = 0;
24333   for(var i = 0; i < cards.length; i++)
24334    cards[i].style.height = "";
24335   for(var i = 0; i < cards.length; i++){
24336    if(cards[i].offsetHeight > height)
24337     height = cards[i].offsetHeight;
24338   }
24339   for(var i = 0; i < cards.length; i++)
24340    cards[i].style.height = height + "px";
24341  },
24342  initializeCardImagesAdjustment: function() {
24343   var images = this.GetMainTable().querySelectorAll("." + CARD_CLASS + " > ." + ASPx.BootstrapCssSelectors.PanelBody + " img");
24344   for(var i = 0; i < images.length; i++){ 
24345    if(!images[i].complete) 
24346     images[i].onload = function() { this.calculateCardsHeight(); }.bind(this);
24347   }
24348  },
24349  AdjustControlCore: function() {
24350   this.calculateCardsHeight();
24351   this.UpdateScrollableControls();
24352  },
24353  OnBrowserWindowResize: function(e) {
24354   this.AdjustControl();
24355  },
24356  BrowserWindowResizeSubscriber: function() {
24357   return true;
24358  },
24359  GetEditFormLayout: function() { return null; },
24360  GetEditFormLayoutItemByColumn: function(column) { return null; },
24361  GetEditFormLayoutItemOrGroup: function(name) { return null; }
24362 });
24363 BootstrapClientCardView.postponeInit = function(name, info) {
24364  var grid = ASPx.GetControlCollection().Get(name);
24365  if(grid) {
24366   if(grid.batchEditClientState)
24367    grid.batchEditClientState.extraCommandButtonsInfo = info.extraCommandButtonsInfo;
24368   grid.errorItemHtml = info.errorItemHtml;
24369   grid.EnsureRowKeys();
24370   grid.UpdateItemsStyle();
24371   if(grid.allowBatchEditing)
24372    grid.prepareBatchEditors();
24373  }
24374 };
24375 var BootstrapCardViewCallbackHelper = ASPx.CreateClass(ASPx.GridCallbackHelper, {
24376  ValidateCommand: function(command) {
24377   if(command === ASPxClientGridViewCallbackCommand.DeleteRow && !this.GetAllowDelete()) {
24378    console.error("Deleting is forbidden");
24379    return false;
24380   }
24381   if(command === ASPxClientGridViewCallbackCommand.StartEdit && !this.GetAllowEdit()) {
24382    console.error("Editing is forbidden");
24383    return false;
24384   }
24385   if(command === ASPxClientGridViewCallbackCommand.AddNewRow && !this.GetAllowInsert()) {
24386    console.error("Inserting is forbidden");
24387    return false;
24388   }
24389   return true;
24390  },
24391 });
24392 var BootstrapCardViewStyleHelper = ASPx.CreateClass(ASPx.GridStyleHelper, {
24393  GetStyleInfoCore: function(styleKey, keyPostFix) {
24394   var cssClasses = this.grid.cssClasses;
24395   switch(styleKey) {
24396    case this.SelectedItemKey:
24397     var selectedRowClassNames = [];
24398     selectedRowClassNames.push(ASPx.BootstrapCore.IsBootstrap3 ? "well" : "bg-light");
24399     if(cssClasses[CSS_CLASSES.SELECTED_CARD])
24400      selectedRowClassNames.push(cssClasses[CSS_CLASSES.SELECTED_CARD]);
24401     return { "className": selectedRowClassNames.join(" ").trim() };
24402    case this.FocusedItemKey:
24403     var defaultCss = ASPx.BootstrapCore.IsBootstrap3 ? "panel-primary" : "border-primary";
24404     return { "className": cssClasses[CSS_CLASSES.FOCUSED_CARD] || defaultCss };
24405    case this.BatchEditModifiedCellKey:
24406     return { "className": "dxbs-batch-changed bg-success" };
24407    case this.BatchEditDeletedItemKey:
24408     return { "className": "dxbs-batch-changed deleted text-muted bg-warning" };
24409   }
24410  }
24411 });
24412 var FILTER_BUTTON_CLASS = "dxbs-header-button",
24413  DATA_TOGGLES = {
24414   ROW_RECOVER: "cardview-card-recover",
24415   FILTER_POPUP: "cardview-column-filterpopup",
24416   DATACELL_CHECK: "cardview-datacell-batchcheck"
24417  },
24418  SELECTORS = {
24419   FILTER_OK: "[data-toggle='cardview-filter-ok']",
24420   FILTER_CANCEL: "[data-toggle='cardview-filter-cancel']",
24421   HEADER_FILTER: "[data-toggle='cardview-column-filterpopup']",
24422   HEADER_SORT: "[data-toggle='cardview-column-sort']",
24423   BATCHEDIT_SAVECHANGES: "[data-toggle='cardview-savechanges']",
24424   BATCHEDIT_CANCELCHANGES: "[data-toggle='cardview-cancelchanges']",
24425   BATCHEDIT_UPDATESUMMARIES: "[data-toggle='cardview-updatesummaries']",
24426   ROW_SELECT_CHECKBOX: "[data-toggle='cardview-card-selecteditor']",
24427   BATCHEDIT_DATACHECK: "[data-toggle='" + DATA_TOGGLES.DATACELL_CHECK + "'] input"
24428  },
24429  CARDVIEW_CLASS = "dxbs-cardview",
24430  CARD_CLASS = "dxbs-card",
24431  CSS_CLASSES = {
24432   ICON_ERROR_ITEM: "iei",
24433   SELECTED_CARD: "sc",
24434   FOCUSED_CARD: "fc"
24435  },
24436  COMMANDS = {
24437   "cardview-savechanges": { method: "UpdateEdit", postponed: false },
24438   "cardview-cancelchanges": { method: "CancelEdit", postponed: false, hasIndex: true },
24439   "cardview-updatesummaries": { method: "UpdateSummaries", postponed: false },
24440   "cardview-newcard": { method: "AddNew", postponed: true },
24441   "cardview-card-edit": { method: "StartEdit", postponed: true, hasIndex: true },
24442   "cardview-card-delete": { method: "Delete", postponed: true, hasIndex: true },
24443   "cardview-card-custom": { method: "CustomButton", postponed: true, hasIndex: true, hasArgs: true },
24444   "cardview-card-recover": { method: "Recover", postponed: true, hasIndex: true },
24445   "cardview-card-select": { method: "Select", postponed: true, hasIndex: true },
24446   "cardview-card-selecteditor": {},
24447   "cardview-search-apply": { method: "ApplySearchFilter", postponed: false },
24448   "cardview-search-clear": { method: "ClearSearchFilter", postponed: false },
24449   "cardview-showmorecards": { method: "EndlessShowMore", postponed: false },
24450  },
24451  INT32_MINVALUE = -2147483647;
24452 dx.BootstrapClientCardView = BootstrapClientCardView;
24453 dx.BootstrapClientCardView.CONSTANTS = {
24454  CSS_CLASSES: CSS_CLASSES,
24455  COMMANDS: COMMANDS,
24456  CARDVIEW_CLASS: CARDVIEW_CLASS,
24457  CARD_CLASS: CARD_CLASS,
24458  DATA_TOGGLES: DATA_TOGGLES,
24459  SELECTORS: SELECTORS
24460 };
24461})(dx || (dx = {}));
24462
24463(function(dx) {
24464 var HEADER_FILTER_LIST_CLASS = "hf-list";
24465 var BootstrapCardViewFilterHelper = ASPx.CreateClass(ASPx.GridFilterHelper, {
24466  InitializeHeaderFilterPopup: function() {
24467   ASPx.GridFilterHelper.prototype.InitializeHeaderFilterPopup.call(this);
24468   var popup = this.GetHeaderFilterPopup();
24469   if(!popup)
24470    return;
24471   popup.PopUp.ClearHandlers();
24472   popup.Resize.ClearHandlers();
24473   popup.AfterResizing.AddHandler(this.OnHeaderFilter_AfterResizing.bind(this));
24474   popup.GetCurrentPopupElement = function () { return this.headerFilterPopupElement; }.bind(this);
24475   popup.getFirstFocusableElement = function () {
24476    if (ASPx.Browser.MacOSMobilePlatform || ASPx.Browser.AndroidMobilePlatform)
24477     return null;
24478    else
24479     return ASPxClientPopupControl.prototype.getFirstFocusableElement.call(this);
24480   };
24481   this.initializeFooterButtons(popup);
24482  },
24483  InitializeListBox: function(column) {
24484   var columnIndex = column.index;
24485   var listBox = this.GetListBox(columnIndex);
24486   if(!listBox) return;
24487   ASPx.GridFilterHelper.prototype.InitializeListBox.call(this, column);
24488   if(ASPx.IsFunction(listBox.RemoveShowHideFilterCssRules))
24489    listBox.RemoveShowHideFilterCssRules();
24490   var popup = this.GetHeaderFilterPopup();
24491   this.correctPopupHeight(popup, columnIndex);
24492   this.EnsureHeaderFilterPopupDefaultSize(popup);
24493   listBox.ResetControlAdjustment();
24494   listBox.AdjustControl();
24495  },
24496  initializeFooterButtons: function(popup) {
24497   var okButton = this.GetHeaderFilterButton(false);
24498   var cancelButton = this.GetHeaderFilterButton(true);
24499   if(okButton && cancelButton)
24500    ASPx.Evt.AttachEventToElement(okButton, "click", this.ApplyHeaderFilter.bind(this));
24501   if(cancelButton)
24502    ASPx.Evt.AttachEventToElement(cancelButton, "click", popup.Hide.bind(popup));
24503  },
24504  InitializeHeaderFilterButtons: function() {
24505   var popup = this.GetHeaderFilterPopup();
24506   var buttons = this.GetHeaderFilterButtons();
24507   for(var i = 0; i < buttons.length; i++) {
24508    this.initHeaderFilterButton(buttons[i], popup);
24509   }
24510  },
24511  initHeaderFilterButton: function(button, popup) {
24512   ASPx.Evt.AttachEventToElement(button, "click", function(evt) {
24513    popup.Hide();
24514    this.headerFilterPopupElement = button;
24515    popup.ShowAtElement(button);
24516    this.OnPopUpHeaderFilter(popup, button, evt);
24517   }.bind(this));
24518  },
24519  PopulateHeaderFilterButtons: function(container, buttons) {
24520   if(!container) return;
24521   var nodeList = container.querySelectorAll(dx.BootstrapClientCardView.CONSTANTS.SELECTORS.HEADER_FILTER);
24522   for(var i = 0, btn; btn = nodeList[i]; i++)
24523    buttons.push(btn);
24524  },
24525  OnPopUpHeaderFilter: function(popup, popupElement, evt) {
24526   var columnIndex = this.FindColumnIndexByHeaderChild(popupElement);
24527   var column = this.GetColumn(columnIndex);
24528   if(!column) return;
24529   var callbackWaiting = this.LoadHeaderFilterPopupData(popup, column, evt.shiftKey);
24530   if(callbackWaiting) {
24531    this.SetHFButtonPanelVisibility(popup, column.HFMode !== ASPx.GridHeaderFilterMode.List);
24532    this.grid.ShowLoadingPanelInsideHeaderFilterPopup();
24533    var popupHeader = popup.GetWindowHeaderElement(-1);
24534    if(!ASPx.ElementHasCssClass(popupHeader, ASPx.BootstrapCssSelectors.Hidden)) {
24535     var height = popup.GetHeight();
24536     if(!popup.cpPreventHideHeader)
24537      ASPx.AddClassNameToElement(popupHeader, ASPx.BootstrapCssSelectors.Hidden);
24538     this.setPopupHeight(popup, height);
24539    }
24540   }
24541  },
24542  OnHeaderFilter_AfterResizing: function(popup) {
24543   var column = this.GetHeaderFilterPopupRelatedColumn();
24544   if(column) {
24545    var columnIndex = column.index;
24546    if(!this.inSetHeight)
24547     this.SetHeaderFilterPopupSize(columnIndex, popup.GetWidth(), popup.GetHeight());
24548    var listBox = this.GetListBox(columnIndex);
24549    if(listBox)
24550     listBox.SetHeight("100%");
24551   }
24552  },
24553  SetHFButtonPanelVisibility: function(popup, visible) {
24554   var popupFooter = popup.GetWindowFooterElement(-1);
24555   if(popupFooter) {
24556    var height = popup.GetHeight();
24557    if(visible)
24558     ASPx.RemoveClassNameFromElement(popupFooter, ASPx.BootstrapCssSelectors.Hidden);
24559    else
24560     ASPx.AddClassNameToElement(popupFooter, ASPx.BootstrapCssSelectors.Hidden);
24561    this.SetHFOkButtonEnabled(false);
24562    this.setPopupHeight(popup, height);
24563   }
24564  },
24565  SetHFOkButtonEnabled: function(enabled) {
24566   var button = this.GetHeaderFilterButton(false);
24567   if(button)
24568    button.disabled = !enabled;
24569  },
24570  GetHeaderFilterButton: function(isCancelButton) {
24571   var popup = this.GetHeaderFilterPopup();
24572   if(popup)
24573    return popup.GetMainElement().querySelectorAll(isCancelButton ? 
24574     dx.BootstrapClientCardView.CONSTANTS.SELECTORS.FILTER_CANCEL : 
24575     dx.BootstrapClientCardView.CONSTANTS.SELECTORS.FILTER_OK)[0];
24576  },
24577  SetHeaderFilterPopupHtml: function(htmlObj, columnIndex) {
24578   var popup = this.GetHeaderFilterPopup();
24579   var popupHeader = popup.GetWindowHeaderElement(-1);
24580   var column = this.GetColumn(columnIndex);
24581   if(!column) return;
24582   if((column.HFMode === ASPx.GridHeaderFilterMode.List) || column.HFMode === ASPx.GridHeaderFilterMode.CheckedList)
24583    ASPx.AddClassNameToElement(popup.GetMainElement(), HEADER_FILTER_LIST_CLASS);
24584   else
24585    ASPx.RemoveClassNameFromElement(popup.GetMainElement(), HEADER_FILTER_LIST_CLASS);
24586   var isDateRangeHeaderFilter = column.HFMode === ASPx.GridHeaderFilterMode.DateRangePicker && !!htmlObj[0];
24587   if(isDateRangeHeaderFilter) {
24588    ASPx.RemoveClassNameFromElement(popupHeader, ASPx.BootstrapCssSelectors.Hidden);
24589    popupHeader.savedInnerHTML = popupHeader.innerHTML;
24590    ASPx.Security.setInnerHtml(popupHeader, htmlObj[0], ASPx.Security.DataType.Trusted);
24591   }
24592   else {
24593    if(popupHeader.savedInnerHTML) {
24594     ASPx.Security.setInnerHtml(popupHeader, popupHeader.savedInnerHTML, ASPx.Security.DataType.Trusted);
24595     popup.AssignHeaderButtonsEvents(-1);
24596     popupHeader.savedInnerHTML = null;
24597    }
24598   }
24599   ASPx.GridFilterHelper.prototype.SetHeaderFilterPopupHtml.call(this, htmlObj[1], columnIndex);
24600   this.correctPopupHeight(popup, columnIndex);
24601   if(isDateRangeHeaderFilter)
24602    this.EnsureHeaderFilterPopupDefaultSize(popup);
24603  },
24604  EnsureHeaderFilterPopupDefaultSize: function(popup) {
24605   if(!this.headerFilterPopupDimensions["Default"])
24606    this.SetHeaderFilterPopupSize("Default", popup.GetWidth(), popup.GetHeight());
24607  },
24608  correctPopupHeight: function(popup, columnIndex) {
24609   var popupSize = this.headerFilterPopupDimensions[columnIndex] || this.headerFilterPopupDimensions["Default"];
24610   if(popupSize || !popup.cpInitialHeight || popup.GetAdaptiveModalMode(-1)) {
24611    if(popupSize)
24612     popup.SetSize(popupSize[0], popupSize[1]);
24613    return;
24614   }
24615   popup.height = 0;
24616   popup.ResetWindowCachedSize(-1);
24617   popup.SetClientWindowSizeCoreLite(-1, popup.GetWidth(), 0);
24618   var height = popup.GetHeight();
24619   var actualHeight = (height < popup.cpInitialHeight) ? height : popup.cpInitialHeight;
24620   this.setPopupHeight(popup, actualHeight);
24621  },
24622  setPopupHeight: function(popup, height) {
24623   this.inSetHeight = true;
24624   popup.SetHeight(height);
24625   this.inSetHeight = false;
24626  },
24627  IsCancelButtonEventSource: function(evt) {
24628   return ASPx.GetIsParent(this.GetHeaderFilterButton(true), ASPx.Evt.GetEventSource(evt));
24629  },
24630  AdjustRangePicker: function(editor_From, editor_To) { },
24631  AdjustHeaderFilterListBox: function(column) { },
24632  PrepareSeparators: function(listBox) {
24633   if(this.IsASPxClientListBox(listBox))
24634    BootstrapGridHFListBoxWrapper.Initialize(listBox);
24635   for(var i = 0; i < listBox.cpFSI.length; i++) {
24636    var separatorIndex = listBox.cpFSI[i];
24637    var item = listBox.GetItemElement(separatorIndex);
24638    if(ASPx.IsExists(item)) {
24639     var tr = ASPx.GetParentByTagName(item, "TR");
24640     this.AppendSeparatorRow(tr);
24641    }
24642   }
24643  }
24644 });
24645 ASPx.BootstrapCardViewFilterHelper = BootstrapCardViewFilterHelper;
24646})(dx || (dx = {}));
24647
24648(function() {
24649var BootstrapCardViewToolbarHelper = ASPx.CreateClass(ASPx.CardViewToolbarHelper, {
24650 UpdateItemBadge: function(item, count) {
24651  ASPx.BootstrapBadgeManager.updateToolbarItemBadge(item, count);
24652 }
24653});
24654ASPx.BootstrapCardViewToolbarHelper = BootstrapCardViewToolbarHelper;
24655})();
24656(function(dx) {
24657 var BootstrapCardViewEndlessPagingHelper = ASPx.CreateClass(ASPx.CardViewEndlessPagingHelper, {
24658  constructor: function(grid){
24659   this.constructor.prototype.constructor.call(this, grid);
24660  },
24661  IsFlowLayout: function(){
24662   return true;
24663  },
24664  IsBreakpointsLayout: function() {
24665   return false;
24666  },
24667  IsTableLayout: function() {
24668   return false;
24669  },
24670  GetItemsContainer: function() {
24671   return this.grid.GetMainTable();
24672  },
24673  GetItemElements: function() {
24674   var container = this.GetItemsContainer();
24675   return ASPx.GetChildNodesByTagName(container, "DIV");
24676  },
24677 });
24678 ASPx.BootstrapCardViewEndlessPagingHelper = BootstrapCardViewEndlessPagingHelper;
24679})(dx || (dx = {}));
24680(function() {
24681var ASPxClientEditBase = ASPx.CreateClass(ASPxClientControl, {
24682 constructor: function(name) {
24683  this.constructor.prototype.constructor.call(this, name);
24684  this.EnabledChanged = new ASPxClientEvent();
24685  this.captionPosition = ASPx.Position.Left;
24686  this.showCaptionColon = true;
24687  this.scPrefix = "dxe";
24688 },
24689 InlineInitialize: function(){
24690  ASPxClientControl.prototype.InlineInitialize.call(this);
24691  this.InitializeEnabled(); 
24692  this.InitializeEvents();
24693 },
24694 InitializeEnabled: function() {
24695  this.SetEnabledInternal(this.clientEnabled, true);
24696 },
24697 InitializeEvents: function() { },
24698 AddDefaultReadOnlyStateControllerItem: function(cssClass, mainElementId) {
24699  ASPx.AddReadOnlyItems(mainElementId, [[[cssClass], [''], ['']]]);
24700 },
24701 AddDefaultDisabledStateControllerItem: function(cssClass, mainElementId) {
24702  ASPx.AddDisabledItems(mainElementId, [[[cssClass], [''], ['']]]);
24703 },
24704 GetValue: function() {
24705  var element = this.GetMainElement();
24706  if(ASPx.IsExistsElement(element))
24707   return element.innerHTML;
24708  return "";
24709 },
24710 GetValueString: function(){
24711  var value = this.GetValue();
24712  return (value == null) ? null : value.toString();
24713 },
24714 EnsureValueStringIsActual: function() {
24715  if(this.maskInfo != null)
24716   this.ParseValue();
24717 },
24718 SetValue: function(value) {
24719  if(value == null)
24720   value = "";
24721  var element = this.GetMainElement();
24722  if(ASPx.IsExistsElement(element))
24723   element.innerHTML = value;
24724 },
24725 GetEnabled: function(){
24726  return this.enabled && this.clientEnabled;
24727 },
24728 SetEnabled: function(enabled){
24729  if(this.clientEnabled != enabled) {
24730   var errorFrameRequiresUpdate = this.GetIsValid && !this.GetIsValid();
24731   if(errorFrameRequiresUpdate && !enabled)
24732    this.UpdateErrorFrameAndFocus(false , null , true );
24733   this.clientEnabled = enabled;
24734   this.SetEnabledInternal(enabled, false);
24735   if(errorFrameRequiresUpdate && enabled)
24736    this.UpdateErrorFrameAndFocus(false );
24737   this.RaiseEnabledChangedEvent();
24738  }
24739 },
24740 SetEnabledInternal: function(enabled, initialization){
24741  if(!this.enabled) return;
24742  if(!initialization || !enabled)
24743   this.ChangeEnabledStateItems(enabled);
24744  this.ChangeEnabledAttributes(enabled);
24745  if(ASPx.Browser.Chrome) {   
24746   var mainElement = this.GetMainElement();
24747   if(mainElement)
24748    mainElement.className = mainElement.className;
24749  } 
24750 },
24751 ChangeEnabledAttributes: function(enabled){
24752 },
24753 ChangeEnabledStateItems: function(enabled){
24754 },
24755 RaiseEnabledChangedEvent: function(){
24756  if(!this.EnabledChanged.IsEmpty()){
24757   var args = new ASPxClientEventArgs();
24758   this.EnabledChanged.FireEvent(this, args);
24759  }
24760 },
24761 GetDecodeValue: function (value) { 
24762  if(typeof (value) == "string" && value.length > 1)
24763   value = this.SimpleDecodeHtml(value);
24764  return value;
24765 },
24766 SimpleDecodeHtml: function (html) {
24767  return ASPx.Str.ApplyReplacement(html, [
24768   [/&lt;/g, '<'],
24769   [/&amp;/g, '&'],
24770   [/&quot;/g, '"'],
24771   [/&#39;/g, '\''],
24772   [/&#32;/g, ' ']
24773  ]);
24774 },
24775 GetCachedElementById: function(idSuffix) {
24776  return ASPx.CacheHelper.GetCachedElementById(this, this.name + idSuffix);
24777 },
24778 GetCaptionCell: function() {
24779  return this.GetCachedElementById(EditElementSuffix.CaptionCell);
24780 },
24781 GetExternalTable: function() {
24782  return this.GetCachedElementById(EditElementSuffix.ExternalTable);
24783 },
24784 getCaptionRelatedCellCount: function() {
24785  if(!this.captionRelatedCellCount)
24786   this.captionRelatedCellCount = ASPx.GetNodesByClassName(this.GetExternalTable(), CaptionRelatedCellClassName).length;
24787  return this.captionRelatedCellCount;
24788 },
24789 addCssClassToCaptionRelatedCells: function() {
24790  if(this.captionPosition == ASPx.Position.Left || this.captionPosition == ASPx.Position.Right) {
24791   var captionRelatedCellsIndex = this.captionPosition == ASPx.Position.Left ? 0 : this.GetCaptionCell().cellIndex;
24792   for(var i = 0; i < this.GetExternalTable().rows.length; i++)
24793    ASPx.AddClassNameToElement(this.GetExternalTable().rows[i].cells[captionRelatedCellsIndex], CaptionRelatedCellClassName);
24794  }
24795  if(this.captionPosition == ASPx.Position.Top || this.captionPosition == ASPx.Position.Bottom)
24796   for(var i = 0; i < this.GetCaptionCell().parentNode.cells.length; i++)
24797    ASPx.AddClassNameToElement(this.GetCaptionCell().parentNode.cells[i], CaptionRelatedCellClassName);
24798 },
24799 GetCaption: function() {
24800  if(ASPx.IsExists(this.GetCaptionCell()))
24801   return this.getCaptionInternal();
24802  return "";
24803 },
24804 SetCaption: function(caption) {
24805  if(!ASPx.IsExists(this.GetCaptionCell()))
24806   return;
24807  if(this.getCaptionRelatedCellCount() == 0)
24808   this.addCssClassToCaptionRelatedCells();
24809  if(caption !== "")
24810   ASPx.RemoveClassNameFromElement(this.GetExternalTable(), ASPxEditExternalTableClassNames.TableWithEmptyCaptionClassName);
24811  else
24812   ASPx.AddClassNameToElement(this.GetExternalTable(), ASPxEditExternalTableClassNames.TableWithEmptyCaptionClassName);
24813  this.setCaptionInternal(caption);
24814 },
24815 getCaptionTextNode: function() {
24816  var captionElement = ASPx.GetNodesByPartialClassName(this.GetCaptionCell(), CaptionElementPartialClassName)[0];
24817  return ASPx.GetNormalizedTextNode(captionElement);
24818 },
24819 getCaptionInternal: function() {
24820  var captionText = this.getCaptionTextNode().nodeValue;
24821  if(captionText !== "" && captionText[captionText.length - 1] == ":")
24822   captionText = captionText.substring(0, captionText.length - 1);
24823  return captionText;
24824 },
24825 setCaptionInternal: function(caption) {
24826  caption = ASPx.Str.Trim(caption);
24827  var captionTextNode = this.getCaptionTextNode();
24828  if(this.showCaptionColon && caption[caption.length - 1] != ":" && caption !== "")
24829   caption += ":";
24830  captionTextNode.nodeValue = caption;
24831 },
24832 onVirtualKeyboardUITouchStart: function(evt) { }
24833});
24834var ValidationPattern = ASPx.CreateClass(null, {
24835 constructor: function(errorText) {
24836  this.errorText = errorText;
24837 }
24838});
24839var RequiredFieldValidationPattern = ASPx.CreateClass(ValidationPattern, {
24840 constructor: function(errorText) {
24841  this.constructor.prototype.constructor.call(this, errorText);
24842 },
24843 EvaluateIsValid: function(value) {
24844  return value != null && (value.constructor == Array || ASPx.Str.Trim(value.toString()) != "");
24845 }
24846});
24847var RegularExpressionValidationPattern = ASPx.CreateClass(ValidationPattern, {
24848 constructor: function(errorText, pattern) {
24849  this.constructor.prototype.constructor.call(this, errorText);
24850  this.pattern = pattern;
24851 },
24852 EvaluateIsValid: function(value) {
24853  if(value == null) 
24854   return true;
24855  var strValue = value.toString();
24856  if(ASPx.Str.Trim(strValue).length == 0)
24857   return true;
24858  var regEx = new RegExp(this.pattern);
24859  var matches = regEx.exec(strValue);
24860  return matches != null && strValue == matches[0];
24861 }
24862});
24863function _aspxIsEditorFocusable(inputElement) {
24864 return ASPx.IsFocusableCore(inputElement, function(container) {
24865  return container.getAttribute("errorFrame") == "errorFrame";
24866 });
24867}
24868var invalidEditorToBeFocused = null;
24869var ValidationType = {
24870 PersonalOnValueChanged: "ValueChanged",
24871 PersonalViaScript: "CalledViaScript",
24872 MassValidation: "MassValidation"
24873};
24874var ErrorFrameDisplay = {
24875 None: "None",
24876 Static: "Static",
24877 Dynamic: "Dynamic"
24878};
24879var EditElementSuffix = {
24880 ExternalTable: "_ET",
24881 ControlCell: "_CC",
24882 ErrorCell: "_EC",
24883 ErrorTextCell: "_ETC",
24884 ErrorImage: "_EI",
24885 CaptionCell: "_CapC",
24886 AccessibilityAdditionalTextRow: "_AHTR"
24887};
24888var ASPxEditExternalTableClassNames = {
24889 ValidStaticTableClassName: "dxeValidStEditorTable",
24890 ValidDynamicTableClassName: "dxeValidDynEditorTable",
24891 TableWithEmptyCaptionClassName: "tableWithEmptyCaption"
24892};
24893var CaptionRelatedCellClassName = "dxeCaptionRelatedCell";
24894var CaptionElementPartialClassName = "dxeCaption";
24895var AccessibilityAssistantID = "AcAs";
24896var ASPxClientEdit = ASPx.CreateClass(ASPxClientEditBase, {
24897 constructor: function(name) {
24898  this.constructor.prototype.constructor.call(this, name);
24899  this.isASPxClientEdit = true;
24900  this.inputElement = null;
24901  this.convertEmptyStringToNull = true;
24902  this.readOnly = false;
24903  this.clientReadOnly = false;
24904  this.focused = false;
24905  this.focusEventsLocked = false;
24906  this.focusEventsLockCount = 0;
24907  this.receiveGlobalMouseWheel = true;
24908  this.styleDecoration = null;
24909  this.heightCorrectionRequired = false;
24910  this.customValidationEnabled = false;
24911  this.display = ErrorFrameDisplay.Static;
24912  this.initialErrorText = "";
24913  this.causesValidation = false;
24914  this.validateOnLeave = true;
24915  this.validationGroup = "";
24916  this.sendPostBackWithValidation = null;
24917  this.validationPatterns = [];
24918  this.setFocusOnError = false;
24919  this.errorDisplayMode = "it";
24920  this.errorText = "";
24921  this.isValid = true;
24922  this.errorImageIsAssigned = false;
24923  this.notifyValidationSummariesToAcceptNewError = false;
24924  this.isErrorFrameRequired = false;
24925  this.enterProcessed = false;
24926  this.keyDownHandlers = {};
24927  this.keyPressHandlers = {};
24928  this.keyUpHandlers = {};
24929  this.onKeyDownHandler = null;
24930  this.onKeyPressHandler = null;
24931  this.onKeyUpHandler = null;
24932  this.onGotFocusHandler = null;
24933  this.onLostFocusHandler = null;
24934  this.GotFocus = new ASPxClientEvent();
24935  this.LostFocus = new ASPxClientEvent();
24936  this.Validation = new ASPxClientEvent();
24937  this.ValueChanged = new ASPxClientEvent();
24938  this.KeyDown = new ASPxClientEvent();
24939  this.KeyPress = new ASPxClientEvent();
24940  this.KeyUp = new ASPxClientEvent();
24941  this.eventHandlersInitialized = false;
24942  this.errorCellVisibilityChanged = new ASPxClientEvent();
24943  this.ariaExplanatoryTextManager = null;
24944  this.InitializeEventHandlers();
24945 },
24946 SetData: function(data){
24947  if(data.decorationStyles){
24948   for(var i = 0; i < data.decorationStyles.length; i++)
24949    this.AddDecorationStyle(data.decorationStyles[i].key, 
24950     data.decorationStyles[i].className, 
24951     data.decorationStyles[i].cssText);
24952  }
24953 },
24954 Initialize: function() {
24955  this.initialErrorText = this.errorText;
24956  ASPxClientEditBase.prototype.Initialize.call(this);
24957  this.InitializeKeyHandlers();
24958  this.UpdateClientValidationState();
24959  this.UpdateValidationSummaries(null , true );
24960 },
24961 InlineInitialize: function() {
24962  if(this.UseDelayedSpecialFocus())
24963   this.InitializeDelayedSpecialFocus();
24964  ASPxClientEditBase.prototype.InlineInitialize.call(this);
24965  this.UpdateStyleDecorations();
24966  var externalTable = this.GetExternalTable();
24967  if(externalTable && ASPx.IsPercentageSize(externalTable.style.width)) {
24968   this.width = "100%";
24969   this.GetMainElement().style.width = "100%";
24970   if(this.isErrorFrameRequired)
24971    externalTable.setAttribute("errorFrame", "errorFrame");
24972  }
24973  this.ariaExplanatoryTextManager = this.CreateAriaExplanatoryTextManager();
24974  if(this.clientReadOnly)
24975   this.SetReadOnlyInternal(true);
24976  this.UpdateErrorCellParentRowVisibility();
24977 }, 
24978 AfterInitialize: function() {
24979  this.ariaExplanatoryTextManager.SetCaptionAssociating();
24980  this.ariaExplanatoryTextManager.UpdateText();
24981  this.ariaExplanatoryTextManager.UpdateValidationState();
24982  ASPxClientEditBase.prototype.AfterInitialize.call(this);
24983 },
24984 UpdateStyleDecorations: function() {
24985  if(this.styleDecoration)
24986   this.styleDecoration.Update();
24987 },
24988 UseSpecialKeyboardHandling: function() {
24989  return false;
24990 },
24991 InitializeKeyHandlers: function() {
24992 },
24993 AddKeyDownHandler: function(key, handler) {
24994  this.keyDownHandlers[key] = handler;
24995 },
24996 AddKeyPressHandler: function(key, handler) {
24997  this.keyPressHandlers[key] = handler;
24998 },
24999 InitializeEventHandlers: function() {
25000  this.onGotFocusHandler = function(evt) { ASPx.EGotFocus(this.name); }.bind(this);
25001  this.onLostFocusHandler = function(evt) { ASPx.ELostFocus(this.name); }.bind(this);
25002  if(this.UseSpecialKeyboardHandling()) {
25003   this.onKeyDownHandler = function(evt) { ASPx.KBSIKeyDown(this.name, evt); }.bind(this);
25004   this.onKeyPressHandler = function(evt) { ASPx.KBSIKeyPress(this.name, evt); }.bind(this);
25005   this.onKeyUpHandler = function(evt) { ASPx.KBSIKeyUp(this.name, evt); }.bind(this);
25006  }
25007 },
25008 ChangeSpecialInputEnabledAttributes: function(element, method, doNotChangeAutoComplete) {
25009  if(!doNotChangeAutoComplete) 
25010   element.autocomplete = "off";
25011  if(this.onKeyDownHandler != null)
25012   method(element, "keydown", this.onKeyDownHandler);
25013  if(this.onKeyPressHandler != null)
25014   method(element, "keypress", this.onKeyPressHandler);
25015  if(this.onKeyUpHandler != null)
25016   method(element, "keyup", this.onKeyUpHandler);
25017  if(this.onGotFocusHandler != null)
25018   method(element, "focus", this.onGotFocusHandler);
25019  if(this.onLostFocusHandler != null)
25020   method(element, "blur", this.onLostFocusHandler);
25021 },
25022 CreateAriaExplanatoryTextManager: function() {
25023  if(this.accessibilityCompliant)
25024   return new EditAccessibilityExplanatoryTextManager(this);
25025  else 
25026   return new DisableAccessibilityExplanatoryTextManager(this);
25027 },
25028 UpdateClientValidationState: function() {
25029  if(!this.customValidationEnabled)
25030   return;
25031  var mainElement = this.GetMainElement();
25032  if(mainElement) {
25033   var validationState = !this.GetIsValid() ? ("-" + this.GetErrorText()) : "";
25034   this.UpdateStateObjectWithObject({ validationState: validationState });
25035  }
25036 },
25037 UpdateValidationSummaries: function(validationType, initializing) {
25038  if(ASPx.Ident.scripts.ASPxClientValidationSummary) {
25039   var summaryCollection = ASPx.GetClientValidationSummaryCollection();
25040   summaryCollection.OnEditorIsValidStateChanged(this, validationType, initializing && this.notifyValidationSummariesToAcceptNewError);
25041  }
25042 },
25043 FindInputElement: function(){
25044  return null;
25045 },
25046 GetInputElement: function(){
25047  if(!ASPx.IsExistsElement(this.inputElement))
25048   this.inputElement = this.FindInputElement();
25049  return this.inputElement;
25050 },
25051 GetFocusableInputElement: function() {
25052  return this.GetInputElement();
25053 },
25054 GetAccessibilityActiveElements: function() {
25055  return [this.GetInputElement()];
25056 },
25057 GetAccessibilityFirstActiveElement: function() {
25058  return this.accessibilityHelper ? 
25059    this.accessibilityHelper.getMainElement() : 
25060    this.GetAccessibilityActiveElements()[0];
25061 },
25062 GetAccessibilityAssistantElement: function() {
25063  return this.GetChildElement(AccessibilityAssistantID);
25064 },
25065 GetErrorImage: function() {
25066  return this.GetCachedElementById(EditElementSuffix.ErrorImage);
25067 },
25068 GetControlCell: function() {
25069  return this.GetCachedElementById(EditElementSuffix.ControlCell);
25070 },
25071 GetErrorCell: function() {
25072  return this.GetCachedElementById(EditElementSuffix.ErrorCell);
25073 },
25074 GetErrorTextCell: function() {
25075  return this.GetCachedElementById(this.errorImageIsAssigned ? EditElementSuffix.ErrorTextCell : EditElementSuffix.ErrorCell);
25076 },
25077 GetReadOnly: function() {
25078  return this.readOnly || this.clientReadOnly;
25079 },
25080 SetReadOnly: function(readOnly) {
25081  readOnly = !!readOnly;
25082  if(this.clientReadOnly === readOnly || this.readOnly)
25083   return;
25084  this.SetReadOnlyInternal(readOnly);
25085 },
25086 SetReadOnlyInternal: function(readOnly) {
25087  this.clientReadOnly = readOnly;
25088  this.ChangeReadOnlyStateItems(readOnly);
25089 },
25090 ChangeReadOnlyStateItems: function(readOnly) {
25091  ASPx.GetStateController().SetElementReadOnly(this.GetMainElement(), readOnly);
25092 },
25093 SetVisible: function (isVisible) {
25094  if(this.clientVisible == isVisible)
25095   return;
25096  var externalTable = this.GetExternalTable();
25097  if(externalTable) {
25098   ASPx.SetElementDisplay(externalTable, isVisible);
25099   if(this.customValidationEnabled) {
25100    var isValid = !isVisible ? true : void (0);
25101    this.UpdateErrorFrameAndFocus(false , true , isValid );
25102   }
25103  }
25104  ASPxClientControl.prototype.SetVisible.call(this, isVisible);
25105 },
25106 GetStateHiddenFieldName: function() {
25107  return this.uniqueID + "$State";
25108 },
25109 GetValueInputToValidate: function() {
25110  return this.GetInputElement();
25111 },
25112 IsVisible: function() {
25113  if(!this.clientVisible)
25114   return false;
25115  var element = this.GetMainElement();
25116  if(!element) 
25117   return false;
25118  while(element && element.tagName != "BODY") {
25119   if(element.getAttribute("errorFrame") != "errorFrame" && (!ASPx.GetElementVisibility(element) || !ASPx.GetElementDisplay(element)))
25120    return false;
25121   element = element.parentNode;
25122  }
25123  return true;
25124 },
25125 AdjustControlCore: function() {
25126  this.CollapseEditor();
25127  this.UnstretchInputElement();
25128  if(this.heightCorrectionRequired)
25129   this.CorrectEditorHeight();
25130 },
25131 CorrectEditorHeight: function() {
25132 },
25133 UnstretchInputElement: function() {
25134 },
25135 UseDelayedSpecialFocus: function() {
25136  return false;
25137 },
25138 GetInnerEditors: function() {
25139  return [];
25140 },
25141 GetDelayedSpecialFocusTriggers: function() {
25142  return [ this.GetMainElement() ];
25143 },
25144 InitializeDelayedSpecialFocus: function() {
25145  this.specialFocusTimer = -1;    
25146  var handler = function(evt) { this.OnDelayedSpecialFocusMouseDown(evt); }.aspxBind(this);
25147  var triggers = this.GetDelayedSpecialFocusTriggers();
25148  for(var i = 0; i < triggers.length; i++)
25149   ASPx.Evt.AttachEventToElement(triggers[i], "mousedown", handler);
25150 },
25151 OnDelayedSpecialFocusMouseDown: function(evt) {
25152  window.setTimeout(function() { this.SetFocus(); }.aspxBind(this), 0);
25153 },
25154 IsFocusEventsLocked: function() {
25155  return this.focusEventsLocked || this.focusEventsLockCount !== 0;
25156 },
25157 BeginFocusUpdate: function() {
25158  this.focusEventsLockCount++;
25159 },
25160 EndFocusUpdate: function() {
25161  this.focusEventsLockCount--;
25162  if(this.focusEventsLockCount === 0)
25163   if(this.focused && !this.IsEditorElement(document.activeElement)) 
25164    this.OnLostFocus();
25165 },
25166 LockFocusEvents: function() {
25167  if(!this.focused) return;
25168  this.focusEventsLocked = true;
25169 },
25170 UnlockFocusEvents: function() {
25171  this.focusEventsLocked = false;
25172 },
25173 ForceRefocusEditor: function(evt, isNativeFocus) {
25174  if(ASPx.Browser.VirtualKeyboardSupported && !this.ownerListBox) {
25175   var focusedEditor = ASPx.VirtualKeyboardUI.getFocusedEditor();
25176   if(ASPx.VirtualKeyboardUI.getInputNativeFocusLocked() && (!focusedEditor || focusedEditor === this))
25177     return;
25178   ASPx.VirtualKeyboardUI.setInputNativeFocusLocked(!isNativeFocus);
25179  }
25180  this.LockFocusEvents();
25181  this.BlurInputElement();
25182  window.setTimeout(function() { 
25183   if(ASPx.Browser.VirtualKeyboardSupported && !this.ownerListBox) {
25184    ASPx.VirtualKeyboardUI.setFocusToEditor(this);
25185   } else {
25186    this.SetFocus();
25187   }
25188  }.aspxBind(this), 0);
25189 },
25190 BlurInputElement: function() {
25191  var inputElement = this.GetFocusableInputElement();
25192  if(inputElement && inputElement.blur)
25193   inputElement.blur();
25194 },
25195 IsEditorElement: function(element) {
25196  return this.GetMainElement() == element || ASPx.GetIsParent(this.GetMainElement(), element);
25197 },
25198 IsClearButtonElement: function(element) {
25199  return false;
25200 },
25201 IsElementBelongToInputElement: function(element) {
25202  return this.GetInputElement() == element;
25203 },
25204 OnFocusCore: function() {
25205  if(this.UseDelayedSpecialFocus())
25206   this.specialFocusTimer = ASPx.Timer.ClearTimer(this.specialFocusTimer);
25207  if(!this.IsFocusEventsLocked()){
25208   this.focused = true;
25209   ASPx.SetFocusedEditor(this);
25210   if(this.styleDecoration)
25211    this.styleDecoration.Update();
25212   if(this.isInitialized)
25213    this.RaiseFocus();
25214  }
25215  else
25216   this.UnlockFocusEvents();
25217 },
25218 OnLostFocusCore: function() {
25219  if(!this.IsFocusEventsLocked()){
25220   this.focused = false;
25221   if(ASPx.GetFocusedEditor() === this)
25222    ASPx.SetFocusedEditor(null);
25223   if(this.styleDecoration)
25224    this.styleDecoration.Update();
25225   this.RaiseLostFocus();
25226  }
25227 },
25228 OnFocus: function() {
25229  var focusedEditor = ASPx.GetFocusedEditor();
25230  if(focusedEditor && focusedEditor.UseDelayedSpecialFocus() && focusedEditor !== this && focusedEditor.GetInnerEditors().indexOf(this) === -1 && ASPx.IsElementVisible(focusedEditor.GetMainElement())) {
25231   var lostFocusHandler = function() {
25232    focusedEditor.LostFocus.RemoveHandler(lostFocusHandler);
25233    this.OnFocusCore();
25234   }.bind(this);
25235   focusedEditor.LostFocus.AddHandler(lostFocusHandler);
25236  }
25237  else {
25238   this.OnFocusCore();
25239  }  
25240 },
25241 OnLostFocus: function() {
25242  if(this.isInitialized)
25243   this.OnLostFocusCore();
25244 },
25245 OnMouseWheel: function(evt){
25246 },
25247 OnValidation: function(validationType) {
25248  if(this.customValidationEnabled && this.isInitialized && ASPx.IsExistsElement(this.GetMainElement()) &&
25249   (!this.IsErrorFrameDisplayed() || this.GetElementRequiredForErrorFrame())) {
25250   this.BeginErrorFrameUpdate();
25251   try {
25252    if(this.validateOnLeave || validationType != ValidationType.PersonalOnValueChanged) {
25253     this.SetIsValid(true, true );
25254     this.SetErrorText(this.initialErrorText, true );
25255     this.ValidateWithPatterns();
25256     this.RaiseValidation();
25257    }
25258    this.UpdateErrorFrameAndFocus(this.editorFocusingRequired(validationType));
25259   } finally {
25260    this.EndErrorFrameUpdate();
25261   }
25262   this.UpdateValidationSummaries(validationType);
25263   this.ariaExplanatoryTextManager.UpdateValidationState(validationType);
25264  }
25265 },
25266 GetElementRequiredForErrorFrame: function() {
25267  return this.GetExternalTable();
25268 },
25269 editorFocusingRequired: function(validationType) {
25270  return !this.GetIsValid() &&
25271   validationType == ValidationType.PersonalViaScript && this.setFocusOnError;
25272 },
25273 OnValueChanged: function() {
25274  if(this.getProcessOnServerOnValueChanged())
25275   this.SendPostBackInternal("");
25276 },
25277 getProcessOnServerOnValueChanged: function() {
25278  var processOnServer = this.RaiseValidationInternal();
25279  return this.RaiseValueChangedEvent() && processOnServer;
25280 },
25281 ParseValue: function() {
25282 },
25283 RaisePersonalStandardValidation: function() {
25284  if(ASPx.IsFunction(window.ValidatorOnChange)) {
25285   var inputElement = this.GetValueInputToValidate();
25286   if(inputElement && inputElement.Validators)
25287    window.ValidatorOnChange({ srcElement: inputElement });
25288  }
25289 },
25290 RaiseValidationInternal: function() {
25291  if(this.isPostBackAllowed() && this.causesValidation && this.validateOnLeave)
25292   return ASPxClientEdit.ValidateGroup(this.validationGroup);
25293  else {
25294   this.OnValidation(ValidationType.PersonalOnValueChanged);
25295   return this.GetIsValid();
25296  }
25297 },
25298 RaiseValueChangedEvent: function(){
25299  return this.RaiseValueChanged();
25300 },
25301 SendPostBackInternal: function(postBackArg) {
25302  if(ASPx.IsFunction(this.sendPostBackWithValidation))
25303   this.sendPostBackWithValidation(postBackArg);
25304  else
25305   this.SendPostBack(postBackArg);
25306 },
25307 SetElementToBeFocused: function() {
25308  if(this.IsVisible())
25309   invalidEditorToBeFocused = this;
25310 },
25311 GetFocusSelectAction: function() {
25312  return null;
25313 },
25314 SetFocus: function() {
25315  var inputElement = this.GetFocusableInputElement();
25316  if(!inputElement) return; 
25317  if((ASPx.GetActiveElement() != inputElement) && _aspxIsEditorFocusable(inputElement))
25318   ASPx.SetFocus(inputElement, this.GetFocusSelectAction());
25319 },
25320 SetFocusOnError: function() {
25321  if(invalidEditorToBeFocused == this) {
25322   this.SetFocus();
25323   invalidEditorToBeFocused = null;
25324  }
25325 },
25326 BeginErrorFrameUpdate: function() {
25327  if(!this.errorFrameUpdateLocked)
25328   this.errorFrameUpdateLocked = true;
25329 },
25330 EndErrorFrameUpdate: function() {
25331  this.errorFrameUpdateLocked = false;
25332  var args = this.updateErrorFrameAndFocusLastCallArgs;
25333  if(args) {
25334   this.UpdateErrorFrameAndFocus(args[0], args[1]);
25335   delete this.updateErrorFrameAndFocusLastCallArgs;
25336  }
25337 },
25338 UpdateErrorFrameAndFocus: function(setFocusOnError, ignoreVisibilityCheck, isValid) {
25339  if(!ignoreVisibilityCheck && !this.GetVisible())
25340   return;
25341  if(this.errorFrameUpdateLocked) {
25342   this.updateErrorFrameAndFocusLastCallArgs = [ setFocusOnError, ignoreVisibilityCheck ];
25343   return;
25344  }
25345  if(this.styleDecoration)
25346   this.styleDecoration.Update();
25347  if(typeof(isValid) == "undefined")
25348   isValid = this.GetIsValid();
25349  if(isValid && this.IsErrorFrameDisplayed())
25350   this.ChangeErrorFrameVisibility(false);
25351  else {
25352   var editorLocatedWithinVisibleContainer = this.IsVisible();
25353   if(this.IsErrorFrameDisplayed()) {
25354    this.UpdateErrorCellContent();
25355    this.ChangeErrorFrameVisibility(true);
25356   }
25357   if(editorLocatedWithinVisibleContainer) {
25358    if(setFocusOnError && this.setFocusOnError && invalidEditorToBeFocused == null) {
25359     this.SetElementToBeFocused();
25360     this.SetFocusOnError();
25361    }
25362   }
25363  }
25364 },
25365 ChangeErrorFrameVisibility: function(visible) {
25366  var externalTable = this.GetExternalTable();
25367  var isStaticDisplay = this.display == ErrorFrameDisplay.Static;
25368  if(!isStaticDisplay && visible) {
25369   this.EnsureControlCellStylesLoaded();
25370   this.RestoreControlCellStyles();
25371  }
25372  this.ChangeErrorCellVisibility(visible, isStaticDisplay);
25373  if(!isStaticDisplay && !visible) {
25374   this.EnsureControlCellStylesLoaded();
25375   this.ClearControlCellStyles();
25376  }
25377  var validExternalTableClassName = isStaticDisplay ? ASPxEditExternalTableClassNames.ValidStaticTableClassName
25378   : ASPxEditExternalTableClassNames.ValidDynamicTableClassName;
25379  ASPx.ToggleClassNameToElement(externalTable, validExternalTableClassName, !visible);
25380  this.UpdateErrorCellParentRowVisibility();
25381 },
25382 ChangeErrorCellVisibility: function(visible, useVisibilityAttribute) {
25383  var errorCell = this.GetErrorCell();
25384  if(errorCell) {
25385   if(useVisibilityAttribute)
25386    ASPx.SetElementVisibility(errorCell, visible);
25387   else {
25388    ASPx.SetElementDisplay(errorCell, visible);
25389    this.raiseErrorCellVisibilityChanged();
25390   }
25391  }
25392 },
25393 raiseErrorCellVisibilityChanged: function() {
25394  if(!this.errorCellVisibilityChanged.IsEmpty())
25395   this.errorCellVisibilityChanged.FireEvent(this);
25396 },
25397 UpdateErrorCellParentRowVisibility: function() {
25398  var errorCell = this.GetErrorCell();
25399  if(!errorCell || this.display == ErrorFrameDisplay.Static)
25400   return;
25401  var displayedCellCount = 0;
25402  var errorCellParentRow = errorCell.parentNode;
25403  for(var i = 0; i < errorCellParentRow.cells.length; i++) {
25404   var cell = errorCellParentRow.cells[i];
25405   if(ASPx.GetElementDisplay(cell))
25406    displayedCellCount++;
25407  }
25408  ASPx.SetElementDisplay(errorCellParentRow, displayedCellCount > 0);
25409 },
25410 EnsureControlCellStylesLoaded: function() {
25411  if(typeof(this.controlCellStyles) == "undefined") {
25412   var controlCell = this.GetControlCell();
25413   this.controlCellStyles = {
25414    cssClass: controlCell.className,
25415    style: this.ExtractElementStyleStringIgnoringVisibilityProps(controlCell)
25416   };
25417  }
25418 },
25419 ClearControlCellStyles: function() {
25420  this.ClearElementStyle(this.GetControlCell());
25421 },
25422 RestoreControlCellStyles: function() {
25423  var controlCell = this.GetControlCell();
25424  controlCell.className = this.controlCellStyles.cssClass;
25425  controlCell.style.cssText = this.controlCellStyles.style;
25426 },
25427 ExtractElementStyleStringIgnoringVisibilityProps: function(element) {
25428  var savedVisibility = element.style.visibility;
25429  var savedDisplay = element.style.display;
25430  element.style.visibility = "";
25431  element.style.display = "";
25432  var styleStr = element.style.cssText;
25433  element.style.visibility = savedVisibility;
25434  element.style.display = savedDisplay;
25435  return styleStr;
25436 },
25437 ClearElementStyle: function(element) {
25438  if(!element)
25439   return;
25440  element.className = "";
25441  var excludedAttrNames = [
25442   "width", "display", "visibility",
25443   "position", "left", "top", "z-index",
25444   "margin", "margin-top", "margin-right", "margin-bottom", "margin-left",
25445   "float", "clear"
25446  ];
25447  var savedAttrValues = { };
25448  for(var i = 0; i < excludedAttrNames.length; i++) {
25449   var attrName = excludedAttrNames[i];
25450   var attrValue = element.style[attrName];
25451   if(attrValue)
25452    savedAttrValues[attrName] = attrValue;
25453  }
25454  element.style.cssText = "";
25455  for(var styleAttrName in savedAttrValues)
25456   if(savedAttrValues.hasOwnProperty(styleAttrName))
25457    element.style[styleAttrName] = savedAttrValues[styleAttrName];
25458 },
25459 Clear: function() {
25460  this.SetValue(null);
25461  this.SetIsValid(true);
25462  return true;
25463 },
25464 ResetEditorState: function() { },
25465 UpdateErrorCellContent: function() {
25466  if(this.errorDisplayMode.indexOf("t") > -1)
25467   this.UpdateErrorText();
25468  if(this.errorDisplayMode == "i")
25469   this.UpdateErrorImage();
25470 },
25471 UpdateErrorImage: function() {
25472  var image = this.GetErrorImage();
25473  if(ASPx.IsExistsElement(image)) {
25474   if(this.accessibilityCompliant) {
25475    ASPx.Attr.SetAttribute(image, "aria-label", this.errorText);
25476    var innerImg = ASPx.GetNodeByTagName(image, "IMG", 0);
25477    if(ASPx.IsExists(innerImg))
25478     innerImg.alt = this.errorText;
25479   }
25480   image.alt = this.errorText;
25481   image.title = this.errorText;
25482  } else {
25483   this.UpdateErrorText();
25484  }
25485 },
25486 UpdateErrorText: function() {
25487  var errorTextCell = this.GetErrorTextCell();
25488  if(ASPx.IsExistsElement(errorTextCell))
25489   errorTextCell.innerHTML = this.HtmlEncode(this.errorText);
25490 },
25491 ValidateWithPatterns: function() {
25492  if(this.validationPatterns.length > 0) {
25493   var value = this.GetValue();
25494   for(var i = 0; i < this.validationPatterns.length; i++) {
25495    var validator = this.validationPatterns[i];
25496    if(!validator.EvaluateIsValid(value)) {
25497     this.SetIsValid(false, true );
25498     this.SetErrorText(validator.errorText, true );
25499     return;
25500    }
25501   }
25502  }
25503 },
25504 OnSpecialKeyDown: function(evt){
25505  this.RaiseKeyDown(evt);
25506  var handler = this.keyDownHandlers[evt.keyCode];
25507  if(handler) 
25508   return this[handler](evt);
25509  return false;
25510 },
25511 OnSpecialKeyPress: function(evt){
25512  this.RaiseKeyPress(evt);
25513  var handler = this.keyPressHandlers[evt.keyCode];
25514  if(handler) 
25515   return this[handler](evt);
25516  if(ASPx.Browser.NetscapeFamily || ASPx.Browser.Opera){
25517   if(evt.keyCode == ASPx.Key.Enter)
25518    return this.enterProcessed;
25519  }
25520  return false;
25521 },
25522 OnSpecialKeyUp: function(evt){
25523  this.RaiseKeyUp(evt);
25524  var handler = this.keyUpHandlers[evt.keyCode];
25525  if(handler) 
25526   return this[handler](evt);
25527  return false;
25528 },
25529 OnKeyDown: function(evt) {
25530  if(!this.UseSpecialKeyboardHandling())
25531   this.RaiseKeyDown(evt);
25532 },
25533 OnKeyPress: function(evt) {
25534  if(!this.UseSpecialKeyboardHandling())
25535   this.RaiseKeyPress(evt);
25536 },
25537 OnKeyUp: function(evt) {
25538  if(!this.UseSpecialKeyboardHandling())
25539   this.RaiseKeyUp(evt);
25540 },
25541 RaiseKeyDown: function(evt){
25542  if(!this.KeyDown.IsEmpty()){
25543   var args = new ASPxClientEditKeyEventArgs(evt);
25544   this.KeyDown.FireEvent(this, args);
25545  }
25546 },
25547 RaiseKeyPress: function(evt){
25548  if(!this.KeyPress.IsEmpty()){
25549   var args = new ASPxClientEditKeyEventArgs(evt);
25550   this.KeyPress.FireEvent(this, args);
25551  }
25552 },
25553 RaiseKeyUp: function(evt){
25554  if(!this.KeyUp.IsEmpty()){
25555   var args = new ASPxClientEditKeyEventArgs(evt);
25556   this.KeyUp.FireEvent(this, args);
25557  }
25558 },
25559 RaiseFocus: function(){
25560  if(!this.GotFocus.IsEmpty()){
25561   var args = new ASPxClientEventArgs();
25562   this.GotFocus.FireEvent(this, args);
25563  }
25564 },
25565 RaiseLostFocus: function(){
25566  if(!this.LostFocus.IsEmpty()){
25567   var args = new ASPxClientEventArgs();
25568   this.LostFocus.FireEvent(this, args);
25569  }
25570 },
25571 RaiseValidation: function() {
25572  if(this.customValidationEnabled && !this.Validation.IsEmpty()) {
25573   var currentValue = this.GetValue();
25574   var args = new ASPxClientEditValidationEventArgs(currentValue, this.errorText, this.GetIsValid());
25575   this.Validation.FireEvent(this, args);
25576   this.SetErrorText(args.errorText, true );
25577   this.SetIsValid(args.isValid, true );
25578   if(args.value != currentValue)
25579    this.SetValue(args.value);
25580  }
25581 },
25582 RaiseValueChanged: function(){
25583  var processOnServer = this.isPostBackAllowed();
25584  if(!this.ValueChanged.IsEmpty()){
25585   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
25586   this.ValueChanged.FireEvent(this, args);
25587   processOnServer = args.processOnServer;
25588  }
25589  return processOnServer;  
25590 },
25591 isPostBackAllowed: function() {
25592  return this.autoPostBack;
25593 },
25594 AddDecorationStyle: function(key, className, cssText) {
25595  if(!this.styleDecoration) 
25596   this.RequireStyleDecoration();
25597  this.styleDecoration.AddStyle(key, className, cssText);
25598 }, 
25599 RequireStyleDecoration: function() {
25600  this.styleDecoration = this.CreateStyleDecoration();
25601  this.PopulateStyleDecorationPostfixes();
25602 },
25603 CreateStyleDecoration: function() {
25604  return new ASPx.EditorStyleDecoration(this);
25605 },
25606 PopulateStyleDecorationPostfixes: function() {
25607  this.styleDecoration.AddPostfix("");
25608 },
25609 LockStyleDecorationUpdate: function() {
25610  if(this.styleDecoration)
25611   this.styleDecoration.LockUpdate();
25612 },
25613 UnlockStyleDecorationUpdate: function() {
25614  if(this.styleDecoration)
25615   this.styleDecoration.UnlockUpdate();
25616 },
25617 Focus: function(){
25618  this.SetFocus();
25619 },
25620 GetIsValid: function() {
25621  var hasRequiredInputElement = !this.RequireInputElementToValidate() || ASPx.IsExistsElement(this.GetInputElement());
25622  if(!hasRequiredInputElement || this.IsErrorFrameDisplayed() && !ASPx.IsExistsElement(this.GetElementRequiredForErrorFrame()))
25623   return true;
25624  return this.isValid;
25625 },
25626 RequireInputElementToValidate: function() {
25627  return true;
25628 },
25629 IsErrorFrameDisplayed: function() {
25630  return this.display !== ErrorFrameDisplay.None;
25631 },
25632 GetErrorText: function(){
25633  return this.errorText;
25634 },
25635 SetIsValid: function(isValid, validating){
25636  if(this.customValidationEnabled && this.isValid != isValid) {
25637   this.isValid = isValid;
25638   this.UpdateErrorFrameAndFocus(false );
25639   this.UpdateClientValidationState();
25640   if(!validating)
25641    this.UpdateValidationSummaries(ValidationType.PersonalViaScript);
25642  }
25643 },
25644 SetErrorText: function(errorText, validating){
25645  if(this.customValidationEnabled && this.errorText != errorText) {
25646   this.errorText = errorText;
25647   this.UpdateErrorFrameAndFocus(false );
25648   this.UpdateClientValidationState();
25649   if(!validating)
25650    this.UpdateValidationSummaries(ValidationType.PersonalViaScript);
25651  }
25652 },
25653 Validate: function(){
25654  this.ParseValue();
25655  this.OnValidation(ValidationType.PersonalViaScript);
25656 },
25657 GetModifyEvent: function() {
25658  return this.ValueChanged;
25659 },
25660 EnsureRequiredNativeAttributesExists: function() { }
25661});
25662ASPx.Ident.scripts.ASPxClientEdit = true;
25663ASPx.focusedEditorName = "";
25664ASPx.GetFocusedEditor = function() {
25665 var focusedEditor = ASPx.GetControlCollection().Get(ASPx.focusedEditorName);
25666 if(focusedEditor && !focusedEditor.focused){
25667  ASPx.SetFocusedEditor(null);
25668  focusedEditor = null;
25669 }
25670 return focusedEditor;
25671};
25672ASPx.SetFocusedEditor = function(editor) {
25673 ASPx.focusedEditorName = editor ? editor.name : "";
25674};
25675ASPx.FindAssociatedLabelElements = function(editor) {
25676 var assocciatedLabels = [];
25677 var inputElement = editor.GetInputElement();
25678 if(!ASPx.IsExists(inputElement) || !inputElement.id) 
25679  return assocciatedLabels;
25680 var labels = ASPx.GetNodesByTagName(document, "LABEL");
25681 for(var i = 0; i < labels.length; i++) {
25682  if(!!labels[i].htmlFor && labels[i].htmlFor === inputElement.id)
25683   assocciatedLabels.push(labels[i]);
25684 }
25685 return assocciatedLabels;
25686};
25687var DisableAccessibilityExplanatoryTextManager = ASPx.CreateClass(null, {
25688 constructor: function(editor) {
25689  this.editor = editor;
25690 },
25691 GetAdditionalTextRowId: function() {
25692  return this.editor.name + EditElementSuffix.AccessibilityAdditionalTextRow;
25693 },
25694 GetErrorTextElement: function () {
25695  return !!this.editor.GetErrorTextCell() ? this.editor.GetErrorTextCell() : this.editor.GetErrorImage();
25696 },
25697 GetTextElement: function() { return null; },
25698 SetCaptionAssociating: function() { },
25699 UpdateText: function() { },
25700 UpdateValidationState: function(validationType) { },
25701 ToggleErrorAlert: function() { },
25702 SetOrRemoveText: function(accessibilityElements, textElement, setText, isLabel, isFirst) { }
25703});
25704var EditAccessibilityExplanatoryTextManager = ASPx.CreateClass(DisableAccessibilityExplanatoryTextManager, {
25705 constructor: function(editor) {
25706  this.constructor.prototype.constructor.call(this, editor);
25707  this.invisibleRowCssClassName = "dxAIR";
25708 },
25709 GetTextElement: function() {
25710  var mainElement = this.editor.GetMainElement();
25711  if(!mainElement) return null;
25712  var explanatoryText = "";
25713  var explanatoryTextElement = null;
25714  if(!!this.editor.nullText)
25715   explanatoryText = this.editor.nullText;
25716  else if(!!this.editor.helpTextObj)
25717   explanatoryTextElement = this.editor.helpTextObj.helpTextElement;
25718  else if(!!mainElement.title)
25719   explanatoryText = mainElement.title;
25720  if(explanatoryText && mainElement.tagName == "TABLE") {
25721   var assistantElement = this.editor.GetAccessibilityFirstActiveElement();
25722   if(assistantElement)
25723    ASPx.Attr.Aria.AppendLabel(assistantElement, explanatoryText, true);
25724  }
25725  return explanatoryTextElement;
25726 },
25727 SetCaptionAssociating: function() {
25728  var captionCell = this.editor.GetCaptionCell();
25729  if(!captionCell || captionCell.childNodes[0].tagName == "LABEL") return;
25730  var labelElement = captionCell.childNodes[0];
25731  ASPx.EditAccessibilityExplanatoryTextManager.SetLabelAssociating(this.editor, this.editor.GetAccessibilityFirstActiveElement(), labelElement);
25732 },
25733 UpdateText: function() {
25734  var additionalTextElement = this.GetTextElement();
25735  if(ASPx.IsExists(additionalTextElement)) {
25736   var pronounceElement = this.editor.GetAccessibilityFirstActiveElement();
25737   var hasAnyLabel = !!ASPx.Attr.GetAttribute(pronounceElement, "aria-label") || 
25738    !!ASPx.Attr.GetAttribute(pronounceElement, "aria-labelledby") ||
25739    ASPx.FindAssociatedLabelElements(this.editor).length > 0;
25740   this.SetOrRemoveText([pronounceElement], additionalTextElement, true, !hasAnyLabel, false);
25741  }
25742 },
25743 UpdateValidationState: function(validationType) {
25744  if(validationType == ValidationType.PersonalOnValueChanged && this.editor.accessibilityHelper) return;
25745  var accessibilityElements = this.editor.GetAccessibilityActiveElements();
25746  var errorTextElement = this.GetErrorTextElement();
25747  this.SetOrRemoveText(accessibilityElements, errorTextElement, !this.editor.isValid, false, true);
25748  if(accessibilityElements.length > 0 && !!errorTextElement) {
25749   for(var i = 0; i < accessibilityElements.length; i++) {
25750    if(!ASPx.IsExists(accessibilityElements[i])) continue;
25751    ASPx.Attr.SetOrRemoveAttribute(accessibilityElements[i], "aria-invalid", !this.editor.isValid);
25752   }
25753  }
25754 },
25755 ToggleErrorAlert: function() {
25756  var errorTextElement = this.GetErrorTextElement();
25757  ASPx.SetElementDisplay(errorTextElement, false);
25758  ASPx.Attr.SetAttribute(errorTextElement, 'role', 'alert');
25759  ASPx.SetElementDisplay(errorTextElement, true);
25760  setTimeout(function() { ASPx.Attr.RemoveAttribute(errorTextElement, 'role'); }, 500);
25761 },
25762 SetOrRemoveText: function(accessibilityElements, textElement, setText, isLabel, isFirst) {
25763  var idsRefAttribute = isLabel ? ASPx.Attr.Aria.labelled : ASPx.Attr.Aria.described;
25764  if(!textElement) return;
25765  var textId = !!textElement.id ? textElement.id : textElement.parentNode.id;
25766  for(var i = 0; i < accessibilityElements.length; i++) {
25767   if(!accessibilityElements[i]) continue;
25768   var descRefString = ASPx.Attr.GetAttribute(accessibilityElements[i], idsRefAttribute);
25769   var descRefIds = !!descRefString ? descRefString.split(" ") : [ ];
25770   var descIndex = descRefIds.indexOf(textId);
25771   if(setText && descIndex == -1) {
25772    if(isFirst)
25773     descRefIds.unshift(textId);
25774    else
25775     descRefIds.push(textId);
25776   }
25777   else if(!setText && descIndex > -1)
25778    descRefIds.splice(descIndex, 1);
25779   ASPx.Attr.SetOrRemoveAttribute(accessibilityElements[i], idsRefAttribute, descRefIds.join(" "));
25780  }
25781 }
25782});
25783ASPx.DisableAccessibilityExplanatoryTextManager = DisableAccessibilityExplanatoryTextManager;
25784ASPx.EditAccessibilityExplanatoryTextManager = EditAccessibilityExplanatoryTextManager;
25785ASPx.EditAccessibilityExplanatoryTextManager.SetLabelAssociating = function(editor, activeElement, labelElement) {
25786 var clickHandler = function(evt) {
25787  if(editor && editor.OnAssociatedLabelClick)
25788   editor.OnAssociatedLabelClick(evt);
25789  else
25790   activeElement.click();
25791 };
25792 ASPx.Evt.AttachEventToElement(labelElement, "click", clickHandler);
25793 if(!!editor) {
25794  var hasAriaLabel = !!ASPx.Attr.GetAttribute(activeElement, "aria-label");
25795  editor.ariaExplanatoryTextManager.SetOrRemoveText([activeElement], labelElement, true, !hasAriaLabel, true);
25796 }
25797};
25798ASPxClientEdit.ClearEditorsInContainer = function(container, validationGroup, clearInvisibleEditors) {
25799 invalidEditorToBeFocused = null;
25800 ASPx.ProcessEditorsInContainer(container, ASPx.ClearProcessingProc, ASPx.ClearChoiceCondition, validationGroup, clearInvisibleEditors, true );
25801 ASPxClientEdit.ClearExternalControlsInContainer(container, validationGroup, clearInvisibleEditors, true );
25802};
25803ASPxClientEdit.ClearEditorsInContainerById = function(containerId, validationGroup, clearInvisibleEditors) {
25804 var container = document.getElementById(containerId);
25805 this.ClearEditorsInContainer(container, validationGroup, clearInvisibleEditors);
25806};
25807ASPxClientEdit.ClearGroup = function(validationGroup, clearInvisibleEditors) {
25808 return this.ClearEditorsInContainer(null, validationGroup, clearInvisibleEditors);
25809};
25810ASPxClientEdit.ValidateEditorsInContainer = function(container, validationGroup, validateInvisibleEditors) {
25811 var summaryCollection;
25812 if(ASPx.Ident.scripts.ASPxClientValidationSummary) {
25813  summaryCollection = ASPx.GetClientValidationSummaryCollection();
25814  summaryCollection.AllowNewErrorsAccepting(validationGroup);
25815 }
25816 var validationResult = ASPx.ProcessEditorsInContainer(container, ASPx.ValidateProcessingProc, _aspxValidateChoiceCondition, validationGroup, validateInvisibleEditors,
25817  false );
25818 validationResult.isValid = ASPxClientEdit.ValidateExternalControlsInContainer(container, validationGroup, validateInvisibleEditors,
25819  false ) && validationResult.isValid;
25820 if(typeof(validateInvisibleEditors) == "undefined")
25821  validateInvisibleEditors = false;
25822 if(typeof(validationGroup) == "undefined")
25823  validationGroup = null;    
25824 validationResult.isValid = ASPx.GetControlCollection().RaiseValidationCompleted(container, validationGroup,
25825 validateInvisibleEditors, validationResult.isValid, validationResult.firstInvalid, validationResult.firstVisibleInvalid);
25826 if(summaryCollection)
25827  summaryCollection.ForbidNewErrorsAccepting(validationGroup);
25828 if(!validationResult.isValid && !!validationResult.firstVisibleInvalid && validationResult.firstVisibleInvalid.accessibilityCompliant && !validationResult.firstVisibleInvalid.setFocusOnError) {
25829  var accessInvalidControl = validationResult.firstVisibleInvalid;
25830  if(!summaryCollection && !accessInvalidControl.focused) {
25831   var beforeDelayActiveElement = ASPx.GetActiveElement();
25832   setTimeout(function() {
25833    var currentActiveElement = ASPx.GetActiveElement();
25834    if(accessInvalidControl.focused || (currentActiveElement != beforeDelayActiveElement && ASPx.Attr.IsExistsAttribute(currentActiveElement, 'role')))
25835     return;
25836    accessInvalidControl.ariaExplanatoryTextManager.ToggleErrorAlert();
25837   }, 500);    
25838  }
25839 }
25840 return validationResult.isValid;
25841};
25842ASPxClientEdit.ValidateEditorsInContainerById = function(containerId, validationGroup, validateInvisibleEditors) {
25843 var container = document.getElementById(containerId);
25844 return this.ValidateEditorsInContainer(container, validationGroup, validateInvisibleEditors);
25845};
25846ASPxClientEdit.ValidateGroup = function(validationGroup, validateInvisibleEditors) {
25847 return this.ValidateEditorsInContainer(null, validationGroup, validateInvisibleEditors);
25848};
25849ASPxClientEdit.AreEditorsValid = function(containerOrContainerId, validationGroup, checkInvisibleEditors) {
25850 var container = typeof(containerOrContainerId) == "string" ? document.getElementById(containerOrContainerId) : containerOrContainerId;
25851 var checkResult = ASPx.ProcessEditorsInContainer(container, ASPx.EditorsValidProcessingProc, _aspxEditorsValidChoiceCondition, validationGroup,
25852  checkInvisibleEditors, false );
25853 checkResult.isValid = ASPxClientEdit.AreExternalControlsValidInContainer(containerOrContainerId, validationGroup,
25854  checkInvisibleEditors, false ) && checkResult.isValid;
25855 return checkResult.isValid;
25856};
25857ASPxClientEdit.AreExternalControlsValidInContainer = function(containerId, validationGroup, validateInvisibleEditors, processDisabledEditors) {
25858 if(ASPx.Ident.scripts.ASPxClientHtmlEditor)
25859  return ASPxClientHtmlEditor.AreEditorsValidInContainer(containerId, validationGroup, validateInvisibleEditors, processDisabledEditors);
25860 return true;
25861};
25862ASPxClientEdit.ClearExternalControlsInContainer = function(containerId, validationGroup, validateInvisibleEditors, processDisabledEditors) {
25863 if(ASPx.Ident.scripts.ASPxClientHtmlEditor)
25864  return ASPxClientHtmlEditor.ClearEditorsInContainer(containerId, validationGroup, validateInvisibleEditors, processDisabledEditors);
25865 return true;
25866};
25867ASPxClientEdit.ValidateExternalControlsInContainer = function(containerId, validationGroup, validateInvisibleEditors, processDisabledEditors) {
25868 if(ASPx.Ident.scripts.ASPxClientHtmlEditor)
25869  return ASPxClientHtmlEditor.ValidateEditorsInContainer(containerId, validationGroup, validateInvisibleEditors, processDisabledEditors);
25870 return true;
25871};
25872ASPxClientEdit.AttachEditorModificationListener = function(handler, predicate) {
25873 var processAction = function(event) { event.AddHandler(handler); };
25874 ASPxClientEdit.ProcessEditorModificationListener(handler, processAction, predicate);
25875};
25876ASPxClientEdit.DetachEditorModificationListener = function(handler, predicate) {
25877 var processAction = function(event) { event.RemoveHandler(handler); };
25878 ASPxClientEdit.ProcessEditorModificationListener(handler, processAction, predicate);
25879};
25880ASPxClientEdit.ProcessEditorModificationListener = function(handler, action, predicate) {
25881 ASPx.GetControlCollection().ForEachControl(function(control) {
25882  if(control.GetModifyEvent && predicate(control)) {
25883   if(control.isNative)
25884    control.EnsureRequiredNativeAttributesExists();
25885   action(control.GetModifyEvent());
25886  }
25887 });
25888};
25889var ASPxClientEditKeyEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
25890 constructor: function(htmlEvent) {
25891  this.constructor.prototype.constructor.call(this);
25892  this.htmlEvent = htmlEvent;
25893 }
25894});
25895var ASPxClientEditValidationEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
25896 constructor: function(value, errorText, isValid) {
25897  this.constructor.prototype.constructor.call(this);
25898  this.errorText = errorText;
25899  this.isValid = isValid;
25900  this.value = value;
25901 }
25902});
25903ASPx.ProcessEditorsInContainer = function(container, processingProc, choiceCondition, validationGroup, processInvisibleEditors, processDisabledEditors) {
25904 var allProcessedSuccessfull = true;
25905 var firstInvalid = null;
25906 var firstVisibleInvalid = null;
25907 var invalidEditorToBeFocused = null;
25908 ASPx.GetControlCollection().ForEachControl(function(control) {
25909  var canValidate = ASPx.CanValidateControl(control, container, processingProc, choiceCondition, validationGroup, processInvisibleEditors, processDisabledEditors);
25910  if(!canValidate) return;
25911  var isSuccess = processingProc(control);
25912  if(!isSuccess) {
25913   allProcessedSuccessfull = false;
25914   if(firstInvalid == null)
25915    firstInvalid = control;
25916   var isVisible = control.IsVisible();
25917   if(isVisible && firstVisibleInvalid == null)
25918    firstVisibleInvalid = control;
25919   if(control.setFocusOnError && invalidEditorToBeFocused == null && isVisible)
25920    invalidEditorToBeFocused = control;
25921  }
25922 }, this);
25923 if(invalidEditorToBeFocused != null)
25924  invalidEditorToBeFocused.SetFocus();
25925 return new ASPxValidationResult(allProcessedSuccessfull, firstInvalid, firstVisibleInvalid);
25926};
25927ASPx.CanValidateControl = function(control, container, processingProc, choiceCondition, validationGroup, processInvisibleEditors, processDisabledEditors) {
25928 var needToProcessRatingControl = window.ASPxClientRatingControl && (control instanceof ASPxClientRatingControl) && processingProc === ASPx.ClearProcessingProc;
25929 var mainElement = control.GetMainElement(); 
25930 if(!ASPx.Ident.IsASPxClientEdit(control) && !needToProcessRatingControl)
25931  return false;
25932 if(ASPx.Ident.isDialogInvisibleControl(control) || ASPx.Ident.isBatchEditUnusedEditor(control))
25933  return false; 
25934 if(!processDisabledEditors && !control.GetEnabled())
25935  return false;
25936 if(!mainElement || (container && !ASPx.GetIsParent(container, mainElement)))
25937  return false;
25938 if(!processInvisibleEditors && !control.IsVisible())
25939  return false;
25940 if(choiceCondition && !choiceCondition(control, validationGroup))
25941  return false;
25942 return true;
25943};
25944var ASPxValidationResult = ASPx.CreateClass(null, {
25945 constructor: function(isValid, firstInvalid, firstVisibleInvalid) {
25946  this.isValid = isValid;
25947  this.firstInvalid = firstInvalid;
25948  this.firstVisibleInvalid = firstVisibleInvalid;
25949 }
25950});
25951ASPx.ClearChoiceCondition = function(edit, validationGroup) {
25952 return !ASPx.IsExists(validationGroup) || (edit.validationGroup == validationGroup);
25953};
25954function _aspxValidateChoiceCondition(edit, validationGroup) {
25955 return ASPx.ClearChoiceCondition(edit, validationGroup) && edit.customValidationEnabled;
25956}
25957function _aspxEditorsValidChoiceCondition(edit, validationGroup) {
25958 return _aspxValidateChoiceCondition(edit, validationGroup);
25959}
25960function wrapLostFocusHandler(handler) {
25961 if(ASPx.Browser.Edge) {
25962  return function(name) {
25963   var edit = ASPx.GetControlCollection().Get(name);
25964   if(edit && !ASPx.IsElementVisible(edit.GetMainElement()))
25965    setTimeout(handler, 0, name);
25966   else
25967    handler(name);
25968  };
25969 }
25970 return handler;
25971}
25972ASPx.EGotFocus = function(name) {
25973 var edit = ASPx.GetControlCollection().Get(name);
25974 if(edit && !ASPx.GetIsParent(edit.mainElement, document.activeElement) && document.activeElement !== edit.GetFocusableInputElement())
25975  return;
25976 if(edit) {
25977  if(edit.isInitialized) {
25978   if(ASPx.Browser.VirtualKeyboardSupported && !edit.ownerListBox)
25979    ASPx.VirtualKeyboardUI.processEditorGotFocus(edit);
25980   else
25981    edit.OnFocus();
25982  }
25983  else {
25984   var inputElement = edit.GetFocusableInputElement();
25985   if(inputElement && inputElement === document.activeElement) {
25986    if(ASPx.Browser.Firefox)
25987     window.setTimeout(function() { document.activeElement.blur(); }, 0);
25988    else
25989     document.activeElement.blur();
25990   }
25991  }
25992 }
25993};
25994ASPx.ELostFocusCore = function(name) {
25995 var edit = ASPx.GetControlCollection().Get(name);
25996 if(ASPx.Browser.VirtualKeyboardSupported && (!edit || !edit.ownerListBox)) {
25997  var supressLostFocus = ASPx.VirtualKeyboardUI.isInputNativeBluring();
25998  if(!supressLostFocus)
25999   ASPx.VirtualKeyboardUI.resetFocusedEditorCore();
26000  else 
26001   return;
26002 }
26003 if(edit && edit.focused) {
26004  if(edit.UseDelayedSpecialFocus()) {
26005   if(edit.specialFocusTimer === -1)
26006    edit.specialFocusTimer = ASPx.Timer.SetControlBoundTimeout(function() { edit.OnLostFocus(); }, edit, 30);
26007  }
26008  else {
26009   edit.OnLostFocus();
26010  }
26011 }
26012};
26013ASPx.ELostFocus = wrapLostFocusHandler(ASPx.ELostFocusCore);
26014ASPx.EValueChanged = function(name) {
26015 var edit = ASPx.GetControlCollection().Get(name);
26016 if(edit != null)
26017  edit.OnValueChanged();
26018};
26019ASPx.VirtualKeyboardUI = (function() {
26020 var result = {
26021  focusedEditor: null,
26022  inputNativeFocusLocked: false,
26023  elementBelongsToEditor: function(element) {
26024   if(!element) return false;
26025   var isBelongsToEditor = false;
26026   ASPx.GetControlCollection().ForEachControl(function(control) {
26027    if(ASPx.Ident.IsASPxClientEdit(control) && control.IsEditorElement(element)) {
26028     isBelongsToEditor = true;
26029     return true;
26030    }
26031   }, this);
26032   return isBelongsToEditor;
26033  },
26034  elementBelongsToFocusedEditor: function (element) {
26035   return this.focusedEditor && this.focusedEditor.IsEditorElement(element);
26036  },
26037  onTouchStart: function (evt) {
26038   if (!ASPx.Browser.VirtualKeyboardSupported || this.isGooglePlaceAutocompleteElementTap(evt)) return;
26039   this.setInputNativeFocusLocked(false);
26040   if(this.focusedEditor)
26041    this.focusedEditor.onVirtualKeyboardUITouchStart(evt);
26042  },
26043  onTouchEnd: function(evt) {
26044   if(ASPx.TouchUIHelper.pointerEnabled) {  
26045    if(!window.testingTouchMode) { 
26046     if(evt.pointerType !== ASPx.TouchUIHelper.pointerType.Touch)
26047      return;
26048    }
26049    this.processFocusEditorControl(evt);
26050   } else
26051    ASPx.TouchUIHelper.handleFastTapIfRequired(evt,
26052     function() {
26053      this.processFocusEditorControl(evt);
26054     }.aspxBind(this), false);
26055  },
26056  processFocusEditorControl: function(evt) {
26057   var evtSource = ASPx.Evt.GetEventSource(evt);
26058   var focusedEditorIsTimeEdit = this.focusedEditor && (ASPx.Ident.IsASPxClientTimeEdit && ASPx.Ident.IsASPxClientTimeEdit(this.focusedEditor));
26059   var focusedTimeEditBelongsToDateEdit = focusedEditorIsTimeEdit && this.focusedEditor.OwnerDateEdit && this.focusedEditor.OwnerDateEdit.GetShowTimeSection();
26060   if(focusedTimeEditBelongsToDateEdit) {
26061    this.focusedEditor.OwnerDateEdit.ForceRefocusTimeSectionTimeEdit(evtSource);
26062    return;
26063   }
26064   var elementWithNativeFocus = ASPx.GetActiveElement();
26065   var someEditorInputIsFocused = this.elementBelongsToEditor(elementWithNativeFocus);
26066   var touchKeyboardIsVisible = someEditorInputIsFocused;
26067   var tapOutsideEditorAndInputs = !this.elementBelongsToEditor(evtSource) && !ASPx.Ident.IsFocusableElementRegardlessTabIndex(evtSource)
26068    && !this.isGooglePlaceAutocompleteElementTap(evt);
26069   var blurToHideTouchKeyboard = touchKeyboardIsVisible && tapOutsideEditorAndInputs;
26070   if(blurToHideTouchKeyboard) {
26071    elementWithNativeFocus.blur();
26072    return;
26073   }
26074   var tapOutsideFocusedEditor = this.focusedEditor && !this.elementBelongsToFocusedEditor(evtSource);
26075   if(tapOutsideFocusedEditor) {
26076    if(!this.elementBelongsToFocusedEditor(elementWithNativeFocus))
26077     this.resetFocusedEditor();
26078   }
26079  },
26080  focusEditor: function(edit) {
26081   if(!edit.focused) {
26082    this.setInputNativeFocusLocked(true);
26083    this.setFocusToEditor(edit);
26084   } else {
26085    edit.ForceRefocusEditor();
26086   }
26087  },
26088  setFocusToEditor: function(edit) {
26089   if(ASPx.Browser.MacOSMobilePlatform) {
26090    var timeoutDuration = ASPx.Browser.Chrome ? 250 : 30;
26091    window.setTimeout(function() {
26092     edit.SetFocus();
26093    }, timeoutDuration);
26094   } else {
26095    edit.SetFocus();
26096   }
26097  },
26098  processEditorGotFocus: function(edit) {
26099   if(this.focusedEditor === edit) {
26100    this.focusedEditor.UnlockFocusEvents();
26101    if(this.focusedEditor.EnsureClearButtonVisibility)
26102     this.focusedEditor.EnsureClearButtonVisibility();
26103   }
26104   else {
26105    this.setFocusedEditor(edit);
26106    if(this.getInputNativeFocusLocked())
26107     edit.BlurInputElement();
26108   }
26109  },
26110  setFocusedEditor: function(edit) {
26111   this.resetFocusedEditor();
26112   this.focusedEditor = edit;
26113   this.focusedEditor.Disposed.AddHandler(this.onFocusedEditorDisposed);
26114   this.focusedEditor.OnFocus();
26115   ASPx.SetFocusedEditor(this.focusedEditor);
26116  },
26117  isInputNativeBluring: function() {
26118   return this.focusedEditor && this.getInputNativeFocusLocked();
26119  },
26120  setInputNativeFocusLocked: function(locked) {
26121   this.inputNativeFocusLocked = locked;
26122  },
26123  getInputNativeFocusLocked: function() {
26124   return this.inputNativeFocusLocked;
26125  },
26126  resetFocusedEditor: function() {
26127   if(this.focusedEditor) {
26128    var curEditorName = this.focusedEditor.name;
26129    var focusedEditorInputElementExists = this.focusedEditor.GetInputElement();
26130    this.resetFocusedEditorCore();
26131    if(focusedEditorInputElementExists)
26132     ASPx.ELostFocusCore(curEditorName);
26133   }
26134  },
26135  resetFocusedEditorCore: function() { 
26136   if(this.focusedEditor)
26137    this.focusedEditor.Disposed.RemoveHandler(this.onFocusedEditorDisposed);
26138   this.focusedEditor = null;
26139  },
26140  getFocusedEditor: function() {
26141   return this.focusedEditor;
26142  },
26143  focusableInputElementIsActive: function(edit) {
26144   var inputElement = edit.GetFocusableInputElement();
26145   return !!inputElement ? ASPx.GetActiveElement() === inputElement : false;
26146  },
26147  isGooglePlaceAutocompleteElementTap: function(evt) {
26148   var googlePlaceAutocompleteContainer = ASPx.GetNodeByClassName(document.body, "pac-container", 0);
26149   if(!googlePlaceAutocompleteContainer)
26150    return false;
26151   return ASPx.GetParentByClassName(ASPx.Evt.GetEventSource(evt), "pac-container") != null;
26152  }
26153 };
26154 result.onFocusedEditorDisposed = function() {
26155  this.resetFocusedEditor();
26156 }.bind(result);
26157 return result;
26158})();
26159if(ASPx.Browser.VirtualKeyboardSupported) {
26160 var touchStartEventName = ASPx.TouchUIHelper.pointerEnabled ? ASPx.TouchUIHelper.pointerDownEventName : 'touchstart';
26161 var touchEndEventName = ASPx.TouchUIHelper.pointerEnabled ? ASPx.TouchUIHelper.pointerUpEventName : 'touchend';
26162 ASPx.Evt.AttachEventToDocument(touchStartEventName, function(evt) { ASPx.VirtualKeyboardUI.onTouchStart(evt); });
26163 ASPx.Evt.AttachEventToDocument(touchEndEventName, function(evt) { ASPx.VirtualKeyboardUI.onTouchEnd(evt); });
26164}
26165ASPx.Evt.AttachEventToDocument("mousedown", function(evt) {
26166 var editor = ASPx.GetFocusedEditor();
26167 if(!editor) 
26168  return;
26169 var evtSource = ASPx.Evt.GetEventSource(evt);
26170 if(editor.IsClearButtonElement(evtSource))
26171  return;
26172 if(editor.OwnerDateEdit && editor.OwnerDateEdit.GetShowTimeSection()) {
26173  editor.OwnerDateEdit.ForceRefocusTimeSectionTimeEdit(evtSource);
26174  return;
26175 }
26176 if(editor.ownerListBox && editor.ownerListBox.IsEditorElement(evtSource) && !editor.IsEditorElement(evtSource)) {
26177  editor.ownerListBox.ForceRefocusEditor(evt);
26178  ASPx.SetFocusedEditor(editor.ownerListBox);
26179  return;
26180 }
26181 if(editor.IsEditorElement(evtSource) && !editor.IsElementBelongToInputElement(evtSource))
26182  editor.ForceRefocusEditor(evt);
26183});
26184ASPx.Evt.AttachEventToDocument(ASPx.Evt.GetMouseWheelEventName(), function(evt) {
26185 var editor = ASPx.GetFocusedEditor();
26186 if(editor != null && ASPx.IsExistsElement(editor.GetMainElement()) && editor.focused && editor.receiveGlobalMouseWheel)
26187  editor.OnMouseWheel(evt);
26188});
26189ASPx.KBSIKeyDown = function(name, evt){
26190 var control = ASPx.GetControlCollection().Get(name);
26191 if(control != null){
26192  var isProcessed = control.OnSpecialKeyDown(evt);
26193  if(isProcessed)
26194   return ASPx.Evt.PreventEventAndBubble(evt);
26195 }
26196};
26197ASPx.KBSIKeyPress = function(name, evt){
26198 var control = ASPx.GetControlCollection().Get(name);
26199 if(control != null){
26200  var isProcessed = control.OnSpecialKeyPress(evt);
26201  if(isProcessed)
26202   return ASPx.Evt.PreventEventAndBubble(evt);
26203 }
26204};
26205ASPx.KBSIKeyUp = function(name, evt){
26206 var control = ASPx.GetControlCollection().Get(name);
26207 if(control != null){
26208  var isProcessed = control.OnSpecialKeyUp(evt);
26209  if(isProcessed)
26210   return ASPx.Evt.PreventEventAndBubble(evt);
26211 }
26212};
26213ASPx.ClearProcessingProc = function(edit) {
26214 return edit.Clear();
26215};
26216ASPx.ValidateProcessingProc = function(edit) {
26217 edit.OnValidation(ValidationType.MassValidation);
26218 return edit.GetIsValid();
26219};
26220ASPx.EditorsValidProcessingProc = function(edit) {
26221 return edit.GetIsValid();
26222};
26223var CheckEditElementHelper = ASPx.CreateClass(ASPx.CheckableElementHelper, {
26224 AttachToMainElement: function(internalCheckBox) {
26225  ASPx.CheckableElementHelper.prototype.AttachToMainElement.call(this, internalCheckBox);
26226  this.AttachToLabelElement(this.GetLabelElement(internalCheckBox.container), internalCheckBox);
26227 },
26228 AttachToLabelElement: function(labelElement, internalCheckBox) {
26229  var _this = this;
26230  if(labelElement) {
26231   ASPx.Evt.AttachEventToElement(labelElement, "click", 
26232    function (evt) { 
26233     _this.InvokeClick(internalCheckBox, evt);
26234    }
26235   );
26236   ASPx.Evt.AttachEventToElement(labelElement, "mousedown",
26237    function (evt) {
26238     internalCheckBox.Refocus();
26239    }
26240   );
26241  }
26242 },
26243 GetLabelElement: function(container) {
26244  var labelElement = ASPx.GetNodeByTagName(container, "LABEL", 0);
26245  if(!labelElement) {
26246   var labelCell = ASPx.GetNodeByClassName(container, "dxichTextCellSys", 0);
26247   labelElement = ASPx.GetNodeByTagName(labelCell, "SPAN", 0);
26248  }
26249  return labelElement;
26250 }
26251});
26252CheckEditElementHelper.Instance = new CheckEditElementHelper();
26253var CalendarSharedParameters = ASPx.CreateClass(null, {
26254 updateCalendarCallbackCommand: "UPDATE",
26255 constructor: function() {
26256  this.minDate = null;
26257  this.maxDate = null;
26258  this.disabledDates = [];
26259  this.calendarCustomDraw = false;
26260  this.hasCustomDisabledDatesViaCallback = false;
26261  this.dateRangeMode = false;
26262  this.currentDateEdit = null;
26263  this.DaysSelectingOnMouseOver = new ASPxClientEvent();
26264  this.VisibleDaysMouseOut = new ASPxClientEvent();
26265  this.CalendarSelectionChangedInternal = new ASPxClientEvent();
26266 },
26267 Assign: function(source) {
26268  this.minDate = source.minDate ? source.minDate : null;
26269  this.maxDate = source.maxDate ? source.maxDate : null;
26270  this.calendarCustomDraw = source.calendarCustomDraw ? source.calendarCustomDraw : false;
26271  this.hasCustomDisabledDatesViaCallback = source.hasCustomDisabledDatesViaCallback ? source.hasCustomDisabledDatesViaCallback : false;
26272  this.disabledDates = source.disabledDates ? source.disabledDates : [];
26273  this.currentDateEdit = source.currentDateEdit ? source.currentDateEdit : null;
26274 },
26275 GetUpdateCallbackParameters: function() {
26276  var callbackArgs = this.GetCallbackArgs();
26277  callbackArgs = this.FormatCallbackArg(this.updateCalendarCallbackCommand, callbackArgs);
26278  return callbackArgs;
26279 },
26280 GetCallbackArgs: function() {
26281  var args = {};
26282  if(this.minDate)
26283   args.clientMinDate = ASPx.DateUtils.GetInvariantDateString(this.minDate);
26284  if(this.maxDate)
26285   args.clientMaxDate = ASPx.DateUtils.GetInvariantDateString(this.maxDate);
26286  if(args.clientMinDate || args.clientMaxDate) {
26287   var jsonArgs = JSON.stringify(args);
26288   return ASPx.Str.EncodeHtml(jsonArgs);
26289  }
26290  return null;
26291 },
26292 FormatCallbackArg: function(prefix, arg) {
26293  if(!arg) return prefix;
26294  return [prefix, '|', arg.length, ';', arg, ';'].join('');
26295 }
26296});
26297ASPx.CalendarSharedParameters = CalendarSharedParameters;
26298ASPx.ValidationType = ValidationType;
26299ASPx.ErrorFrameDisplay = ErrorFrameDisplay;
26300ASPx.EditElementSuffix = EditElementSuffix;
26301ASPx.ValidationPattern = ValidationPattern;
26302ASPx.RequiredFieldValidationPattern = RequiredFieldValidationPattern;
26303ASPx.RegularExpressionValidationPattern = RegularExpressionValidationPattern;
26304ASPx.CheckEditElementHelper = CheckEditElementHelper;
26305ASPx.IsEditorFocusable = _aspxIsEditorFocusable;
26306window.ASPxClientEditBase = ASPxClientEditBase;
26307window.ASPxClientEdit = ASPxClientEdit;
26308window.ASPxClientEditKeyEventArgs = ASPxClientEditKeyEventArgs;
26309window.ASPxClientEditValidationEventArgs = ASPxClientEditValidationEventArgs;
26310})();
26311
26312(function() {
26313ASPx.TEInputSuffix = "_I";
26314ASPx.PasteCheckInterval = 50;
26315ASPx.CheckUserInputInterval = 10;
26316ASPx.TEHelpTextElementSuffix = "_HTE";
26317ASPx.TempHiddenInputSuffix = "_THI";
26318var passwordInputClonedSuffix = "_CLND";
26319var CHROME_AUTOFILL_SELECTOR = ":-webkit-autofill";
26320var BrowserHelper = {
26321 SAFARI_SYSTEM_CLASS_NAME: "dxeSafariSys",
26322 MOBILE_SAFARI_SYSTEM_CLASS_NAME: "dxeIPadSys",
26323 GetBrowserSpecificSystemClassName: function() {
26324  if(ASPx.Browser.Safari)
26325   return ASPx.Browser.MacOSMobilePlatform ? this.MOBILE_SAFARI_SYSTEM_CLASS_NAME : this.SAFARI_SYSTEM_CLASS_NAME;
26326  return "";
26327 }
26328};
26329var focusedNullTextClassName = "dxeFNTextSys";
26330var NullTextDisplayMode = {
26331 Unfocused: "Unfocused",
26332 UnfocusedAndFocused: "UnfocusedAndFocused"
26333};
26334ASPx.NullTextDisplayMode = NullTextDisplayMode;
26335var ASPxClientTextEdit = ASPx.CreateClass(ASPxClientEdit, {
26336 constructor: function(name) {
26337  this.constructor.prototype.constructor.call(this, name);      
26338  this.isASPxClientTextEdit = true;
26339  this.nullText = "";
26340  this.nullTextDisplayMode = NullTextDisplayMode.Unfocused;
26341  this.nullTextOnFocusCssText = "";
26342  this.focusedNullTextTimerID = -1;
26343  this.escCount = 0;
26344  this.raiseValueChangedOnEnter = true;
26345  this.autoResizeWithContainer = false;
26346  this.lastChangedValue = null;
26347  this.autoCompleteAttribute = null;
26348  this.isTextSelectionOnClickEnabled = false;
26349  this.trySelectInputTextOnClick = true;
26350  this.passwordNullTextIntervalID = -1;
26351  this.nullTextInputElement = null;
26352  this.helpText = "";
26353  this.helpTextObj = null;  
26354  this.helpTextStyle = [];
26355  this.externalTableStyle = [];
26356  this.helpTextPosition = ASPx.Position.Right;
26357  this.helpTextMargins = null;
26358  this.helpTextHAlign = ASPxClientTextEditHelpTextHAlign.Left;
26359  this.helpTextVAlign = ASPxClientTextEditHelpTextVAlign.Top;
26360  this.enableHelpTextPopupAnimation = true;
26361  this.helpTextDisplayMode = ASPxClientTextEditHelpTextDisplayMode.Inline;
26362  this.maskInfo = null;  
26363  this.maskValueBeforeUserInput = "";
26364  this.maskValueChangedByPassKeyPressOnAndroid = false;
26365  this.maskPasteTimerID = -1;
26366  this.maskPasteLock = false;    
26367  this.maskPasteCounter = 0;
26368  this.maskTextBeforePaste = "";    
26369  this.maskHintHtml = "";
26370  this.maskHintTimerID = -1;
26371  this.errorCellPosition = ASPx.Position.Right;
26372  this.inlineInitializeInputValue = null;
26373  this.initializeInputValue = null;
26374  this.displayFormat = null;
26375  this.TextChanged = new ASPxClientEvent();
26376  this.UserInput = new ASPxClientEvent();
26377  this.userInputEventTimerID = -1;
26378 },
26379 AddDefaultReadOnlyStateControllerItem: function(cssClass, mainElementId) {
26380  ASPx.AddReadOnlyItems(mainElementId, [[[cssClass], [''], ['', 'I']]]);
26381 },
26382 AddDefaultDisabledStateControllerItem: function(cssClass, mainElementId) {
26383  ASPx.AddDisabledItems(mainElementId, [[[cssClass], [''], ['', 'I']]]);
26384 },
26385 SetData: function(data){
26386  ASPxClientEdit.prototype.SetData.call(this, data);
26387  if(data.maskInfo) {
26388   var maskProperties = data.maskInfo.properties;
26389   var useInvariantCultureDecimalSymbol = maskProperties && maskProperties.useInvariantCultureDecimalSymbol || false;
26390   this.maskInfo = ASPx.MaskInfo.Create(data.maskInfo.maskText, data.maskInfo.dateTimeOnly, data.maskInfo.allowEscapingInEnums, useInvariantCultureDecimalSymbol);
26391   this.SetProperties(data.maskInfo.properties, this.maskInfo);
26392  }
26393 },
26394 InlineInitialize: function() {
26395  this.SaveInputValue(true);
26396  ASPxClientEdit.prototype.InlineInitialize.call(this);
26397  if(this.maskInfo != null)
26398   this.InitMask();
26399  this.ApplyBrowserSpecificClassName();
26400  this.helpTextInitialize();
26401 },
26402 Initialize: function(){
26403  this.SaveInputValue(false);
26404  this.SaveChangedValue();
26405  ASPxClientEdit.prototype.Initialize.call(this);
26406  if(ASPx.Browser.WebKitFamily)  
26407   this.CorrectMainElementWhiteSpaceStyle();
26408  this.InitializeTextDecoration();
26409  this.InitializeAutocompleteAttribute();
26410  if(this.IsValueRestoredByBrowser())
26411   this.SynchronizeRestoredValue();
26412 },
26413 InitializeEvents: function() {
26414  ASPxClientEdit.prototype.InitializeEvents.call(this);
26415  ASPx.Evt.AttachEventToElement(this.GetInputElement(), "keydown", this.OnKeyDown.aspxBind(this));
26416  ASPx.Evt.AttachEventToElement(this.GetInputElement(), "keyup", this.OnKeyUp.aspxBind(this));
26417  ASPx.Evt.AttachEventToElement(this.GetInputElement(), "keypress", this.OnKeyPress.aspxBind(this));
26418  if(this.isTextSelectionOnClickEnabled) {
26419   ASPx.Evt.AttachEventToElement(this.GetInputElement(), ASPx.TouchUIHelper.touchMouseDownEventName, this.OnMouseDown.aspxBind(this));
26420   ASPx.Evt.AttachEventToElement(this.GetInputElement(), "click", this.OnClick.aspxBind(this));
26421  }
26422  this.Unload.AddHandler(this.OnUnload.aspxBind(this));
26423 },
26424 InitializeTextDecoration: function() {
26425  var input = this.GetInputElement();
26426  if(input.type === "password" && !this.IsInputPasswordFilledAutomaticallyByChrome())
26427   this.ToggleTextDecoration();
26428 },
26429 IsInputPasswordFilledAutomaticallyByChrome: function() {
26430  if(!ASPx.Browser.Chrome)
26431   return false;
26432  var input = this.GetInputElement();
26433  return ASPx.ElementMatchesSelector(input, CHROME_AUTOFILL_SELECTOR);
26434 },
26435 OnMouseDown: function() {
26436  this.trySelectInputTextOnClick = ASPx.GetActiveElement() !== this.GetInputElement() && !this.IsFocusEventsLocked();
26437 },
26438 OnClick: function() {
26439  if(this.trySelectInputTextOnClick) {
26440   var input = this.GetInputElement();
26441   setTimeout(function() {
26442    var inputSelection = ASPx.Selection.GetInfo(input);
26443    if (inputSelection.startPos === inputSelection.endPos)
26444     ASPx.Selection.Set(input);
26445   }, 0);
26446  }
26447 },
26448 InitializeAutocompleteAttribute: function() {
26449  var input = this.GetInputElement();
26450  if(this.IsVCardAttributeRequired())
26451   ASPx.Attr.SetAttribute(input, this.autoCompleteAttribute.name, this.autoCompleteAttribute.value);
26452  else if(this.IsAutocompleteOffRequiredOnInitialize())
26453   ASPx.Attr.SetAttribute(input, "autocomplete", "off");
26454 },
26455 SaveInputValue: function(isInlineInitialize) {
26456  var input = this.GetInputElement();
26457  if(!input)
26458   return;
26459  var inputValue = input.value;
26460  if(inputValue === null)
26461   inputValue = "";
26462  if(isInlineInitialize)
26463   this.inlineInitializeInputValue = inputValue;
26464  else
26465   this.initializeInputValue = inputValue;
26466 },
26467 IsValueRestoredByBrowser: function() {
26468  if(this.displayFormat || this.isNative || this.inlineInitializeInputValue === null || this.initializeInputValue === null)
26469   return false;
26470  if(ASPx.Browser.Chrome)
26471   return this.IsValueRestoredByChrome();
26472  else if(ASPx.Browser.Firefox)
26473   return this.IsValueRestoredByFirefox();
26474  else
26475   return this.IsValueRestoredByBrowserCore();
26476 },
26477 IsValueRestoredByBrowserCore: function() {
26478  return this.IsValueChangedBeforeInitialize() || this.IsClientValueNotExists() || this.IsValueChangedOnMaskInitialize();
26479 },
26480 IsValueRestoredByChrome: function() {
26481  return this.IsValueRestoredByBrowserCore();
26482 },
26483 IsValueRestoredByFirefox: function() {
26484  return this.IsValueRestoredByBrowserCore();
26485 },
26486 IsValueChangedBeforeInitialize: function() {
26487  return this.inlineInitializeInputValue !== this.initializeInputValue;
26488 },
26489 IsClientValueNotExists: function() {
26490  return this.inlineInitializeInputValue !== "" &&
26491      this.inlineInitializeInputValue !== this.nullText &&
26492      this.inlineInitializeInputValue !== this.GetValue() &&
26493      this.inlineInitializeInputValue !== this.GetText();
26494 },
26495 IsValueChangedOnMaskInitialize: function() {
26496  return this.maskInfo && this.inlineInitializeInputValue !== this.GetInputElement().value;
26497 },
26498 SynchronizeRestoredValue: function() {
26499  this.SetText(this.initializeInputValue);
26500 },
26501 AdjustControl: function() {
26502  ASPxClientEdit.prototype.AdjustControl.call(this);
26503  this.ensureAdjustFocusedNullTextElement();
26504 },
26505 correctInputElementHeight: function() {
26506  var mainElement = this.GetMainElement();
26507  if(mainElement) {
26508   var mainElementHeight = mainElement.style.height;
26509   var mainElementHeightSpecified = mainElementHeight && mainElementHeight.indexOf('px') !== -1; 
26510   if(mainElementHeightSpecified) {
26511    var inputElement = this.GetInputElement();
26512    var inputElementHeight = this.getInputElementHeight();
26513    inputElement.style.height = inputElementHeight + "px";
26514    if(!ASPx.Ident.IsASPxClientMemo(this))
26515     inputElement.style.lineHeight = inputElementHeight + "px";
26516   }
26517  }
26518 },
26519 getInputElementHeight: function() {
26520  var mainElement = this.GetMainElement(),
26521   inputElement = this.GetInputElement();
26522  var inputElementHeight = ASPx.PxToInt(mainElement.style.height) - ASPx.GetTopBottomBordersAndPaddingsSummaryValue(mainElement);
26523  var inputElementContainer = inputElement.parentNode,
26524   inputContainerStyle = ASPx.GetCurrentStyle(inputElementContainer);
26525  inputElementHeight -= ASPx.GetTopBottomBordersAndPaddingsSummaryValue(inputElementContainer, inputContainerStyle) 
26526   + ASPx.GetTopBottomMargins(inputElementContainer, inputContainerStyle);
26527  var mainElementCellspacing = ASPx.GetCellSpacing(mainElement);
26528  if(mainElementCellspacing)
26529   inputElementHeight -= mainElementCellspacing * 2;
26530  var inputStyle = ASPx.GetCurrentStyle(inputElement);
26531  inputElementHeight -= ASPx.GetTopBottomBordersAndPaddingsSummaryValue(inputElement, inputStyle) 
26532   + ASPx.GetTopBottomMargins(inputElement, inputStyle);
26533  return inputElementHeight;
26534 },
26535 getInputCell: function() {
26536  var inputElement = this.GetInputElement();
26537  if(inputElement)
26538   return inputElement.parentNode;
26539 },
26540 ensureOutOfRangeWarningManager: function (minValue, maxValue, defaultMinValue, defaultMaxValue, valueFormatter) {
26541  if (!this.outOfRangeWarningManager)
26542   this.outOfRangeWarningManager = new ASPxOutOfRangeWarningManager(this, minValue, maxValue, defaultMinValue, defaultMaxValue,
26543    this.showOutOfRangeWarningElementAtBottom() ? ASPx.Position.Bottom : ASPx.Position.Right, valueFormatter);
26544 },
26545 showOutOfRangeWarningElementAtBottom: function() {
26546  return this.hasRightPopupHelpText();
26547 },
26548 GetOutOfRangeWarningElementPrevSibling: function() {
26549  return this.GetMainElement();
26550 },
26551 helpTextInitialize: function () {
26552  if(this.helpText) {
26553   this.helpTextObj = new ASPxClientTextEditHelpText(this, this.helpTextStyle, this.helpText, this.helpTextPosition,
26554    this.helpTextHAlign, this.helpTextVAlign, this.helpTextMargins, this.enableHelpTextPopupAnimation, this.helpTextDisplayMode);
26555  }
26556 },
26557 hasPopupHelpText: function() {
26558  return this.helpText && this.helpTextDisplayMode === ASPxClientTextEditHelpTextDisplayMode.Popup;
26559 },
26560 hasRightPopupHelpText: function() {
26561  return this.hasPopupHelpText() && this.helpTextPosition === ASPx.Position.Right;
26562 },
26563 showHelpText: function () {
26564  if(this.helpTextObj)
26565   this.helpTextObj.show();
26566 },
26567 hideHelpText: function () {
26568  if(this.helpTextObj)
26569   this.helpTextObj.hide();
26570 },
26571 ApplyBrowserSpecificClassName: function() {
26572  var mainElement = this.GetMainElement();
26573  if(ASPx.IsExistsElement(mainElement)) {
26574   var className = BrowserHelper.GetBrowserSpecificSystemClassName();
26575   if(className)
26576    mainElement.className += " " + className;
26577  }
26578 },
26579  CorrectMainElementWhiteSpaceStyle: function() {
26580  var inputElement = this.GetInputElement();
26581  if(inputElement && inputElement.parentNode) {
26582   if(this.IsElementHasWhiteSpaceStyle(inputElement.parentNode))
26583    inputElement.parentNode.style.whiteSpace = "normal";
26584  }
26585 },
26586 IsElementHasWhiteSpaceStyle: function(element) {
26587  var currentStyle = ASPx.GetCurrentStyle(element);
26588  return currentStyle.whiteSpace == "nowrap" || currentStyle.whiteSpace == "pre";  
26589 },
26590 FindInputElement: function(){
26591  return this.isNative ? this.GetMainElement() : ASPx.GetElementById(this.name + ASPx.TEInputSuffix);
26592 },
26593 DecodeRawInputValue: function(value) {
26594  return value;
26595 },
26596 GetRawValue: function(value){
26597  return ASPx.IsExists(this.stateObject) ? this.stateObject.rawValue : null;
26598 },
26599 SetRawValue: function(value){
26600  if(ASPx.IsExists(value))
26601   value = value.toString();
26602  this.UpdateStateObjectWithObject({ rawValue: value });
26603 },
26604 SyncRawValue: function() {
26605  if(this.maskInfo != null)
26606   this.SetRawValue(this.maskInfo.GetValue(true));
26607  else
26608   this.SetRawValue(this.GetInputElement().value);
26609 },
26610 HasTextDecorators: function() {
26611  return this.nullText != "" || this.displayFormat != null;
26612 },
26613 CanApplyTextDecorators: function(){
26614  return !this.focused;
26615 },
26616 CreateStyleDecoration: function () {
26617  return new ASPx.TextEditorStyleDecoration(this);
26618 },
26619 CanApplyNullTextDecoration: function() {
26620  var value = this.GetValue();
26621  return this.IsNull(value);
26622 },
26623 GetDecoratedText: function(value) {
26624  var result = value;
26625  if(this.IsNull(value) && this.nullText != "" && this.CanApplyNullTextDecoration())
26626   result = this.nullText;
26627  else if(this.displayFormat != null)
26628   result = this.GetDisplayFormatText(value);
26629  else if(this.maskInfo != null)
26630   result = this.maskInfo.GetText();
26631  else if(value == null)
26632   result = "";
26633  return result;
26634 },
26635 GetDisplayFormatText: function(value) {
26636  return ASPx.Formatter.Format(this.displayFormat, value);
26637 },
26638 ToggleTextDecoration: function() {
26639  if(this.HasTextDecorators()) {
26640   if(this.focused) {
26641    var input = this.GetInputElement();
26642    var oldValue = input.value;
26643    var sel = ASPx.Selection.GetExtInfo(input);
26644    this.ToggleTextDecorationCore();
26645    this.ensureActivateFocusedNullTextMechanism();
26646    if(oldValue != input.value || !ASPx.Selection.AreEqual(sel, ASPx.Selection.GetExtInfo(input))) {
26647     if(sel.startPos == 0 && sel.endPos == oldValue.length)
26648      sel.endPos = input.value.length;
26649     else
26650      sel.endPos = sel.startPos;
26651     if(!this.accessibilityCompliant || ASPx.GetActiveElement() == input)
26652      this.SetSelectionOnToggleTextDecoration(input, sel);
26653    }
26654   } else {
26655    this.ToggleTextDecorationCore();
26656    this.ensureDeactivateFocusedNullTextMechanism();
26657   }
26658  }
26659 },
26660 SetSelectionOnToggleTextDecoration: function(input, sel) {
26661  ASPx.Selection.Set(input, sel.startPos, sel.endPos);
26662 },
26663 ToggleTextDecorationCore: function() {
26664  if(this.maskInfo != null) {   
26665   this.ApplyMaskInfo(false);
26666  } else {
26667   var input = this.GetInputElement();
26668   var rawValue = this.GetRawValue();
26669   var value = this.CanApplyTextDecorators() ? this.GetDecoratedText(rawValue) : rawValue;
26670   if(input.value != value) {
26671    if(input.type == "password")
26672     this.TogglePasswordInputTextDecoration(value);
26673    else
26674     input.value = value;
26675   }
26676  }
26677 },
26678 GetPasswordNullTextInputElement: function() {
26679  if(!this.isPasswordNullTextInputElementExists())
26680   this.nullTextInputElement = this.createPasswordNullTextInputElement();
26681  return this.nullTextInputElement;
26682 },
26683 createPasswordNullTextInputElement: function() {
26684  var inputElement = this.GetInputElement(),
26685   nullTextInputElement = document.createElement("INPUT");
26686  nullTextInputElement.className = inputElement.className;
26687  nullTextInputElement.style.cssText = inputElement.style.cssText;
26688  nullTextInputElement.id = inputElement.id + passwordInputClonedSuffix;
26689  nullTextInputElement.type = "text";
26690  if(ASPx.IsExists(inputElement.tabIndex))
26691   nullTextInputElement.tabIndex = inputElement.tabIndex;
26692  nullTextInputElement.disabled = inputElement.disabled;
26693  var onFocusEventHandler = function() {
26694   var inputElement = this.GetInputElement(),
26695    nullTextInputElement = this.GetPasswordNullTextInputElement();
26696   if(inputElement) {
26697    this.LockFocusEvents();  
26698    ASPx.SetElementDisplay(inputElement, true);
26699    if((ASPx.Browser.MacOSMobilePlatform && ASPx.Browser.PlaformMajorVersion >= 14) || (ASPx.Browser.MacOSPlatform && ASPx.Browser.Safari && ASPx.Browser.Version >= 14)) { 
26700     ASPx.GetCurrentStyle(inputElement).display; 
26701    }
26702    inputElement.focus();
26703    ASPx.SetElementDisplay(nullTextInputElement, false);
26704    this.ensureAdjustFocusedNullTextElement();
26705    this.ReplaceAssociatedIdInLabels(nullTextInputElement.id, inputElement.id);
26706   }
26707  }.aspxBind(this);
26708  ASPx.Evt.AttachEventToElement(nullTextInputElement, "focus", onFocusEventHandler);
26709  return nullTextInputElement;
26710 },
26711 isPasswordNullTextInputElementExists: function() {
26712  return ASPx.IsExistsElement(this.nullTextInputElement);
26713 },
26714 TogglePasswordNullTextTimeoutChecker: function() {
26715  if(this.passwordNullTextIntervalID < 0) {
26716   var timeoutChecker = function() {
26717    var inputElement = this.GetInputElement();
26718    if(ASPx.GetControlCollection().GetByName(this.name) !== this || inputElement == null) {
26719     window.clearTimeout(this.passwordNullTextIntervalID);
26720     this.passwordNullTextIntervalID = -1;
26721     return;
26722    } else {
26723     if(!this.focused) {
26724      var passwordNullTextInputElement = this.GetPasswordNullTextInputElement();
26725      if(passwordNullTextInputElement.value != this.nullText && inputElement.value == "") { 
26726       passwordNullTextInputElement.value = this.nullText;
26727       this.SetValue(null);
26728      }
26729      if(inputElement.value != "") {
26730       if(inputElement.style.display == "none") {
26731        this.SetValue(inputElement.value);
26732        this.UnhidePasswordInput();
26733       }
26734      } else {
26735       if(inputElement.style.display != "none") {
26736        this.SetValue(null);
26737        this.HidePasswordInput();
26738       }
26739      }
26740     }
26741     else {
26742      var passwordNullTextInputElement = this.GetPasswordNullTextInputElement();
26743      if(passwordNullTextInputElement.value !== this.nullText && passwordNullTextInputElement.value !== "") { 
26744       if(inputElement.value === "")
26745        inputElement.value = passwordNullTextInputElement.value;
26746       passwordNullTextInputElement.value = this.nullText;
26747      }
26748     }
26749    }
26750   }.aspxBind(this);
26751   timeoutChecker(); 
26752   this.passwordNullTextIntervalID = window.setInterval(timeoutChecker, 100);
26753  }
26754 },
26755 TogglePasswordInputTextDecoration: function(value) {
26756  var inputElement = this.GetInputElement();
26757  var nullTextInputElement = this.GetPasswordNullTextInputElement();
26758  nullTextInputElement.value = value;
26759  var parentNode = inputElement.parentNode;
26760  if(ASPx.Data.ArrayIndexOf(parentNode.childNodes, nullTextInputElement) < 0) {
26761   ASPx.Attr.ChangeStyleAttribute(nullTextInputElement, "display", "none");
26762   ASPx.InsertElementAfter(nullTextInputElement, inputElement);
26763  }
26764  this.HidePasswordInput();
26765  this.TogglePasswordNullTextTimeoutChecker();
26766 },
26767 HidePasswordInput: function() {
26768  ASPx.Attr.ChangeStyleAttribute(this.GetInputElement(), "display", "none");
26769  ASPx.Attr.ChangeStyleAttribute(this.GetPasswordNullTextInputElement(), "display", "");
26770  this.ReplaceAssociatedIdInLabels(this.GetInputElement().id, this.GetPasswordNullTextInputElement().id);
26771 },
26772 UnhidePasswordInput: function() {
26773  ASPx.Attr.ChangeStyleAttribute(this.GetInputElement(), "display", "");
26774  ASPx.Attr.ChangeStyleAttribute(this.GetPasswordNullTextInputElement(), "display", "none");
26775  this.ReplaceAssociatedIdInLabels(this.GetPasswordNullTextInputElement().id, this.GetInputElement().id);
26776 },
26777 ReplaceAssociatedIdInLabels: function(oldId, newId) {
26778  var labels = document.getElementsByTagName("LABEL");
26779  for(var i = 0; i < labels.length; i++) {
26780   if(labels[i].attributes["for"] && labels[i].attributes["for"].value == oldId)
26781    labels[i].attributes["for"].value = newId;
26782  }
26783 },
26784 GetFormattedText: function() {
26785  var value = this.GetValue();
26786  if(this.IsNull(value) && this.nullText != "")
26787   return this.GetText();
26788  return this.GetDecoratedText(value);
26789 },
26790 IsNull: function(value) {
26791  return value == null || value === "";
26792 },
26793 PopulateStyleDecorationPostfixes: function() {
26794  ASPxClientEdit.prototype.PopulateStyleDecorationPostfixes.call(this);
26795  this.styleDecoration.AddPostfix(ASPx.TEInputSuffix);
26796  if(this.GetInputElement().type === "password" && this.nullText !== "")
26797   this.styleDecoration.AddPostfix(ASPx.TEInputSuffix + passwordInputClonedSuffix);
26798 },
26799 GetValue: function() {
26800  var value = null;
26801  if(this.maskInfo != null)
26802   value = this.maskInfo.GetValue();
26803  else if(this.HasTextDecorators())
26804   value = this.GetRawValue();
26805  else {
26806   var input = this.GetInputElement();
26807   value = input ? input.value : null;
26808  }
26809  return (value == "" && this.convertEmptyStringToNull) ? null : value;
26810 },
26811 SetValue: function(value) {
26812  if(value == null || value === undefined) 
26813   value = "";
26814  if(this.maskInfo != null) {
26815   this.maskInfo.SetValue(value.toString());
26816   this.ApplyMaskInfo(false);
26817   this.SavePrevMaskValue();
26818  } 
26819  else if(this.HasTextDecorators()) {
26820   this.SetRawValue(value);
26821   this.GetInputElement().value = this.CanApplyTextDecorators() && this.GetInputElement().type != "password" ? this.GetDecoratedText(value) : value;
26822  }
26823  else
26824   this.GetInputElement().value = value;
26825  this.UpdateStyleDecorations(); 
26826  this.SaveChangedValue();   
26827 },
26828 SetVisible: function(visible) {
26829  ASPxClientEdit.prototype.SetVisible.call(this, visible);
26830  if(this.helpTextDisplayMode === ASPxClientTextEditHelpTextDisplayMode.Inline) {
26831   if(visible)
26832    this.showHelpText();
26833   else
26834    this.hideHelpText();
26835  }
26836 },
26837 UnstretchInputElement: function(){
26838  var inputElement = this.GetInputElement();
26839  var mainElement = this.GetMainElement();
26840  var mainElementCurStyle = ASPx.GetCurrentStyle(mainElement);
26841  if(ASPx.IsExistsElement(mainElement) && ASPx.IsExistsElement(inputElement) && ASPx.IsExists(mainElementCurStyle) && 
26842   inputElement.style.width == "100%" &&
26843   (mainElementCurStyle.width == "" || mainElementCurStyle.width == "auto"))
26844   inputElement.style.width = "";
26845 },
26846 RestoreActiveElement: function(activeElement) {
26847  if(activeElement && activeElement.setActive && activeElement.tagName != "IFRAME")
26848   activeElement.setActive();
26849 },
26850 RaiseValueChangedEvent: function() {
26851  var processOnServer = ASPxClientEdit.prototype.RaiseValueChangedEvent.call(this);
26852  processOnServer = this.RaiseTextChanged(processOnServer);
26853  return processOnServer;
26854 },
26855 InitMask: function() {
26856  var rawValue = this.GetRawValue();
26857  this.SetValue(rawValue.length ? this.DecodeRawInputValue(rawValue) : this.maskInfo.GetValue());
26858  this.validationPatterns.unshift(new MaskValidationPattern(this.maskInfo.errorText, this.maskInfo));
26859 },
26860 SetMaskPasteTimer: function() {
26861  this.ClearMaskPasteTimer();
26862  this.maskPasteTimerID = ASPx.Timer.SetControlBoundInterval(this.MaskPasteTimerProc, this, ASPx.PasteCheckInterval);
26863 },
26864 ClearMaskPasteTimer: function() {
26865  this.maskPasteTimerID = ASPx.Timer.ClearInterval(this.maskPasteTimerID);
26866 },
26867 SavePrevMaskValue: function() {
26868  this.maskValueBeforeUserInput = this.maskInfo.GetValue();
26869 },
26870 FillMaskInfo: function() {
26871  var input = this.GetInputElement();
26872  if(!input) return; 
26873  var sel = ASPx.Selection.GetInfo(input);
26874  this.maskInfo.SetCaret(sel.startPos, sel.endPos - sel.startPos);  
26875 },
26876 ApplyMaskInfo: function(applyCaret) {
26877  this.SyncRawValue();
26878  var input = this.GetInputElement();
26879  var text = this.GetMaskDisplayText();
26880  this.maskTextBeforePaste = text;
26881  if(input.value != text)
26882   input.value = text;
26883  if(applyCaret)
26884   ASPx.Selection.Set(input, this.maskInfo.caretPos, this.maskInfo.caretPos + this.maskInfo.selectionLength);
26885 },
26886 GetMaskDisplayText: function() {
26887  if(!this.focused && this.HasTextDecorators())
26888   return this.GetDecoratedText(this.maskInfo.GetValue());
26889  return this.maskInfo.GetText();
26890 },
26891 ShouldCancelMaskKeyProcessing: function(htmlEvent, keyDownInfo) {
26892  return ASPx.Evt.IsEventPrevented(htmlEvent);
26893 }, 
26894 HandleMaskKeyDown: function(evt) {
26895  var keyInfo = ASPx.MaskManager.CreateKeyInfoByEvent(evt);
26896  ASPx.MaskManager.keyCancelled = this.ShouldCancelMaskKeyProcessing(evt, keyInfo);
26897  if(ASPx.MaskManager.keyCancelled) {
26898   ASPx.Evt.PreventEvent(evt);
26899   return;
26900  }
26901  this.maskPasteLock = true;
26902  this.FillMaskInfo();  
26903  var canHandle = ASPx.MaskManager.CanHandleControlKey(keyInfo);   
26904  ASPx.MaskManager.savedKeyDownKeyInfo = keyInfo;
26905  if(canHandle) {   
26906   ASPx.MaskManager.OnKeyDown(this.maskInfo, keyInfo);
26907   this.ApplyMaskInfo(true);
26908   ASPx.Evt.PreventEvent(evt);
26909  }
26910  ASPx.MaskManager.keyDownHandled = canHandle;
26911  this.maskPasteLock = false;
26912  this.UpdateMaskHintHtml();
26913 },
26914 HandleMaskKeyPress: function(evt) {
26915  var keyInfo = ASPx.MaskManager.CreateKeyInfoByEvent(evt);
26916  ASPx.MaskManager.keyCancelled = ASPx.MaskManager.keyCancelled || this.ShouldCancelMaskKeyProcessing(evt, ASPx.MaskManager.savedKeyDownKeyInfo);
26917  if(ASPx.MaskManager.keyCancelled) {
26918   ASPx.Evt.PreventEvent(evt);
26919   return;
26920  }
26921  this.maskPasteLock = true;  
26922  var printable = ASPx.MaskManager.savedKeyDownKeyInfo != null && ASPx.MaskManager.IsPrintableKeyCode(ASPx.MaskManager.savedKeyDownKeyInfo);
26923  if(printable) {
26924   ASPx.MaskManager.OnKeyPress(this.maskInfo, keyInfo);
26925   this.ApplyMaskInfo(true);
26926  }
26927  if(printable || ASPx.MaskManager.keyDownHandled)   
26928   ASPx.Evt.PreventEvent(evt); 
26929  this.maskPasteLock = false;
26930  this.UpdateMaskHintHtml();
26931 },
26932 MaskPasteTimerProc: function() {
26933  if(this.maskPasteLock || !this.maskInfo) return;
26934  this.maskPasteCounter++;
26935  var inputElement = this.inputElement;
26936  if(!inputElement || this.maskPasteCounter > 40) {
26937   this.maskPasteCounter = 0;
26938   inputElement = this.GetInputElement();
26939   if(!ASPx.IsExistsElement(inputElement)) {
26940    this.ClearMaskPasteTimer();
26941    return;
26942   }
26943  }
26944  if(this.maskTextBeforePaste !== inputElement.value)
26945   this.ProcessInputValueChangedOnTimer();
26946  if(!this.focused)
26947   this.ClearMaskPasteTimer();
26948 },
26949 ProcessInputValueChangedOnTimer: function() {
26950  var inputElement = this.inputElement;
26951  var selectionInfo = ASPx.Selection.GetInfo(inputElement);
26952  var startCaretPosition = selectionInfo.startPos;
26953  var endCaretPosition = selectionInfo.endPos;
26954  var oldText = this.maskTextBeforePaste;
26955  var newText = inputElement.value;
26956  var isAndroidBackSpacePressed = this.isAndroidBackSpacePressed(oldText, newText, startCaretPosition, endCaretPosition);
26957  var isLastTypedCharacter = newText.indexOf(oldText) == 0 && newText.length > oldText.length;
26958  if(isAndroidBackSpacePressed || isLastTypedCharacter) {
26959   this.SetText(newText);
26960   this.SetCaretPosition(endCaretPosition);
26961   this.maskValueChangedByPassKeyPressOnAndroid = true;
26962  } else {
26963   this.maskInfo.ProcessPaste(newText, endCaretPosition);
26964   this.ApplyMaskInfo(true);
26965  }
26966 },
26967 isAndroidBackSpacePressed: function(oldText, newText, startCaretPosition, endCaretPosition) {
26968  if(!ASPx.Browser.AndroidMobilePlatform || startCaretPosition !== endCaretPosition || newText.length >= oldText.length)
26969   return false;
26970  var startSubstring = newText.substring(0, startCaretPosition);
26971  var endSubstring = newText.substring(startCaretPosition);
26972  var isStartSubstringMatches = oldText.indexOf(startSubstring) == 0;
26973  var isEndSubstringMatches = endSubstring == "" || oldText.lastIndexOf(endSubstring) == oldText.length - endSubstring.length;
26974  return isStartSubstringMatches && isEndSubstringMatches;
26975 },
26976 BeginShowMaskHint: function() {
26977  if(!this.GetReadOnly() && this.maskHintTimerID == -1)
26978   this.maskHintTimerID = window.setInterval(ASPx.MaskHintTimerProc, 500);
26979 },
26980 EndShowMaskHint: function() {
26981  window.clearInterval(this.maskHintTimerID);
26982  this.maskHintTimerID = -1;
26983 },
26984 MaskHintTimerProc: function() {  
26985  if(this.maskInfo) {
26986   this.FillMaskInfo();
26987   this.UpdateMaskHintHtml();
26988  } else {
26989   this.EndShowMaskHint();
26990  }
26991 },
26992 UpdateMaskHintHtml: function() {  
26993  var hint =  this.GetMaskHintElement();
26994  if(!ASPx.IsExistsElement(hint))
26995   return;
26996  var html = ASPx.MaskManager.GetHintHtml(this.maskInfo);
26997  if(html == this.maskHintHtml)
26998   return;
26999  if(html != "") {
27000   var mainElement = this.GetMainElement();
27001   if(ASPx.IsExistsElement(mainElement)) {
27002    hint.innerHTML = html;
27003    hint.style.position = "absolute";  
27004    hint.style.left = ASPx.PrepareClientPosForElement(ASPx.GetAbsoluteX(mainElement), mainElement, true) + "px";
27005    hint.style.top = (ASPx.PrepareClientPosForElement(ASPx.GetAbsoluteY(mainElement), mainElement, false) + mainElement.offsetHeight + 2) + "px";
27006    hint.style.display = "block";    
27007   }   
27008  } else {
27009   hint.style.display = "none";
27010  }
27011  this.maskHintHtml = html;
27012 },
27013 HideMaskHint: function() {
27014  var hint =  this.GetMaskHintElement();
27015  if(ASPx.IsExistsElement(hint))
27016   hint.style.display = "none";
27017  this.maskHintHtml = "";
27018 },
27019 GetMaskHintElement: function() {
27020  return ASPx.GetElementById(this.name + "_MaskHint");
27021 },
27022 OnLostFocus: function() {
27023  if(this.IsAutocompleteOffRequiredOnLostFocus())
27024   ASPx.Attr.SetAttribute(this.GetInputElement(), "autocomplete", "off");
27025  ASPxClientEdit.prototype.OnLostFocus.call(this);
27026 },
27027 OnMouseWheel: function(evt){
27028  if(this.GetReadOnly() || this.maskInfo == null || !this.maskInfo.allowMouseWheel)
27029   return;
27030  this.FillMaskInfo();
27031  ASPx.MaskManager.OnMouseWheel(this.maskInfo, ASPx.Evt.GetWheelDelta(evt) < 0 ? -1 : 1);
27032  this.ApplyMaskInfo(true);
27033  ASPx.Evt.PreventEvent(evt);
27034  this.UpdateMaskHintHtml();
27035 }, 
27036 OnBrowserWindowResize: function(e) {
27037  if(!this.autoResizeWithContainer)
27038   this.AdjustControl();
27039 },
27040 IsValueChanged: function() {
27041  return this.GetValue() != this.lastChangedValue; 
27042 },
27043 OnKeyDown: function(evt) {        
27044  if(!(evt instanceof KeyboardEvent) || this.NeedPreventBrowserUndoBehaviour(evt))
27045   return ASPx.Evt.PreventEvent(evt);
27046  if(this.RequireHandleMaxlenManually()) {
27047   this.onKeyDownInputValue = this.GetInputElement().value;
27048   var selectionInfo = ASPx.Selection.GetExtInfo(this.GetInputElement());
27049   this.onKeyDownCursorPos = selectionInfo.startPos;
27050  }
27051  this.escCount = 0;
27052  ASPxClientEdit.prototype.OnKeyDown.call(this, evt);
27053  if(!this.IsRaiseStandardOnChange(evt)) {
27054   if(!this.GetReadOnly() && this.maskInfo != null)
27055    this.HandleMaskKeyDown(evt);
27056  }
27057 },
27058 IsCtrlZ: function(evt) {
27059  return evt.ctrlKey && !evt.altKey && !evt.shiftKey && (ASPx.Evt.GetKeyCode(evt) == 122 || ASPx.Evt.GetKeyCode(evt) == 90);
27060 },
27061 NeedPreventBrowserUndoBehaviour: function(evt) {
27062  var inputElement = this.GetInputElement();
27063  return this.IsCtrlZ(evt) && !!inputElement && !inputElement.value;
27064 },
27065 OnKeyPress: function(evt) {
27066  ASPxClientEdit.prototype.OnKeyPress.call(this, evt);
27067  if(!this.GetReadOnly() && this.maskInfo != null && !this.IsRaiseStandardOnChange(evt))
27068   this.HandleMaskKeyPress(evt);
27069  if(this.NeedOnKeyEventEnd(evt, true))
27070   this.OnKeyEventEnd(evt);
27071 },
27072 OnKeyUp: function(evt) {
27073  if(!(evt instanceof KeyboardEvent) || ASPx.Browser.Firefox && !this.focused && ASPx.Evt.GetKeyCode(evt) === ASPx.Key.Tab)
27074   return;
27075  if(this.NeedOnKeyEventEnd(evt, false)) {
27076   var proccessNextCommingPress = ASPx.Evt.GetKeyCode(evt) === ASPx.Key.Alt; 
27077   this.OnKeyEventEnd(evt, proccessNextCommingPress);
27078  }
27079  if(this.RequireHandleMaxlenManually()) {
27080   var inputValueLength = this.GetInputElement().value.length;
27081   var maxLength = this.GetInputMaxLength();
27082   if(inputValueLength > maxLength && inputValueLength > this.onKeyDownInputValue.length) {
27083    this.GetInputElement().value = this.onKeyDownInputValue;
27084    this.SetCaretPosition(this.onKeyDownCursorPos);
27085   }
27086  }
27087  ASPxClientEdit.prototype.OnKeyUp.call(this, evt);
27088 },
27089 RequireHandleMaxlenManually: function() { 
27090  return ASPx.Browser.AndroidMobilePlatform && ASPx.Browser.SamsungAndroidDevice && ASPx.Browser.PlaformMajorVersion < 6 && this.GetInputMaxLength() !== -1;
27091 },
27092 GetInputMaxLength: function() {
27093  var input = this.GetInputElement();
27094  if(ASPx.Attr.IsExistsAttribute(input, "maxlength"))
27095   return input.maxLength;
27096  return -1;
27097 },
27098 NeedOnKeyEventEnd: function(evt, isKeyPress) { 
27099  var handleKeyPress = this.maskInfo != null && evt.keyCode == ASPx.Key.Enter;
27100  return handleKeyPress == isKeyPress;
27101 },
27102 OnKeyEventEnd: function(evt, withDelay){
27103  if(!this.GetReadOnly()) {
27104   if(this.IsRaiseStandardOnChange(evt))
27105    this.RaiseStandardOnChange();
27106   this.SyncRawValueIfHasTextDecorators(withDelay);
27107  }
27108 },
27109 SyncRawValueIfHasTextDecorators: function(withDelay) {
27110  if(this.HasTextDecorators()) {
27111   if(withDelay) {
27112    window.setTimeout(function() {
27113     this.SyncRawValue();
27114    }.aspxBind(this), 0);
27115   } else 
27116    this.SyncRawValue();
27117  }
27118 },
27119 IsRaiseStandardOnChange: function(evt){
27120  return !this.UseSpecialKeyboardHandling() && this.raiseValueChangedOnEnter && evt.keyCode == ASPx.Key.Enter;
27121 },
27122 GetFocusSelectAction: function() {
27123  if (this.maskInfo)
27124   return this.maskInfo.IsEmpty() ? null : "start";
27125  return "all"; 
27126 },
27127 CorrectFocusWhenDisabled: function() {
27128  if(!this.GetEnabled()) {
27129   var inputElement = this.GetInputElement();
27130   if(inputElement)
27131    inputElement.blur();
27132   return true;
27133  }
27134  return false;
27135 },
27136 EnsureShowPopupHelpText: function() {
27137  if(this.helpTextDisplayMode === ASPxClientTextEditHelpTextDisplayMode.Popup)
27138   this.showHelpText();
27139 },
27140 EnsureHidePopupHelpText: function() {
27141  if(this.helpTextDisplayMode === ASPxClientTextEditHelpTextDisplayMode.Popup)
27142   this.hideHelpText();
27143 },
27144 OnFocusCore: function() {
27145  if(this.maskInfo != null && !ASPx.GetControlCollection().InCallback()) {
27146   this.TrySetCursorToStartPosition();
27147   this.SetMaskPasteTimer();
27148  }
27149  if(this.IsAutocompleteDropDownListRequiredOnFocus())
27150   ASPx.Attr.RemoveAttribute(this.GetInputElement(), "autocomplete");
27151  if(this.CorrectFocusWhenDisabled())
27152   return;
27153  var wasLocked = this.IsFocusEventsLocked();
27154  ASPxClientEdit.prototype.OnFocusCore.call(this);
27155  if(this.maskInfo != null) {
27156   this.SavePrevMaskValue();
27157   this.BeginShowMaskHint();
27158  }
27159  if(!wasLocked) {
27160   this.ToggleTextDecoration();
27161   this.startUserInputEventTimerIfRequired();
27162  }
27163  if(this.isPasswordNullTextInputElementExists())
27164   setTimeout(function() { this.EnsureShowPopupHelpText(); }.aspxBind(this), 0);
27165  else
27166   this.EnsureShowPopupHelpText();
27167 },
27168 startUserInputEventTimerIfRequired: function () {
27169  if(this.shouldStartUserInputTimer() && this.userInputEventTimerID === -1) {
27170   this.prevInputValue = this.GetInputElement().value;
27171   this.userInputEventTimerID = ASPx.Timer.SetControlBoundInterval(this.processUserInputEventTimer, this, ASPx.CheckUserInputInterval);
27172  }
27173 },
27174 shouldStartUserInputTimer: function() {
27175  return !this.UserInput.IsEmpty();
27176 },
27177 restartCurrentUserInputTimer: function() {
27178  if(this.userInputEventTimerID !== -1) {
27179   this.processUserInputEventTimer(true);
27180   this.clearUserInputEventTimerIfRequired();
27181   this.startUserInputEventTimerIfRequired();
27182  }
27183 },
27184 clearUserInputEventTimerIfRequired: function () {
27185  if (this.userInputEventTimerID !== -1)
27186   this.userInputEventTimerID = ASPx.Timer.ClearInterval(this.userInputEventTimerID);
27187 },
27188 processUserInputEventTimer: function(onRestart) {
27189  var currentInputValue = this.GetInputElement().value;
27190  if(currentInputValue !== this.prevInputValue) {
27191   this.onInputChangedOnUserInputTimer(onRestart);
27192   this.prevInputValue = currentInputValue;
27193  }
27194 },
27195 onInputChangedOnUserInputTimer: function(onRestart) {
27196  if(this.raiseUserInputTimeout > -1)
27197   clearTimeout(this.raiseUserInputTimeout);
27198  this.raiseUserInputTimeout = setTimeout(function() {
27199   this.RaiseUserInput();
27200   this.raiseUserInputTimeout = -1;
27201  }.bind(this), 0);
27202 },
27203 ensureFocusedNullTextElement: function () {
27204  if(!this.focusedNullTextElement)
27205   this.createFocusedNullTextElement();
27206 },
27207 getFocusedNullTextElementClassName: function() {
27208  return focusedNullTextClassName;
27209 },
27210 getFocusedNullTextElementTagName: function() {
27211  return "INPUT";
27212 },
27213 getCopyFromInputElementStyles: function() {
27214  return [ "paddingLeft", "paddingTop", "paddingRight", "paddingBottom", "borderCollapse", "borderLeftWidth", "borderTopWidth", "borderRightWidth", "borderBottomWidth" ];
27215 },
27216 copyStylesFromInputElementToFocusedNullTextElement: function() {
27217  var input = this.GetInputElement();
27218  var inputStyle = ASPx.GetCurrentStyle(input);
27219  var stylesToCopy = this.getCopyFromInputElementStyles();
27220  for(var i = 0; i < stylesToCopy.length; i++)
27221   this.focusedNullTextElement.style[stylesToCopy[i]] = inputStyle[stylesToCopy[i]];
27222 },
27223 createFocusedNullTextElement: function() {
27224  this.focusedNullTextElement = document.createElement(this.getFocusedNullTextElementTagName());
27225  this.focusedNullTextElement.value = this.nullText;
27226  this.focusedNullTextElement.className = this.getFocusedNullTextElementClassName();
27227  this.focusedNullTextElement.tabIndex = -1;
27228  ASPx.SetElementDisplay(this.focusedNullTextElement, false);
27229  if(this.accessibilityCompliant) {
27230   ASPx.Attr.SetAttribute(this.focusedNullTextElement, "aria-label", this.nullText);
27231   ASPx.Attr.SetAttribute(this.focusedNullTextElement, "aria-hidden", true);
27232  }
27233  this.copyStylesFromInputElementToFocusedNullTextElement();
27234  if (this.nullTextOnFocusCssText) {
27235   var styleSheet = ASPx.GetCurrentStyleSheet();
27236   this.focusedNullTextElement.className += " " + ASPx.CreateImportantStyleRule(styleSheet, this.nullTextOnFocusCssText);
27237  }
27238  var inputElement = this.GetInputElement();
27239  inputElement.parentNode.insertBefore(this.focusedNullTextElement, inputElement.nextSibling);
27240 },
27241 ensureActivateFocusedNullTextMechanism: function() {
27242  if (this.nullTextDisplayMode === NullTextDisplayMode.UnfocusedAndFocused) {
27243   if(this.IsNull(this.GetValue()))
27244    this.changeFocusedNullTextElementVisibility(true);
27245   this.setFocusedNullTextTimer();
27246  }
27247 },
27248 ensureDeactivateFocusedNullTextMechanism: function () {
27249  if (this.nullTextDisplayMode === NullTextDisplayMode.UnfocusedAndFocused) {
27250   this.clearFocusedNullTextTimer();
27251   this.changeFocusedNullTextElementVisibility(false);
27252  }
27253 },
27254 setFocusedNullTextTimer: function () {
27255  if(this.focusedNullTextTimerID === -1)
27256   this.focusedNullTextTimerID = ASPx.Timer.SetControlBoundInterval(this.onFocusedNullTextVisibilityCheck, this, ASPx.PasteCheckInterval);
27257 },
27258 clearFocusedNullTextTimer: function () {
27259  this.focusedNullTextTimerID = ASPx.Timer.ClearInterval(this.focusedNullTextTimerID);
27260 },
27261 onFocusedNullTextVisibilityCheck: function (evt) {
27262  if(!this.needShowFocusedNullText() && this.isFocusedNullTextElementDisplayed())
27263   this.changeFocusedNullTextElementVisibility(false);
27264  else if(this.needShowFocusedNullText() && !this.isFocusedNullTextElementDisplayed())
27265   this.changeFocusedNullTextElementVisibility(true);
27266 },
27267 isFocusedNullTextElementDisplayed: function() {
27268  return this.focusedNullTextElement && ASPx.GetElementDisplay(this.focusedNullTextElement);
27269 },
27270 needShowFocusedNullText: function() {
27271  if(this.focusedNullTextTimerID === -1)
27272   return this.IsNull(this.GetValue());
27273  var result = this.GetInputElement().value === "";
27274  if(this.CanApplyNullTextDecoration)
27275   result = result && this.CanApplyNullTextDecoration();
27276  return result;
27277 }, 
27278 changeFocusedNullTextElementVisibility: function (visible) {
27279  this.ensureFocusedNullTextElement();
27280  ASPx.SetElementDisplay(this.focusedNullTextElement, visible);
27281  if(visible)
27282   this.adjustFocusedNullTextElement();  
27283 },
27284 getInputElementAbsoluteX: function(input) {
27285  var result = ASPx.GetAbsoluteX(input);
27286  if(ASPx.Browser.Opera || ASPx.Browser.AndroidMobilePlatform) 
27287   result++;
27288  return result;
27289 },
27290 getInputElementAbsoluteY: function (input) {
27291  var result = ASPx.GetAbsoluteY(input);
27292  if(ASPx.Browser.Opera || ASPx.Browser.AndroidMobilePlatform) 
27293   result++;
27294  return result;
27295 },
27296 adjustFocusedNullTextElement: function() {
27297  var input = this.GetInputElement();
27298  this.focusedNullTextElement.style.width = input.offsetWidth + "px";
27299  this.focusedNullTextElement.style.height = input.offsetHeight + "px";
27300  var inputXPos = this.getInputElementAbsoluteX(input);
27301  var inputYPos = this.getInputElementAbsoluteY(input);
27302  ASPx.SetAbsoluteX(this.focusedNullTextElement, inputXPos);
27303  ASPx.SetAbsoluteY(this.focusedNullTextElement, inputYPos);
27304  var shiftByX = inputXPos - ASPx.GetAbsoluteX(this.focusedNullTextElement);
27305  var shiftByY = inputYPos - ASPx.GetAbsoluteY(this.focusedNullTextElement);
27306  if (shiftByX !== 0)
27307   this.focusedNullTextElement.style.left = ASPx.PxToFloat(this.focusedNullTextElement.style.left) + shiftByX + "px";
27308  if (shiftByY !== 0)
27309   this.focusedNullTextElement.style.top = ASPx.PxToFloat(this.focusedNullTextElement.style.top) + shiftByY + "px";
27310 },
27311 ensureAdjustFocusedNullTextElement: function () {
27312  if(this.isFocusedNullTextElementDisplayed())
27313   this.adjustFocusedNullTextElement(this.focusedNullTextElement);
27314 },
27315 TrySetCursorToStartPosition: function() {
27316  var input = this.GetInputElement();
27317  var sel = ASPx.Selection.GetInfo(input);
27318  if (sel.startPos === sel.endPos && this.IsMaskInfoEmpty()) {
27319   var pos = this.maskInfo.GetFirstNonLiteralPosition();
27320   var setCaret = ASPx.Selection.SetCaretPosition.bind(this, input, pos);
27321   setTimeout(function() {
27322    if (document.activeElement === input) {
27323     setCaret();
27324     setTimeout(setCaret, 50);
27325    }
27326   }, 0);
27327  }
27328 },
27329 IsMaskInfoEmpty: function() {
27330  return this.maskInfo.IsEmpty();
27331 },
27332 OnLostFocusCore: function() {
27333  var wasLocked = this.IsFocusEventsLocked();
27334  ASPxClientEdit.prototype.OnLostFocusCore.call(this);
27335  if(this.maskInfo != null) {
27336   this.EndShowMaskHint();
27337   this.HideMaskHint();   
27338   if(this.maskInfo.ApplyFixes(null))
27339    this.ApplyMaskInfo(false);
27340   this.RaiseStandardOnChange();
27341  }
27342  if(!wasLocked) {
27343   this.clearUserInputEventTimerIfRequired();
27344   this.ToggleTextDecoration();
27345  }
27346  this.escCount = 0;
27347  this.EnsureHidePopupHelpText();
27348 },
27349 SetFocus: function() {
27350  if(this.isPasswordNullTextInputElementExists()) {
27351   this.GetPasswordNullTextInputElement().focus();
27352  } else {
27353     ASPxClientEdit.prototype.SetFocus.call(this);
27354  }
27355 },
27356 OnValueChanged: function() {
27357  if(this.maskInfo != null) {
27358   if(!this.maskValueChangedByPassKeyPressOnAndroid && this.maskInfo.GetValue() == this.maskValueBeforeUserInput && !this.IsValueChangeForced())
27359    return;
27360   if(this.maskValueChangedByPassKeyPressOnAndroid)
27361    this.maskValueChangedByPassKeyPressOnAndroid = false;
27362   this.SavePrevMaskValue();
27363  }
27364  if(this.HasTextDecorators())
27365   this.SyncRawValue();
27366  if(!this.IsValueChanged() && !this.IsValueChangeForced())
27367   return;
27368  this.SaveChangedValue(); 
27369  ASPxClientEdit.prototype.OnValueChanged.call(this);
27370 },
27371 IsValueChangeForced: function() {
27372  return false;
27373 },
27374 OnTextChanged: function() {
27375 },
27376 ForceTextChanged: function() {
27377  this.OnTextChanged();
27378 },
27379 SaveChangedValue: function() {
27380  this.lastChangedValue = this.GetValue();
27381 },
27382 RaiseStandardOnChange: function(){
27383  var element = this.GetInputElement();
27384  if(element && element.onchange) {
27385   element.onchange({ target: this.GetInputElement() });
27386  }
27387  else if(this.ValueChanged) {
27388   this.ValueChanged.FireEvent(this);
27389  }
27390 },
27391 RaiseTextChanged: function(processOnServer){
27392  if(!this.TextChanged.IsEmpty()){
27393   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
27394   this.TextChanged.FireEvent(this, args);
27395   processOnServer = args.processOnServer;
27396  }
27397  return processOnServer;  
27398 },
27399 RaiseUserInput: function () {
27400  if(!this.UserInput.IsEmpty()) {
27401   var args = new ASPxClientEventArgs();
27402   this.UserInput.FireEvent(this, args);
27403  }
27404 },
27405 GetText: function(){
27406  if(this.maskInfo != null) {
27407   return this.maskInfo.GetText();
27408  } else {
27409   var value = this.GetValue();
27410   return value != null ? value : "";
27411  }
27412 },
27413 SetText: function (value){
27414  if(this.maskInfo != null) {
27415   this.maskInfo.SetText(value);
27416   this.ApplyMaskInfo(false);
27417   this.SavePrevMaskValue();
27418  } else {
27419   this.SetValue(value);
27420  }
27421 },
27422 SelectAll: function() {
27423  this.SetSelection(0, -1, false);
27424 },
27425 SetCaretPosition: function(pos) {
27426  var inputElement = this.GetInputElement();
27427  ASPx.Selection.SetCaretPosition(inputElement, pos);
27428 },
27429 GetCaretPosition: function() {
27430  var inputElement = this.GetInputElement();
27431  return ASPx.Selection.GetCaretPosition(inputElement);
27432 },
27433 SetSelection: function(startPos, endPos, scrollToSelection) { 
27434  var inputElement = this.GetInputElement();
27435  ASPx.Selection.Set(inputElement, startPos, endPos, scrollToSelection, true);
27436 },
27437 ChangeEnabledAttributes: function(enabled){
27438  var inputElement = this.GetInputElement();
27439  if(inputElement){
27440   this.ChangeInputEnabledAttributes(inputElement, ASPx.Attr.ChangeAttributesMethod(enabled), enabled);
27441   this.ChangeSpecialInputEnabledAttributes(inputElement, ASPx.Attr.ChangeEventsMethod(enabled), true);
27442   this.ChangeInputEnabled(inputElement, enabled, this.GetReadOnly());
27443   if(this.isPasswordNullTextInputElementExists())
27444    this.GetPasswordNullTextInputElement().disabled = inputElement.disabled;
27445  }
27446 },
27447 SetReadOnlyInternal: function(readOnly) {
27448  ASPxClientEdit.prototype.SetReadOnlyInternal.call(this, readOnly);
27449  this.ChangeInputReadOnly(readOnly);
27450 },
27451 ChangeReadOnlyStateItems: function(readOnly) {
27452  ASPxClientEdit.prototype.ChangeReadOnlyStateItems.call(this, readOnly);
27453  ASPx.GetStateController().SetElementReadOnly(this.GetInputElement(), readOnly);
27454  if(this.isPasswordNullTextInputElementExists())
27455   ASPx.GetStateController().SetElementReadOnly(this.GetPasswordNullTextInputElement(), readOnly);
27456 },
27457 ChangeInputReadOnly: function(readOnly) {
27458  var inputElement = this.GetInputElement();
27459  if(inputElement)
27460   inputElement.readOnly = readOnly || !this.GetEnabled() && this.UseReadOnlyForDisabled();
27461 },
27462 ChangeEnabledStateItems: function(enabled){
27463  if(!this.isNative) {
27464   var sc = ASPx.GetStateController();
27465   sc.SetElementEnabled(this.GetMainElement(), enabled);
27466   sc.SetElementEnabled(this.GetInputElement(), enabled);
27467   if(this.isPasswordNullTextInputElementExists())
27468    sc.SetElementEnabled(this.GetPasswordNullTextInputElement(), enabled);
27469  }
27470 },
27471 ChangeInputEnabled: function(element, enabled, readOnly) {
27472  if(this.UseReadOnlyForDisabled())
27473   element.readOnly = !enabled || readOnly;
27474  else
27475   element.disabled = !enabled;
27476 },
27477 ChangeInputEnabledAttributes: function(element, method, enabled) {
27478  method(element, "tabIndex");
27479  if(!enabled) element.tabIndex = -1;
27480  method(element, "onclick");
27481  method(element, "onkeydown");
27482  method(element, "onkeypress");
27483  method(element, "onkeyup");
27484 },
27485 UseReadOnlyForDisabled: function() {
27486  return false;
27487 },
27488 OnPostFinalization: function(args) {
27489  this.TryRestoreDisabledOnPost(args);
27490  this.TryClearInputTextDecorationOnPost(args);
27491 },
27492 TryRestoreDisabledOnPost: function(args) { 
27493  if(this.GetEnabled() || !this.UseReadOnlyForDisabled() || args.isDXCallback)
27494   return;
27495  var inputElement = this.GetInputElement();
27496  if(inputElement) {
27497   var inputDisabled = inputElement.disabled;
27498   inputElement.disabled = true;
27499   window.setTimeout(function() {
27500    inputElement.disabled = inputDisabled;
27501   }, 0);
27502  }
27503 },
27504 GetTempHiddenInputID: function() {
27505  return this.name + ASPx.TempHiddenInputSuffix;
27506 },
27507 TryClearInputTextDecorationOnPost: function(args) {
27508  if(ASPx.Platform === "NETCORE")
27509   return;
27510  if(this.HasTextDecorators() && !ASPx.IsExists(this.GetValue())) {
27511   var inputElement = this.GetInputElement();
27512   if(inputElement) {
27513    var name = ASPx.Attr.GetAttribute(inputElement, "name");
27514    if(name)
27515     this.TryClearInputTextDecorationOnPostCore(inputElement, name);
27516   }
27517  }
27518 },
27519 TryClearInputTextDecorationOnPostCore: function(inputElement, name) {
27520  var hiddenInput = ASPx.CreateHiddenField(name, this.GetTempHiddenInputID(), inputElement.parentNode);
27521  ASPx.Attr.SetAttribute(inputElement, "data-name", name);
27522  ASPx.Attr.RemoveAttribute(inputElement, "name");
27523  setTimeout(function() {
27524   ASPx.Attr.SetAttribute(inputElement, "name", name);
27525   ASPx.Attr.RemoveAttribute(inputElement, "data-name");
27526   ASPx.RemoveElement(hiddenInput);
27527  }, 0);
27528 },
27529 OnUnload: function() {
27530  var input = this.GetInputElement();
27531  if(!input)
27532   return;
27533  if(this.IsAutocompleteOffNotRequiredOnUnload())
27534   ASPx.Attr.RemoveAttribute(input, "autocomplete");
27535  if(this.focusedNullTextElement)
27536   ASPx.RemoveElement(this.focusedNullTextElement);
27537 },
27538 IsVCardAttributeRequired: function() {
27539  return this.autoCompleteAttribute && this.autoCompleteAttribute.name !== "autocomplete";
27540 },
27541 IsAutocompleteDropDownListRequiredOnFocus: function() {
27542  return !this.autoCompleteAttribute || this.IsVCardAttributeRequired();
27543 },
27544 IsAutocompleteOffRequiredOnInitialize: function() {
27545  return !this.isNative && (this.autoCompleteAttribute && this.autoCompleteAttribute.name === "autocomplete" || ASPx.Browser.WebKitFamily);
27546 },
27547 IsAutocompleteOffRequiredOnLostFocus: function() {
27548  return !this.autoCompleteAttribute && this.IsNullTextVisible() && !this.IsVCardAttributeRequired();
27549 },
27550 IsAutocompleteOffNotRequiredOnUnload: function() {
27551  return !this.IsNullTextVisible() || this.IsVCardAttributeRequired() || (this.maskInfo != null && this.GetValue() == null);
27552 },
27553 IsNullTextVisible: function() {
27554  return this.nullText && !this.GetValue() && !this.GetText();
27555 },
27556 GetModifyEvent: function() {
27557  return this.UserInput;
27558 }
27559});
27560MaskValidationPattern = ASPx.CreateClass(ASPx.ValidationPattern, {
27561 constructor: function(errorText, maskInfo) {
27562  this.constructor.prototype.constructor.call(this, errorText);
27563  this.maskInfo = maskInfo;
27564 },
27565 EvaluateIsValid: function(value) {
27566  return this.maskInfo.IsValid();
27567 }
27568});
27569ASPx.Ident.IsASPxClientTextEdit = function(obj) {
27570 return !!obj.isASPxClientTextEdit;
27571};
27572var ASPxClientTextBoxBase = ASPx.CreateClass(ASPxClientTextEdit, {
27573 constructor: function(name) {
27574  this.constructor.prototype.constructor.call(this, name);
27575  this.sizingConfig.allowSetHeight = false;
27576  this.sizingConfig.adjustControl = true;
27577 }
27578});
27579var ASPxClientTextBox = ASPx.CreateClass(ASPxClientTextBoxBase, {
27580 constructor: function(name) {
27581  this.constructor.prototype.constructor.call(this, name);
27582  this.isASPxClientTextBox = true;
27583  this.isCaptchaTextBox = false;
27584 },
27585 NeedProcessUnload: function() {
27586  return ASPxClientTextBoxBase.prototype.NeedProcessUnload.call(this) && !this.isCaptchaTextBox;
27587 },
27588 IsValueRestoredByBrowser: function() {
27589  if(this.isCaptchaTextBox)
27590   return this.initializeInputValue !== "" && this.initializeInputValue !== this.nullText;
27591  return  ASPxClientTextBoxBase.prototype.IsValueRestoredByBrowser.call(this);
27592 },
27593 SynchronizeRestoredValue: function() {
27594  if(this.isCaptchaTextBox)
27595   this.SetText(null);
27596  else
27597   ASPxClientTextBoxBase.prototype.SynchronizeRestoredValue.call(this);
27598 },
27599});
27600ASPxClientTextBox.Cast = ASPxClientControl.Cast;
27601ASPx.Ident.IsASPxClientTextBox = function(obj) {
27602 return !!obj.isASPxClientTextBox;
27603};
27604var ASPxClientMemo = ASPx.CreateClass(ASPxClientTextEdit, { 
27605 constructor: function(name) {
27606  this.constructor.prototype.constructor.call(this, name);        
27607  this.isASPxClientMemo = true;
27608  this.raiseValueChangedOnEnter = false;
27609  this.maxLength = 0;
27610  this.pasteTimerID = -1;
27611  this.pasteTimerActivatorCount = 0;
27612 },
27613 Initialize: function() {
27614  ASPxClientTextEdit.prototype.Initialize.call(this);
27615  this.SaveChangedValue();
27616  this.maxLengthRestricted = this.maxLength > 0;
27617 },
27618 CutString: function() {
27619  var text = this.GetText();
27620  if(text.length > this.maxLength) {
27621   text = text.substring(0, this.maxLength);
27622   this.SetText(text);
27623  }
27624 },
27625 EventKeyCodeChangesTheInput: function(evt) {
27626  if(ASPx.IsPasteShortcut(evt))
27627   return true;
27628  else if(evt.ctrlKey)
27629   return false;
27630  var keyCode = ASPx.Evt.GetKeyCode(evt);
27631  var isSystemKey = ASPx.Key.Windows <= keyCode && keyCode <= ASPx.Key.ContextMenu;
27632  var isFKey = ASPx.Key.F1 <= keyCode && keyCode <= 127; 
27633  return ASPx.Key.Delete < keyCode && !isSystemKey && !isFKey || keyCode == ASPx.Key.Enter || keyCode == ASPx.Key.Space;
27634 },
27635 OnTextChangingCheck: function() {
27636  if(this.maxLengthRestricted)  
27637   this.CutString(); 
27638 },
27639 StartTextChangingTimer: function() {
27640  if(this.maxLengthRestricted) {
27641   if(this.pasteTimerActivatorCount == 0) 
27642    this.SetTextChangingTimer();
27643   this.pasteTimerActivatorCount ++;
27644  }
27645 },
27646 EndTextChangingTimer: function() {
27647  if(this.maxLengthRestricted) {
27648   this.pasteTimerActivatorCount --;
27649   if(this.pasteTimerActivatorCount == 0) 
27650    this.ClearTextChangingTimer();
27651  }
27652 },
27653 CollapseEditor: function() {
27654  if(!this.IsAdjustmentRequired()) return;
27655  var mainElement = this.GetMainElement();
27656  var inputElement = this.GetInputElement();
27657  if(!ASPx.IsExistsElement(mainElement) || !ASPx.IsExistsElement(inputElement))
27658   return;
27659  ASPxClientTextEdit.prototype.CollapseEditor.call(this);
27660  var mainElementCurStyle = ASPx.GetCurrentStyle(mainElement);
27661  if(this.heightCorrectionRequired && mainElement && inputElement) {
27662   if(mainElement.style.height == "100%" || mainElementCurStyle.height == "100%") {
27663    mainElement.style.height = "0";
27664    mainElement.wasCollapsed = true;
27665   }
27666   inputElement.style.height = "0";
27667  }
27668 },
27669 SetWidth: function(width) {
27670  ASPxClientTextEdit.prototype.SetWidth.call(this, width);
27671 },
27672 ClearErrorFrameElementsStyles: function() {
27673  var textarea = this.GetInputElement();
27674  if(!textarea)
27675   return;
27676  var scrollBarPosition = textarea.scrollTop;
27677  ASPxClientTextEdit.prototype.ClearErrorFrameElementsStyles.call(this);
27678  if(ASPx.Browser.Firefox)
27679   textarea.scrollTop = scrollBarPosition;
27680 },
27681 OnMouseOver: function() {
27682  this.StartTextChangingTimer();
27683 },  
27684 OnMouseOut: function() {
27685  this.EndTextChangingTimer();
27686 },
27687 OnFocusCore: function() {  
27688  this.StartTextChangingTimer();
27689  ASPxClientTextEdit.prototype.OnFocusCore.call(this);
27690 },
27691 OnLostFocus: function() {
27692  this.EndTextChangingTimer();
27693  ASPxClientTextEdit.prototype.OnLostFocus.call(this);
27694 },
27695 OnKeyDown: function(evt) { 
27696  if(this.NeedPreventBrowserUndoBehaviour(evt))
27697   return ASPx.Evt.PreventEvent(evt);
27698  if(this.maxLengthRestricted){
27699   var selection = ASPx.Selection.GetInfo(this.GetInputElement()); 
27700   var noCharToReplace = selection.startPos == selection.endPos;
27701   if(this.GetText().length >= this.maxLength && noCharToReplace && this.EventKeyCodeChangesTheInput(evt)) {
27702    return ASPx.Evt.PreventEvent(evt);
27703   }
27704  }
27705  ASPxClientEdit.prototype.OnKeyDown.call(this, evt);
27706 },
27707 SetTextChangingTimer: function() {
27708  this.pasteTimerID = ASPx.Timer.SetControlBoundInterval(this.OnTextChangingCheck, this, ASPx.PasteCheckInterval);
27709 },
27710 ClearTextChangingTimer: function() {
27711  this.pasteTimerID = ASPx.Timer.ClearInterval(this.pasteTimerID);
27712 },
27713 getFocusedNullTextElementTagName: function() {
27714  return "TEXTAREA";
27715 },
27716 getCopyFromInputElementStyles: function() {
27717  var result = ASPxClientTextEdit.prototype.getCopyFromInputElementStyles.call(this);
27718  result.push("resize");
27719  return result;
27720 }
27721});
27722ASPxClientMemo.Cast = ASPxClientControl.Cast;
27723ASPx.Ident.IsASPxClientMemo = function(obj) { return obj && !!obj.isASPxClientMemo; };
27724var CLEAR_BUTTON_INDEX = -100;
27725var HIDE_CONTENT_CSS_CLASS_NAME = "dxHideContent";
27726var setContentVisibility = function(clearButtonElement, value) {
27727 var action = value ? ASPx.RemoveClassNameFromElement : ASPx.AddClassNameToElement;
27728 action(clearButtonElement, HIDE_CONTENT_CSS_CLASS_NAME);
27729};
27730var CLEAR_BUTTON_DISPLAY_MODE = {
27731 AUTO: 'Auto',
27732 ALWAYS: 'Always',
27733 NEVER: 'Never',
27734 ON_HOVER: 'OnHover'
27735};
27736var AccessibilityFocusedButtonClassName = "dxAFB";
27737var ButtonEditButtonLeftSystemClassName = "dxeButtonLeft";
27738var ASPxClientButtonEditBase = ASPx.CreateClass(ASPxClientTextBoxBase, {
27739 constructor: function(name) {
27740  this.constructor.prototype.constructor.call(this, name);        
27741  this.allowUserInput = true;
27742  this.isValueChanging = false;
27743  this.allowMouseWheel = true;
27744  this.isMouseOver = false;
27745  this.buttonCount = 0;
27746  this.emptyValueMaskDisplayText = "";
27747  this.clearButtonDisplayMode = CLEAR_BUTTON_DISPLAY_MODE.AUTO;
27748  this.forceShowClearButtonAlways = false;
27749  this.recoverClearButtonVisibility = false;
27750  this.ButtonClick = new ASPxClientEvent();
27751 },
27752 Initialize: function() {
27753  ASPxClientTextBoxBase.prototype.Initialize.call(this);
27754  this.EnsureEmptyValueMaskDisplayText();
27755  if(this.HasClearButton())
27756   this.InitializeClearButton();
27757  this.InitAccessibilityCompliant();
27758 },
27759 InlineInitialize: function() {
27760  ASPxClientTextBoxBase.prototype.InlineInitialize.call(this);
27761  if(this.clearButtonDisplayMode === CLEAR_BUTTON_DISPLAY_MODE.AUTO) {
27762   this.clearButtonDisplayMode = this.IsClearButtonVisibleAuto() || this.forceShowClearButtonAlways ?
27763    CLEAR_BUTTON_DISPLAY_MODE.ALWAYS : CLEAR_BUTTON_DISPLAY_MODE.NEVER;
27764  }
27765  this.EnsureClearButtonVisibility();
27766 },
27767 InitializeClearButton: function() {
27768  if(this.clearButtonDisplayMode === CLEAR_BUTTON_DISPLAY_MODE.ON_HOVER) {
27769   ASPx.Evt.AttachMouseEnterToElement(this.GetHoverElementToShowClearButton(), this.OnMouseOver.aspxBind(this), this.OnMouseOut.aspxBind(this));
27770  }
27771 },
27772 GetHoverElementToShowClearButton: function() {
27773  return this.GetMainElement();
27774 },
27775 IsClearButtonVisibleAuto: function() {
27776  return ASPx.Browser.MobileUI;
27777 },
27778 SetEnabled: function(enabled) {
27779  ASPxClientTextBoxBase.prototype.SetEnabled.call(this, enabled);
27780  this.EnsureClearButtonVisibility();
27781 },
27782 EnsureEmptyValueMaskDisplayText: function() {
27783  if(this.maskInfo && this.HasClearButton()) {
27784   var savedText = this.maskInfo.GetText();
27785   this.maskInfo.SetText("");
27786   this.emptyValueMaskDisplayText = this.maskInfo.GetText();
27787   this.maskInfo.SetText(savedText);
27788  }
27789 },
27790 GetButton: function(number) {
27791  return this.GetChildElement("B" + number);
27792 },
27793 GetCustomButtonCollection: function() {
27794  var buttonElements = [];
27795  for(var i = 0; i < this.buttonCount; i++) {
27796   var button =  this.GetButton(i);
27797   if(!!button)
27798    buttonElements.push(button);
27799  }
27800  return buttonElements;
27801 },
27802 GetButtonCollection: function() {
27803  var buttonElements = [];
27804  var clearButton = this.GetClearButton();
27805  if(!!clearButton)
27806   buttonElements.push(clearButton);
27807  return buttonElements.concat(this.GetCustomButtonCollection());
27808 },
27809 GetAccessibilityAnchor: function(buttonElement) {
27810  var firstChild = buttonElement.firstElementChild;
27811  var isExistsAnchorElement = ASPx.Attr.GetAttribute(firstChild, "role") === "button";
27812  return isExistsAnchorElement ? firstChild : null;
27813 },
27814 GetButtonByAccessibilityAnchor: function(anchorElement) {
27815  return anchorElement.parentNode;
27816 },
27817 SetAccessibilityAnchorEnabled: function(buttonElement, enabled) {
27818  var anchorElement = this.GetAccessibilityAnchor(buttonElement);
27819  if(ASPx.IsExists(anchorElement))
27820   ASPx.Attr.SetOrRemoveAttribute(anchorElement, "tabindex", enabled ? "0" : "");
27821 },
27822 InitAccessibilityCompliant: function() {
27823  if(!this.accessibilityCompliant) return;
27824  var buttonElements = this.GetButtonCollection();
27825  var labelElements = ASPx.FindAssociatedLabelElements(this);
27826  for(var i = 0; i < buttonElements.length; i++) {
27827   this.InitAccessibilityAnchor(this.GetAccessibilityAnchor(buttonElements[i]), labelElements);
27828   ASPx.Evt.AttachEventToElement(buttonElements[i], "mousedown", this.Button_MouseDown.bind(this));
27829  }
27830 },
27831 InitAccessibilityAnchor: function(anchorElement, labelElements) {
27832  if(!ASPx.IsExists(anchorElement))
27833   return;
27834  for(var i = 0; i < labelElements.length; i++)
27835   this.ariaExplanatoryTextManager.SetOrRemoveText([anchorElement], labelElements[i], true, false, false);
27836  this.InitAccessibilityAnchorEvents(anchorElement);
27837 },
27838 InitAccessibilityAnchorEvents: function(anchorElement) {
27839  ASPx.Evt.AttachEventToElement(anchorElement, "keydown", function(evt) { this.OnButtonKeysHandling(evt); }.aspxBind(this));
27840  ASPx.Evt.AttachEventToElement(anchorElement, "keyup", function(evt) { this.OnButtonKeysHandling(evt); }.aspxBind(this));
27841  ASPx.Evt.AttachEventToElement(anchorElement, "focus", function(evt) { this.OnButtonGotFocus(evt); }.aspxBind(this));
27842  ASPx.Evt.AttachEventToElement(anchorElement, "blur", function(evt) { this.OnButtonLostFocus(evt); }.aspxBind(this));
27843 },
27844 EmulateButtonMouseEvent: function(sourceElement) {
27845  var buttonElement = this.GetButtonByAccessibilityAnchor(sourceElement);
27846  var mouseEvent = buttonElement.onclick || buttonElement.onmousedown || buttonElement.ontouchstart || buttonElement.onpointerdown;
27847  var emulateMouseEvtArgs = { button: 0, which: 1, srcElement: buttonElement, target: buttonElement };
27848  if(!!mouseEvent) {
27849   ASPx.Attr.SetAttribute(sourceElement, "aria-pressed", true);
27850   setTimeout(function() {
27851    mouseEvent(emulateMouseEvtArgs);
27852    ASPx.Attr.RemoveAttribute(sourceElement, "aria-pressed");
27853   }, 300);
27854  }
27855 },
27856 OnButtonKeysHandling: function(evt) {
27857  var isKeyUp = evt.type == "keyup";
27858  var keyCode = ASPx.Evt.GetKeyCode(evt);
27859  var sourceElement = ASPx.Evt.GetEventSource(evt);
27860  if((keyCode == ASPx.Key.Space && isKeyUp) || (keyCode == ASPx.Key.Enter && !isKeyUp))
27861   this.EmulateButtonMouseEvent(sourceElement);
27862  if(keyCode != ASPx.Key.Tab)
27863   ASPx.Evt.PreventEventAndBubble(evt);
27864  return false;
27865 },
27866 OnButtonGotFocus: function(evt) {
27867  this.UnlockFocusEvents();
27868  var editor = ASPx.GetControlCollection().Get(this.name);
27869  var sourceElement = ASPx.Evt.GetEventSource(evt);
27870  if(!!editor && !editor.CorrectAccessibilityButtonFocus(sourceElement)) {
27871   var buttonElement = editor.GetButtonByAccessibilityAnchor(sourceElement);
27872   ASPx.AddClassNameToElement(buttonElement, this.GetAccessibilityFocusedButtonClassName());
27873   ASPx.EGotFocus(editor.name);
27874  }
27875 },
27876 OnButtonLostFocus: function(evt) {
27877  var editor = ASPx.GetControlCollection().Get(this.name);
27878  var sourceElement = ASPx.Evt.GetEventSource(evt);
27879  if(!!editor) {
27880   var buttonElement = editor.GetButtonByAccessibilityAnchor(sourceElement);
27881   ASPx.RemoveClassNameFromElement(buttonElement, this.GetAccessibilityFocusedButtonClassName());
27882  }
27883  setTimeout(function() {
27884   if(!!editor && !editor.IsEditorElement(ASPx.GetActiveElement())) {
27885    ASPx.ELostFocus(editor.name);
27886   }
27887  }.aspxBind(this), 0);
27888 },
27889 Button_MouseDown: function(evt) {
27890  var editor = ASPx.GetControlCollection().Get(this.name);
27891  if(!!editor) {
27892   var sourceElement = ASPx.Evt.GetEventSource(evt);
27893   if(document.activeElement !== sourceElement)
27894    this.LockFocusEvents();
27895  }
27896 },
27897 ForceRefocusEditor: function(evt, isNativeFocus) {
27898  if(this.accessibilityCompliant) {
27899   var srcElement = ASPx.Evt.GetEventSource(evt);
27900   var customButtons = this.GetCustomButtonCollection();
27901   for(var i = 0; i < customButtons.length; i++)
27902    if(customButtons[i] == srcElement || ASPx.GetIsParent(customButtons[i], srcElement))
27903     return;
27904  }
27905  ASPxClientEdit.prototype.ForceRefocusEditor.call(this, evt, isNativeFocus);
27906  if(this.GetInputElement().type == "password") {
27907   window.setTimeout(function() { this.GetInputElement().focus(); }.bind(this), 0);
27908  }
27909 },
27910 CorrectAccessibilityButtonFocus: function(sourceElement) {
27911  if(ASPx.Attr.IsExistsAttribute(sourceElement, "tabindex"))
27912   return false;
27913  setTimeout(function() {
27914   var buttonElements = this.GetButtonCollection();
27915   for(var i = 0; i < buttonElements.length; i++)
27916    if(ASPx.GetIsParent(buttonElements[i], sourceElement))
27917     this.GetAccessibilityAnchor(buttonElements[i]).focus();
27918  }.aspxBind(this), 0);
27919  return true;
27920 },
27921 OnKeyDown: function(evt) { 
27922  if(this.NeedEnsureClearButtonVisibilityOnKeyDown()) {
27923   var hasClearButtonOnHover = this.HasClearButton() && this.clearButtonDisplayMode === CLEAR_BUTTON_DISPLAY_MODE.ON_HOVER;
27924   this.recoverClearButtonVisibility = hasClearButtonOnHover && ASPx.Evt.GetKeyCode(evt) == ASPx.Key.Tab && !evt.shiftKey;
27925  }
27926  if(this.accessibilityCompliant) {
27927   var hasVisibleFocusableButtonToTheRIGHT = this.GetButtonCollection().some(function(buttonElement) {
27928    return this.IsButtonVisible(buttonElement)
27929     && !ASPx.ElementHasCssClass(buttonElement, ButtonEditButtonLeftSystemClassName)
27930     && this.GetAccessibilityAnchor(buttonElement) !== null;
27931   }, this);
27932   var hasVisibleFocusableButtonToTheLEFT = this.GetButtonCollection().some(function(buttonElement) {
27933    return this.IsButtonVisible(buttonElement)
27934     && ASPx.ElementHasCssClass(buttonElement, ButtonEditButtonLeftSystemClassName)
27935     && this.GetAccessibilityAnchor(buttonElement) !== null;
27936   }, this);
27937   if((ASPx.Evt.GetKeyCode(evt) === ASPx.Key.Tab && !evt.shiftKey && hasVisibleFocusableButtonToTheRIGHT) ||
27938    (ASPx.Evt.GetKeyCode(evt) === ASPx.Key.Tab && evt.shiftKey && hasVisibleFocusableButtonToTheLEFT ))
27939    this.LockFocusEvents();
27940  }
27941  ASPxClientTextBoxBase.prototype.OnKeyDown.call(this, evt);
27942 },
27943 NeedEnsureClearButtonVisibilityOnKeyDown: function() {
27944  return this.accessibilityCompliant;
27945 },
27946 GetAccessibilityFocusedButtonClassName: function() {
27947  return AccessibilityFocusedButtonClassName;
27948 },
27949 SetButtonVisible: function(number, value) {
27950  var button = this.GetButton(number);
27951  if(!button)
27952   return;
27953  var isClearButton = number === CLEAR_BUTTON_INDEX;
27954  var visibilityModifier = isClearButton ? setContentVisibility : ASPx.SetElementDisplay;
27955  if(isClearButton && this.clearButtonDisplayMode === CLEAR_BUTTON_DISPLAY_MODE.ALWAYS && this.accessibilityCompliant && this.enabled)
27956   this.SetAccessibilityAnchorEnabled(button, value);
27957  visibilityModifier(button, value);
27958 },
27959 GetButtonVisible: function(number) {
27960  var button = this.GetButton(number);
27961  return this.IsButtonVisible(button);
27962 },
27963 IsButtonVisible: function(button) {
27964  var result = false;
27965  if(button) {
27966   if(this.IsClearButtonElement(button) && this.clearButtonDisplayMode === CLEAR_BUTTON_DISPLAY_MODE.ALWAYS)
27967    result = !ASPx.ElementHasCssClass(button, this.GetHideContentCssClassName());
27968   else
27969    result = ASPx.IsElementVisible(button);
27970  }
27971  return result;
27972 },
27973 GetHideContentCssClassName: function() {
27974  return HIDE_CONTENT_CSS_CLASS_NAME;
27975 },
27976 ProcessInternalButtonClick: function(buttonIndex) {
27977  return false;
27978 },
27979 OnButtonClick: function(number) {
27980  var processOnServer = this.RaiseButtonClick(number);
27981  if(!this.ProcessInternalButtonClick(number) && processOnServer)
27982   this.SendPostBack('BC:' + number);
27983 },
27984 GetLastSuccesfullValue: function() {
27985  return this.lastChangedValue;
27986 },
27987 OnClear: function() {
27988  this.startUserInputEventTimerIfRequired();
27989  this.ClearEditorValueAndForceOnChange();
27990  this.ForceRefocusEditor(null, true);
27991  window.setTimeout(this.EnsureClearButtonVisibility.aspxBind(this), 0);
27992 },
27993 ClearEditorValueAndForceOnChange: function() {
27994  if(this.GetReadOnly() || !this.GetButtonVisible(CLEAR_BUTTON_INDEX))
27995   return;
27996  var raiseOnChange = this.ClearEditorValueByClearButton();
27997  if(raiseOnChange)
27998   this.ForceStandardOnChange();
27999 },
28000 ClearEditorValueByClearButton: function() {
28001  var prevValue = this.GetLastSuccesfullValue();
28002  this.ClearEditorValueByClearButtonCore();
28003  return prevValue !== this.GetValue();
28004 },
28005 ClearEditorValueByClearButtonCore: function() {
28006  this.Clear();
28007  this.GetInputElement().value = '';
28008 },
28009 ForceStandardOnChange: function() {
28010  this.forceValueChanged = true;
28011  this.RaiseStandardOnChange();
28012  this.forceValueChanged = false;
28013 },
28014 IsValueChangeForced: function() {
28015  return this.forceValueChanged || ASPxClientTextBoxBase.prototype.IsValueChangeForced.call(this);
28016 },
28017 IsValueChanging: function() { return this.isValueChanging; },
28018 StartValueChanging: function() { this.isValueChanging = true; },
28019 EndValueChanging: function() { this.isValueChanging = false; },
28020 IsClearButtonElement: function(element) {
28021  return ASPx.GetIsParent(this.GetClearButton(), element);
28022 },
28023 OnFocusCore: function() {
28024  if(this.accessibilityCompliant) {
28025   if(this.focused) 
28026    this.UnlockFocusEvents();   
28027   else 
28028    ASPxClientTextBoxBase.prototype.OnFocusCore.call(this);
28029  }
28030  else
28031   ASPxClientTextBoxBase.prototype.OnFocusCore.call(this);
28032  this.EnsureClearButtonVisibility();
28033 },
28034 OnLostFocusCore: function() {
28035  ASPxClientTextBoxBase.prototype.OnLostFocusCore.call(this);
28036  this.EnsureClearButtonVisibility();
28037  this.recoverClearButtonVisibility = false;
28038 },
28039 GetClearButton: function() {
28040  return this.GetButton(CLEAR_BUTTON_INDEX);
28041 },
28042 HasClearButton: function() {
28043  return !!this.GetClearButton();
28044 },
28045 RequireShowClearButton: function() {
28046  return !this.IsClearButtonDisabled() && !this.IsClearButtonNotRequired() && this.RequireShowClearButtonInternal();
28047 },
28048 IsClearButtonDisabled: function() {
28049  return !this.clientEnabled || !this.HasClearButton() || this.clearButtonDisplayMode === CLEAR_BUTTON_DISPLAY_MODE.NEVER;
28050 },
28051 IsClearButtonNotRequired: function() {
28052  return !this.IsFocused() && !this.isMouseOver && this.clearButtonDisplayMode !== CLEAR_BUTTON_DISPLAY_MODE.ALWAYS && !this.recoverClearButtonVisibility;
28053 },
28054 RequireShowClearButtonInternal: function () {
28055  return this.IsFocused() && this.RequireShowClearButtonCore() || !this.IsNullState();
28056 },
28057 RequireShowClearButtonCore: function() {
28058  var inputText = this.GetInputElement().value;
28059  return inputText !== this.GetEmptyValueDisplayText();
28060 },
28061 IsFocused: function() {
28062  return this === ASPx.GetFocusedEditor();
28063 },
28064 IsNullState: function() {
28065  var value = this.GetValue();
28066  return this.IsNull(value) || value === this.GetEmptyValueDisplayText();
28067 },
28068 GetEmptyValueDisplayText: function() { 
28069  return this.maskInfo ? this.emptyValueMaskDisplayText : "";
28070 },
28071 EnsureClearButtonVisibility: function() {
28072  this.SetButtonVisible(CLEAR_BUTTON_INDEX, this.RequireShowClearButton());
28073 },
28074 OnMouseOver: function() {
28075  this.isMouseOver = true;
28076  this.EnsureClearButtonVisibility();
28077 },
28078 OnMouseOut: function() {
28079  this.isMouseOver = false;
28080  this.EnsureClearButtonVisibility();
28081 },
28082 OnKeyPress: function(evt) {
28083  if(this.allowUserInput)
28084   ASPxClientTextBoxBase.prototype.OnKeyPress.call(this, evt);
28085 },
28086 OnKeyEventEnd: function(evt, withDelay) {
28087  ASPxClientTextBoxBase.prototype.OnKeyEventEnd.call(this, evt, withDelay);
28088  this.EnsureClearButtonVisibility();
28089 },
28090 RaiseButtonClick: function(number){
28091  var processOnServer = this.autoPostBack || this.IsServerEventAssigned("ButtonClick");
28092  if(!this.ButtonClick.IsEmpty()){
28093   var args = new ASPxClientButtonEditClickEventArgs(processOnServer, number);
28094   this.ButtonClick.FireEvent(this, args);
28095   processOnServer = args.processOnServer;
28096  }
28097  return processOnServer;
28098 },
28099 ChangeEnabledAttributes: function(enabled){
28100  ASPxClientTextEdit.prototype.ChangeEnabledAttributes.call(this, enabled);
28101  for(var i = 0; i < this.buttonCount; i++){
28102   var element = this.GetButton(i);
28103   if(element)
28104    this.ChangeButtonEnabledAttributes(element, this.GetChangeButtonEnabledAttributesMethod(enabled));
28105  }
28106  if(this.accessibilityCompliant)
28107   this.ChangeAccessibilityButtonEnabledAttributes(enabled);
28108 },
28109 ChangeEnabledStateItems: function(enabled){
28110  ASPxClientTextEdit.prototype.ChangeEnabledStateItems.call(this, enabled);
28111  for(var i = 0; i < this.buttonCount; i++){
28112   var element = this.GetButton(i);
28113   if(element) 
28114    ASPx.GetStateController().SetElementEnabled(element, enabled);
28115  }
28116 },
28117 GetChangeButtonEnabledAttributesMethod: function(enabled) {
28118  return ASPx.Attr.ChangeAttributesMethod(enabled);
28119 },
28120 ChangeButtonEnabledAttributes: function(element, method){
28121  method(element, "onclick");
28122  method(element, "ondblclick");
28123  if(ASPx.Browser.Edge)
28124   method(element, "onmousedown");
28125  method(element, "on" + ASPx.TouchUIHelper.touchMouseDownEventName);
28126  method(element, "on" + ASPx.TouchUIHelper.touchMouseUpEventName);
28127 },
28128 ChangeInputEnabled: function(element, enabled, readOnly) {
28129  ASPxClientTextEdit.prototype.ChangeInputEnabled.call(this, element, enabled, readOnly || !this.allowUserInput);
28130 },
28131 ChangeAccessibilityButtonEnabledAttributes: function(enabled) {
28132  var buttonElements = this.GetButtonCollection();
28133  for(var i = 0; i < buttonElements.length; i++)
28134   this.SetAccessibilityAnchorEnabled(buttonElements[i], enabled);
28135 },
28136 SetValue: function(value) {
28137  ASPxClientTextEdit.prototype.SetValue.call(this, value);
28138  if(!this.IsFocused())
28139   this.EnsureClearButtonVisibility();
28140 },
28141 OnAssociatedLabelClick: function(focusableElement) {
28142  var isValidElement = focusableElement && ASPx.IsActionElement(focusableElement) && ASPx.GetIsParent(this.GetMainElement(), focusableElement) && ASPx.IsElementVisible(focusableElement);
28143  if(isValidElement)
28144   focusableElement.focus();
28145  else
28146   this.SetFocus();
28147 },
28148 onClearButtonClick: function() {
28149  var requireFocus = !ASPx.Browser.VirtualKeyboardSupported || ASPx.Browser.MSTouchUI;
28150  if(this.ownerListBox)
28151   this.ownerListBox.ForceLockFocusEvents();
28152  if((requireFocus && !this.IsFocused()) || this.accessibilityCompliant)
28153   this.GetInputElement().focus();
28154  if(this.IsFocused() || !requireFocus) {
28155   if(this.ownerListBox)
28156    this.ownerListBox.UnlockFocusEvents();
28157   else if(this.accessibilityCompliant)
28158    this.UnlockFocusEvents();
28159   this.OnClear();
28160  }
28161  else
28162   window.setTimeout(this.onClearButtonClick.bind(this), 100);
28163 }
28164});
28165var ASPxClientButtonEdit = ASPx.CreateClass(ASPxClientButtonEditBase, {
28166});
28167ASPxClientButtonEdit.Cast = ASPxClientControl.Cast;
28168var ASPxClientButtonEditClickEventArgs = ASPx.CreateClass(ASPxClientProcessingModeEventArgs, {
28169 constructor: function(processOnServer, buttonIndex){
28170  this.constructor.prototype.constructor.call(this, processOnServer);
28171  this.buttonIndex = buttonIndex;
28172 }
28173});
28174var ASPxClientTextEditHelpTextHAlign = {
28175 Left: "Left",
28176 Right: "Right",
28177 Center: "Center"
28178};
28179var ASPxClientTextEditHelpTextVAlign = {
28180 Top: "Top",
28181 Bottom: "Bottom",
28182 Middle: "Middle"
28183};
28184var ASPxClientTextEditHelpTextDisplayMode = {
28185 Inline: "Inline",
28186 Popup: "Popup"
28187};
28188var ASPxClientTextEditHelpTextConsts = {
28189 VERTICAL_ORIENTATION_CLASS_NAME: "dxeVHelpTextSys",
28190 HORIZONTAL_ORIENTATION_CLASS_NAME: "dxeHHelpTextSys"
28191};
28192var ASPxClientTextEditHelpText = ASPx.CreateClass(null, {
28193 constructor: function (editor, helpTextStyle, helpText, position, hAlign, vAlign, margins, animationEnabled, helpTextDisplayMode) {
28194  this.hAlign = hAlign;
28195  this.vAlign = vAlign;
28196  this.animationEnabled = animationEnabled;
28197  this.displayMode = helpTextDisplayMode;
28198  this.editor = editor;
28199  this.editorMainElement = editor.GetMainElement();
28200  this.margins = margins ? { Top: margins[0], Right: margins[1], Bottom: margins[2], Left: margins[3] } : null;
28201  this.defaultMargins = { Top: 10, Right: 10, Bottom: 10, Left: 10 };
28202  this.position = position;
28203  this.helpTextElement = this.createHelpTextElement();
28204  this.setHelpTextZIndex(true);
28205  this.prepareHelpTextElement(helpTextStyle, helpText);
28206 },
28207 getRows: function (table) {
28208  return ASPx.GetChildNodesByTagName(table, "TR");
28209 },
28210 getCells: function (row) {
28211  return ASPx.GetChildNodesByTagName(row, "TD");
28212 },
28213 getCellByIndex: function(row, cellIndex) {
28214  return this.getCells(row)[cellIndex];
28215 },
28216 getCellIndex: function(row, cell) {
28217  var cells = this.getCells(row);
28218  for(var i = 0; i < cells.length; i++) {
28219   if(cells[i] === cell)
28220    return i;
28221  }
28222 },
28223 isHorizontal: function(position) {
28224  return position === ASPx.Position.Left || position === ASPx.Position.Right;
28225 },
28226 isVertical: function (position) {
28227  return position === ASPx.Position.Top || position === ASPx.Position.Bottom;
28228 },
28229 createEmptyCell: function(assignClassName) {
28230  var cell = document.createElement("TD");
28231  if(assignClassName)
28232   cell.className = "dxeFakeEmptyCell";
28233  return cell;
28234 },
28235 addHelpTextCellToExternalTableWithTwoCells: function (captionCell, errorCell, helpTextCell, errorTableBody, tableRows) {
28236  var captionPosition = this.editor.captionPosition;
28237  var errorCellPosition = this.editor.errorCellPosition;
28238  var helpTextRow = this.isVertical(this.position) ? document.createElement("TR") : null;
28239  if(captionPosition === ASPx.Position.Left && this.position === ASPx.Position.Left && this.isHorizontal(errorCellPosition))
28240   captionCell.parentNode.insertBefore(helpTextCell, captionCell.nextSibling);
28241  if(captionPosition === ASPx.Position.Right && this.position === ASPx.Position.Right && this.isHorizontal(errorCellPosition))
28242   captionCell.parentNode.insertBefore(helpTextCell, captionCell);
28243  if(captionPosition === ASPx.Position.Left && this.position === ASPx.Position.Right && this.isHorizontal(errorCellPosition))
28244   tableRows[0].appendChild(helpTextCell);
28245  if(captionPosition === ASPx.Position.Right && this.position === ASPx.Position.Left && this.isHorizontal(errorCellPosition))
28246   tableRows[0].insertBefore(helpTextCell, tableRows[0].childNodes[0]);
28247  if(captionPosition === ASPx.Position.Top && this.position === ASPx.Position.Bottom && this.isVertical(errorCellPosition)) {
28248   helpTextRow.appendChild(helpTextCell);
28249   errorTableBody.appendChild(helpTextRow);
28250  }
28251  if(captionPosition === ASPx.Position.Bottom && this.position === ASPx.Position.Top && this.isVertical(errorCellPosition)) {
28252   helpTextRow.appendChild(helpTextCell);
28253   errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28254  }
28255  if(captionPosition === ASPx.Position.Top && this.position === ASPx.Position.Top && this.isVertical(errorCellPosition)) {
28256   helpTextRow.appendChild(helpTextCell);
28257   errorTableBody.insertBefore(helpTextRow, captionCell.parentNode.nextSibling);
28258  }
28259  if(captionPosition === ASPx.Position.Bottom && this.position === ASPx.Position.Bottom && this.isVertical(errorCellPosition)) {
28260   helpTextRow.appendChild(helpTextCell);
28261   errorTableBody.insertBefore(helpTextRow, captionCell.parentNode);
28262  }
28263  if(captionPosition === ASPx.Position.Right && this.position === ASPx.Position.Top && this.isVertical(errorCellPosition)) {
28264   helpTextRow.appendChild(helpTextCell);
28265   helpTextRow.appendChild(this.createEmptyCell());
28266   errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28267  }
28268  if(this.position === ASPx.Position.Bottom) {
28269   if(captionPosition === ASPx.Position.Right && errorCellPosition === ASPx.Position.Top || captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Right) {
28270    helpTextRow.appendChild(helpTextCell);
28271    helpTextRow.appendChild(this.createEmptyCell());
28272    errorTableBody.appendChild(helpTextRow);
28273   }
28274  }
28275  if(captionPosition === ASPx.Position.Left && this.position === ASPx.Position.Top && this.isVertical(errorCellPosition)) {
28276   helpTextRow.appendChild(this.createEmptyCell());
28277   helpTextRow.appendChild(helpTextCell);
28278   errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28279  }
28280  if(captionPosition === ASPx.Position.Left && this.position === ASPx.Position.Bottom && this.isVertical(errorCellPosition)) {
28281   helpTextRow.appendChild(this.createEmptyCell());
28282   helpTextRow.appendChild(helpTextCell);
28283   errorTableBody.appendChild(helpTextRow);
28284  }
28285  if(this.position === ASPx.Position.Right) {
28286   if(captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Left || captionPosition === ASPx.Position.Left && errorCellPosition === ASPx.Position.Top
28287    || captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Right) {
28288    tableRows[1].appendChild(helpTextCell);
28289    tableRows[0].appendChild(this.createEmptyCell());
28290   }
28291   if(captionPosition === ASPx.Position.Left && errorCellPosition === ASPx.Position.Bottom || captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Left) {
28292    tableRows[0].appendChild(helpTextCell);
28293    tableRows[1].appendChild(this.createEmptyCell());
28294   }
28295  }
28296  if(this.position === ASPx.Position.Left) {
28297   if(captionPosition === ASPx.Position.Right && errorCellPosition === ASPx.Position.Top || captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Right
28298    || captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Left) {
28299    tableRows[1].insertBefore(helpTextCell, tableRows[1].childNodes[0]);
28300    tableRows[0].insertBefore(this.createEmptyCell(), tableRows[0].childNodes[0]);
28301   }
28302   if(captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Top || captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Bottom) {
28303    tableRows[1].insertBefore(helpTextCell, tableRows[1].childNodes[0]);
28304    tableRows[0].insertBefore(this.createEmptyCell(errorCellPosition === ASPx.Position.Top), tableRows[0].childNodes[0]);
28305    tableRows[2].insertBefore(this.createEmptyCell(errorCellPosition !== ASPx.Position.Top), tableRows[2].childNodes[0]);
28306   }
28307   if(captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Top) {
28308    tableRows[2].insertBefore(helpTextCell, tableRows[2].childNodes[0]);
28309    tableRows[0].insertBefore(this.createEmptyCell(false), tableRows[0].childNodes[0]);
28310    tableRows[1].insertBefore(this.createEmptyCell(true), tableRows[1].childNodes[0]);
28311   }
28312   if(captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Bottom) {
28313    tableRows[0].insertBefore(helpTextCell, tableRows[0].childNodes[0]);
28314    tableRows[1].insertBefore(this.createEmptyCell(true), tableRows[1].childNodes[0]);
28315    tableRows[2].insertBefore(this.createEmptyCell(false), tableRows[2].childNodes[0]);
28316   }
28317   if(captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Left || captionPosition === ASPx.Position.Right && errorCellPosition === ASPx.Position.Bottom
28318    || captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Right) {
28319    tableRows[0].insertBefore(helpTextCell, tableRows[0].childNodes[0]);
28320    tableRows[1].insertBefore(this.createEmptyCell(), tableRows[1].childNodes[0]);
28321   }
28322   if(captionPosition === ASPx.Position.Left && this.isVertical(errorCellPosition)) {
28323    captionCell.parentNode.insertBefore(helpTextCell, captionCell.nextSibling);
28324    var emptyCellParentRow = errorCellPosition === ASPx.Position.Top ? tableRows[0] : tableRows[1];
28325    var helpTextCellIndex = this.getCellIndex(helpTextCell.parentNode, helpTextCell);
28326    emptyCellParentRow.insertBefore(this.createEmptyCell(), this.getCellByIndex(emptyCellParentRow, helpTextCellIndex));
28327   }
28328  }
28329  if(this.position === ASPx.Position.Right) {
28330   if(captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Top || captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Bottom) {
28331    tableRows[1].appendChild(helpTextCell);
28332    tableRows[0].appendChild(this.createEmptyCell(errorCellPosition === ASPx.Position.Top));
28333    tableRows[2].appendChild(this.createEmptyCell(errorCellPosition !== ASPx.Position.Top));
28334   }
28335   if(captionPosition === ASPx.Position.Top && errorCellPosition === ASPx.Position.Top) {
28336    tableRows[2].appendChild(helpTextCell);
28337    tableRows[0].appendChild(this.createEmptyCell(false));
28338    tableRows[1].appendChild(this.createEmptyCell(true));
28339   }
28340   if(captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Bottom) {
28341    tableRows[0].appendChild(helpTextCell);
28342    tableRows[1].appendChild(this.createEmptyCell(true));
28343    tableRows[2].appendChild(this.createEmptyCell(false));
28344   }
28345   if(captionPosition === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Right) {
28346    tableRows[0].appendChild(helpTextCell);
28347    tableRows[1].appendChild(this.createEmptyCell());
28348   }
28349   if(captionPosition === ASPx.Position.Right && this.isVertical(errorCellPosition)) {
28350    captionCell.parentNode.insertBefore(helpTextCell, captionCell);
28351    var emptyCellParentRow = errorCellPosition === ASPx.Position.Top ? tableRows[0] : tableRows[1];
28352    var helpTextCellIndex = this.getCellIndex(helpTextCell.parentNode, helpTextCell);
28353    emptyCellParentRow.insertBefore(this.createEmptyCell(), this.getCellByIndex(emptyCellParentRow, helpTextCellIndex));
28354   }
28355  }
28356  if(captionPosition === ASPx.Position.Top && this.position === ASPx.Position.Top && this.isHorizontal(errorCellPosition)) {
28357   if(errorCellPosition === ASPx.Position.Left) {
28358    helpTextRow.appendChild(this.createEmptyCell(true));
28359    helpTextRow.appendChild(helpTextCell);
28360   }
28361   else {
28362    helpTextRow.appendChild(helpTextCell);
28363    helpTextRow.appendChild(this.createEmptyCell());
28364   }
28365   errorTableBody.insertBefore(helpTextRow, captionCell.parentNode.nextSibling);
28366  }
28367  if(captionPosition === ASPx.Position.Bottom && this.position === ASPx.Position.Top && this.isHorizontal(errorCellPosition)) {
28368   if(errorCellPosition === ASPx.Position.Left) {
28369    helpTextRow.appendChild(this.createEmptyCell(true));
28370    helpTextRow.appendChild(helpTextCell);
28371   }
28372   else {
28373    helpTextRow.appendChild(helpTextCell);
28374    helpTextRow.appendChild(this.createEmptyCell());
28375   }
28376   errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28377  }
28378  if(captionPosition === ASPx.Position.Bottom && this.position === ASPx.Position.Bottom && this.isHorizontal(errorCellPosition)) {
28379   if(errorCellPosition === ASPx.Position.Left) {
28380    helpTextRow.appendChild(this.createEmptyCell(true));
28381    helpTextRow.appendChild(helpTextCell);
28382   }
28383   else {
28384    helpTextRow.appendChild(helpTextCell);
28385    helpTextRow.appendChild(this.createEmptyCell());
28386   }
28387   errorTableBody.insertBefore(helpTextRow, captionCell.parentNode);
28388  }
28389  if(captionPosition === ASPx.Position.Top && this.position === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Left) {
28390   helpTextRow.appendChild(this.createEmptyCell(true));
28391   helpTextRow.appendChild(helpTextCell);
28392   errorTableBody.appendChild(helpTextRow);
28393  }
28394  if(captionPosition === ASPx.Position.Right && this.position === ASPx.Position.Bottom && errorCellPosition === ASPx.Position.Bottom) {
28395   helpTextRow.appendChild(helpTextCell);
28396   helpTextRow.appendChild(this.createEmptyCell());
28397   errorTableBody.appendChild(helpTextRow);
28398  }
28399  if(this.position === ASPx.Position.Bottom) {
28400   if(captionPosition === ASPx.Position.Left && errorCellPosition === ASPx.Position.Right || captionPosition === ASPx.Position.Right && errorCellPosition === ASPx.Position.Left) {
28401    helpTextRow.appendChild(this.createEmptyCell(errorCellPosition !== ASPx.Position.Right));
28402    helpTextRow.appendChild(helpTextCell);
28403    helpTextRow.appendChild(this.createEmptyCell(errorCellPosition === ASPx.Position.Right));
28404    errorTableBody.appendChild(helpTextRow);
28405   }
28406   if(captionPosition === ASPx.Position.Left && errorCellPosition === ASPx.Position.Left) {
28407    helpTextRow.appendChild(this.createEmptyCell(false));
28408    helpTextRow.appendChild(this.createEmptyCell(true));
28409    helpTextRow.appendChild(helpTextCell);
28410    errorTableBody.appendChild(helpTextRow);
28411   }
28412   if(captionPosition === ASPx.Position.Right && errorCellPosition === ASPx.Position.Right) {
28413    helpTextRow.appendChild(helpTextCell);
28414    helpTextRow.appendChild(this.createEmptyCell(true));
28415    helpTextRow.appendChild(this.createEmptyCell(false));
28416    errorTableBody.appendChild(helpTextRow);
28417   }   
28418  }
28419  if(this.position === ASPx.Position.Top) {
28420   if(captionPosition === ASPx.Position.Left && errorCellPosition === ASPx.Position.Right || captionPosition === ASPx.Position.Right && errorCellPosition === ASPx.Position.Left) {
28421    helpTextRow.appendChild(this.createEmptyCell(errorCellPosition !== ASPx.Position.Right));
28422    helpTextRow.appendChild(helpTextCell);
28423    helpTextRow.appendChild(this.createEmptyCell(errorCellPosition === ASPx.Position.Right));
28424    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28425   }
28426   if(captionPosition === ASPx.Position.Left && errorCellPosition === ASPx.Position.Left) {
28427    helpTextRow.appendChild(this.createEmptyCell(false));
28428    helpTextRow.appendChild(this.createEmptyCell(true));
28429    helpTextRow.appendChild(helpTextCell);
28430    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28431   }
28432   if(captionPosition === ASPx.Position.Right && errorCellPosition === ASPx.Position.Right) {
28433    helpTextRow.appendChild(helpTextCell);
28434    helpTextRow.appendChild(this.createEmptyCell(true));
28435    helpTextRow.appendChild(this.createEmptyCell(false));
28436    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28437   }
28438  }
28439 },
28440 addHelpTextCellToExternalTableWithErrorCell
28440: function (errorCell, helpTextCell, errorTableBody, tableRows) {
28441  var errorCellPosition = this.editor.errorCellPosition;
28442  var helpTextRow = document.createElement("TR");
28443  if(this.position === ASPx.Position.Left && this.isHorizontal(errorCellPosition))
28444   tableRows[0].insertBefore(helpTextCell, tableRows[0].childNodes[0]);
28445  if(this.position === ASPx.Position.Right && this.isHorizontal(errorCellPosition))
28446   tableRows[0].appendChild(helpTextCell);
28447  if(this.position === ASPx.Position.Top && this.isVertical(errorCellPosition)) {
28448   helpTextRow.appendChild(helpTextCell);
28449   errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28450  }
28451  if(this.position === ASPx.Position.Bottom && this.isVertical(errorCellPosition)) {
28452   helpTextRow.appendChild(helpTextCell);
28453   errorTableBody.appendChild(helpTextRow);
28454  }
28455  if(errorCellPosition === ASPx.Position.Left && this.isVertical(this.position)) {
28456   helpTextRow.appendChild(this.createEmptyCell(true));
28457   helpTextRow.appendChild(helpTextCell);
28458   if(this.position === ASPx.Position.Top)
28459    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28460   else
28461    errorTableBody.appendChild(helpTextRow);
28462  }
28463  if(errorCellPosition === ASPx.Position.Right && this.isVertical(this.position)) {
28464   helpTextRow.appendChild(helpTextCell);
28465   helpTextRow.appendChild(this.createEmptyCell(true));
28466   if(this.position === ASPx.Position.Top)
28467    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28468   else
28469    errorTableBody.appendChild(helpTextRow);
28470  }
28471  if(this.position === ASPx.Position.Left && this.isVertical(errorCellPosition)) {
28472   var helpTextParentRowIndex = errorCellPosition === ASPx.Position.Top ? 1 : 0;
28473   var emptyCellRowIndex = helpTextParentRowIndex === 0 ? 1 : 0;
28474   tableRows[helpTextParentRowIndex].insertBefore(helpTextCell, tableRows[helpTextParentRowIndex].childNodes[0]);
28475   tableRows[emptyCellRowIndex].insertBefore(this.createEmptyCell(true), tableRows[emptyCellRowIndex].childNodes[0]);
28476  }
28477  if(this.position === ASPx.Position.Right && this.isVertical(errorCellPosition)) {
28478   var helpTextParentRowIndex = errorCellPosition === ASPx.Position.Top ? 1 : 0;
28479   var emptyCellRowIndex = helpTextParentRowIndex === 0 ? 1 : 0;
28480   tableRows[helpTextParentRowIndex].appendChild(helpTextCell);
28481   tableRows[emptyCellRowIndex].appendChild(this.createEmptyCell(true));
28482  }
28483 },
28484 addHelpTextCellToExternalTableWithCaption: function (captionCell, helpTextCell, errorTableBody, tableRows) {
28485  var captionPosition = this.editor.captionPosition;
28486  var helpTextRow = document.createElement("TR");
28487  if(captionPosition === ASPx.Position.Left && this.isVertical(this.position)) {
28488   helpTextRow.appendChild(this.createEmptyCell());
28489   helpTextRow.appendChild(helpTextCell);
28490   if(this.position === ASPx.Position.Top)
28491    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28492   else
28493    errorTableBody.appendChild(helpTextRow);
28494  }
28495  if(this.position === ASPx.Position.Left && this.isVertical(captionPosition)) {
28496   var helpTextParentRowIndex = captionPosition === ASPx.Position.Top ? 1 : 0;
28497   var emptyCellParentRowIndex = helpTextParentRowIndex === 0 ? 1 : 0;
28498   tableRows[helpTextParentRowIndex].insertBefore(helpTextCell, tableRows[helpTextParentRowIndex].childNodes[0]);
28499   tableRows[emptyCellParentRowIndex].insertBefore(this.createEmptyCell(), tableRows[emptyCellParentRowIndex].childNodes[0]);
28500  }
28501  if(this.position === ASPx.Position.Right && this.isVertical(captionPosition)) {
28502   var helpTextParentRowIndex = captionPosition === ASPx.Position.Top ? 1 : 0;
28503   var emptyCellParentRowIndex = helpTextParentRowIndex === 0 ? 1 : 0;
28504   tableRows[helpTextParentRowIndex].appendChild(helpTextCell);
28505   tableRows[emptyCellParentRowIndex].appendChild(this.createEmptyCell());
28506  }
28507  if(captionPosition === ASPx.Position.Right && this.isVertical(this.position)) {
28508   helpTextRow.appendChild(helpTextCell);
28509   helpTextRow.appendChild(this.createEmptyCell());
28510   if(this.position === ASPx.Position.Top)
28511    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28512   else
28513    errorTableBody.appendChild(helpTextRow);
28514  }
28515  if(this.isVertical(captionPosition) && this.isVertical(this.position)) {
28516   helpTextRow.appendChild(helpTextCell);
28517   if(captionPosition === ASPx.Position.Top && this.position === ASPx.Position.Top)
28518    errorTableBody.insertBefore(helpTextRow, captionCell.parentNode.nextSibling);
28519   if(captionPosition === ASPx.Position.Top && this.position === ASPx.Position.Bottom)
28520    errorTableBody.appendChild(helpTextRow);
28521   if(captionPosition === ASPx.Position.Bottom && this.position === ASPx.Position.Top)
28522    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28523   if(captionPosition === ASPx.Position.Bottom && this.position === ASPx.Position.Bottom)
28524    errorTableBody.insertBefore(helpTextRow, captionCell.parentNode);
28525  }
28526  if(captionPosition === ASPx.Position.Left && this.position === ASPx.Position.Left)
28527   captionCell.parentNode.insertBefore(helpTextCell, captionCell.nextSibling);
28528  if(captionPosition === ASPx.Position.Right && this.position === ASPx.Position.Right)
28529   captionCell.parentNode.insertBefore(helpTextCell, captionCell);
28530  if(captionPosition === ASPx.Position.Left && this.position === ASPx.Position.Right)
28531   tableRows[0].appendChild(helpTextCell);
28532  if(captionPosition === ASPx.Position.Right && this.position === ASPx.Position.Left)
28533   tableRows[0].insertBefore(helpTextCell, tableRows[0].childNodes[0]);
28534 },
28535 addHelpTextCellToExternalTableWithEditorOnly: function (helpTextCell, errorTableBody, tableRows) {
28536  if(this.isHorizontal(this.position)) {
28537   if(this.position === ASPx.Position.Left)
28538    tableRows[0].insertBefore(helpTextCell, tableRows[0].childNodes[0]);
28539   else
28540    tableRows[0].appendChild(helpTextCell);
28541  }
28542  else {
28543   var helpTextRow = document.createElement("TR");
28544   helpTextRow.appendChild(helpTextCell);
28545   if(this.position === ASPx.Position.Top)
28546    errorTableBody.insertBefore(helpTextRow, errorTableBody.childNodes[0]);
28547   else
28548    errorTableBody.appendChild(helpTextRow);
28549  }
28550 },
28551 addHelpTextCellToExternalTable: function (errorTable, helpTextCell) {
28552  var errorTableBody = ASPx.GetNodeByTagName(errorTable, "TBODY", 0);
28553  var tableRows = this.getRows(errorTableBody);
28554  var captionCell = this.editor.GetCaptionCell();
28555  var errorCell = this.editor.GetErrorCell();
28556  if(captionCell) {
28557   if(errorCell)
28558    this.addHelpTextCellToExternalTableWithTwoCells(captionCell, errorCell, helpTextCell, errorTableBody, tableRows);
28559   else
28560    this.addHelpTextCellToExternalTableWithCaption(captionCell, helpTextCell, errorTableBody, tableRows);
28561  }
28562  else if(errorCell)
28563   this.addHelpTextCellToExternalTableWithErrorCell(errorCell, helpTextCell, errorTableBody, tableRows);
28564  else
28565   this.addHelpTextCellToExternalTableWithEditorOnly(helpTextCell, errorTableBody, tableRows);
28566 },
28567 createExternalTable: function () {
28568  var externalTable = document.createElement("TABLE");
28569  externalTable.id = this.editor.name + ASPx.EditElementSuffix.ExternalTable;
28570  externalTable.cellPadding = 0;
28571  externalTable.cellSpacing = 0;
28572  this.applyExternalTableStyle(externalTable);
28573  var editorWidth = this.editorMainElement.style.width;
28574  if(ASPx.IsPercentageSize(editorWidth)) {
28575   externalTable.style.width = editorWidth;
28576   this.editorMainElement.style.width = "100%";
28577   this.editor.width = "100%";
28578  }
28579  var externalTableBody = document.createElement("TBODY");
28580  var externalTableRow = document.createElement("TR");
28581  var externalTableCell = document.createElement("TD");
28582  externalTable.appendChild(externalTableBody);
28583  externalTableBody.appendChild(externalTableRow);
28584  externalTableRow.appendChild(externalTableCell);
28585  this.editorMainElement.parentNode.appendChild(externalTable);
28586  ASPx.ChangeElementContainer(this.editorMainElement, externalTableCell, true);
28587  if(this.editor.accessibilityCompliant)
28588   ASPx.Attr.SetAttribute(externalTable, "role", "presentation");
28589  return externalTable;
28590 },
28591 applyExternalTableStyle: function (externalTable) {
28592  var externalTableStyle = this.editor.externalTableStyle;
28593  if(externalTableStyle.length > 0) {
28594   this.applyStyleToElement(externalTable, externalTableStyle);
28595  }
28596 },
28597 applyStyleToElement: function(element, style) {
28598  element.className = style[0];
28599  if(style[1]) {
28600   var styleSheet = ASPx.GetCurrentStyleSheet();
28601   element.className += " " + ASPx.CreateImportantStyleRule(styleSheet, style[1]);
28602  }
28603 },
28604 createInlineHelpTextElement: function () {
28605  var helpTextElement = document.createElement("TD");
28606  var externalTable = this.editor.GetExternalTable();
28607  if(!externalTable)
28608   externalTable = this.createExternalTable();
28609  this.addHelpTextCellToExternalTable(externalTable, helpTextElement);
28610  return helpTextElement;
28611 },
28612 createPopupHelpTextElement: function () {
28613  var helpTextElement = document.createElement("DIV");
28614  ASPx.InsertElementAfter(helpTextElement, this.editor.GetMainElement());
28615  ASPx.AnimationHelper.setOpacity(helpTextElement, 0);
28616  ASPx.SetElementDisplay(helpTextElement, false);
28617  return helpTextElement;
28618 },
28619 createHelpTextElement: function () {
28620  return this.displayMode === ASPxClientTextEditHelpTextDisplayMode.Popup ?
28621   this.createPopupHelpTextElement() : this.createInlineHelpTextElement();
28622 },
28623 prepareHelpTextElement: function (helpTextStyle, helpText) {
28624  this.helpTextElement.id = this.getHelpTextElementId();
28625  this.applyStyleToElement(this.helpTextElement, helpTextStyle);
28626  ASPx.SetInnerHtml(this.helpTextElement, "<SPAN>" + helpText + "</SPAN>");
28627  if(this.displayMode === ASPxClientTextEditHelpTextDisplayMode.Popup)
28628   this.updatePopupHelpTextPosition();
28629  else {
28630   var isVerticalOrientation = this.position === ASPx.Position.Top || this.position === ASPx.Position.Bottom;
28631   var orientationClassName = isVerticalOrientation ? ASPxClientTextEditHelpTextConsts.VERTICAL_ORIENTATION_CLASS_NAME :
28632    ASPxClientTextEditHelpTextConsts.HORIZONTAL_ORIENTATION_CLASS_NAME;
28633   this.helpTextElement.className += " " + orientationClassName;
28634   this.setInlineHelpTextElementAlign();
28635   ASPx.SetElementDisplay(this.helpTextElement, this.editor.clientVisible);
28636  }
28637 },
28638 getHelpTextElementId: function() {
28639  return this.editor.name + ASPx.TEHelpTextElementSuffix;
28640 },
28641 setInlineHelpTextElementAlign: function() {
28642  var hAlignValue = "", vAlignValue = "";
28643  switch(this.hAlign) {
28644   case ASPxClientTextEditHelpTextHAlign.Left: hAlignValue = "left"; break;
28645   case ASPxClientTextEditHelpTextHAlign.Right: hAlignValue = "right"; break;
28646   case ASPxClientTextEditHelpTextHAlign.Center: hAlignValue = "center"; break;
28647  }
28648  switch(this.vAlign) {
28649   case ASPxClientTextEditHelpTextVAlign.Top: vAlignValue = "top"; break;
28650   case ASPxClientTextEditHelpTextVAlign.Bottom: vAlignValue = "bottom"; break;
28651   case ASPxClientTextEditHelpTextVAlign.Middle: vAlignValue = "middle"; break;
28652  }
28653  this.helpTextElement.style.textAlign = hAlignValue;
28654  this.helpTextElement.style.verticalAlign = vAlignValue;
28655 },
28656 getHelpTextMargins: function() {
28657  if(this.margins)
28658   return this.margins;
28659  var result = this.defaultMargins;
28660  if(this.position === ASPx.Position.Top || this.position === ASPx.Position.Bottom)
28661   result.Left = result.Right = 0;
28662  else
28663   result.Top = result.Bottom = 0;
28664  return result;
28665 },
28666 updatePopupHelpTextPosition: function (editorMainElement) {
28667  var editorWidth = this.editorMainElement.offsetWidth;
28668  var editorHeight = this.editorMainElement.offsetHeight;
28669  var helpTextWidth = this.helpTextElement.offsetWidth;
28670  var helpTextHeight = this.helpTextElement.offsetHeight;
28671  var editorX = ASPx.GetAbsoluteX(this.editorMainElement);
28672  var editorY = ASPx.GetAbsoluteY(this.editorMainElement);
28673  var helpTextX = 0, helpTextY = 0;
28674  var margins = this.getHelpTextMargins();
28675  if(this.position === ASPx.Position.Top || this.position === ASPx.Position.Bottom) {
28676   if(this.position === ASPx.Position.Top)
28677    helpTextY = editorY - margins.Bottom - helpTextHeight;
28678   else if(this.position === ASPx.Position.Bottom)
28679    helpTextY = editorY + editorHeight + margins.Top;
28680   if(this.hAlign === ASPxClientTextEditHelpTextHAlign.Left)
28681    helpTextX = editorX + margins.Left;
28682   else if(this.hAlign === ASPxClientTextEditHelpTextHAlign.Right)
28683    helpTextX = editorX + editorWidth - helpTextWidth - margins.Right;
28684   else if(this.hAlign === ASPxClientTextEditHelpTextHAlign.Center) {
28685    var editorCenterX = editorX + editorWidth / 2;
28686    var helpTextWidthWithMargins = helpTextWidth + margins.Left + margins.Right;
28687    helpTextX = editorCenterX - helpTextWidthWithMargins / 2 + margins.Left;
28688   }
28689  } else {
28690   if(this.position === ASPx.Position.Left)
28691    helpTextX = editorX - margins.Right - helpTextWidth;
28692   else if(this.position === ASPx.Position.Right)
28693    helpTextX = editorX + editorWidth + margins.Left;
28694   if(this.vAlign === ASPxClientTextEditHelpTextVAlign.Top)
28695    helpTextY = editorY + margins.Top;
28696   else if(this.vAlign === ASPxClientTextEditHelpTextVAlign.Bottom)
28697    helpTextY = editorY + editorHeight - helpTextHeight - margins.Bottom;
28698   else if(this.vAlign === ASPxClientTextEditHelpTextVAlign.Middle) {
28699    var editorCenterY = editorY + editorHeight / 2;
28700    var helpTextHeightWithMargins = helpTextHeight + margins.Top + margins.Bottom;
28701    helpTextY = editorCenterY - helpTextHeightWithMargins / 2 + margins.Top;
28702   }
28703  }
28704  helpTextX = helpTextX < 0 ? 0 : helpTextX;
28705  helpTextY = helpTextY < 0 ? 0 : helpTextY;
28706  ASPx.SetAbsoluteX(this.helpTextElement, helpTextX);
28707  ASPx.SetAbsoluteY(this.helpTextElement, helpTextY);
28708 },
28709 setHelpTextZIndex: function (hide) { 
28710  var newZIndex = 41998 * (hide ? -1 : 1);
28711  if(this.helpTextElement.style.zIndex != newZIndex)
28712   this.helpTextElement.style.zIndex = newZIndex;
28713 },
28714 hide: function () {
28715  if(this.displayMode === ASPxClientTextEditHelpTextDisplayMode.Inline) {
28716   ASPx.SetElementDisplay(this.helpTextElement, false);
28717  }
28718  else
28719   this.hidePopupHelpText();
28720 },
28721 hidePopupHelpText: function() {
28722  var onHidePopupHelpTextComplete = function () {
28723   this.setHelpTextZIndex(true);
28724   ASPx.SetElementDisplay(this.helpTextElement, false);
28725  }.aspxBind(this);
28726  if(this.animationEnabled)
28727   ASPx.AnimationHelper.fadeOut(this.helpTextElement, onHidePopupHelpTextComplete);
28728  else {
28729   ASPx.AnimationHelper.setOpacity(this.helpTextElement, 0);
28730   onHidePopupHelpTextComplete();
28731  }    
28732 },
28733 show: function () {
28734  if(this.displayMode === ASPxClientTextEditHelpTextDisplayMode.Inline) {
28735   ASPx.SetElementDisplay(this.helpTextElement, true);
28736  }
28737  else
28738   this.showPopupHelpText();
28739 },
28740 showPopupHelpText: function () {
28741  ASPx.SetElementDisplay(this.helpTextElement, true);
28742  this.updatePopupHelpTextPosition();
28743  if(this.animationEnabled)
28744   ASPx.AnimationHelper.fadeIn(this.helpTextElement);
28745  else
28746   ASPx.AnimationHelper.setOpacity(this.helpTextElement, 1);
28747  this.setHelpTextZIndex(false);
28748 }
28749});
28750var ASPxOutOfRangeWarningManager = ASPx.CreateClass(null, {
28751 constructor: function (editor, minValue, maxValue, defaultMinValue, defaultMaxValue, outOfRangeWarningElementPosition, valueFormatter) {
28752  this.editor = editor;
28753  this.outOfRangeWarningElementPosition = outOfRangeWarningElementPosition;
28754  this.minValue = minValue;
28755  this.maxValue = maxValue;
28756  this.defaultMinValue = defaultMinValue;
28757  this.defaultMaxValue = defaultMaxValue;
28758  this.minMaxValueFormatter = valueFormatter;
28759  this.animationDuration = 150;
28760  this.CreateOutOfRangeWarningElement();
28761 },
28762 SetMinValue: function (minValue) {
28763  this.minValue = minValue;
28764  this.UpdateOutOfRangeWarningElementText();
28765 },
28766 SetMaxValue: function (maxValue) {
28767  this.maxValue = maxValue;
28768  this.UpdateOutOfRangeWarningElementText();
28769 },
28770 CreateOutOfRangeWarningElement: function () {
28771  this.outOfRangeWarningElement = document.createElement("DIV");
28772  this.outOfRangeWarningElement.id = this.editor.name + "OutOfRWarn";
28773  ASPx.InsertElementAfter(this.outOfRangeWarningElement, this.editor.GetOutOfRangeWarningElementPrevSibling());
28774  ASPx.AnimationHelper.setOpacity(this.outOfRangeWarningElement, 0);
28775  this.outOfRangeWarningElement.className = this.editor.outOfRangeWarningClassName;
28776  this.UpdateOutOfRangeWarningElementText();
28777 },
28778 IsValueInRange: function (value) {
28779  return (!this.IsMinValueExists() || value >= this.minValue)
28780   && (!this.IsMaxValueExists() || value <= this.maxValue);
28781 },
28782 IsMinValueExists: function() {
28783  return ASPx.IsExists(this.minValue) && !isNaN(this.minValue) && this.minValue !== this.defaultMinValue;
28784 },
28785 IsMaxValueExists: function () {
28786  return ASPx.IsExists(this.maxValue) && !isNaN(this.maxValue) && this.maxValue !== this.defaultMaxValue;
28787 },
28788 GetFormattedTextByValue: function(value) {
28789  if (this.minMaxValueFormatter)
28790   return this.minMaxValueFormatter.Format(value);
28791  return value;
28792 },
28793 GetWarningText: function() {
28794  var textTemplate = arguments[0];
28795  var valueTexts = [];
28796  for (var i = 1; i < arguments.length; i++) {
28797   var valueText = this.GetFormattedTextByValue(arguments[i]);
28798   valueTexts.push(valueText);
28799  }
28800  return ASPx.Formatter.Format(textTemplate, valueTexts);
28801 },
28802 UpdateOutOfRangeWarningElementText: function () {
28803  var text = "";
28804  if (this.IsMinValueExists() && this.IsMaxValueExists())
28805   text = this.GetWarningText(this.editor.outOfRangeWarningMessages[0], this.minValue, this.maxValue);
28806  if (this.IsMinValueExists() && !this.IsMaxValueExists())
28807   text = this.GetWarningText(this.editor.outOfRangeWarningMessages[1], this.minValue);
28808  if (!this.IsMinValueExists() && this.IsMaxValueExists())
28809   text = this.GetWarningText(this.editor.outOfRangeWarningMessages[2], this.maxValue);
28810  ASPx.SetInnerHtml(this.outOfRangeWarningElement, "<LABEL>" + text + "</LABEL>");
28811 },
28812 UpdateOutOfRangeWarningElementVisibility: function (currentValue) {
28813  var isValidValue = currentValue == null || this.IsValueInRange(currentValue);
28814  if (!isValidValue && !this.outOfRangeWarningElementShown)
28815   this.ShowOutOfRangeWarningElement();
28816  if (isValidValue && this.outOfRangeWarningElementShown)
28817   this.HideOutOfRangeWarningElement();
28818 },
28819 GetOutOfRangeWarningElementCoordinates: function() {
28820  var editorMainElement = this.editor.GetMainElement();
28821  var editorWidth = editorMainElement.offsetWidth;
28822  var editorHeight = editorMainElement.offsetHeight;
28823  var editorX = ASPx.GetAbsoluteX(editorMainElement);
28824  var editorY = ASPx.GetAbsoluteY(editorMainElement);
28825  var outOfRangeWarningElementX = this.outOfRangeWarningElementPosition === ASPx.Position.Right ? editorX + editorWidth : editorX;
28826  var outOfRangeWarningElementY = this.outOfRangeWarningElementPosition === ASPx.Position.Right ? editorY : editorY + editorHeight;
28827  outOfRangeWarningElementX = outOfRangeWarningElementX < 0 ? 0 : outOfRangeWarningElementX;
28828  outOfRangeWarningElementY = outOfRangeWarningElementY < 0 ? 0 : outOfRangeWarningElementY;
28829  return {
28830   x: outOfRangeWarningElementX,
28831   y: outOfRangeWarningElementY
28832  };
28833 },
28834 ShowOutOfRangeWarningElement: function () {
28835  this.outOfRangeWarningElement.style.display = "inline";
28836  var outOfRangeWarningElementCoordinates = this.GetOutOfRangeWarningElementCoordinates();
28837  ASPx.SetAbsoluteX(this.outOfRangeWarningElement, outOfRangeWarningElementCoordinates.x);
28838  ASPx.SetAbsoluteY(this.outOfRangeWarningElement, outOfRangeWarningElementCoordinates.y);
28839  ASPx.AnimationHelper.fadeIn(this.outOfRangeWarningElement, null, this.animationDuration);
28840  this.ScrollToWarningElementIfRequired(outOfRangeWarningElementCoordinates);
28841  this.outOfRangeWarningElementShown = true;
28842 },
28843 HideOutOfRangeWarningElement: function () {
28844  ASPx.AnimationHelper.fadeOut(this.outOfRangeWarningElement, function () {
28845   ASPx.SetElementDisplay(this.outOfRangeWarningElement, false);
28846  }.aspxBind(this), this.animationDuration);
28847  this.outOfRangeWarningElementShown = false;
28848 },
28849 ScrollToWarningElementIfRequired: function (outOfRangeWarningElementCoordinates) {
28850  if(this.outOfRangeWarningElementPosition === ASPx.Position.Right) {
28851   var warnElementRightPos = outOfRangeWarningElementCoordinates.x
28852    + ASPx.PxToInt(ASPx.GetCurrentStyle(this.outOfRangeWarningElement).marginLeft)
28853    + this.outOfRangeWarningElement.offsetWidth;
28854   if(warnElementRightPos > ASPx.GetDocumentClientWidth() + ASPx.GetDocumentScrollLeft())
28855    ASPx.SetDocumentScrollLeft(warnElementRightPos - ASPx.GetDocumentClientWidth());
28856  }
28857  if(this.outOfRangeWarningElementPosition === ASPx.Position.Bottom) {
28858   var warnElementBottomPos = outOfRangeWarningElementCoordinates.y
28859    + ASPx.PxToInt(ASPx.GetCurrentStyle(this.outOfRangeWarningElement).marginTop)
28860    + this.outOfRangeWarningElement.offsetHeight;
28861   if(warnElementBottomPos > ASPx.GetDocumentClientHeight() + ASPx.GetDocumentScrollTop())
28862    ASPx.SetDocumentScrollTop(warnElementBottomPos - ASPx.GetDocumentClientHeight());
28863  }
28864 }
28865});
28866ASPx.MMMouseOut = function(name, evt) {
28867 var edit = ASPx.GetControlCollection().Get(name);
28868 if(edit != null) edit.OnMouseOut(evt);
28869};
28870ASPx.MMMouseOver = function(name, evt) {
28871 var edit = ASPx.GetControlCollection().Get(name);
28872 if(edit != null) edit.OnMouseOver(evt);
28873};
28874ASPx.MaskHintTimerProc = function() {
28875 var focusedEditor = ASPx.GetFocusedEditor();
28876 if(focusedEditor != null && ASPx.IsFunction(focusedEditor.MaskHintTimerProc))
28877  focusedEditor.MaskHintTimerProc();
28878};
28879ASPx.ETextChanged = function(name) {
28880 var edit = ASPx.GetControlCollection().Get(name);
28881 if(edit != null) edit.OnTextChanged(); 
28882};
28883ASPx.BEClick = function(name,number){
28884 var edit = ASPx.GetControlCollection().Get(name);
28885 if(edit != null) edit.OnButtonClick(number);
28886};
28887ASPx.BEClear = function(name, evt) {
28888 var edit = ASPx.GetControlCollection().Get(name);
28889 if(edit && (evt.button === 0 || ASPx.Browser.TouchUI))
28890  edit.onClearButtonClick();
28891};
28892ASPx.SetFocusToTextEditWithDelay = function(name) {
28893 window.setTimeout(function() {
28894  var edit = ASPx.GetControlCollection().Get(name);
28895  if(edit)
28896   edit.SetFocus();
28897 }, 500);
28898};
28899window.ASPxClientTextEdit = ASPxClientTextEdit;
28900window.ASPxClientTextBoxBase = ASPxClientTextBoxBase;
28901window.ASPxClientTextBox = ASPxClientTextBox;
28902window.ASPxClientMemo = ASPxClientMemo;
28903window.ASPxClientButtonEditBase = ASPxClientButtonEditBase;
28904window.ASPxClientButtonEdit = ASPxClientButtonEdit;
28905window.ASPxClientButtonEditClickEventArgs = ASPxClientButtonEditClickEventArgs;
28906})();
28907
28908(function(dx) {
28909 var BootstrapClientTextBox = ASPx.CreateClass(ASPxClientTextBox, {
28910  constructor: function(name) {
28911   this.constructor.prototype.constructor.call(this, name);
28912   this.feedbackRenderHelper = new ASPx.BootstrapEditFeedbackRenderHelper(this);
28913  },
28914  InlineInitialize: function() {
28915   this.RequireStyleDecoration();
28916   ASPxClientTextBox.prototype.InlineInitialize.call(this);
28917   this.feedbackRenderHelper.updateInputRightPadding();
28918   if(ASPx.Browser.TouchUI && !this.GetIsValid())
28919    this.UpdateErrorText();
28920  },
28921  InitializeEvents: function() {
28922   ASPxClientTextBox.prototype.InitializeEvents.call(this);
28923   var inputElement = this.GetInputElement();
28924   if(inputElement)
28925    ASPx.Evt.AttachEventToElement(inputElement, "change", function() { ASPx.EValueChanged(this.name); }.bind(this));
28926   if(ASPx.Browser.MacOSMobilePlatform) {
28927    var errorImage = this.GetErrorImage();
28928    if(errorImage)
28929     ASPx.Evt.AttachEventToElement(errorImage, "touchstart", function() { });
28930   }
28931  },
28932  RaiseStandardOnChange: function() {
28933   var element = this.GetInputElement();
28934   if(element)
28935    ASPx.Evt.DispatchEvent(element, "change", true, false);
28936   else
28937    ASPxClientTextBox.prototype.RaiseStandardOnChange.call(this);
28938  },
28939  ChangeEnabledStateItems: function(enabled) { },
28940  GetControlCell: function() {
28941   return this.GetInputContainerElement();
28942  },
28943  EnsureControlCellStylesLoaded: function() { },
28944  ClearControlCellStyles: function() { },
28945  RestoreControlCellStyles: function() { },
28946  GetElementRequiredForErrorFrame: function() {
28947   return this.GetInputContainerElement();
28948  },
28949  GetErrorImage: function() {
28950   return this.feedbackRenderHelper.getErrorImage();
28951  },
28952  UpdateErrorText: function() {
28953   this.feedbackRenderHelper.updateErrorText();
28954  },
28955  ChangeErrorCellVisibility: function(visible, useVisibilityAttribute) {
28956   this.feedbackRenderHelper.setErrorControlVisible(visible);
28957  },
28958  PopulateStyleDecorationPostfixes: function() {
28959   this.styleDecoration.AddPostfix("");
28960   this.styleDecoration.AddPostfix("div > .form-control");
28961  },
28962  CreateStyleDecoration: function() {
28963   return new ASPx.BootstrapEditorStyleDecoration(this);
28964  },
28965  GetInputContainerElement: function() {
28966   var inputElement = this.GetInputElement();
28967   return inputElement ? inputElement.parentNode : null;
28968  },
28969  GetCaptionCell: function() {
28970   return ASPx.CacheHelper.GetCachedElement(this, "captionElement",
28971    function() {
28972     var mainElement = this.GetMainElement();
28973     return mainElement && mainElement.querySelector(".dxbs-edit-caption");
28974    }
28975   );
28976  },
28977  getCaptionTextNode: function() {
28978   return ASPx.GetNormalizedTextNode(this.GetCaptionCell());
28979  },
28980  getCaptionRelatedCellCount: function() {
28981   return undefined;
28982  },
28983  helpTextInitialize: function() {
28984   if(this.helpText)
28985    this.helpTextObj = new ASPx.BootstrapTextEditHelpText(this, this.helpText, this.enableHelpTextPopupAnimation, this.hasPopupHelpText());
28986  },
28987  GetHelpTextElementPrevSibling: function() {
28988   return this.feedbackRenderHelper.getErrorTextElement() || this.GetInputContainerElement();
28989  },
28990  getFocusedNullTextElementClassName: function() {
28991   return "dxbs-null-text text-muted" + (this.cssClasses.nt ? " " + this.cssClasses.nt : "");
28992  }
28993 });
28994 dx.BootstrapClientTextBox = BootstrapClientTextBox;
28995 var BootstrapClientMemo = ASPx.CreateClass(ASPxClientMemo, {
28996  constructor: function(name) {
28997   this.constructor.prototype.constructor.call(this, name);
28998   this.feedbackRenderHelper = new ASPx.BootstrapEditFeedbackRenderHelper(this);
28999  },
29000  InlineInitialize: function() {
29001   this.RequireStyleDecoration();
29002   ASPxClientMemo.prototype.InlineInitialize.call(this);
29003   this.feedbackRenderHelper.updateInputRightPadding();
29004   if(ASPx.Browser.TouchUI && !this.GetIsValid())
29005    this.UpdateErrorText();
29006  },
29007  InitializeEvents: function() {
29008   ASPxClientMemo.prototype.InitializeEvents.call(this);
29009   var inputElement = this.GetInputElement();
29010   if(inputElement) {
29011    if(this.maxLengthRestricted) {
29012     ASPx.Evt.AttachEventToElement(inputElement, "mouseout", function(evt) { ASPx.MMMouseOut(this.name, evt); }.bind(this));
29013     ASPx.Evt.AttachEventToElement(inputElement, "mouseover", function(evt) { ASPx.MMMouseOver(this.name, evt); }.bind(this));
29014    }
29015    ASPx.Evt.AttachEventToElement(inputElement, "change", function () { ASPx.EValueChanged(this.name); }.bind(this));
29016   }
29017   if(ASPx.Browser.MacOSMobilePlatform) {
29018    var errorImage = this.GetErrorImage();
29019    if(errorImage)
29020     ASPx.Evt.AttachEventToElement(errorImage, "touchstart", function() { });
29021   }
29022  },
29023  RaiseStandardOnChange: function() {
29024   var element = this.GetInputElement();
29025   if(element)
29026    ASPx.Evt.DispatchEvent(element, "change", true, false);
29027   else
29028    ASPxClientMemo.prototype.RaiseStandardOnChange.call(this);
29029  },
29030  ChangeEnabledStateItems: function (enabled) { },
29031  IsAdjustmentRequired: function() {
29032   return false;
29033  },
29034  AdjustControl: function() { },
29035  GetControlCell: function() {
29036   return this.GetInputContainerElement();
29037  },
29038  EnsureControlCellStylesLoaded: function() { },
29039  ClearControlCellStyles: function() { },
29040  RestoreControlCellStyles: function() { },
29041  GetElementRequiredForErrorFrame: function() {
29042   return this.GetInputContainerElement();
29043  },
29044  GetErrorImage: function() {
29045   return this.feedbackRenderHelper.getErrorImage();
29046  },
29047  UpdateErrorText: function() {
29048   this.feedbackRenderHelper.updateErrorText();
29049  },
29050  ChangeErrorCellVisibility: function(visible, useVisibilityAttribute) {
29051   this.feedbackRenderHelper.setErrorControlVisible(visible);
29052  },
29053  PopulateStyleDecorationPostfixes: function() {
29054   this.styleDecoration.AddPostfix("");
29055   this.styleDecoration.AddPostfix("div > .form-control");
29056  },
29057  CreateStyleDecoration: function() {
29058   return new ASPx.BootstrapEditorStyleDecoration(this);
29059  },
29060  GetInputContainerElement: function() {
29061   var inputElement = this.GetInputElement();
29062   return inputElement ? inputElement.parentNode : null;
29063  },
29064  GetCaptionCell: function() {
29065   return ASPx.CacheHelper.GetCachedElement(this, "captionElement",
29066    function() {
29067     var mainElement = this.GetMainElement();
29068     return mainElement && mainElement.querySelector(".dxbs-edit-caption");
29069    }
29070   );
29071  },
29072  getCaptionTextNode: function() {
29073   return ASPx.GetNormalizedTextNode(this.GetCaptionCell());
29074  },
29075  getCaptionRelatedCellCount: function() {
29076   return undefined;
29077  },
29078  helpTextInitialize: function() {
29079   if(this.helpText)
29080    this.helpTextObj = new ASPx.BootstrapTextEditHelpText(this, this.helpText, this.enableHelpTextPopupAnimation, this.hasPopupHelpText());
29081  },
29082  GetHelpTextElementPrevSibling: function() {
29083   return this.feedbackRenderHelper.getErrorTextElement() || this.GetInputContainerElement();
29084  },
29085  getFocusedNullTextElementClassName: function() {
29086   return "dxbs-null-text text-muted" + (this.cssClasses.nt ? " " + this.cssClasses.nt : "");
29087  }
29088 });
29089 dx.BootstrapClientMemo = BootstrapClientMemo;
29090 var BootstrapClientButtonEdit = ASPx.CreateClass(ASPxClientButtonEdit, {
29091  constructor: function(name) {
29092   this.constructor.prototype.constructor.call(this, name);
29093   this.feedbackRenderHelper = new ASPx.BootstrapEditFeedbackRenderHelper(this);
29094  },
29095  InlineInitialize: function() {
29096   this.RequireStyleDecoration();
29097   ASPxClientButtonEdit.prototype.InlineInitialize.call(this);
29098   this.feedbackRenderHelper.updateInputRightPadding();
29099   if(ASPx.Browser.TouchUI && !this.GetIsValid())
29100    this.UpdateErrorText();
29101  },
29102  InitializeEvents: function() {
29103   ASPxClientButtonEdit.prototype.InitializeEvents.call(this);
29104   var inputElement = this.GetInputElement();
29105   if(inputElement)
29106    ASPx.Evt.AttachEventToElement(inputElement, "change", function() { ASPx.EValueChanged(this.name); }.bind(this));
29107   var buttonElements = this.GetCustomButtonCollection();
29108   for(var i = 0; i < buttonElements.length; i++) 
29109    this.InitializeButtonEvents(buttonElements[i], i);
29110   var clearButton = this.GetClearButton();
29111   if(clearButton) {
29112    ASPx.Evt.AttachEventToElement(clearButton, "mousedown", function(evt) { ASPx.BEClear(this.name, evt); }.bind(this));
29113    if(this.IsAccessibleButton(clearButton))
29114     this.InitAccessibilityAnchorEvents(clearButton);
29115   }
29116   if(ASPx.Browser.MacOSMobilePlatform) {
29117    var errorImage = this.GetErrorImage();
29118    if(errorImage)
29119     ASPx.Evt.AttachEventToElement(errorImage, "touchstart", function() { });
29120   }
29121  },
29122  InitializeButtonEvents: function(element, number){
29123   ASPx.Evt.AttachEventToElement(element, "click", function() {
29124    this.OnButtonClick(number);
29125   }.bind(this));
29126   if(this.IsAccessibleButton(element))
29127    this.InitAccessibilityAnchorEvents(element);
29128  },
29129  SetButtonVisible: function(number, value) {
29130   if(number == -100) {
29131    this.feedbackRenderHelper.setClearButtonVisible(value);
29132    return;
29133   }
29134   if(ASPx.BootstrapCore.IsBootstrap3 || ASPx.BootstrapCore.IsBootstrap4) {
29135    var inputGroupButton = ASPxClientButtonEdit.prototype.GetButton.call(this, number);
29136    if(inputGroupButton)
29137     ASPx.SetElementDisplay(inputGroupButton.parentNode, value);
29138   }
29139   ASPxClientButtonEdit.prototype.SetButtonVisible.call(this, number, value);
29140  },
29141  ChangeEnabledAttributes: function(enabled) {
29142   ASPxClientButtonEdit.prototype.ChangeEnabledAttributes.call(this, enabled);
29143   var clearButton = this.GetClearButton();
29144   if(clearButton)
29145    this.ChangeButtonEnabledAttributes(clearButton, this.GetChangeButtonEnabledAttributesMethod(enabled));
29146  },
29147  GetChangeButtonEnabledAttributesMethod: function(enabled) {
29148   return dx.BootstrapClientUtils.GetChangeButtonEnabledAttributesMethod(enabled);
29149  },
29150  ChangeButtonEnabledAttributes: function(element, method) {
29151   if(ASPx.Attr.IsExistsAttribute(element, "disabledOnServer"))
29152    return;
29153   method(element, ASPx.BootstrapCssSelectors.Disabled);
29154  },
29155  NeedEnsureClearButtonVisibilityOnKeyDown: function() {
29156   return this.IsAccessibleButton(this.GetClearButton());
29157  },
29158  GetAccessibilityFocusedButtonClassName: function() {
29159   return "";
29160  },
29161  IsAccessibleButton: function(button) {
29162   return !!button && (button.tagName.toUpperCase() == "BUTTON" || ASPx.Attr.GetAttribute(button, "role") == "button");
29163  },
29164  GetButtonByAccessibilityAnchor: function(anchorElement) {
29165   return anchorElement;
29166  },
29167  GetAccessibilityAnchor: function(buttonElement) {
29168   return buttonElement;
29169  },
29170  SetAccessibilityAnchorEnabled: function(buttonElement, enabled) {
29171   if(buttonElement.tagName.toUpperCase() == "BUTTON")
29172    return;
29173   ASPxClientButtonEdit.prototype.SetAccessibilityAnchorEnabled.call(this, buttonElement, enabled);
29174  },
29175  EmulateButtonMouseEvent: function(sourceElement) {
29176   ASPx.Evt.EmulateMouseClick(sourceElement);
29177  },
29178  RaiseStandardOnChange: function() {
29179   var element = this.GetInputElement();
29180   if(element)
29181    ASPx.Evt.DispatchEvent(element, "change", true, false);
29182   else
29183    ASPxClientButtonEdit.prototype.RaiseStandardOnChange.call(this);
29184  },
29185  ChangeEnabledStateItems: function(enabled) { },
29186  GetControlCell: function() {
29187   return this.GetInputContainerElement();
29188  },
29189  EnsureControlCellStylesLoaded: function() { },
29190  ClearControlCellStyles: function() { },
29191  RestoreControlCellStyles: function() { },
29192  GetElementRequiredForErrorFrame: function() {
29193   return this.GetInputContainerElement();
29194  },
29195  GetErrorImage: function() {
29196   return this.feedbackRenderHelper.getErrorImage();
29197  },
29198  UpdateErrorText: function() {
29199   this.feedbackRenderHelper.updateErrorText();
29200  },
29201  ChangeErrorCellVisibility: function(visible, useVisibilityAttribute) {
29202   this.feedbackRenderHelper.setErrorControlVisible(visible);
29203  },
29204  PopulateStyleDecorationPostfixes: function() {
29205   var inputContainerSelector = this.GetInputContainerSelector();
29206   this.styleDecoration.AddPostfix("");
29207   this.styleDecoration.AddPostfix(inputContainerSelector);
29208   this.styleDecoration.AddPostfix(inputContainerSelector + " .form-control");
29209  },
29210  GetInputContainerSelector: function() {
29211   var selector = "";
29212   if(!!this.GetInputGroupElement())
29213    selector = ".input-group";
29214   else {
29215    var invalidSelectors = ASPx.Data.GetDistinctArray(["." + ASPx.BootstrapCssSelectors.InputGroupAppendButton,
29216     "." + ASPx.BootstrapCssSelectors.InputGroupPrependButton]);
29217    selector = "div";
29218    for(var i = 0; i < invalidSelectors.length; i++)
29219     selector += ":not(" + invalidSelectors[i] + ")";
29220   }
29221   return selector;
29222  },
29223  CreateStyleDecoration: function() {
29224   return new ASPx.BootstrapEditorStyleDecoration(this);
29225  },
29226  GetHideContentCssClassName: function() {
29227   return ASPx.BootstrapCssSelectors.Hidden;
29228  },
29229  GetHoverElementToShowClearButton: function() {
29230   return this.GetInputGroupElement() || this.GetInputContainerElement();
29231  },
29232  GetInputGroupElement: function() {
29233   var mainElement = this.GetMainElement();
29234   return mainElement && mainElement.querySelector(".input-group");
29235  },
29236  GetInputContainerElement: function() {
29237   var inputElement = this.GetInputElement();
29238   return inputElement ? inputElement.parentNode : null;
29239  },
29240  GetCaptionCell: function() {
29241   return ASPx.CacheHelper.GetCachedElement(this, "captionElement",
29242    function() {
29243     var mainElement = this.GetMainElement();
29244     return mainElement && mainElement.querySelector(".dxbs-edit-caption");
29245    }
29246   );
29247  },
29248  getCaptionTextNode: function () {
29249   return ASPx.GetNormalizedTextNode(this.GetCaptionCell());
29250  },
29251  getCaptionRelatedCellCount: function () {
29252   return undefined;
29253  },
29254  GetClearButton: function() {
29255   return this.feedbackRenderHelper.getClearButton();
29256  },
29257  GetButton: function (number) {
29258   var inputGroupButton = ASPxClientButtonEdit.prototype.GetButton.call(this, number);
29259   return number == -100 ? this.GetClearButton() :
29260    inputGroupButton && (inputGroupButton.querySelector(".dxbs-edit-btn") || inputGroupButton.querySelector(".btn") || inputGroupButton);
29261  },
29262  helpTextInitialize: function() {
29263   if(this.helpText)
29264    this.helpTextObj = new ASPx.BootstrapTextEditHelpText(this, this.helpText, this.enableHelpTextPopupAnimation, this.hasPopupHelpText());
29265  },
29266  GetHelpTextElementPrevSibling: function() {
29267   var errorTextElement = this.feedbackRenderHelper.getErrorTextElement();
29268   return errorTextElement || this.GetInputGroupElement() || this.GetInputContainerElement();
29269  },
29270  getFocusedNullTextElementClassName: function() {
29271   return "dxbs-null-text text-muted" + (this.cssClasses.nt ? " " + this.cssClasses.nt : "");
29272  }
29273 });
29274 dx.BootstrapClientButtonEdit = BootstrapClientButtonEdit;
29275})(dx || (dx = {}));
29276(function() {
29277var CheckBoxValidStateMode = {
29278 Checked: "Checked",
29279 CheckedAndUnchecked: "CheckedAndUnchecked"
29280};
29281var CheckBoxRequiredValidationPattern = ASPx.CreateClass(ASPx.ValidationPattern, {
29282 constructor: function(checkBox, errorText) {
29283  this.constructor.prototype.constructor.call(this, errorText);
29284  this.checkBox = checkBox;
29285 },
29286 EvaluateIsValid: function(value) {
29287  var checkState = this.checkBox.GetCheckState();
29288  if(this.checkBox.validStateMode === CheckBoxValidStateMode.Checked)
29289   return checkState === ASPx.CheckBoxCheckState.Checked;
29290  else
29291   return checkState !== ASPx.CheckBoxCheckState.Indeterminate;
29292 },
29293});
29294var ASPxClientCheckBox = ASPx.CreateClass(ASPxClientEdit, {
29295 constructor: function(name) {
29296  this.constructor.prototype.constructor.call(this, name);
29297  this.isASPxClientCheckEdit = true;
29298  this.valueChecked = true;
29299  this.valueUnchecked = false;
29300  this.valueGrayed = null;
29301  this.allowGrayed = false;
29302  this.isNative = false;
29303  this.stateController = null;
29304  this.imageProperties = null;
29305  this.allowGrayedByClick = true;
29306  this.displaySwitch = false;
29307  this.internalCheckBox = null;
29308  this.icbFocusedStyle = [];
29309  this.checkedIsValidOnly = false;
29310  this.sizingConfig.allowSetWidth = false;
29311  this.sizingConfig.allowSetHeight = false;
29312  this.isRequiredCheckBox = false;
29313  this.requiredCheckBoxErrorText = "*";
29314  this.validStateMode = CheckBoxValidStateMode.Checked;
29315  this.CheckedChanged = new ASPxClientEvent();
29316 },
29317 InlineInitialize: function() {
29318  this.isNative = !this.imageProperties;
29319  this.allowGrayed = this.IsGrayedAllowed();
29320  this.stateController = ASPx.CheckableElementStateController.Create(this.imageProperties, this.valueChecked,  this.valueUnchecked, this.valueGrayed, this.allowGrayed);
29321  if(!this.isNative)
29322   this.CreateInternalCheckBox();
29323  if(this.isRequiredCheckBox)
29324   this.validationPatterns.push(new CheckBoxRequiredValidationPattern(this, this.requiredCheckBoxErrorText));
29325  ASPxClientEdit.prototype.InlineInitialize.call(this);
29326 },
29327 Initialize: function() {
29328  ASPxClientEdit.prototype.Initialize.call(this);
29329  if(!ASPx.IsExistsElement(this.GetMainElement()))
29330   return;
29331  if(!this.isNative) {
29332   this.previousValue = this.GetStateInput().value;
29333   if(this.GetValue() !== null)
29334    this.UpdateInternalCheckState(); 
29335   this.SetValue(this.GetValue());
29336  }
29337  else
29338   this.previousValue = this.GetInputElement().checked;
29339 },
29340 UpdateInternalCheckState: function() {
29341  var stateInput = this.GetStateInput();
29342  stateInput.value = this.stateController.GetInputKeyByValue(true);
29343  stateInput.value = this.stateController.GetInputKeyByValue(false);
29344  var checkState = this.stateController.GetCheckStateByInputKey(this.previousValue);
29345  this.SetCheckState(checkState);
29346 },
29347 GetInputElement: function() {
29348  if(this.isNative)
29349   return ASPxClientEdit.prototype.GetInputElement.call(this);
29350  else
29351   return this.GetStateInput();
29352 },
29353 CreateInternalCheckBox: function() {
29354  var instance = this;
29355  this.internalCheckBox = new ASPx.CheckBoxInternal(this.GetStateInput(), this.stateController, this.allowGrayed, this.allowGrayedByClick, 
29356   ASPx.CheckEditElementHelper.Instance, this.GetMainElement(), true, undefined, undefined, this.accessibilityCompliant, this.displaySwitch);
29357  this.internalCheckBox.CreateFocusDecoration(this.icbFocusedStyle);
29358  this.internalCheckBox.SetValue(this.GetValue(), true); 
29359  this.internalCheckBox.SetEnabled(this.GetEnabled());
29360  this.internalCheckBox.GetReadOnly = this.GetReadOnly.bind(this);
29361  this.internalCheckBox.CheckedChanged.AddHandler(function(s, e) { instance.OnClick(e); });
29362  this.internalCheckBox.Focus.AddHandler(function() { instance.OnFocus(); });
29363  this.internalCheckBox.LostFocus.AddHandler(function() { instance.OnLostFocus(); });
29364  if(ASPx.Browser.WebKitFamily) 
29365   ASPx.Evt.AttachEventToElement(this.internalCheckBox.mainElement.parentNode, "selectstart", ASPx.Evt.PreventEventAndBubble);
29366 },
29367 FindInputElement: function() {
29368  var element = this.GetMainElement();
29369  if(ASPx.IsExistsElement(element) && element.tagName != "INPUT")
29370   element = this.GetChildElement("I");
29371  return element;
29372 },
29373 GetFocusableInputElement: function() {
29374  if(this.isNative)
29375   return this.GetInputElement();
29376  return this.accessibilityCompliant ? this.GetICBMainElement() : this.GetInputElement();
29377 },
29378 IsGrayedAllowed: function() {
29379  for(var propertyKey in this.imageProperties)
29380   if(this.imageProperties[propertyKey].length === 3)
29381    return true;
29382  return false;
29383 },
29384 RaiseValueChangedEvent: function() {
29385  var processOnServer = ASPxClientEdit.prototype.RaiseValueChangedEvent.call(this);
29386  processOnServer = this.RaiseCheckedChanged(processOnServer);
29387  return processOnServer;
29388 }, 
29389 OnClick: function() {
29390  if(this.ToogleCheckState() && !this.focused)
29391   this.SetFocus();
29392 },  
29393 ToogleCheckState: function() {
29394  if(!this.GetEnabled() || this.GetReadOnly())
29395   return false;
29396  var value = this.GetCorrectValue(this.previousValue);
29397  value = this.stateController.GetNextCheckBoxValue(value, this.allowGrayedByClick && this.allowGrayed);    
29398  this.SetValue(value);
29399  this.OnValueChanged();
29400  return true;
29401 },
29402 IsElementBelongToInputElement: function(element) {
29403  return false; 
29404 },
29405 ForceRefocusEditor: function() {
29406  if(this.isNative)
29407   ASPxClientEdit.prototype.ForceRefocusEditor.call(this);
29408 },
29409 GetValue: function() {
29410  var value = this.stateController.GetValueByInputKey(this.GetStateInput().value);
29411  if(value === "" && this.convertEmptyStringToNull)
29412   value = null;     
29413  return value;
29414 },  
29415 SetValue: function(value) {
29416  this.previousValue = value;
29417  value = this.GetCorrectValue(value);
29418  if(this.isNative)
29419   this.GetInputElement().checked = (this.previousValue == this.valueChecked);
29420  else
29421   this.internalCheckBox.SetValue(value);
29422  this.GetStateInput().value = this.stateController.GetInputKeyByValue(value);
29423  if(this.accessibilityCompliant) {
29424   var state = this.GetCheckState();
29425   var mainElement = this.GetICBMainElement();
29426   this.stateController.SetAriaCheckedSelectedAttributes(mainElement, state);
29427  }
29428  this.OnValueSet();
29429 },
29430 GetICBMainElement: function() {
29431  return ASPx.CheckableElementHelper.Instance.GetICBMainElementByInput(this.GetStateInput());
29432 },
29433 GetLabelElement: function() {
29434  return ASPx.CheckEditElementHelper.Instance.GetLabelElement(this.GetMainElement());
29435 },
29436 GetStateInput: function() {
29437  return this.GetChildElement("S");
29438 },
29439 GetAccessibilityActiveElements: function() {
29440  return [this.GetFocusableInputElement()];
29441 },
29442 GetCorrectValue: function(value) {
29443  var stateIsExist = typeof(this.stateController.GetInputKeyByValue(value)) != "undefined";
29444  if(!stateIsExist)
29445   return this.allowGrayed ? this.valueGrayed : this.valueUnchecked; 
29446  return value;
29447 },
29448 OnValueSet: function() {},
29449 RaiseCheckedChanged: function(processOnServer) {
29450  if(!this.CheckedChanged.IsEmpty()) {
29451   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
29452   this.CheckedChanged.FireEvent(this, args);
29453   processOnServer = args.processOnServer;
29454  }
29455  return processOnServer;
29456 },
29457 SetEnabled: function(enabled) {
29458  ASPxClientEdit.prototype.SetEnabled.call(this, enabled);
29459  if(!this.isNative) 
29460    this.internalCheckBox.SetEnabled(enabled);
29461 },
29462 GetChecked: function() {
29463  return this.stateController.GetCheckStateByInputKey(this.GetStateInput().value) == ASPx.CheckBoxCheckState.Checked;
29464 },
29465 SetChecked: function(isChecked) {
29466  this.SetCheckState(isChecked ? ASPx.CheckBoxCheckState.Checked : ASPx.CheckBoxCheckState.Unchecked);
29467 },
29468 GetText: function() {
29469  var labelElement = this.GetLabelElement();
29470  return (labelElement != null) ? labelElement.innerHTML : "";
29471 },
29472 GetCheckState: function() {
29473  var internalCheckeState = this.stateController.GetCheckStateByInputKey(this.GetStateInput().value);
29474  if(internalCheckeState != ASPx.CheckBoxCheckState.Indeterminate || this.allowGrayed)
29475   return internalCheckeState;
29476  else 
29477   return ASPx.CheckBoxCheckState.Unchecked;
29478 },
29479 SetCheckState: function(checkState) {
29480  if(checkState != ASPx.CheckBoxCheckState.Indeterminate || this.allowGrayed) {
29481   var value = this.stateController.GetValueByCheckState(checkState);
29482   this.SetValue(value);
29483  }
29484 },
29485 SetText: function(text) {
29486  var labelElement = this.GetLabelElement();
29487  if(labelElement != null) 
29488   ASPx.SetInnerHtml(labelElement, text);
29489 },
29490 ChangeEnabledAttributes: function(enabled){
29491  if(this.isNative) {
29492   this.ChangeInputEnabledAttributes(this.GetInputElement(), ASPx.Attr.ChangeAttributesMethod(enabled));
29493   this.ChangeSpecialInputEnabledAttributes(this.GetInputElement(), ASPx.Attr.ChangeEventsMethod(enabled), true);
29494   this.GetInputElement().disabled = !enabled;
29495  } else
29496   this.internalCheckBox.SetEnabled(enabled);
29497 },
29498 ChangeEnabledStateItems: function(enabled){
29499  ASPx.GetStateController().SetElementEnabled(this.GetMainElement(), enabled);
29500  this.GetStateInput().disabled = !enabled;
29501 },
29502 ChangeInputEnabledAttributes: function(element, method){
29503  method(element, "onclick");
29504 }
29505});
29506ASPxClientCheckBox.Cast = ASPxClientControl.Cast;
29507var ASPxClientRadioButton = ASPx.CreateClass(ASPxClientCheckBox, {
29508 constructor: function(name) {
29509  this.constructor.prototype.constructor.call(this, name);
29510  this.isASPxClientRadioButton = true;
29511  this.groupName = "";
29512 },
29513 Initialize: function() {
29514  ASPxClientCheckBox.prototype.Initialize.call(this);
29515  if(this.accessibilityCompliant && this.groupName)
29516   this.setAccessibilityGroupAttributes();
29517 },
29518 setAccessibilityGroupAttributes: function() {
29519  var members = this.GetGroupMembers();
29520  var currentIndex = members.indexOf(this);
29521  var focusableElement = this.GetFocusableInputElement();
29522  ASPx.Attr.SetAttribute(focusableElement, "aria-setsize", members.length);
29523  ASPx.Attr.SetAttribute(focusableElement, "aria-posinset", currentIndex + 1);
29524 },
29525 OnValueSet: function() {
29526  if(this.previousValue === true) 
29527   this.UncheckOtherGroupMembers(true );
29528 },
29529 OnClick: function() {
29530  if(!this.previousValue) {
29531   this.UncheckOtherGroupMembers();
29532   ASPxClientCheckBox.prototype.OnClick.call(this);
29533  } else {
29534   if(!this.focused)
29535    this.SetFocus();
29536  }
29537 },
29538 CreateInternalCheckBox: function() {
29539  ASPxClientCheckBox.prototype.CreateInternalCheckBox.call(this);
29540  this.internalCheckBox.autoSwitchEnabled = false;
29541 },
29542 UncheckOtherGroupMembers: function(suppressEvents) {
29543  var members = this.GetGroupMembers();
29544  for(var i = 0; i < members.length; i++) {
29545   var radioButton = members[i];
29546   if(!ASPx.IsExistsElement(radioButton.GetMainElement()))
29547    members[i] = null;
29548   else {
29549    if(radioButton != this && radioButton.GetValue()){
29550     radioButton.SetValue(false);
29551     if(!suppressEvents)
29552      radioButton.RaiseValueChangedEvent();
29553    }
29554   }
29555  }
29556 },
29557 OnReadonlyClick: function() {
29558  if(!this.previousValue) {   
29559   var members = this.GetGroupMembers();   
29560   for(var i = 0; i < members.length; i++) {
29561    var radioButton = members[i];
29562    radioButton.SetValue(radioButton.GetValue());
29563   }
29564  }
29565 },
29566 GetGroupName: function() {
29567  if(!this.isNative)
29568   return this.groupName;
29569  var inputElement = this.GetInputElement();
29570  if (!ASPx.IsExistsElement(inputElement))
29571   return null;
29572  var name = inputElement.name;
29573  if(!name.length)
29574   name = "";
29575  return name;
29576 },
29577 GetGroupMembers: function() {
29578  var result = [ ];
29579  var groupName = this.GetGroupName();
29580  if(groupName.length > 0) {
29581   ASPx.GetControlCollection().ForEachControl(function(control) {
29582    if(ASPx.Ident.IsASPxClientRadioButton(control)) {
29583     var controlGroupName = control.GetGroupName();
29584     if (controlGroupName != null && controlGroupName == groupName)
29585      result.push(control);
29586    }
29587   });
29588  } else {
29589   result.push(this);
29590  }
29591  return result;  
29592 },
29593 GetChecked: function() {
29594  return this.GetValue() == true;
29595 },
29596 SetChecked: function(isChecked) {
29597  this.SetValue(isChecked);
29598 }
29599});
29600ASPxClientRadioButton.Cast = ASPxClientControl.Cast;
29601ASPx.Ident.IsASPxClientCheckEdit = function(obj) {
29602 return !!obj.isASPxClientCheckEdit;
29603};
29604ASPx.Ident.IsASPxClientRadioButton = function(obj) {
29605 return !!obj.isASPxClientRadioButton;
29606};
29607ASPx.Ident.IsASPxClientCheckBox = function(obj) {
29608 return ASPx.Ident.IsASPxClientCheckEdit(obj) && !ASPx.Ident.IsASPxClientRadioButton(obj);
29609};
29610ASPx.ChkOnClick = function(name) {
29611 var edit = ASPx.GetControlCollection().Get(name);
29612 if(edit) {
29613  if(edit.isNative && edit.GetReadOnly())
29614   return false;
29615  edit.OnClick();
29616 }
29617};
29618ASPx.ERBOnReadonlyClick = function(name) {
29619 var rb = ASPx.GetControlCollection().Get(name);
29620 if(rb)
29621  rb.OnReadonlyClick();
29622};
29623window.ASPxClientCheckBox = ASPxClientCheckBox;
29624window.ASPxClientRadioButton = ASPxClientRadioButton;
29625})();
29626
29627(function(dx) {
29628 var BootstrapClientCheckBox = ASPx.CreateClass(ASPxClientEdit, {
29629  constructor: function(name) {
29630   this.constructor.prototype.constructor.call(this, name);
29631   this.isASPxClientCheckEdit = true;
29632   this.valueChecked = true;
29633   this.valueUnchecked = false;
29634   this.valueGrayed = null;
29635   this.allowGrayed = false;
29636   this.allowGrayedByClick = true;
29637   this.internalCheckBox = null;
29638   this.sizingConfig.allowSetWidth = false;
29639   this.sizingConfig.allowSetHeight = false;
29640   this.CheckedChanged = new ASPxClientEvent();
29641   this.feedbackRenderHelper = new ASPx.BootstrapEditFeedbackRenderHelper(this);
29642  },
29643  InlineInitialize: function() {
29644   this.CreateInternalCheckBox();
29645   this.GetInputElement().id = this.GetMainElement().id + "_I";
29646   this.internalCheckBox.initializeSiblingLabelElement();
29647   this.RequireStyleDecoration();
29648   ASPxClientEdit.prototype.InlineInitialize.call(this);
29649   if(ASPx.Browser.TouchUI && !this.GetIsValid())
29650    this.UpdateErrorText();
29651  },
29652  InitializeEvents: function() {
29653   ASPxClientEdit.prototype.InitializeEvents.call(this);
29654   var errorImage = this.GetErrorImage();
29655   if(errorImage) {
29656    ASPx.Evt.AttachEventToElement(errorImage, "click", ASPx.Evt.PreventEventAndBubble);
29657    if(ASPx.Browser.MacOSMobilePlatform)
29658     ASPx.Evt.AttachEventToElement(errorImage, "touchstart", function() { });
29659   }
29660  },
29661  Initialize: function() {
29662   ASPxClientEdit.prototype.Initialize.call(this);
29663   this.previousValue = this.internalCheckBox.GetValue();
29664  },
29665  GetInputElement: function() {
29666   return this.internalCheckBox.mainInput;
29667  },
29668  GetControlCell: function() {
29669   return this.GetMainElement();
29670  },
29671  EnsureControlCellStylesLoaded: function() { },
29672  ClearControlCellStyles: function() { },
29673  RestoreControlCellStyles: function() { },
29674  GetElementRequiredForErrorFrame: function() {
29675   return this.GetMainElement();
29676  },
29677  GetErrorImage: function() {
29678   var mainElement = this.GetMainElement();
29679   return mainElement && mainElement.querySelector("[data-error-image]");
29680  },
29681  UpdateErrorText: function() {
29682   this.feedbackRenderHelper.updateErrorText();
29683  },
29684  ChangeErrorCellVisibility: function(visible, useVisibilityAttribute) {
29685   this.feedbackRenderHelper.setErrorControlVisible(visible);
29686  },
29687  CreateInternalCheckBox: function() {
29688   this.internalCheckBox = new ASPx.BootstrapCheckBoxInternal(this.GetMainElement(), this.allowGrayed, this.allowGrayedByClick, true, this.uniqueID);
29689   this.internalCheckBox.SetEnabled(this.GetEnabled());
29690   this.internalCheckBox.GetReadOnly = this.GetReadOnly.bind(this);
29691   this.internalCheckBox.CheckedChanged.AddHandler(function(s, e) { this.OnCheckedChanged(e); }.bind(this));
29692   this.internalCheckBox.Focus.AddHandler(function() { this.OnFocus(); }.bind(this));
29693   this.internalCheckBox.LostFocus.AddHandler(function() { this.OnLostFocus(); }.bind(this));
29694   if(this.indeterminate) {
29695    this.internalCheckBox.SetValue(null);
29696    delete this.indeterminate;
29697   }
29698  },
29699  FindInputElement: function() {
29700   return this.GetInputElement();
29701  },
29702  GetFocusableInputElement: function() {
29703   return this.GetInputElement();
29704  },
29705  PopulateStyleDecorationPostfixes: function() {
29706   this.styleDecoration.AddPostfix("");
29707   if(ASPx.BootstrapCore.IsBootstrap4) {
29708    var checkInputSelector = "." + ASPx.BootstrapCssSelectors.CheckBoxInput + ",." + ASPx.BootstrapCssSelectors.CustomCheckInput;
29709    this.styleDecoration.AddPostfix(checkInputSelector);
29710   }
29711  },
29712  CreateStyleDecoration: function () {
29713   return new ASPx.BootstrapEditorStyleDecoration(this);
29714  },
29715  RaiseValueChangedEvent: function() {
29716   var processOnServer = ASPxClientEdit.prototype.RaiseValueChangedEvent.call(this);
29717   processOnServer = this.RaiseCheckedChanged(processOnServer);
29718   return processOnServer;
29719  },
29720  OnCheckedChanged: function() {
29721   this.OnValueChanged();
29722  },
29723  GetValue: function() {
29724   var value = this.internalCheckBox.GetValue();
29725   if(value === true)
29726    return this.valueChecked;
29727   if(value === false)
29728    return this.valueUnchecked;
29729   if(value === null)
29730    return this.valueGrayed;
29731  },
29732  SetValue: function(value) {
29733   this.previousValue = value;
29734   value = this.GetCorrectValue(value);
29735   this.internalCheckBox.SetValue(value);
29736   this.OnValueSet();
29737  },
29738  GetLabelElement: function() {
29739   return ASPx.GetNodeByTagName(this.GetMainElement(), "LABEL", 0);
29740  },
29741  GetStateInput: function() {
29742   return this.internalCheckBox.stateInput;
29743  },
29744  GetAccessibilityActiveElements: function() {
29745   return [this.GetFocusableInputElement()];
29746  },
29747  GetCorrectValue: function(value) {
29748   if(value === this.valueGrayed)
29749    return null;
29750   if(value === this.valueUnchecked)
29751    return false;
29752   if(value === this.valueChecked)
29753    return true;
29754   return this.allowGrayed ? null : false;
29755  },
29756  OnValueSet: function() { },
29757  RaiseCheckedChanged: function(processOnServer) {
29758   if(!this.CheckedChanged.IsEmpty()) {
29759    var args = new ASPxClientProcessingModeEventArgs(processOnServer);
29760    this.CheckedChanged.FireEvent(this, args);
29761    processOnServer = args.processOnServer;
29762   }
29763   return processOnServer;
29764  },
29765  SetEnabled: function(enabled) {
29766   ASPxClientEdit.prototype.SetEnabled.call(this, enabled);
29767   this.internalCheckBox.SetEnabled(enabled);
29768  },
29769  GetChecked: function() {
29770   return this.internalCheckBox.GetChecked();
29771  },
29772  SetChecked: function(isChecked) {
29773   return this.internalCheckBox.SetChecked(!!isChecked);
29774  },
29775  GetText: function() {
29776   var labelElement = this.GetLabelElement();
29777   return (labelElement != null) ? ASPx.GetInnerText(labelElement) : "";
29778  },
29779  GetCheckState: function() {
29780   var value = this.GetValue();
29781   if(value === true)
29782    return ASPx.CheckBoxCheckState.Checked;
29783   if(value === false)
29784    return ASPx.CheckBoxCheckState.Unchecked;
29785   if(value === null)
29786    return ASPx.CheckBoxCheckState.Indeterminate;
29787  },
29788  SetCheckState: function(checkState) {
29789   if(checkState === ASPx.CheckBoxCheckState.Checked)
29790    this.internalCheckBox.SetValue(true);
29791   else if(checkState === ASPx.CheckBoxCheckState.Unchecked)
29792    this.internalCheckBox.SetValue(false);
29793   else if(this.allowGrayed)
29794    this.internalCheckBox.SetValue(null);
29795  },
29796  SetText: function(text) {
29797   var labelElement = this.GetLabelElement();
29798   if(labelElement != null) {
29799    var textNode = ASPx.GetTextNode(labelElement);
29800    if(textNode)
29801     textNode.nodeValue = text;
29802    else {
29803     textNode = document.createTextNode(text);
29804     if(ASPx.BootstrapCore.IsBootstrap3)
29805      labelElement.appendChild(textNode);
29806     else {
29807      var textContainer = document.createElement("SPAN");
29808      textContainer.appendChild(textNode);
29809      labelElement.appendChild(textContainer);
29810     }
29811    }
29812   }
29813  },
29814  ChangeEnabledAttributes: function(enabled) {
29815   this.internalCheckBox.SetEnabled(enabled);
29816  },
29817  ToogleCheckState: function() {
29818   if (!this.GetEnabled() || this.GetReadOnly())
29819    return false;
29820   if (this.internalCheckBox.correctNextValue())
29821    this.internalCheckBox.updateState();
29822   else
29823    this.SetChecked(!this.GetChecked());
29824   this.OnValueChanged();
29825   return true;
29826  }
29827 });
29828 var BootstrapClientRadioButton = ASPx.CreateClass(BootstrapClientCheckBox, {
29829  constructor: function(name) {
29830   this.constructor.prototype.constructor.call(this, name);
29831   this.isASPxClientRadioButton = true;
29832   this.groupName = "";
29833  },
29834  OnCheckedChanged: function() {
29835   if(!this.previousValue)
29836    this.UncheckOtherGroupMembers();
29837   BootstrapClientCheckBox.prototype.OnCheckedChanged.call(this);
29838  },
29839  OnValueSet: function() {
29840   if(this.previousValue === true)
29841    this.UncheckOtherGroupMembers(true);
29842  },
29843  UncheckOtherGroupMembers: function(suppressEvents) {
29844   var members = this.GetGroupMembers();
29845   for(var i = 0; i < members.length; i++) {
29846    var radioButton = members[i];
29847    if(!ASPx.IsExistsElement(radioButton.GetMainElement()))
29848     members[i] = null;
29849    else {
29850     if(radioButton != this && radioButton.GetValue()) {
29851      radioButton.SetValue(false);
29852      if(!suppressEvents)
29853       radioButton.RaiseValueChangedEvent();
29854     }
29855    }
29856   }
29857  },
29858  GetGroupName: function() {
29859   return this.groupName;
29860  },
29861  GetGroupMembers: function() {
29862   var result = [];
29863   var groupName = this.GetGroupName();
29864   if(groupName.length > 0) {
29865    ASPx.GetControlCollection().ForEachControl(function(control) {
29866     if(ASPx.Ident.IsASPxClientRadioButton(control)) {
29867      var controlGroupName = control.GetGroupName();
29868      if(controlGroupName != null && controlGroupName == groupName)
29869       result.push(control);
29870     }
29871    });
29872   } else {
29873    result.push(this);
29874   }
29875   return result;
29876  }
29877 });
29878 dx.BootstrapClientCheckBox = BootstrapClientCheckBox;
29879 dx.BootstrapClientRadioButton = BootstrapClientRadioButton;
29880})(dx || (dx = {}));
29881(function() {
29882var DateFormatter = ASPx.CreateClass(null, {
29883 constructor: function() {
29884  this.date = new Date(2000, 0, 1);
29885  this.mask = "";
29886  this.specifiers = {};     
29887  this.spPositions = [];    
29888  this.parserKeys = [];
29889  this.knownSpecifiers = ["d", "M", "y", "H", "h", "m", "s", "f", "F", "g", "t"];
29890  this.savedYear = -1;
29891  this.isYearParsed = false;
29892  this.parsedMonth = -1;
29893  this.replacers = {
29894   "d": this.ReplaceDay,
29895   "M": this.ReplaceMonth,
29896   "y": this.ReplaceYear,
29897   "H": this.ReplaceHours23,
29898   "h": this.ReplaceHours12,
29899   "m": this.ReplaceMinutes,
29900   "s": this.ReplaceSeconds,
29901   "F": this.ReplaceMsTrimmed,
29902   "f": this.ReplaceMs,
29903   "g": this.ReplaceEra,
29904   "t": this.ReplaceAmPm
29905  };
29906  this.parsers = {
29907   "d": this.ParseDay,
29908   "M": this.ParseMonth,
29909   "y": this.ParseYear,
29910   "H": this.ParseHours,
29911   "h": this.ParseHours,
29912   "m": this.ParseMinutes,
29913   "s": this.ParseSeconds,
29914   "F": this.ParseMs,
29915   "f": this.ParseMs,
29916   "g": this.ParseEra,
29917   "t": this.ParseAmPm
29918  };
29919 },
29920 Format: function(date) {
29921  this.date = date;
29922  var sp;
29923  var pos;
29924  var replacerKey;
29925  var result = this.mask;
29926  for(var i = 0; i < this.spPositions.length; i++) {
29927   pos = this.spPositions[i];
29928   sp = this.specifiers[pos];
29929   replacerKey = sp.substr(0, 1);
29930   if(this.replacers[replacerKey]) {
29931    result = result.substr(0, pos) + this.replacers[replacerKey].call(this, sp.length) + result.substr(pos + sp.length);
29932   }
29933  }
29934  return result;
29935 }, 
29936 Parse: function(str, rememberParserKeys, spPositionsParam, specifiersParam) {
29937  var spPositions = !!spPositionsParam ? spPositionsParam : this.spPositions;
29938  var specifiers = !!specifiersParam ? specifiersParam : this.specifiers;
29939  var now = new Date();  
29940  this.savedYear = now.getFullYear();
29941  this.isYearParsed = false;
29942  this.parsedMonth = -1;
29943  this.date = new Date(2000, 0, now.getDate());    
29944  this.strToParse = str;
29945  this.catchNumbers(str, specifiers);
29946  var parserKey;
29947  var sp;
29948  var pos;
29949  var parseResult;
29950  var error = false;
29951  this.hasAmPm = false;
29952  for(var i = 0; i < spPositions.length; i++) {
29953   pos = spPositions[i];
29954   sp = specifiers[pos];
29955   parserKey = sp.substr(0, 1);
29956   if(this.parsers[parserKey]) {
29957    if(rememberParserKeys)
29958     this.parserKeys.push(parserKey);
29959    parseResult = this.parsers[parserKey].call(this, sp.length);
29960    if(!parseResult) {
29961     error = true;
29962     break;
29963    }
29964   }
29965  }
29966  if(error)
29967   return false;
29968  if(this.hasAmPm) {
29969   if(!this.fixHours())
29970    return false;
29971  }
29972  if(!this.isYearParsed)
29973   this.date.setYear(this.savedYear);
29974  if(this.parsedMonth < 0)
29975   this.parsedMonth = now.getMonth();   
29976  this.ApplyMonth();
29977  return this.date;  
29978 },
29979 ParseAndMergeWithDate: function(str, sourceDate) {
29980  this.parserKeys = [];
29981  var date = this.Parse(str, true);
29982  if(date && sourceDate)
29983   date = new Date(
29984        this.HasYear() ? date.getFullYear() : sourceDate.getFullYear(),
29985        this.HasMonth() ? date.getMonth() : sourceDate.getMonth(),
29986        this.HasDay() ? date.getDate() : sourceDate.getDate(),
29987        this.HasHours() ? date.getHours() : sourceDate.getHours(),
29988        this.HasMinutes() ? date.getMinutes() : sourceDate.getMinutes(),
29989        this.HasSeconds() ? date.getSeconds() : sourceDate.getSeconds(),
29990        this.HasMilliseconds() ? date.getMilliseconds() : sourceDate.getMilliseconds()
29991        );
29992  this.parserKeys = [];
29993  return date;
29994 },
29995 HasYear: function() { return this.HasParserKey("y"); },
29996 HasMonth: function() { return this.HasParserKey("M"); },
29997 HasDay: function() { return this.HasParserKey("d"); },
29998 HasHours: function() { return this.HasParserKey("h") || this.HasParserKey("H"); },
29999 HasMinutes: function() { return this.HasParserKey("m"); },
30000 HasSeconds: function() { return this.HasParserKey("s"); },
30001 HasMilliseconds: function() { return this.HasParserKey("f") || this.HasParserKey("F"); },
30002 HasParserKey: function(key) { return ASPx.Data.ArrayIndexOf(this.parserKeys, key) !== -1; },
30003 ApplyMonth: function() {
30004  var trial;
30005  var day = this.date.getDate();
30006  while(true) {
30007   trial = new Date();
30008   trial.setTime(this.date.getTime());   
30009   trial.setMonth(this.parsedMonth);
30010   if(trial.getMonth() == this.parsedMonth)
30011    break;
30012   --day;
30013   this.date.setDate(day);
30014  }
30015  ASPx.DateUtils.FixTimezoneGap(this.date, trial);
30016  this.date = trial;
30017 },
30018 SetFormatString: function(mask) {
30019  var format = this.GetFormat(mask);
30020  this.specifiers = format.specifiers;
30021  this.spPositions = format.spPositions;
30022  this.mask = format.mask;
30023 },
30024 GetFormat: function(maskParam) {
30025  if(maskParam.length == 2 && maskParam.charAt(0) == "%")
30026   maskParam = maskParam.charAt(1);
30027  var stringContainsDateSeparator = maskParam && maskParam.indexOf(ASPx.CultureInfo.ds) !== -1;
30028  var subt = 0;
30029  var pos = 0;
30030  var startPos = 0;
30031  var ch;
30032  var prevCh = "";
30033  var skip = false;
30034  var backslash = false;
30035  var sp = "";
30036  var specifiers = {};
30037  var spPositions = [];
30038  var mask = "";
30039  while(true) {
30040   ch = maskParam.charAt(pos);
30041   if(ch == "") {
30042    if(sp.length > 0) {
30043     var specifier = this.GetSpecifier(startPos, sp, stringContainsDateSeparator, mask);
30044     spPositions.push(specifier.pos);
30045     specifiers[specifier.pos] = specifier.sp;
30046    }
30047    break;
30048   }
30049   if(ch == "\\" && !backslash) {
30050    backslash = true;
30051    subt++;
30052   } else {
30053    if(!backslash && (ch == "'" || ch == '"')) {
30054     skip = !skip;
30055     subt++;
30056    } else {     
30057     if(!skip) {
30058      if(ch == "/")
30059       ch = ASPx.CultureInfo.ds;
30060      else if(ch == ":")
30061       ch = ASPx.CultureInfo.ts;
30062      else if(this.IsKnownSpecifier(ch)) {
30063       if(prevCh.length == 0)
30064        prevCh = ch;
30065       if(ch == prevCh)
30066        sp += ch;
30067       else {
30068        if(sp.length > 0) {
30069         var specifier = this.GetSpecifier(startPos, sp, stringContainsDateSeparator, mask);
30070         spPositions.push(specifier.pos);
30071         specifiers[specifier.pos] = specifier.sp;
30072        }
30073        sp = ch;
30074        startPos = pos - subt;
30075       }
30076      }
30077     }     
30078     mask += ch;
30079    }      
30080    backslash = false;
30081   }            
30082   prevCh = ch;
30083   pos++;
30084  }
30085  spPositions.reverse();
30086  return { specifiers: specifiers, spPositions: spPositions, mask: mask };
30087 },
30088 GetSpecifier: function (pos, sp, stringContainsDateSeparator, mask) {
30089  if(ASPx.CultureInfo.ds.length > 1 && mask && !stringContainsDateSeparator) {
30090   var dateParts = mask.split(ASPx.CultureInfo.ds);
30091   if(dateParts) {
30092    if(dateParts.length > 0 && dateParts[dateParts.length - 1] == "")
30093     dateParts.pop();
30094    pos += (dateParts.length - 1) * (ASPx.CultureInfo.ds.length - 1);
30095   }
30096  }
30097  return { pos: pos, sp: sp };
30098 },
30099 ReplaceDay: function(length) {
30100  if(length < 3) {
30101   var value = this.date.getDate().toString();
30102   return length == 2 ? this.padLeft(value, 2) : value;  
30103  } else if(length == 3) {
30104   return ASPx.CultureInfo.abbrDayNames[this.date.getDay()];
30105  } else {
30106   return ASPx.CultureInfo.dayNames[this.date.getDay()];
30107  }
30108 }, 
30109 ReplaceMonth: function(length) {
30110  var value = 1 + this.date.getMonth();
30111  switch(length) {
30112   case 1:
30113    return value.toString();
30114   case 2:
30115    return this.padLeft(value.toString(), 2);
30116   case 3:
30117    return ASPx.CultureInfo.abbrMonthNames[value - 1];
30118   default:
30119    for(var i in this.specifiers) {
30120     if(this.specifiers.hasOwnProperty(i)) {
30121      var spec = this.specifiers[i];
30122      if(spec == "d" || spec == "dd")
30123       return ASPx.CultureInfo.genMonthNames[value - 1];
30124     }
30125    }
30126    return ASPx.CultureInfo.monthNames[value - 1];
30127  }
30128 },
30129 ReplaceYear: function(length) {
30130  var value = this.date.getFullYear();
30131  if(length <= 2)
30132   value = value % 100;
30133  return this.padLeft(value.toString(), length);
30134 },
30135 ReplaceHours23: function(length) {
30136  var value = this.date.getHours().toString();
30137  return length > 1 ? this.padLeft(value, 2) : value;
30138 },
30139 ReplaceHours12: function(length) {
30140  var value = this.date.getHours() % 12;
30141  if(value == 0)
30142   value = 12;
30143  value = value.toString();
30144  return length > 1 ? this.padLeft(value, 2) : value;
30145 },
30146 ReplaceMinutes: function(length) {
30147  var value = this.date.getMinutes().toString();
30148  return length > 1 ? this.padLeft(value, 2) : value;
30149 },
30150 ReplaceSeconds: function(length) {
30151  var value = this.date.getSeconds().toString();
30152  return length > 1 ? this.padLeft(value, 2) : value;
30153 },
30154 ReplaceMsTrimmed: function(length) {   
30155  return this.formatMs(length, true);
30156 },
30157 ReplaceMs: function(length) { 
30158  return this.formatMs(length, false);
30159 },
30160 ReplaceEra: function(length) {
30161  return "A.D.";
30162 },
30163 ReplaceAmPm: function(length) {
30164  var value = this.date.getHours() < 12 ? ASPx.CultureInfo.am : ASPx.CultureInfo.pm;
30165  return length < 2 ? value.charAt(0) : value;
30166 },
30167 catchNumbers: function(str, specifiers) {
30168  this.parseNumbers = [];  
30169  var regex = /\d+/g;  
30170  var match;
30171  for(;;) {
30172   match = regex.exec(str);
30173   if(!match)
30174    break;
30175   this.parseNumbers.push(this.parseDecInt(match[0]));
30176  }  
30177  var spCount = 0;
30178  var now = new Date();
30179  for(var i in specifiers) {
30180   if(specifiers.hasOwnProperty(i)) {
30181    var sp = specifiers[i];
30182    if (sp.constructor != String || !this.IsNumericSpecifier(sp)) continue;
30183    spCount++;
30184    if(this.parseNumbers.length < spCount) {
30185     var defaultValue = 0;
30186     if (sp.charAt(0) == "y") defaultValue = now.getFullYear();
30187     this.parseNumbers.push(defaultValue);
30188    }
30189   }
30190  }
30191  var excess = this.parseNumbers.length - spCount;
30192  if(excess > 0)
30193   this.parseNumbers.splice(spCount, excess);  
30194  this.currentParseNumber = this.parseNumbers.length - 1;
30195 },
30196 popParseNumber: function() {
30197  return this.parseNumbers[this.currentParseNumber--];
30198 },
30199 findAbbrMonth: function() {
30200  return this.findMonthCore(ASPx.CultureInfo.abbrMonthNames);
30201 },
30202 findFullMonth: function() {
30203  return this.findMonthCore(ASPx.CultureInfo.genMonthNames);
30204 },
30205 findMonthCore: function(monthNames) {
30206  var inputLower = this.strToParse.toLowerCase();
30207  var matchMonthNames = monthNames.filter(function(n) { return inputLower.indexOf(n.toLowerCase()) > -1; });
30208  if(matchMonthNames.length == 0)
30209   return false;
30210  var sortedMatchNames = matchMonthNames.sort(function(a, b) { return b.length - a.length; });
30211  var name = sortedMatchNames[0];
30212  var emptyMonth = new Array(name.length + 1).join(" ");
30213  this.strToParse = this.strToParse.replace(new RegExp(name, "gi"), emptyMonth);
30214  return monthNames.indexOf(name) + 1;
30215 },
30216 ParseDay: function(length) {
30217  if(length < 3) {
30218   var value = this.popParseNumber();
30219   if(value < 1 || value > 31)
30220    return false;
30221   this.date.setDate(value);
30222  }
30223  return true;
30224 },
30225 ParseMonth: function(length) {
30226  var value;
30227  var actualMonthTextContainsDigitOnly = this.actualDayMonthTextContainsDigitOnly("M", length);
30228  if(length < 3 || actualMonthTextContainsDigitOnly)
30229   value = this.popParseNumber();
30230  else
30231   value = length === 3 ? this.findAbbrMonth() : this.findFullMonth();
30232  if(value < 1 || value > 12)
30233   return false;
30234  this.parsedMonth = value - 1;
30235  if(this.actualDayMonthTextContainsAnyDigit("M", length) && !actualMonthTextContainsDigitOnly && length > 2)
30236   this.currentParseNumber--;
30237  return true;
30238 }, 
30239 ParseYear: function(length) {  
30240  var value = this.popParseNumber();
30241  if(value > 9999)
30242   return false;
30243  if(value < 100)
30244   value = ASPx.DateUtils.ExpandTwoDigitYear(value);
30245  this.date.setFullYear(value);
30246  this.isYearParsed = true;
30247  return true;
30248 },
30249 ParseHours: function(length) {
30250  var value = this.popParseNumber();
30251  if(value > 23)
30252   return false;
30253  this.date.setHours(value);
30254  return true;
30255 },
30256 ParseMinutes: function(length) {
30257  var value = this.parseMinSecCore();
30258  if(value == -1)
30259   return false;
30260  this.date.setMinutes(value);
30261  return true;
30262 },
30263 ParseSeconds: function(length) {
30264  var value = this.parseMinSecCore();
30265  if(value == -1)
30266   return false;
30267  this.date.setSeconds(value);
30268  return true;
30269 },
30270 ParseMs: function(length) {
30271  if(length > 3)
30272   length = 3;
30273  var thr = 1;
30274  for(var i = 0; i < length; i++)
30275   thr *= 10;
30276  thr -= 1;
30277  var value = this.popParseNumber();
30278  while(value > thr)
30279   value /= 10;
30280  this.date.setMilliseconds(Math.round(value));
30281  return true;
30282 },
30283 ParseEra: function(length) {
30284  return true;
30285 },
30286 ParseAmPm: function(length) {
30287  this.hasAmPm = ASPx.CultureInfo.is12HoursCulture;
30288  return true;
30289 },
30290 parseDecInt: function(str) {
30291  return parseInt(str, 10);
30292 },
30293 padLeft: function(str, length) {
30294  while(str.length < length)
30295   str = "0" + str;
30296  return str;
30297 },
30298 formatMs: function(length, trim) {
30299  var value = Math.floor(this.date.getMilliseconds() * Math.pow(10, length - 3));
30300  value = this.padLeft(value.toString(), length);    
30301  if(trim) {
30302   var pos = value.length - 1;
30303   var req = false;
30304   while(value.charAt(pos) == "0") {
30305    req = true;
30306    pos--;
30307   }
30308   if(req)
30309    value = value.substring(0, pos + 1);   
30310  }
30311  return value;
30312 },
30313 parseMinSecCore: function() {
30314  var value = this.popParseNumber();
30315  return value > 59 ? -1 : value;
30316 },
30317 fixHours: function() {
30318  var state = this.getAmPmState(this.strToParse);
30319  if(!state) return true;
30320  var h = this.date.getHours();
30321  switch(state) {
30322   case "P":
30323    if(h > 12) return false;
30324    if(h < 12)
30325     this.date.setHours(12 + h);
30326    break;
30327   case "A":
30328    if(h == 12)
30329     this.date.setHours(0);
30330  }
30331  return true;
30332 },
30333 getAmPmState: function(str, skipCorrection) {
30334  var am = ASPx.CultureInfo.am.charAt(0).toLowerCase();
30335  var pm = ASPx.CultureInfo.pm.charAt(0).toLowerCase();
30336  var amMatches = new RegExp(am, "gi").exec(str);
30337  var pmMatches = new RegExp(pm, "gi").exec(str);
30338  var amCount = amMatches ? amMatches.length : 0;
30339  var pmCount = pmMatches ? pmMatches.length : 0;
30340  var hasAm = amCount > 0;
30341  var hasPm = pmCount > 0;
30342  if(hasAm ^ hasPm && amCount < 2 && pmCount < 2)
30343   return hasAm ? "A" : "P";
30344  if(!skipCorrection) {
30345   str = str.replace(new RegExp(this.getDayMonthNameReplacePattern(), "gi"), "");
30346   return this.getAmPmState(str, true);
30347  }
30348  return null;
30349 },
30350 getDayMonthNameReplacePattern: function() {
30351  if(!this.dayMonthNameReplacePattern)
30352   return this.createDayMonthNameReplacePattern();
30353  return this.dayMonthNameReplacePattern;
30354 },
30355 createDayMonthNameReplacePattern: function() {
30356  var parts = [ ] ;
30357  parts.push("(?:");
30358  parts.push(this.createReplacePattern(ASPx.CultureInfo.monthNames));
30359  parts.push(this.createReplacePattern(ASPx.CultureInfo.genMonthNames));
30360  parts.push(this.createReplacePattern(ASPx.CultureInfo.abbrMonthNames));
30361  parts.push(this.createReplacePattern(ASPx.CultureInfo.abbrDayNames));
30362  parts.push(this.createReplacePattern(ASPx.CultureInfo.dayNames));
30363  parts.push(")");
30364  return parts.join("");
30365 },
30366 createReplacePattern: function(names) {
30367  return names && names.length > 0 ? "\\b" + names.join("\\b|\\b") + "\\b" : "";
30368 },
30369 IsNumericSpecifier: function(sp) {
30370  var ch = sp.charAt(0);
30371  if(ch == "g" || ch == "t" || ((ch == "M" || ch == "d") && !this.actualDayMonthTextContainsAnyDigit(ch, sp.length)))
30372   return false;
30373  return true;
30374 },
30375 actualDayMonthTextContainsAnyDigit: function(datePart, datePartLength) {
30376  return this.actualDayMonthTextContainsDigitCore(datePart, datePartLength, function(name) { return /\d+/g.test(name); });
30377 },
30378 actualDayMonthTextContainsDigitOnly: function(datePart, datePartLength) {
30379  return this.actualDayMonthTextContainsDigitCore(datePart, datePartLength, function(name) { return !isNaN(parseInt(name)); });
30380 },
30381 actualDayMonthTextContainsDigitCore: function(datePart, datePartLength, matchDigitFunc) {
30382  if(datePartLength < 3)
30383   return true;
30384  var targetNames = this.getDayMonthNames(datePart, datePartLength);
30385  return targetNames.length > 0 ? matchDigitFunc(targetNames[0]) : false;
30386 },
30387 getDayMonthNames: function(datePart, datePartLength) {
30388  var result = [];
30389  var useAbbrNames = datePartLength == 3;
30390  if(datePart == "d")
30391   result = useAbbrNames ? ASPx.CultureInfo.abbrDayNames : ASPx.CultureInfo.dayNames;
30392  else
30393   result = useAbbrNames ? ASPx.CultureInfo.abbrMonthNames : ASPx.CultureInfo.monthNames;
30394  return result;
30395 },
30396 IsKnownSpecifier: function(sp) {
30397  if(sp.length > 1)
30398   sp = sp.charAt(0);
30399  for(var i = 0; i < this.knownSpecifiers.length; i++) {
30400   if(this.knownSpecifiers[i] == sp)
30401    return true;
30402  }
30403  return false;
30404 }
30405});
30406DateFormatter.Create = function(format) {
30407 var instance = new DateFormatter();
30408 instance.SetFormatString(format);
30409 return instance;
30410};
30411DateFormatter.ExpandPredefinedFormat = function(format) {
30412 switch(format) {
30413  case "d":
30414   return ASPx.CultureInfo.shortDate;
30415  case "D":
30416   return ASPx.CultureInfo.longDate;
30417  case "t":
30418   return ASPx.CultureInfo.shortTime;
30419  case "T":
30420   return ASPx.CultureInfo.longTime;
30421  case "g":
30422   return ASPx.CultureInfo.shortDate + " " + ASPx.CultureInfo.shortTime;   
30423  case "f":
30424   return ASPx.CultureInfo.longDate + " " + ASPx.CultureInfo.shortTime;
30425  case "G":
30426   return ASPx.CultureInfo.shortDate + " " + ASPx.CultureInfo.longTime;
30427  case "F":
30428  case "U":
30429   return ASPx.CultureInfo.longDate + " " + ASPx.CultureInfo.longTime;   
30430  case "M":
30431  case "m":
30432   return ASPx.CultureInfo.monthDay;
30433  case "Y":
30434  case "y":
30435   return ASPx.CultureInfo.yearMonth;   
30436  case "O":
30437  case "o":
30438   return "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffff";
30439  case "R":
30440  case "r":
30441   return "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
30442  case "s":
30443   return "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
30444  case "u":
30445    return "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
30446 }
30447 return format;
30448};
30449ASPx.DateFormatter = DateFormatter;
30450})();
30451
30452(function() {
30453ASPx.Formatter = {
30454 Format: function() {
30455  if(arguments.length < 1) 
30456   return "";
30457  var format = arguments[0];
30458  if(format == null)
30459   return "";
30460  var args;
30461  if(arguments.length > 1 && arguments[1] != null && arguments[1].constructor == Array) {
30462   args = arguments[1];
30463  } else {
30464   args = [ ];
30465   for(var i = 1; i < arguments.length; i++)
30466    args.push(arguments[i]);
30467  }
30468  var bag = [ ];
30469  var pos = 0;
30470  var savedPos = 0;  
30471  while(pos < format.length) {
30472   var ch = format.charAt(pos);
30473   pos++;
30474   if(ch == '{') {
30475    bag.push(format.substr(savedPos, pos - savedPos - 1));    
30476    if(format.charAt(pos) == "{") {
30477     savedPos = pos;
30478     pos++;
30479     continue;
30480    }
30481    var spec = this.ParseSpec(format, pos);
30482    var pos = spec.pos;
30483    var arg = args[spec.index];
30484    var argString;
30485    if(arg == null) {
30486     argString = "";
30487    } else if(typeof arg == "number") {
30488     argString = ASPx.NumberFormatter.Format(spec.format, arg);
30489    } else if(arg.constructor == Date) {     
30490     if(spec.format != this.activeDateFormat) {
30491      this.activeDateFormat = spec.format;
30492      if(spec.format == "")
30493       spec.format = "G";      
30494      if(spec.format.length == 1)
30495       spec.format = ASPx.DateFormatter.ExpandPredefinedFormat(spec.format);
30496      this.GetDateFormatter().SetFormatString(spec.format);
30497     }
30498     if(this.activeDateFormat == "U")
30499      arg = ASPx.DateUtils.ToUtcTime(arg);
30500     argString = this.GetDateFormatter().Format(arg);
30501    } else {
30502     argString = String(arg);     
30503     if(spec.format != "" && argString.length > 0) {
30504      var num = Number(argString.replace(",", "."));
30505      if(!isNaN(num))
30506       argString = ASPx.NumberFormatter.Format(spec.format, num);
30507     }
30508    }
30509    var padLen = spec.width - argString.length;
30510    if(padLen > 0) {
30511     if(spec.left)
30512      bag.push(argString);
30513     for(var i = 0; i < padLen; i++)
30514      bag.push(" ");
30515     if(!spec.left)
30516      bag.push(argString);
30517    } else {
30518     bag.push(argString);
30519    }
30520    savedPos = pos;
30521   }
30522   else if(ch == "}" && pos < format.length && format.charAt(pos) == "}") {
30523    bag.push(format.substr(savedPos, pos - savedPos - 1));
30524    savedPos = pos;
30525    pos++;
30526   }
30527   else if (ch == "}") {
30528    return "";
30529   }
30530  }
30531  if(savedPos < format.length)
30532   bag.push(format.substr(savedPos));   
30533  return bag.join("");
30534 },
30535 ParseSpec: function(format, pos) {
30536  var result = {
30537   index: -1,   
30538   left: false,
30539   width: 0,
30540   format: "",
30541   pos: 0
30542  };
30543  var savedPos, ch;
30544  savedPos = pos;
30545  while(true) {   
30546   ch = format.charAt(pos);
30547   if(ch < "0" || ch > "9")
30548    break;
30549   pos++;
30550  }  
30551  if(pos > savedPos)
30552   result.index = Number(format.substr(savedPos, pos - savedPos));  
30553  if(format.charAt(pos) == ",") {
30554   pos++;
30555   while(true) {
30556    ch = format.charAt(pos);
30557    if(ch != " " && ch != "\t")
30558     break;
30559    pos++;
30560   }
30561   result.left = format.charAt(pos) == "-";
30562   if(result.left)
30563    pos++;   
30564   savedPos = pos;
30565   while(true) {
30566    ch = format.charAt(pos);
30567    if(ch < "0" || ch > "9")
30568     break;
30569    pos++;
30570   }
30571   if(pos > savedPos)
30572    result.width = Number(format.substr(savedPos, pos - savedPos));
30573  }
30574  if(format.charAt(pos) == ":") {
30575   pos++;
30576   savedPos = pos;
30577   while(format.charAt(pos) != "}")
30578    pos++;
30579   result.format = format.substr(savedPos, pos - savedPos);
30580  }
30581  pos++;
30582  result.pos = pos;
30583  return result;
30584 },
30585 activeDateFormat: null,
30586 GetDateFormatter: function() {
30587  if(!this.__dateFormatter)
30588   this.__dateFormatter = new ASPx.DateFormatter();
30589  return this.__dateFormatter;
30590 }
30591};
30592ASPx.NumberFormatter = {
30593 Format: function(format, value) {
30594  if(isNaN(value))
30595   return ASPx.CultureInfo.numNan;
30596  if(!isFinite(value)) {
30597   return value > 0 
30598    ? ASPx.CultureInfo.numPosInf 
30599    : ASPx.CultureInfo.numNegInf;
30600  }
30601  this.FillFormatInfo(format);
30602  if(this.spec == "X")
30603   return this.FormatHex(value);
30604  this.FillDigitInfo(value);  
30605  switch(this.spec) {
30606   case "C":
30607    return this.FormatCurrency();
30608   case "D":
30609    return this.FormatDecimal();
30610   case "E":
30611    return this.FormatExp();
30612   case "F":
30613    return this.FormatFixed();
30614   case "G":   
30615    return this.FormatGeneral();
30616   case "N":
30617    return this.FormatNumber();
30618   case "P":
30619    return this.FormatPercent();
30620   default:
30621    if(this.custom)
30622     return this.FormatCustom(format);
30623    return "?";
30624  }
30625 },
30626 positive: true,
30627 digits: null,
30628 pointPos: 0, 
30629 spec: "",
30630 prec: -1,  
30631 upper: true,
30632 custom: false,
30633 FormatCurrency: function() {  
30634  if(this.prec < 0)
30635   this.prec = ASPx.CultureInfo.currPrec;
30636  this.Round(this.prec);
30637  var bag = [ ];
30638  if(this.positive) {
30639   switch(ASPx.CultureInfo.currPosPattern) {
30640    case 0:
30641     bag.push(ASPx.CultureInfo.currency);
30642     break;
30643    case 2:
30644     bag.push(ASPx.CultureInfo.currency, " ");     
30645     break;     
30646   }
30647  } else {
30648   switch(ASPx.CultureInfo.currNegPattern) {
30649    case 0:
30650     bag.push("(", ASPx.CultureInfo.currency);
30651     break;
30652    case 1:
30653     bag.push("-", ASPx.CultureInfo.currency);
30654     break;
30655    case 2:
30656     bag.push(ASPx.CultureInfo.currency, "-");
30657     break;
30658    case 3:
30659     bag.push(ASPx.CultureInfo.currency);
30660     break;
30661    case 4:
30662     bag.push("(");
30663     break;
30664    case 5:
30665    case 8:
30666     bag.push("-");
30667     break;
30668    case 9:
30669     bag.push("-", ASPx.CultureInfo.currency, " ");
30670     break;
30671    case 11:
30672     bag.push(ASPx.CultureInfo.currency, " ");
30673     break;
30674    case 12:
30675     bag.push(ASPx.CultureInfo.currency, " -");
30676     break;
30677    case 14:
30678     bag.push("(", ASPx.CultureInfo.currency, " ");
30679     break;
30680    case 15:
30681     bag.push("(");
30682     break;
30683   }
30684  }
30685  this.AppendGroupedInteger(bag, ASPx.CultureInfo.currGroups, ASPx.CultureInfo.currGroupSeparator);
30686  if(this.prec > 0) {
30687   bag.push(ASPx.CultureInfo.currDecimalPoint);
30688   this.AppendDigits(bag, this.pointPos, this.pointPos + this.prec);
30689  }
30690  if(this.positive) {
30691   switch(ASPx.CultureInfo.currPosPattern) {
30692    case 1:
30693     bag.push(ASPx.CultureInfo.currency);
30694     break;
30695    case 3:
30696     bag.push(" ", ASPx.CultureInfo.currency);
30697     break;     
30698   }   
30699  } else {
30700   switch(ASPx.CultureInfo.currNegPattern) {
30701    case 0:
30702    case 14:
30703     bag.push(")");
30704     break;
30705    case 3:
30706     bag.push("-");
30707     break;
30708    case 4:
30709     bag.push(ASPx.CultureInfo.currency, ")");
30710     break;
30711    case 5:
30712     bag.push(ASPx.CultureInfo.currency);
30713     break;
30714    case 6:
30715     bag.push("-", ASPx.CultureInfo.currency);
30716     break;
30717    case 7:
30718     bag.push(ASPx.CultureInfo.currency, "-");
30719     break;
30720    case 8:
30721     bag.push(" ", ASPx.CultureInfo.currency);
30722     break;
30723    case 10:
30724     bag.push(" ", ASPx.CultureInfo.currency, "-");
30725     break;
30726    case 11:
30727     bag.push("-");
30728     break;
30729    case 13:
30730     bag.push("- ", ASPx.CultureInfo.currency);
30731     break;
30732    case 15:
30733     bag.push(" ", ASPx.CultureInfo.currency, ")");
30734     break;
30735   }
30736  }
30737  return bag.join("");
30738 }, 
30739 FormatDecimal: function() {
30740  if(this.prec < this.pointPos)
30741   this.prec = this.pointPos;
30742  if(this.prec < 1)
30743   return "0";
30744  var bag = [ ];
30745  if(!this.positive)
30746   bag.push("-");
30747  this.AppendDigits(bag, this.pointPos - this.prec, this.pointPos);
30748  return bag.join("");
30749 },
30750 FormatExp: function() {  
30751  if(this.prec < 0)
30752   this.prec = 6;
30753  this.Round(1 - this.pointPos + this.prec);
30754  return this.FormatExpCore(3);
30755 },
30756 FormatExpCore: function(minExpDigits) {
30757  var bag = [ ];
30758  if(!this.positive)
30759   bag.push("-");
30760  this.AppendDigits(bag, 0, 1);
30761  if(this.prec > 0) {
30762   bag.push(ASPx.CultureInfo.numDecimalPoint);
30763   this.AppendDigits(bag, 1, 1 + this.prec);
30764  }
30765  bag.push(this.upper ? "E" : "e");
30766  var order = this.pointPos - 1;  
30767  if(order >= 0) {
30768   bag.push("+");
30769  } else {
30770   bag.push("-");
30771   order = -order;
30772  }
30773  var orderStr = String(order);
30774  for(var i = orderStr.length; i < minExpDigits; i++)
30775   bag.push(0);
30776  bag.push(orderStr);
30777  return bag.join("");
30778 },
30779 FormatFixed: function() {
30780  if(this.prec < 0)
30781   this.prec = ASPx.CultureInfo.numPrec;
30782  this.Round(this.prec);
30783  var bag = [ ];
30784  if(!this.positive)
30785   bag.push("-");
30786  if(this.pointPos < 1)
30787   bag.push(0);
30788  else
30789   this.AppendDigits(bag, 0, this.pointPos);
30790  if(this.prec > 0) {
30791   bag.push(ASPx.CultureInfo.numDecimalPoint);
30792   this.AppendDigits(bag, this.pointPos, this.pointPos + this.prec);
30793  }
30794  return bag.join(""); 
30795 },
30796 FormatGeneral: function() {
30797  var hasFrac = this.pointPos < this.digits.length;
30798  var allowExp;
30799  if(this.prec < 0) {
30800   allowExp = hasFrac;
30801   this.prec = hasFrac ? 15 : 10;
30802  } else {   
30803   allowExp = true;
30804   if(this.prec < 1)
30805    this.prec = hasFrac ? 15 : 10;
30806   this.Round(this.prec - this.pointPos);
30807  }
30808  if(allowExp) {
30809   if(this.pointPos > this.prec || this.pointPos <= -4) {
30810    this.prec = this.digits.length - 1;
30811    return this.FormatExpCore(2);
30812   }
30813  }
30814  this.prec = Math.min(this.prec, Math.max(1, this.digits.length)) - this.pointPos;
30815  return this.FormatFixed();
30816 },
30817 FormatNumber: function() {
30818  if(this.prec < 0)
30819   this.prec = ASPx.CultureInfo.numPrec;
30820  this.Round(this.prec);
30821  var bag = [ ];
30822  if(!this.positive) {
30823   switch(ASPx.CultureInfo.numNegPattern) {
30824    case 0:
30825     bag.push("(");
30826     break;
30827    case 1:
30828     bag.push("-");
30829     break;
30830    case 2:
30831     bag.push("- ");
30832     break;
30833   }
30834  }
30835  this.AppendGroupedInteger(bag, ASPx.CultureInfo.numGroups, ASPx.CultureInfo.numGroupSeparator);
30836  if(this.prec > 0) {
30837   bag.push(ASPx.CultureInfo.numDecimalPoint);
30838   this.AppendDigits(bag, this.pointPos, this.pointPos + this.prec);
30839  }
30840  if(!this.positive) {
30841   switch(ASPx.CultureInfo.numNegPattern) {
30842    case 0:
30843     bag.push(")");
30844     break;
30845    case 3:
30846     bag.push("-");
30847     break;
30848    case 4:
30849     bag.push(" -");
30850     break;
30851   }
30852  }
30853  return bag.join("");
30854 },
30855 FormatPercent: function() {
30856  if(this.prec < 0)
30857   this.prec = ASPx.CultureInfo.numPrec;
30858  if(this.digits.length > 0)
30859   this.pointPos += 2;
30860  this.Round(this.prec);
30861  var bag = [ ];
30862  if(!this.positive)
30863   bag.push("-");
30864  if(ASPx.CultureInfo.percentPattern == 2)
30865   bag.push("%");    
30866  this.AppendGroupedInteger(bag, ASPx.CultureInfo.numGroups, ASPx.CultureInfo.numGroupSeparator);
30867  if(this.prec > 0) {
30868   bag.push(ASPx.CultureInfo.numDecimalPoint);
30869   this.AppendDigits(bag, this.pointPos, this.pointPos + this.prec);
30870  }  
30871  switch(ASPx.CultureInfo.percentPattern) {
30872   case 0:
30873    bag.push(" %");
30874    break;
30875   case 1:
30876    bag.push("%");
30877    break;
30878  }  
30879  return bag.join("");
30880 },
30881 FormatHex: function(value) {
30882  var result = value.toString(16);
30883  if(result.indexOf("(") > -1)
30884   return result;
30885  result = this.upper ? result.toUpperCase() : result.toLowerCase();
30886  if(this.prec <= result.length)
30887   return result;
30888  var bag = [ ];
30889  for(var i = result.length; i < this.prec; i++)
30890   bag.push(0);
30891  bag.push(result);
30892  return bag.join("");
30893 },
30894 FormatCustom: function(format) {
30895  var sectionList = this.GetCustomFormatSections(format);
30896  var section = this.SelectCustomFormatSection(sectionList);
30897  if(section == "")
30898   return this.positive ? "" : "-";
30899  var info = this.ParseCustomFormatSection(section);
30900  var lists = this.CreateCustomFormatLists(info);
30901  if(sectionList.length > 2 && section != sectionList[2]) {
30902   var zero = lists.i.concat(lists.f).join("").split(0).join("") == "";
30903   if(zero) {
30904    section = sectionList[2];
30905    info = this.ParseCustomFormatSection(section);
30906    lists = this.CreateCustomFormatLists(info);   
30907   }   
30908  }
30909  return this.FormatCustomCore(section, info, lists);
30910 },
30911 GetCustomFormatSections: function(format) {
30912  var sections = [ ];
30913  var escaping = false;
30914  var quote = "";
30915  var length = 0;
30916  var prevPos = 0;
30917  for(var i = 0; i < format.length; i++) {
30918   var ch = format.charAt(i);
30919   if(!escaping && quote == "" && ch == ";") {
30920    sections.push(format.substr(prevPos, length));
30921    length = 0;
30922    prevPos = i + 1;
30923    if(sections.length > 2)
30924     break;
30925   } else {
30926    if(escaping)
30927     escaping = false;
30928    else if(ch == quote)
30929     quote = quote == "" ? ch : "";
30930    else if(ch == "\\")
30931     escaping = true;
30932    else if(ch == "'" || ch == '"')
30933     quote = ch;
30934    ++length;
30935   }
30936  }
30937  if(length > 0)
30938   sections.push(format.substr(prevPos, length));
30939  if(sections.length < 1)
30940   sections.push(format);
30941  return sections;
30942 },
30943 SelectCustomFormatSection: function(sections) {
30944  if(!this.positive && sections.length > 1 && sections[1] != "") {
30945   this.positive = true;
30946   return sections[1];
30947  }
30948  if(this.digits.length < 1 && sections.length > 2 && sections[2] != "")
30949   return sections[2];
30950  return sections[0];
30951 },
30952 CreateCustomFormatInfo: function() {
30953  return {
30954   pointPos: -1,
30955   grouping: false,
30956   exp: false,
30957   expShowPlus: false,
30958   percent: false,
30959   scaling: 0,
30960   intDigits: 0,
30961   fracDigits: 0,
30962   expDigits: 0,
30963   intSharps: 0,
30964   fracSharps: 0, 
30965   expSharps: 0
30966  };
30967 },
30968 ParseCustomFormatSection: function(section) {  
30969  var quote = "";
30970  var area = "i"; 
30971  var canParseIntSharps = true;
30972  var result = this.CreateCustomFormatInfo();
30973  var groupSeparators = 0;  
30974  for(var i = 0; i < section.length; i++) {
30975   var ch = section.charAt(i);   
30976   if(ch == quote) {
30977    quote = "";    
30978    continue;
30979   }
30980   if(quote != "")
30981    continue;
30982   if(area == "e" && ch != "0" && ch != "#") {
30983    area = result.pointPos < 0 ? "i" : "f";
30984    i--;
30985    continue;
30986   }
30987   switch(ch) {
30988    case "\\":
30989     i++;
30990     continue;
30991    case "'":
30992    case '"':
30993     quote = ch;
30994     continue;
30995    case "#":
30996    case "0":
30997     if(ch == "#") {
30998      switch(area) {
30999       case "i":
31000        if(canParseIntSharps)
31001         result.intSharps++;
31002        break;
31003       case "f":
31004        result.fracSharps++;
31005        break;
31006       case "e":
31007        result.expSharps++;
31008        break;
31009      }
31010     } else {
31011      canParseIntSharps = false;
31012      switch(area) {
31013       case "f":
31014        result.fracSharps = 0;        
31015        break;
31016       case "e":
31017        result.expSharps = 0;
31018        break;
31019      }
31020     }
31021     switch(area) {
31022      case "i":
31023       result.intDigits++;
31024       if(groupSeparators > 0)
31025        result.grouping = true;
31026       groupSeparators = 0;
31027       break;
31028      case "f":
31029       result.fracDigits++;  
31030       break;
31031      case "e":
31032       result.expDigits++;
31033       break;
31034     }
31035     break;
31036    case "e":
31037    case "E":
31038     if(result.exp)
31039      break;
31040     result.exp = true;     
31041     area = "e"; 
31042     if(i < section.length - 1) {
31043      var next = section.charAt(1 + i);
31044      if(next == "+" || next == "-") {
31045       if(next == "+")
31046        result.expShowPlus = true;
31047       i++;
31048      }
31049      else if(next != "0" && next != "#") {
31050       result.exp = false;
31051       if(result.pointPos < 0)
31052        area = "i";       
31053      }
31054     }
31055     break;
31056    case ".":
31057     area = "f";
31058     if(result.pointPos < 0)
31059      result.pointPos = i;
31060     break;
31061    case "%":
31062     result.percent = true;     
31063     break;
31064    case ",":
31065     if(area == "i" && result.intDigits > 0)
31066      groupSeparators++;
31067     break;
31068    default:
31069     break;
31070   }
31071  }
31072  if(result.expDigits < 1)
31073   result.exp = false;
31074  else
31075   result.intSharps = 0;
31076  if(result.fracDigits < 1)
31077   result.pointPos = -1;
31078  result.scaling = 3 * groupSeparators;  
31079  return result;
31080 },
31081 CreateCustomFormatLists: function(info) {
31082  var intList = [ ];
31083  var fracList = [ ];
31084  var expList = [ ];
31085  if(this.digits.length > 0) {
31086   if(info.percent)
31087    this.pointPos += 2;
31088   this.pointPos -= info.scaling;
31089  }
31090  var expPositive = true;
31091  if(info.exp && (info.intDigits > 0 || info.fracDigits > 0)) {
31092   var diff = 0;
31093   if(this.digits.length > 0) {
31094    this.Round(info.intDigits + info.fracDigits - this.pointPos);
31095    diff -= this.pointPos - info.intDigits;
31096    this.pointPos = info.intDigits;
31097   }
31098   expPositive = diff <= 0;   
31099   expList = String(diff < 0 ? -diff : diff).split("");
31100  } else {
31101   this.Round(info.fracDigits);
31102  }
31103  if(this.digits.length < 1 || this.pointPos < 1)
31104   intList = [ 0 ];
31105  else
31106   this.AppendDigits(intList, 0, this.pointPos);
31107  this.AppendDigits(fracList, this.pointPos, this.digits.length);
31108  if(info.exp) {
31109   while(intList.length < info.intDigits)
31110    intList.unshift(0);
31111   while(expList.length < info.expDigits - info.expSharps)
31112    expList.unshift(0);
31113   if(expPositive && info.expShowPlus)
31114    expList.unshift("+");
31115   else if(!expPositive)
31116    expList.unshift("-");
31117  } else {
31118   while(intList.length < info.intDigits - info.intSharps)
31119    intList.unshift(0);    
31120   if(info.intSharps >= info.intDigits) {
31121    var zero = true;
31122    for(var i = 0; i < intList.length; i++) {
31123     if(intList[i] != 0) {
31124      zero = false;
31125      break;
31126     }
31127    }
31128    if(zero)
31129     intList = [ ];
31130   }
31131  }
31132  while(fracList.length < info.fracDigits - info.fracSharps)
31133   fracList.push(0);
31134  return {
31135   i: intList,
31136   f: fracList,
31137   e: expList
31138  };
31139 },
31140 FormatCustomCore: function(section, info, lists) {
31141  var intLen = 0; 
31142  var total = 0;
31143  var groupIndex = 0; 
31144  var counter = 0;
31145  var groupSize = 0;
31146  if(info.grouping && ASPx.CultureInfo.numGroups.length > 0) {
31147   intLen = lists.i.length;
31148   for(var i = 0; i < ASPx.CultureInfo.numGroups.length; i++) {
31149    if(total + ASPx.CultureInfo.numGroups[i] <= intLen) {
31150     total += ASPx.CultureInfo.numGroups[i];
31151     groupIndex = i;
31152    }
31153   }
31154   groupSize = ASPx.CultureInfo.numGroups[groupIndex];
31155   var fraction = intLen > total ? intLen - total : 0;
31156   if(groupSize == 0) {
31157    while(groupIndex >= 0 && ASPx.CultureInfo.numGroups[groupIndex] == 0)
31158     groupIndex--;
31159    groupSize = fraction > 0 ? fraction : ASPx.CultureInfo.numGroups[groupIndex];
31160   }
31161   if(fraction == 0) {
31162    counter = groupSize;
31163   } else {
31164    groupIndex += Math.floor(fraction / groupSize);
31165    counter = fraction % groupSize;
31166    if(counter == 0)
31167     counter = groupSize;
31168    else
31169     groupIndex++;
31170   }
31171  } else {
31172   info.grouping = false;
31173  }
31174  var bag = [ ];
31175  var area = "i";
31176  var intSharps = 0;
31177  var intListIndex = 0;
31178  var fracListIndex = 0;
31179  var savedCh = "";
31180  for(var i = 0; i < section.length; i++) {
31181   var ch = section.charAt(i);
31182   if(ch == savedCh) {
31183    savedCh = "";
31184    continue;
31185   }
31186   if(savedCh != "") {
31187    bag.push(ch);
31188    continue;
31189   }
31190   switch(ch) {
31191    case "\\":
31192     ++i;
31193     if(i < section.length)
31194      bag.push(section.charAt(i));
31195     continue;
31196    case "'":
31197    case '"':     
31198     savedCh = ch;
31199     continue;
31200    case "#":     
31201    case "0":
31202     if(area == "i") {
31203      intSharps++;
31204      if(ch == "0" || info.intDigits - intSharps < lists.i.length + intListIndex) {
31205       while(info.intDigits - intSharps + intListIndex < lists.i.length) {
31206        bag.push(lists.i[intListIndex]);
31207        intListIndex++;
31208        if(info.grouping && --intLen > 0 && --counter == 0) {
31209         bag.push(ASPx.CultureInfo.numGroupSeparator);
31210         if(--groupIndex < ASPx.CultureInfo.numGroups.length && groupIndex >= 0)
31211          groupSize = ASPx.CultureInfo.numGroups[groupIndex];
31212         counter = groupSize;
31213        }
31214       }
31215      }
31216     } else if(area == "f") {
31217      if(fracListIndex < lists.f.length) {
31218       bag.push(lists.f[fracListIndex]);
31219       fracListIndex++;
31220      }
31221     }
31222     break;
31223    case "e":
31224    case "E":
31225     if(lists.e == null || !info.exp) {
31226      bag.push(ch);
31227      break;
31228     }
31229     for(var q = i + 1; q < section.length; q++) {
31230      if(q == i + 1 && (section.charAt(q) == "+" || section.charAt(q) == "-"))
31231       continue;                   
31232      if(section.charAt(q) == "0" || section.charAt(q) == "#")
31233       continue;
31234      break;
31235     }
31236     i = q - 1;
31237     area = info.pointPos < 0 ? "i" : "f";
31238     bag.push(ch);
31239     bag = bag.concat(lists.e);
31240     lists.e = null;      
31241     break;
31242    case ".":
31243     if(info.pointPos == i && lists.f.length > 0)
31244      bag.push(ASPx.CultureInfo.numDecimalPoint);
31245     area = "f";
31246     break;
31247    case ",":
31248     break;
31249    default:
31250     bag.push(ch);
31251     break;
31252   }
31253  }
31254  if(!this.positive)
31255   bag.unshift("-");
31256  return bag.join("");
31257 },
31258 FillDigitInfo: function(value) {
31259  this.positive = true;
31260  if(value < 0) {
31261   value = -value;
31262   this.positive = false;   
31263  }
31264  this.digits = [ ];
31265  this.pointPos = 0;    
31266  if(value == 0 || !isFinite(value) || isNaN(value)) {
31267   this.pointPos = 1;
31268   return;
31269  }
31270  var list = String(value).split("e");
31271  var str = list[0];
31272  if(list.length > 1) {   
31273   this.pointPos = Number(list[1]);
31274  }
31275  var frac = false;
31276  var decimalCount = 0;
31277  for(var i = 0; i < str.length; i++) {
31278   var ch = str.charAt(i);
31279   if(ch == ".") {
31280    frac = true;
31281   } else {
31282    if(frac)
31283     decimalCount++;     
31284    if(ch != "0" || this.digits.length > 0)
31285     this.digits.push(Number(ch));
31286   }
31287  }
31288  this.pointPos += this.digits.length - decimalCount;
31289 },
31290 FillFormatInfo: function(format) {
31291  this.upper = true;
31292  this.custom = false;
31293  this.prec = -1;
31294  var spec;
31295  if(format == null || format.length < 1)
31296   spec = "G";
31297  else
31298   spec = format.charAt(0);
31299  if(spec >= "a" && spec <= "z") {
31300   spec = spec.toUpperCase();
31301   this.upper = false;
31302  }
31303  if(spec >= "A" && spec <= "Z") {   
31304   if(format != null && format.length > 1) {
31305    var prec = Number(format.substr(1));
31306    if(!isNaN(prec))
31307     this.prec = prec;
31308    else
31309     this.custom = true;
31310   }
31311  } else {
31312   this.custom = true;   
31313  }  
31314  this.spec = this.custom ? "0" : spec;
31315 },
31316 Round: function(shift) {
31317  var amount = this.digits.length - this.pointPos - shift;
31318  if(amount <= 0) 
31319   return;
31320  var cutPos = this.pointPos + shift;
31321  if(cutPos < 0) {
31322   this.digits = [ ];
31323   this.pointPos = 0;
31324   return;
31325  }
31326  var digit = this.digits[cutPos];
31327  if(digit > 4) { 
31328   for(var i = 0; i < amount; i++) {
31329    var index = cutPos - 1 - i;
31330    if(index < 0) {
31331     this.digits.unshift(0);
31332     this.pointPos++;
31333     cutPos++;
31334     index++;
31335    }
31336    digit = this.digits[index];    
31337    if(digit < 9) {
31338     this.digits[index] = 1 + digit;
31339     break;
31340    } else {
31341     this.digits[index] = 0;
31342     amount++;
31343    }
31344   }
31345  }
31346  for(var i = cutPos - 1; i >= 0; i--) {
31347   if(this.digits[i] > 0) break;
31348   cutPos--;
31349  }
31350  this.digits.splice(cutPos, this.digits.length - cutPos);
31351 },
31352 AppendGroupedInteger: function(list, groups, separator) { 
31353  if(this.pointPos < 1) {
31354   list.push(0);
31355   return;
31356  }
31357  var total = 0;
31358  var groupIndex = 0;
31359  for(var i = 0; i < groups.length; i++) {
31360   if(total + groups[i] <= this.pointPos) {
31361    total += groups[i];
31362    groupIndex = i;
31363   }
31364   else
31365    break;
31366  }
31367  if(groups.length > 0 && total > 0) {
31368   var counter;
31369   var groupSize = groups[groupIndex];
31370   var fraction = this.pointPos > total ? this.pointPos - total : 0;
31371   if(groupSize == 0) {
31372    while(groupIndex >= 0 && groups[groupIndex] == 0)
31373     groupIndex--;
31374    groupSize = fraction > 0 ? fraction : groups[groupIndex];
31375   }
31376   if(fraction == 0) {
31377    counter = groupSize;
31378   } else {
31379    groupIndex += Math.floor(fraction / groupSize);
31380    counter = fraction % groupSize;
31381    if(counter == 0)
31382     counter = groupSize;
31383    else
31384     groupIndex++;
31385   }
31386   var i = 0;
31387   while(true) {
31388    if(this.pointPos - i <= counter || counter == 0) {
31389     this.AppendDigits(list, i, this.pointPos);
31390     break;
31391    }
31392    this.AppendDigits(list, i, i + counter);
31393    list.push(separator);
31394    i += counter;    
31395    groupIndex--;     
31396    if(groupIndex < groups.length && groupIndex >= 0)
31397     groupSize = groups[groupIndex];
31398    counter = groupSize;
31399   }
31400  } else {
31401   this.AppendDigits(list, 0, this.pointPos);   
31402  }  
31403 },
31404 AppendDigits: function(list, start, end) {
31405  for(var i = start; i < end; i++) {
31406   if(i < 0 || i >= this.digits.length)
31407    list.push(0);
31408   else
31409    list.push(this.digits[i]);
31410  }
31411 }
31412};
31413})();
31414(function() {
31415var dropDownNameSuffix = "_DDD";
31416var itemImageCellClassName = "dxeIIC";
31417var CONSTANTS = {
31418 DROPDOWN_COMMAND_APPLY: "Apply",
31419 DROPDOWN_COMMAND_CLOSE: "Close",
31420 DROPDOWN_HELPTEXT_CLASS: "dxdd-help",
31421 DROPDOWN_CAPTION_CLASS: "dxdd-caption",
31422 DROPDOWN_HEADER_CLASS: "dxdd-header",
31423 DROPDOWN_MODALVISIBLE_CLASS: "dxdd-vmdd"
31424};
31425var DROPDOWN_ELEMENT_VISIBILITY = {
31426 Never: 0,
31427 DropDown: 1,
31428 ModalDropDown: 2,
31429 Always: 3
31430};
31431ASPx.DROPDOWN_ELEMENT_VISIBILITY = DROPDOWN_ELEMENT_VISIBILITY;
31432var ASPxClientDropDownEditBase = ASPx.CreateClass(ASPxClientButtonEditBase, {
31433 constructor: function(name) {
31434  this.constructor.prototype.constructor.call(this, name);
31435  this.DropDown = new ASPxClientEvent();
31436  this.CloseUp = new ASPxClientEvent();
31437  this.QueryCloseUp = new ASPxClientEvent();
31438  this.ddHeightCache = ASPx.InvalidDimension;
31439  this.ddWidthCache = ASPx.InvalidDimension;
31440  this.mainElementWidthCache = ASPx.InvalidDimension;
31441  this.dropDownButtonIndex = -1;
31442  this.droppedDown = false;
31443  this.ddButtonPushed = false;
31444  this.lastSuccessText = "";
31445  this.isToolbarItem = false;
31446  this.allowFocusDropDownWindow = false;
31447  this.pcIsShowingNow = false;
31448  this.needTimeoutForInputElementFocusEvent = false;
31449  this.ddButtonsVis = 0;
31450  this.ddmInput = false;
31451  this.ddDefCap = true;
31452  this.ddScrPicker = ASPx.DROPDOWN_ELEMENT_VISIBILITY.Never;
31453  this.accessibilityHelper = null;
31454  aspxGetDropDownCollection().Add(this);
31455 },
31456 InitializeEvents: function() {
31457  ASPxClientButtonEditBase.prototype.InitializeEvents.call(this);
31458  var ddTargets = this.getDropDownEventTargets();
31459  ddTargets
31460   .filter(function(trg, index, arr) { return trg && arr.indexOf(trg) === index; })
31461   .forEach(function(trg) {
31462    ASPx.Evt.AttachEventToElement(trg, "click", this.onDropDownEvent.bind(this));
31463    ASPx.Evt.AttachEventToElement(trg, ASPx.TouchUIHelper.touchMouseDownEventName, this.onDropDownEvent.bind(this));
31464  }.bind(this));
31465 },
31466 getDropDownEventTargets: function() {
31467  return [
31468   this.GetDropDownItemImageCell(),
31469   this.GetDropDownButton()
31470  ];
31471 },
31472 onDropDownEvent: function(evt) {
31473  if(evt.type === this.getDropDownEvent() && ASPx.Evt.IsLeftButtonPressed(evt) && this.GetEnabled())
31474   return this.OnDropDown(evt);
31475 },
31476 getDropDownEvent: function() {
31477  return this.isDropDownModal() || ASPx.Browser.MobileUI && !ASPx.Browser.MacOSMobilePlatform ? "click" : ASPx.TouchUIHelper.touchMouseDownEventName;
31478 },
31479 Initialize: function(){
31480  this.initializePopupControl();
31481  this.AssignClientAttributes();
31482  this.InitLastSuccessText();
31483  if(this.accessibilityCompliant && ASPx.IsExists(this.GetAccessibilityAssistantElement())) {
31484   this.GotFocus.AddHandler(function() { 
31485    this.ariaExplanatoryTextManager.SetHelperLabel(); 
31486   }.aspxBind(this));
31487  }
31488  ASPxClientButtonEditBase.prototype.Initialize.call(this);
31489 },
31490 initializePopupControl: function() {
31491  var pc = this.GetPopupControl();
31492  if(!pc) return;
31493  pc.usedInDropDown = true;
31494  pc.dropDownEditName = this.name;
31495  pc.setFocusOnCallback = false;
31496  this.initializeDropDown(pc);
31497 },
31498 initializeDropDown: function(pc) {
31499  pc = pc || this.GetPopupControl();
31500  if(!pc)
31501   return;
31502  if(this.ddmBP !== undefined) {
31503   pc.AdaptiveModeChanged.AddHandler(function() {
31504    this.onDropDownModalChanged(pc.GetAdaptiveModalMode());
31505   }.bind(this));
31506   pc.PopUp.AddHandler(function() {
31507    if(pc.GetAdaptiveModalMode())
31508     this.onDropDownModalChanged(true);
31509   }.bind(this));
31510   pc.Closing.AddHandler(function() {
31511    if(pc.GetAdaptiveModalMode())
31512     this.onDropDownModalChanged(false);
31513   }.bind(this));
31514  }
31515  this.initializeDropDownCommandButtons(pc);
31516  if(this.flSettings) {
31517   this.initializeDropDownContent(pc, this.flSettings.caption, this.flSettings.helpText);
31518   delete this.flSettings;
31519  }
31520 },
31521 initializeDropDownCommandButtons: function(pc) {
31522  this.dropDownCommandButtons = {};
31523  [CONSTANTS.DROPDOWN_COMMAND_APPLY, CONSTANTS.DROPDOWN_COMMAND_CLOSE].forEac
31523h(function(cmd) {
31524   var button = this.createDropDownCommandButtonClientInstance(pc, cmd);
31525   if(button) {
31526    button.allowFocus = false;
31527    button.useSubmitBehavior = false;
31528    button.causesValidation = false;
31529    button.accessibilityCompliant = this.accessibilityCompliant;
31530    button.Click.AddHandler(this.onDropDownCommandButtonClick.bind(this, cmd));
31531    button.InlineInitialize();
31532    this.dropDownCommandButtons[cmd] = button;
31533   }
31534  }.bind(this));
31535  this.ensureDropDownApplyCommandState();
31536 },
31537 createDropDownCommandButtonClientInstance: function(pc, cmd) {
31538  var buttonElementSelector = "." + CONSTANTS.DROPDOWN_HEADER_CLASS + " .dxbButtonSys[id*=" + cmd + "]";
31539  var popupContentContainer = pc.GetContentContainer(-1);
31540  var buttonElement = popupContentContainer ? popupContentContainer.querySelector(buttonElementSelector) : null;
31541  return buttonElement ? new ASPxClientButton(buttonElement.id) : null;  
31542 },
31543 initializeDropDownContent: function(pc, caption, helpText) {
31544  if(this.ddmBP === undefined)
31545   return;
31546  var container = pc.GetContentContainer(-1);
31547  if(helpText) {
31548   var helpTextContainer = container.querySelector(CONSTANTS.DROPDOWN_HELPTEXT_CLASS);
31549   if(!helpTextContainer) {
31550    helpTextContainer = document.createElement("div");
31551    helpTextContainer.innerHTML = this.HtmlEncode(helpText);
31552    helpTextContainer.className = CONSTANTS.DROPDOWN_HELPTEXT_CLASS + " " + CONSTANTS.DROPDOWN_MODALVISIBLE_CLASS;
31553    container.appendChild(helpTextContainer);
31554   }
31555  }
31556  if(caption && this.ddDefCap) {
31557   var captionContainer = container.querySelector("." + CONSTANTS.DROPDOWN_CAPTION_CLASS);
31558   if(!captionContainer) {
31559    captionContainer = document.createElement("div");
31560    captionContainer.className = CONSTANTS.DROPDOWN_CAPTION_CLASS + " " + CONSTANTS.DROPDOWN_MODALVISIBLE_CLASS;
31561    var headerContainer = container.querySelector("." + CONSTANTS.DROPDOWN_HEADER_CLASS);
31562    if(!headerContainer) {
31563     headerContainer = document.createElement("div");
31564     headerContainer.className = CONSTANTS.DROPDOWN_HEADER_CLASS + " " + CONSTANTS.DROPDOWN_MODALVISIBLE_CLASS;
31565     container.insertBefore(headerContainer, container.firstChild);
31566    }
31567    headerContainer.insertBefore(captionContainer, headerContainer.firstChild);
31568   }
31569   captionContainer.innerHTML = this.HtmlEncode(caption);
31570  }
31571 },
31572 InitLastSuccessText: function(){
31573  var rawText = this.GetTextInternal();
31574  this.SetLastSuccessText(rawText);
31575 },
31576 AssignClientAttributes: function(){
31577  var element = this.GetDropDownButton();
31578  if(ASPx.IsExistsElement(element))
31579   ASPx.Evt.PreventElementDragAndSelect(element, true);
31580 },
31581 SetReadOnlyInternal: function(readOnly) {
31582  ASPxClientButtonEditBase.prototype.SetReadOnlyInternal.call(this, readOnly);
31583  if(this.isDropDownModal())
31584   this.ensureDropDownModalInputVisibility();
31585  this.ensureDropDownApplyCommandState();
31586 },
31587 SetEnabled: function(enabled) {
31588  ASPxClientButtonEditBase.prototype.SetEnabled.call(this, enabled);
31589  this.ensureDropDownApplyCommandState();
31590 },
31591 GetDropDownButton: function(){
31592  return this.GetButton(this.dropDownButtonIndex);
31593 },
31594 GetButtonCollection: function(){
31595  var buttonElements = ASPxClientButtonEditBase.prototype.GetButtonCollection.call(this);
31596  var dropDownButtonElement = this.GetDropDownButton();
31597  if(ASPx.IsExists(dropDownButtonElement))
31598   buttonElements.push(dropDownButtonElement);
31599  return buttonElements;
31600 },
31601 GetPopupControl: function(){
31602  var pc = ASPx.GetControlCollection().Get(this.name + dropDownNameSuffix);
31603  if(pc && pc.GetWindowElement(-1))
31604   return pc;
31605  else
31606   return null;
31607 },
31608 GetDropDownWindow: function() {
31609  var pc = this.GetPopupControl();
31610  if(pc)
31611   return pc.GetWindowElement(-1);
31612  return null;
31613 },
31614 GetDropDownInnerControlName: function(suffix){
31615  var pc = this.GetPopupControl();
31616  if(pc)
31617   return this.GetPopupControl().name + suffix;
31618  return "";
31619 },
31620 GetDropDownItemImageCell: function() {
31621  return ASPx.GetNodesByPartialClassName(this.GetMainElement(), itemImageCellClassName)[0];
31622 },
31623 GetIsControlWidthWasChanged: function(){
31624  return this.mainElementWidthCache == ASPx.InvalidDimension || this.mainElementWidthCache != this.GetMainElement().clientWidth;
31625 },
31626 GetDropDownHeight: function(){
31627  return null;
31628 },
31629 GetDropDownWidth: function(){
31630  return null;
31631 },
31632 GetDropDownIsWindowElement: function(id, pcPostfix) {
31633  var pos = id.lastIndexOf(pcPostfix);
31634  if(pos != -1) {
31635   var name = id.substring(0, pos);
31636   var pc = ASPx.GetPopupControlCollection().Get(name);
31637   if(pc && pc.dropDownEditName)
31638    return aspxGetDropDownCollection().Get(pc.dropDownEditName);
31639  }
31640  return null;
31641 },
31642 GetDropDownParents: function() {
31643  var parents = [ ];
31644  var mainElement = this.GetMainElement();
31645  var element = mainElement.parentNode;
31646  while(element != null){
31647   if(element.tagName == "BODY")
31648    break;
31649   var dropDown = this.GetElementIsDropDownParent(element);
31650   if(dropDown != null)
31651    parents.push(dropDown);
31652   element = element.parentNode;
31653  }
31654  return parents.reverse();
31655 },
31656 GetElementIsDropDownParent: function(element) {
31657  return ASPx.Attr.IsExistsAttribute(element, "id") 
31658   ? this.GetDropDownIsWindowElement(ASPx.Attr.GetAttribute(element, "id"), ASPx.PCWIdSuffix + "-1") : null;
31659 },
31660 BeforePopupControlResizing: function() {
31661 },
31662 AfterPopupControlResizing: function() {
31663 },
31664 AfterPopupControlShown: function() {
31665 },
31666 ShowDropDownArea: function(isRaiseEvent, forceSize) {
31667  this.SetPCIsShowingNow(true);
31668  aspxGetDropDownCollection().RegisterDroppedDownControl(this, this.GetDropDownParents());
31669  if(!this.droppedDown) 
31670   this.SetLockListBoxClick();
31671  this.lockClosing = true; 
31672  var pc = this.GetPopupControl();
31673  var element = this.GetMainElement();
31674  var pcwElement = pc.GetCurrentWindowElement();
31675  pc.OnBeforeDropdownShow();
31676  if(ASPx.Browser.Chrome && pcwElement.clientHeight <= 0) 
31677   this.RestorePopupInsideNonStaticPositionedContainer();
31678  var height = forceSize ? forceSize.height : this.GetDropDownHeight();
31679  var width = forceSize ? forceSize.width : this.GetDropDownWidth();
31680  this.BeforePopupControlResizing();
31681  if(this.ddHeightCache != height || this.ddWidthCache != width || forceSize) {
31682   pc.SetSize(width, height);
31683   if(!forceSize) {
31684    this.ddHeightCache = height;
31685    this.ddWidthCache = width;
31686   }
31687  }
31688  this.AfterPopupControlResizing();
31689  if(ASPx.Browser.Chrome && pcwElement.clientHeight <= 0) 
31690   this.RestorePopupInsideNonStaticPositionedContainer();
31691  this.RaiseDropDownEventRequired = isRaiseEvent;
31692  pc.ShowAtElement(element, true);
31693  this.AfterPopupControlShown();
31694  this.droppedDown = true;
31695  this.lockClosing = false;
31696 },
31697 HideDropDownArea: function(isRaiseEvent){
31698  if(this.lockClosing || !this.droppedDown) return;
31699  if(!this.RaiseQueryCloseUp()) {
31700   return;
31701  }
31702  this.RemoveLockListBoxClick();
31703  this.DropDownButtonPop();
31704  var pc = this.GetPopupControl();
31705  if(pc){
31706   aspxGetDropDownCollection().UnregisterDroppedDownControl(this);
31707   pc.Hide();
31708   if(isRaiseEvent)
31709    this.RaiseCloseUp();
31710   this.droppedDown = false;
31711  }
31712 },
31713 RaiseLostFocus: function() {
31714  this.ensureDropDownClosedOnLostFocus();
31715  ASPxClientButtonEditBase.prototype.RaiseLostFocus.call(this);
31716 },
31717 ensureDropDownClosedOnLostFocus: function() {
31718  if(!this.isDropDownModal() && this.droppedDown)
31719   this.HideDropDownArea(true);
31720 },
31721 RestorePopupInsideNonStaticPositionedContainer: function() {
31722  var pc = this.GetPopupControl();
31723  var pcwElement = pc.GetCurrentWindowElement();
31724  var pcwParentElement = pcwElement.parentNode;
31725  var offsetParentElement = pcwElement.offsetParent;
31726  if(!offsetParentElement || offsetParentElement.tagName == "BODY") return;
31727  pcwParentElement.style.position = "relative";
31728  setTimeout(
31729   function() { 
31730    pcwParentElement.style.position = "";
31731    if(this.focused)
31732     pc.ShowAtElement(this.GetMainElement());
31733   }.aspxBind(this), 0);
31734 },
31735 SetLockListBoxClick: function() {
31736  this.lockListBoxClick = true;
31737 },
31738 RemoveLockListBoxClick: function() {
31739  delete this.lockListBoxClick;
31740 },
31741 ProcessInternalButtonClick: function(buttonIndex) {
31742  return this.dropDownButtonIndex == buttonIndex;
31743 },
31744 ToggleDropDown: function(){
31745  this.OnApplyChanges();
31746  if(this.droppedDown)
31747   this.HideDropDownArea(true);
31748  else
31749   this.ShowDropDownArea(true);  
31750 },
31751 GetTextInternal: function(){
31752  var text = ASPxClientButtonEditBase.prototype.GetValue.call(this);
31753  return text != null ? text : "";
31754 },
31755 SetTextInternal: function(text){
31756  if(!this.GetReadOnly())
31757   this.SetTextBase(text);
31758 },
31759 SetTextBase: function(text) {
31760  ASPxClientButtonEditBase.prototype.SetValue.call(this, text);
31761 },
31762 SetValue: function(value) {
31763  ASPxClientButtonEditBase.prototype.SetValue.call(this, value);
31764  this.SetLastSuccessText(this.GetTextInternal());
31765 },
31766 SetLastSuccessText: function(text){
31767  var tmpText = text;
31768  if(text == null) tmpText = "";
31769  else if(typeof(text) != "string")
31770     tmpText = text.toString();
31771  this.lastSuccessText = tmpText;
31772 },
31773 SetVisible: function(visible) {
31774  ASPxClientButtonEditBase.prototype.SetVisible.call(this, visible);
31775  if(!visible)
31776   this.HideDropDown();
31777 },
31778 RollbackTextInputValue: function () {
31779  this.SetTextBase(this.lastSuccessText);
31780 },
31781 SetPCIsShowingNow: function(value){
31782  this.pcIsShowingNow = value;
31783 },
31784 GetLastSuccesfullValue: function() {
31785  return this.lastSuccessText !== '' ? this.lastSuccessText : null;
31786 },
31787 GetAccessibilityHelper: function() {
31788  if(!this.accessibilityCompliant)
31789   return null;
31790  if(!this.accessibilityHelper)
31791   this.accessibilityHelper = this.CreateAccessibilityHelper();
31792  return this.accessibilityHelper;
31793 },
31794 CreateAccessibilityHelper: function() {
31795  return new ASPx.AccessibilityHelper(this);
31796 },
31797 CreateAriaExplanatoryTextManager: function() {
31798  if(this.accessibilityCompliant)
31799   return new DropDownAccessibilityExplanatoryTextManager(this);
31800  else 
31801   return new ASPx.DisableAccessibilityExplanatoryTextManager(this);
31802 },
31803 GetAccessibilityText: function() {
31804  var labelText = "";
31805  var helperContainer = this.GetAccessibilityAssistantElement();
31806  if(ASPx.IsExists(helperContainer))
31807   labelText = ASPx.Attr.GetAttribute(helperContainer, "aria-label");
31808  return !!labelText ? labelText : this.GetTextInternal();
31809 },
31810 GetAccessibilityActiveElements: function() {
31811  var helperContainer = this.GetAccessibilityAssistantElement();
31812  if(!this.accessibilityCompliant || !ASPx.IsExists(helperContainer))
31813   return [this.GetInputElement()];
31814  return [this.GetAccessibilityHelper().GetActiveElement(true)];
31815 },
31816 OnValueChanged: function() {
31817  this.SetLastSuccessText(this.GetTextInternal());
31818  ASPxClientEdit.prototype.OnValueChanged.call(this);
31819 },
31820 OnApplyChanges: function(){
31821 },
31822 OnCancelChanges: function(){
31823  var isCancelProcessed = (this.GetTextInternal() != this.lastSuccessText);
31824  this.SetTextInternal(this.lastSuccessText);
31825  return isCancelProcessed;
31826 },
31827 OnFocusCore: function () {
31828  if(!this.CorrectFocusWhenDisabled())
31829   this.OnFocusInternal();
31830 },
31831 OnFocusInternal: function() {
31832  this.OnSetFocus(true);
31833  ASPxClientButtonEditBase.prototype.OnFocusCore.call(this);
31834 },
31835 OnLostFocus: function(){
31836  this.OnSetFocus(false);
31837  ASPxClientButtonEditBase.prototype.OnLostFocus.call(this);
31838 },
31839 OnSetFocus: function(isFocused){
31840  aspxGetDropDownCollection().SetFocusedDropDownName(isFocused ? this.name : "");
31841 },
31842 IsEditorElement: function(element) {
31843  if(ASPxClientButtonEditBase.prototype.IsEditorElement.call(this, element))
31844   return true;
31845  if(this.allowFocusDropDownWindow)
31846   return false;
31847  var pc = this.GetPopupControl();
31848  if(pc != null) {
31849   var windowElement = pc.GetCurrentWindowElement();
31850   return windowElement == element || ASPx.GetIsParent(windowElement, element);
31851  }
31852  return false;
31853 },
31854 OnPopupControlShown: function(){
31855  this.SetPCIsShowingNow(false);
31856  if(this.RaiseDropDownEventRequired){
31857   this.RaiseDropDownEventRequired = false;
31858   window.setTimeout(function() { this.RaiseDropDown(); }.aspxBind(this), 0);
31859  }
31860 },
31861 IsCanToDropDown: function(){
31862  return true;
31863 },
31864 OnDropDown: function(evt) { 
31865  if(!this.isInitialized) 
31866   return true;
31867  if(evt.type === ASPx.TouchUIHelper.touchMouseDownEventName && ASPx.Evt.GetEventSource(evt) === this.GetInputElement())
31868   this.OnMouseDown();
31869  if(!this.IsCanToDropDown()) {
31870   this.ForceRefocusEditor(evt);
31871   return true;
31872  }
31873  if(ASPx.Browser.Opera){
31874   if(!this.droppedDown) {
31875    ASPx.Evt.EmulateOnMouseDown(this.GetMainElement(), evt);
31876    ASPx.GetStateController().ClearSavedCurrentPressedElement();
31877   }
31878  }
31879  this.OnDropDownCore(evt);
31880  if(this.needCancelBubbleDropDownEvent())
31881   return ASPx.Evt.CancelBubble(evt); 
31882  return true;
31883 },
31884 OnDropDownCore: function(evt) {
31885  if(!this.droppedDown)
31886   this.DropDownButtonPush();
31887  this.ToggleDropDown();
31888  var isNativeFocus = this.isNativeFocus(evt);
31889  if(!isNativeFocus || (!ASPx.Browser.MacOSMobilePlatform && !ASPx.Browser.AndroidMobilePlatform))
31890   this.ForceRefocusEditor(evt, isNativeFocus);
31891 },
31892 isNativeFocus: function(evt) {
31893  var inputElement = this.GetInputElement();
31894  return !!inputElement ? this.IsElementBelongToInputElement(ASPx.Evt.GetEventSource(evt)) : false;
31895 },
31896 needCancelBubbleDropDownEvent: function() {
31897  return true;
31898 },
31899 DropDownButtonPush: function(){
31900  if(this.droppedDown || this.ddButtonPushed) return;
31901  this.ddButtonPushed = true;
31902  if(ASPx.Browser.Opera)
31903   this.DropDownButtonPushPop(true);
31904  else
31905   this.DropDownButtonPushMozilla();
31906 }, 
31907 DropDownButtonPop: function(force){
31908  if((!this.droppedDown || !this.ddButtonPushed) && !force) return;
31909  this.ddButtonPushed = false;
31910  if(ASPx.Browser.Opera)
31911   this.DropDownButtonPushPop(false);
31912  else
31913   this.DropDownButtonPopMozilla();
31914 },
31915 DropDownButtonPushPop: function(isPush){
31916  var buttonElement = this.GetDropDownButton();
31917  if(buttonElement){
31918   var controller = ASPx.GetStateController();
31919   var element = controller.GetPressedElement(buttonElement);
31920   if(element){
31921    if(isPush){
31922     controller.SetCurrentHoverElement(null);
31923     controller.DoSetPressedState(element);
31924    } else {
31925     controller.DoClearPressedState(element);
31926     controller.SetCurrentPressedElement(null);
31927     controller.SetCurrentHoverElement(element);
31928    }
31929   }
31930  }
31931 },
31932 DropDownButtonPushMozilla: function(){
31933  this.DisableStyleControllerForDDButton();
31934  var controller = ASPx.GetStateController();
31935  controller.savedCurrentPressedElement = null;
31936 },
31937 DropDownButtonPopMozilla: function(){
31938  this.EnableStyleControllerForDDButton();
31939  var controller = ASPx.GetStateController();
31940  var buttonElement = this.GetDropDownButton();
31941  if(buttonElement){
31942   var element = controller.GetPressedElement(buttonElement);
31943   if(element)
31944    controller.DoClearPressedState(element);
31945   controller.currentPressedElement = null;
31946   element = controller.GetHoverElement(buttonElement);
31947   if(element)
31948    controller.SetCurrentHoverElement(element);
31949  }
31950 },
31951 EnableStyleControllerForDDButton: function(){
31952  var element = this.GetDropDownButton();
31953  if(element){
31954   var controller = ASPx.GetStateController();
31955   this.ReplaceElementControlStyleItem(controller.hoverItems, ASPx.HoverItemKind, element, this.ddButtonHoverStyle);
31956   this.ReplaceElementControlStyleItem(controller.pressedItems, ASPx.PressedItemKind, element, this.ddButtonPressedStyle);
31957   this.ReplaceElementControlStyleItem(controller.selectedItems, ASPx.SelectedItemKind, element, this.ddButtonSelectedStyle);
31958  }
31959 },
31960 DisableStyleControllerForDDButton: function(){
31961  var element = this.GetDropDownButton();
31962  if(element){
31963   var controller = ASPx.GetStateController();
31964   this.ddButtonHoverStyle = this.ReplaceElementControlStyleItem(controller.hoverItems, ASPx.HoverItemKind, element, null);
31965   this.ddButtonPressedStyle = this.ReplaceElementControlStyleItem(controller.pressedItems, ASPx.PressedItemKind, element, null);
31966   this.ddButtonSelectedStyle = this.ReplaceElementControlStyleItem(controller.selectedItems, ASPx.SelectedItemKind, element, null);
31967  }
31968 },
31969 ReplaceElementControlStyleItem: function(items, kind, element, newStyleItem){
31970  var styleItem = items[element.id];
31971  items[element.id] = newStyleItem;
31972  element[kind] = newStyleItem;
31973  return styleItem;
31974 },
31975 CloseDropDownByDocumentOrWindowEvent: function(causedByWindowResizing){
31976  if(!causedByWindowResizing || !this.pcIsShowingNow)
31977   this.HideDropDownArea(true);
31978 },
31979 OnDocumentMouseUp: function() {
31980  this.DropDownButtonPop();
31981 },
31982 OnDDButtonMouseMove: function(evt){
31983 },
31984 ShouldCloseOnMCMouseDown: function () {
31985  return true;
31986 },
31987 OnMainCellMouseDown: function (evt) {
31988  if(this.ShouldCloseOnMCMouseDown())
31989   this.OnCloseUp(evt);
31990 },
31991 OnCloseUp: function (evt) {
31992  this.HideDropDownArea(true);
31993 },
31994 OnOpenAnotherDropDown: function(){
31995  this.HideDropDownArea(true);
31996 },
31997 OnTextChanged: function() {
31998  if(!this.ChangedByEnterKeyPress())
31999   this.OnTextChangedInternal();
32000 },
32001 OnTextChangedInternal: function() {
32002  this.ParseValue();
32003 },
32004 ChangedByEnterKeyPress: function() {
32005  if(ASPx.Browser.Firefox || ASPx.Browser.WebKitFamily) 
32006   if(this.enterKeyPressed) {
32007    this.enterKeyPressed = false;
32008    return true;
32009   } 
32010  return false;
32011 },
32012 ChangeEnabledAttributes: function(enabled){
32013  ASPxClientButtonEditBase.prototype.ChangeEnabledAttributes.call(this, enabled);
32014  var btnElement = this.GetDropDownButton();
32015  if(btnElement)
32016   this.ChangeButtonEnabledAttributes(btnElement, this.GetChangeButtonEnabledAttributesMethod(enabled));
32017  var inputElement = this.GetInputElement();
32018  if(inputElement)
32019   this.ChangeInputCellEnabledAttributes(inputElement.parentNode, ASPx.Attr.ChangeAttributesMethod(enabled));
32020  var imageCell = this.GetDropDownItemImageCell();
32021  if(ASPx.IsExists(imageCell))
32022   this.ChangeImageCellEnabledAttributes(imageCell, ASPx.Attr.ChangeAttributesMethod(enabled));
32023 },
32024 ChangeEnabledStateItems: function(enabled){
32025  ASPxClientButtonEditBase.prototype.ChangeEnabledStateItems.call(this, enabled);
32026  var btnElement = this.GetDropDownButton();
32027  if(btnElement)
32028   ASPx.GetStateController().SetElementEnabled(btnElement, enabled);
32029 },
32030 ChangeInputCellEnabledAttributes: function(element, method){
32031  method(element, "onclick");
32032  method(element, "onkeyup");
32033  if(ASPx.Browser.Edge)
32034   method(element, "onmousedown");
32035  method(element, "on" + ASPx.TouchUIHelper.touchMouseDownEventName);
32036  method(element, "on" + ASPx.TouchUIHelper.touchMouseUpEventName);
32037 },
32038 ChangeImageCellEnabledAttributes: function(imageCell, method){
32039  method(imageCell, "onmousedown");
32040 },
32041 InitializeKeyHandlers: function() {
32042  this.AddKeyDownHandler(ASPx.Key.Enter, "OnEnter");
32043  this.AddKeyDownHandler(ASPx.Key.Esc, "OnEscape");
32044  this.AddKeyDownHandler(ASPx.Key.PageUp, "OnPageUp");
32045  this.AddKeyDownHandler(ASPx.Key.PageDown, "OnPageDown");
32046  this.AddKeyDownHandler(ASPx.Key.End, "OnEndKeyDown");
32047  this.AddKeyDownHandler(ASPx.Key.Home, "OnHomeKeyDown");
32048  this.AddKeyDownHandler(ASPx.Key.Left, "OnArrowLeft");
32049  this.AddKeyDownHandler(ASPx.Key.Right, "OnArrowRight");
32050  this.AddKeyDownHandler(ASPx.Key.Up, "OnArrowUp");
32051  this.AddKeyDownHandler(ASPx.Key.Down, "OnArrowDown");
32052  this.AddKeyDownHandler(ASPx.Key.Tab, "OnTab");
32053 },
32054 OnArrowUp: function(evt){
32055  if(evt.altKey) {
32056   this.ToggleDropDown();
32057   return true;
32058  }
32059  return false;
32060 },
32061 OnArrowDown: function(evt){
32062  if(evt.altKey) {
32063   this.ToggleDropDown();
32064   return true;
32065  }
32066  return false;
32067 },
32068 OnPageUp: function(evt){
32069  return false;
32070 }, 
32071 OnPageDown: function(evt){
32072  return false;
32073 },
32074 OnEndKeyDown: function(evt){
32075  return false;
32076 },
32077 OnHomeKeyDown: function(evt){
32078  return false;
32079 },
32080 OnArrowLeft: function(evt){
32081  return false;
32082 },
32083 OnArrowRight: function(evt){
32084  return false;
32085 },
32086 OnEscape: function(evt){
32087  return this.OnEscapeInternal();
32088 },
32089 OnEscapeInternal: function() {
32090  var isCancelProcessed = this.OnCancelChanges() || this.droppedDown;
32091  this.HideDropDownArea(true);
32092  return isCancelProcessed;
32093 },
32094 OnEnter: function(evt){
32095  return false;
32096 },
32097 OnTab: function(evt){
32098  return false;
32099 },
32100 isDropDownModalRequired: function() {
32101  return this.ddmBP && window.innerWidth < this.ddmBP;
32102 },
32103 isDropDownModal: function(undefinedIfPopupIsDifferent) {
32104  var result = this.isDropDownModalRequired();
32105  if(undefinedIfPopupIsDifferent) {
32106   var pc = this.GetPopupControl();
32107   if(pc && pc.GetAdaptiveModalMode(-1) != result)
32108    return undefined;
32109  }
32110  return !!result;
32111 },
32112 onDropDownModalChanged: function(enabled) {
32113  if(!this.ddmInput)
32114   return;
32115  if(enabled)
32116   this.enableDropDownModal();
32117  else
32118   this.disableDropDownModal();
32119  if(this.focusedNullTextElement)
32120   this.ensureAdjustFocusedNullTextElement();
32121 },
32122 enableDropDownModal: function() {
32123  this.loadMainElementHeight();
32124  var pc = this.GetPopupControl();
32125  var contentContainer = pc.GetContentContainer(-1);
32126  var inputContainer = contentContainer.querySelector(".dxdd-input");
32127  var inputElement = this.GetInputElement();
32128  inputContainer.appendChild(inputElement);
32129  if(this.focusedNullTextElement)
32130   inputContainer.appendChild(this.focusedNullTextElement);
32131  this.initializeDropDownModalClearButton(inputContainer);
32132  if(this.dropDownModalClearButton)
32133   this.EnsureClearButtonVisibility();
32134  this.ensureDropDownModalInputVisibility(inputContainer);
32135 },
32136 disableDropDownModal: function() {
32137  this.resetMainElementHeight();
32138  var inputElement = this.GetInputElement();
32139  this.getInputCell().appendChild(inputElement);
32140  if(this.focusedNullTextElement)
32141   this.getInputCell().appendChild(this.focusedNullTextElement);
32142 },
32143 loadMainElementHeight: function() {
32144  var mainElement = this.GetMainElement();
32145  var mainElementHeight = mainElement.style.height;
32146  if(!mainElementHeight) {
32147   var currentHeight = mainElement.getBoundingClientRect().height;
32148   mainElement.style.height = currentHeight + "px";
32149   ASPx.Attr.SetAttribute(mainElement, "data-hasAssignedHeight", true);
32150  }
32151 },
32152 resetMainElementHeight: function() {
32153  var mainElement = this.GetMainElement();
32154  var hasAssignedHeight = ASPx.Attr.GetAttribute(mainElement, "data-hasAssignedHeight");
32155  if(hasAssignedHeight) {
32156   mainElement.style.height = "";
32157   ASPx.Attr.RemoveAttribute(mainElement, "data-hasAssignedHeight");
32158  }
32159 },
32160 ensureDropDownModalInputVisibility: function(inputContainer) {
32161  if(!inputContainer && this.ddmInput) {
32162   var pc = this.GetPopupControl();
32163   inputContainer = pc && pc.GetContentContainer(-1).querySelector(".dxdd-input");
32164  }
32165  if(!inputContainer)
32166   return;
32167  ASPx.ToggleClassNameToElement(inputContainer, "dxdd-readonly", this.GetReadOnly() || !this.GetEnabled());
32168 },
32169 onDropDownCommandButtonClick: function(command) {
32170  if(command === CONSTANTS.DROPDOWN_COMMAND_APPLY)
32171   this.onDropDownApplyCommandClick();
32172  this.onDropDownCloseCommandClick();
32173 },
32174 onDropDownApplyCommandClick: function() {
32175  throw "Not Implemented";
32176 },
32177 onDropDownCloseCommandClick: function() {
32178  throw "Not Implemented";
32179 },
32180 ensureDropDownApplyCommandState: function() {
32181  if(!this.dropDownCommandButtons)
32182   return;
32183  var button = this.dropDownCommandButtons[CONSTANTS.DROPDOWN_COMMAND_APPLY];
32184  if(button)
32185   button.SetEnabled(this.isDropDownApplyCommandEnabled());
32186 },
32187 isDropDownApplyCommandEnabled: function() {
32188  return this.GetEnabled() && !this.GetReadOnly();
32189 },
32190 initializeDropDownModalClearButton: function(inputContainer) {
32191  if(this.dropDownModalClearButton === undefined) {
32192   this.dropDownModalClearButton = inputContainer.querySelector(this.getDropDownModalClearButtonSelector()) || null;
32193   if(this.dropDownModalClearButton)
32194    ASPx.Evt.AttachEventToElement(this.dropDownModalClearButton, "click", this.onClearButtonClick.bind(this));
32195  }
32196 },
32197 getDropDownModalClearButtonSelector: function() {
32198  return ".dxdd-clearbutton";
32199 },
32200 EnsureClearButtonVisibility: function() {
32201  ASPxClientButtonEditBase.prototype.EnsureClearButtonVisibility.call(this);
32202  if(this.dropDownModalClearButton && this.isDropDownModal())
32203   ASPx.SetElementDisplay(this.dropDownModalClearButton, this.RequireShowClearButton());
32204 },
32205 applyFormLayoutItemSettings: function(settings) {
32206  var pc = this.GetPopupControl();
32207  if(pc)
32208   this.initializeDropDownContent(pc, settings.caption, settings.helpText);
32209  else
32210   this.flSettings = settings;
32211 },
32212 getInputCell: function() {
32213  var cell = ASPxClientButtonEditBase.prototype.getInputCell.call(this);
32214  return ASPx.ElementHasCssClass(cell, "dxic") ? cell : this.GetMainElement().querySelector(".dxic");
32215 },
32216 RaiseCloseUp: function(){
32217  if(!this.CloseUp.IsEmpty()){
32218   var args = new ASPxClientEventArgs();
32219   this.CloseUp.FireEvent(this, args);
32220  }
32221 },
32222 RaiseDropDown: function(){
32223  if(!this.DropDown.IsEmpty() && this.isInitialized){
32224   var args = new ASPxClientEventArgs();
32225   this.DropDown.FireEvent(this, args);
32226  }
32227 },
32228 RaiseQueryCloseUp: function(){
32229  if(!this.QueryCloseUp.IsEmpty() && this.isInitialized) {
32230   var args = new ASPxClientCancelEventArgs();
32231   this.QueryCloseUp.FireEvent(this, args);
32232   return !args.cancel;
32233  }
32234  return true;
32235 },
32236 AdjustDropDownWindow: function(){
32237  var pc = this.GetPopupControl();
32238  if(pc) {
32239   pc.AdjustSize();
32240   pc.UpdatePositionAtElement(this.GetMainElement());
32241  }
32242 },
32243 ResetDropDownSizeCache: function(){
32244  this.ddHeightCache = ASPx.InvalidDimension;
32245  this.ddWidthCache = ASPx.InvalidDimension;
32246 },
32247 ShowDropDown: function(){
32248  if(!this.droppedDown)
32249   this.ShowDropDownArea(false);
32250 },
32251 HideDropDown: function(){
32252  if(this.droppedDown)
32253   this.HideDropDownArea(false);
32254 }
32255});
32256var ASPxClientDropDownEdit = ASPx.CreateClass(ASPxClientDropDownEditBase, {
32257 constructor: function(name) {
32258  this.constructor.prototype.constructor.call(this, name);
32259  this.LostFocusInternal = new ASPxClientEvent();
32260  this.dropDownWindowHeight = "";
32261  this.dropDownWindowWidth = "";
32262  this.allowFocusDropDownWindow = true;
32263  this.needAdjustControlsInDropDownWindow = true;
32264  this.DropDownCommandButtonClick = new ASPxClientEvent();
32265 },
32266 UseSpecialKeyboardHandling: function() {
32267  return true;
32268 },
32269 getDropDownEventTargets: function() {
32270  return ASPxClientDropDownEditBase.prototype.getDropDownEventTargets.call(this).concat([
32271   this.shouldDropDownOnMCMouseDown() ? this.getInputCell() : null,
32272  ]);
32273 },
32274 shouldDropDownOnMCMouseDown: function() {
32275  return this.readOnly || !this.allowUserInput;
32276 },
32277 ShouldCloseOnMCMouseDown: function() {
32278  return !this.shouldDropDownOnMCMouseDown();
32279 },
32280 InitializeEvents: function() {
32281  this.LostFocus.AddHandler(this.ProcessLostFocus.aspxBind(this));
32282  this.QueryCloseUp.AddHandler(this.ProcessQueryCloseUp.aspxBind(this));
32283  ASPxClientDropDownEditBase.prototype.InitializeEvents.call(this);
32284 },
32285 BeforePopupControlResizing: function() {
32286  var divContainer = this.GetDropDownDivContainer();
32287  if(divContainer && this.needAdjustControlsInDropDownWindow) {
32288   this.AdjustControlsInDropDownWindow();
32289   ASPx.SetElementDisplay(divContainer, false);
32290  }
32291 },
32292 AfterPopupControlResizing: function() {
32293  var divContainer = this.GetDropDownDivContainer();
32294  if(divContainer && this.needAdjustControlsInDropDownWindow) {
32295   ASPx.SetElementDisplay(divContainer, true);
32296   this.AdjustControlsInDropDownWindow();
32297   this.needAdjustControlsInDropDownWindow = false;
32298  }
32299 },
32300 AdjustControlsInDropDownWindow: function() {
32301  var pc = this.GetPopupControl();
32302  var pcwElement = pc.GetCurrentWindowElement();
32303  ASPx.GetControlCollection().ProcessControlsInContainer(pcwElement, function(control) {
32304   control.AdjustControl(false);
32305  });
32306 },
32307 GetDropDownDivContainer: function() {
32308  return ASPx.GetElementById(this.name + dropDownNameSuffix + "_DDDC");
32309 },
32310 GetDropDownHeight: function(){
32311  if(this.dropDownWindowHeight != "")
32312   return this.dropDownWindowHeight;
32313  return ASPxClientDropDownEditBase.prototype.GetDropDown
32313Height.call(this);
32314 },
32315 GetDropDownWidth: function(){
32316  if(this.dropDownWindowWidth != "")
32317   return this.dropDownWindowWidth;
32318  return this.GetMainElement().offsetWidth;
32319 },
32320 CloseDropDownByDocumentOrWindowEvent: function(causedByWindowResizing){
32321  if(!ASPx.GetPopupControlCollection().WindowResizeByBodyScrollVisibilityChangingLocked())
32322   ASPxClientDropDownEditBase.prototype.CloseDropDownByDocumentOrWindowEvent.call(this, causedByWindowResizing);
32323 },
32324 OnBrowserWindowResize: function(e){
32325  this.needAdjustControlsInDropDownWindow = true;
32326 },
32327 OnEnter: function(evt){
32328  return this.droppedDown;
32329 },
32330 OnEscape: function(evt){
32331  var isCancelProcessed = this.droppedDown;
32332  this.HideDropDownArea(true);
32333  return isCancelProcessed;
32334 },
32335 OnTextChanged: function() {
32336  this.OnValueChanged();
32337 },
32338 ProcessLostFocus: function() {
32339  if(!this.droppedDown)
32340   this.RaiseLostFocusInternal();
32341 },
32342 ProcessQueryCloseUp: function() {
32343  if(this.focused)
32344   return;
32345  var forceRefocusTimeout = 150;
32346  setTimeout(function() {
32347   if(!this.IsDropDownContainsFocus())
32348    this.RaiseLostFocusInternal();
32349  }.aspxBind(this), forceRefocusTimeout);
32350 },
32351 IsDropDownContainsFocus: function() {
32352  return ASPx.GetIsParent(this.GetDropDownWindow(), ASPx.GetActiveElement());
32353 },
32354 GetKeyValueInternal: function(){
32355  if(ASPx.IsExists(this.stateObject))
32356   return this.stateObject.keyValue;
32357  return null;
32358 },
32359 SetKeyValueInternal: function(keyValue){
32360  this.UpdateStateObjectWithObject({ keyValue: keyValue });
32361 },
32362 GetValueString: function() {
32363  var value = this.GetKeyValue();
32364  return (value === null || value === "") ? ASPxClientDropDownEditBase.prototype.GetValueString.call(this) : value.toString();
32365 },
32366 onDropDownCommandButtonClick: function(action) {
32367  this.raiseDropDownCommandButtonClick(action);
32368 },
32369 raiseDropDownCommandButtonClick: function(command) {
32370  var args = new ASPxClientDropDownCommandEventArgs(command);
32371  if(!this.DropDownCommandButtonClick.IsEmpty())
32372   this.DropDownCommandButtonClick.FireEvent(this, args);
32373  return !args.cancel;
32374 },
32375 GetKeyValue: function(){
32376  return this.GetKeyValueInternal();
32377 },
32378 SetKeyValue: function(keyValue){
32379  this.SetKeyValueInternal(keyValue);
32380 },
32381 RaiseLostFocusInternal: function() {
32382  if(!this.isInitialized)
32383   return;
32384  this.ensureDropDownClosedOnLostFocus();
32385  if(this.LostFocusInternal.IsEmpty())
32386   return;
32387  var args = new ASPxClientEventArgs();
32388  this.LostFocusInternal.FireEvent(this, args);
32389 },
32390 ensureDropDownClosedOnLostFocus: function() { }
32391});
32392ASPxClientDropDownEdit.Cast = ASPxClientControl.Cast;
32393var ASPxClientDropDownCollection = ASPx.CreateClass(ASPxClientControlCollection, {
32394 constructor: function() {
32395  this.constructor.prototype.constructor.call(this);
32396  this.droppedControlName = "";
32397  this.droppedParentNames = [ ];
32398  this.focusedControlName = "";
32399 },
32400 GetCollectionType: function(){
32401  return "DropDown";
32402 },
32403 SetFocusedDropDownName: function(name){
32404  this.focusedControlName = name;
32405 },
32406 ResetDroppedDownControl: function(){
32407  this.droppedControlName = "";
32408 },
32409 ResetDroppedDownParentCollection: function(startDroppedDownControlName) {
32410  var regArray = [ ];
32411  for(var i = 0; i < this.droppedParentNames.length; i++) {
32412   if(this.droppedParentNames[i] == startDroppedDownControlName)
32413    break;
32414   regArray.push(this.droppedParentNames[i]);
32415  }
32416  this.droppedParentNames = regArray;
32417  if(this.droppedParentNames.length > 0) {
32418   this.droppedControlName = this.droppedParentNames[this.droppedParentNames.length - 1];
32419   ASPx.Data.ArrayRemoveAt(this.droppedParentNames, this.droppedParentNames.length - 1);
32420  }
32421 },
32422 ResetFocusedControl: function(){
32423  this.focusedControlName = "";
32424 },
32425 GetFocusedDropDown: function(){
32426  var control = this.GetDropDownControlInternal(this.focusedControlName);
32427  if(control == null) this.ResetFocusedControl();
32428  return control;
32429 },
32430 GetDroppedDropDown: function(){
32431  var control = this.GetDropDownControlInternal(this.droppedControlName);
32432  if(control == null) this.ResetDroppedDownControl();
32433  return control;
32434 },
32435 GetDroppedDropDownParents: function(startDroppedDownControlName) {
32436  var dropDownArray = [ ];
32437  var isNeedGetControl = false;
32438  for(var i = 0; i < this.droppedParentNames.length; i++) {
32439   if(this.droppedParentNames[i] == startDroppedDownControlName) isNeedGetControl = true;
32440   if(isNeedGetControl) {
32441    var control = this.GetDropDownControlInternal(this.droppedParentNames[i]);
32442    if(control != null)
32443     dropDownArray.push(control);
32444   }
32445  }
32446  return dropDownArray;
32447 },
32448 FindFirstNameForClose: function(newDroppedDownParentArray) {
32449  var firstNameToClose = newDroppedDownParentArray.length > 0 ? "" : this.droppedParentNames[i];
32450  for(var i = 0; i < this.droppedParentNames.length; i++) {
32451   if(ASPx.Data.ArrayIndexOf(newDroppedDownParentArray, this.Get(this.droppedParentNames[i])) == -1) {
32452    firstNameToClose = this.droppedParentNames[i];
32453    break;
32454   }
32455  }
32456  return firstNameToClose;
32457 },
32458 GetDropDownControlInternal: function(name){
32459  var control = this.Get(name);
32460  var isControlExists = control && !control.IsDOMDisposed();
32461  if(!isControlExists)
32462   control = null;
32463  return control;
32464 },
32465 IsDroppedDropDownParentExist: function(name) {
32466  for(var i = 0; i < this.droppedParentNames.length; i++) {
32467   if(this.droppedParentNames[i] == name)
32468    return true;
32469  }
32470  return false;
32471 },
32472 OnDDButtonMouseMove: function(evt){
32473  var dropDownControl = this.GetDroppedDropDown();
32474  if(dropDownControl != null)
32475   dropDownControl.OnDDButtonMouseMove(evt);
32476 },
32477 OnDocumentMouseDown: function(evt){
32478  if(ASPxClientControl.documentDropDownMouseDownLocked) return; 
32479  if(!ASPx.TouchUIHelper.handleFastTapIfRequired(evt, function(){ this.CloseDropDownByDocumentOrWindowEvent(evt, false); }.aspxBind(this), false))
32480   this.CloseDropDownByDocumentOrWindowEvent(evt, false);
32481 },
32482 OnDocumentMouseUp: function(evt){
32483  var dropDownControl = this.GetDroppedDropDown();
32484  if(dropDownControl != null)
32485   dropDownControl.OnDocumentMouseUp();
32486 },
32487 OnBrowserWindowResize: function(e){
32488  if(typeof(ASPx.GetPopupControlCollection) != "undefined" && !ASPx.GetPopupControlCollection().WindowResizeByBodyScrollVisibilityChangingLocked()){
32489   this.CloseDropDownByDocumentOrWindowEvent(e.htmlEvent, true);
32490   this.AdjustControls();
32491  }
32492 },
32493 CloseDropDownByDocumentOrWindowEvent: function(evt, causedByWindowResizing){
32494  var dropDownControl = this.GetDroppedDropDown();
32495  if(dropDownControl != null && (this.IsEventNotFromControlSelf(evt, dropDownControl) || causedByWindowResizing))
32496   dropDownControl.CloseDropDownByDocumentOrWindowEvent(causedByWindowResizing);
32497  var childrenDropDownsToClose = this.GetDroppedDropDownParents(this.droppedParentNames[0]);
32498  if(childrenDropDownsToClose.length != 0) {
32499   childrenDropDownsToClose = childrenDropDownsToClose.reverse();
32500   this.ResetDroppedDownParentCollection(this.droppedParentNames[0]);
32501   var rollbackDroppedDownNames = [ ];
32502   for(var c = 0; c < childrenDropDownsToClose.length; c++) {
32503    if(this.IsEventNotFromControlSelf(evt, childrenDropDownsToClose[c]))
32504     childrenDropDownsToClose[c].CloseDropDownByDocumentOrWindowEvent(causedByWindowResizing);
32505    else
32506     rollbackDroppedDownNames.push(childrenDropDownsToClose[c].name);
32507   }
32508   if(rollbackDroppedDownNames != 0) {
32509    rollbackDroppedDownNames = rollbackDroppedDownNames.reverse();
32510    this.droppedParentNames = rollbackDroppedDownNames;
32511   }
32512  }
32513 },
32514 AdjustControls: function(){
32515  this.ForEachControl(function(control) {
32516   control.AdjustControl(false);
32517  });
32518 },
32519 IsEventNotFromControlSelf: function(evt, control){
32520  var srcElement = ASPx.Evt.GetEventSource(evt);
32521  var mainElement = control.GetMainElement();
32522  var dropDownWindow = control.GetDropDownWindow();
32523  if(!srcElement || !mainElement || !dropDownWindow) return true;
32524  return (!ASPx.GetIsParent(mainElement, srcElement) &&
32525   !ASPx.GetIsParent(dropDownWindow, srcElement) &&
32526   !this.IsEventFromSharedPopupOfInnerEditor(dropDownWindow, srcElement));
32527 },
32528 IsEventFromSharedPopupOfInnerEditor: function(dropDownWindow, srcElement) {
32529  var eventFromPopupOfInnerEditor = false;
32530  ASPx.GetControlCollection().ProcessControlsInContainer(dropDownWindow,
32531   function(control){
32532    if(control.calendarOwnerName) {
32533     var sharedCalendarPopup = control.GetCalendarOwner().GetDropDownWindow();
32534     if(ASPx.GetIsParent(sharedCalendarPopup, srcElement))
32535      eventFromPopupOfInnerEditor = true;
32536    }
32537  });
32538  return eventFromPopupOfInnerEditor;
32539 },
32540 RegisterDroppedDownControl: function(dropDownControl, droppedDownParentArray){
32541  var prevDropDownControl = this.GetDroppedDropDown();
32542  var areDroppedDownsCollectionParents = ASPx.Data.ArrayIndexOf(droppedDownParentArray, prevDropDownControl) != -1;
32543  if(prevDropDownControl != null && prevDropDownControl != dropDownControl && !areDroppedDownsCollectionParents)
32544   prevDropDownControl.OnOpenAnotherDropDown();
32545  if(this.droppedParentNames.length > 0) {
32546   var firstDropDownsNameToClose = this.FindFirstNameForClose(droppedDownParentArray);
32547   if(firstDropDownsNameToClose != "") {
32548    var childrenDropDownsToClose = this.GetDroppedDropDownParents(firstDropDownsNameToClose);
32549    this.ResetDroppedDownParentCollection(firstDropDownsNameToClose);
32550    this.CloseDroppedDownCollection(childrenDropDownsToClose.reverse());
32551   }
32552  }
32553  this.droppedControlName = dropDownControl.name;
32554  this.droppedParentNames = [ ];
32555  for(var i = 0; i < droppedDownParentArray.length; i++)
32556   this.droppedParentNames.push(droppedDownParentArray[i].name);
32557 },
32558 UnregisterDroppedDownControl: function(dropDownControl){
32559  if(this.droppedControlName == dropDownControl.name)
32560   this.ResetDroppedDownControl();
32561  if(this.IsDroppedDropDownParentExist(dropDownControl.name)) {
32562   var prevDropDownControl = this.GetDroppedDropDown();
32563   if(prevDropDownControl != null)
32564    prevDropDownControl.OnOpenAnotherDropDown();
32565   var childrenDropDownsToClose = this.GetDroppedDropDownParents(dropDownControl.name);
32566   this.ResetDroppedDownParentCollection(dropDownControl.name);
32567   ASPx.Data.ArrayRemoveAt(childrenDropDownsToClose, 0);
32568   this.CloseDroppedDownCollection(childrenDropDownsToClose.reverse());
32569  }
32570 },
32571 CloseDroppedDownCollection: function(dropDownParentArray) {
32572  for(var c = 0; c < dropDownParentArray.length; c++)
32573   dropDownParentArray[c].OnOpenAnotherDropDown();
32574 }
32575});
32576var DropDownAccessibilityExplanatoryTextManager = ASPx.CreateClass(ASPx.EditAccessibilityExplanatoryTextManager , {
32577 constructor: function(editor) {
32578  this.constructor.prototype.constructor.call(this, editor);
32579 },
32580 SetHelperLabel: function() {
32581  var pronounceText = this.editor.GetAccessibilityText();
32582  var labelElements = ASPx.FindAssociatedLabelElements(this.editor);
32583  if(labelElements.length > 0) {
32584   var labelText = labelElements.map(function(label) { return ASPx.GetInnerText(label); }).join(" ");
32585   if(pronounceText.indexOf(labelText) < 0)
32586    pronounceText = labelText + " " + pronounceText;
32587  }
32588  var pronounceElement = !!this.editor.accessibilityHelper ?
32589   this.editor.accessibilityHelper.GetPronounceElement() :
32590   this.editor.GetAccessibilityAssistantElement();
32591  ASPx.Attr.SetAttribute(pronounceElement, "aria-label", pronounceText);
32592  var textElement = this.GetTextElement();
32593  if(ASPx.IsExists(textElement)) {
32594   if(!ASPx.IsExists(ASPx.Attr.GetAttribute(this.editor.GetInputElement(), 'aria-activedescendant')))
32595    pronounceElement = this.editor.GetInputElement();
32596   this.SetOrRemoveText([pronounceElement], textElement, true, false, false);
32597   setTimeout(function() {
32598    this.SetOrRemoveText([pronounceElement], textElement, false, false, false);
32599   }.aspxBind(this), 500);
32600  }
32601 }
32602});
32603var ASPxClientDropDownCommandEventArgs = ASPx.CreateClass(ASPxClientCancelEventArgs, {
32604 constructor: function (command) {
32605  this.constructor.prototype.constructor.call(this);
32606  this.commandName = command;
32607 }
32608});
32609var dropDownCollection = null;
32610function aspxGetDropDownCollection() {
32611 if(dropDownCollection == null)
32612  dropDownCollection  = new ASPxClientDropDownCollection();
32613 return dropDownCollection;
32614}
32615ASPx.Ident.IsASPxClientDateEdit = function(obj) {
32616 return !!obj.isASPxClientDateEdit;
32617};
32618ASPx.DDMC_MD = function(name, evt) {
32619 var dd = ASPx.GetControlCollection().Get(name);
32620 if(dd)
32621  dd.OnMainCellMouseDown(evt);
32622};
32623ASPx.DDBPCShown = function(name){
32624 var cb = ASPx.GetControlCollection().Get(name);
32625 if(cb != null) cb.OnPopupControlShown();
32626};
32627ASPx.CBLBSelectedIndexChanged = function(name, evt){
32628 var cb = ASPx.GetControlCollection().Get(name);
32629 if(cb != null) cb.OnLBSelectedIndexChanged();
32630};
32631ASPx.CBLBItemMouseUp = function(name, evt){
32632 var cb = ASPx.GetControlCollection().Get(name);
32633 if(cb != null) cb.OnListBoxItemMouseUp(evt);
32634};
32635ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseDownEventName, function(evt) {
32636 return aspxGetDropDownCollection().OnDocumentMouseDown(evt);
32637});
32638ASPx.Evt.AttachEventToDocument(ASPx.TouchUIHelper.touchMouseUpEventName, function(evt) {
32639 return aspxGetDropDownCollection().OnDocumentMouseUp(evt);
32640});
32641window.ASPxClientDropDownEditBase = ASPxClientDropDownEditBase;
32642window.ASPxClientDropDownEdit = ASPxClientDropDownEdit;
32643ASPx.GetDropDownCollection = aspxGetDropDownCollection;
32644})();
32645
32646(function() {
32647var calendarNameSuffix = "_C";
32648var timeEditNameSiffix = calendarNameSuffix + "_TE";
32649var clockNameSiffix = calendarNameSuffix + "_CL";
32650var lbIPostfixes = ['C', 'I', 'T'];
32651var verticalTimeSectionClassName = "dxeCalendarVerticalDETS";
32652var timeSectionFooterClassName = "dxeDETSF";
32653var calendarWithFullWidthChildsClassName = "dxeCalendarFullWidth";
32654var calendarWithAutoWidthChildsClassName = "dxeCalendarCollapsed";
32655var DefaultMinMaxRangeValues = {
32656 Min: -1,
32657 Max: 0
32658};
32659var ASPxDateRangeHelper = {
32660 GetCurrentRangeRestrictions: function(dateRangePair) {
32661  if (dateRangePair.isInRangeMode)
32662  return {
32663   startDate: dateRangePair.startDateEdit.GetDate(),
32664   endDate: dateRangePair.endDateEdit.GetDate()
32665  };
32666  else
32667   return {
32668    startDate: null,
32669    endDate: null
32670   };
32671 },
32672 IsBothRangeRestrictionsExist: function (rangeRestricts) {
32673  return rangeRestricts.startDate && rangeRestricts.endDate;
32674 },
32675 IsNegativeRange: function (rangeRestricts) {
32676  return this.IsBothRangeRestrictionsExist(rangeRestricts)
32677   && rangeRestricts.startDate > rangeRestricts.endDate;
32678 },
32679 IsOneRestrictionExistsOnly: function (rangeRestricts) {
32680  return this.IsStartRestrictionExistsOnly(rangeRestricts)
32681   || this.IsEndRestrictionExistsOnly(rangeRestricts);
32682 },
32683 IsStartRestrictionExistsOnly: function (rangeRestricts) {
32684  return rangeRestricts.startDate && !rangeRestricts.endDate;
32685 },
32686 IsEndRestrictionExistsOnly: function (rangeRestricts) {
32687  return !rangeRestricts.startDate && rangeRestricts.endDate;
32688 },
32689 AreRestrictionsOfSamePeriod: function (rangeRestricts, pickerType) {
32690  return this.IsBothRangeRestrictionsExist(rangeRestricts)
32691   && ASPxClientCalendar.AreDatesOfSamePeriod(rangeRestricts.startDate, rangeRestricts.endDate, pickerType);
32692 },
32693 GetFullDaysInCurrentRange: function(rangeRestricts) {
32694  var timezoneOffsetDifference = ASPx.DateUtils.GetTimeZoneOffsetDifference(rangeRestricts.startDate, rangeRestricts.endDate);
32695  var rangeLength = rangeRestricts.endDate - rangeRestricts.startDate + timezoneOffsetDifference;
32696  return Math.floor(rangeLength / ASPx.calendarMsPerDay);
32697 },
32698 GetRangeLength: function(currentDateEdit, pickerType) {
32699  var dateRangePair = this.GetDateEditPair(currentDateEdit);
32700  if(!dateRangePair.isStart) {
32701   var rangeRestricts = this.GetCurrentRangeRestrictions(dateRangePair);
32702   if(this.IsBothRangeRestrictionsExist(rangeRestricts) && !this.IsNegativeRange(rangeRestricts))
32703    return this.GetRangeLengthCore(rangeRestricts, pickerType);
32704  }
32705  return -1;
32706 },
32707 GetRangeLengthCore: function(rangeRestricts, pickerType) {
32708  if(pickerType == ASPx.DatePickerType.Days)
32709   return this.GetFullDaysInCurrentRange(rangeRestricts);
32710  if(pickerType == ASPx.DatePickerType.Months)
32711   return ASPxClientCalendar.GetOffsetInMonths(rangeRestricts.startDate, rangeRestricts.endDate);
32712  if(pickerType == ASPx.DatePickerType.Years)
32713   return ASPxClientCalendar.GetOffsetInYears(rangeRestricts.startDate, rangeRestricts.endDate);
32714  if(pickerType == ASPx.DatePickerType.Decades)
32715   return ASPxClientCalendar.GetOffsetInDecades(rangeRestricts.startDate, rangeRestricts.endDate);
32716  return -1;
32717 },
32718 NeedCorrectSecondDateOnDateChanging: function (rangeRestricts, isStartDateChanged, minRange) {
32719  if (this.IsNegativeRange(rangeRestricts))
32720   return true;
32721  var isSecondDateEmpty = isStartDateChanged && this.IsStartRestrictionExistsOnly(rangeRestricts)
32722   || !isStartDateChanged && this.IsEndRestrictionExistsOnly(rangeRestricts);
32723  return isSecondDateEmpty && minRange > DefaultMinMaxRangeValues.Min;
32724 },
32725 GetDateEditPair: function(currentDateEdit) {
32726  if(currentDateEdit.IsInDateRangeMode()) {
32727   var startDE = currentDateEdit.GetStartDateEdit();
32728   startDE = (startDE == null) ? currentDateEdit : startDE;
32729   var endDE = startDE.endDateEdit;
32730   var isCurrentDateEditStart = currentDateEdit === startDE;
32731   return {
32732    startDateEdit: startDE,
32733    endDateEdit: endDE,
32734    isStart: isCurrentDateEditStart,
32735    isInRangeMode: true
32736   };
32737  }
32738  else
32739   return {
32740    startDateEdit: currentDateEdit,
32741    endDateEdit: null,
32742    isStart: true,
32743    isInRangeMode: false
32744   };
32745 }
32746};
32747var DateRangeValidationPattern = ASPx.CreateClass(ASPx.ValidationPattern, {
32748 constructor: function (endDateEdit) {
32749  this.constructor.prototype.constructor.call(this, endDateEdit.invalidDateRangeErrorText);
32750  this.startDateEdit = null;
32751  this.endDateEdit = endDateEdit;
32752  this.pickerType = endDateEdit.pickerType;
32753 },
32754 GetStartDateEdit: function() {
32755  if(!this.startDateEdit)
32756   this.startDateEdit = this.endDateEdit.GetStartDateEdit();
32757  return this.startDateEdit;
32758 },
32759 EvaluateIsValid: function(value) {
32760  var startDateEdit = this.GetStartDateEdit();
32761  if(!startDateEdit)
32762   return true;
32763  var dateEditPair = ASPxDateRangeHelper.GetDateEditPair(startDateEdit);
32764  var rangeRestricts = ASPxDateRangeHelper.GetCurrentRangeRestrictions(dateEditPair);
32765  if (this.endDateEdit.IsDateChangeProcessing()
32766   && ASPxDateRangeHelper.NeedCorrectSecondDateOnDateChanging(rangeRestricts, false, this.endDateEdit.minRange))
32767   return true;
32768  if (ASPxDateRangeHelper.IsOneRestrictionExistsOnly(rangeRestricts))
32769   return false;
32770  if (ASPxDateRangeHelper.IsBothRangeRestrictionsExist(rangeRestricts)) {
32771   var startDate = rangeRestricts.startDate;
32772   var endDate = rangeRestricts.endDate;
32773   return this.IsRangeFitToMinRange(startDate, endDate) && this.IsRangeFitToMaxRange(startDate, endDate);
32774  }
32775  return true;
32776 },
32777 IsRangeFitToMinRange: function(startDate, endDate) {
32778  return this.endDateEdit.minRange === DefaultMinMaxRangeValues.Min
32779   || ASPxClientCalendar.GetDateByOffset(startDate, this.endDateEdit.minRange, this.pickerType) <= endDate;
32780 },
32781 IsRangeFitToMaxRange: function(startDate, endDate) {
32782  return this.endDateEdit.maxRange === DefaultMinMaxRangeValues.Max
32783   || ASPxClientCalendar.GetDateByOffset(startDate, this.endDateEdit.maxRange, this.pickerType) >= endDate;
32784 },
32785});
32786var ASPxClientDateEdit = ASPx.CreateClass(ASPxClientDropDownEditBase, {
32787 constructor: function(name) {
32788  this.constructor.prototype.constructor.call(this, name);
32789  this.dateFormatter = null;
32790  this.isASPxClientDateEdit = true;
32791  this.date = null;
32792  this.dateOnError = "u";
32793  this.allowNull = true;
32794  this.calendarOwnerName = null;
32795  this.calendarConsumerName = null;
32796  this.textWasChangedInInput = false;
32797  this.showTimeSection = false;
32798  this.enableAdaptiveTimeSection = true;
32799  this.adjustInnerControls = true;
32800  this.pasteTimerID = -1;
32801  this.keyUpProcessing = false;
32802  this.showOutOfRangeWarning = true;
32803  this.startDateEditName = "";
32804  this.minRange = DefaultMinMaxRangeValues.Min;
32805  this.maxRange = DefaultMinMaxRangeValues.Max;
32806  this.sharedParameters = new ASPx.CalendarSharedParameters();
32807  this.endDateEdit = null;
32808  this.calendarController = null;
32809  this.rollersController = null;
32810  this.viewContainer = null;
32811  this.pickerType = ASPx.DatePickerType.Days;
32812  this.hasDecadeDisplayFormat = false;
32813  this.showHourWheel = false;
32814  this.showMinuteWheel = false;
32815  this.showSecondWheel = false;
32816  this.showMillisecondWheel = false;
32817  this.onControlsInitializedHandler = null;
32818  this.DateChanged = new ASPxClientEvent();
32819  this.ParseDate = new ASPxClientEvent();
32820  this.CalendarCustomDisabledDate = new ASPxClientEvent();
32821  this.CalendarCellClick = new ASPxClientEvent();
32822  this.CalendarShowing = new ASPxClientEvent();
32823  this.ValueSet = new ASPxClientEvent();
32824 },
32825 SetData: function(data){
32826  ASPxClientTextEdit.prototype.SetData.call(this, data);
32827  if(data.sharedParameters)
32828   this.SetProperties(data.sharedParameters, this.sharedParameters);
32829 },
32830 Initialize: function() {
32831  this.InitializeControllers();
32832  this.GetActiveController().InitializeViewHandlers();
32833  ASPxClientDropDownEditBase.prototype.Initialize.call(this);
32834  var startDateEdit = this.GetStartDateEdit();
32835  if(startDateEdit) {
32836   this.GetActiveController().PrepareToDateRangeMode(startDateEdit);
32837   this.onControlsInitializedHandler = function() { this.ensureStartDateEditInDateRangeMode(); }.bind(this);
32838   ASPx.GetControlCollection().ControlsInitialized.AddHandler(this.onControlsInitializedHandler);
32839  }
32840  this.GetActiveController().AttachToDateEditClientEvents();
32841  this.InitializeSharedParameters();
32842 },
32843 OnDispose: function() {
32844  ASPxClientDropDownEditBase.prototype.OnDispose.call(this);
32845  if(this.onControlsInitializedHandler)
32846   ASPx.GetControlCollection().ControlsInitialized.RemoveHandler(this.onControlsInitializedHandler);
32847 },
32848 ensureStartDateEditInDateRangeMode: function() {
32849  var startDateEdit = this.GetStartDateEdit();
32850  if(startDateEdit)
32851   this.GetActiveController().EnsureStartDateEditInDateRangeMode(startDateEdit);
32852 },
32853 InitializeControllers: function() {
32854  var shouldDisplayCalendarOnInit = this.ShouldDisplayCalendarOnInit();
32855  if(this.ddScrPicker !== ASPx.DROPDOWN_ELEMENT_VISIBILITY.Always) {
32856   this.calendarController = new DateEditCalendarController(this);
32857   this.calendarController.Initialize(shouldDisplayCalendarOnInit);
32858  }
32859  if(this.ddScrPicker !== ASPx.DROPDOWN_ELEMENT_VISIBILITY.Never) {
32860   this.rollersController = this.CreateScrollPickerController(this.spOptions); 
32861   this.rollersController.Initialize(!shouldDisplayCalendarOnInit);   
32862  }
32863 },
32864 InitializeCalendarController: function() {
32865  if(this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.Always)
32866   return;
32867  this.calendarController = new DateEditCalendarController(this);
32868  this.calendarController.Initialize();
32869 },
32870 ShouldDisplayCalendarOnInit: function() {
32871  return this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.Never || this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.ModalDropDown;
32872 },
32873 ShouldDisplayCalendar: function() {
32874  return this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.Never ||
32875      this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.DropDown && this.isDropDownModal() ||
32876      this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.ModalDropDown && !this.isDropDownModal();
32877 },
32878 ShouldDisplayRoller: function() {
32879  return !this.ShouldDisplayCalendar();
32880 },
32881 InitializeRollerController: function() {
32882  if(this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.Never)
32883   return;
32884  this.rollersController = this.CreateScrollPickerController(this.spOptions);
32885  this.rollersController.Initialize();
32886 },
32887 GetActiveController: function() {
32888  if(this.calendarController && this.calendarController.IsActive())
32889   return this.calendarController;
32890  return this.rollersController;
32891 },
32892 CreateScrollPickerController: function(spOptions) {
32893  return new DateEditScrollPickerController(this, spOptions);
32894 },
32895 UpdateActiveController: function() {
32896  if(!this.calendarController || !this.rollersController)
32897   return;
32898  var shouldDisplayCalendar = this.ShouldDisplayCalendar();  
32899  this.calendarController.SetActive(shouldDisplayCalendar);
32900  this.rollersController.SetActive(!shouldDisplayCalendar);
32901 },
32902 GetViewContainer: function() {
32903  var popupControl = this.GetPopupControl();
32904  if(!popupControl)
32905   return null;
32906  if(!this.viewContainer)
32907   this.viewContainer = popupControl.GetContentContainer(-1);
32908  return this.viewContainer;
32909 },
32910 IsInDateRangeMode: function() {
32911  var startDateEdit = this.GetStartDateEdit();
32912  return startDateEdit !== null || this.endDateEdit !== null;
32913 },
32914 MinOrMaxRangeExist: function() {
32915  return this.minRange !== DefaultMinMaxRangeValues.Min || this.maxRange !== DefaultMinMaxRangeValues.Max;
32916 },
32917 InitializeSharedParameters: function() {
32918  this.sharedParameters.currentDateEdit = this;
32919  this.sharedParameters.DaysSelectingOnMouseOver.AddHandler(function(s, e) {
32920   this.OnCalendarDayMouseOver(s, e);
32921  }.aspxBind(this));
32922  this.sharedParameters.VisibleDaysMouseOut.AddHandler(function(s, e) {
32923   UTILS.SelectRangeInCalendar(s, false);
32924  }.aspxBind(this));
32925  if(this.GetShowTimeSection())
32926   this.sharedParameters.CalendarSelectionChangedInternal.AddHandler(function(s, e) {
32927    UTILS.SelectRangeInCalendar(s, false);
32928   }.aspxBind(this));
32929 },
32930 OnCalendarDayMouseOver: function(targetCalendar, e) {
32931  var dateRangePair = ASPxDateRangeHelper.GetDateEditPair(ASPxClientDateEdit.active);
32932  if(!dateRangePair.isInRangeMode) {
32933   e.cancel = true;
32934   return;
32935  }
32936  var rangeRestricts = ASPxDateRangeHelper.GetCurrentRangeRestrictions(dateRangePair);
32937  var isRangeNegative = ASPxDateRangeHelper.IsNegativeRange(rangeRestricts);
32938  var isOverDateCorrectForSelection = false;
32939  if (!isRangeNegative) {
32940   var requiredStartDate = dateRangePair.isStart ? rangeRestricts.endDate : rangeRestricts.startDate;
32941   e.selectionStartDate = requiredStartDate ? ASPxClientCalendar.CloneDate(requiredStartDate) : null;
32942   isOverDateCorrectForSelection = e.selectionStartDate
32943    && (dateRangePair.isStart && e.selectionStartDate >= e.overDate
32944    || !dateRangePair.isStart && e.selectionStartDate <= e.overDate);
32945  }
32946  e.cancel = isRangeNegative || !e.selectionStartDate || !isOverDateCorrectForSelection;
32947 },   
32948 InlineInitialize: function(){
32949  ASPxClientDropDownEditBase.prototype.InlineInitialize.call(this);
32950  this.lastValue = this.GetInputElement().value;
32951  if (this.UseRestrictions() && this.showOutOfRangeWarning)
32952   this.EnsureOutOfRangeWarningManager();
32953  if(this.MinOrMaxRangeExist())
32954   this.validationPatterns.push(new DateRangeValidationPattern(this));
32955 },
32956 UseSpecialKeyboardHandling: function() {
32957  return true;
32958 },
32959 GetStartDateEdit: function() {
32960  return this.startDateEditName ? ASPx.GetControlCollection().Get(this.startDateEditName) : null;
32961 },
32962 CloseDropDownByDocumentOrWindowEvent: function(causedByWindowResizing) {
32963  var isInputTextEmpty = this.GetInputElement().value === "" || this.IsMaskInfoEmpty();
32964  var isInputTextEmptyInDateRangeMode = this.IsInDateRangeMode() && isInputTextEmpty;
32965  if((!causedByWindowResizing || !this.pcIsShowingNow) && !this.GetTextWasChangedInInput() && !isInputTextEmptyInDateRangeMode)
32966   this.ApplySelectedDate();
32967  ASPxClientDropDownEditBase.prototype.CloseDropDownByDocumentOrWindowEvent.call(this, causedByWindowResizing);
32968 },
32969 UseRestrictions: function() {
32970  return this.GetMinDate() || this.GetMaxDate();
32971 },
32972 OnDropDownCore: function(evt) {
32973  ASPxClientDropDownEditBase.prototype.OnDropDownCore.call(this, evt);
32974  this.GetActiveController().OnDropDownCore();
32975 },
32976 CreateUpdateCallback: function(result) {
32977  this.CreateCallback(this.sharedParameters.GetUpdateCallbackParameters());
32978 },
32979 OnCallback: function(result) {
32980  var calendar = this.GetCalendar();
32981  if(calendar != null)
32982   calendar.OnCallback(result);
32983 },
32984 ShowDropDownArea: function(isRaiseEvent) {
32985  this.UpdateActiveController();
32986  this.GetActiveController().OnBeforeShowDropDown(this.date);
32987  ASPxClientDropDownEditBase.prototype.ShowDropDownArea.call(this, isRaiseEvent);  
32988  this.GetActiveController().OnAfterShowDropDown();
32989 },
32990 BrowserWindowResizeSubscriber: function() {
32991  return this.droppedDown && this.IsAdaptiveTimeSectionEnabled();
32992 },
32993 OnBrowserWindowResize: function(e) {
32994  this.GetActiveController().OnBrowserWindowResize();
32995 },
32996 BeforePopupControlResizing: function() {
32997  this.adjustTimeSection();
32998 },
32999 AfterPopupControlShown: function() {
33000  if(!this.isDropDownModal())
33001   this.adjustTimeSection(true);
33002 },
33003 adjustTimeSection: function(force) {
33004  var calendarOwner = this;
33005  if(this.calendarOwnerName)
33006   calendarOwner = this.GetCalendarOwner();
33007  if((force || calendarOwner.adjustInnerControls) && calendarOwner.GetTimeEdit()){
33008   calendarOwner.GetClock().AdjustControl();
33009   calendarOwner.GetTimeEdit().AdjustControl();
33010   calendarOwner.adjustInnerControls = false;
33011  }
33012 },
33013 onDropDownModalChanged: function(enabled) {
33014  ASPxClientDropDownEditBase.prototype.onDropDownModalChanged.call(this, enabled);
33015  this.UpdateActiveController();
33016  this.GetActiveController().onDropDownModalChanged(enabled);
33017  this.adjustTimeSection(true);
33018 },
33019 onDropDownCommandButtonClick: function(command) {
33020  if(ASPxClientDateEdit.active && ASPxClientDateEdit.active !== this)
33021   ASPxClientDateEdit.active.onDropDownCommandButtonClick(command);
33022  else
33023   ASPxClientDropDownEditBase.prototype.onDropDownCommandButtonClick.call(this, command);
33024 },
33025 GetPopupControl: function() { 
33026  var calendarOwner = this.GetCalendarOwner();
33027  if(calendarOwner != null)
33028   return calendarOwner.GetPopupControl();
33029  return ASPxClientDropDownEditBase.prototype.GetPopupControl.call(this);
33030 },
33031 OnPopupControlShown: function() {
33032  if(this.calendarConsumerName != null)
33033   ASPx.GetControlCollection().Get(this.calendarConsumerName).OnPopupControlShown();
33034  else  
33035   ASPxClientDropDownEditBase.prototype.OnPopupControlShown.call(this);
33036  this.GetActiveController().OnPopupControlShown();
33037 },
33038 GetCalendar: function() { 
33039  var name = this.GetDropDownInnerControlName(calendarNameSuffix);
33040  return ASPx.GetControlCollection().Get(name);
33041 },
33042 GetTimeEdit: function() { 
33043  var name = this.GetDropDownInnerControlName(timeEditNameSiffix);
33044  return ASPx.GetControlCollection().Get(name);
33045 },
33046 GetClock: function() {
33047  var name = this.GetDropDownInnerControlName(clockNameSiffix);
33048  return ASPx.GetControlCollection().Get(name);
33049 },
33050 GetCalendarOwner: function() {
33051  if(!this.calendarOwnerName)
33052   return null;
33053  return ASPx.GetControlCollection().Get(this.calendarOwnerName);
33054 },
33055 GetShowTimeSection: function(){
33056  var calendarOwner = this.GetCalendarOwner();
33057  if(calendarOwner)
33058   return calendarOwner.showTimeSection;
33059  return this.showTimeSection;
33060 },
33061 IsAdaptiveTimeSectionEnabled: function() {
33062  if(!this.GetShowTimeSection())
33063   return false;
33064  var calendarOwner = this.GetCalendarOwner();
33065  if(calendarOwner)
33066   return calendarOwner.enableAdaptiveTimeSection;
33067  return this.enableAdaptiveTimeSection;
33068 },
33069 GetFormattedDate: function(date) {
33070  date = date || this.date;
33071  if(this.maskInfo != null)
33072   return this.maskInfo.GetValue();
33073  if(date == null)
33074   return this.focused ? "" : this.nullText;
33075  return this.dateFormatter.Format(date);
33076 },
33077 SetTextWasChangedInInput: function(value) {
33078  this.textWasChangedInInput = value;
33079 },
33080 GetTextWasChangedInInput: function() {
33081  return this.textWasChangedInInput;
33082 },
33083 RaiseValueChangedEvent: function(isInternal) {
33084  if(!this.isInitialized) return false;
33085  var processOnServer = ASPxClientEdit.prototype.RaiseValueChangedEvent.call(this);
33086  processOnServer = this.RaiseDateChanged(processOnServer, isInternal);
33087  return processOnServer;
33088 },
33089 OnApplyChanges: function(){
33090  if(this.focused)
33091   this.OnTextChanged();
33092 },
33093 OnCalendarSelectionChanging: function(date, select) {
33094  if(this.GetShowTimeSection()) {
33095   var timeEditDate = ASPx.MaskDateTimeHelper.GetDate(this.GetTimeEdit().maskInfo);
33096   var selectedDate = this.ReplaceTimePart(date, timeEditDate);
33097   this.SetValue(selectedDate, true);
33098   this.SetTextWasChangedInInput(false);
33099  }
33100  else {
33101   if(date != null)
33102    this.ApplyExistingTime(date);
33103   if(!this.GetCalendar().isDateChangingByKeyboard) {
33104    this.HideDropDownArea(true);
33105    this.ChangeDate(date);
33106    if(select)
33107     ASPx.Selection.Set(this.GetInputElement());
33108    this.lastValue = this.GetInputElement().value;
33109   }
33110   else {
33111    this.SetValue(date, true);
33112   }
33113  }  
33114 },
33115 OnCalendarCustomDisabledDate: function(e) {
33116  this.RaiseCalendarCustomDisabledDate(e);
33117 },
33118 OnCustomDisabledDate: function(date) {
33119  return this.RaiseCustomDisabledDateEvent(date);
33120 },
33121 RaiseCustomDisabledDateEvent: function(date) {
33122  var args = new ASPxClientCalendarCustomDisabledDateEventArgs(date);
33123  this.CalendarCustomDisabledDate.FireEvent(this, args);
33124  return args;
33125 },
33126 RaiseCalendarCellClick: function(e) {
33127  if(!this.CalendarCellClick.IsEmpty())
33128   this.CalendarCellClick.FireEvent(this, e);
33129 },
33130 ReplaceDatePart: function(targetDate, sourceDate) {
33131  var result = ASPxClientCalendar.CloneDate(targetDate);
33132  if(sourceDate) {
33133   result.setFullYear(sourceDate.getFullYear());
33134   result.setMonth(sourceDate.getMonth());
33135   result.setDate(sourceDate.getDate());
33136  }
33137  return result;
33138 },
33139 ReplaceTimePart: function(targetDate, sourceDate) {
33140  var result = ASPxClientCalendar.CloneDate(targetDate);  
33141  if(sourceDate) {
33142   result.setHours(sourceDate.getHours());
33143   result.setMinutes(sourceDate.getMinutes());
33144   result.setSeconds(sourceDate.getSeconds());
33145   result.setMilliseconds(sourceDate.getMilliseconds());
33146  }
33147  return result;
33148 },
33149 ForceRefocusTimeSectionTimeEdit: function(mouseDownSource) {
33150  var dateEdit = this;
33151  if(this.calendarConsumerName)
33152   dateEdit = ASPx.GetControlCollection().Get(this.calendarConsumerName);
33153  var timeEdit = dateEdit.GetTimeEdit();
33154  var isTimeEditElement = timeEdit.IsEditorElement(mouseDownSource);
33155  if(isTimeEditElement && !timeEdit.IsElementBelongToInputElement(mouseDownSource)) { 
33156   if(!ASPx.Browser.VirtualKeyboardSupported) 
33157    timeEdit.ForceRefocusEditor();
33158   return;
33159  }
33160  if(!dateEdit.IsEditorElement(mouseDownSource)) {
33161   if(ASPx.Browser.VirtualKeyboardSupported && !isTimeEditElement) {
33162    this.lockLostFocus = false;
33163    if(ASPx.VirtualKeyboardUI.focusableInputElementIsActive(timeEdit)) {
33164     timeEdit.GetInputElement().blur();
33165    } else {
33166     ASPx.VirtualKeyboardUI.lostAppliedFocusOfEditor();
33167    }
33168   }
33169   return;
33170  }
33171  if(ASPx.Browser.VirtualKeyboardSupported) {
33172   this.lockLostFocus = true;
33173  } else {
33174   dateEdit.ForceRefocusEditor();
33175   var input = timeEdit.GetInputElement();
33176   if(input)
33177    input.blur();
33178   window.setTimeout(function() { ASPx.SetFocusedEditor(dateEdit); }, 0);
33179  }
33180 },
33181 ApplySelectedDate: function() {
33182  if(!this.GetReadOnly()) {
33183   var selectedDate = this.GetActiveController().GetSelectedDate();
33184   if(selectedDate && !this.GetShowTimeSection())
33185    this.ApplyExistingTime(selectedDate);
33186   this.ApplyParsedDate(selectedDate, true);
33187  }
33188 },
33189 RollbackSelectedDate: function() {
33190  if(!this.GetReadOnly())
33191   this.ApplyParsedDate(this.GetDate(), false);
33192 },
33193 IsEditorElement: function(element) {
33194  var timeEdit = this.GetTimeEdit();
33195  if(this.GetShowTimeSection() && timeEdit && ASPx.GetIsParent(timeEdit.GetMainElement(), element)) {
33196   this.lockLostFocus = true;
33197   return false;
33198  }
33199  return ASPxClientDropDownEditBase.prototype.IsEditorElement.call(this, element);
33200 },
33201 OnFocusCore: function() {
33202  this.GetActiveController().SetActiveControl();
33203  ASPxClientDropDownEditBase.prototype.OnFocusCore.call(this);
33204  if(!ASPx.GetControlCollection().InCallback())
33205   this.SetTextChangingTimer();
33206 },
33207 OnLostFocusCore: function() {
33208  if(!this.isFocusUnlocked())
33209   return;
33210  ASPxClientDropDownEditBase.prototype.OnLostFocusCore.call(this);
33211  if(!this.focused) {
33212   this.ClearTextChangingTimer();
33213   if(this.outOfRangeWarningManager)
33214    this.outOfRangeWarningManager.HideOutOfRangeWarningElement();
33215  }
33216 },
33217 isFocusUnlocked: function() {
33218  return this.ensureFocusUnlockedOnShowTimeSection() && this.ensureFocusUnlockedOnShowDropDown();
33219 },
33220 ensureFocusUnlockedOnShowTimeSection: function() {
33221  var result = true;
33222  if(this.GetShowTimeSection() && this.lockLostFocus) {
33223   this.lockLostFocus = false;
33224   result = false;
33225  }
33226  return result;
33227 },
33228 ensureFocusUnlockedOnShowDropDown: function() {
33229  return true;
33230 },
33231 OnTimeEditLostFocus: function() {
33232  this.OnLostFocusCore();
33233 },
33234 OnTimeEditEnter: function() {
33235  this.ForceRefocusEditor();
33236  this.ApplySelectedDate();
33237  this.HideDropDownArea(true);
33238  ASPx.Selection.Set(this.GetInputElement());
33239 },
33240 OnTimeEditEsc: function() {
33241  this.ForceRefocusEditor();
33242  this.HideDropDownArea(true);
33243 },
33244 OnTimeEditTab: function(shiftKey) {
33245  if(shiftKey && !this.GetCalendarOwner())
33246   this.ForceRefocusEditor();
33247  this.ApplySelectedDate();
33248  this.HideDropDownArea(true);
33249 },
33250 OnApplyButtonClick: function() {
33251  this.ApplySelectedDate();
33252  this.HideDropDownArea(true);
33253 },
33254 OnTimeSectionCancelClick: function() {
33255  this.RollbackSelectedDate();
33256  this.HideDropDownArea(true);
33257 },
33258 OnTimeSectionClearClick: function() {
33259  this.ChangeDate(null);
33260  this.GetCalendar().ResetLastSelectedDate();
33261  this.HideDropDownArea(true);
33262 },
33263 OnTimeEditInternalValueChanging: function(eventArgs) {
33264  var timeEditDate = eventArgs.date;
33265  if(eventArgs.oldInputValue !== "" && eventArgs.newInputValue !== "") {
33266   var calendarSelectedDate = this.GetCalendar().GetSelectedDate();
33267   var selectedDate = this.ReplaceDatePart(timeEditDate, calendarSelectedDate);
33268   this.SetValue(selectedDate, true);
33269  }
33270  var clock = this.GetClock();
33271  if(clock)
33272   clock.SetDate(timeEditDate);
33273 },
33274 OnArrowUp: function(evt){ 
33275  var isProcessed = ASPxClientDropDownEditBase.prototype.OnArrowUp.call(this, evt);
33276  if(!isProcessed && this.droppedDown)
33277   return this.OnCalendarMethod("OnArrowUp", evt);       
33278  return false;
33279 },
33280 OnArrowDown: function(evt){
33281  var isProcessed = ASPxClientDropDownEditBase.prototype.OnArrowDown.call(this, evt);
33282  if(!isProcessed && this.droppedDown)
33283   return this.OnCalendarMethod("OnArrowDown", evt);
33284  return false;
33285 },
33286 OnArrowLeft: function(evt){
33287  if(this.droppedDown) {
33288   this.OnCalendarMethod("OnArrowLeft", evt);
33289   return true;
33290  }
33291  return false;
33292 },
33293 OnArrowRight: function(evt){
33294  if(this.droppedDown) { 
33295   this.OnCalendarMethod("OnArrowRight", evt);
33296   return true;
33297  }
33298  return false;
33299 },
33300 OnPageUp: function(evt){
33301  if(this.droppedDown) { 
33302   this.OnCalendarMethod("OnPageUp", evt);
33303   return true;
33304  }
33305  return false;  
33306 },
33307 OnPageDown: function(evt){
33308  if(this.droppedDown) {
33309   this.OnCalendarMethod("OnPageDown", evt);
33310   return true;
33311  }
33312  return false;  
33313 },
33314 OnEndKeyDown: function(evt) {
33315  if(this.droppedDown) {
33316   this.OnCalendarMethod("OnEndKeyDown", evt);
33317   return true;
33318  }
33319  return false;
33320 },
33321 OnHomeKeyDown: function(evt) {
33322  if(this.droppedDown) {
33323   this.OnCalendarMethod("OnHomeKeyDown", evt);
33324   return true;
33325  }
33326  return false; 
33327 },
33328 OnCalendarMethod: function(methodName, evt){
33329  var calendar = this.GetCalendar();
33330  if(!calendar)
33331   return;
33332  if(!calendar.IsFastNavigationActive())
33333   this.SetTextWasChangedInInput(false);
33334  return calendar[methodName](evt);
33335 },
33336 GetDateByCurrentValueString: function(valueString) {
33337  var inputValueParseResult = this.dateFormatter.ParseAndMergeWithDate(valueString, this.date);
33338  return inputValueParseResult ? inputValueParseResult : null;
33339 },
33340 OnKeyDown: function(evt) {
33341  ASPxClientDropDownEditBase.prototype.OnKeyDown.call(this, evt);
33342  this.keyUpProcessing = true;
33343 },
33344 OnKeyUp: function(evt) {
33345  if(ASPx.FilteringUtils.EventKeyCodeChangesTheInput(evt)){
33346   this.SetTextWasChangedInInput(true);
33347   if (this.UseRestrictions() && this.outOfRangeWarningManager) {
33348    var valueString = this.GetInputElement().value;
33349    this.lastValue = valueString;
33350    this.UpdateOutOfRangeWarning(valueString);
33351   }
33352  }
33353  this.keyUpProcessing = false;
33354  this.EnsureClearButtonVisibility();
33355 },
33356 UpdateOutOfRangeWarning: function(valueString) {
33357  var currentDate = this.GetDateByCurrentValueString(valueString);
33358  currentDate = this.CorrectDateByPickerType(currentDate);
33359  if(this.maskInfo && ASPx.DateUtils.AreDatesEqualExact(currentDate, new Date(100, 0, 1)))
33360   currentDate = null;
33361  this.outOfRangeWarningManager.UpdateOutOfRangeWarningElementVisibility(currentDate);
33362 },
33363 SetTextChangingTimer: function () {
33364  if(this.pasteTimerID === -1)
33365   this.pasteTimerID = ASPx.Timer.SetControlBoundInterval(this.OnTextChangingCheck, this, ASPx.PasteCheckInterval);
33366 },
33367 ClearTextChangingTimer: function () {
33368  this.pasteTimerID = ASPx.Timer.ClearInterval(this.pasteTimerID);
33369 },
33370 OnTextChangingCheck: function (evt) {
33371  var input = this.GetInputElement();
33372  if (!input)
33373   return;
33374  var curValueString = input.value.toString();
33375  if (this.lastValue != curValueString && !this.keyUpProcessing) {
33376   var isChromeOnAndroid = ASPx.Browser.AndroidMobilePlatform && ASPx.Browser.Chrome;
33377   if (!isChromeOnAndroid)
33378    this.OnPaste(curValueString);
33379  }
33380 },
33381 OnPaste: function (valueString) {
33382  this.lastValue = valueString;
33383  if(this.UseRestrictions() && this.outOfRangeWarningManager)
33384   this.UpdateOutOfRangeWarning(valueString);
33385 },
33386 OnEnter: function() {
33387  this.enterProcessed = false; 
33388  if(this.droppedDown) {
33389   this.GetActiveController().OnEnter();
33390   this.enterProcessed = true;
33391  }
33392  else
33393   this.OnApplyChanges();
33394  this.SetTextWasChangedInInput(false);
33395  return this.enterProcessed;
33396 },
33397 OnEscape: function() {
33398  if(this.droppedDown)
33399   this.GetActiveController().OnEscape();
33400  this.ChangeDate(this.date);  
33401  this.SetTextWasChangedInInput(false);
33402  return true;
33403 },
33404 OnTab: function(evt){
33405  if(!this.droppedDown) return;
33406  this.GetActiveController().OnTab(evt);
33407 },
33408 HideDropDownArea: function(isRaiseEvent) {
33409  if(this.accessibilityCompliant && this.focused)
33410   this.OnHideCalendarAccessible();
33411  var calendar = this.GetCalendar();
33412  if(calendar)
33413   calendar.EnsureHideFastNavigation();
33414  ASPxClientDropDownEditBase.prototype.HideDropDownArea.call(this, isRaiseEvent);
33415 },
33416 OnTextChanged: function() {
33417  if(!this.IsFocusEventsLocked() || !this.droppedDown) {
33418   ASPxClientDropDownEditBase.prototype.OnTextChanged.call(this);
33419   var newText = this.GetInputElement().value;
33420   var calendar = this.GetCalendar();
33421   if(this.accessibilityCompliant && calendar) {
33422    if(!newText)
33423     newText = ASPx.AccessibilitySR.BlankEditorText;
33424    var accessibilityElement = calendar.GetAccessibilityAssistantElement();
33425    ASPx.Attr.SetAttribute(accessibilityElement, "aria-label", newText);
33426   }
33427  }
33428 },
33429 IsMaskInfoEmpty: function() {
33430  return this.maskInfo && (this.maskInfo.IsEmpty() || this.GetValue() == null);
33431 },
33432 OnMouseWheel: function(evt) {
33433  var source = ASPx.Evt.GetEventSource(evt);
33434  var parentWheel = ASPx.GetParentByClassName(source, "dxsp-wheel");
33435  if(!parentWheel)
33436   ASPxClientDropDownEditBase.prototype.OnMouseWheel.call(this, evt);
33437 },
33438 ParseValue: function() { 
33439  this.ParseValueCore(true);
33440 },
33441 ParseValueCore: function(raiseChangedEvent) {
33442  var date;
33443  if(this.maskInfo != null) {   
33444   date = ASPx.MaskDateTimeHelper.GetDate(this.maskInfo, this.date);
33445  } else {
33446   var text = this.GetInputElement().value;
33447   var userParseResult = this.GetUserParsedDate(text);
33448   if(userParseResult !== false) {
33449    date = userParseResult;
33450   } else {
33451    if(text == null || text == "" || text == this.nullText)
33452     date = null;
33453    else
33454     date = !this.focused && raiseChangedEvent ? this.date : this.dateFormatter.ParseAndMergeWithDate(text, this.date);
33455   }   
33456  }
33457  if(this.GetShowTimeSection() && !this.HasTimeInEditFormat() && date)
33458   this.ApplyExistingTime(date);
33459  date = this.CorrectDateByPickerType(date);
33460  this.ApplyParsedDate(date, raiseChangedEvent);
33461  this.lastValue = this.GetInputElement().value;
33462 },
33463 GetUserParsedDate: function(text) {
33464  if(!this.ParseDate.IsEmpty()) {
33465   var args = new ASPxClientParseDateEventArgs(text);
33466   this.ParseDate.FireEvent(this, args);
33467   if(args.handled)
33468    return args.date;
33469  }
33470  return false;
33471 },
33472 ApplyParsedDate: function(date, raiseChangedEvent) {
33473  if(date === false || !ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, date, true) ||
33474   this.IsDateDisabled(date)) {
33475   switch(this.dateOnError) {
33476    case "n":
33477     date = null;
33478     break;
33479    case "t":
33480     date = new Date();
33481     break;
33482    default:
33483     date = this.date;
33484     break;
33485   }
33486  }
33487  if(!this.allowNull && date == null)
33488   date = this.date;
33489  if(raiseChangedEvent)
33490   this.ChangeDate(date);  
33491  else
33492   this.SetValue(date);
33493 },
33494 CorrectDateByPickerType: function(date) {
33495  return ASPx.DateUtils.CorrectDateByPickerType(date, this.pickerType);
33496 },
33497 SetSelectionOnToggleTextDecoration: function(input, sel) {
33498  if(this.maskInfo != null && this.GetValue() === null)
33499   sel.endPos = sel.startPos = 0;
33500  ASPxClientDropDownEditBase.prototype.SetSelectionOnToggleTextDecoration.call(this, input, sel);
33501 },
33502 IsDateDisabled: function(date) {
33503  var calendar = this.GetCalendar();
33504  var currentViewType = calendar ? calendar.currentViewType : this.pickerType;
33505  return ASPxClientCalendarDateDisabledHelper.IsDateDisabled(this.sharedParameters, date, function(d) { return this.OnCustomDisabledDate(d); }.aspxBind(this), currentViewType, this.pickerType);
33506 },
33507 HasTimeInEditFormat: function() {
33508  if(this.maskInfo) {
33509   for(var i = 0; i < this.maskInfo.parts.length; i++) {
33510    var part = this.maskInfo.parts[i];
33511    if(part.dateTimeRole && part.dateTimeRole.toLowerCase() == "h")
33512     return true;
33513   }
33514   return false;
33515  }
33516  return this.dateFormatter.mask.toLowerCase().indexOf("h") != -1;
33517 },
33518 ApplyExistingTime: function(date) {
33519  if(this.date == null)  return;  
33520  var savedDay = date.getDate();
33521  date.setHours(this.date.getHours());
33522  var diff = date.getDate() - savedDay;
33523  if(diff != 0) {
33524   var sign = (diff == 1 || date.getDate() == 1) ? -1 : 1;
33525   date.setTime(date.getTime() + sign * 3600000);
33526  }
33527  date.setMinutes(this.date.getMinutes());
33528  date.setSeconds(this.date.getSeconds());
33529  date.setMilliseconds(this.date.getMilliseconds());
33530 },
33531 GetValue: function() {
33532  return this.date;
33533 },
33534 GetLastSuccesfullValue: function() {
33535  return this.GetValue();
33536 },
33537 GetValueString: function() {
33538  return this.date != null ? ASPx.DateUtils.GetInvariantDateTimeString(this.date) : null;
33539 },
33540 SetValueWithValidationWarning: function(date, isInputUpdate) {
33541  if(this.UseRestrictions() && this.outOfRangeWarningManager) {
33542   this.UpdateOutOfRangeWarning(this.GetFormattedDate(date));
33543  }
33544  this.SetValue(date, isInputUpdate);
33545 },
33546 SetValue: function(date, isInputUpdate) {
33547  date = this.CorrectDateByPickerType(date);
33548  if(!isInputUpdate)
33549   this.date = date;
33550  this.SetValueInternal(date, isInputUpdate);
33551  this.RaiseValueSet(isInputUpdate);
33552 },
33553 SetValueInternal: function(date, isInputUpdate) {
33554  if(this.maskInfo != null)
33555   this.SetMaskValue(date);
33556  else
33557   this.SetValueCore(date, isInputUpdate);
33558  if(this.styleDecoration)
33559   this.styleDecoration.Update();
33560 },
33561 SetMaskValue: function(date) {
33562  ASPx.MaskDateTimeHelper.SetDate(this.maskInfo, date);
33563  this.ApplyMaskInfo(false);
33564  this.SavePrevMaskValue();
33565 },
33566 SetValueCore: function(date, isInputUpdate) {
33567  this.GetInputElement().value = this.GetFormattedDate(date);
33568  if(!isInputUpdate)
33569   this.SyncRawValue();
33570  if(this.CanApplyTextDecorators())
33571   this.ToggleTextDecoration();
33572 },
33573 RaiseValueSet: function(isInputUpdate) {
33574  if(!isInputUpdate && !this.ValueSet.IsEmpty())
33575   this.ValueSet.FireEvent(this);
33576 },
33577 ChangeDate: function(date) { 
33578  var changed = !ASPx.DateUtils.AreDatesEqualExact(this.date, date);
33579  this.SetDate(date);
33580  var forceValueChanged = this.IsValueChangeForced() && !this.IsValueChanging();
33581  if(changed || forceValueChanged) {
33582   try {
33583    this.StartValueChanging();
33584    this.dateChangeProcessing = true;
33585    this.RaisePersonalStandardValidation();
33586    this.OnValueChanged();
33587   }
33588   finally {
33589    this.dateChangeProcessing = false;
33590    this.EndValueChanging();
33591   }
33592  }
33593 },
33594 IsDateChangeProcessing: function() {
33595  return this.dateChangeProcessing;
33596 },
33597 getProcessOnServerOnValueChanged: function() {
33598  var dateRangePair = ASPxDateRangeHelper.GetDateEditPair(this);
33599  if(!dateRangePair.isInRangeMode)
33600   return ASPxClientDropDownEditBase.prototype.getProcessOnServerOnValueChanged.call(this);
33601  var processOnServer = this.RaiseValueChangedEvent();
33602  return this.RaiseValidationInternal() && processOnServer;
33603 },
33604 GetText: function() {
33605  return this.GetFormattedDate();
33606 },
33607 SetText: function(value) {
33608  ASPxClientTextEdit.prototype.SetValue.call(this, value);
33609  if(this.maskInfo == null)
33610   this.ParseValueCore(false);
33611 },
33612 GetFormattedText: function() {
33613  if(this.maskInfo != null)
33614   return this.GetMaskDisplayText();
33615  if(this.date == null)
33616   return this.nullText;
33617  if(this.displayFormat != null)
33618   return this.GetDisplayFormatText(this.date);
33619  return this.GetFormattedDate();
33620 },
33621 ClearEditorValueByClearButtonCore: function() {
33622  if(this.allowNull === false) 
33623   this.SetValue(this.GetLastSuccesfullValue());
33624  else
33625   ASPxClientDropDownEditBase.prototype.ClearEditorValueByClearButtonCore.call(this);
33626 },
33627 ShouldCancelMaskKeyProcessing: function(htmlEvent, keyDownInfo) {
33628  if(htmlEvent.altKey)
33629   return true;
33630  if(ASPxClientDropDownEditBase.prototype.ShouldCancelMaskKeyProcessing.call(this, htmlEvent, keyDownInfo))
33631   return true;  
33632  if(!this.droppedDown)
33633   return false;
33634  if(this.GetShowTimeSection() && htmlEvent.keyCode == ASPx.Key.Tab)
33635   return false;
33636  return !ASPx.MaskManager.IsPrintableKeyCode(keyDownInfo) 
33637   && keyDownInfo.keyCode != ASPx.Key.Backspace
33638   && keyDownInfo.keyCode != ASPx.Key.Delete;
33639 },
33640 DecodeRawInputValue: function(value) {
33641  if(value == "N") return null;
33642  var date = new Date();
33643  date.setTime(Number(value));
33644  var result = ASPx.DateUtils.ToUtcTime(date);
33645  var offsetDiff = ASPx.DateUtils.GetTimeZoneOffsetDifference(result, date);
33646  if(offsetDiff !== 0)
33647   result.setTime(result.valueOf() + offsetDiff);
33648  return result;
33649 },
33650 SyncRawValue: function() {
33651  this.SetRawValue(this.date == null ? "N" : ASPx.DateUtils.ToLocalTime(this.date).valueOf());
33652 }, 
33653 HasTextDecorators: function() {
33654  return (this.maskInfo != null && this.date == null) || ASPxClientDropDownEditBase.prototype.HasTextDecorators.call(this);
33655 },
33656 GetDisplayFormatText: function(value) {
33657  if(this.pickerType == ASPx.DatePickerType.Decades && this.hasDecadeDisplayFormat && value && value.getFullYear)
33658   return ASPx.DateUtils.GetYearRangeFormatString(value.getFullYear(), 10);
33659  return ASPxClientDropDownEditBase.prototype.GetDisplayFormatText.call(this, value);
33660 },
33661 GetMaskDisplayText: function() {
33662  if(!this.focused) {
33663   if(this.date == null)
33664    return this.nullText;
33665   if(this.HasTextDecorators())
33666    return this.GetDecoratedText(this.date);
33667  }
33668  return this.maskInfo.GetText();
33669 },
33670 ToggleTextDecorationCore: function() {
33671  if(this.maskInfo != null) {
33672   this.ApplyMaskInfo(false);
33673  } else {
33674   var text = this.focused ? this.GetFormattedDate() : this.GetFormattedText();
33675   var input = this.GetInputElement();
33676   if(input.value != text)
33677    input.value = text;
33678  }
33679 },
33680 BeginShowMaskHint: function() {
33681 },
33682 EnsureOutOfRangeWarningManager: function () {
33683  this.ensureOutOfRangeWarningManager(this.GetMinDate(), this.GetMaxDate(), null, null, this.dateFormatter);
33684 },
33685 SetReadOnlyInternal: function(readOnly) {
33686  ASPxClientDropDownEditBase.prototype.SetReadOnlyInternal.call(this, readOnly);
33687  var calendar = this.GetCalendar();
33688  if(calendar)
33689   calendar.SetReadOnly(readOnly);
33690  var timeEdit = this.GetTimeEdit();
33691  if(timeEdit)
33692   timeEdit.SetReadOnly(readOnly);
33693 },
33694 OnHideCalendarAccessible: function() {
33695  var calendar = this.GetCalendar();
33696  if(!calendar)
33697   return;
33698  var inputElement = this.GetInputElement();
33699  var accessibilityElement = calendar.GetAccessibilityAssistantElement();
33700  var pronounceTimeout = 300;
33701  ASPx.Attr.RemoveAttribute(inputElement, "aria-activedescendant");
33702  window.setTimeout(function() { 
33703   ASPx.Attr.SetAttribute(accessibilityElement, "aria-label", inputElement.value);
33704   ASPx.Attr.SetAttribute(inputElement, "aria-activedescendant", accessibilityElement.id);
33705  }, pronounceTimeout);
33706 },
33707 onDropDownApplyCommandClick: function() {
33708  this.OnApplyButtonClick();
33709 },
33710 onDropDownCloseCommandClick: function() {
33711  this.OnTimeSectionCancelClick();
33712 },
33713 ensureDropDownClosedOnLostFocus: function() {
33714  if(this.accessibilityCompliant && this.GetShowTimeSection())
33715   return;
33716  ASPxClientDropDownEditBase.prototype.ensureDropDownClosedOnLostFocus.call(this);
33717 },
33718 RaiseDateChanged: function(processOnServer, isInternal) {
33719  if(!this.DateChanged.IsEmpty()) {
33720   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
33721   if (isInternal)
33722    args.isInternal = true;
33723   this.DateChanged.FireEvent(this, args);
33724   processOnServer = args.processOnServer;
33725  }
33726  return processOnServer;
33727 },
33728 RaiseCalendarCustomDisabledDate: function(e) {
33729  this.CalendarCustomDisabledDate.FireEvent(this, e);
33730 },
33731 SetDate: function(date) {
33732  if(!ASPx.Ident.IsDate(date) || isNaN(date))
33733   date = null;
33734  this.SetValue(date);
33735  if(this.droppedDown)
33736   this.GetActiveController().SetSelectedDate(this.date);
33737 },
33738 GetDate: function() {
33739  return this.date ? new Date(this.date.valueOf()) : null;
33740 },
33741 GetRangeDayCount: function () {
33742  return ASPxDateRangeHelper.GetRangeLength(this, ASPx.DatePickerType.Days);
33743 },
33744 GetRangeLength: function() {
33745  return ASPxDateRangeHelper.GetRangeLength(this, this.pickerType);
33746 },
33747 GetMinDate: function() {
33748  return this.sharedParameters.minDate;
33749 },
33750 SetMinDate: function(date) {
33751  this.SetMinDateCore(date);
33752  this.ownMinDate = this.GetMinDate();
33753 },
33754 SetMinDateCore: function(date) {
33755  var newMinDate = this.CorrectDateByPickerType(date);
33756  this.sharedParameters.minDate = newMinDate;
33757  if(this.droppedDown) {
33758   var calendar = this.GetCalendar();
33759   if(calendar)
33760    calendar.SetMinDate(newMinDate);
33761  }
33762  if(this.showOutOfRangeWarning) {
33763   this.EnsureOutOfRangeWarningManager();
33764   this.outOfRangeWarningManager.SetMinValue(this.GetMinDate());
33765  }
33766  if(this.droppedDown)
33767   this.GetActiveController().UpdateMinMaxYears();
33768 },
33769 GetMaxDate: function() {
33770  return this.sharedParameters.maxDate;
33771 },
33772 SetMaxDate: function(date) {
33773  var newMaxDate = this.CorrectDateByPickerType(date);
33774  this.sharedParameters.maxDate = newMaxDate;
33775  if(this.droppedDown) {
33776   var calendar = this.GetCalendar();
33777   if(calendar)
33778    calendar.SetMaxDate(newMaxDate);
33779  }
33780  if(this.showOutOfRangeWarning) {
33781   this.EnsureOutOfRangeWarningManager();
33782   this.outOfRangeWarningManager.SetMaxValue(this.GetMaxDate());
33783  }
33784  if(this.droppedDown)
33785   this.GetActiveController().UpdateMinMaxYears();
33786 },
33787 GetDropDownHeight: function(){
33788  return this.GetActiveController().GetDropDownHeight();
33789 },
33790 GetDropDownWidth: function(){
33791  return this.GetActiveController().GetDropDownWidth();
33792 },
33793 getThemeClassName: function() {
33794  var controlClassName = "dxeButtonEdit_";
33795  var controlClassNames = ASPx.GetClassNameList(this.GetMainElement());
33796  var themedClassName = controlClassNames
33797   .filter(function(className) { return className.indexOf(controlClassName) === 0; })[0];
33798  return themedClassName && themedClassName.substr(controlClassName.length);
33799 },
33800});
33801var DateEditController = ASPx.CreateClass(null, {
33802 constructor: function(owner) {
33803  this.owner = owner;
33804  this.active = false;
33805  this.isComboBoxList = true;
33806 },
33807 Initialize: function(toActivate) {
33808  this.SetActive(toActivate);
33809 },
33810 SetActive: function(active) {
33811  this.active = active;
33812  var viewContainer = this.GetViewContainer();
33813  if(viewContainer)
33814   ASPx.SetElementDisplay(viewContainer, active);
33815  if(active)
33816   this.AdjustViews();
33817 },
33818 IsActive: function() {
33819  return this.active;
33820 },
33821 PrepareToDateRangeMode: function(startDateEdit) {
33822  this.EnsureStartDateEditInDateRangeMode(startDateEdit);
33823  this.owner.sharedParameters.dateRangeMode = true;
33824  this.owner.ownMinDate = this.owner.GetMinDate();
33825  UTILS.SetActualMinDate(this.owner);
33826  UTILS.PrepareCalendarDateRangeMode(this.owner, this.owner);
33827 },
33828 EnsureStartDateEditInDateRangeMode: function(startDateEdit) {
33829  if(!startDateEdit.IsInDateRangeMode())
33830   this.PrepareStartDateEditToDateRangeMode(startDateEdit);
33831 },
33832 PrepareStartDateEditToDateRangeMode: function(startDateEdit) {
33833  startDateEdit.endDateEdit = this.owner;
33834  startDateEdit.sharedParameters.dateRangeMode = true;
33835  UTILS.PrepareCalendarDateRangeMode(startDateEdit, this.owner);
33836  startDateEdit.ValueSet.AddHandler(function(s, e) { UTILS.SetActualMinDate(s); });
33837 },
33838 GetViewContainer: function() {
33839  throw "Not Implemented";
33840 },
33841 AttachToDateEditClientEvents: function() {
33842  this.owner.DateChanged.AddHandler(function(s, e) {
33843   if(!e.isInternal)
33844    UTILS.OnRangeRestrictionChanged(s);
33845  });
33846  this.owner.CalendarShowing.AddHandler(function(s, e) {
33847   UTILS.OnCalendarShowing(this.owner);
33848  }.aspxBind(this));
33849 },
33850 InitializeViewHandlers: function() { },
33851 OnDropDownCore: function() { },
33852 GetDropDownHeight: function() { return; },
33853 GetDropDownWidth: function() { return; },
33854 AdjustViews: function() { },
33855 GetSelectedDate: function() { },
33856 SetActiveControl: function() {
33857  ASPxClientDateEdit.active = this.owner;
33858 },
33859 OnBeforeShowDropDown: function(date) {
33860  this.SetActiveControl();
33861  this.SetSelectedDate(date);
33862 },
33863 OnAfterShowDropDown: function() {
33864  this.AdjustViews();
33865 },
33866 onDropDownModalChanged: function(enabled) { },
33867 OnBrowserWindowResize: function(e) { },
33868 UpdateMinMaxYears: function() { },
33869 OnTab: function(evt) { },
33870 OnEnter: function() { },
33871 OnEscape: function() { },
33872 OnPopupControlShown: function() { },
33873 ResetControlAdjustment: function() { this.owner.ResetControlAdjustment(); }
33874});
33875var DateEditCalendarController = ASPx.CreateClass(DateEditController, {
33876 constructor: function(owner) {
33877  this.constructor.prototype.constructor.call(this, owner);
33878  this.dropDownPosition = 0;
33879 },
33880 Initialize: function(toActivate) {
33881  DateEditController.prototype.Initialize.call(this, toActivate);
33882  var calendar = this.GetCalendar();
33883  if(calendar)
33884   calendar.customDraw = calendar.customDraw || this.owner.sharedParameters.calendarCustomDraw;
33885 },
33886 GetCalendar: function() {
33887  return this.owner.GetCalendar();
33888 },
33889 GetTimeEdit: function() { 
33890  return this.owner.GetTimeEdit();
33891 },
33892 GetViewContainer: function() {
33893  var calendar = this.GetCalendar();
33894  return calendar ? calendar.GetMainElement() : null;
33895 },
33896 InitializeViewHandlers: function() {
33897  if(this.HasOwnedCalendar()) {
33898   this.InitializeCalendarHandlers();
33899   this.InitializeTimeEditHandlers();
33900  } else 
33901   UTILS.RegisterSharedCalendar(this.GetCalendar()); 
33902 },
33903 HasOwnedCalendar: function() {
33904  return this.owner.calendarOwnerName == null;
33905 },
33906 InitializeCalendarHandlers: function() {
33907  var calendar = this.GetCalendar();
33908  if(!calendar)
33909   return;
33910  calendar.SelectionChanging.AddHandler(ASPxClientDateEdit.HandleCalendarSelectionChanging);
33911  calendar.MainElementClick.AddHandler(ASPxClientDateEdit.HandleCalendarMainElementClick);
33912  this.ReAssignCalendarSharedEventHandlers(calendar);
33913  var calendarMainElement = calendar.GetMainElement();
33914  if(ASPx.Browser.NetscapeFamily && ASPx.IsExistsElement(calendarMainElement))
33915   calendarMainElement.style.borderCollapse = "separate";
33916 },
33917 ReAssignCalendarSharedEventHandlers: function(calendar) {
33918  calendar.CustomDisabledDate.ClearHandlers();
33919  calendar.CellClick.ClearHandlers();
33920  calendar.CustomDisabledDate.AddHandler(ASPxClientDateEdit.HandleCalendarCustomDisabledDate.aspxBind(this.owner));
33921  calendar.CellClick.AddHandler(ASPxClientDateEdit.HandleCalendarCellClick.aspxBind(this.owner));
33922 },   
33923 InitializeTimeEditHandlers: function() {
33924  var timeEdit = this.GetTimeEdit();
33925  if(timeEdit) {
33926   timeEdit.InternalValueChanging.AddHandler(ASPxClientDateEdit.HandleTimeEditInternalValueChanging);
33927   timeEdit.OwnerDateEdit = this.owner;
33928  }
33929 },
33930 OnDropDownCore: function() {
33931  DateEditController.prototype.OnDropDownCore.call(this);
33932  var cal = this.GetCalendar();
33933  if(cal && this.owner.droppedDown)
33934     cal.forceMouseDown = true;
33935  if(cal && this.owner.isDropDownModal())
33936   cal.forceMouseDown = false;
33937 },
33938 onDropDownModalChanged: function(enabled) {
33939  if(!enabled)
33940   this.AdjustTimeSectionLayoutOnShowDropDown();
33941 },
33942 EnsureCalendarSelectedDateIsActual: function() {
33943  var calendar = this.GetCalendar();
33944  if(calendar.sharedParameters.dateRangeMode && (calendar.lastSelectedDate || !this.owner.date))
33945   calendar.SetSelectedDate(calendar.lastSelectedDate);
33946 },
33947 IsCalendarShared: function() {
33948  var calendar = this.GetCalendar();
33949  var calendarName = calendar != null ? calendar.name : "";
33950  return ASPxClientDateEdit.SharedCalendarCollection.calendarIsShared(calendarName);
33951 },
33952 SetDateToCalendar: function(date) {
33953  var calendar = this.GetCalendar();
33954  if(!calendar) return;
33955  calendar.sharedParameters = this.owner.sharedParameters;
33956  if(this.IsCalendarShared())
33957   this.ReAssignCalendarSharedEventHandlers(calendar);
33958  calendar.forceUpdate = true;
33959  if(!date) {
33960   calendar.SetValue(null);
33961   this.SetDefaultVisibleDateToCalendar(calendar);
33962  } else {
33963   var dateWithoutTime = new Date(date.getFullYear(), date.getMonth(), date.getDate());
33964   calendar.SetValue(dateWithoutTime);
33965  }
33966 },
33967 SetDefaultVisibleDateToCalendar: function(calendar) {
33968  var minDate = this.owner.GetMinDate();
33969  var maxDate = this.owner.GetMaxDate();
33970  var requiredVisibleDate = new Date();
33971  if(minDate != null && minDate > requiredVisibleDate)
33972   requiredVisibleDate = minDate;
33973  else if(maxDate != null && maxDate < requiredVisibleDate)
33974   requiredVisibleDate = ASPxClientCalendar.AddMonths(maxDate, 1 - calendar.rows * calendar.columns);
33975  calendar.SetVisibleDate(new Date(
33976   requiredVisibleDate.getFullYear(),
33977   requiredVisibleDate.getMonth(),
33978   requiredVisibleDate.getDate())
33979  );
33980 },
33981 SetDateToTimeSection: function(date) {
33982  if(this.owner.GetShowTimeSection()) {
33983   var timeEdit = this.GetTimeEdit();
33984   if(timeEdit)
33985    timeEdit.SetValue(date);
33986  }
33987 },
33988 GetTimeEditDate: function() {
33989  var result = null;
33990  var timeEdit = this.GetTimeEdit();
33991  if(timeEdit) {
33992   timeEdit.ParseValue();
33993   var result = timeEdit.GetDate();
33994  }
33995  return result;
33996 },
33997 GetSelectedDate: function() {
33998  this.EnsureCalendarSelectedDateIsActual();
33999  var result = this.GetCalendar().GetSelectedDate();
34000  var timeEditDate = this.GetTimeEditDate();
34001  if(!result && timeEditDate)
34002   result = new Date(100, 0, 1);
34003  if(result && timeEditDate)
34004   result = this.owner.ReplaceTimePart(result, timeEditDate);
34005  return result;
34006 },
34007 SetSelectedDate: function(date) {
34008  this.SetDateToCalendar(date);
34009  this.SetDateToTimeSection(date);
34010 },
34011 SetActiveControl: function() {
34012  var calendar = this.GetCalendar();
34013  ASPx.activeCalendar = calendar;
34014  DateEditController.prototype.SetActiveControl.call(this);  
34015 },
34016 OnBeforeShowDropDown: function(date) {
34017  this.GetCalendar().LockUpdateAnimation();
34018  DateEditController.prototype.OnBeforeShowDropDown.call(this, date);
34019  this.owner.CalendarShowing.FireEvent(this.owner);
34020 },
34021 OnAfterShowDropDown: function() {
34022  var calendar = this.GetCalendar();
34023  if(calendar)
34024   calendar.SwitchToInitialView();
34025  var calendarOwner = this.owner.GetCalendarOwner();
34026  if(calendarOwner != null)
34027   calendarOwner.calendarConsumerName = this.owner.name;
34028  this.owner.calendarConsumerName = null;
34029  DateEditController.prototype.OnAfterShowDropDown.call(this);
34030  this.GetCalendar().UnlockUpdateAnimation();
34031 },
34032 AdjustTimeSectionLayoutOnShowDropDown: function() {
34033  if(this.owner.IsAdaptiveTimeSectionEnabled()) {
34034   var pc = this.owner.GetPopupControl();
34035   this.dropDownPosition = ASPx.GetAbsoluteX(pc.GetCurrentWindowElement());
34036   this.AdjustTimeSectionLayout();
34037   pc.UpdatePosition();
34038  }
34039 },
34040 AdjustTimeSectionLayout: function() {
34041  this.EnsureCalendarMaxWidth();
34042  var requiredTimeSectionPos = this.GetRequiredTimeSectionPosition();
34043  var currentTimeSectionPos = this.GetCurrentTimeSectionPosition();
34044  if(requiredTimeSectionPos !== currentTimeSectionPos) {
34045   if(requiredTimeSectionPos === ASPx.Position.Bottom)
34046    this.SwitchToVerticalTimeSectionLayout();
34047   else
34048    this.SwitchToHorizontalTimeSectionLayout();
34049   if(this.owner.isDropDownModal() === false)
34050    this.owner.GetClock().RecreateRectBag();
34051  }
34052 },
34053 SetCalendarMinMaxWidth: function(value) {
34054  var calendarMainElement = this.GetCalendar().GetMainElement();
34055  if(value === undefined) {
34056   calendarMainElement.style.minWidth = "";
34057   calendarMainElement.style.maxWidth = "";
34058  }
34059  else {
34060   calendarMainElement.style.minWidth = value + "px";
34061   calendarMainElement.style.maxWidth = value + "px";
34062  }
34063 },
34064 SwitchToHorizontalTimeSectionLayout: function() {
34065  var calendarMainElement = this.GetCalendar().GetMainElement();
34066  ASPx.RemoveClassNameFromElement(calendarMainElement, verticalTimeSectionClassName);
34067  ASPx.RemoveClassNameFromElement(calendarMainElement, calendarWithFullWidthChildsClassName);
34068  this.SetCalendarMinMaxWidth(this.GetCalendarWithHorizontalTimeSectionWidth());
34069  ASPx.SetElementDisplay(this.owner.GetPopupControl().GetWindowElement(-1), true);
34070 },
34071 SwitchToVerticalTimeSectionLayout: function() {
34072  var calendarMainElement = this.GetCalendar().GetMainElement();
34073  ASPx.AddClassNameToElement(calendarMainElement, verticalTimeSectionClassName);
34074  this.SetCalendarMinMaxWidth(this.GetCalendarWithVerticalTimeSectionWidth());
34075  ASPx.AddClassNameToElement(calendarMainElement, calendarWithFullWidthChildsClassName);
34076  ASPx.SetElementDisplay(this.owner.GetPopupControl().GetWindowElement(-1), true); 
34077 },
34078 GetCalendarMainElementHorizontalBorderPaddings: function() {
34079  if(!this.calendarMainElementHorizontalBorderPaddings) {
34080   var calendarMainElement = this.GetCalendar().GetMainElement();
34081   this.calendarMainElementHorizontalBorderPaddings = ASPx.GetLeftRightPaddings(calendarMainElement);
34082   var calendarMainElementCurrentStyle = ASPx.GetCurrentStyle(calendarMainElement);
34083   if(calendarMainElementCurrentStyle && calendarMainElementCurrentStyle.borderCollapse == "collapse") {
34084    var calendarMainElementHorizontalBordersWidth = ASPx.GetHorizontalBordersWidth(calendarMainElement);
34085    if(!ASPx.Browser.Edge)
34086     calendarMainElementHorizontalBordersWidth /= 2;
34087    this.calendarMainElementHorizontalBorderPaddings += calendarMainElementHorizontalBordersWidth;
34088   }
34089  }
34090  return this.calendarMainElementHorizontalBorderPaddings;
34091 },
34092 GetCalendarWithVerticalTimeSectionWidth: function() {
34093  if(this.owner.isDropDownModal())
34094   return undefined;
34095  if(!this.calendarWithVerticalTimeSectionWidth) {
34096   this.calendarWithVerticalTimeSectionWidth = 0;
34097   var calendarMainElement = this.GetCalendar().GetMainElement();
34098   var maxChildElementWidth = 0;
34099   ASPx.AddClassNameToElement(calendarMainElement, calendarWithAutoWidthChildsClassName);
34100   for(var i = 0; i < calendarMainElement.childNodes.length; i++) {
34101    var calendarChildElement = calendarMainElement.childNodes[i];
34102    if(calendarChildElement.tagName != "DIV")
34103     continue;
34104    var calendarChildElementWidth = calendarChildElement.getBoundingClientRect().width;
34105    if(calendarChildElementWidth > maxChildElementWidth)
34106     maxChildElementWidth = calendarChildElementWidth;
34107   }
34108   ASPx.RemoveClassNameFromElement(calendarMainElement, calendarWithAutoWidthChildsClassName);
34109   this.calendarWithVerticalTimeSectionWidth = maxChildElementWidth + this.GetCalendarMainElementHorizontalBorderPaddings();
34110   this.calendarWithVerticalTimeSectionWidth = Math.ceil(this.calendarWithVerticalTimeSectionWidth);
34111  }
34112  return this.calendarWithVerticalTimeSectionWidth;
34113 },
34114 EnsureCalendarMaxWidth: function() {
34115  var calendarMainElement = this.GetCalendar().GetMainElement();
34116  if(!calendarMainElement.style.maxWidth) {
34117   ASPx.RemoveClassNameFromElement(calendarMainElement, verticalTimeSectionClassName);
34118   ASPx.RemoveClassNameFromElement(calendarMainElement, calendarWithFullWidthChildsClassName);
34119   this.SetCalendarMinMaxWidth(this.GetCalendarWithHorizontalTimeSectionWidth());
34120  }
34121 },
34122 GetCalendarWithHorizontalTimeSectionWidth: function() {
34123  if(this.owner.isDropDownModal())
34124   return undefined;
34125  if(!this.calendarWithHorizontalTimeSectionWidth) {
34126   this.calendarWithHorizontalTimeSectionWidth = 0;
34127   var calendarMainElement = this.GetCalendar().GetMainElement();
34128   for(var i = 0; i < calendarMainElement.childNodes.length; i++) {
34129    var calendarChildElement = calendarMainElement.childNodes[i];
34130    if(calendarChildElement.tagName == "DIV" && !ASPx.ElementHasCssClass(calendarChildElement, timeSectionFooterClassName))
34131     this.calendarWithHorizontalTimeSectionWidth += calendarChildElement.getBoundingClientRect().width;
34132   }
34133   this.calendarWithHorizontalTimeSectionWidth += this.GetCalendarMainElementHorizontalBorderPaddings();
34134   this.calendarWithHorizontalTimeSectionWidth = Math.ceil(this.calendarWithHorizontalTimeSectionWidth);
34135  }
34136  return this.calendarWithHorizontalTimeSectionWidth;
34137 },
34138 GetRequiredTimeSectionPosition: function() {
34139  var horizontalTimeSectionRightPos = this.GetCalendarWithHorizontalTimeSectionWidth();
34140  if(this.owner.isDropDownModal()) {
34141   var modalSys = this.owner.GetPopupControl().GetModalWrapperElement(-1);
34142   var modalSysStyle = ASPx.GetCurrentStyle(modalSys);
34143   horizontalTimeSectionRightPos += ASPx.PxToInt(modalSysStyle.paddingLeft) + ASPx.PxToInt(modalSysStyle.paddingRight);
34144  }
34145  else
34146   horizontalTimeSectionRightPos += this.dropDownPosition;
34147  var verticalScrollBarWidth = ASPx.GetCurrentDocumentWidth() > ASPx.GetDocumentClientWidth() ? ASPx.GetVerticalScrollBarWidth() : 0;
34148  return horizontalTimeSectionRightPos <= ASPx.GetDocumentScrollLeft() + window.innerWidth - verticalScrollBarWidth ? ASPx.Position.Right : ASPx.Position.Bottom;
34149 },
34150 GetCurrentTimeSectionPosition: function() {
34151  var calendarMainElement = this.GetCalendar().GetMainElement();
34152  return ASPx.ElementHasCssClass(calendarMainElement, verticalTimeSectionClassName) ? ASPx.Position.Bottom : ASPx.Position.Right;
34153 },
34154 OnBrowserWindowResize: function(e) {
34155  if(this.owner.ddmBP === undefined || this.owner.isDropDownModal(true) !== undefined)
34156   this.AdjustTimeSectionLayout();
34157 },
34158 OnTab: function(evt) {
34159  var calendar = this.GetCalendar();
34160  if(calendar.IsFastNavigationActive())
34161   calendar.CancelFastNavigation();
34162  if(this.owner.GetShowTimeSection()) {
34163   this.owner.lockLostFocus = true;
34164   if(this.owner.GetCalendarOwner()) {
34165    ASPx.Evt.PreventEvent(evt);  
34166    this.owner.GetTimeEdit().SetFocus();
34167   }
34168   return;
34169  }
34170  if(this.owner.GetTextWasChangedInInput()) {
34171   this.owner.ParseValue();
34172   this.owner.HideDropDownArea(true);
34173  } else 
34174   this.owner.OnCalendarSelectionChanging(this.GetCalendar().GetValue(), false);
34175  this.owner.SetTextWasChangedInInput(false);
34176 },
34177 OnEnter: function(evt) {
34178  var calendar = this.GetCalendar();
34179  if(calendar.IsFastNavigationActive())
34180   calendar.OnEnterDown();
34181  else if(this.owner.GetTextWasChangedInInput()) {
34182   this.owner.ParseValue();
34183   this.owner.HideDropDownArea(true);
34184  } else {
34185   var calendarSelection = calendar.GetValue();
34186   if(this.owner.GetShowTimeSection()) {
34187    if(calendarSelection) {
34188     this.owner.ApplySelectedDate();
34189     ASPx.Selection.Set(this.owner.GetInputElement());
34190    } 
34191    this.owner.HideDropDownArea(true);
34192   } else
34193    this.owner.OnCalendarSelectionChanging(calendarSelection, true);
34194  }
34195 },
34196 OnEscape: function() {
34197  if(this.GetCalendar().IsFastNavigationActive())
34198   this.GetCalendar().OnEscape();
34199  else
34200   this.owner.HideDropDownArea(true);
34201 },
34202 OnPopupControlShown: function() {
34203  this.AdjustTimeSectionLayoutOnShowDropDown();
34204 }
34205});
34206var DateEditScrollPickerController = ASPx.CreateClass(DateEditController, {
34207 constructor: function(owner, spOptions) {
34208  this.constructor.prototype.constructor.call(this, owner, spOptions);
34209  this.mask = owner.dateFormatter.mask;
34210  this.width = owner.width;
34211  this.height = owner.height;
34212  this.viewContainer = null;
34213  this.processDate = false;
34214  this.tempCache = new ListBoxTemporaryCache();
34215  this.lastSuccessfulDayIndex = 0;
34216  this.daysViewFilterUpdate = false;
34217  this.spOptions = spOptions;
34218  this.views = {};
34219  this.groups = [];
34220  this.wheelsStructure = [];
34221 },
34222 Initialize: function(toActivate) {
34223  DateEditController.prototype.Initialize.call(this, toActivate);
34224  this.createWheels();
34225  this.InitializeEvents();
34226 },
34227 InitializeEvents: function() {
34228  this.AttachToYearViewFocusEvents();
34229  this.AttachToMonthViewFocusEvents();
34230  this.AttachToDayViewFocusEvents();
34231  this.AttachToHoursViewFocusEvents();
34232  this.AttachToMinutesViewFocusEvents();
34233  this.AttachToSecondsViewFocusEvents();
34234  this.AttachToMillisecondsViewFocusEvents();
34235  this.AttachToAmPmViewFocusEvents();
34236 },
34237 createWheels: function() {
34238  this.groups = this.createGroups();
34239  var container = this.GetViewContainer();
34240  if(!container)
34241   return;
34242  this.groups.forEach(function(g) {
34243   var groupElement = this.createWheelGroupElement(container);
34244   g.forEach(function(w) {
34245    this.views[w.key] = this.createRollerView(groupElement, w.items.call(this), [], w.id, false, w.caption);
34246   }.bind(this));
34247  }.bind(this));
34248 },
34249 createWheelGroupElement: function(container) {
34250  var el = document.createElement("div");
34251  el.className = this.GetGroupElementClassName();
34252  container.appendChild(el);
34253  return el;
34254 },
34255 createRollerView: function(container, itemsInfo, itemsValue, id, isComboBoxList, caption) {
34256  return new ASPx.ASPxClientRollersView(this, container, itemsInfo, itemsValue, id, isComboBoxList, caption);
34257 },
34258 createGroups: function() {
34259  return [
34260   [
34261    { key: "years", index: this.GetYearsViewIndex(), caption: this.spOptions.yearsCaption, id: "Y", items: this.GetYearsViewItems },
34262    { key: "months", index: this.GetMonthsViewIndex(), caption: this.spOptions.monthsCaption, id: "M", items: this.GetMonthViewItems },
34263    { key: "days", index: this.GetDaysViewIndex(), caption: this.spOptions.daysCaption, id: "D", items: this.GetDayViewItems }
34264   ],
34265   [
34266    { key: "hours", index: this.owner.showHourWheel ? 0 : -1, caption: this.spOptions.hoursCaption, id: "TH", items: this.GetHoursViewItems },
34267    { key: "minutes", index: this.owner.showMinuteWheel ? 1 : -1, caption: this.spOptions.minutesCaption, id: "TM", items: this.GetMinutesSecondsViewItems },
34268    { key: "seconds", index: this.owner.showSecondWheel ? 2 : -1, caption: this.spOptions.secondsCaption, id: "TS", items: this.GetMinutesSecondsViewItems },
34269    { key: "milliseconds", index: this.owner.showMillisecondWheel ? 3 : -1, caption: this.spOptions.millisecondsCaption, id: "TMS", items: this.GetMillisecondsViewItems },
34270    { key: "ampm", index: this.IsAmPmViewExists() ? 4 : -1, caption: this.spOptions.ampmCaption, id: "TAP", items: this.GetAmPmViewItems }
34271   ]
34272  ]
34273  .map(function(g) {
34274   return g
34275    .filter(function(w) { return w.index >= 0; })
34276    .sort(function(w1, w2) { return w1.index - w2.index; });
34277  })
34278  .filter(function(g) {
34279   return g.length;
34280  });
34281 },
34282 GetYearsViewIndex: function() {
34283  return this.GetDateComponentKeyIndex("y");
34284 },
34285 GetMonthsViewIndex: function() {
34286  if(this.owner.pickerType <= ASPx.DatePickerType.Months)
34287   return this.GetDateComponentKeyIndex("M");
34288  return -1;
34289 },
34290 GetDaysViewIndex: function() {
34291  if(this.owner.pickerType == ASPx.DatePickerType.Days)
34292   return this.GetDateComponentKeyIndex("d");
34293  return -1;
34294 },
34295 GetDateComponentKeyIndex: function(key) {
34296  return ASPx.Data.ArrayIndexOf(ASPx.CultureInfo.shortDate, key);
34297 },
34298 GetDayViewItems: function() {
34299  var result = [];
34300  for(var i = 1; i <= 31; i++)
34301   result.push({ texts: [i.toString()], value: i.toString() });
34302  return result;
34303 },
34304 GetMonthViewItems: function() {
34305  var result = [];
34306  var monthNames = ASPx.CultureInfo.genMonthNames.slice(0, 12);
34307  for(var i = 0; i < 12; i++)
34308   result.push({ texts: [monthNames[i]], value: i.toString() });
34309  return result;
34310 },
34311 GetYearsViewItems: function() {
34312  var result = [];
34313  for(var i = 100; i < 10000; i++)
34314   result.push({ texts: [i.toString()], value: i.toString() });
34315  return result;
34316 },
34317 IsAmPmExists: function() {
34318  return ASPx.CultureInfo.is12HoursCulture;
34319 },
34320 IsAmPmViewExists: function() {
34321  return this.owner.showHourWheel && this.IsAmPmExists();
34322 },
34323 GetHoursViewItems: function() {
34324  var result = [];
34325  var startHour = this.IsAmPmExists() ? 1 : 0;
34326  var endHour = this.IsAmPmExists() ? 12 : 23;
34327  for(var i = startHour; i <= endHour; i++)
34328   result.push({ texts: [i.toString()], value: i.toString() });
34329  return result;
34330 },
34331 GetMinutesSecondsViewItems: function() {
34332  var result = [];
34333  for(var i = 0; i < 60; i++) {
34334   var itemText = i.toString();
34335   if(itemText.length == 1)
34336    itemText = "0" + itemText;
34337   result.push({ texts: [itemText], value: i.toString() });
34338  }
34339  return result;
34340 },
34341 GetMillisecondsViewItems: function() {
34342  var result = [];
34343  for(var i = 0; i < 1000; i++) {
34344   var itemText = i.toString();
34345   while(itemText.length < 3)
34346    itemText = "0" + itemText;
34347   result.push({ texts: [itemText], value: i.toString() });
34348  }
34349  return result;
34350 },
34351 GetAmPmViewItems: function() {
34352  var result = [];
34353  result.push({ texts: [ASPx.CultureInfo.am], value: "am" });
34354  result.push({ texts: [ASPx.CultureInfo.pm], value: "pm" });
34355  return result;
34356 },
34357 GetViewContainer: function() {
34358  if(!this.viewContainer)
34359   this.viewContainer = this.CreateViewContainer();
34360  return this.viewContainer;
34361 },
34362 CreateViewContainer: function() {
34363  var viewContainer = this.owner.GetViewContainer();
34364  if(!viewContainer)
34365   return;
34366  var container = document.createElement("DIV");
34367  container.className = this.GetControllerClassName();
34368  container.id = this.GetControlName() + "_" + "controllerContainer";
34369  viewContainer.appendChild(container);
34370  return container;
34371 },
34372 GetControllerClassName: function() {
34373  var className = "dxScrollPicker";
34374  var theme = this.owner.getThemeClassName();
34375  if(theme)
34376   className += "_" + theme;
34377  return className + " dxScrollPickerSys";
34378 },
34379 GetGroupElementClassName: function() {
34380  return "dxsp-wgroup";
34381 },
34382 GetSelectedDayItem: function() {
34383  var daysView = this.views["days"];
34384  if(!daysView)
34385   return null;
34386  return daysView.GetFocusedItem();
34387 },
34388 GetSelectedDay: function() {
34389  var item = this.GetSelectedDayItem();
34390  if(item && item.value)
34391   return item.value;
34392  return 1;
34393 },
34394 GetSelectedDayIndex: function() {
34395  var item = this.GetSelectedDayItem();
34396  if(item)
34397   return item.index;
34398  return 0;
34399 },
34400 GetSelectedMonth: function() {
34401  var result = 0;
34402  var monthsView = this.views["months"];
34403  if(!monthsView)
34404   return result;
34405  var selectedItem = monthsView.GetFocusedItem();
34406  if(selectedItem && selectedItem.value)
34407   result = selectedItem.value;
34408  return result;
34409 },
34410 GetSelectedYearItem: function() {
34411  var yearsView = this.views["years"];
34412  if(!yearsView)
34413   return null;
34414  return this.views["years"].GetFocusedItem();
34415 },
34416 GetSelectedYear: function() {
34417  var item = this.GetSelectedYearItem();
34418  if(item && item.value)
34419   return item.value;
34420  return 100;
34421 },
34422 GetSelectedYearIndex: function() {
34423  var item = this.GetSelectedYearItem();
34424  if(item && item.index)
34425   return item.index;
34426  return 0;
34427 },
34428 GetSelectedHour: function() {
34429  var result = 0;
34430  var hoursView = this.views["hours"];
34431  if(!hoursView)
34432   return result;
34433  var selectedItem = hoursView.GetFocusedItem();
34434  if(selectedItem && selectedItem.value)
34435   result = selectedItem.value;
34436  result = this.ConvertAmPmValueToHours(result);
34437  return result;
34438 },
34439 GetSelectedMinute: function() {
34440  var result = 0;
34441  var minutesView = this.views["minutes"];
34442  if(!minutesView)
34443   return result;
34444  var selectedItem = minutesView.GetFocusedItem();
34445  if(selectedItem && selectedItem.value)
34446   result = selectedItem.value;
34447  return result;
34448 },
34449 GetSelectedSecond: function() {
34450  var result = 0;
34451  var secondsView = this.views["seconds"];
34452  if(!secondsView)
34453   return result;
34454  var selectedItem = secondsView.GetFocusedItem();
34455  if(selectedItem && selectedItem.value)
34456   result = selectedItem.value;
34457  return result;
34458 },
34459 GetSelectedMillisecond: function() {
34460  var result = 0;
34461  var millisecondsView = this.views["milliseconds"];
34462  if(!millisecondsView)
34463   return result;
34464  var selectedItem = millisecondsView.GetFocusedItem();
34465  if(selectedItem && selectedItem.value)
34466   result = selectedItem.value;
34467  return result;
34468 },
34469 GetSelectedAmPm: function() {
34470  var result = "am";
34471  var ampmView = this.views["ampm"];
34472  if(!ampmView)
34473   return result;
34474  var selectedItem = ampmView.GetFocusedItem();
34475  if(selectedItem && selectedItem.value)
34476   result = selectedItem.value;
34477  return result;
34478 },
34479 GetSelectedDate: function() {
34480  var result = new Date(
34481   this.GetSelectedYear(),
34482   this.GetSelectedMonth(),
34483   this.GetSelectedDay(),
34484   this.GetSelectedHour(),
34485   this.GetSelectedMinute(),
34486   this.GetSelectedSecond(),
34487   this.GetSelectedMillisecond()
34488  );
34489  return result;
34490 },
34491 SetSelectedDate: function(date) {
34492  this.processDate = true;
34493  date = date || new Date();
34494  this.currentMaxDayValue = date.getDate();
34495  setTimeout(function() {
34496   if(this.views["days"]) {
34497    this.views["days"].FocusItemByValue(date.getDate());
34498    this.UpdateLastSuccessfulDayIndex();
34499   }
34500   if(this.views["years"]) {
34501    this.UpdateMinMaxYears();
34502    this.views["years"].FocusItemByValue(date.getFullYear());
34503   }
34504   if(this.views["months"])
34505    this.views["months"].FocusItemByValue(date.getMonth());
34506   if(this.views["hours"]) {
34507    var value = this.ConvertHoursToAmPmValue(date.getHours());
34508    this.views["hours"].FocusItemByValue(value);
34509   }
34510   if(this.views["ampm"])
34511    this.views["ampm"].FocusItemByValue(date.getHours() >= 12 ? "pm" : "am");
34512   if(this.views["minutes"])
34513    this.views["minutes"].FocusItemByValue(date.getMinutes());
34514   if(this.views["seconds"])
34515    this.views["seconds"].FocusItemByValue(date.getSeconds());
34516   if(this.views["milliseconds"])
34517    this.views["milliseconds"].FocusItemByValue(date.getMilliseconds());
34518   this.processDate = false;
34519   this.UpdateInputDate();
34520   this.UpdateDaysViewFilter();
34521   }.bind(this), 0);
34522 },
34523 GetControlName: function() {
34524  return this.owner.name;
34525 },
34526 HasVirtualScrolling: function() {
34527  return true;
34528 },
34529 GetItemCellsIdPostfixes: function() {
34530  return [lbIPostfixes[2]];
34531 },
34532 FormatText: function(texts) {
34533  return texts[0];
34534 },
34535 IsMultiColumn: function() {
34536  return false;
34537 },
34538 LockSynchronization: function() {
34539 },
34540 GetSampleItemRow: function() {
34541  var row = document.createElement("DIV");
34542  row.className = "dxsp-item";
34543  row.id = "LBI-1T";
34544  return row;
34545 },
34546 GetAccessibilityHeaderRow: function() {
34547  return null;
34548 },
34549 GetItem: function (index) {
34550  return this.view.GetItem(index);
34551 },
34552 GetIsItemSelected: function(index) {
34553  return false;
34554 },
34555 InitializeItemAttributes: function(newItemRow, newClientId) {
34556  newItemRow.id = newClientId;
34557 },
34558 AddStateControllerClasses: function(newID) {
34559 },
34560 GetIsCheckColumnExists: function() {
34561  return false;
34562 },
34563 GetItemCellCount: function() {
34564  return 1;
34565 },
34566 SetItemSelectionAppearance: function() {
34567 },
34568 ChangeEnabledStateItem: function() {
34569 },
34570 TryApplyHighlighting: function() {
34571 },
34572 UnlockSynchronization: function() {
34573 },
34574 InitDXTextAttributes: function() {
34575 },
34576 isSimplifiedRowIndexCalculationApplicable: function() {
34577  return false;
34578 },
34579 GetTopScrollSpacerHeight: function() {
34580  return 0;
34581 },
34582 GetBottomScrollSpacerHeight: function() {
34583  return 0;
34584 },
34585 NeedToHandleCellWidth: function() {
34586  return false;
34587 },
34588 GetDropDownHeight: function(){
34589  if(this.owner.ddHeightCache != ASPx.InvalidDimension)
34590   return this.owner.ddHeightCache;
34591  this.EnsureDropDownWidth(); 
34592  var result = this.AdjustListBoxHeight();  
34593  return result;
34594 },
34595 GetDropDownWidth: function() {
34596  var result = this.owner.ddWidthCache;
34597  if(this.owner.ddWidthCache == ASPx.InvalidDimension || this.owner.GetIsControlWidthWasChanged())
34598   result = this.AdjustListBoxWidth();
34599  return result;
34600 },
34601 EnsureDropDownWidth: function() {
34602  this.GetDropDownWidth();
34603 },
34604 AttachToYearViewFocusEvents: function() {
34605  var yearsView = this.views["years"];
34606  if(!yearsView)
34607   return;
34608  yearsView.EndFocus.AddHandler(this.UpdateDaysViewFilter.aspxBind(this));
34609  yearsView.ItemFocused.AddHandler(function(s, e) {
34610   var value = parseInt(e.item.value);
34611   this.UpdateInputDate(value, yearsView.id);
34612  }.aspxBind(this));
34613 },
34614 AttachToMonthViewFocusEvents: function() {
34615  var monthView = this.views["months"];
34616  if(!monthView)
34617   return;
34618  monthView.EndFocus.AddHandler(this.UpdateDaysViewFilter.aspxBind(this));
34619  monthView.ItemFocused.AddHandler(function(s, e) {
34620   var value = parseInt(e.item.value);
34621   this.UpdateInputDate(value, monthView.id);
34622  }.aspxBind(this));
34623 },
34624 AttachToDayViewFocusEvents: function() {
34625  var daysView = this.views["days"];
34626  if(!daysView)
34627   return;
34628  daysView.EndFocus.AddHandler(this.UpdateLastSuccessfulDayIndex.aspxBind(this));
34629  daysView.ItemFocused.AddHandler(function(s, e) {
34630   var value = parseInt(e.item.value);
34631   this.UpdateInputDate(value, daysView.id);
34632  }.aspxBind(this));
34633 },
34634 AttachToHoursViewFocusEvents: function() {
34635  var hoursView = this.views["hours"];
34636  if(!hoursView)
34637   return;
34638  hoursView.ItemFocused.AddHandler(function(s, e) {
34639   var value = parseInt(e.item.value);
34640   var hours = this.ConvertAmPmValueToHours(value);
34641   this.UpdateInputDate(hours, hoursView.id);
34642  }.aspxBind(this));
34643 },
34644 AttachToMinutesViewFocusEvents: function() {
34645  var minutesView = this.views["minutes"];
34646  if(!minutesView)
34647   return;
34648  minutesView.ItemFocused.AddHandler(function(s, e) {
34649   var value = parseInt(e.item.value);
34650   this.UpdateInputDate(value, minutesView.id);
34651  }.aspxBind(this));
34652 },
34653 AttachToSecondsViewFocusEvents: function() {
34654  var secondsView = this.views["seconds"];
34655  if(!secondsView)
34656   return;
34657  secondsView.ItemFocused.AddHandler(function(s, e) {
34658   var value = parseInt(e.item.value);
34659   this.UpdateInputDate(value, secondsView.id);
34660  }.aspxBind(this));
34661 },
34662 AttachToMillisecondsViewFocusEvents: function() {
34663  var millisecondsView = this.views["milliseconds"];
34664  if(!millisecondsView)
34665   return;
34666  millisecondsView.ItemFocused.AddHandler(function(s, e) {
34667   var value = parseInt(e.item.value);
34668   this.UpdateInputDate(value, millisecondsView.id);
34669  }.aspxBind(this));
34670 },
34671 AttachToAmPmViewFocusEvents: function() {
34672  var ampmView = this.views["ampm"];
34673  if(!ampmView)
34674   return;
34675  ampmView.ItemFocused.AddHandler(function(s, e) {
34676   this.UpdateInputDate(e.item.value, ampmView.id);
34677  }.aspxBind(this));
34678 },
34679 UpdateDaysViewFilter: function() {
34680  if(this.processDate)
34681   return;
34682  var daysView = this.views["days"];
34683  if(!daysView)
34684   return;
34685  this.daysViewFilterUpdate = true;
34686  var year = this.GetSelectedYear();
34687  var month = this.GetSelectedMonth();
34688  var dayInMonth = this.GetDayCountInMonth(year, month);
34689  var visibleItemCount = daysView.GetVisibleItemCount();
34690  if(dayInMonth == visibleItemCount)
34691   return;
34692  var isSatisfyDelegate = function(day) { 
34693   return parseInt(day) <= dayInMonth;
34694  };
34695  var newDayIndices = [];
34696  var itemCount = daysView.GetItemCount();
34697  for(var i = 0; i < itemCount; i++) {
34698   var item = daysView.GetItem(i);
34699   var isSatisfy = isSatisfyDelegate(item.value);
34700   if(isSatisfy)
34701    newDayIndices.push(i);
34702   daysView.ApplyFilterToItem(i, isSatisfy);
34703  }
34704  daysView.RewriteFilteredItemIndices(newDayIndices);
34705  daysView.OnEndItemsFiltering();
34706  var focusedDayValue = this.GetFocusedDayValueAfterFiltering(year, month);
34707  daysView.FocusItemByValue(focusedDayValue);
34708  daysView.ProcessSmoothScroll(null, false);
34709  this.daysViewFilterUpdate = false;
34710 },
34711 UpdateLastSuccessfulDayIndex: function() {
34712  if(this.daysViewFilterUpdate)
34713   return;
34714  this.lastSuccessfulDayIndex = this.GetSelectedDayIndex();
34715 },
34716 UpdateInputDate: function(value, viewID) {
34717  if(this.processDate || this.IsReadOnly())
34718   return;
34719  var focusedDate = this.GetFocusedDate(value, viewID);
34720  if(focusedDate && !this.owner.GetShowTimeSection())
34721   this.owner.ApplyExistingTime(focusedDate);
34722  this.owner.SetValueWithValidationWarning(focusedDate, true);
34723 },
34724 GetFocusedDayValueAfterFiltering: function(year, month) {
34725  var daysView = this.views["days"];
34726  var result = null;
34727  if(!daysView.IsItemFiltered(this.lastSuccessfulDayIndex))
34728   result = this.GetDayCountInMonth(year, month);
34729  else
34730   result = daysView.GetItem(this.lastSuccessfulDayIndex).value;
34731  return result;
34732 },
34733 GetFocusedDate: function(value, viewID) {
34734  var date = this.GetSelectedDate();
34735  switch(viewID) {
34736   case "Y": 
34737    date.setFullYear(value);
34738    break;
34739   case "M":
34740    date.setMonth(value);
34741    break;
34742   case "D":
34743    date.setDate(value);
34744    break;
34745   case "TH":
34746    date.setHours(value);
34747    break;
34748   case "TM":
34749    date.setMinutes(value);
34750    break;
34751   case "TS": 
34752    date.setSeconds(value);
34753    break;
34754   case "TMS": 
34755    date.setMilliseconds(value);
34756    break;
34757   case "TAP":
34758    var hours = date.getHours();
34759    var ampm = this.GetSelectedAmPm();
34760    if(ampm !== value) {
34761     if(value === "pm" && hours <= 12)
34762      hours = hours + 12;
34763     if(value === "am" && hours >= 12)
34764      hours = hours - 12;
34765    }
34766    date.setHours(hours);
34767    break;
34768   default: 
34769    break;
34770  }
34771  return date;
34772 },
34773 ConvertAmPmValueToHours: function(value) {
34774  var result = parseInt(value);
34775  if(!this.IsAmPmViewExists())
34776   return result;
34777  var ampm = this.GetSelectedAmPm();
34778  if(ampm === "pm" && result < 12)
34779   result = result + 12;
34780  if(ampm === "am" && result === 12)
34781   result = 0;
34782  return result;
34783 },
34784 ConvertHoursToAmPmValue: function(hours) {
34785  if(!this.IsAmPmViewExists())
34786   return hours;
34787  if(hours === 0)
34788   hours = hours + 12;
34789  if(hours > 12)
34790   hours = hours - 12;
34791  return hours;
34792 },
34793 GetDayCountInMonth: function(year, month) {
34794  return new Date(year, parseInt(month) + 1, 0).getDate();
34795 },
34796 UpdateMinMaxYears: function() {
34797  var minDate = this.owner.GetMinDate();
34798  var minYear = minDate ? minDate.getFullYear() : 100;
34799  var maxDate = this.owner.GetMaxDate();
34800  var maxYear = maxDate ? maxDate.getFullYear() : 9999;
34801  var isSatisfyDelegate = function(year) {
34802   return year >= minYear && year <= maxYear;
34803  };
34804  var selectedYear = parseInt(this.GetSelectedYear());
34805  var yearsView = this.views["years"];
34806  var newYearIndices = [];
34807  var itemCountHiddenFromTop = 0;
34808  var itemCount = yearsView.GetItemCount();
34809  for(var i = 0; i < itemCount; i++) {
34810   var item = yearsView.GetItem(i);
34811   var value = parseInt(item.value);
34812   var isSatisfy = isSatisfyDelegate(value);
34813   if(isSatisfy)
34814    newYearIndices.push(i);
34815   if(value < selectedYear) {
34816    if(item.filtered && !isSatisfy)
34817     itemCountHiddenFromTop++;
34818    if(!item.filtered && isSatisfy)
34819     itemCountHiddenFromTop--;
34820   }
34821   yearsView.ApplyFilterToItem(i, isSatisfy);
34822  }
34823  yearsView.RewriteFilteredItemIndices(newYearIndices);
34824  yearsView.OnEndItemsFiltering(itemCountHiddenFromTop);
34825 },
34826 AdjustListBoxHeight: function () {
34827  var height = 0;
34828  for(var key in this.views) {
34829   if(this.views.hasOwnProperty(key)) {
34830    var view = this.views[key];
34831    if(view) {
34832     height = Math.max(view.GetScrollDivElement().offsetHeight, height);
34833     view.Adjust();
34834    }
34835   }
34836  }     
34837  return height;
34838 },
34839 AdjustListBoxWidth: function () {
34840  var width = 0;
34841  for(var key in this.views) {
34842   if(this.views.hasOwnProperty(key)) {
34843    var view = this.views[key];
34844    if(view) {
34845     width = Math.max(view.GetScrollDivElement().offsetWidth, width);
34846     view.Adjust();
34847    }
34848   }
34849  }     
34850  return width;
34851 },
34852 InitMainElementCache: function(){
34853  this.mainElementWidthCache = this.GetMainElement().clientWidth;
34854 },
34855 AdjustViews: function() {
34856    for(var key in this.views) {
34857   if(this.views.hasOwnProperty(key)) {
34858    var view = this.views[key];
34859    if(view) {
34860     view.Adjust();
34861    }
34862   }
34863  }
34864 },
34865 IsDisplayed: function() {
34866  return this.owner.IsDisplayed();
34867 },
34868 OnTab: function(evt) { 
34869  this.owner.HideDropDownArea(true);
34870 },
34871 OnEnter: function() { 
34872  this.owner.ApplySelectedDate();
34873  this.owner.HideDropDownArea(true);
34874 },
34875 OnEscape: function() {
34876  this.owner.RollbackSelectedDate();
34877  this.owner.HideDropDownArea(true);
34878 },
34879 IsReadOnly: function() {
34880  return this.owner.GetReadOnly();
34881 }
34882});
34883var UTILS = { 
34884 PrepareCalendarDateRangeMode: function(dateEdit, endDateEdit) {
34885  if(dateEdit.enabled) {
34886   var calendar = dateEdit.GetCalendar();
34887   if(calendar)
34888    calendar.updateDayStylesTwiceOnMouseOver = ASPx.Browser.Opera && this.DateEditHasParentWithRelativePosition(endDateEdit);
34889  }
34890 },
34891 DateEditHasParentWithRelativePosition: function(endDateEdit) {
34892  return ASPx.GetParent(endDateEdit.GetMainElement(),
34893   function (element) { return ASPx.GetCurrentStyle(element).position === "relative"; }) != null;
34894 },
34895 SetActualMinDate: function(dateEdit) {
34896  var dateRangePair = ASPxDateRangeHelper.GetDateEditPair(dateEdit);
34897  if(!dateRangePair.isInRangeMode) return;
34898  var rangeRestricts = ASPxDateRangeHelper.GetCurrentRangeRestrictions(dateRangePair);
34899  var newMinDate = rangeRestricts.startDate ? rangeRestricts.startDate : dateRangePair.endDateEdit.ownMinDate;
34900  if(!ASPx.DateUtils.AreDatesEqualExact(dateRangePair.endDateEdit.GetMinDate(), newMinDate))
34901   dateRangePair.endDateEdit.SetMinDateCore(newMinDate);
34902 },
34903 OnRangeRestrictionChanged: function(dateEdit) {
34904  var dateRangePair = ASPxDateRangeHelper.GetDateEditPair(dateEdit);
34905  if(!dateRangePair.isInRangeMode) return;
34906  var rangeRestricts = ASPxDateRangeHelper.GetCurrentRangeRestrictions(dateRangePair);
34907  if(ASPxDateRangeHelper.NeedCorrectSecondDateOnDateChanging(rangeRestricts, dateRangePair.isStart, dateRangePair.endDateEdit.minRange))
34908   this.CorrestSecondRangeDate(dateRangePair);
34909  if(dateRangePair.isStart)
34910   dateRangePair.endDateEdit.Validate();
34911  else {
34912   UTILS.SetActualMinDate(dateRangePair.endDateEdit);
34913   dateRangePair.startDateEdit.Validate();
34914  }
34915 },
34916 CorrestSecondRangeDate: function(dateRangePair) {
34917  var changedDate = (dateRangePair.isStart) ? dateRangePair.startDateEdit.GetDate() : dateRangePair.endDateEdit.GetDate();
34918  var endDateMinRange = Math.max(dateRangePair.endDateEdit.minRange, 0);
34919  var dateDifference = dateRangePair.isStart ? endDateMinRange : -endDateMinRange;
34920  var secondDateEdit = dateRangePair.isStart ? dateRangePair.endDateEdit : dateRangePair.startDateEdit;
34921  var secondDate = ASPxClientCalendar.GetDateByOffset(changedDate, dateDifference, secondDateEdit.pickerType);
34922  secondDateEdit.SetDate(secondDate);
34923  secondDateEdit.RaiseValueChangedEvent(true);
34924 },
34925 UpdateCalendarVisibleDate: function(targetCalendar, dateRangePair) {
34926  var rangeRestricts = ASPxDateRangeHelper.GetCurrentRangeRestrictions(dateRangePair);
34927  targetCalendar.visibleDateColumnOffset = 0;
34928  if (ASPxDateRangeHelper.IsStartRestrictionExistsOnly(rangeRestricts) && !dateRangePair.isStart) {
34929   targetCalendar.SetVisibleDate(rangeRestricts.startDate);
34930  }
34931  if (ASPxDateRangeHelper.IsEndRestrictionExistsOnly(rangeRestricts)
34932   || ASPxDateRangeHelper.IsBothRangeRestrictionsExist(rangeRestricts) && !dateRangePair.isStart) {
34933   targetCalendar.SetVisibleDate(rangeRestricts.endDate);
34934   if(!ASPxDateRangeHelper.AreRestrictionsOfSamePeriod(rangeRestricts, targetCalendar.pickerType))
34935    targetCalendar.OnShiftMonth(-1 * (targetCalendar.columns - 1), true);
34936  }
34937 },
34938 GetRangeToSelectInCalendar: function(targetCalendar, dateRangePair, isCalendarShowing) {
34939  var rangeRestricts = ASPxDateRangeHelper.GetCurrentRangeRestrictions(dateRangePair);
34940  var calendarHasOwnSelectedDate = targetCalendar.lastSelectedDate != null;
34941  var correctRangeRestrictsForSelection = !isCalendarShowing && calendarHasOwnSelectedDate;
34942  if (correctRangeRestrictsForSelection) {
34943   var calendarLastSelectedDate = ASPxClientCalendar.CloneDate(targetCalendar.lastSelectedDate);
34944   if (dateRangePair.isStart)
34945    rangeRestricts.startDate = calendarLastSelectedDate;
34946   else
34947    rangeRestricts.endDate = calendarLastSelectedDate;
34948  }
34949  return rangeRestricts;
34950 },
34951 SelectRangeInCalendar: function(targetCalendar, isCalendarShowing) {
34952  var dateRangePair = ASPxDateRangeHelper.GetDateEditPair(ASPxClientDateEdit.active);
34953  if(!dateRangePair.isInRangeMode)
34954   return;
34955  var rangeRestrictsToSelect = this.GetRangeToSelectInCalendar(targetCalendar, dateRangePair, isCalendarShowing);
34956  if(ASPxDateRangeHelper.IsNegativeRange(rangeRestrictsToSelect))
34957   return;
34958  targetCalendar.clientUpdate = true;
34959  targetCalendar.LockUpdateAnimation();
34960  targetCalendar.ClearSelection();
34961  if(ASPxDateRangeHelper.IsBothRangeRestrictionsExist(rangeRestrictsToSelect))
34962   targetCalendar.SelectRange(rangeRestrictsToSelect.startDate, rangeRestrictsToSelect.endDate);
34963  if(ASPxDateRangeHelper.IsEndRestrictionExistsOnly(rangeRestrictsToSelect))
34964   targetCalendar.SelectDate(rangeRestrictsToSelect.endDate);
34965  if(ASPxDateRangeHelper.IsStartRestrictionExistsOnly(rangeRestrictsToSelect))
34966   targetCalendar.SelectDate(rangeRestrictsToSelect.startDate);
34967  targetCalendar.UnlockUpdateAnimation();
34968  targetCalendar.Update();
34969  targetCalendar.clientUpdate = false;
34970 },
34971 OnCalendarShowing: function(dateEdit) {
34972  var dateRangePair = ASPxDateRangeHelper.GetDateEditPair(ASPxClientDateEdit.active);
34973  if(!dateRangePair.isInRangeMode)
34974   return;
34975  var targetCalendar = ASPxClientDateEdit.active.GetCalendar();
34976  if(!targetCalendar)
34977   return;
34978  UTILS.UpdateCalendarVisibleDate(targetCalendar, dateRangePair);
34979  UTILS.SetActualMinDate(dateEdit);
34980  UTILS.SelectRangeInCalendar(targetCalendar, true);
34981 },
34982 RegisterSharedCalendar: function(calendar) {
34983  if(calendar)
34984   ASPxClientDateEdit.SharedCalendarCollection.registerCalendarId(calendar.name);   
34985 }
34986};
34987ASPxClientDateEdit.SharedCalendarCollection = (function(){
34988 var sharedCalendarIdCollection = [];
34989 return {
34990  registerCalendarId: function(calendarId) {
34991   if(ASPx.Data.ArrayIndexOf(sharedCalendarIdCollection, calendarId) == -1)
34992    sharedCalendarIdCollection.push(calendarId);
34993  },
34994  calendarIsShared: function(calendarId) {
34995   return ASPx.Data.ArrayIndexOf(sharedCalendarIdCollection, calendarId) != -1;
34996  }
34997 };
34998})();
34999ASPxClientDateEdit.Cast = ASPxClientControl.Cast;
35000ASPxClientDateEdit.active = null;
35001ASPxClientDateEdit.HandleCalendarSelectionChanging = function(s, e) {
35002 if(ASPxClientDateEdit.active == null) return;
35003 ASPxClientDateEdit.active.OnCalendarSelectionChanging(e.selection.GetFirstDate(), true);
35004};
35005ASPxClientDateEdit.HandleCalendarCustomDisabledDate = function(s, e) {
35006 this.OnCalendarCustomDisabledDate(e);
35007};
35008ASPxClientDateEdit.HandleCalendarCellClick = function(s, e) {
35009 this.RaiseCalendarCellClick(e);
35010};
35011ASPxClientDateEdit.HandleTimeEditInternalValueChanging = function(s, e) {
35012 if(ASPxClientDateEdit.active == null) return;
35013 ASPxClientDateEdit.active.OnTimeEditInternalValueChanging(e);
35014};
35015ASPxClientDateEdit.HandleCalendarMainElementClick = function(s, e) {
35016 var dateEdit = ASPxClientDateEdit.active;
35017 if(dateEdit == null) 
35018  return;
35019 var focusEditor = true;
35020 if(dateEdit.GetShowTimeSection())
35021  focusEditor = !ASPx.GetIsParent(dateEdit.GetTimeEdit().GetMainElement(), ASPx.Evt.GetEventSource(e));
35022 if(focusEditor) {
35023  if(ASPx.Browser.VirtualKeyboardSupported)
35024   ASPx.VirtualKeyboardUI.focusEditor(dateEdit);
35025  else 
35026   dateEdit.SetFocus();
35027 }
35028};
35029var ASPxClientParseDateEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
35030 constructor: function(value) {
35031  this.constructor.prototype.constructor.call(this);
35032  this.value = value;
35033  this.date = null;
35034  this.handled = false;
35035 } 
35036});
35037ASPx.DECalClearClick = function() {
35038 var edit = ASPxClientDateEdit.active;
35039 if(edit)
35040  edit.OnTimeSectionClearClick();
35041};
35042ASPx.DETimeEditKeyDown = function(s,e) {
35043 var edit = ASPxClientDateEdit.active;
35044 if(!edit) return;
35045 switch(e.htmlEvent.keyCode) {
35046  case ASPx.Key.Enter:
35047   edit.OnTimeEditEnter();
35048   break;
35049  case ASPx.Key.Esc:
35050   edit.OnTimeEditEsc();
35051   break;
35052  case ASPx.Key.Tab:
35053   edit.OnTimeEditTab(e.htmlEvent.shiftKey);
35054   break;
35055 }
35056};
35057ASPx.DETimeEditLostFocus = function() {
35058 var edit = ASPxClientDateEdit.active;
35059 if(!edit) return;
35060 edit.OnTimeEditLostFocus();
35061};
35062window.ASPxClientDateEdit = ASPxClientDateEdit;
35063window.ASPxClientParseDateEventArgs = ASPxClientParseDateEventArgs;
35064ASPx.DateRangeValidationPattern = DateRangeValidationPattern;
35065ASPx.DateEditScrollPickerController = DateEditScrollPickerController;
35066})();
35067
35068(function(dx) {
35069 var BootstrapClientDateEdit = ASPx.CreateClass(ASPxClientDateEdit, {
35070  constructor: function (name) {
35071   this.constructor.prototype.constructor.call(this, name);
35072   this.needAdjustControlsInDropDownWindow = false;
35073   this.outOfRangeWarningClassName = BS_OUT_OF_RANGE_WARNING_CLASS_NAME;
35074   this.feedbackRenderHelper = new ASPx.BootstrapEditFeedbackRenderHelper(this);
35075  },
35076  InlineInitialize: function() {
35077   this.RequireStyleDecoration();
35078   ASPxClientDateEdit.prototype.InlineInitialize.call(this);
35079   this.feedbackRenderHelper.updateInputRightPadding();
35080   if(ASPx.Browser.TouchUI && !this.GetIsValid())
35081    this.UpdateErrorText();
35082  },
35083  InitializeEvents: function() {
35084   ASPxClientDateEdit.prototype.InitializeEvents.call(this);
35085   var inputElement = this.GetInputElement();
35086   if(inputElement) {
35087    ASPx.Evt.AttachEventToElement(inputElement, "change", function() { ASPx.ETextChanged(this.name); }.bind(this));
35088    ASPx.Evt.AttachEventToElement(inputElement, "mousedown", function(evt) { ASPx.DDMC_MD(this.name, evt); }.bind(this));
35089   }
35090   var buttonElements = this.GetCustomButtonCollection();
35091   for(var i = 0; i < buttonElements.length; i++) 
35092    this.InitializeButtonEvents(buttonElements[i], i);
35093   var clearButton = this.GetClearButton();
35094   if(clearButton) {
35095    ASPx.Evt.AttachEventToElement(clearButton, "mousedown", function(evt) { ASPx.BEClear(this.name, evt); }.bind(this));
35096    if(this.IsAccessibleButton(clearButton))
35097     this.InitAccessibilityAnchorEvents(clearButton);
35098   }
35099   if(ASPx.Browser.MacOSMobilePlatform) {
35100    var errorImage = this.GetErrorImage();
35101    if(errorImage)
35102     ASPx.Evt.AttachEventToElement(errorImage, "touchstart", function() { });
35103   }
35104   if(this.ddmBP !== undefined || this.ddScrPicker === ASPx.DROPDOWN_ELEMENT_VISIBILITY.Always)
35105    this.initializeDropDownCommandButtons();
35106  },
35107  InitializeButtonEvents: function(element, number){
35108   ASPx.Evt.AttachEventToElement(element, "click", function() {
35109    this.OnButtonClick(number);
35110   }.bind(this));
35111   if(this.IsAccessibleButton(element))
35112    this.InitAccessibilityAnchorEvents(element);
35113  },
35114  GetOutOfRangeWarningElementPrevSibling: function() {
35115   return this.GetInputGroupElement() || this.GetInputContainerElement();
35116  },
35117  showOutOfRangeWarningElementAtBottom: function() {
35118   return true;
35119  },
35120  NeedEnsureClearButtonVisibilityOnKeyDown: function() {
35121   return this.IsAccessibleButton(this.GetClearButton());
35122  },
35123  GetAccessibilityFocusedButtonClassName: function() {
35124   return "";
35125  },
35126  IsAccessibleButton: function(button) {
35127   return !!button && (button.tagName.toUpperCase() == "BUTTON" || ASPx.Attr.GetAttribute(button, "role") == "button");
35128  },
35129  GetButtonByAccessibilityAnchor: function(anchorElement) {
35130   return anchorElement;
35131  },
35132  GetAccessibilityAnchor: function(buttonElement) {
35133   return buttonElement;
35134  },
35135  SetAccessibilityAnchorEnabled: function(buttonElement, enabled) {
35136   if(buttonElement.tagName.toUpperCase() == "BUTTON")
35137    return;
35138   ASPxClientDateEdit.prototype.SetAccessibilityAnchorEnabled.call(this, buttonElement, enabled);
35139  },
35140  EmulateButtonMouseEvent: function(sourceElement) {
35141   ASPx.Evt.EmulateMouseClick(sourceElement);
35142  },
35143  RaiseStandardOnChange: function() {
35144   var element = this.GetInputElement();
35145   if(element)
35146    ASPx.Evt.DispatchEvent(element, "change", true, false);
35147   else
35148    ASPxClientDateEdit.prototype.RaiseStandardOnChange.call(this);
35149  },
35150  SetButtonVisible: function(number, value) {
35151   if(number == -100) {
35152    this.feedbackRenderHelper.setClearButtonVisible(value);
35153    return;
35154   }
35155   var inputGroupButton = ASPxClientDateEdit.prototype.GetButton.call(this, number);
35156   if(inputGroupButton)
35157    ASPx.SetElementDisplay(inputGroupButton, value);
35158   ASPxClientDateEdit.prototype.SetButtonVisible.call(this, number, value);
35159  },
35160  ChangeEnabledAttributes: function(enabled) {
35161   ASPxClientDateEdit.prototype.ChangeEnabledAttributes.call(this, enabled);
35162   var clearButton = this.GetClearButton();
35163   if(clearButton)
35164    this.ChangeButtonEnabledAttributes(clearButton, this.GetChangeButtonEnabledAttributesMethod(enabled));
35165  },
35166  GetChangeButtonEnabledAttributesMethod: function(enabled) {
35167   return dx.BootstrapClientUtils.GetChangeButtonEnabledAttributesMethod(enabled);
35168  },
35169  ChangeButtonEnabledAttributes: function(element, method) {
35170   if(ASPx.Attr.IsExistsAttribute(element, "disabledOnServer"))
35171    return;
35172   method(element, ASPx.BootstrapCssSelectors.Disabled);
35173  },
35174  createDropDownCommandButtonClientInstance: function(pc, cmd) {
35175   var buttonElement = this.GetMainElement().querySelector("[data-toggle=dropdown-" + cmd.toLowerCase() + "]");
35176   if(buttonElement) {
35177    var clientInstance = new dx.BootstrapClientButton(this.name + "_" + cmd);
35178    clientInstance.mainElement = buttonElement;
35179    return clientInstance;
35180   }
35181   return null;
35182  },
35183  GetControlCell: function() {
35184   return this.GetInputContainerElement();
35185  },
35186  EnsureControlCellStylesLoaded: function() { },
35187  ClearControlCellStyles: function() { },
35188  RestoreControlCellStyles: function() { },
35189  GetElementRequiredForErrorFrame: function() {
35190   return this.GetInputContainerElement();
35191  },
35192  GetErrorImage: function() {
35193   return this.feedbackRenderHelper.getErrorImage();
35194  },
35195  UpdateErrorText: function() {
35196   this.feedbackRenderHelper.updateErrorText();
35197  },
35198  ChangeErrorCellVisibility: function(visible, useVisibilityAttribute) {
35199   this.feedbackRenderHelper.setErrorControlVisible(visible);
35200  },
35201  PopulateStyleDecorationPostfixes: function() {
35202   var inputContainerSelector = this.GetInputContainerSelector();
35203   this.styleDecoration.AddPostfix("");
35204   this.styleDecoration.AddPostfix(inputContainerSelector);
35205   this.styleDecoration.AddPostfix(inputContainerSelector + " .form-control");
35206  },
35207  GetInputContainerSelector: function() {
35208   var selector = "";
35209   if(!!this.GetInputGroupElement())
35210    selector = ".input-group";
35211   else {
35212    var invalidSelectors = ASPx.Data.GetDistinctArray([DROPDOWN_AREA_SELECTOR,
35213     "." + ASPx.BootstrapCssSelectors.InputGroupAppendButton, "." + ASPx.BootstrapCssSelectors.InputGroupPrependButton]);
35214    selector = "div";
35215    for(var i = 0; i < invalidSelectors.length; i++)
35216     selector += ":not(" + invalidSelectors[i] + ")";
35217   }
35218   return selector;
35219  },
35220  CreateStyleDecoration: function() {
35221   return new ASPx.BootstrapEditorStyleDecoration(this);
35222  },
35223  GetPopupControl: function() {
35224   return null;
35225  },
35226  GetDropDownDivContainer: function() {
35227   return null;
35228  },
35229  GetDropDownItemImageCell: function() {
35230   return null;
35231  },
35232  GetHideContentCssClassName: function() {
35233   return ASPx.BootstrapCssSelectors.Hidden;
35234  },
35235  GetHoverElementToShowClearButton: function() {
35236   return this.GetInputGroupElement() || this.GetInputContainerElement();
35237  },
35238  GetInputGroupElement: function() {
35239   var mainElement = this.GetMainElement();
35240   return mainElement && mainElement.querySelector(".input-group");
35241  },
35242  GetInputContainerElement: function() {
35243   var container = this.GetMainElement().querySelector(INPUT_CONTAINER_SELECTOR);
35244   if(container == null) {
35245    var inputElement = this.GetInputElement();
35246    if(inputElement)
35247     container = inputElement.parentNode;
35248   }
35249   return container;
35250  },
35251  GetModalElement: function() {
35252   return ASPx.GetChildByClassName(this.GetMainElement(), MODAL_CLASS);
35253  },
35254  GetModalElementBackground: function() {
35255   return ASPx.GetChildByClassName(this.GetMainElement(), MODAL_BACKGROUND_CLASS);
35256  },
35257  GetModalInputContainerElement: function() {
35258   var modalElement = this.GetModalElement();
35259   return modalElement ? modalElement.querySelector("." + MODAL_INPUT_CONTAINER_CLASS) : null;
35260  },
35261  getInputCell: function() {
35262   return this.GetInputElement();
35263  },
35264  GetCaptionCell: function() {
35265   return ASPx.CacheHelper.GetCachedElement(this, "captionElement",
35266    function() {
35267     var mainElement = this.GetMainElement();
35268     return mainElement && mainElement.querySelector(".dxbs-edit-caption");
35269    }
35270   );
35271  },
35272  getCaptionTextNode: function() {
35273   return ASPx.GetNormalizedTextNode(this.GetCaptionCell());
35274  },
35275  getCaptionRelatedCellCount: function() {
35276   return undefined;
35277  },
35278  GetDropDownButton: function() {
35279   var inputGroupElement = this.GetInputGroupElement();
35280   return inputGroupElement && inputGroupElement.querySelector(DROPDOWN_SELECTOR);
35281  },
35282  GetClearButton: function() {
35283   return this.feedbackRenderHelper.getClearButton();
35284  },
35285  GetButton: function(number) {
35286   switch(number) {
35287    case this.dropDownButtonIndex:
35288     return this.GetDropDownButton();
35289    case -100: 
35290     return this.GetClearButton();
35291    default:
35292     var inputGroupButton = ASPxClientDateEdit.prototype.GetButton.call(this, number);
35293     return inputGroupButton && (inputGroupButton.querySelector(".dxbs-edit-btn") || inputGroupButton.querySelector(".btn") || inputGroupButton);
35294   }
35295  },
35296  GetDropDownInnerControlName: function(suffix) {
35297   return this.name + suffix;
35298  },
35299  ChangeEnabledStateItems: function(enabled) { },
35300  AdjustControls: function() { },
35301  AdjustTimeSectionLayout: function() { },
35302  AdjustDropDownWindow: function() { },
35303  GetDropDownIsWindowElement: function(id, pcPostfix) {
35304   return null;
35305  },
35306  GetElementIsDropDownParent: function(element) {
35307   return ASPx.ElementHasCssClass(element, "dxbs-dropdown-edit") && ASPx.Attr.IsExistsAttribute(element, "id") 
35308    ? ASPx.GetDropDownCollection().Get(ASPx.Attr.GetAttribute(element, "id")) : null;
35309  },
35310  GetDropDownWindow: function() {
35311   return this.getDropDownArea();
35312  },
35313  OnBrowserWindowResizeInternal: function(e) {
35314   this.UpdateDropDownPosition();
35315  },
35316  EnableStyleControllerForDDButton: function() { },
35317  DisableStyleControllerForDDButton: function() { },
35318  OnMainCellMouseDown: function(evt) {
35319   if(!ASPx.ElementHasCssClass(this.GetInputElement().parentNode, MODAL_INPUT_CONTAINER_CLASS))
35320    ASPxClientDateEdit.prototype.OnMainCellMouseDown.call(this, evt);
35321  },
35322  GetViewContainer: function() {
35323   var dropDownArea = this.getDropDownArea();
35324   if(!dropDownArea)
35325    return null;
35326   if(!this.viewContainer)
35327    this.viewContainer = dropDownArea.querySelector(".modal-body > div:not(." + MODAL_INPUT_CONTAINER_CLASS + ")");
35328   return this.viewContainer;
35329  },
35330  getDropDownArea: function() {
35331   var mainElement = this.GetMainElement();
35332   return mainElement ? mainElement.querySelector(DROPDOWN_AREA_SELECTOR) : null;
35333  },
35334  getPopupOriginElement: function() {
35335   return this.GetInputGroupElement() || this.GetInputContainerElement();
35336  },
35337  getPopupElements: function() {
35338   return [this.getDropDownArea(), this.getPopupOriginElement()];
35339  },
35340  ShowDropDownArea: function(isRaiseEvent, forceSize) {
35341   this.UpdateActiveController();
35342   this.GetActiveController().OnBeforeShowDropDown(this.date);
35343   this.SetPCIsShowingNow(true);
35344   ASPx.GetDropDownCollection().RegisterDroppedDownControl(this, this.GetDropDownParents());
35345   this.RaiseDropDownEventRequired = isRaiseEvent;
35346   this.SetModalElementVisibility(true);
35347   if(this.isDropDownModalRequired())
35348    this.SetModalInputVisible(true);
35349   ASPx.BootstrapPopupManager.registerVisiblePopup(this.getPopupElements(), function() {
35350    this.SetModalElementVisibility(false);
35351    this.SetModalInputVisible(false);
35352   }.aspxBind(this));
35353   ASPx.Attr.Aria.SetExpanded(this.GetDropDownButton(), true);
35354   this.droppedDown = true;
35355   this.lockClosing = false;
35356   this.OnPopupControlShown();
35357   this.GetActiveController().OnAfterShowDropDown();
35358   this.UpdateDropDownPosition();
35359  },
35360  HideDropDownArea: function(isRaiseEvent) {
35361   if(this.lockClosing || !this.droppedDown || !this.RaiseQueryCloseUp())
35362    return;
35363   var calendar = this.GetCalendar();
35364   if(calendar)
35365    calendar.EnsureHideFastNavigation();
35366   this.DropDownButtonPop();
35367   ASPx.GetDropDownCollection().UnregisterDroppedDownControl(this);
35368   ASPx.BootstrapPopupManager.unregisterVisiblePopup(this.getPopupElements());
35369   ASPx.Attr.Aria.SetExpanded(this.GetDropDownButton(), false);
35370   if(isRaiseEvent)
35371    this.RaiseCloseUp();
35372   this.droppedDown = false;
35373  },
35374  IsAdaptiveTimeSectionEnabled: function() {
35375   return false;
35376  },
35377  CreateScrollPickerController: function(spOptions) {
35378   return new BootstrapDateEditScrollPickerController(this, spOptions);
35379  },
35380  UpdateDropDownPosition: function() {
35381   var dropDownArea = this.getDropDownArea();
35382   if(dropDownArea) {
35383    var isDisplayed = ASPx.GetElementDisplay(dropDownArea);
35384    var needPositionCorrection = isDisplayed;
35385    var modalElement = this.GetModalElement();
35386    if(modalElement && this.ddmBP) {
35387     var currentModeIsModal = ASPx.ElementHasCssClass(modalElement, ASPx.BootstrapCssSelectors.Modal);
35388     if(isDisplayed)
35389      this.ToggleModalMode(this.isDropDownModalRequired());
35390     var modeChanged = currentModeIsModal != ASPx.ElementHasCssClass(modalElement, ASPx.BootstrapCssSelectors.Modal);
35391     if(modeChanged) {
35392      ASPx.SetElementDisplay(modalElement, isDisplayed);
35393      var modalModeEnabled = !currentModeIsModal;
35394      this.UpdateActiveController();
35395      this.GetActiveController().onDropDownModalChanged(modalModeEnabled);
35396      this.SetModalInputVisible(modalModeEnabled);
35397     }
35398     needPositionCorrection &= currentModeIsModal == modeChanged;
35399    }
35400    if(needPositionCorrection) {
35401     if(this.dropDownAutoWidth)
35402      dropDownArea.style.width = this.getPopupOriginElement().offsetWidth + "px";
35403     ASPx.BootstrapPopupManager.correctPopupPositionForClientWindow(this.getPopupElements(), "LeftSides", 0, "Below", -ASPx.GetClientTop(this.getPopupOriginElement()));
35404    }
35405   }
35406  },
35407  UpdateDropDownOnFeedbackChanged: function() {
35408   this.UpdateDropDownPosition();
35409  },
35410  SetModalElementVisibility: function(visible) {
35411   var modalElement = this.GetModalElement();
35412   if(modalElement) {
35413    ASPx.SetElementDisplay(modalElement, visible);
35414    var background = this.GetModalElementBackground();
35415    (visible ? ASPx.AddClassNameToElement : ASPx.RemoveClassNameFromElement)(background, "show");
35416   }
35417  },
35418  ToggleModalMode: function(enabled) {
35419   ASPx.ToggleClassNameToElement(this.GetModalElement(), ASPx.BootstrapCssSelectors.Modal, enabled);
35420   ASPx.ToggleClassNameToElement(this.GetModalElementBackground(), "show", enabled);
35421  },
35422  SetModalInputVisible: function(visible) {
35423   var modalElement = this.GetModalElement();
35424   if(!modalElement)
35425    return;
35426   if(this.ddmInput) {
35427    var inputElement = this.GetInputElement();
35428    var inputContainer = this.GetInputContainerElement();
35429    if(visible) {
35430     var modalInputContainer = this.GetModalInputContainerElement();
35431     modalInputContainer.appendChild(inputElement);
35432     if(this.focusedNullTextElement)
35433      modalInputContainer.appendChild(this.focusedNullTextElement);
35434     ASPx.AddClassNameToElement(inputContainer, ASPx.BootstrapCssSelectors.FormControl);
35435     this.initializeDropDownModalClearButton(modalInputContainer);
35436     if(this.dropDownModalClearButton)
35437      this.EnsureClearButtonVisibility();
35438     this.ensureDropDownModalInputVisibility(modalInputContainer);
35439    }
35440    else if(this.isDropDownModalRequired()) {
35441     ASPx.RemoveClassNameFromElement(inputContainer, ASPx.BootstrapCssSelectors.FormControl);
35442     inputContainer.insertBefore(inputElement, inputContainer.firstChild);
35443     if(this.focusedNullTextElement)
35444      inputContainer.appendChild(this.focusedNullTextElement);
35445    }
35446   }
35447  },
35448  ensureDropDownModalInputVisibility: function(inputContainer) {
35449   if(!inputContainer && this.ddmInput)
35450    inputContainer = this.GetModalInputContainerElement();
35451   if(inputContainer)
35452    ASPx.ToggleClassNameToElement(inputContainer, ASPx.BootstrapCssSelectors.Hidden, this.GetReadOnly() || !this.GetEnabled());
35453  },
35454  getDropDownModalClearButtonSelector: function() {
35455   return MODAL_INPUT_CLEARBUTTON_SELECTOR;
35456  },
35457  helpTextInitialize: function() {
35458   if(this.helpText)
35459    this.helpTextObj = new ASPx.BootstrapTextEditHelpText(this, this.helpText, this.enableHelpTextPopupAnimation, this.hasPopupHelpText());
35460  },
35461  GetHelpTextElementPrevSibling: function() {
35462   var errorTextElement = this.feedbackRenderHelper.getErrorTextElement();
35463   return errorTextElement || this.GetInputGroupElement() || this.GetInputContainerElement();
35464  },
35465  getFocusedNullTextElementClassName: function() {
35466   return "dxbs-null-text text-muted" + (this.cssClasses.nt ? " " + this.cssClasses.nt : "");
35467  },
35468  GetRangeLength: function() {
35469   return ASPxClientDateEdit.prototype.GetRangeLength.call(this);
35470  }
35471 });
35472 var BootstrapDateEditScrollPickerController = ASPx.CreateClass(ASPx.DateEditScrollPickerController, {
35473  createRollerView: function(container, itemsInfo, itemsValue, id, isComboBoxList, caption) {
35474   return new dx.BootstrapDateEditRollersView(this, container, itemsInfo, itemsValue, id, isComboBoxList, caption);
35475  },
35476  createWheels: function() {
35477   ASPx.DateEditScrollPickerController.prototype.createWheels.call(this);
35478   var container = this.GetViewContainer();
35479   if(container) {
35480    if(this.groups.length > 1) {
35481     var navElement = document.createElement("nav");
35482     container.insertBefore(navElement, container.firstChild);
35483     var tabsElement = document.createElement("div");
35484     navElement.appendChild(tabsElement);
35485     tabsElement.className = "nav nav-tabs nav-justified dx-accent-color";
35486     this.groups.forEach(function(g, index) {
35487      var tabElement = document.createElement("a");
35488      tabElement.href = ASPx.AccessibilityEmptyUrl;
35489      tabsElement.appendChild(tabElement);
35490      tabElement.className = "nav-item nav-link";
35491      var textElement = document.createElement("span");
35492      tabElement.appendChild(textElement);
35493      var textNode = document.createTextNode(index == 0 ? "Date" : "Time");
35494      textElement.appendChild(textNode);
35495      ASPx.Evt.AttachEventToElement(tabElement, "click", function(evt) { this.setActiveGroupElement(index); }.aspxBind(this));
35496     }.aspxBind(this));
35497    }
35498   }
35499  },
35500  setActiveGroupElement: function(activeIndex) {
35501   var container = this.GetViewContainer();
35502   if(container) {
35503    var tabElements = ASPx.NodeListToArray(container.querySelectorAll("nav > .nav-tabs > .nav-item"));
35504    var groupElements = ASPx.NodeListToArray(container.querySelectorAll(".tab-content > .tab-pane"));
35505    if(tabElements.length) {
35506     tabElements.forEach(function(tabElement, index) {
35507      var isActive = index == activeIndex;
35508      var selectedDate = this.processDate ? null : this.GetSelectedDate();
35509      ASPx.ToggleClassNameToElement(tabElement, "active", isActive);
35510      ASPx.SetElementDisplay(groupElements[index], isActive, true);
35511      if(isActive && selectedDate) {
35512       this.SetSelectedDate(selectedDate);
35513      }
35514     }.aspxBind(this));
35515     if(!container.style.minWidth)
35516      container.style.minWidth = container.offsetWidth + "px";
35517    }
35518   }
35519  },
35520  createWheelGroupElement: function(container) {
35521   var groupElement = document.createElement("div");
35522   groupElement.className = this.GetGroupElementClassName();
35523   var hasSeveralGroups = this.groups.length > 1;
35524   if(hasSeveralGroups) {
35525    var tabContentContainer = container.querySelector(".tab-content");
35526    if(!tabContentContainer) {
35527     tabContentContainer = document.createElement("div");
35528     tabContentContainer.className = "tab-content";
35529     container.appendChild(tabContentContainer);
35530    }
35531    groupElement.className += " tab-pane";
35532    tabContentContainer.appendChild(groupElement);
35533   }
35534   else
35535    container.appendChild(groupElement);
35536   return groupElement;
35537  },
35538  GetControllerClassName: function() {
35539   return SCROLL_PICKER_CLASS_NAME;
35540  },
35541  GetSampleItemRow: function() {
35542   var row = ASPx.DateEditScrollPickerController.prototype.GetSampleItemRow.call(this);
35543   row.className += " list-group-item";
35544   return row;
35545  },
35546  OnAfterShowDropDown: function() {
35547   ASPx.DateEditScrollPickerController.prototype.OnAfterShowDropDown.call(this);
35548   this.setActiveGroupElement(0);
35549  }
35550 });
35551 var DROPDOWN_SELECTOR = "[data-toggle=dropdown-show]",
35552  DROPDOWN_AREA_SELECTOR = ".dxbs-dropdown-area",
35553  INPUT_CONTAINER_SELECTOR = ".dxbs-input-cntr",
35554  MODAL_INPUT_CONTAINER_CLASS = "dxbs-modal-input-cntr",
35555  MODAL_INPUT_CLEARBUTTON_SELECTOR = ".dxbs-modal-clear-btn",
35556  MODAL_CLASS = "dxbs-ddmodal",
35557  MODAL_BACKGROUND_CLASS = "dxbs-ddmodal-back",
35558  BS_OUT_OF_RANGE_WARNING_CLASS_NAME = "dxbs-out-of-range-warn text-danger mark",
35559  SCROLL_PICKER_CLASS_NAME = "dxbs-scroll-picker";
35560 dx.BootstrapClientDateEdit = BootstrapClientDateEdit;
35561})(dx || (dx = {}));
35562
35563(function() {
35564ASPx.activeCalendar = null;
35565ASPx.calendarMsPerDay = 86400000;
35566var calendarWeekCount = 6;
35567var viewsContainerClassName = "dxeCVC";
35568var emptyDateCellClassName = "dxeEmptyDC";
35569var ASPxClientCalendar = ASPx.CreateClass(ASPxClientEdit, {
35570 constructor: function(name) {
35571  this.constructor.prototype.constructor.call(this, name);
35572  this.SelectionChanging = new ASPxClientEvent();
35573  this.SelectionChanged = new ASPxClientEvent();
35574  this.VisibleMonthChanged = new ASPxClientEvent();
35575  this.CustomDisabledDate = new ASPxClientEvent();
35576  this.CellClick = new ASPxClientEvent();
35577  this.isMouseDown = false;  
35578  this.forceMouseDown = false;
35579  this.supportGestures = true;
35580  this.swipeGestureStated = false;
35581  this.updateAnimationProcessing = false;
35582  this.selection = new ASPxClientCalendarSelection();
35583  this.selectionTransaction = null;  
35584  this.selectionStartDate = null;
35585  this.selectionPrevStartDate = null;
35586  this.lastSelectedDate = null;
35587  this.selectionCtrl = false;
35588  this.selectionByWeeks = false;  
35589  this.titleFormatter = null;
35590  this.updateAnimationLockCount = 0;
35591  this.forceUpdate = false;
35592  this.needToSetCursor = true;
35593  this.visibleDate = new Date();
35594  this.visibleDates = {};
35595  this.selectedNavigationDates = {};
35596  this.firstDayOfWeek = 0;    
35597  this.columns = 1;
35598  this.rows = 1;
35599  this.switchToSingleMonthAtWindowInnerWidth = 0;
35600  this.enableFast = true;
35601  this.showFastPopup = false;
35602  this.pickerType = ASPx.DatePickerType.Days;
35603  this.maxViewType = ASPx.DatePickerType.Decades;
35604  this.initialViewType = ASPx.DatePickerType.Days;
35605  this.enableFastNavInlineAnimation = true;
35606  this.enableMulti = false;
35607  this.customDraw = false;  
35608  this.showWeekNumbers = true;
35609  this.showDayHeaders = true;
35610  this.isDateEditCalendar = false;
35611  this.sharedParameters = new ASPx.CalendarSharedParameters();
35612  this.visibleDateColumnOffset = 0;
35613  this.enableDaysViewPeriodNavigation = true;
35614  this.enableMonthsYearsViewPeriodNavigation = true;
35615  this.accessibilityHelper = null;
35616  this.sizingConfig.allowSetHeight = false;
35617  this.isDateChangingByKeyboard = false;
35618  this.MainElementClick = new ASPxClientEvent();
35619 },
35620 SetData: function(data){
35621  ASPxClientEdit.prototype.SetData.call(this, data);
35622  if(data.selection)
35623   this.selection.AddArray(data.selection);
35624  if(data.sharedParameters)
35625   this.SetProperties(data.sharedParameters, this.sharedParameters);
35626 },
35627 SetProperties: function(properties, obj) {
35628  ASPxClientEdit.prototype.SetProperties.call(this, properties, obj);
35629  this.selection.SetPickerType(this.pickerType);
35630 },
35631 Initialize: function() {
35632  this.selectionTransaction = new ASPxClientCalendarSelectionTransaction(this);
35633  this.selectionPrevStartDate = this.selection.GetFirstDate();
35634  ASPxClientEdit.prototype.Initialize.call(this);
35635  var mainElement = this.GetMainElement();
35636  ASPx.Evt.PreventElementDragAndSelect(mainElement, false, false);
35637  if(ASPx.Browser.Opera && !ASPx.Browser.WebKitFamily)
35638   ASPx.Selection.SetElementAsUnselectable(mainElement, true, true);
35639  this.EnsureTodayStyle();
35640  if(this.accessibilityCompliant)
35641   this.accessibilityHelper = new AccessibilityHelperCalendar(this);
35642 },
35643 InlineInitialize: function() {
35644  this.customDraw = this.sharedParameters.calendarCustomDraw;
35645  for(var i = this.pickerType; i <= this.maxViewType; i++) {
35646   this.visibleDates[i] = this.visibleDate;
35647   this.selectedNavigationDates[i] = this.visibleDate;
35648  }
35649  this.currentViewType = this.pickerType;
35650  this.CreateViews();
35651  if(this.NeedFastNavigation())
35652   this.InitializeFastNavigation();
35653  if(this.isSlideCallbackAnimationEnabled() && !this.isSwipeGesturesEnabled() && this.AnimationHelperExists())
35654   ASPx.AnimationHelper.getSlideAnimationContainer(this.GetCallbackAnimationElement(), true, false);
35655  ASPxClientEdit.prototype.InlineInitialize.call(this);
35656  if(!this.CustomDisabledDate.IsEmpty())
35657   this.Update();
35658  this.SetInitialVisibleDate();
35659  this.CreateAdaptivityCssRules();
35660  if(!this.isDateEditCalendar)
35661   this.SwitchToInitialView();
35662 },
35663 UseSpecialKeyboardHandling: function() {
35664  return true;
35665 },
35666 SwitchToInitialView: function() {
35667  if(this.pickerType !== this.initialViewType)
35668   this.SwitchToGreaterView(0, 0, this.initialViewType, true);
35669 },
35670 AddActiveViewHoverStateItems: function() {
35671  var activeViews = this.GetActiveViews();
35672  for(var key in activeViews) {
35673   if(activeViews.hasOwnProperty(key)) {
35674    var view = activeViews[key];
35675    view.AddHoverStateItems();
35676   }
35677  }
35678 },
35679 RemoveActiveViewHoverStateItems: function() {
35680  var activeViews = this.GetActiveViews();
35681  for(var key in activeViews) {
35682   if(activeViews.hasOwnProperty(key)) {
35683    var view = activeViews[key];
35684    view.RemoveHoverStateItems();
35685   }
35686  }
35687 },
35688 NeedFastNavigation: function() {
35689  return this.showFastPopup;
35690 },
35691 InitializeFastNavigation: function() {
35692  this.fastNavigation = this.CreateFastNavigation();
35693 },
35694 InitializeEvents: function() { 
35695  ASPxClientEdit.prototype.InitializeEvents.call(this);
35696  var clear = this.GetClearButton();
35697  if(clear)
35698   ASPx.Evt.AttachEventToElement(clear, "click", this.OnClearClick.bind(this));
35699  var today = this.GetTodayButton();
35700  if(today)
35701   ASPx.Evt.AttachEventToElement(today, "click", this.OnTodayClick.bind(this));
35702  if(this.isDateEditCalendar) {
35703   var ok = this.GetTimeSectionOkButton();
35704   if(ok)
35705    ASPx.Evt.AttachEventToElement(ok, "click", this.OnOkClick.bind(this));
35706   var cancel = this.GetTimeSectionCancelButton();
35707   if(cancel)
35708    ASPx.Evt.AttachEventToElement(cancel, "click", this.OnCancelClick.bind(this));
35709  }
35710 },
35711 CreateAdaptivityCssRules: function() {
35712  if (this.switchToSingleMonthAtWindowInnerWidth <= 0)
35713   return;
35714  var styleSheet = ASPx.GetCurrentStyleSheet();
35715  if (!styleSheet || !styleSheet.insertRule) return;
35716  var lastColumn = this.columns - 1;
35717  var rule =
35718  "@media all and (max-width: " + this.switchToSingleMonthAtWindowInnerWidth + "px) { " +
35719   "#" + this.name + ".dxeCVC > tbody > tr > td:not(.view-visible):not(#" + this.name + "_F) > * { display: none; }" +
35720   "#" + this.name + " .dxeCVC > tbody > tr > td:not(.view-visible):not(#" + this.name + "_F) > * { display: none; }" +
35721   ".view-visible #" + this.name + "_" + this.GetArrowButtonID("M", true, "0x0") + "," +
35722   ".view-visible #" + this.name + "_" + this.GetArrowButtonID("M", false, "0x" + lastColumn) + "," +
35723   ".view-visible #" + this.name + "_" + this.GetArrowButtonID("Y", true, "0x0") + "," +
35724   ".view-visible #" + this.name + "_" + this.GetArrowButtonID("Y", false, "0x" + lastColumn) + "," +
35725   ".view-visible #" + this.name + "_" + this.GetArrowButtonID("TP", true, "0x0") + "," +
35726   ".view-visible #" + this.name + "_" + this.GetArrowButtonID("TP", false, "0x" + lastColumn) +
35727    " { visibility: visible!important; } " +
35728   "}";
35729  styleSheet.insertRule(rule, styleSheet.cssRules.length);
35730 },
35731 OnNavigationImageClick: function(offset, isVisibleInAdaptiveOnly) {
35732  if(!isVisibleInAdaptiveOnly || (this.switchToSingleMonthAtWindowInnerWidth > 0 && window.innerWidth <= this.switchToSingleMonthAtWindowInnerWidth))
35733   this.OnShiftMonth(offset);
35734 },
35735 SetInitialVisibleDate: function() {
35736  this.initialVisibleDate = this.GetVisibleDate();
35737 },
35738 EnsureTodayStyle: function() {
35739  if(!ASPxClientCalendar.AreDatesEqual(this.serverCurrentDate, new Date())) {
35740   var activeViews = this.GetActiveViews();
35741   for(var key in activeViews) {
35742    if(activeViews.hasOwnProperty(key)) {
35743     var view = activeViews[key];
35744     view.EnsureTodayStyle();
35745    }
35746   }
35747  }
35748 },
35749 CreateFastNavigation: function() {
35750  return new ASPxClientCalendarFastNavigation(this);
35751 },
35752 GetCalendarRowElements: function() {
35753  if(!this.viewsContainer) {
35754   var mainElement = this.GetMainElement();
35755   var mainElementIsViewsContainer = ASPx.ElementHasCssClass(this.GetMainElement(), viewsContainerClassName);
35756   this.viewsContainer = mainElementIsViewsContainer ? mainElement : ASPx.GetNodeByClassName(mainElement, viewsContainerClassName);
35757  }
35758  return this.viewsContainer.rows;
35759 },
35760 GetCalendarViewCellElements: function(rowElement) {
35761  return rowElement.cells;
35762 },
35763 GetMonthTable: function(viewIdPostfix) {
35764  return this.GetChildElement("mt" + viewIdPostfix);
35765 },
35766 GetYearCell: function(viewIdPostfix) {
35767  return this.GetChildElement("yc" + viewIdPostfix);
35768 },
35769 GetYearCellChildArea: function(viewIdPostfix) {
35770  return this.GetChildElement("yt" + viewIdPostfix);
35771 },
35772 GetMonthCell: function(viewIdPostfix) {
35773  return this.GetChildElement("mc" + viewIdPostfix);
35774 },
35775 GetViewCell: function(viewIdPostfix) {
35776  if (this.switchToSingleMonthAtWindowInnerWidth <= 0)
35777   throw new Error("Not Implemented");
35778  return this.GetChildElement("v" + viewIdPostfix);
35779 },
35780 GetFastNavHeader: function(viewIdPostfix) {
35781  return this.GetChildElement("FNH" + viewIdPostfix);
35782 },
35783 GetFastNavHeaderTextElement: function(viewIdPostfix) {
35784  return this.GetChildElement("yt" + viewIdPostfix);
35785 },
35786 GetArrowButton: function(type, isNext, viewID) {
35787  return this.GetChildElement(this.GetArrowButtonID(type, isNext, viewID));
35788 },
35789 GetArrowButtonID: function(type, isNext, viewID) {
35790  var id = (isNext ? "N" : "P") + type.toUpperCase() + "C";
35791  if(this.IsMultiView() && viewID === undefined)
35792   id += "_0x" + (isNext ? this.columns - 1 : 0);
35793  else if (viewID)
35794   id += "_" + viewID;
35795  return id + "Img";
35796 },
35797 SetMonthTableCellContent: function(cell, content, isWeekNumber) {
35798  cell.innerHTML = content;
35799 },
35800 FindInputElement: function() {
35801  return this.accessibilityCompliant ? this.GetAccessibilityAssistantElement() : this.GetChildElement("KBS");
35802 },
35803 GetAccessibilityActiveElements: function() {
35804  return this.accessibilityCompliant ? [this.accessibilityHelper.GetActiveElement()] : [this.GetInputElement()];
35805 },
35806 GetClearButton: function() {
35807  return this.GetChildElement("BC");
35808 },
35809 GetTodayButton: function() {
35810  return this.GetChildElement("BT");
35811 },
35812 GetTimeSectionOkButton: function() {
35813  return this.GetChildElement("BO");
35814 },
35815 GetTimeSectionCancelButton: function() {
35816  return this.GetChildElement("BCN");
35817 },
35818 GetFooter: function() {
35819  return this.GetChildElement("F");
35820 },
35821 GetValue: function() {
35822  return this.selection.GetFirstDate();
35823 },
35824 GetValueString: function() {
35825  var value = this.GetValue();
35826  return value == null ? null : ASPx.DateUtils.GetInvariantDateString(value);
35827 },
35828 SetValue: function(date) {  
35829  if(date) {
35830   date = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(date);
35831   date = ASPxClientCalendar.GetCorrectedDate(date, this.pickerType);
35832   this.SetVisibleDate(date);
35833  }
35834  this.SetSelectedDate(date);
35835 },
35836 GetViewKey: function(row, column) {
35837  return row + "x" + column;
35838 },
35839 GetView: function(row, column, viewType) {
35840  if(!ASPx.IsExists(viewType))
35841   return this.GetActiveView(row, column);
35842  var key = this.GetViewKey(row, column);
35843  return this.GetViewByKey(viewType, key);
35844 },
35845 GetViewByKey: function(viewType, key) {
35846  return this.views[viewType][key];
35847 },
35848 GetActiveView: function(row, column) {
35849  var key = this.GetViewKey(row, column);
35850  return this.GetActiveViews()[key];
35851 },
35852 GetActiveViews: function() {
35853  return this.GetViews(this.currentViewType);
35854 },
35855 GetViews: function(viewType) {
35856  return this.views[viewType];
35857 },
35858 CreateViews: function() {
35859  this.views = { };
35860  var key;
35861  for(var i = this.pickerType; i <= this.maxViewType; i++) {
35862   if(i == this.pickerType)
35863    this.visibleDates[i] = this.visibleDate;
35864   this.views[i] = {};
35865   for(var row = 0 ; row < this.rows; row++) {
35866    for(var col = 0; col < this.columns; col++) {
35867     key = this.GetViewKey(row, col);
35868     var view = this.CreateView(i, row, col);
35869     view.Initialize();
35870     this.views[i][key] = view;
35871    }
35872   }
35873  }
35874  if (this.switchToSingleMonthAtWindowInnerWidth)
35875   this.GetActiveViews()["0x0"].EnsureVisible(true);
35876 },
35877 CreateView: function(viewType, row, column) {
35878  switch(viewType) {
35879   case ASPx.DatePickerType.Days:
35880    return new ASPxClientCalendarDaysView(this, row, column);
35881   case ASPx.DatePickerType.Months:
35882    return new ASPxClientCalendarMonthsView(this, row, column);
35883   case ASPx.DatePickerType.Years:
35884    return new ASPxClientCalendarYearsView(this, row, column);
35885   case ASPx.DatePickerType.Decades:
35886    return new ASPxClientCalendarDecadesView(this, row, column);
35887  }
35888 },
35889 ChangeView: function(newViewType, disableAnimation) {
35890  var needChangeMonthYearCellVisibility = this.currentViewType == ASPx.DatePickerType.Days || newViewType == ASPx.DatePickerType.Days;
35891  var needUpdateHoverStateItems = this.NeedUpdateHoverStateItemsOnViewChanging(this.currentViewType, newViewType);
35892  if(needUpdateHoverStateItems)
35893   this.RemoveActiveViewHoverStateItems();
35894  this.currentViewType = newViewType;
35895  if(needUpdateHoverStateItems)
35896   this.AddActiveViewHoverStateItems();
35897  if(needChangeMonthYearCellVisibility)
35898   this.ChangeMonthYearCellVisibility(newViewType == ASPx.DatePickerType.Days);
35899  if(this.enableFastNavInlineAnimation && !disableAnimation)
35900   this.PerformActiveViewAnimation();
35901  this.Update();
35902  ASPx.SetElementDisplay(this.GetClearButton(), !this.IsInlineFastNavigationActive());
35903 },
35904 NeedUpdateHoverStateItemsOnViewChanging: function(oldViewType, newViewType) {
35905  return this.pickerType !== ASPx.DatePickerType.Days && (oldViewType === this.pickerType || newViewType === this.pickerType);
35906 },
35907 PerformActiveViewAnimation: function() {
35908  var activeViews = this.GetActiveViews();
35909  for(var key in activeViews) {
35910   if(activeViews.hasOwnProperty(key)) {
35911    var view = activeViews[key];
35912    ASPx.AnimationHelper.fadeIn(view.GetMainElement());
35913   }
35914  }
35915 },
35916 ChangeMonthYearCellVisibility: function(showMonthCell) {
35917  var activeViews = this.GetActiveViews();
35918  for(var key in activeViews) {
35919   if(activeViews.hasOwnProperty(key)) {
35920    this.ChangeViewMonthYearCellVisibility(key, showMonthCell);
35921   }
35922  }
35923  var spacers = ASPx.GetNodesByClassName(this.GetMainElement(), "dxeCHS");
35924  spacers.forEach(function(spacer) { this.SetElementVisible(spacer, showMonthCell); }.aspxBind(this));
35925 },
35926 ChangeViewMonthYearCellVisibility: function(key, showMonthCell) {
35927  var monthView = this.GetViewByKey(ASPx.DatePickerType.Days, key);
35928  var yearView = this.GetViewByKey(ASPx.DatePickerType.Months, key);
35929  var monthViewMainElement = monthView.GetMainElement();
35930  var yearViewMainElement = yearView.GetMainElement();
35931  if(!showMonthCell) {
35932   yearViewMainElement.style.width = monthViewMainElement.offsetWidth + "px";
35933   yearViewMainElement.style.height = monthViewMainElement.offsetHeight + "px";
35934  }
35935  this.SetElementVisible(monthViewMainElement, showMonthCell);
35936  this.SetElementVisible(yearViewMainElement, !showMonthCell);
35937  this.SetViewMainElementParentsVisibility(monthViewMainElement, yearViewMainElement, showMonthCell);
35938  var monthViewNavigationCells = monthView.GetNavigationCells();
35939  var yearViewNavigationCells = yearView.GetNavigationCells();
35940  for(var i = 0; i < monthViewNavigationCells.length; i++)
35941   if(monthViewNavigationCells[i])
35942    this.SetElementVisible(monthViewNavigationCells[i], showMonthCell);
35943  for(var i = 0; i < yearViewNavigationCells.length; i++)
35944   if(yearViewNavigationCells[i])
35945    this.SetElementVisible(yearViewNavigationCells[i], !showMonthCell);
35946 },
35947 SetViewMainElementParentsVisibility: function(monthViewMainElement, yearViewMainElement, showMonthCell) {
35948  this.SetElementVisible(monthViewMainElement.parentNode, showMonthCell);
35949  this.SetElementVisible(yearViewMainElement.parentNode, !showMonthCell);
35950 },
35951 SetElementVisible: function(element, visible) {
35952  ASPx.SetElementDisplay(element, visible);
35953 },
35954 IsFastNavigationActive: function() {
35955  return this.IsPopupFastNavigationActive() || this.IsInlineFastNavigationActive();
35956 },
35957 IsPopupFastNavigationActive: function() {
35958  return this.fastNavigation && this.fastNavigation.IsActive();
35959 },
35960 IsInlineFastNavigationActive: function() {
35961  return this.currentViewType != this.pickerType;
35962 },
35963 IsDateSelected: function(date) {
35964  return this.selection.Contains(date);
35965 },
35966 IsDateVisible: function(date) {
35967  var startDate = ASPxClientCalendar.CloneDate(this.GetActiveView(0, 0).visibleDate);
35968  startDate.setDate(1);  
35969  var endDate = this.GetActiveView(this.rows - 1, this.columns - 1).GetMaxVisibleDate();
35970  return (date >= startDate) && (date < endDate);
35971 },
35972 IsDateWeekend: function(date) {
35973  var day = date.getDay();
35974  return day == 0 || day == 6;
35975 },
35976 IsCustomDisabledDatesViaCallback: function(){
35977  return (this.callBack && this.IsCustomDisabledDateEventEmpty() && this.sharedParameters.disabledDates.length > 0);
35978 },
35979 HasCallback: function () {
35980  if (this.isDateEditCalendar)
35981   return this.customDraw;
35982  else
35983   return this.callBack;
35984 },
35985 IsCustomDisabledDateEventEmpty: function() {
35986  if(this.isDateEditCalendar)
35987   return ASPxClientDateEdit.active == null || ASPxClientDateEdit.active.CalendarCustomDisabledDate.IsEmpty();
35988  return this.CustomDisabledDate.IsEmpty();
35989 },
35990 IsDateDisabled: function(date) {
35991  return ASPxClientCalendarDateDisabledHelper.IsDateDisabled(this.sharedParameters, date, function(d) { return this.OnCustomDisabledDate(d); }.aspxBind(this), this.currentViewType, this.pickerType);
35992 },
35993 IsMultiView: function() {
35994  return this.columns > 1 || this.rows > 1;
35995 },
35996 UpdateCustomDisabledDatesOnCallback: function(callbackResult) {
35997  var callbackDatesInfo = eval(callbackResult[callbackResult.length - 1]);
35998  this.RemoveVisibleDisabledDates(callbackDatesInfo);
35999  this.sharedParameters.disabledDates = this.sharedParameters.disabledDates
36000   .concat(callbackDatesInfo.disabledDates);
36001 },
36002 RemoveVisibleDisabledDates: function(callbackDatesInfo) {
36003  var firstVisibleDate = callbackDatesInfo.firstVisibleDate;
36004  var lastVisibleDate = callbackDatesInfo.lastVisibleDate;
36005  var currentVisibleDate = ASPxClientCalendar.CloneDate(firstVisibleDate);
36006  while(currentVisibleDate.getTime() <= lastVisibleDate.getTime()) {
36007   var disabledDateIndex = this.GetDisabledDateIndex(currentVisibleDate);
36008   if(disabledDateIndex > -1)
36009    this.sharedParameters.disabledDates.splice(disabledDateIndex, 1);
36010   currentVisibleDate = ASPxClientCalendar.GetNextDate(currentVisibleDate, this.pickerType);
36011  }
36012 },
36013 GetDisabledDateIndex: function(disabledDate) {
36014  return ASPx.Data.ArrayIndexOf(this.sharedParameters.disabledDates, disabledDate, function(date) {
36015   return ASPxClientCalendar.AreDatesEqual(date, disabledDate);
36016  });
36017 },
36018 ShowLoadingPanel: function(){
36019  this.CreateLoadingPanelWithAbsolutePosition(this.GetMainElement().parentNode, this.GetLoadingPanelOffsetElement(this.GetMainElement()));
36020 },
36021 ShowLoadingDiv: function () {
36022  this.CreateLoadingDiv(this.GetMainElement().parentNode, this.GetMainElement());
36023 },
36024 GetCallbackAnimationElement: function() {
36025  return !this.IsMultiView() ? this.GetActiveView(0, 0).GetAnimatedElement() : this.GetMainElement();
36026 },
36027 CanHandleGesture: function(evt) {
36028  if(!this.AllowShiftVisiblePeriod())
36029   return false;
36030  var source = ASPx.Evt.GetEventSource(evt);
36031  var element = !this.IsMultiView() ? this.GetActiveView(0, 0).GetMainElement() : this.GetMainElement();
36032  return ASPx.GetIsParent(element, source);
36033 },
36034 AllowStartGesture: function() {
36035  return ASPxClientControl.prototype.AllowStartGesture.call(this) && (!this.enableMulti || !this.selectionTransaction.isActive) && !this.updateAnimationProcessing;
36036 },
36037 StartGesture: function() {
36038  this.swipeGestureStated = true;
36039 },
36040 AllowExecuteGesture: function(value) {
36041  return true;
36042 },
36043 ExecuteGesture: function(value, count) {
36044  if(!count) count = 1;
36045  this.OnShiftMonth((value > 0 ? -1 : 1) * count);
36046 }, 
36047 Update: function() {
36048  if(this.customDraw && !this.clientUpdate && !this.IsInlineFastNavigationActive()) {
36049   if(!this.isDateEditCalendar)
36050    this.UpdateFromServer();
36051   else if (this.sharedParameters.currentDateEdit != null)
36052    this.sharedParameters.currentDateEdit.CreateUpdateCallback();
36053  }
36054  else {
36055   if(this.IsAnimationEnabled() && !this.forceUpdatingOnMouseOver)
36056    this.StartBeforeUpdateAnimation();
36057   else
36058    this.UpdateInternal();
36059  }
36060 },
36061 UpdateFromServer: function() {
36062  if(this.callBack) {
36063   this.ShowLoadingElements();
36064   this.CreateCallback(this.sharedParameters.GetUpdateCallbackParameters());
36065  }
36066  else {
36067   this.SendPostBack("");
36068  }
36069 },
36070 UpdateInternal: function() {
36071  if(this.NeedCalculateSelectionOnUpdating())
36072   this.selection.Clear();
36073  var activeViews = this.GetActiveViews();
36074  for(var key in activeViews) {
36075   if(activeViews.hasOwnProperty(key)) {
36076    var view = activeViews[key];
36077    if(!view.isASPxClientCalendarView) continue;
36078    view.Update();
36079    if (this.switchToSingleMonthAtWindowInnerWidth)
36080     view.EnsureVisible(view.GetIndex() === this.visibleDateColumnOffset);
36081   }
36082  }
36083  if(this.IsAnimationEnabled() && !this.forceUpdatingOnMouseOver)
36084   this.StartAfterUpdateAnimation();
36085 },
36086 AnimationHelperExists: function() {
36087  return typeof (ASPx.AnimationHelper) !== "undefined";
36088 },
36089 IsAnimationEnabled: function() {
36090  return (this.isSlideCallbackAnimationEnabled() || this.enableCallbackAnimation) && !this.IsUpdateAnimationLocked();
36091 },
36092 LockUpdateAnimation: function() {
36093  this.updateAnimationLockCount++;
36094 },
36095 UnlockUpdateAnimation: function() {
36096  this.updateAnimationLockCount--;
36097 },
36098 IsUpdateAnimationLocked: function() {
36099  return this.updateAnimationLockCount > 0;
36100 },
36101 StartBeforeUpdateAnimation: function() {
36102  this.updateAnimationProcessing = true;
36103  var element = this.GetCallbackAnimationElement();
36104  if(!element.aspxTransition) {
36105   if(this.isSlideCallbackAnimationEnabled() && this.slideAnimationDirection)
36106    ASPx.AnimationHelper.slideOut(element, this.slideAnimationDirection, this.FinishBeforeUpdateAnimation.aspxBind(this), ASPx.AnimationEngineType.JS, this.rtl);
36107   else if(this.enableCallbackAnimation)
36108    ASPx.AnimationHelper.fadeOut(element, this.FinishBeforeUpdateAnimation.aspxBind(this));
36109  }
36110  if(this.updateAnimationProcessing)
36111   this.FinishBeforeUpdateAnimation();
36112 },
36113 FinishBeforeUpdateAnimation: function() {
36114  this.UpdateInternal();
36115 },
36116 StartAfterUpdateAnimation: function() {
36117  var element = this.GetCallbackAnimationElement();
36118  if (this.isSlideCallbackAnimationEnabled() && this.slideAnimationDirection)
36119   ASPx.AnimationHelper.slideIn(element, this.slideAnimationDirection, this.FinishAfterUpdateAnimation.aspxBind(this), ASPx.AnimationEngineType.JS, this.rtl);
36120  else if(this.enableCallbackAnimation) 
36121   ASPx.AnimationHelper.fadeIn(element, this.FinishAfterUpdateAnimation.aspxBind(this));
36122  else
36123   this.FinishAfterUpdateAnimation();
36124 },
36125 FinishAfterUpdateAnimation: function() {
36126  this.updateAnimationProcessing = false;
36127  this.slideAnimationDirection = null;
36128  this.CheckRepeatGesture();
36129 },
36130 ApplySelectionByDiff: function(selection, save) {
36131  var toShow = [ ];
36132  var toHide = [ ];
36133  var dates =  selection.GetDates();
36134  var oldDates = this.selection.GetDates();
36135  var selectionEdges = this.sharedParameters.dateRangeMode ? ASPx.Data.ArrayGetIntegerEdgeValues(dates) : null;
36136  var oldSelectionEdges = this.sharedParameters.dateRangeMode ? ASPx.Data.ArrayGetIntegerEdgeValues(oldDates) : null;
36137  var date;
36138  for(var i = 0; i < dates.length; i++) {
36139   date = dates[i];
36140   var isEdgeDateInSelection = selectionEdges
36141    && ASPxClientCalendar.IsFirstDateEqualToAnyOther(dates[i], selectionEdges.start, selectionEdges.end);
36142   var isEdgeDateInOldSelection = oldSelectionEdges
36143    && ASPxClientCalendar.IsFirstDateEqualToAnyOther(dates[i], oldSelectionEdges.start, oldSelectionEdges.end);
36144   if (!this.selection.Contains(date)
36145    || isEdgeDateInSelection && !isEdgeDateInOldSelection
36146    || !isEdgeDateInSelection && isEdgeDateInOldSelection)
36147    toShow.push(date);
36148  }
36149  for(var i = 0; i < oldDates.length; i++) {
36150   date = oldDates[i];
36151   if(!selection.Contains(date))
36152    toHide.push(date);
36153  }
36154  var activeViews = this.GetActiveViews();
36155  for(var key in activeViews) {
36156   if(activeViews.hasOwnProperty(key)) {
36157    var view = activeViews[key];
36158    if(!view.isASPxClientCalendarView) continue;
36159    view.UpdateSelection(toHide, false, selectionEdges);
36160    view.UpdateSelection(toShow, true, selectionEdges);
36161   }
36162  }
36163  this.selection.Assign(selection);
36164  if(this.accessibilityCompliant)
36165   this.accessibilityHelper.PronounceDates(dates);
36166 },
36167 GetDayInRangeClassName: function() {
36168  return ASPxClientCalendarView.DayInRangeClassName;
36169 },
36170 NeedApplySelectionToDayInRange: function() {
36171  return true;
36172 },
36173 ImportEtalonStyle: function(info, suffix) {
36174  var cell = this.GetEtalonStyleCell(suffix);
36175  if(ASPx.IsExistsElement(cell))
36176   info.Import(cell);   
36177 },
36178 GetEtalonStyleCell: function(name) {
36179  return ASPx.CacheHelper.GetCachedElementById(this, this.name + "_EC_" + name);
36180 },
36181 CanApplyDayCellStyle: function(suffix, isCurrentMonthDay) {
36182  return true;
36183 },
36184 UpdateStateObject: function() {
36185  var stateObject = { };
36186  var visibleDate = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(this.visibleDate);
36187  visibleDate = ASPxClientCalendar.GetCorrectedDate(visibleDate, this.pickerType);
36188  var initialVisibleDate = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(this.initialVisibleDate);
36189  initialVisibleDate = ASPxClientCalendar.GetCorrectedDate(initialVisibleDate, this.pickerType);
36190  stateObject.visibleDate = ASPx.DateUtils.GetInvariantDateString(visibleDate);
36191  stateObject.initialVisibleDate = ASPx.DateUtils.GetInvariantDateString(initialVisibleDate);
36192  stateObject.selectedDates = [];
36193  if(this.selection.count > 0) {
36194   var dates = this.selection.GetDates();
36195   for(var i = 0; i < dates.length; i++)
36196    stateObject.selectedDates.push(ASPx.DateUtils.GetInvariantDateString(dates[i]));
36197  }
36198  this.UpdateStateObjectWithObject(stateObject);
36199 },
36200 GetStateHiddenFieldName: function() {
36201  return this.uniqueID;
36202 },
36203 FormatDates: function(dates, separator) {
36204  var result = "";
36205  for(var i = 0; i < dates.length; i++) {
36206   if(result.length > 0)
36207    result += separator;
36208   result += ASPx.DateUtils.GetInvariantDateString(dates[i]);     
36209  }
36210  return result;
36211 },
36212 InitializeKeyHandlers: function() {
36213  this.AddKeyDownHandler(ASPx.Key.Enter, "OnEnterDown");
36214  this.AddKeyDownHandler(ASPx.Key.Esc, "OnEscape");
36215  this.AddKeyDownHandler(ASPx.Key.PageUp, "OnPageUp");
36216  this.AddKeyDownHandler(ASPx.Key.PageDown, "OnPageDown");
36217  this.AddKeyDownHandler(ASPx.Key.End, "OnEndKeyDown");
36218  this.AddKeyDownHandler(ASPx.Key.Home, "OnHomeKeyDown");
36219  this.AddKeyDownHandler(ASPx.Key.Left, this.rtl ? "OnArrowRight" : "OnArrowLeft");
36220  this.AddKeyDownHandler(ASPx.Key.Right, this.rtl ? "OnArrowLeft" : "OnArrowRight");
36221  this.AddKeyDownHandler(ASPx.Key.Up, "OnArrowUp");
36222  this.AddKeyDownHandler(ASPx.Key.Down, "OnArrowDown");
36223  this.AddKeyPressHandler(ASPx.Key.Enter, "OnEnterPressed");
36224 },
36225 OnArrowUp: function(evt) {
36226  if(this.IsPopupFastNavigationActive())
36227   this.fastNavigation.OnArrowUp(evt);
36228  else if(!this.GetReadOnly() || this.IsInlineFastNavigationActive()) {
36229   var newDate;
36230   if(!this.IsInlineFastNavigationActive()) {
36231    newDate = this.GetNearestDayForToday();
36232    if(this.lastSelectedDate)
36233     newDate = this.currentViewType == ASPx.DatePickerType.Days ? ASPxClientCalendar.GetPrevWeekDate(this.lastSelectedDate) : this.GetNearestDateFromUp(this.lastSelectedDate);
36234   }
36235   else
36236    newDate = this.GetNearestDateFromUp(this.selectedNavigationDates[this.currentViewType]);
36237   if(!ASPxClientCalendarDateDisabledHelper.IsDateWithinBoundaries(newDate))
36238    return true;
36239   if(this.CorrectVisibleMonth(newDate, false))
36240    this.DoKeyboardSelection(newDate, evt.shiftKey, "up");
36241  }
36242  return true;
36243 }, 
36244 OnArrowDown: function(evt) {
36245  if(this.IsPopupFastNavigationActive())
36246   this.fastNavigation.OnArrowDown(evt);
36247  else if(!this.GetReadOnly() || this.IsInlineFastNavigationActive()) {
36248   var newDate;
36249   if(!this.IsInlineFastNavigationActive()) {
36250    newDate = this.GetNearestDayForToday();
36251    if(this.lastSelectedDate)
36252     newDate = this.currentViewType == ASPx.DatePickerType.Days ? ASPxClientCalendar.GetNextWeekDate(this.lastSelectedDate) : this.GetNearestDateFromDown(this.lastSelectedDate);
36253   }
36254   else
36255    newDate = this.GetNearestDateFromDown(this.selectedNavigationDates[this.currentViewType]);
36256   if(this.CorrectVisibleMonth(newDate, true))
36257    this.DoKeyboardSelection(newDate, evt.shiftKey, "down");
36258  }
36259  return true;
36260 }, 
36261 OnArrowLeft: function(evt) {
36262  if(this.IsPopupFastNavigationActive())
36263   this.fastNavigation.OnArrowLeft(evt);
36264  else if(!this.GetReadOnly() || this.IsInlineFastNavigationActive()) {
36265   var newDate;
36266   if(!this.IsInlineFastNavigationActive()) {
36267    newDate = this.GetNearestDayForToday();
36268    if(this.lastSelectedDate)
36269     newDate = this.currentViewType == ASPx.DatePickerType.Days ? ASPxClientCalendar.GetYesterDate(this.lastSelectedDate) : this.GetNearestDateFromLeft(this.lastSelectedDate);
36270   }
36271   else
36272    newDate = this.GetNearestDateFromLeft(this.selectedNavigationDates[this.currentViewType]);
36273   if(!ASPxClientCalendarDateDisabledHelper.IsDateWithinBoundaries(newDate))
36274    return true;
36275   if(this.CorrectVisibleMonth(newDate, false))
36276    this.DoKeyboardSelection(newDate, evt.shiftKey, "left");
36277  }
36278  return true;
36279 }, 
36280 OnArrowRight: function(evt) {
36281  if(this.IsPopupFastNavigationActive())
36282   this.fastNavigation.OnArrowRight(evt);
36283  else if(!this.GetReadOnly() || this.IsInlineFastNavigationActive()) {
36284   var newDate;
36285   if(!this.IsInlineFastNavigationActive()) {
36286    newDate = this.GetNearestDayForToday();
36287    if(this.lastSelectedDate)
36288     newDate = this.currentViewType == ASPx.DatePickerType.Days ? ASPxClientCalendar.GetTomorrowDate(this.lastSelectedDate) : this.GetNearestDateFromRight(this.lastSelectedDate);
36289   }
36290   else
36291    newDate = this.GetNearestDateFromRight(this.selectedNavigationDates[this.currentViewType]);
36292   if(this.CorrectVisibleMonth(newDate, true))
36293    this.DoKeyboardSelection(newDate, evt.shiftKey, "right");
36294  }
36295  return true;
36296 }, 
36297 OnCallback: function(result){
36298  var rowElements = this.GetCalendarRowElements();
36299  for(var rowIndex = 0; rowIndex < this.rows; rowIndex++) {
36300   var viewCellElements = this.GetCalendarViewCellElements(rowElements[rowIndex]);
36301   for(var cellIndex = 0; cellIndex < this.columns; cellIndex++)
36302    ASPx.SetInnerHtml(viewCellElements[cellIndex], result[rowIndex * this.columns + cellIndex]);
36303  }
36304  if(this.sharedParameters.hasCustomDisabledDatesViaCallback)
36305   this.UpdateCustomDisabledDatesOnCallback(result);
36306  this.CreateViews();
36307  this.InitializeGestures();
36308  this.InitializeEnabled();
36309  if(!this.isDateEditCalendar)
36310   this.SetFocus();
36311  if(!this.sharedParameters.calendarCustomDraw)
36312   this.UpdateInternal();
36313  this.EnsureTodayStyle();
36314  this.SetInitialVisibleDate();
36315 }, 
36316 OnPageUp: function(evt) {
36317  if(this.IsPopupFastNavigationActive())
36318   this.fastNavigation.OnPageUp(evt);
36319  else if(!this.GetReadOnly() || this.IsInlineFastNavigationActive()) {
36320   var newDate;
36321   if(this.IsInlineFastNavigationActive())
36322    newDate = this.GetPageUpPageDownResultDate(true, evt.shiftKey, this.selectedNavigationDates[this.currentViewType]);
36323   else if(this.lastSelectedDate)
36324    newDate = this.GetPageUpPageDownResultDate(true, evt.shiftKey, this.lastSelectedDate);
36325   else
36326    newDate = this.GetNearestDayForToday();
36327   if(!ASPxClientCalendarDateDisabledHelper.IsDateWithinBoundaries(newDate))
36328    return true;
36329   if(this.CorrectVisibleMonth(newDate, false))
36330    this.DoKeyboardSelection(newDate, false, "left");
36331  }
36332  return true; 
36333 },
36334 OnPageDown: function(evt) {
36335  if(this.IsPopupFastNavigationActive())
36336   this.fastNavigation.OnPageDown(evt);
36337  else if(!this.GetReadOnly() || this.IsInlineFastNavigationActive()) {
36338   var newDate;
36339   if(this.IsInlineFastNavigationActive())
36340    newDate = this.GetPageUpPageDownResultDate(false, evt.shiftKey, this.selectedNavigationDates[this.currentViewType]);
36341   else if(this.lastSelectedDate)
36342    newDate = this.GetPageUpPageDownResultDate(false, evt.shiftKey, this.lastSelectedDate);
36343   else
36344    newDate = this.GetNearestDayForToday();
36345   if(!ASPxClientCalendarDateDisabledHelper.IsDateWithinBoundaries(newDate))
36346    return true;
36347   if(this.CorrectVisibleMonth(newDate, true))
36348    this.DoKeyboardSelection(newDate, false, "right");
36349  }
36350  return true;
36351 },
36352 OnEndKeyDown: function(evt) {
36353  if(!this.GetReadOnly() && !this.IsPopupFastNavigationActive() || this.IsInlineFastNavigationActive()) {
36354   var currentDate;
36355   if(this.IsInlineFastNavigationActive())
36356    currentDate = this.selectedNavigationDates[this.currentViewType];
36357   else
36358    currentDate = this.lastSelectedDate ?
36359     ASPxClientCalendar.CloneDate(this.lastSelectedDate) : this.GetNearestDayForToday();
36360   var newDate;
36361   if(this.currentViewType == ASPx.DatePickerType.Days)
36362    newDate = ASPxClientCalendar.GetLastDayInWeek(currentDate, this.firstDayOfWeek);    
36363   if(this.currentViewType == ASPx.DatePickerType.Months)
36364    newDate = new Date(currentDate.getFullYear(), 11, 1);
36365   if(this.currentViewType == ASPx.DatePickerType.Years)
36366    newDate = new Date(ASPxClientCalendar.GetDecadeStartYear(currentDate.getFullYear()) + 9, 0, 1);
36367   if(this.currentViewType == ASPx.DatePickerType.Decades)
36368    newDate = new Date(ASPxClientCalendar.GetCenturyStartYear(currentDate.getFullYear()) + 90, 0, 1);
36369   if(this.CorrectVisibleMonth(newDate, true))
36370    this.DoKeyboardSelection(newDate, evt.shiftKey, "left");
36371  }
36372  return true;
36373 },
36374 OnHomeKeyDown: function(evt) {
36375  if(!this.GetReadOnly() && !this.IsPopupFastNavigationActive() || this.IsInlineFastNavigationActive()) {
36376   var currentDate;
36377   if(this.IsInlineFastNavigationActive())
36378    currentDate = this.selectedNavigationDates[this.currentViewType];
36379   else
36380    currentDate = this.lastSelectedDate ?
36381     ASPxClientCalendar.CloneDate(this.lastSelectedDate) : this.GetNearestDayForToday();
36382   var newDate;
36383   if(this.currentViewType == ASPx.DatePickerType.Days)
36384    newDate = ASPxClientCalendar.GetFirstDayInWeek(currentDate, this.firstDayOfWeek);
36385   if(this.currentViewType == ASPx.DatePickerType.Months)
36386    newDate = new Date(currentDate.getFullYear(), 0, 1);
36387   if(this.currentViewType == ASPx.DatePickerType.Years)
36388    newDate = new Date(ASPxClientCalendar.GetDecadeStartYear(currentDate.getFullYear()), 0, 1);
36389   if(this.currentViewType == ASPx.DatePickerType.Decades)
36390    newDate = new Date(ASPxClientCalendar.GetCenturyStartYear(currentDate.getFullYear()), 0, 1);
36391   if(this.CorrectVisibleMonth(newDate, false))
36392    this.DoKeyboardSelection(newDate, evt.shiftKey, "right");
36393  }
36394  return true;
36395 },
36396 GetPageUpPageDownResultDate: function(isPageUp, shiftKey, currentDate) {
36397  var getNeighbourMonthDateAction = isPageUp ? ASPxClientCalendar.GetPrevMonthDate : ASPxClientCalendar.GetNextMonthDate;
36398  var getNeighbourYearDateAction = isPageUp ? ASPxClientCalendar.GetPrevYearDate : ASPxClientCalendar.GetNextYearDate;
36399  var offsetYearSign = isPageUp ? -1 : 1;
36400  if(this.currentViewType == ASPx.DatePickerType.Days)
36401   return shiftKey ? getNeighbourYearDateAction(currentDate) : getNeighbourMonthDateAction(currentDate);
36402  if(this.currentViewType == ASPx.DatePickerType.Months)
36403   return ASPxClientCalendar.GetDateWithYearOffset(currentDate, offsetYearSign);
36404  if(this.currentViewType == ASPx.DatePickerType.Years)
36405   return ASPxClientCalendar.GetDateWithYearOffset(currentDate, offsetYearSign * 10);
36406  if(this.currentViewType == ASPx.DatePickerType.Decades)
36407   return ASPxClientCalendar.GetDateWithYearOffset(currentDate, offsetYearSign * 100);
36408 },
36409 OnEnterDown: function() {
36410  var isPopupFastNavActive = this.IsPopupFastNavigationActive();
36411  var isInlineFastNavActive = this.IsInlineFastNavigationActive();
36412  if(isPopupFastNavActive || isInlineFastNavActive) {
36413   if(isPopupFastNavActive)
36414    this.fastNavigation.ApplyChanges();
36415   else {
36416    var selectedNavigationDate = this.selectedNavigationDates[this.currentViewType];
36417    this.SwitchToLessView();
36418    this.RaiseCellClick(selectedNavigationDate);
36419   }
36420   return true;
36421  }
36422  return false;
36423 },
36424 OnEnterPressed: function() {
36425  return true;
36426 },
36427 OnEscape: function() {
36428  this.CancelFastNavigation();
36429  return true;
36430 },
36431 CancelFastNavigation: function() {
36432  var isPopupFastNavActive = this.IsPopupFastNavigationActive();
36433  var isInlineFastNavActive = this.IsInlineFastNavigationActive();
36434  if(isPopupFastNavActive || isInlineFastNavActive) {
36435   if(isPopupFastNavActive)
36436    this.fastNavigation.CancelChanges();
36437   else
36438    this.ChangeView(this.currentViewType - 1);
36439  }
36440  if(!this.IsInlineFastNavigationActive())
36441   this.OnMainElementClick();
36442 },
36443 OnShiftMonth: function(offset, keepVisibleInSingleMode) {
36444  if(offset) {
36445   var date = this.GetNewVisibleDateByOffset(offset);
36446   if(this.IsInlineFastNavigationActive())
36447    this.selectedNavigationDates[this.currentViewType] = this.GetNewSelectedNavigationDateByOffset(offset);
36448   this.OnVisibleMonthChanged(date);
36449   if (keepVisibleInSingleMode)
36450    this.visibleDateColumnOffset = Math.min(Math.abs(offset), this.columns - 1);
36451  }
36452 },
36453 GetNewVisibleDateByOffset: function(offset) {
36454  return this.GetNewVisibleOrSelectedNavigationDateByOffset(this.visibleDates[this.currentViewType], offset);
36455 },
36456 GetNewSelectedNavigationDateByOffset: function(offset) {
36457  return this.GetNewVisibleOrSelectedNavigationDateByOffset(this.selectedNavigationDates[this.currentViewType], offset);
36458 },
36459 GetNewVisibleOrSelectedNavigationDateByOffset: function(currentDate, offset) {
36460  var date = ASPxClientCalendar.CloneDate(currentDate);
36461  if(this.currentViewType == ASPx.DatePickerType.Days)
36462   return ASPxClientCalendar.AddMonths(date, offset);
36463  if(this.currentViewType == ASPx.DatePickerType.Months)
36464   return ASPxClientCalendar.AddYears(date, offset);
36465  if(this.currentViewType == ASPx.DatePickerType.Years)
36466   return ASPxClientCalendar.AddYears(date, offset * 10);
36467  if(this.currentViewType == ASPx.DatePickerType.Decades)
36468   return ASPxClientCalendar.AddYears(date, offset * 100);
36469 },
36470 OnDayMouseDown: function(date, shift, ctrl, byWeeks) {
36471  if(!this.IsInlineFastNavigationActive())
36472   this.OnPickerViewMouseDown(date, shift, ctrl, byWeeks);
36473  else {
36474   this.selectedNavigationDates[this.currentViewType] = date;
36475   this.SwitchToLessView();
36476  }
36477  this.RaiseCellClick(date);
36478 },
36479 OnPickerViewMouseDown: function(date, shift, ctrl, byWeeks) {
36480  this.isMouseDown = true;
36481  this.selectionByWeeks = byWeeks;
36482  if(!this.enableMulti && this.isSwipeGesturesEnabled())
36483   return;
36484  this.selectionTransaction.Start();
36485  if(this.enableMulti) {
36486   if(ctrl) {
36487    this.selectionCtrl = true;
36488    this.selectionTransaction.CopyFromBackup();
36489   } else
36490    this.selectionCtrl = false;
36491   if(shift && this.selectionPrevStartDate) {
36492    this.selectionStartDate = this.selectionPrevStartDate;         
36493    this.selectionTransaction.selection.AddRange(this.selectionStartDate, date);
36494    if(byWeeks)
36495     this.selectionTransaction.selection.AddWeek(date);
36496   } else {
36497    this.selectionStartDate = date;
36498    this.selectionPrevStartDate = date;
36499    if(byWeeks)
36500     this.selectionTransaction.selection.AddWeek(date);
36501    else
36502     this.selectionTransaction.selection.Add(date);
36503   }
36504  } 
36505  else 
36506   this.selectionTransaction.selection.Add(date);
36507  if(!ASPxClientCalendarDateDisabledHelper.IsDateWithinBoundaries(date))
36508   this.selectionTransaction.CopyFromBackup();
36509  if(this.enableMulti)
36510   this.RemoveDisabledDatesFromSelection(this.selectionTransaction.selection);
36511  this.ApplySelectionByDiff(this.selectionTransaction.selection, false);
36512 },
36513 OnDayMouseOver: function(date) {
36514  if(this.IsInlineFastNavigationActive())
36515   return;
36516  if (!this.sharedParameters.DaysSelectingOnMouseOver.IsEmpty()) {
36517   var args = new ASPxDaysSelectingOnMouseOverEventArgs(date);
36518   this.sharedParameters.DaysSelectingOnMouseOver.FireEvent(this, args);
36519   if (args.cancel)
36520    return;
36521   this.selectionStartDate = args.selectionStartDate;
36522   date = args.overDate;
36523  }
36524  if (!this.enableMulti && this.isSwipeGesturesEnabled() && !this.sharedParameters.dateRangeMode)
36525   return;
36526  if (this.enableMulti || this.sharedParameters.dateRangeMode) {
36527   if(this.selectionCtrl)
36528    this.selectionTransaction.CopyFromBackup();
36529   else
36530    this.selectionTransaction.selection.Clear();
36531   if(this.sharedParameters.dateRangeMode)
36532    this.CalculateRangeSelectionOnMouseOver(date);
36533   else
36534    this.selectionTransaction.selection.AddRange(this.selectionStartDate, date);
36535   if(this.selectionByWeeks) {
36536    this.selectionTransaction.selection.AddWeek(date);
36537    this.selectionTransaction.selection.AddWeek(this.selectionStartDate);
36538   }
36539  } 
36540  else {
36541   this.selectionTransaction.selection.Clear();
36542   this.selectionTransaction.selection.Add(date);
36543  }
36544  if (this.enableMulti || this.sharedParameters.dateRangeMode)
36545   this.RemoveDisabledDatesFromSelection(this.selectionTransaction.selection);
36546  this.ApplySelectionByDiff(this.selectionTransaction.selection, false);
36547  if (this.updateDayStylesTwiceOnMouseOver)
36548   this.ForceUpdateOnMouseOver();
36549 },
36550 ForceUpdateOnMouseOver: function() {
36551  this.forceUpdatingOnMouseOver = true;
36552  try {
36553   this.Update();
36554  }
36555  finally {
36556   this.forceUpdatingOnMouseOver = false;
36557  }
36558 },
36559 CalculateRangeSelectionOnMouseOver: function(overDate) {
36560  var selectedRangeRestrictions = {
36561   start: ASPxClientCalendar.GetMinDate(this.selectionStartDate, overDate),
36562   end: ASPxClientCalendar.GetMaxDate(this.selectionStartDate, overDate)
36563  };
36564  var visibleRangeRestrictions = this.GetVisibleRangeRestrictions();
36565  ASPxClientCalendar.AddSelectedRangeVisiblePartToSelection(this.selectionTransaction.selection, selectedRangeRestrictions, visibleRangeRestrictions);
36566 },
36567 RaiseVisibleDaysMouseOut: function() {
36568  if (!this.sharedParameters.VisibleDaysMouseOut.IsEmpty())
36569   this.sharedParameters.VisibleDaysMouseOut.FireEvent(this);
36570 },
36571 OnDayMouseUp: function(date) {
36572  if(this.IsInlineFastNavigationActive())
36573   return;
36574  if(this.isMouseDown)
36575   this.OnMainElementClick();
36576  this.isMouseDown = false;
36577  if(!this.enableMulti && this.isSwipeGesturesEnabled() && this.swipeGestureStated)
36578   this.swipeGestureStated = false;
36579  if(this.enableMulti) {
36580   if(this.selectionCtrl && this.selectionTransaction.backup.Contains(date) &&
36581    ASPxClientCalendar.AreDatesEqual(date, this.selectionStartDate)) {
36582    if(this.selectionByWeeks)
36583     this.selectionTransaction.selection.RemoveWeek(date);
36584    else
36585     this.selectionTransaction.selection.Remove(date);
36586   }
36587  }
36588  else if(this.sharedParameters.dateRangeMode) {
36589   this.selectionTransaction.selection.Clear();
36590   this.selectionTransaction.selection.Add(date);
36591  }
36592  else if(this.isSwipeGesturesEnabled() && !this.swipeGestureStated) {
36593   this.selectionTransaction.selection.Add(date);
36594   if(!ASPxClientCalendarDateDisabledHelper.IsDateWithinBoundaries(date))
36595    this.selectionTransaction.CopyFromBackup();
36596   this.ApplySelectionByDiff(this.selectionTransaction.selection, false);
36597  }
36598  this.lastSelectedDate = ASPxClientCalendar.CloneDate(date);
36599  this.OnSelectionChanging();
36600 },
36601 GetTodayDate: function() {
36602  var parentSchedulerTodayDate = this.GetParentSchedulerTodayDate();
36603  if(parentSchedulerTodayDate)
36604   return parentSchedulerTodayDate;
36605  var now = new Date();
36606  var correctedNowDate = ASPxClientCalendar.GetCorrectedDate(now, this.pickerType);
36607  return new Date(correctedNowDate.getFullYear(), correctedNowDate.getMonth(), correctedNowDate.getDate());
36608 },
36609 GetParentSchedulerTodayDate: function() {
36610  return this.actualTodayDate;
36611 },
36612 EnsureHideFastNavigation: function() {
36613  if(this.fastNavigation)
36614   this.fastNavigation.Hide();
36615  else if(this.IsInlineFastNavigationActive())
36616   this.ChangeView(this.pickerType);
36617 },
36618 OnTodayClick: function() {
36619  this.EnsureHideFastNavigation();
36620  var todayDate = this.GetTodayDate();
36621  if(ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, todayDate)) {
36622   if(!this.IsDateDisabled(todayDate)) {
36623    this.selectionTransaction.Start();
36624    this.selectionTransaction.selection.Add(todayDate);
36625    this.lastSelectedDate = ASPxClientCalendar.CloneDate(todayDate);
36626    this.OnSelectionChanging();
36627   }
36628   if(!ASPxClientCalendar.AreDatesOfSamePeriod(todayDate, this.visibleDate, this.currentViewType))
36629    this.OnVisibleMonthChanged(todayDate);  
36630  }
36631 },
36632 OnClearClick: function() {
36633  if(this.isDateEditCalendar && ASPxClientDateEdit.active)
36634   ASPxClientDateEdit.active.OnTimeSectionClearClick();
36635  else {
36636   this.selectionTransaction.Start();
36637   this.OnSelectionChanging();
36638   this.selectionStartDate = null;
36639   this.selectionPrevStartDate = null;    
36640   this.ResetLastSelectedDate();
36641  }
36642 },
36643 OnOkClick: function() {
36644  var edit = ASPxClientDateEdit.active;
36645  if(edit)
36646   edit.OnApplyButtonClick();
36647 },
36648 OnCancelClick: function() {
36649  var edit = ASPxClientDateEdit.active;
36650  if(edit)
36651   edit.OnTimeSectionCancelClick();
36652 },
36653 ResetLastSelectedDate: function() {
36654  this.lastSelectedDate = null;
36655 },
36656 OnSelectMonth: function(row, column) {  
36657  var txn = this.selectionTransaction;
36658  txn.Start();
36659  var date = ASPxClientCalendar.CloneDate(this.GetActiveView(row, column).visibleDate);
36660  date.setDate(1);
36661  do {  
36662   if(ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, date) &&
36663    !this.IsDateDisabled(date))
36664    txn.selection.Add(date);
36665   date = ASPxClientCalendar.AddDays(date, 1);
36666  } while(date.getDate() > 1);
36667  this.OnSelectionChanging();
36668 },
36669 OnTitleClick: function(row, column) {
36670  if(!this.AllowProcessTitleClick())
36671   return;
36672  if(this.showFastPopup)
36673   this.ShowPopupFastNavigation(row, column);
36674  else
36675   this.SwitchToGreaterView(row, column);
36676 },
36677 SwitchToGreaterView: function(row, column, newViewType, disableAnimation) {
36678  newViewType = newViewType || this.currentViewType + 1;
36679  this.visibleDates[newViewType] = this.GetGreaterViewVisibleDate(newViewType, row, column);
36680  this.selectedNavigationDates[newViewType] = this.GetGreaterViewSelectedNavigationDate(newViewType, row, column);
36681  this.ChangeView(newViewType, disableAnimation);
36682 },
36683 SwitchToLessView: function() {
36684  var newViewType = this.currentViewType - 1;
36685  var selectedDate = this.selectedNavigationDates[this.currentViewType];
36686  this.visibleDates[newViewType] = this.GetLessViewVisibleDate(newViewType, selectedDate);
36687  var isSwitchedToPickerView = newViewType == this.pickerType;
36688  var oldVisibleDate = ASPxClientCalendar.CloneDate(this.visibleDate);
36689  if(isSwitchedToPickerView)
36690   this.visibleDate = this.visibleDates[newViewType];
36691  else
36692   this.selectedNavigationDates[newViewType] = selectedDate;
36693  this.ChangeView(newViewType);
36694  if(isSwitchedToPickerView && !ASPxClientCalendar.AreDatesOfSamePeriod(this.visibleDate, oldVisibleDate, this.pickerType))
36695   this.OnVisibleMonthChanged(this.visibleDate, oldVisibleDate, true);
36696 },
36697 GetViewByDate: function(date) {
36698  var activeViews = this.GetActiveViews();
36699  for(var key in activeViews) {
36700   if(activeViews.hasOwnProperty(key)) {
36701    var view = activeViews[key];
36702    if(view.IsDateVisible(date))
36703     return view;
36704   }
36705  }
36706 },
36707 GetGreaterViewVisibleDate: function(greaterViewType, currentRow, currentColumn) {
36708  var currentViewVisibleYear = this.GetActiveView(currentRow, currentColumn).visibleDate.getFullYear();
36709  var greaterViewTypeCurrentView = this.GetView(currentRow, currentColumn, greaterViewType);
36710  var greaterViewTypeCurrentViewVisibleYearOffset = greaterViewTypeCurrentView.GetVisibleDateOffsetInfo().year;
36711  var greaterViewTypeCurrentViewVisibleYear;
36712  if(greaterViewType == ASPx.DatePickerType.Months)
36713   greaterViewTypeCurrentViewVisibleYear = currentViewVisibleYear;
36714  if(greaterViewType == ASPx.DatePickerType.Years)
36715   greaterViewTypeCurrentViewVisibleYear = ASPxClientCalendar.GetDecadeStartYear(currentViewVisibleYear);
36716  if(greaterViewType == ASPx.DatePickerType.Decades)
36717   greaterViewTypeCurrentViewVisibleYear = ASPxClientCalendar.GetCenturyStartYear(currentViewVisibleYear);
36718  return new Date(greaterViewTypeCurrentViewVisibleYear - greaterViewTypeCurrentViewVisibleYearOff
36718set, 0, 1);
36719 },
36720 GetGreaterViewSelectedNavigationDate: function(greaterViewType, currentRow, currentColumn) {
36721  var currentViewVisibleDate = this.GetActiveView(currentRow, currentColumn).visibleDate;
36722  var currentViewVisibleYear = currentViewVisibleDate.getFullYear();
36723  var currentViewVisibleMonth = currentViewVisibleDate.getMonth();
36724  var resultYear = greaterViewType != ASPx.DatePickerType.Decades ? currentViewVisibleYear : ASPxClientCalendar.GetDecadeStartYear(currentViewVisibleYear);
36725  var resultMonth = greaterViewType == ASPx.DatePickerType.Months ? currentViewVisibleMonth : 0;
36726  return new Date(resultYear, resultMonth, 1);
36727 },
36728 GetLessViewVisibleDate: function(lessViewType, currentSelectedNavigationDate) {
36729  var result = null;
36730  var currentView = this.GetViewByDate(currentSelectedNavigationDate);
36731  var prevViewVisibleDateOffsetInfo = this.GetView(currentView.row, currentView.column, lessViewType).GetVisibleDateOffsetInfo();
36732  if(lessViewType == ASPx.DatePickerType.Days) {
36733   result = new Date(currentSelectedNavigationDate.getFullYear(), currentSelectedNavigationDate.getMonth(), 1);
36734   result = ASPxClientCalendar.AddMonths(result, (-1) * prevViewVisibleDateOffsetInfo.month);
36735  }
36736  else
36737   result = new Date(currentSelectedNavigationDate.getFullYear() - prevViewVisibleDateOffsetInfo.year, 0, 1);
36738  return result;
36739 },
36740 ShowPopupFastNavigation: function(row, column) {
36741  this.fastNavigation.activeView = this.GetActiveView(row, column);
36742  this.fastNavigation.Show();
36743 },
36744 AllowProcessTitleClick: function() {
36745  return this.showFastPopup || this.enableFast && this.currentViewType < this.maxViewType;
36746 },
36747 OnMainElementClick: function(mouseEvt) {
36748  this.MainElementClick.FireEvent(this, mouseEvt);
36749 },
36750 OnSelectionChanging: function() {
36751  if(!this.SelectionChanging.IsEmpty()){
36752   var args = new ASPxClientCalendarSelectionEventArgs(false, this.selectionTransaction.selection);
36753   this.SelectionChanging.FireEvent(this, args);  
36754  }
36755  var changed = this.selectionTransaction.IsChanged();
36756  this.selectionTransaction.Commit();
36757  if(changed)
36758   this.OnValueChanged();  
36759 },
36760 OnVisibleMonthChanged: function(date, oldDate, skipVisibleDateUpdating) {
36761  oldDate = oldDate || this.visibleDate;
36762  var offsetInternal = this.currentViewType == ASPx.DatePickerType.Days ? ASPxClientCalendar.GetOffsetInMonths(oldDate, date) : 0;
36763  if(!skipVisibleDateUpdating)
36764   this.SetVisibleDateInternal(date);
36765  var processOnServer = this.currentViewType == ASPx.DatePickerType.Days ? this.RaiseVisibleMonthChanged(offsetInternal) : this.autoPostBack;
36766  if(processOnServer && !this.customDraw && !this.IsInlineFastNavigationActive())
36767   this.SendPostBackInternal("");
36768 },
36769 OnSelectionCancelled: function() {
36770  this.isMouseDown = false;  
36771  this.selectionTransaction.Rollback();
36772 },
36773 OnCustomDisabledDate: function(date) {
36774  return this.RaiseCustomDisabledDate(date);
36775 },
36776 RaiseCustomDisabledDate: function(date) {
36777  var args = new ASPxClientCalendarCustomDisabledDateEventArgs(date);
36778  this.CustomDisabledDate.FireEvent(this, args);
36779  return args;
36780 },
36781 RaiseValueChangedEvent: function() {
36782  var processOnServer = ASPxClientEdit.prototype.RaiseValueChangedEvent.call(this);
36783  processOnServer = this.RaiseSelectionChanged(processOnServer);
36784  return processOnServer;
36785 },
36786 SetVisibleDate: function(date) {
36787  this.EnsureHideFastNavigation(); 
36788  this.SetVisibleDateInternal(date);
36789 }, 
36790 SetVisibleDateInternal: function(date) {
36791  var old = this.visibleDates[this.currentViewType];
36792  date = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(date);
36793  date = ASPxClientCalendar.GetCorrectedDate(date, this.pickerType);
36794  this.visibleDates[this.currentViewType] = date;
36795  if(!this.IsInlineFastNavigationActive())
36796   this.visibleDate = date;
36797  if (this.IsAnimationEnabled() && this.AnimationHelperExists()) {
36798   var leftDir = this.rtl ? ASPx.AnimationHelper.SLIDE_LEFT_DIRECTION : ASPx.AnimationHelper.SLIDE_RIGHT_DIRECTION;
36799   var rightDir = this.rtl ? ASPx.AnimationHelper.SLIDE_RIGHT_DIRECTION : ASPx.AnimationHelper.SLIDE_LEFT_DIRECTION;
36800   this.slideAnimationDirection = old < this.visibleDates[this.currentViewType] ? rightDir : leftDir;
36801  } else {
36802   this.slideAnimationDirection = null;
36803  }
36804  if(!ASPxClientCalendar.AreDatesOfSamePeriod(date, old, this.currentViewType) || this.forceUpdate) {
36805   this.forceUpdate = false;
36806   this.Update(); 
36807  }
36808 },
36809 SetSelectedDate: function(date) {
36810  date = ASPxClientCalendar.GetCorrectedDate(date, this.pickerType);
36811  this.EnsureHideFastNavigation();
36812  if(ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, date) &&
36813   !this.IsDateDisabled(date)) {
36814   var selection = new ASPxClientCalendarSelection();
36815   selection.SetPickerType(this.pickerType);
36816   if(date != null) {
36817    selection.Add(date);
36818    this.lastSelectedDate = ASPxClientCalendar.CloneDate(date);
36819   }
36820   this.ApplySelectionByDiff(selection, true);
36821  }
36822 },
36823 AllowShiftVisiblePeriod: function() {
36824  return this.currentViewType == ASPx.DatePickerType.Days ?
36825   this.enableDaysViewPeriodNavigation : this.enableMonthsYearsViewPeriodNavigation;
36826 },
36827 CorrectVisibleMonth: function(newDate, isForwardDirection) {
36828  var offset = this.GetOffsetInCurrentViewTypePeriods(this.visibleDates[this.currentViewType], newDate);
36829  if(this.IsMultiView() && offset != 0) {
36830   var view = isForwardDirection ? this.GetActiveView(this.rows - 1, this.columns - 1) : 
36831            this.GetActiveView(0, 0);
36832   offset = this.IsDateVisible(newDate) ? 0 :
36833       this.GetOffsetInCurrentViewTypePeriods(view.visibleDate, newDate);
36834  }
36835  if(!this.IsInlineFastNavigationActive() && (!ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, newDate) ||
36836   this.IsDateDisabled(newDate)))
36837   offset = 0;
36838  var result = offset == 0 || this.AllowShiftVisiblePeriod();
36839  if(offset != 0 && this.AllowShiftVisiblePeriod())
36840   this.OnShiftMonth(offset);
36841  return result;
36842 },
36843 GetOffsetInCurrentViewTypePeriods: function(visibleDate, newDate) {
36844  return ASPxClientCalendar.GetOffsetInPeriods(visibleDate, newDate, this.currentViewType);
36845 },
36846 DoKeyboardSelection: function(date, shift, direction) {
36847  if(!this.IsInlineFastNavigationActive())
36848   this.DoKeyboardSelectionOnPickerView(date, shift, direction);
36849  else {
36850   var activeViews = this.GetActiveViews();
36851   for(var key in activeViews) {
36852    if(!activeViews.hasOwnProperty(key)) continue;
36853    var view = activeViews[key];
36854    view.UpdateSelection(this.selectedNavigationDates[this.currentViewType], false);
36855    view.UpdateSelection(date, true);
36856   }
36857   this.selectedNavigationDates[this.currentViewType] = date;
36858  }
36859 },
36860 DoKeyboardSelectionOnPickerView: function(date, shift, direction) {
36861  if(ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, date)) {
36862   this.isDateChangingByKeyboard = true;
36863   var existDate = this.IsDateDisabled(date) ? this.GetNearestDayForDate(date, direction) : date;
36864   if(existDate != null) {
36865    this.selectionTransaction.Start();
36866    if(this.enableMulti && shift && this.selectionStartDate) {
36867     this.selectionTransaction.selection.AddRange(this.selectionStartDate, existDate);
36868     this.RemoveDisabledDatesFromSelection(this.selectionTransaction.selection);
36869    } else {
36870     this.selectionTransaction.selection.Add(existDate);
36871     this.selectionStartDate = existDate;
36872    }
36873    this.lastSelectedDate = ASPxClientCalendar.CloneDate(existDate);
36874    this.OnSelectionChanging();
36875   }
36876   this.isDateChangingByKeyboard = false;
36877  }
36878 },
36879 RemoveDisabledDatesFromSelection: function(selection) {
36880  var selectedDates = selection.GetDates();
36881  for(var i = 0; i < selectedDates.length; i++) {
36882   if(this.IsDateDisabled(selectedDates[i]))
36883    selection.Remove(selectedDates[i]);
36884  }
36885 },
36886 GetNearestDayForToday: function() {
36887  var todayDate = this.GetTodayDate();
36888  if(this.sharedParameters.minDate && !ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, todayDate))
36889   todayDate = ASPxClientCalendar.CloneDate(this.IsDateDisabled(this.sharedParameters.minDate) ? this.GetNearestDayForDate(this.sharedParameters.minDate, "left") : this.sharedParameters.minDate);
36890  return todayDate;
36891 },
36892 GetNearestDayForDate: function(date, direction) {
36893  var nearestDate = null;
36894  var nextDate = date;
36895  while(nearestDate == null) {
36896   switch(direction) {
36897    case "up":
36898     nextDate = this.GetNearestDateFromUp(nextDate);
36899     break;
36900    case "down":
36901     nextDate = this.GetNearestDateFromDown(nextDate);
36902     break;
36903    case "left":
36904     nextDate = this.GetNearestDateFromLeft(nextDate);
36905     break;
36906    case "right":
36907     nextDate = this.GetNearestDateFromRight(nextDate);
36908     break;
36909   }
36910   var isForbiddenDate = !ASPxClientCalendarDateDisabledHelper.IsDateInRange(this.sharedParameters, nextDate) || this.IsDateDisabled(nextDate);
36911   nearestDate = isForbiddenDate ? null : nextDate;
36912  }
36913  return nearestDate;
36914 },
36915 GetNearestDateFromUp: function(date) {
36916  if(this.currentViewType == ASPx.DatePickerType.Days)
36917   return new Date(date.getTime() - (7 * 24 * 60 * 60 * 1000));
36918  if(this.currentViewType == ASPx.DatePickerType.Months) {
36919   var newDate = new Date(date.getTime());
36920   newDate = ASPxClientCalendar.AddMonths(newDate, -4);
36921   return newDate;
36922  }
36923  if(this.currentViewType == ASPx.DatePickerType.Years) {
36924   var newDate = new Date(date.getTime());
36925   newDate = ASPxClientCalendar.AddYears(newDate, -4);
36926   return newDate;
36927  }
36928  if(this.currentViewType == ASPx.DatePickerType.Decades) {
36929   var newDate = new Date(date.getTime());
36930   newDate = ASPxClientCalendar.AddYears(newDate, -40);
36931   return newDate;
36932  }
36933 },
36934 GetNearestDateFromDown: function(date) {
36935  if(this.currentViewType == ASPx.DatePickerType.Days)
36936   return new Date(date.getTime() + (7 * 24 * 60 * 60 * 1000));
36937  if(this.currentViewType == ASPx.DatePickerType.Months) {
36938   var newDate = new Date(date.getTime());
36939   newDate = ASPxClientCalendar.AddMonths(newDate, 4);
36940   return newDate;
36941  }
36942  if(this.currentViewType == ASPx.DatePickerType.Years) {
36943   var newDate = new Date(date.getTime());
36944   newDate = ASPxClientCalendar.AddYears(newDate, 4);
36945   return newDate;
36946  }
36947  if(this.currentViewType == ASPx.DatePickerType.Decades) {
36948   var newDate = new Date(date.getTime());
36949   newDate = ASPxClientCalendar.AddYears(newDate, 40);
36950   return newDate;
36951  }
36952 },
36953 GetNearestDateFromLeft: function(date) {
36954  if(this.currentViewType == ASPx.DatePickerType.Days)
36955   return new Date(date.getTime() - (1 * 24 * 60 * 60 * 1000));
36956  if(this.currentViewType == ASPx.DatePickerType.Months) {
36957   var newDate = new Date(date.getTime());
36958   newDate = ASPxClientCalendar.AddMonths(newDate, -1);
36959   return newDate;
36960  }
36961  if(this.currentViewType == ASPx.DatePickerType.Years) {
36962   var newDate = new Date(date.getTime());
36963   newDate = ASPxClientCalendar.AddYears(newDate, -1);
36964   return newDate;
36965  }
36966  if(this.currentViewType == ASPx.DatePickerType.Decades) {
36967   var newDate = new Date(date.getTime());
36968   newDate = ASPxClientCalendar.AddYears(newDate, -10);
36969   return newDate;
36970  }
36971 },
36972 GetNearestDateFromRight: function(date) {
36973  if(this.currentViewType == ASPx.DatePickerType.Days)
36974   return new Date(date.getTime() + (1 * 24 * 60 * 60 * 1000));
36975  if(this.currentViewType == ASPx.DatePickerType.Months) {
36976   var newDate = new Date(date.getTime());
36977   newDate = ASPxClientCalendar.AddMonths(newDate, 1);
36978   return newDate;
36979  }
36980  if(this.currentViewType == ASPx.DatePickerType.Years) {
36981   var newDate = new Date(date.getTime());
36982   newDate = ASPxClientCalendar.AddYears(newDate, 1);
36983   return newDate;
36984  }
36985  if(this.currentViewType == ASPx.DatePickerType.Decades) {
36986   var newDate = new Date(date.getTime());
36987   newDate = ASPxClientCalendar.AddYears(newDate, 10);
36988   return newDate;
36989  }
36990 },
36991 UseDelayedSpecialFocus: function() { 
36992  return true;
36993 },
36994 GetInnerEditors: function() {
36995  return [];
36996 },
36997 GetDelayedSpecialFocusTriggers: function() {
36998  var list = ASPxClientEdit.prototype.GetDelayedSpecialFocusTriggers.c
36998all(this);
36999  if(this.fastNavigation && this.showFastPopup)
37000   list.push(this.fastNavigation.GetPopupWindowElement());
37001  return list;
37002 },
37003 GetSelectedDate: function() {
37004  return this.GetValue();
37005 },
37006 GetVisibleDate: function() {
37007  return this.visibleDate;
37008 },
37009 SelectDate: function(date) {
37010  if(date) {
37011   date = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(date);
37012   this.selection.Add(date);
37013   this.Update();
37014  }
37015 },
37016 GetVisibleRangeRestrictions: function() {
37017  return {
37018   start: this.GetActiveView(0, 0).GetVisibleRangeRestrictions().start,
37019   end: this.GetActiveView(this.rows - 1, this.columns - 1).GetVisibleRangeRestrictions().end
37020  };
37021 },
37022 NeedCalculateSelectionOnUpdating: function() {
37023  return this.sharedParameters.dateRangeMode && this.selection.startDate && this.selection.endDate && !this.forceUpdatingOnMouseOver;
37024 },
37025 SelectRange: function(start, end) {
37026  if(start && end) {
37027   start = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(start);
37028   end = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(end);
37029   if(this.sharedParameters.dateRangeMode)
37030    this.selection.SetRestrictions(start, end);
37031   else
37032    this.selection.AddRange(start, end);
37033   this.Update();
37034  }
37035 },
37036 DeselectDate: function(date) {
37037  if(date) {
37038   this.selection.Remove(date);
37039   this.Update(); 
37040  }
37041 },
37042 DeselectRange: function(start, end) {
37043  if(start && end) {
37044   this.selection.RemoveRange(start, end);
37045   this.Update();
37046  }
37047 },
37048 ClearSelection: function() {
37049  this.selection.Clear();
37050  if(this.sharedParameters.dateRangeMode)
37051   this.selection.ResetRestrictions();
37052  this.Update();
37053 },
37054 GetSelectedDates: function() {
37055  return this.selection.GetDates();
37056 },
37057 RaiseSelectionChangedInternal: function(processOnServer) {
37058  if(!this.sharedParameters.CalendarSelectionChangedInternal.IsEmpty()) {
37059   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
37060   this.sharedParameters.CalendarSelectionChangedInternal.FireEvent(this, args);
37061   processOnServer = args.processOnServer;
37062  }
37063  return processOnServer;
37064 },
37065 RaiseSelectionChanged: function(processOnServer) {
37066  processOnServer = this.RaiseSelectionChangedInternal(processOnServer);
37067  if(!this.SelectionChanged.IsEmpty()){
37068   var args = new ASPxClientProcessingModeEventArgs(processOnServer);  
37069   this.SelectionChanged.FireEvent(this, args);
37070   processOnServer = args.processOnServer;
37071  }
37072  return processOnServer;
37073 },
37074 RaiseVisibleMonthChanged: function(offsetInternal) {
37075  var processOnServer = this.autoPostBack;
37076  if(!this.VisibleMonthChanged.IsEmpty()){
37077   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
37078   args.offsetInternal = offsetInternal;
37079   this.VisibleMonthChanged.FireEvent(this, args);
37080   processOnServer = args.processOnServer;
37081  }
37082  return processOnServer;
37083 },
37084 RaiseCellClick: function(date) {
37085  if(!this.CellClick.IsEmpty()) {
37086   var args = new ASPxClientCalendarCellClickEventArgs(date);
37087   this.CellClick.FireEvent(this, args);
37088  }
37089 },
37090 SetReadOnlyInternal: function(readOnly) {
37091  ASPxClientEdit.prototype.SetReadOnlyInternal.call(this, readOnly);
37092  this.ChangeReadOnlyAttributes(readOnly);
37093  var footer = this.GetFooter();
37094  if(footer)
37095   footer.style.display = readOnly ? "none" : "";
37096 },
37097 ChangeEnabledAttributes: function(enabled) {
37098  ASPx.Attr.ChangeDocumentEventsMethod(enabled)("mouseup", aspxCalDocMouseUp);
37099  ASPx.Attr.ChangeEventsMethod(enabled)(this.GetMainElement(), "click", ASPxClientCalendar.AnonymousHandlers.MainElementClick(this.name));
37100  var inputElement = this.GetInputElement();
37101  if(inputElement) {
37102   this.ChangeSpecialInputEnabledAttributes(inputElement, ASPx.Attr.ChangeEventsMethod(enabled));
37103   if(!this.accessibilityCompliant) {
37104    var changeMethod = enabled ? ASPx.Attr.RestoreTabIndexAttribute : ASPx.Attr.SaveTabIndexAttributeAndReset;
37105    changeMethod(inputElement);
37106   }
37107  }
37108  var btnElement = this.GetTodayButton();
37109  if(btnElement)
37110   this.ChangeButtonEnabledAttributes(btnElement, this.GetChangeButtonEnabledAttributesMethod(enabled));
37111  btnElement = this.GetClearButton();
37112  if(btnElement)
37113   this.ChangeButtonEnabledAttributes(btnElement, this.GetChangeButtonEnabledAttributesMethod(enabled));
37114  for(var i = this.pickerType; i <= this.maxViewType; i++) {
37115   var views = this.GetViews(i);
37116   for(var key in views) {
37117    if(views.hasOwnProperty(key)) {
37118     var view = views[key];
37119     if(!view.isASPxClientCalendarView) continue;
37120     view.ChangeEnabledAttributes(enabled);
37121     view.ChangeEditableAttributesOnChangeEnabledState(enabled);
37122    }
37123   }
37124  }
37125 },
37126 ChangeReadOnlyAttributes: function(readOnly) {
37127  if(!this.GetEnabled())
37128   return;
37129  for(var i = this.pickerType; i <= this.maxViewType; i++) {
37130   var views = this.GetViews(i);
37131   for(var key in views) {
37132    if(views.hasOwnProperty(key)) {
37133     var view = views[key];
37134     if(!view.isASPxClientCalendarView) continue;
37135     view.ChangeEditableAttributesOnChangeReadOnlyState(readOnly);
37136    }
37137   }
37138  }  
37139 },
37140 ChangeEnabledStateItems: function(enabled){
37141  ASPx.GetStateController().SetElementEnabled(this.GetMainElement(), enabled);
37142  var btnElement = this.GetTodayButton();
37143  if(btnElement)
37144   ASPx.GetStateController().SetElementEnabled(btnElement, enabled);
37145  btnElement = this.GetClearButton();
37146  if(btnElement)
37147   ASPx.GetStateController().SetElementEnabled(btnElement, enabled);
37148  this.EnsureHideFastNavigation();
37149  for(var i = this.pickerType; i <= this.maxViewType; i++) {
37150   var views = this.GetViews(i);
37151   for(var key in views) {
37152    if(views.hasOwnProperty(key)) {
37153     var view = views[key];
37154     if(!view.isASPxClientCalendarView) continue;
37155     view.ChangeEnabledStateItems(enabled);
37156    }
37157   }
37158  }
37159  this.UpdateInternal();   
37160 },
37161 ChangeButtonEnabledAttributes: function(element, method){
37162  method(element, "onclick");
37163  method(element, "ondblclick");
37164 },
37165 GetChangeButtonEnabledAttributesMethod: function(enabled) {
37166  return ASPx.Attr.ChangeAttributesMethod(enabled);
37167 },
37168 GetMinDate: function() {
37169  return this.sharedParameters.minDate;
37170 },
37171 SetMinDate: function(date) {
37172  date = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(date);
37173  date = ASPxClientCalendar.GetCorrectedDate(date, this.pickerType);
37174  this.sharedParameters.minDate = date;
37175  this.Update();
37176 },
37177 GetMaxDate: function() {
37178  return this.sharedParameters.maxDate;
37179 },
37180 SetMaxDate: function(date) {
37181  date = ASPxClientCalendarDateDisabledHelper.GetCorrectedDate(date);
37182  date = ASPxClientCalendar.GetCorrectedDate(date, this.pickerType);
37183  this.sharedParameters.maxDate = date;
37184  this.Update();
37185 },
37186 CheckDateEnabled: function(date){
37187  return !this.IsDateDisabled(date);
37188 },
37189 CanMouseDown: function(evt, date){
37190  if(!evt) return false;
37191  return ASPx.Evt.IsLeftButtonPressed(evt) && (!this.IsDateDisabled(date) || this.IsInlineFastNavigationActive());
37192 },
37193 CanMouseOver: function(date) {
37194  if(this.IsInlineFastNavigationActive())
37195   return false;
37196  if(this.forceMouseDown || this.isMouseDown || this.sharedParameters.dateRangeMode)
37197   return !this.IsDateDisabled(date);
37198  return false;
37199 },
37200 OnAssociatedLabelClick: function(evt) {
37201  ASPxClientCalendar.prototype.OnDelayedSpecialFocusMouseDown.call(this, evt);
37202 },
37203 getElementToObserveVisibilityChange: function () {
37204  return this.GetMainElement();
37205 },
37206 processVisibilityChanged: function (visible) {
37207  var focusHandlingInputForKeyboardSupport = this.GetMainElement().querySelector(".dxKBSI");
37208  ASPx.ToggleClassNameToElement(focusHandlingInputForKeyboardSupport, "dx-position-fixed", visible);
37209 }
37210});
37211ASPxClientCalendar.Cast = ASPxClientControl.Cast;
37212var AccessibilityHelperCalendar = ASPx.CreateClass(ASPx.AccessibilityHelper, {
37213 constructor: function(calendar) {
37214  this.constructor.prototype.constructor.call(this, calendar);
37215  this.control.GotFocus.AddHandler(function() { this.PronounceDates(this.control.GetSelectedDates(), true); }.aspxBind(this));
37216  this.control.LostFocus.AddHandler(function() { 
37217   setTimeout(function() { this.changeActivityAttributes(this.getMainElement(), { "aria-activedescendant": "" }); }.aspxBind(this), 200); 
37218  }.aspxBind(this));
37219  this.pickerType = calendar.pickerType;
37220 },
37221 PronounceDates: function(dates, useDescriptionText) {
37222  var datesText = this.getDatesText(dates);
37223  var dateEditInput = null;
37224  var activeItemArgs = null;
37225  var inactiveItemArgs = null;
37226  if(this.control.isDateEditCalendar) {
37227   var dateEdit = this.control.sharedParameters.currentDateEdit;
37228   if(dateEdit)
37229    dateEditInput = dateEdit.GetInputElement();
37230   activeItemArgs = {
37231    "role"    : "option",
37232    "aria-selected" : true
37233   };
37234   inactiveItemArgs = {
37235    "role"    : "",
37236    "aria-selected" : ""
37237   };
37238  }
37239  if(!this.control.isDateEditCalendar && useDescriptionText) 
37240   datesText = ASPx.AccessibilitySR.CalendarDescription + " " + datesText;
37241  this.PronounceMessage(datesText, activeItemArgs, inactiveItemArgs, null, dateEditInput);
37242 },
37243 getDatesText: function(dates) {
37244  var datesText = "";
37245  if(dates.length == 0)
37246   datesText = this.control.isDateEditCalendar ? ASPx.AccessibilitySR.CalendarDescription : ASPx.AccessibilitySR.BlankEditorText;
37247  else {
37248   dates.sort(function(x, y) { return x.valueOf() - y.valueOf(); });
37249   var ranges = this.getDateRanges(dates);
37250   datesText = this.getRangesText(ranges);
37251  }
37252  return datesText;
37253 },
37254 GetActiveElement: function(inputIsMainElement) {
37255  var activeElement = ASPx.AccessibilityHelper.prototype.GetActiveElement.call(this, inputIsMainElement);
37256  var mainElement = inputIsMainElement ? this.control.GetInputElement() : this.getMainElement();
37257  return activeElement == mainElement ? null : activeElement;
37258 },
37259 getRangesText: function(ranges) {
37260  var dateText = "";
37261  var hasMultiSelect = ranges.length > 1 || ranges.length === 1 && ranges[0].count > 1;
37262  if(hasMultiSelect)
37263   dateText = ASPx.AccessibilitySR.CalendarMultiSelectText;
37264  var rangesLength = ranges.length;
37265  var rangeDatesTextArray = [ ];
37266  for(var i = 0; i < rangesLength; i++)
37267   rangeDatesTextArray.push(this.getRangeText(ranges[i]));
37268  return dateText + rangeDatesTextArray.join(', ');
37269 },
37270 getRangeText: function(range) {
37271  var rangeFormatString = ASPx.AccessibilitySR.CalendarRangeFormatString;
37272  var startDateString = this.getDateString(range.start);
37273  if(range.count === 1)
37274   return startDateString;
37275  var endDateString = this.getDateString(ASPxClientCalendar.GetDateByOffset(range.start, range.count - 1, this.pickerType));
37276  return ASPx.Str.ApplyReplacement(rangeFormatString, [["{0}", startDateString], ["{1}", endDateString]]);
37277 },
37278 getDateString: function(date) {
37279  var dateStringArray = [ ];
37280  dateStringArray.push(ASPx.CultureInfo.dayNames[date.getDay()]);
37281  dateStringArray.push(ASPx.CultureInfo.monthNames[date.getMonth()]);
37282  dateStringArray.push(date.getDate());
37283  dateStringArray.push(date.getFullYear());
37284  return dateStringArray.join(' ');
37285 },
37286 getDateRanges: function(dates) {
37287  var ranges = [ ];
37288  var start = null;
37289  var end = null;
37290  for(var i = 0; i < dates.length; i++) {
37291   var d1 = dates[i];
37292   var d2 = i < dates.length ? dates[i + 1] : d1;
37293   if(!start)
37294    start = end = d1;
37295   if(this.isNeibourDates(d1, d2)) {
37296    end = d2;
37297   } else {
37298    ranges.push({ start: start, count: ASPxClientCalendar.GetPeriodsInRange(start, end, this.pickerType) });
37299    start = end = null;
37300   }
37301  }
37302  return ranges;
37303 },
37304 isNeibourDates: function(date1, date2) {
37305  var nextDate = ASPxClientCalendar.GetNextDate(date1, this.pickerType);
37306  return ASPxClientCalendar.AreDatesEqual(nextDate, date2);
37307 }
37308});
37309var ASPxClientCalendarCustomDisabledDateEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
37310 constructor: function(date) {
37311  this.constructor.prototype.constructor.call(this);
37312  this.date = date;
37313  this.isDisabled = false;
37314 }
37315});
37316ASPxClientCalendar.AnonymousHandlers = { 
37317 MainElementClick: function(name) {
37318  return function(e) {
37319   var cal = ASPx.GetControlCollection().Get(name);
37320   if(cal)
37321    cal.OnMainElementClick(e);
37322  };
37323 },
37324 SelectMonth: function(name, row, column) {
37325  return function() {
37326   var cal = ASPx.GetControlCollection().Get(name);
37327   if(cal)
37328    cal.OnSelectMonth(row, column);
37329  };
37330 },
37331 NavigationButtonClick: function(name, offset, isVisibleInAdaptiveOnly) {
37332  return function() {
37333   var cal = ASPx.GetControlCollection().Get(name);
37334   if(cal)
37335    cal.OnNavigationImageClick(offset, isVisibleInAdaptiveOnly);
37336  };
37337 },
37338 TitleClick: function(name, row, column) {
37339  return function() {
37340   var cal = ASPx.GetControlCollection().Get(name);
37341   if(cal)
37342    cal.OnTitleClick(row, column);
37343  };
37344 },
37345 DayMouseEvent: function(name, row, column, index, byWeeks) {
37346  return function(e) {
37347   var cal = ASPx.GetControlCollection().Get(name);
37348   if(!cal)
37349    return;
37350   var view = cal.GetActiveView(row, column);
37351   if(!view.isNavigationView && cal.GetReadOnly())
37352    return;
37353   var date = view.GetDateByIndex(index);
37354   if(byWeeks)
37355    date = ASPxClientCalendar.AddDays(date, cal.firstDayOfWeek - date.getDay());
37356   var allowed = ASPxClientCalendarDateDisabledHelper.IsDateInRange(cal.sharedParameters, date) && (view.IsDateVisible(date) || byWeeks);
37357   if(view.isNavigationView)
37358    allowed = view.IsDateVisible(date);
37359   switch(e.type) {
37360    case "mousedown":
37361     if(allowed && cal.CanMouseDown(e, date)) {
37362      var ctrl = e.ctrlKey || ASPx.Browser.MacOSPlatform && e.metaKey;
37363      cal.OnDayMouseDown(date, e.shiftKey, ctrl, byWeeks);
37364     }
37365     break;
37366    case "mouseover":
37367     if(allowed && cal.CanMouseOver(date)) {
37368      if(cal.forceMouseDown)
37369       cal.OnDayMouseDown(date, false, false, false);
37370      else if (cal.isMouseDown || cal.sharedParameters.dateRangeMode)
37371       cal.OnDayMouseOver(date);
37372     }
37373     break;
37374    case "mouseup":
37375     if(cal.isMouseDown && !view.isNavigationView) {
37376      if(allowed && !cal.IsDateDisabled(date))
37377       cal.OnDayMouseUp(date);
37378      else
37379       cal.OnSelectionCancelled();
37380     }
37381     break;
37382    case "mouseout":
37383     if(cal.sharedParameters.dateRangeMode && !view.isNavigationView) {
37384      var isAllowedOverDate = false;
37385      var overCell = ASPx.Evt.GetEventRelatedTarget(e, false);
37386      var overCellIndex = view.GetDayCellIndex(overCell);
37387      if (ASPx.IsExists(overCellIndex)) {
37388       var overDate = view.GetDateByIndex(overCellIndex);
37389       isAllowedOverDate = overDate && ASPxClientCalendarDateDisabledHelper.IsDateInRange(cal.sharedParameters, overDate) && view.IsDateVisible(overDate) && !cal.IsDateDisabled(overDate);
37390      }
37391      if (!isAllowedOverDate) {
37392       cal.RaiseVisibleDaysMouseOut();
37393      }
37394     }
37395     break;
37396   }     
37397  };
37398 },
37399 FastNavMonthClick: function(name, month) {
37400  return function() {
37401   var cal = ASPx.GetControlCollection().Get(name);
37402   if(cal) {
37403    cal.fastNavigation.OnMonthClick(month);
37404   }
37405  };
37406 },
37407 FastNavYearClick: function(name, index) {
37408  return function() {
37409   var cal = ASPx.GetControlCollection().Get(name);
37410   if(cal)
37411    cal.fastNavigation.OnYearClick(index);
37412  };
37413 }
37414};
37415ASPxClientCalendar.GetMinDate = function(date1, date2) {
37416 return date1 < date2 ? date1 : date2;
37417};
37418ASPxClientCalendar.GetMaxDate = function(date1, date2) {
37419 return date1 > date2 ? date1 : date2;
37420};
37421ASPxClientCalendar.AddSelectedRangeVisiblePartToSelection = function(selection, selectedRangeRestrictions, visibleRangeRestrictions) {
37422 selection.Add(selectedRangeRestrictions.start);
37423 selection.Add(selectedRangeRestrictions.end);
37424 var bothRangeRestrictsLessThanVisibleStartDate = selectedRangeRestrictions.start < visibleRangeRestrictions.start
37425  && selectedRangeRestrictions.end < visibleRangeRestrictions.start;
37426 var bothRangeRestrictsGreaterThanVisibleEndDate = selectedRangeRestrictions.start > visibleRangeRestrictions.end
37427  && selectedRangeRestrictions.end > visibleRangeRestrictions.end;
37428 var rangeHasVisiblePart = !bothRangeRestrictsLessThanVisibleStartDate && !bothRangeRestrictsGreaterThanVisibleEndDate;
37429 if(rangeHasVisiblePart) {
37430  var requiredSelectionStart = ASPxClientCalendar.GetMaxDate(selectedRangeRestrictions.start, visibleRangeRestrictions.start);
37431  var requiredSelectionEnd = ASPxClientCalendar.GetMinDate(selectedRangeRestrictions.end, visibleRangeRestrictions.end);
37432  selection.AddRange(requiredSelectionStart, requiredSelectionEnd);
37433 }
37434};
37435ASPxClientCalendar.AreDatesEqual = function(date1, date2) {
37436 if(date1 == date2)  
37437  return true;
37438 if(!date1 || !date2)
37439  return false;
37440 return date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth() && date1.getDate() == date2.getDate();
37441};
37442ASPxClientCalendar.IsFirstDateEqualToAnyOther = function () {
37443 var actualDate = arguments[0];
37444 for (var i = 1; i < arguments.length; i++)
37445  if (ASPxClientCalendar.AreDatesEqual(actualDate, arguments[i]))
37446   return true;
37447 return false;
37448};
37449ASPxClientCalendar.AreDatesOfSameMonth = function(date1, date2) {
37450 if(!date1 || !date2)
37451  return false;
37452 return date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth();
37453};
37454ASPxClientCalendar.AreDatesOfSameYear = function(date1, date2) {
37455 if(!date1 || !date2)
37456  return false;
37457 return date1.getFullYear() == date2.getFullYear();
37458};
37459ASPxClientCalendar.AreDatesOfSameDecade = function(date1, date2) {
37460 if(!date1 || !date2)
37461  return false;
37462 return ASPxClientCalendar.GetDecadeStartYear(date1.getFullYear()) == ASPxClientCalendar.GetDecadeStartYear(date2.getFullYear());
37463};
37464ASPxClientCalendar.AreDatesOfSameCentury = function(date1, date2) {
37465 if(!date1 || !date2)
37466  return false;
37467 return ASPxClientCalendar.GetCenturyStartYear(date1.getFullYear()) == ASPxClientCalendar.GetCenturyStartYear(date2.getFullYear());
37468};
37469ASPxClientCalendar.AreDatesOfSamePeriod = function(date1, date2, viewT
37469ype) {
37470 if(viewType == ASPx.DatePickerType.Days)
37471  return ASPxClientCalendar.AreDatesOfSameMonth(date1, date2);
37472 if(viewType == ASPx.DatePickerType.Months)
37473  return ASPxClientCalendar.AreDatesOfSameYear(date1, date2);
37474 if(viewType == ASPx.DatePickerType.Years)
37475  return ASPxClientCalendar.AreDatesOfSameDecade(date1, date2);
37476 if(viewType == ASPx.DatePickerType.Decades)
37477  return ASPxClientCalendar.AreDatesOfSameCentury(date1, date2);
37478};
37479ASPxClientCalendar.GetUTCTime = function(date) {
37480 return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate());
37481};
37482ASPxClientCalendar.GetFirstDayOfYear = function(date) {
37483 return new Date(date.getFullYear(), 0, 1);  
37484};
37485ASPxClientCalendar.GetDayOfYear = function(date) {
37486 var ms = ASPxClientCalendar.GetUTCTime(date) - 
37487  ASPxClientCalendar.GetUTCTime(ASPxClientCalendar.GetFirstDayOfYear(date));
37488 return 1 + Math.floor(ms / ASPx.calendarMsPerDay);
37489};
37490ASPxClientCalendar.GetISO8601WeekOfYear = function(date) {
37491 var firstDate = new Date(date.getFullYear(), 0, 1);
37492 var firstDayOfWeek = firstDate.getDay();
37493 if(firstDayOfWeek == 0)
37494  firstDayOfWeek = 7;
37495 var daysInFirstWeek = 8 - firstDayOfWeek;
37496 var lastDate = new Date(date.getFullYear(), 11, 31);   
37497 var lastDayOfWeek = lastDate.getDay();
37498 if(lastDayOfWeek == 0)
37499  lastDayOfWeek = 7;
37500 var fullWeeks = Math.ceil((ASPxClientCalendar.GetDayOfYear(date) - daysInFirstWeek) / 7);
37501 var result = fullWeeks;   
37502 if(daysInFirstWeek > 3)
37503  result++;
37504 var isThursday = firstDayOfWeek == 4 || lastDayOfWeek == 4;
37505 if(result > 52 && !isThursday)
37506  result = 1;
37507 if(result == 0)
37508  return ASPxClientCalendar.GetISO8601WeekOfYear(new Date(date.getFullYear() - 1, 11, 31));
37509 return result;
37510};
37511ASPxClientCalendar.GetNextWeekDate = function(date) {
37512 var ret = new Date(date.getTime()); 
37513 var newDay = date.getDate() + 7;
37514 ret.setDate(newDay);
37515 return ret;
37516};
37517ASPxClientCalendar.GetPrevWeekDate = function(date) {
37518 var ret = new Date(date.getTime());
37519 var newDay = date.getDate() - 7;
37520 ret.setDate(newDay);
37521 return ret;
37522};
37523ASPxClientCalendar.GetYesterDate = function(date) {
37524 var ret = new Date(date.getTime());
37525 ret.setDate(ret.getDate() - 1);
37526 return ret;
37527};
37528ASPxClientCalendar.GetTomorrowDate = function(date) {
37529 var ret = new Date(date.getTime());
37530 ret.setDate(ret.getDate() + 1);
37531 return ret;
37532};
37533ASPxClientCalendar.GetNextMonthDate = function(date) {
37534 var ret = new Date(date.getTime());
37535 var maxDateInNextMonth = ASPxClientCalendar.GetDaysInMonth(ret.getMonth() + 1, ret.getFullYear());
37536 if(ret.getDate() > maxDateInNextMonth)
37537  ret.setDate(maxDateInNextMonth);
37538 ret.setMonth(ret.getMonth() + 1);
37539 return ret;
37540};
37541ASPxClientCalendar.GetNextYearDate = function(date) {
37542 return ASPxClientCalendar.GetDateWithYearOffset(date, 1);
37543};
37544ASPxClientCalendar.GetDateWithYearOffset = function(date, offset) {
37545 var ret = new Date(date.getTime());
37546 var maxDateInPrevYearMonth = ASPxClientCalendar.GetDaysInMonth(ret.getMonth(), ret.getFullYear() + offset);
37547 if(ret.getDate() > maxDateInPrevYearMonth)
37548  ret.setDate(maxDateInPrevYearMonth);
37549 ret.setFullYear(ret.getFullYear() + offset);
37550 return ret;
37551};
37552ASPxClientCalendar.GetPrevMonthDate = function(date) {
37553 var ret = new Date(date.getTime());
37554 var maxDateInPrevMonth = ASPxClientCalendar.GetDaysInMonth(ret.getMonth() - 1, ret.getFullYear());
37555 if(ret.getDate() > maxDateInPrevMonth)
37556  ret.setDate(maxDateInPrevMonth);
37557 ret.setMonth(ret.getMonth() - 1);
37558 return ret;
37559};
37560ASPxClientCalendar.GetPrevYearDate = function(date) {
37561 return ASPxClientCalendar.GetDateWithYearOffset(date, -1);
37562 };
37563ASPxClientCalendar.GetFirstDayInWeek = function(date, firstDayOfWeek) {
37564 var offset = date.getDay() - firstDayOfWeek;
37565 if(offset < 0)
37566  offset += 7;
37567 return ASPxClientCalendar.AddDays(date, -offset);
37568};
37569ASPxClientCalendar.GetLastDayInWeek = function(date,firstDayOfWeek) {
37570 return ASPxClientCalendar.AddDays(ASPxClientCalendar.GetFirstDayInWeek(date, firstDayOfWeek), 6);
37571};
37572ASPxClientCalendar.GetFirstDayInMonthDate = function(date) {
37573 var ret = new Date(date.getTime());
37574 ret.setDate(1);
37575 return ret;
37576};
37577ASPxClientCalendar.GetLastDayInMonthDate = function(date) {
37578 var ret = new Date(date.getTime());
37579 var maxDateInYearMonth = ASPxClientCalendar.GetDaysInMonth(ret.getMonth(), ret.getFullYear());
37580 ret.setDate(maxDateInYearMonth);
37581 return ret;
37582};
37583ASPxClientCalendar.AddDays = function(startDate, dayCount) {
37584 var date = ASPxClientCalendar.CloneDate(startDate);
37585 var dayDiff = 0;
37586 var hourInc = 3600000;
37587 if(dayCount < 0)
37588  hourInc = -1 * hourInc;
37589 dayCount = Math.abs(dayCount);
37590 while(true) {
37591  if(dayDiff == dayCount && startDate.getHours() == date.getHours())
37592   return date;
37593  if(dayDiff > dayCount) {
37594   date.setTime(-1 * hourInc + date.getTime());
37595   return date;
37596  }
37597  var day = date.getDate();
37598  date.setTime(hourInc + date.getTime());
37599  if(day != date.getDate())
37600   dayDiff++;
37601 }
37602 return date;
37603};
37604ASPxClientCalendar.AddMonths = function(date, count) {
37605 var newDate = ASPxClientCalendar.CloneDate(date);
37606 newDate.setMonth(count + newDate.getMonth());
37607 ASPx.DateUtils.FixTimezoneGap(date, newDate);
37608 if(newDate.getDate() < date.getDate())
37609  newDate = ASPxClientCalendar.AddDays(newDate, -newDate.getDate()); 
37610 return newDate;
37611};
37612ASPxClientCalendar.AddYears = function(date, count) {
37613 var newDate = ASPxClientCalendar.CloneDate(date);
37614 newDate.setFullYear(count + newDate.getFullYear());
37615 ASPx.DateUtils.FixTimezoneGap(date, newDate);
37616 return newDate;
37617};
37618ASPxClientCalendar.GetNextDate = function(date, viewType) {
37619 return ASPxClientCalendar.GetDateByOffset(date, 1, viewType);
37620};
37621ASPxClientCalendar.GetDateByOffset = function(date, offset, viewType) {
37622 if(viewType == ASPx.DatePickerType.Days)
37623  return ASPxClientCalendar.AddDays(date, offset);
37624 if(viewType == ASPx.DatePickerType.Months)
37625  return ASPxClientCalendar.AddMonths(date, offset);
37626 if(viewType == ASPx.DatePickerType.Years)
37627  return ASPxClientCalendar.AddYears(date, offset);
37628 if(viewType == ASPx.DatePickerType.Decades)
37629  return ASPxClientCalendar.AddYears(date, offset * 10);
37630};
37631ASPxClientCalendar.CloneDate = function(date) {
37632 var cloned = new Date();
37633 cloned.setTime(date.getTime());
37634 return cloned;
37635};
37636ASPxClientCalendar.GetDecadeStartYear = function(year) {
37637 return ASPx.DateUtils.GetDecadeStartYear(year);
37638};
37639ASPxClientCalendar.GetCenturyStartYear = function(year) {
37640 return ASPx.DateUtils.GetCenturyStartYear(year);
37641};
37642ASPxClientCalendar.GetDaysInRange = function(start, end) {
37643 return 1 + (ASPxClientCalendar.GetUTCTime(end) - ASPxClientCalendar.GetUTCTime(start)) / ASPx.calendarMsPerDay;
37644};
37645ASPxClientCalendar.GetDaysInMonth = function(month, year) {
37646 var d = new Date(year, month + 1, 0);
37647 return d.getDate();
37648};
37649ASPxClientCalendar.GetOffsetInMonths = function(start, end) {
37650 return end.getMonth() - start.getMonth() + 12 * (end.getFullYear() - start.getFullYear());
37651};
37652ASPxClientCalendar.GetOffsetInYears = function(start, end) {
37653 return end.getFullYear() - start.getFullYear();
37654};
37655ASPxClientCalendar.GetOffsetInDecades = function(start, end) {
37656 return (ASPxClientCalendar.GetDecadeStartYear(end.getFullYear()) - ASPxClientCalendar.GetDecadeStartYear(start.getFullYear())) / 10;
37657};
37658ASPxClientCalendar.GetOffsetInCenturies = function(start, end) {
37659 return (ASPxClientCalendar.GetCenturyStartYear(end.getFullYear()) - ASPxClientCalendar.GetCenturyStartYear(start.getFullYear())) / 100;
37660};
37661ASPxClientCalendar.GetOffsetInPeriods = function(start, end, viewType) {
37662 if(viewType == ASPx.DatePickerType.Days)
37663  return ASPxClientCalendar.GetOffsetInMonths(start, end);
37664 if(viewType == ASPx.DatePickerType.Months)
37665  return ASPxClientCalendar.GetOffsetInYears(start, end);
37666 if(viewType == ASPx.DatePickerType.Years)
37667  return ASPxClientCalendar.GetOffsetInDecades(start, end);
37668 if(viewType == ASPx.DatePickerType.Decades)
37669  return ASPxClientCalendar.GetOffsetInCenturies(start, end);
37670};
37671ASPxClientCalendar.GetPeriodsInRange = function(start, end, pickerType) {
37672 if(pickerType == ASPx.DatePickerType.Days)
37673  return ASPxClientCalendar.GetDaysInRange(start, end);
37674 if(pickerType == ASPx.DatePickerType.Months)
37675  return ASPxClientCalendar.GetOffsetInMonths(start, end) + 1;
37676 if(pickerType == ASPx.DatePickerType.Years)
37677  return ASPxClientCalendar.GetOffsetInYears(start, end) + 1;
37678 if(pickerType == ASPx.DatePickerType.Decades)
37679  return ASPxClientCalendar.GetOffsetInDecades(start, end) + 1;
37680};
37681ASPxClientCalendar.GetCorrectedDate = function(date, viewType) {
37682 return ASPx.DateUtils.CorrectDateByPickerType(date, viewType);
37683};
37684var ASPxClientCalendarDateDisabledHelper = {
37685 MinDate: new Date(100, 0, 1, 0, 0, 0, 0),
37686 MaxDate: new Date(9999, 11, 31, 23, 59, 59, 999),
37687 GetUpperLimitDate: function() {
37688  return this.MaxDate;
37689 },
37690 GetLowerLimitDate: function() {
37691  return this.MinDate;
37692 },
37693 IsDateWithinBoundaries: function(date) {
37694  return date >= this.GetLowerLimitDate() && date <= this.GetUpperLimitDate();
37695 },
37696 GetCorrectedDate: function(date) {
37697  if(!date)
37698   return null;
37699  if(this.IsDateWithinBoundaries(date))
37700   return date;
37701  else
37702   return date > this.GetUpperLimitDate() ? this.GetUpperLimitDate() : this.GetLowerLimitDate();
37703 },
37704 IsDateInRange: function(sharedParameters, date, keepTimePart) {
37705  if(date == null)
37706   return true;
37707  return this.IsDateFitToMinDate(date, sharedParameters.minDate, keepTimePart) && this.IsDateFitToMaxDate(date, sharedParameters.maxDate, keepTimePart) && this.IsDateWithinBoundaries(date);
37708 },
37709 IsDateFitToMinDate: function(date, minDate, keepTimePart) {
37710  if(minDate === null)
37711   return true;
37712  if(!keepTimePart)
37713   minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
37714  return date >= minDate;
37715 },
37716 IsDateFitToMaxDate: function(date, maxDate, keepTimePart) {
37717  if(maxDate === null)
37718   return true;
37719  if(!keepTimePart)
37720   maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999);
37721  return date <= maxDate;
37722 },
37723 IsDateDisabled: function(sharedParameters, date, OnCustomDisabledDate, viewType, pickerType) {
37724  if(viewType !== pickerType)
37725   return false;
37726  if(date != null) {
37727   var length = sharedParameters.disabledDates.length;
37728   var correctedDate = ASPxClientCalendar.CloneDate(date);
37729   if(length > 0 && date != null) {
37730    correctedDate = ASPxClientCalendar.GetCorrectedDate(date, pickerType);
37731    for(var i = 0; i < length; i++) {
37732     var disabledDate = sharedParameters.disabledDates[i];
37733     if(disabledDate.getDate() == correctedDate.getDate() &&
37734      disabledDate.getMonth() == correctedDate.getMonth() &&
37735      disabledDate.getFullYear() == correctedDate.getFullYear())
37736      return true;
37737    }
37738   }
37739   if(OnCustomDisabledDate(correctedDate).isDisabled)
37740    return true;
37741  }
37742  return false;
37743 }
37744};
37745var ASPxClientCalendarSelection = ASPx.CreateClass(null, {
37746 constructor: function() {
37747  this.dates = { };
37748  this.count = 0;
37749  this.pickerType = ASPx.DatePickerType.Days;
37750 },
37751 SetPickerType: function(pickerType) {
37752  this.pickerType = pickerType;
37753 },
37754 Assign: function(source) {
37755  this.Clear();
37756  for(var key in source.dates) {
37757   if(source.dates.hasOwnProperty(key)) {
37758    var item = source.dates[key];
37759    if(item.constructor != Date) continue;
37760    this.Add(item);
37761   }
37762  }
37763 },
37764 Clear: function() {
37765  if(this.count > 0) {
37766   this.dates = { };
37767   this.count = 0;
37768  }
37769 },
37770 Equals: function(selection) {
37771  if(this.count != selection.count)
37772   return false;
37773  for(var key in this.dates) {
37774   if(this.dates.hasOwnProperty(key)) {
37775    if(this.dates[key].constructor != Date) continue;
37776    if(!selection.ContainsKey(key))
37777     return false;
37778   }
37779  }
37780  return true;
37781 },
37782 Contains: function(date) {
37783  var key = this.GetKey(this.GetCorrectedDate(date));
37784  return this.ContainsKey(key);
37785 },
37786 ContainsKey: function(key) {
37787  return !!this.dates[key];
37788 },
37789 GetCorrectedDate: function(date) {
37790  return ASPxClientCalendar.GetCorrectedDate(date, this.pickerType);
37791 },
37792 GetCorrectedYear: function(date) {
37793  var year = date.getFullYear();
37794  return this.pickerType != ASPx.DatePickerType.Decades ? year : ASPxClientCalendar.GetDecadeStartYear(year);
37795 },
37796 GetCorrectedMonth: function(date) {
37797  return this.pickerType < ASPx.DatePickerType.Years ? date.getMonth() : 0;
37798 },
37799 GetCorrectedDay: function(date) {
37800  return this.pickerType == ASPx.DatePickerType.Days ? date.getDate() : 1;
37801 },
37802 Add: function(date) {
37803  var correctedDate = this.GetCorrectedDate(date);
37804  var key = this.GetKey(correctedDate);
37805  if(!this.ContainsKey(key)) {
37806   this.dates[key] = ASPxClientCalendar.CloneDate(correctedDate);
37807   this.count++;
37808  }
37809 },
37810 AddArray: function(dates) {
37811  for(var i = 0; i < dates.length; i++)
37812   this.Add(dates[i]);
37813 },
37814 AddRange: function(start, end) {
37815  var correctedStart = this.GetCorrectedDate(start);
37816  var correctedEnd = this.GetCorrectedDate(end);
37817  if(correctedEnd < correctedStart) {
37818   this.AddRange(correctedEnd, correctedStart);
37819   return;
37820  }
37821  var date = ASPxClientCalendar.CloneDate(correctedStart);
37822  while(date <= correctedEnd) {
37823   this.Add(date);
37824   date = ASPxClientCalendar.GetNextDate(date, this.pickerType);
37825  }
37826 },
37827 AddWeek: function(startDate) {
37828  this.AddRange(startDate, ASPxClientCalendar.AddDays(startDate, 6));
37829 },
37830 SetRestrictions: function(start, end) {
37831  this.startDate = this.GetCorrectedDate(ASPxClientCalendar.CloneDate(start));
37832  this.endDate = this.GetCorrectedDate(ASPxClientCalendar.CloneDate(end));
37833 },
37834 ResetRestrictions: function() {
37835  this.startDate = null;
37836  this.endDate = null;
37837 },
37838 Remove: function(date) {
37839  var correctedDate = this.GetCorrectedDate(date);
37840  var key = this.GetKey(correctedDate);
37841  if(this.ContainsKey(key)) {
37842   delete this.dates[key];
37843   this.count--;
37844  }
37845 },
37846 RemoveArray: function(dates) {
37847  for(var i = 0; i < dates.length; i++)
37848   this.Remove(dates[i]);
37849 },
37850 RemoveRange: function(start, end) {
37851  var correctedStart = this.GetCorrectedDate(start);
37852  var correctedEnd = this.GetCorrectedDate(end);
37853  if(correctedEnd < correctedStart) {
37854   this.RemoveRange(correctedEnd, correctedStart);
37855   return;
37856  }
37857  var date = ASPxClientCalendar.CloneDate(correctedStart);
37858  while(date <= correctedEnd) {
37859   this.Remove(date);
37860   date = ASPxClientCalendar.GetNextDate(date, this.pickerType);
37861  }
37862 },
37863 RemoveWeek: function(startDate) {
37864  this.RemoveRange(startDate, ASPxClientCalendar.AddDays(startDate, 6));
37865 },
37866 GetDates: function() {
37867  var result = [ ];
37868  for(var key in this.dates) {
37869   if(this.dates.hasOwnProperty(key)) {
37870    var item = this.dates[key];
37871    if(item.constructor != Date) continue;
37872    result.push(ASPxClientCalendar.CloneDate(item));
37873   }
37874  }
37875  return result;  
37876 },
37877 GetFirstDate: function() {
37878  if(this.count == 0)
37879   return null;
37880  for(var key in this.dates) {
37881   if(this.dates.hasOwnProperty(key)) {
37882    var item = this.dates[key];
37883    if(item.constructor != Date) continue;
37884    return ASPxClientCalendar.CloneDate(item);
37885   }
37886  }
37887  return null;
37888 },
37889 GetKey: function(date) {  
37890  return ASPx.DateUtils.GetInvariantDateString(date);
37891 }
37892});
37893var ASPxClientCalendarSelectionTransaction = ASPx.CreateClass(null, {
37894 constructor: function(calendar) {
37895  this.calendar = calendar;
37896  this.isActive = false;
37897  this.backup = new ASPxClientCalendarSelection();
37898  this.selection = new ASPxClientCalendarSelection();
37899  this.backup.SetPickerType(calendar.pickerType);
37900  this.selection.SetPickerType(calendar.pickerType);
37901 },
37902 Start: function() {
37903  if(this.isActive)
37904   this.Rollback();
37905  this.backup.Assign(this.calendar.selection);
37906  this.selection.Clear();
37907  this.isActive = true;
37908  ASPx.activeCalendar = this.calendar;
37909 },
37910 Commit: function() {  
37911  this.calendar.ApplySelectionByDiff(this.selection, true);
37912  this.Reset();
37913 },
37914 Rollback: function() {
37915  this.calendar.ApplySelectionByDiff(this.backup);  
37916  this.Reset();
37917 },
37918 Reset: function() {
37919  this.backup.Clear();
37920  this.selection.Clear();
37921  this.isActive = false;
37922  ASPx.activeCalendar = null;
37923 },
37924 CopyFromBackup: function() {
37925  this.selection.Assign(this.backup);
37926 },
37927 IsChanged: function() {
37928  return !this.backup.Equals(this.selection);
37929 }
37930});
37931var ASPxClientCalendarView = ASPx.CreateClass(null, {
37932 constructor: function(calendar, row, column) {
37933  this.row = row;
37934  this.column = column;
37935  this.calendar = calendar;
37936  this.isASPxClientCalendarView = true;
37937  var temp = column + row;
37938  this.isLowBoundary = temp == 0;
37939  this.isHighBoundary = temp == calendar.rows + calendar.columns - 2;
37940  this.isLastViewInFirstRow = row == 0 && column == calendar.columns - 1;
37941  this.visibleDate = null;
37942  this.startDate = null;
37943  this.dayFunctions = {};
37944  this.dayStyleCache = {};
37945  this.dayCellCache = {};
37946  this.navButtonFunctions = {};
37947  this.titleFunction = null;
37948  this.isNavigationView = this.GetViewType() > this.calendar.pickerType;
37949  this.isFirstNavigationView = this.GetViewType() === ASPx.DatePickerType.Months;
37950  this.isLastNavigationView = this.GetViewType() === this.calendar.maxViewType;
37951 },
37952 Initialize: function() {
37953  if(!this.isNavigationView || this.isFirstNavigationView) {
37954   this.UpdateDate();
37955   this.AddHoverStateItems();
37956   if(!this.isNavigationView) {
37957    this.UpdateTitle();
37958    this.EnsureSelection();
37959    this.MakeDisabledStateItems();
37960   }
37961  }
37962 },
37963 GetDateFunctionsHash: function(selectWeeks) {
37964  return this.dayFunctions;
37965 },
37966 GetViewCell: function() {
37967  return this.calendar.GetViewCell(this.calendar.IsMultiView() ? this.GetIDPostfix() : "");
37968 },
37969 GetIndex: function() {
37970  return this.row * this.calendar.columns + this.column;
37971 },
37972 GetTitleCell: function() {
37973  return this.GetChildElement("TC");
37974 },
37975 GetTitleElement: function() {
37976  return this.GetChildElement("T") || this.GetTitleCell();
37977 },
37978 EnsureVisible: function(visible) {
37979  if(this.calendar.switchToSingleMonthAtWindowInnerWidth <= 0) return;
37980  var cell = this.GetViewCell();
37981  ASPx.ToggleClassNameToElement(cell, "view-visible", visible);
37982 },
37983 AttachCancelSelect: function(method, element) {
37984  method(element, "mouseup", aspxCalCancelSelect);
37985 },
37986 IsValidIndex: function(index) {
37987  return index >= 0 && index <= this.GetMaxIndex();
37988 },
37989 GetIDPostfix: function() {
37990  return "_" + this.row.toString() + "x" + this.column.toString();
37991 },
37992 GetChildElement: function(postfix) {
37993  if(this.calendar.IsMultiView())
37994   postfix += this.GetIDPostfix();
37995  return this.calendar.GetChildElement(postfix);
37996 },
37997 AttachDayMouseEvents: function(method, cell, handler) {
37998  var types = ["down", "up", "over", "out"];
37999  for(var i = 0; i < types.length; i++)
38000   method(cell, "mouse" + types[i], handler);
38001 },
38002 GetDayMouseEventFunction: function(index, selectWeeks) {
38003  var hash = this.GetDateFunctionsHash(selectWeeks);
38004  if(!hash[index])
38005   hash[index] = ASPxClientCalendar.AnonymousHandlers.DayMouseEvent(this.calendar.name, this.row, this.column, index, selectWeeks);
38006  return hash[index];
38007 },
38008 GetNavButtonFunction: function(buttonID, offset, isVisibleInAdaptiveOnly) {
38009  if(!this.navButtonFunctions[buttonID])
38010   this.navButtonFunctions[buttonID] = ASPxClientCalendar.AnonymousHandlers.NavigationButtonClick(this.calendar.name, offset, isVisibleInAdaptiveOnly);
38011  return this.navButtonFunctions[buttonID];
38012 },
38013 GetTitleFunction: function() {
38014  if(!this.titleFunction)
38015   this.titleFunction = ASPxClientCalendar.AnonymousHandlers.TitleClick(this.calendar.name, this.row, this.column);
38016  return this.titleFunction;
38017 },
38018 UpdateDate: function() {
38019  this.visibleDate = this.GetCurrentVisibleDate();
38020  var date = ASPxClientCalendar.CloneDate(this.visibleDate);
38021  date.setDate(1);
38022  this.UpdateNavigationCells(date);
38023  this.startDate = this.GetCurrentStartDate(date);
38024 },
38025 UpdateTitle: function() {
38026  var el = this.GetTitleElement();
38027  if(!el) return;
38028  el.innerHTML = this.GetTitleText();
38029  el.style.cursor = this.isLastNavigationView && !this.calendar.showFastPopup ? "default" : ASPx.GetPointerCursor();
38030 },
38031 GetActualTodayDate: function() {
38032  if(!this.calendar || !this.calendar.actualTodayDate)
38033   return ASPxClientCalendar.GetCorrectedDate(new Date(), this.GetViewType());
38034  return this.calendar.actualTodayDate;
38035 },
38036 IsDateVisible: function(date) {
38037  var result = !this.calendar.IsMultiView() || !this.IsDateOtherPeriod(date);
38038  if(!result) {
38039   result = result || this.isLowBoundary && date <= this.visibleDate ||
38040    this.isHighBoundary && date >= this.visibleDate;
38041  }
38042  return result;
38043 },
38044 GetDayCell: function(index) {
38045  if(ASPx.IsExistsElement(this.dayCellCache[index]))
38046   return this.dayCellCache[index];
38047  var dateContainer = this.GetDateCellContainer();
38048  var colIndex = this.GetDateCellColIndex(index);
38049  var rowIndex = this.GetDateCellRowIndex(index);
38050  var cell = dateContainer.rows[rowIndex].cells[colIndex];
38051  this.dayCellCache[index] = cell;
38052  return cell;
38053 },
38054 GetDayCellIndex: function(cell) {
38055  var currentDate = ASPxClientCalendar.CloneDate(this.startDate);
38056  var maxIndex = this.GetMaxIndex();
38057  var currentIndex = 0;
38058  do {
38059   currentIndex = this.GetIndexByDate(currentDate);
38060   if(this.GetDayCell(currentIndex) === cell)
38061    return currentIndex;
38062   currentDate = this.GetNextDate(currentDate);
38063  }
38064  while(currentIndex < maxIndex);
38065  return null;
38066 },
38067 ChangeTitleElementEnabledAttributes: function(element, method) {
38068  method(element, "cursor");
38069 },
38070 RemoveDayCellStyle: function(cell, suffix) {
38071  var info = new ASPxClientCalendarStyleInfo();
38072  this.calendar.ImportEtalonStyle(info, suffix);
38073  info.Remove(cell);
38074 },
38075 ApplySelectionToCell: function(index, showSelection, applyDateInRangeStyle) {
38076  var cell = this.GetDayCell(index);
38077  var info;
38078  if(showSelection) {
38079   if(this.GetStateController())
38080    this.GetStateController().DoClearHoverState(cell);
38081   if(!this.dayStyleCache[index]) {
38082    var backup = new ASPxClientCalendarStyleInfo();
38083    backup.Import(cell);
38084    this.dayStyleCache[index] = backup;
38085    info = backup.Clone();
38086   } else
38087    info = this.dayStyleCache[index].Clone();
38088   if(!applyDateInRangeStyle || this.calendar.NeedApplySelectionToDayInRange())
38089    this.calendar.ImportEtalonStyle(info, this.GetCellSelectedStyleName());
38090  } else
38091   info = this.dayStyleCache[index];
38092  info.Apply(cell);
38093  if(applyDateInRangeStyle) {
38094   if(showSelection)
38095    ASPx.AddClassNameToElement(cell, this.calendar.GetDayInRangeClassName());
38096   else
38097    ASPx.RemoveClassNameFromElement(cell, this.calendar.GetDayInRangeClassName());
38098  }
38099 },
38100 UpdateSelection: function(dates, showSelection, totalSelectionEdges) {
38101  if(ASPx.Ident.IsArray(dates))
38102   for(var i = 0; i < dates.length; i++)
38103    this.UpdateDateSelection(dates[i], showSelection, totalSelectionEdges);
38104  else
38105   this.UpdateDateSelection(dates, showSelection, totalSelectionEdges);
38106 },
38107 UpdateDateSelection: function(date, showSelection, totalSelectionEdges) {
38108  var index = this.GetIndexByDate(date);
38109  if(!this.IsValidIndex(index) || !this.IsDateVisible(date))
38110   return;
38111  var applyDateInRangeStyle = totalSelectionEdges
38112   && !ASPxClientCalendar.IsFirstDateEqualToAnyOther(date, totalSelectionEdges.start, totalSelectionEdges.end);
38113  this.ApplySelectionToCell(index, showSelection, applyDateInRangeStyle);
38114 },
38115 EnsureSelection: function() {
38116  var selection = this.calendar.selection;
38117  var selectedRangeRestrictions = null;
38118  if(!this.isNavigationView) {
38119   selectedRangeRestrictions = this.calendar.sharedParameters.dateRangeMode ? ASPx.Data.ArrayGetIntegerEdgeValues(selection.GetDates()) : null;
38120   if(this.calendar.NeedCalculateSelectionOnUpdating()) {
38121    selectedRangeRestrictions.start = ASPxClientCalendar.CloneDate(selection.startDate);
38122    selectedRangeRestrictions.end = ASPxClientCalendar.CloneDate(selection.endDate);
38123    var visibleRangeRestrictions = this.GetVisibleRangeRestrictions();
38124    ASPxClientCalendar.AddSelectedRangeVisiblePartToSelection(selection, selectedRangeRestrictions, visibleRangeRestrictions);
38125   }
38126  }
38127  var selectedDates = !this.isNavigationView ? selection.GetDates() : this.calendar.selectedNavigationDates[this.GetViewType()];
38128  this.UpdateSelection(selectedDates, true, selectedRangeRestrictions);
38129 },
38130 Update: function() {
38131  this.dayStyleCache = {};
38132  this.UpdateDate();
38133  this.UpdateDateCellHtml();
38134  this.UpdateTitle();
38135  this.EnsureSelection();
38136 },
38137 GetVisibleRangeRestrictions: function() {
38138  return {
38139   start: this.GetDateByIndex(0),
38140   end: this.GetDateByIndex(this.GetMaxIndex())
38141  };
38142 },
38143 GetMaxVisibleDate: function() {
38144  return this.GetVisibleRangeRestrictions().end;
38145 },
38146 ChangeButtonEnabledAttributes: function(element, method) {
38147  method(element, "onclick");
38148  method(element, "ondblclick");
38149 },
38150 AddHeaderDisabledStateItem: function(element) {
38151  var cell = this.calendar.GetEtalonStyleCell("DD");
38152  if(cell)
38153   ASPx.GetStateController().AddDisabledItem(element.id, cell.className, cell.style.cssText, null, null, null);
38154 },
38155 ApplyDayCellStyle: function(cell, date) {
38156  cell.style.cursor = "";
38157  var cal = this.calendar;
38158  var info = new ASPxClientCalendarStyleInfo();
38159  var needPointer = false;
38160  var readOnly = cal.GetReadOnly();
38161  cal.ImportEtalonStyle(info, this.GetCellStyleName());
38162  var isDateDisabled = false;
38163  if(this.IsDateVisible(date)) {
38164   var isCurrentMonthDate = !this.IsDateOtherPeriod(date);
38165   if(cal.IsDateWeekend(date) && cal.CanApplyDayCellStyle("DW", isCurrentMonthDate) && this.SupportsWeekendStyle())
38166    cal.ImportEtalonStyle(info, "DW");
38167   if(!isCurrentMonthDate)
38168    cal.ImportEtalonStyle(info, this.GetCellOtherPeriodStyleName());
38169   if(!ASPxClientCalendarDateDisabledHelper.IsDateInRange(cal.sharedParameters, date)
38170    && cal.CanApplyDayCellStyle(this.GetCellOutOfRangeStyleName(), isCurrentMonthDate) && !this.isNavigationView)
38171    cal.ImportEtalonStyle(info, this.GetCellOutOfRangeStyleName());
38172   if(cal.IsDateDisabled(date) && cal.CanApplyDayCellStyle(this.GetCellDisabledStyleName(), isCurrentMonthDate) && !this.isNavigationView) {
38173    cal.ImportEtalonStyle(info, this.GetCellDisabledStyleName());
38174    isDateDisabled = true;
38175   }
38176   if(ASPxClientCalendar.AreDatesEqual(this.GetActualTodayDate(), date) && cal.CanApplyDayCellStyle("DT", isCurrentMonthDate) && !this.isNavigationView)
38177    cal.ImportEtalonStyle(info, "DT");
38178   if(!cal.clientEnabled && cal.CanApplyDayCellStyle("DD", isCurrentMonthDate) && !this.isNavigationView)
38179    cal.ImportEtalonStyle(info, "DD");
38180   else if(!cal.enableMulti && !isDateDisabled && !readOnly || this.isNavigationView)
38181    needPointer = true;
38182  } else
38183   info.AddClassName(emptyDateCellClassName);
38184  info.Apply(cell);
38185  if(needPointer && cal.needToSetCursor)
38186   ASPx.SetPointerCursor(cell);
38187 },
38188 EnsureTodayStyle: function() {
38189  var serverCurrentDateIndex = this.GetIndexByDate(this.calendar.serverCurrentDate);
38190  var clientCurrentDateIndex = this.GetIndexByDate(new Date());
38191  if(this.IsValidIndex(serverCurrentDateIndex))
38192   this.RemoveDayCellStyle(this.GetDayCell(serverCurrentDateIndex), "DT");
38193  if(this.IsValidIndex(clientCurrentDateIndex))
38194   this.ApplyDayCellStyle(this.GetDayCell(clientCurrentDateIndex), new Date());
38195  this.dayStyleCache[serverCurrentDateIndex] = null;
38196  this.dayStyleCache[clientCurrentDateIndex] = null;
38197  this.EnsureSelection();
38198 },
38199 GetHeaderCellElements: function() {
38200  var result = [
38201   this.GetTitleCell(),
38202   this.GetTitleElement()
38203  ];
38204  var navigationCells = this.GetNavigationCells();
38205  for(var i = 0; i < navigationCells.length; i++)
38206   if(navigationCells[i])
38207    result.push(navigationCells[i]);
38208  return result;
38209 },
38210 SetHeaderCellsEnabled: function(enabled) {
38211  var headerCellElements = this.GetHeaderCellElements();
38212  for(var i = 0; i < headerCellElements.length; i++)
38213   if(headerCellElements[i])
38214    ASPx.GetStateController().SetElementEnabled(headerCellElements[i], enabled);
38215 },
38216 MakeDisabledStateItems: function() {
38217  if(this.isNavigationView)
38218   return;
38219  var element = this.GetTitleCell();
38220  if(element)
38221   this.AddHeaderDisabledStateItem(element);
38222  var element = this.GetTitleElement();
38223  if(element)
38224   this.AddHeaderDisabledStateItem(element);
38225 },
38226 ChangeEnabledStateItems: function(enabled) {
38227  this.SetHeaderCellsEnabled(enabled);
38228  if(enabled)
38229   this.AddHoverStateItems();
38230  else
38231   this.RemoveHoverStateItems();
38232 },
38233 ChangeEnabledAttributes: function(enabled) {
38234  var element = this.GetTitleElement();
38235  if(element)
38236   this.ChangeTitleElementEnabledAttributes(element, ASPx.Attr.ChangeStyleAttributesMethod(enabled));
38237 },
38238 ChangeEditableAttributesOnChangeEnabledState: function(enabled) {
38239  if(!this.calendar.enabled)
38240   return;
38241  var eventMethod = ASPx.Attr.ChangeEventsMethod(enabled);
38242  if(!this.isNavigationView)
38243   this.AttachTitleMouseEvents(eventMethod);
38244  if(!this.isNavigationView || this.isFirstNavigationView) {
38245   this.AttachNavigationMouseEvents(eventMethod);
38246   if(this.AllowAttachDetachDateEventsOnChangeEnabled())
38247    this.AttachDateMouseEvents(eventMethod, ASPx.Attr.InitiallyChangeStyleAttributesMethod(enabled));
38248  }
38249 },
38250 ChangeEditableAttributesOnChangeReadOnlyState: function(readOnly) {
38251  if(!this.calendar.enabled)
38252   return;
38253  if(this.AllowAttachDetachDateEventsOnChangeReadOnly()) {
38254   var eventMethod = ASPx.Attr.ChangeEventsMethod(!readOnly);
38255   this.AttachDateMouseEvents(eventMethod, ASPx.Attr.InitiallyChangeStyleAttributesMethod(!readOnly));
38256  }
38257 },
38258 GetNextDate: function(date) {
38259  return ASPxClientCalendar.GetNextDate(date, this.GetViewType());
38260 },
38261 AttachTitleMouseEvents: function(eventMethod) {
38262  var title = this.GetTitleElement();
38263  if(title)
38264   eventMethod(title, "click", this.GetTitleFunction());
38265 },
38266 AttachNavigationMouseEvents: function(eventMethod) {
38267  var navigationCells = this.GetNavigationCells();
38268  for(var i = 0; i < navigationCells.length; i++)
38269   if(this.NeedToAttachNavigationEvent(navigationCells[i])) {
38270    var navigationCellImage = this.GetNavigationCellImage(navigationCells[i]);
38271    var offset = this.GetNavigationCellOffset(navigationCells[i]);
38272    var isVisibleInAdaptiveOnly = this.IsVisibleInAdaptiveModeNavigationCell(navigationCells[i]);
38273    this.AttachNavigationImageEvent(navigationCellImage || navigationCells[i], eventMethod, offset, isVisibleInAdaptiveOnly);
38274   }
38275 },
38276 NeedToAttachNavigationEvent: function(navigationCell) {
38277  if(!ASPx.IsExists(navigationCell))
38278   return false;
38279  return this.IsDefaultVisibleNavigationCell(navigationCell) || this.IsVisibleInAdaptiveModeNavigationCell(navigationCell);
38280 },
38281 IsDefaultVisibleNavigationCell: function(navigationCell) {
38282  return this.IsPrevNavCell(navigationCell) && this.isLowBoundary
38283   || this.IsNextNavCell(navigationCell) && this.isLastViewInFirstRow;
38284 },
38285 IsVisibleInAdaptiveModeNavigationCell: function(navigationCell) {
38286  return this.calendar.IsMultiView()
38287   && (this.IsNextNavCell(navigationCell) && this.isLowBoundary && !this.isLastViewInFirstRow
38288   || this.IsPrevNavCell(navigationCell) && this.isLastViewInFirstRow && !this.isLowBoundary);
38289 },
38290 GetNavigationCellImage: function(navigationCell) {
38291  return ASPx.GetChildByTagName(navigationCell, "IMG");
38292 },
38293 AttachNavigationImageEvent: function(navigationCellImage, eventMethod, offset, isVisibleInAdaptiveOnly) {
38294  eventMethod(navigationCellImage, "click", this.GetNavButtonFunction(navigationCellImage.id, offset, isVisibleInAdaptiveOnly));
38295 },
38296 GetDateCells: function() {
38297  if(!this.dateCells)
38298   this.dateCells = this.GetMainElement().querySelectorAll(this.GetDateCellSelector());
38299  return this.dateCells;
38300 },
38301 GetStateController: function() {
38302  return typeof (ASPx.GetStateController) != "undefined" ? ASPx.GetStateController() : null;
38303 },
38304 AddHoverStateItems: function() {
38305  var stateController = this.GetStateController();
38306  if(!stateController)
38307   return;
38308  var hoverStyleInfo = new ASPxClientCalendarStyleInfo();
38309  this.calendar.ImportEtalonStyle(hoverStyleInfo, this.GetCellHoverStyleName());
38310  var dateCells = this.GetDateCells();
38311  for(var i = 0; i < dateCells.length; i++) {
38312   var cell = dateCells[i];
38313   if(!cell.id)
38314    cell.id = this.GetDateCellID(i);
38315   stateController.ClearCache(cell, ASPx.HoverItemKind);
38316   stateController.AddHoverItem(cell.id, [hoverStyleInfo.className], [hoverStyleInfo.cssText], null, null, null);
38317  }
38318 },
38319 RemoveHoverStateItems: function() {
38320  var stateController = this.GetStateController();
38321  if(!stateController)
38322   return;
38323  var dateCells = this.GetDateCells();
38324  for(var i = 0; i < dateCells.length; i++) {
38325   var cell = dateCells[i];
38326   if(!cell.id)
38327    cell.id = this.GetDateCellID(i);
38328   stateController.RemoveHoverItem(cell.id);
38329   stateController.ClearCache(cell, ASPx.HoverItemKind);
38330  }
38331 },
38332 GetDateCellID: function(cellIndex) { return this.GetMainElement().id + "_" + cellIndex; },
38333 GetNavigationCells: function() { throw "Not Implemented"; },
38334 GetNavigationCellOffset: function(navigationCell) { throw "Not Implemented"; },
38335 GetTitleText: function() { throw "Not Implemented"; },
38336 IsDateOtherPeriod: function(date) { throw "Not Implemented"; },
38337 GetCurrentVisibleDate: function() { throw "Not Implemented"; },
38338 GetCurrentStartDate: function() { throw "Not Implemented"; },
38339 UpdateNavigationCells: function(date) { throw "Not Implemented"; },
38340 GetDateByIndex: function(index) { throw "Not Implemented"; },
38341 GetIndexByDate: function(date) { throw "Not Implemented"; },
38342 GetDateCellContainer: function() { throw "Not Implemented"; },
38343 GetMainElement: function() { throw "Not Implemented"; },
38344 GetAnimatedElement: function() { throw "Not Implemented"; },
38345 GetDateCellColIndex: function(index) { throw "Not Implemented"; },
38346 GetDateCellRowIndex: function(index) { throw "Not Implemented"; },
38347 UpdateDateCellHtml: function(date) { throw "Not Implemented"; },
38348 SupportsWeekendStyle: function(date) { throw "Not Implemented"; },
38349 AttachDateMouseEvents: function(eventMethod, styleMethod) { throw "Not Implemented"; },
38350 GetVisibleDateOffsetInfo: function() { throw "Not Implemented"; },
38351 GetViewType: function() { throw "Not Implemented"; },
38352 AllowAttachDetachDateEventsOnChangeEnabled: function() { throw "Not Implemented"; },
38353 AllowAttachDetachDateEventsOnChangeReadOnly: function() { throw "Not Implemented"; },
38354 IsPrevNavCell: function(navigationCell) { throw "Not Implemented"; },
38355 IsNextNavCell: function(navigationCell) { throw "Not Implemented"; },
38356 GetCellStyleName: function() { throw "Not Implemented"; },
38357 GetCellSelectedStyleName: function() { throw "Not Implemented"; },
38358 GetCellHoverStyleName: function() { throw "Not Implemented"; },
38359 GetCellOtherPeriodStyleName: function() { throw "Not Implemented"; },
38360 GetCellOutOfRangeStyleName: function() { throw "Not Implemented"; },
38361 GetCellDisabledStyleName: function() { throw "Not Implemented"; },
38362 GetDateCellSelector: function() { throw "Not Implemented"; },
38363});
38364var ASPxClientCalendarDaysView = ASPx.CreateClass(ASPxClientCalendarView, {
38365 constructor: function(calendar, row, column) {
38366  this.constructor.prototype.constructor.call(this, calendar, row, column);
38367  this.dayFunctionsWithWeekSelection = {};
38368 },
38369 AttachDateMouseEvents: function(eventMethod, styleMethod) {
38370  var index;
38371  var cell;
38372  if(this.calendar.showDayHeaders) {
38373   var headCells = this.GetMonthTable().rows[0].cells;
38374   var dayNameIndex = 0;
38375   if(this.calendar.showWeekNumbers) {
38376    dayNameIndex++;
38377    cell = headCells[0];
38378    if(this.calendar.enableMulti) {
38379     eventMethod(cell, "click", ASPxClientCalendar.AnonymousHandlers.SelectMonth(this.calendar.name, this.row, this.column));
38380     if(this.calendar.needToSetCursor)
38381      styleMethod(cell, "cursor", ASPx.GetPointerCursor());
38382    }
38383    this.AttachCancelSelect(eventMethod, cell);
38384   }
38385   for(var j = 0; j < 7; j++)
38386    this.AttachCancelSelect(eventMethod, headCells[dayNameIndex++]);
38387  }
38388  for(var i = 0; i < calendarWeekCount; i++) {
38389   if(this.calendar.showWeekNumbers) {
38390    cell = this.GetWeekNumberCell(i);
38391    if(this.calendar.enableMulti)
38392     this.AttachDayMouseEvents(eventMethod, cell, this.GetDayMouseEventFunction(7 * i, true));
38393    else
38394     this.AttachCancelSelect(eventMethod, cell);
38395   }
38396   var date;
38397   for(var j = 0; j < 7; j++) {
38398    index = i * 7 + j;
38399    cell = this.GetDayCell(index);
38400    date = this.GetDateByIndex(index);
38401    var cal = this.calendar;
38402    if(!this.calendar.enableMulti && this.IsDateVisible(date) &&
38403     ASPxClientCalendarDateDisabledHelper.IsDateInRange(cal.sharedParameters, date) &&
38404     !cal.IsDateDisabled(date)) {
38405     if(this.calendar.needToSetCursor && (!cell.style.cursor || cell.style.cursor == ASPx.GetPointerCursor()))
38406      styleMethod(cell, "cursor", ASPx.GetPointerCursor());
38407    }
38408    this.AttachDayMouseEvents(eventMethod, cell, this.GetDayMouseEventFunction(index, false));
38409   }
38410  }
38411 },
38412 GetDateFunctionsHash: function(selectWeeks) {
38413  return selectWeeks ? this.dayFunctionsWithWeekSelection : this.dayFunctions;
38414 },
38415 UpdateNavigationCells: function(date) {
38416  var prevYearCell = this.GetPrevYearCell();
38417  var prevMonthCell = this.GetPrevMonthCell();
38418  var isEnabledDate = date.getFullYear() > 100;
38419  if(prevYearCell && ASPx.GetElementVisibility(prevYearCell) != isEnabledDate) {
38420   ASPx.SetElementVisibility(prevYearCell, isEnabledDate);
38421  }
38422  if(prevMonthCell) {
38423   var isEnabledDate = isEnabledDate || (date.getFullYear() == 100 && date.getMonth() > 0);
38424   if(ASPx.GetElementVisibility(prevMonthCell) != isEnabledDate)
38425    ASPx.SetElementVisibility(prevMonthCell, isEnabledDate);
38426  }
38427  var nextYearCell = this.GetNextYearCell();
38428  var nextMonthCell = this.GetNextMonthCell();
38429  isEnabledDate = date.getFullYear() < 9999;
38430  if(nextYearCell && ASPx.GetElementVisibility(nextYearCell) != isEnabledDate) {
38431   ASPx.SetElementVisibility(nextYearCell, isEnabledDate);
38432  }
38433  if(nextMonthCell) {
38434   var isEnabledDate = isEnabledDate || (date.getFullYear() == 9999 && date.getMonth() < 11);
38435   if(ASPx.GetElementVisibility(nextMonthCell) != isEnabledDate)
38436    ASPx.SetElementVisibility(nextMonthCell, isEnabledDate);
38437  }
38438 },
38439 IsPrevNavCell: function(navigationCell) {
38440  return navigationCell == this.GetPrevMonthCell() || navigationCell == this.GetPrevYearCell();
38441 },
38442 IsNextNavCell: function(navigationCell) {
38443  return navigationCell == this.GetNextMonthCell() || navigationCell == this.GetNextYearCell();
38444 },
38445 GetNavigationCellOffset: function(navigationCell) {
38446  if(navigationCell == this.GetPrevYearCell())
38447   return -12;
38448  if(navigationCell == this.GetPrevMonthCell())
38449   return -1;
38450  if(navigationCell == this.GetNextMonthCell())
38451   return 1;
38452  if(navigationCell == this.GetNextYearCell())
38453   return 12;
38454  return 0;
38455 },
38456 GetCurrentVisibleDate: function() {
38457  return ASPxClientCalendar.AddMonths(this.calendar.visibleDates[this.GetViewType()], this.GetIndex());
38458 },
38459 GetCurrentStartDate: function(visibleDate) {
38460  var offset = visibleDate.getDay() - this.calendar.firstDayOfWeek;
38461  if(offset < 0)
38462   offset += 7;
38463  return ASPxClientCalendar.AddDays(visibleDate, -offset);
38464 },
38465 GetDateByIndex: function(index) {
38466  return ASPxClientCalendar.AddDays(this.startDate, index);
38467 },
38468 GetIndexByDate: function(date) {
38469  return ASPxClientCalendar.GetDaysInRange(this.startDate, date) - 1;
38470 },
38471 IsDateOtherPeriod: function(date) {
38472  if(date == null)
38473   return false;
38474  return date.getMonth() != this.visibleDate.getMonth() ||
38475   date.getFullYear() != this.visibleDate.getFullYear();
38476 },
38477 GetDateCellColIndex: function(index) {
38478  var result = index % 7;
38479  if(this.calendar.showWeekNumbers)
38480   result++;
38481  return result;
38482 },
38483 GetDateCellRowIndex: function(index) {
38484  var result = (index - index % 7) / 7;
38485  if(this.calendar.showDayHeaders)
38486   result++;
38487  return result;
38488 },
38489 GetMaxIndex: function() {
38490  return 7 * calendarWeekCount - 1;
38491 },
38492 GetMaxVisibleDate: function() {
38493  var result = ASPxClientCalendar.CloneDate(this.visibleDate);
38494  result.setDate(ASPxClientCalendar.GetDaysInMonth(result.getMonth(), result.getFullYear()));
38495  return result;
38496 },
38497 GetDateCellContainer: function() {
38498  return this.GetMonthTable();
38499 },
38500 GetMainElement: function() {
38501  return this.GetMonthCell();
38502 },
38503 GetAnimatedElement: function() {
38504  return this.GetMonthTable();
38505 },
38506 GetMonthTable: function() {
38507  return this.calendar.GetMonthTable(this.calendar.IsMultiView() ? this.GetIDPostfix() : "");
38508 },
38509 GetMonthCell: function() {
38510  return this.calendar.GetMonthCell(this.calendar.IsMultiView() ? this.GetIDPostfix() : "");
38511 },
38512 GetWeekNumberCell: function(index) {
38513  if(this.calendar.showDayHeaders)
38514   index++;
38515  return this.GetMonthTable().rows[index].cells[0];
38516 },
38517 GetPrevYearCell: function() {
38518  return this.GetChildElement("PYC");
38519 },
38520 GetPrevMonthCell: function() {
38521  return this.GetChildElement("PMC");
38522 },
38523 GetNextMonthCell: function() {
38524  return this.GetChildElement("NMC");
38525 },
38526 GetNextYearCell: function() {
38527  return this.GetChildElement("NYC");
38528 },
38529 UpdateDateCellHtml: function() {
38530  var date = ASPxClientCalendar.CloneDate(this.startDate);
38531  var offset = this.calendar.firstDayOfWeek - 1;
38532  if(offset < 0)
38533   offset += 7;
38534  var weekNumber = ASPxClientCalendar.GetISO8601WeekOfYear(ASPxClientCalendar.AddDays(date, offset));
38535  var cell;
38536  for(var i = 0; i < calendarWeekCount; i++) {
38537   if(this.calendar.showWeekNumbers)
38538    this.calendar.SetMonthTableCellContent(this.GetWeekNumberCell(i), (weekNumber < 10 ? "0" : "") + weekNumber.toString(), true);
38539   for(var j = 0; j < 7; j++) {
38540    cell = this.GetDayCell(i * 7 + j);
38541    this.calendar.SetMonthTableCellContent(cell, this.IsDateVisible(date) ? date.getDate() : "&nbsp;");
38542    this.ApplyDayCellStyle(cell, date);
38543    date = this.GetNextDate(date);
38544   }
38545   if(++weekNumber > 52)
38546    weekNumber = ASPxClientCalendar.GetISO8601WeekOfYear(ASPxClientCalendar.AddDays(date, offset));
38547  }
38548 },
38549 GetTitleText: function() {
38550  if(!this.titleFormatter) {
38551   this.titleFormatter = new ASPx.DateFormatter();
38552   this.titleFormatter.SetFormatString(this.calendar.rtl ? "MMMM yyyy" : ASPx.CultureInfo.yearMonth);
38553  }
38554  return this.titleFormatter.Format(this.visibleDate);
38555 },
38556 SupportsWeekendStyle: function(date) {
38557  return true;
38558 },
38559 MakeDisabledStateItems: function() {
38560  var cells = this.GetAuxCells();
38561  for(var i = 0; i < cells.length; i++)
38562   this.AddAuxDisabledStateItem(cells[i], this.GetAuxId(i));
38563  ASPxClientCalendarView.prototype.MakeDisabledStateItems.call(this);
38564 },
38565 ChangeEnabledStateItems: function(enabled) {
38566  this.SetAuxCellsEnabled(enabled);
38567  ASPxClientCalendarView.prototype.ChangeEnabledStateItems.call(this, enabled);
38568 },
38569 SetAuxCellsEnabled: function(enabled) {
38570  var cells = this.GetAuxCells();
38571  for(var i = 0; i < cells.length; i++)
38572   ASPx.GetStateController().SetElementEnabled(cells[i], enabled);
38573 },
38574 GetNavigationCells: function() {
38575  return [
38576   this.GetPrevYearCell(),
38577   this.GetPrevMonthCell(),
38578   this.GetNextMonthCell(),
38579   this.GetNextYearCell()
38580  ];
38581 },
38582 GetAuxCells: function() {
38583  if(this.auxCells == null) {
38584   this.auxCells = [];
38585   var table = this.GetMonthTable();
38586   for(var i = 0; i < table.rows.length; i++) {
38587    var row = table.rows[i];
38588    if(i == 0 && this.calendar.showDayHeaders) {
38589     for(var j = 0; j < row.cells.length; j++)
38590      this.auxCells.push(row.cells[j]);
38591    }
38592    if(i > 0 && this.calendar.showWeekNumbers)
38593     this.auxCells.push(row.cells[0]);
38594   }
38595  }
38596  return this.auxCells;
38597 },
38598 GetAuxId: function(index) {
38599  return this.calendar.name + "_AUX_" + this.row + "_" + this.column + "_" + index;
38600 },
38601 AddAuxDisabledStateItem: function(element, id) {
38602  var cell = this.calendar.GetEtalonStyleCell("DD");
38603  if(cell) {
38604   element.id = id;
38605   ASPx.GetStateController().AddDisabledItem(id, cell.className, cell.style.cssText, null, null, null);
38606  }
38607 },
38608 GetVisibleDateOffsetInfo: function() {
38609  return {
38610   month: this.GetIndex(),
38611   year: 0
38612  };
38613 },
38614 GetViewType: function() { return ASPx.DatePickerType.Days; },
38615 AllowAttachDetachDateEventsOnChangeEnabled: function() {
38616  return !this.calendar.GetReadOnly();
38617 },
38618 AllowAttachDetachDateEventsOnChangeReadOnly: function() {
38619  return this.calendar.clientEnabled;
38620 },
38621 GetCellStyleName: function() { return "D"; },
38622 GetCellSelectedStyleName: function() { return "DS"; },
38623 GetCellHoverStyleName: function() { return "DH"; },
38624 GetCellOtherPeriodStyleName: function() { return "DA"; },
38625 GetCellOutOfRangeStyleName: function() { return "DO"; },
38626 GetCellDisabledStyleName: function() { return "DDD"; },
38627 GetDateCellSelector: function() { return "td[class*=\"dxeCalendarDay\"]"; },
38628});
38629ASPxClientCalendarView.DayInRangeClassName = "dxeDayInRange";
38630var ASPxClientCalendarLargeTimePeriodView = ASPx.CreateClass(ASPxClientCalendarView, {
38631 constructor: function(calendar, row, column) {
38632  this.constructor.prototype.constructor.call(this, calendar, row, column);
38633  if(calendar.fastNavRollbackTexts && this.isNavigationView)
38634   this.headerRollbackText = calendar.fastNavRollbackTexts[this.GetViewType() - 1];
38635 },
38636 GetMaxIndex: function() {
38637  return 11;
38638 },
38639 GetPrevTimePeriodCell: function() {
38640  return this.GetChildElement("PTPC");
38641 },
38642 GetNextTimePeriodCell: function() {
38643  return this.GetChildElement("NTPC");
38644 },
38645 Update: function() {
38646  ASPxClientCalendarView.prototype.Update.call(this);
38647  this.UpdateFastNavHeader();
38648 },
38649 UpdateFastNavHeader: function() {
38650  var fastNavHeader = this.GetFastNavHeader();
38651  if(fastNavHeader) {
38652   ASPx.SetElementDisplay(fastNavHeader, this.isNavigationView);
38653   if(this.isNavigationView) {
38654    var textElement = this.GetFastNavHeaderTextElement();
38655    if(textElement)
38656     ASPx.SetInnerHtml(textElement, this.headerRollbackText);
38657   }
38658  }
38659 },
38660 UpdateNavigationCells: function(date) {
38661  var prevPeriodCell = this.GetPrevTimePeriodCell();
38662  var isEnabledDate = date.getFullYear() > 100;
38663  if(prevPeriodCell && ASPx.GetElementVisibility(prevPeriodCell) != isEnabledDate) {
38664   ASPx.SetElementVisibility(prevPeriodCell, isEnabledDate);
38665  }
38666  var nextPeriodCell = this.GetNextTimePeriodCell();
38667  isEnabledDate = date.getFullYear() < 9999;
38668  if(nextPeriodCell && ASPx.GetElementVisibility(nextPeriodCell) != isEnabledDate) {
38669   ASPx.SetElementVisibility(nextPeriodCell, isEnabledDate);
38670  }
38671 },
38672 IsPrevNavCell: function(navigationCell) {
38673  return navigationCell == this.GetPrevTimePeriodCell();
38674 },
38675 IsNextNavCell: function(navigationCell) {
38676  return navigationCell == this.GetNextTimePeriodCell();
38677 },
38678 GetNavigationCellOffset: function(navigationCell) {
38679  if(navigationCell == this.GetPrevTimePeriodCell())
38680   return -1;
38681  if(navigationCell == this.GetNextTimePeriodCell())
38682   return 1;
38683  return 0;
38684 },
38685 GetYearCell: function() {
38686  return this.calendar.GetYearCell(this.calendar.IsMultiView() ? this.GetIDPostfix() : "");
38687 },
38688 GetFastNavHeader: function() {
38689  return this.calendar.GetFastNavHeader(this.calendar.IsMultiView() ? this.GetIDPostfix() : "");
38690 },
38691 GetFastNavHeaderTextElement: function() {
38692  var idPostfix = this.calendar.IsMultiView() ? this.GetIDPostfix() : "";
38693  idPostfix += "_rt";
38694  return this.calendar.GetFastNavHeaderTextElement(idPostfix);
38695 },
38696 GetAnimatedElement: function() {
38697  return this.GetYearCell();
38698 },
38699 SupportsWeekendStyle: function(date) {
38700  return false;
38701 },
38702 GetNavigationCells: function() {
38703  return [
38704   this.GetPrevTimePeriodCell(),
38705   this.GetNextTimePeriodCell()
38706  ];
38707 },
38708 GetDateCellContainer: function() {
38709  var idPostfix = this.calendar.IsMultiView() ? this.GetIDPostfix() : "";
38710  idPostfix += "_n";
38711  return this.calendar.GetYearCellChildArea(idPostfix);
38712 },
38713 GetDateCellColIndex: function(index) {
38714  return index % 4;
38715 },
38716 GetDateCellRowIndex: function(index) {
38717  return (index - index % 4) / 4;
38718 },
38719 GetMainElement: function() {
38720  return this.GetYearCell();
38721 },
38722 ChangeEnabledStateItems: function(enabled) {
38723  if(!this.isNavigationView)
38724   ASPxClientCalendarView.prototype.ChangeEnabledStateItems.call(this, enabled);
38725 },
38726 ChangeEnabledAttributes: function(enabled) {
38727  if(!this.isNavigationView)
38728   ASPxClientCalendarView.prototype.ChangeEnabledAttributes.call(this, enabled);
38729 },
38730 AttachDateMouseEvents: function(eventMethod, styleMethod) {
38731  var index;
38732  var date;
38733  for(var index = 0; index <= this.GetMaxIndex() ; index++) {
38734   cell = this.GetDayCell(index);
38735   date = this.GetDateByIndex(index);
38736   var cal = this.calendar;
38737   if(!this.isNavigationView && !this.calendar.enableMulti && this.IsDateVisible(date) &&
38738    ASPxClientCalendarDateDisabledHelper.IsDateInRange(cal.sharedParameters, date) &&
38739    !cal.IsDateDisabled(date)) {
38740    if(this.calendar.needToSetCursor && (!cell.style.cursor || cell.style.cursor == ASPx.GetPointerCursor()))
38741     styleMethod(cell, "cursor", ASPx.GetPointerCursor());
38742   }
38743   this.AttachDayMouseEvents(eventMethod, cell, this.GetDayMouseEventFunction(index, false));
38744  }
38745 },
38746 AllowAttachDetachDateEventsOnChangeEnabled: function() {
38747  return true;
38748 },
38749 AllowAttachDetachDateEventsOnChangeReadOnly: function() {
38750  return false;
38751 },
38752 GetCellStyleName: function() { return this.isNavigationView ? "FNI" : "MY"; },
38753 GetCellHoverStyleName: function() { return this.isNavigationView ? "FNIH" : "MYH"; },
38754 GetCellSelectedStyleName: function() { return this.isNavigationView ? "FNIS" : "MYS"; },
38755 GetCellOtherPeriodStyleName: function() { return this.isNavigationView ? "FNIA" : "MYA"; },
38756 GetCellOutOfRangeStyleName: function() { return "MYO"; },
38757 GetCellDisabledStyleName: function() { return "MYDD"; },
38758 GetDateCellSelector: function() { return "td[class*=\"dxeCalendarFastNavItemArea\"] td[class*=\"dxeCalendarFastNavItem\"]"; }
38759});
38760var ASPxClientCalendarMonthsView = ASPx.CreateClass(ASPxClientCalendarLargeTimePeriodView, {
38761 constructor: function(calendar, row, column) {
38762  this.constructor.prototype.constructor.call(this, calendar, row, column);
38763 },
38764 GetTitleText: function() {
38765  return this.startDate.getFullYear();
38766 },
38767 IsDateOtherPeriod: function(date) {
38768  return date.getFullYear() != this.visibleDate.getFullYear();
38769 },
38770 GetCurrentVisibleDate: function() {
38771  return ASPxClientCalendar.AddYears(this.calendar.visibleDates[this.GetViewType()], this.GetIndex());
38772 },
38773 GetCurrentStartDate: function(visibleDate) {
38774  return new Date(visibleDate.getFullYear(), 0, 1);
38775 },
38776 GetDateByIndex: function(index) {
38777  return ASPxClientCalendar.AddMonths(this.startDate, index);
38778 },
38779 GetIndexByDate: function(date) {
38780  return date.getMonth() + 12 * (date.getFullYear() - this.startDate.getFullYear());
38781 },
38782 UpdateDateCellHtml: function() {
38783  var date = ASPxClientCalendar.CloneDate(this.startDate);
38784  var cell;
38785  for(var i = 0; i <= this.GetMaxIndex(); i++) {
38786   cell = this.GetDayCell(i);
38787   cell.innerHTML = ASPx.CultureInfo.abbrMonthNames[i];
38788   this.ApplyDayCellStyle(cell, date);
38789   date = this.GetNextDate(date);
38790  }
38791 },
38792 GetVisibleDateOffsetInfo: function() {
38793  return {
38794   month: 0,
38795   year: this.GetIndex()
38796  };
38797 },
38798 GetViewType: function() { return ASPx.DatePickerType.Months; },
38799});
38800var ASPxClientCalendarYearsView = ASPx.CreateClass(ASPxClientCalendarLargeTimePeriodView, {
38801 constructor: function(calendar, row, column) {
38802  this.constructor.prototype.constructor.call(this, calendar, row, column);
38803 },
38804 GetTitleText: function() {
38805  var startYear = this.startDate.getFullYear();
38806  return ASPx.DateUtils.GetYearRangeFormatString(startYear + 1, 10);
38807 },
38808 IsDateOtherPeriod: function(date) {
38809  return date != null && ASPxClientCalendar.GetDecadeStartYear(date.getFullYear()) !== ASPxClientCalendar.GetDecadeStartYear(this.visibleDate.getFullYear());
38810 },
38811 GetCurrentVisibleDate: function() {
38812  return ASPxClientCalendar.AddYears(this.calendar.visibleDates[this.GetViewType()], this.GetIndex() * 10);
38813 },
38814 GetCurrentStartDate: function(visibleDate) {
38815  var decadeStartYear = ASPxClientCalendar.GetDecadeStartYear(visibleDate.getFullYear());
38816  return new Date(decadeStartYear - 1, 0, 1);
38817 },
38818 GetDateByIndex: function(index) {
38819  return ASPxClientCalendar.AddYears(this.startDate, index);
38820 },
38821 GetIndexByDate: function(date) {
38822  return date.getFullYear() - this.startDate.getFullYear();
38823 },
38824 UpdateDateCellHtml: function() {
38825  var date = ASPxClientCalendar.CloneDate(this.startDate);
38826  var cell;
38827  for(var i = 0; i <= this.GetMaxIndex(); i++) {
38828   cell = this.GetDayCell(i);
38829   cell.innerHTML = this.IsDateVisible(date) ? date.getFullYear() : "";
38830   this.ApplyDayCellStyle(cell, date);
38831   date = this.GetNextDate(date);
38832  }
38833 },
38834 GetVisibleDateOffsetInfo: function() {
38835  return {
38836   month: 0,
38837   year: this.GetIndex() * 10
38838  };
38839 },
38840 GetViewType: function() { return ASPx.DatePickerType.Years; },
38841});
38842var ASPxClientCalendarDecadesView = ASPx.CreateClass(ASPxClientCalendarLargeTimePeriodView, {
38843 constructor: function(calendar, row, column) {
38844  this.constructor.prototype.constructor.call(this, calendar, row, column);
38845 },
38846 GetTitleText: function() {
38847  var startYear = this.startDate.getFullYear();
38848  return ASPx.DateUtils.GetYearRangeFormatString(startYear + 10, 100);
38849 },
38850 IsDateOtherPeriod: function(date) {
38851  return date != null && ASPxClientCalendar.GetCenturyStartYear(date.getFullYear()) !== ASPxClientCalendar.GetCenturyStartYear(this.visibleDate.getFullYear());
38852 },
38853 GetCurrentVisibleDate: function() {
38854  return ASPxClientCalendar.AddYears(this.calendar.visibleDates[this.GetViewType()], this.GetIndex() * 100);
38855 },
38856 GetCurrentStartDate: function(visibleDate) {
38857  var centuryStartYear = ASPxClientCalendar.GetCenturyStartYear(visibleDate.getFullYear());
38858  return new Date(centuryStartYear - 10, 0, 1);
38859 },
38860 GetDateByIndex: function(index) {
38861  return ASPxClientCalendar.AddYears(this.startDate, index * 10);
38862 },
38863 GetIndexByDate: function(date) {
38864  return Math.floor((date.getFullYear() - this.startDate.getFullYear()) / 10);
38865 },
38866 UpdateDateCellHtml: function() {
38867  var date = ASPxClientCalendar.CloneDate(this.startDate);
38868  var cell;
38869  for(var i = 0; i <= this.GetMaxIndex() ; i++) {
38870   cell = this.GetDayCell(i);
38871   var dateYear = date.getFullYear();
38872   cell.innerHTML = this.IsDateVisible(date) ? ASPx.DateUtils.GetYearRangeFormatString(dateYear, 10) : "";
38873   this.ApplyDayCellStyle(cell, date);
38874   date = this.GetNextDate(date);
38875  }
38876 },
38877 GetVisibleDateOffsetInfo: function() {
38878  return {
38879   month: 0,
38880   year: this.GetIndex() * 100
38881  };
38882 },
38883 GetViewType: function() { return ASPx.DatePickerType.Decades; },
38884});
38885var ASPxClientCalendarFastNavigation = ASPx.CreateClass(null, {
38886 constructor: function(calendar) {
38887  this.calendar = calendar;
38888  this.activeMonth = -1;
38889  this.activeYear = -1;
38890  this.startYear = -1;
38891  this.activeView = null;
38892  this.partialId = "FNP";
38893  this.InitializeUI();
38894 },
38895 InitializeUI: function() {
38896  var item;
38897  var prefix = this.GetId();
38898  for(var m = 0; m < 12; m++) {
38899   item = this.GetMonthItem(m);
38900   if(!ASPx.IsExistsElement(item))
38901    break;
38902   item.id = prefix + "_M" + m;
38903   ASPx.Evt.AttachEventToElement(item, "click", ASPxClientCalendar.AnonymousHandlers.FastNavMonthClick(this.calendar.name, m));
38904  }
38905  for(var i = 0; i < 10; i++) {
38906   item = this.GetYearItem(i);
38907   if(!ASPx.IsExistsElement(item))
38908    break;
38909   item.id = prefix + "_Y" + i;
38910   ASPx.Evt.AttachEventToElement(item, "click", ASPxClientCalendar.AnonymousHandlers.FastNavYearClick(this.calendar.name, i));
38911  }
38912  ASPx.Evt.AttachEventToElement(this.GetPopupWindowElement(), "click", ASPxClientCalendar.AnonymousHandlers.MainElementClick(this.calendar.name));
38913  this.InitializePopup();
38914 },
38915 InitializePopup: function() {
38916  var popup = this.GetPopup();
38917  if(popup)
38918   popup.CloseUp.AddHandler(function(s, e) { this.Hide(); }.aspxBind(this));
38919 },
38920 IsActive: function() {
38921  return this.GetPopup().IsVisible();
38922 },
38923 Show: function() {
38924  this.Prepare();
38925  this.GetPopup().ShowAtElement(this.activeView.GetTitleElement());
38926 },
38927 Hide: function() {
38928  this.GetPopup().Hide();
38929 },
38930 SetMonth: function(month) {
38931  if(month != this.activeMonth) {
38932   var prevCell = this.GetMonthItem(this.activeMonth);
38933   var cell = this.GetMonthItem(month);
38934   if(ASPx.IsExistsElement(prevCell))
38935    this.ApplyItemStyle(prevCell, false, "M");
38936   this.ApplyItemStyle(cell, true, "M");
38937   this.activeMonth = month;
38938  }
38939 },
38940 ShiftMonth: function(offset) {
38941  var month = (this.activeMonth + offset) % 12;
38942  month = (month < 0) ? month + 12 : month;
38943  this.SetMonth(month);
38944 },
38945 SetYear: function(year) {
38946  var startYear = Math.floor(year / 10) * 10;
38947  this.SetStartYear(startYear);
38948  this.SetYearIndex(year - startYear);
38949 },
38950 SetYearIndex: function(index) {
38951  var prevIndex = this.activeYear - this.startYear;
38952  if(index != prevIndex) {
38953   var prevCell = this.GetYearItem(prevIndex);
38954   if(ASPx.IsExistsElement(prevCell))
38955    this.ApplyItemStyle(prevCell, false, "Y");
38956   var cell = this.GetYearItem(index);
38957   this.ApplyItemStyle(cell, true, "Y");
38958   this.activeYear = index + this.startYear;
38959  }
38960 },
38961 SetStartYear: function(year) {
38962  if(this.startYear == year) return;
38963  this.startYear = year;
38964  this.PrepareYearList();
38965 },
38966 ShiftYear: function(offset) {
38967  if(this.activeYear + offset > 99 && this.activeYear + offset < 9999)
38968   this.SetYear(this.activeYear + offset);
38969 },
38970 ShiftStartYear: function(offset) {
38971  this.SetStartYear(this.startYear + offset);
38972 },
38973 ApplyChanges: function() {
38974  this.Hide();
38975  var offset = this.calendar.GetOffsetInCurrentViewTypePeriods(this.calendar.visibleDate, new Date(this.activeYear, this.activeMonth, 1));
38976  offset -= this.activeView.GetIndex();
38977  if(offset != 0) {
38978   var date = this.calendar.GetNewVisibleDateByOffset(offset);
38979   this.calendar.OnVisibleMonthChanged(date);
38980  }
38981  this.calendar.OnMainElementClick();
38982 },
38983 CancelChanges: function() {
38984  this.Hide();
38985 },
38986 Prepare: function() {
38987  var date = this.activeView.visibleDate;
38988  this.activeYear = date.getFullYear();
38989  this.activeMonth = date.getMonth();
38990  this.startYear = ASPxClientCalendar.GetDecadeStartYear(this.activeYear);
38991  this.PrepareMonthList();
38992  this.PrepareYearList();
38993 },
38994 PrepareMonthList: function() {
38995  var item;
38996  for(var month = 0; month < 12; month++) {
38997   item = this.GetMonthItem(month);
38998   if(item == null)
38999    return;
39000   this.ApplyItemStyle(item, month == this.activeMonth, "M");
39001  }
39002 },
39003 PrepareYearList: function() {
39004  var year = this.startYear;
39005  var item;
39006  for(var index = 0; index < 10; index++) {
39007   item = this.GetYearItem(index);
39008   if(item == null)
39009    return;
39010   item.innerHTML = year;
39011   this.ApplyItemStyle(item, year == this.activeYear, "Y");
39012   year++;
39013  }
39014  this.PreparePreviousYearListCell();
39015  this.PrepareNextYearListCell();
39016 },
39017 PreparePreviousYearListCell: function() {
39018  var yearListTable = this.GetChildElement("y");
39019  if(!ASPx.IsExistsElement(yearListTable))
39020   return;
39021  var isEnabledDate = this.startYear > 100;
39022  var prevYearListCell = yearListTable.rows[0].cells[0];
39023  var isPrevYearListCellVisible = ASPx.GetElementVisibility(prevYearListCell);
39024  if(isPrevYearListCellVisible != isEnabledDate)
39025   ASPx.SetElementVisibility(prevYearListCell, isEnabledDate);
39026 },
39027 PrepareNextYearListCell: function() {
39028  var yearListTable = this.GetChildElement("y");
39029  if(!ASPx.IsExistsElement(yearListTable))
39030   return;
39031  var firstYearListRow = yearListTable.rows[0];
39032  var nextYearListCell = firstYearListRow.cells[firstYearListRow.cells.length - 1];
39033  var isLastYear = this.startYear + 9 == 9999;
39034  ASPx.SetElementVisibility(nextYearListCell, !isLastYear);
39035 },
39036 GetMonthItem: function(month) {
39037  var t = this.GetChildElement("m");
39038  if(!ASPx.IsExistsElement(t))
39039   return null;
39040  var colIndex = month % 4;
39041  var rowIndex = (month - colIndex) / 4;
39042  return t.rows[rowIndex].cells[colIndex];
39043 },
39044 GetYearItem: function(index) {
39045  var t = this.GetChildElement("y");
39046  if(!ASPx.IsExistsElement(t) || index < 0 || index > 9)
39047   return null;
39048  var colIndex = index % 5;
39049  var rowIndex = (index - colIndex) / 5;
39050  if(rowIndex == 0)
39051   colIndex++;
39052  return t.rows[rowIndex].cells[colIndex];
39053 },
39054 GetPopup: function() {
39055  return ASPx.GetControlCollection().Get(this.GetId());
39056 },
39057 GetPopupWindowElement: function() {
39058  return this.GetPopup().GetWindowElement(-1);
39059 },
39060 ApplyItemStyle: function(item, isSelected, type) {
39061  var info = new ASPxClientCalendarStyleInfo();
39062  this.calendar.ImportEtalonStyle(info, "FN" + type);
39063  if(isSelected)
39064   this.calendar.ImportEtalonStyle(info, "FN" + type + "S");
39065  info.Apply(item);
39066 },
39067 GetChildElement: function(postfix) {
39068  return ASPx.CacheHelper.GetCachedElementById(this.calendar, this.calendar.name + "_" + this.partialId + "_" + postfix);
39069 },
39070 GetId: function() {
39071  return this.calendar.name + "_" + this.partialId;
39072 },
39073 OnArrowUp: function(evt) {
39074  if(evt.shiftKey)
39075   this.ShiftMonth(-4);
39076  else
39077   this.ShiftYear(-5);
39078 },
39079 OnArrowDown: function(evt) {
39080  if(!evt.shiftKey)
39081   this.ShiftYear(5);
39082  else
39083   this.ShiftMonth(4);
39084 },
39085 OnArrowLeft: function(evt) {
39086  if(evt.shiftKey)
39087   this.ShiftMonth(-1);
39088  else
39089   this.ShiftYear(-1);
39090 },
39091 OnArrowRight: function(evt) {
39092  if(!evt.shiftKey)
39093   this.ShiftYear(1);
39094  else
39095   this.ShiftMonth(1);
39096 },
39097 OnPageUp: function(evt) {
39098  this.ShiftYear(-10);
39099 },
39100 OnPageDown: function(evt) {
39101  this.ShiftYear(10);
39102 },
39103 OnEnter: function() {
39104  this.ApplyChanges();
39105 },
39106 OnMonthClick: function(month) {
39107  this.SetMonth(month);
39108 },
39109 OnYearClick: function(index) {
39110  this.SetYearIndex(index);
39111 },
39112 OnYearShuffle: function(offset) {
39113  this.ShiftStartYear(offset);
39114 }
39115});
39116ASPx.ASPxClientCalendarFastNavigation = ASPxClientCalendarFastNavigation;
39117var ASPxClientCalendarStyleInfo = ASPx.CreateClass(null, {
39118 constructor: function() {
39119  this.className = "";
39120  this.cssText = "";
39121 },
39122 Clone: function() {
39123  var clone = new ASPxClientCalendarStyleInfo();
39124  clone.className = this.className;
39125  clone.cssText = this.cssText;
39126  return clone;
39127 },
39128 Apply: function(element) {
39129  if(element.className != this.className)
39130   element.className = this.className;
39131  if(element._style != this.cssText) {
39132   element.style.cssText = this.cssText; 
39133   element._style = this.cssText; 
39134  } 
39135 },
39136 Remove: function(element) {
39137  ASPx.RemoveClassNameFromElement(element, this.className);
39138  var styleRules = this.cssText.split(";");
39139  for(var i = 0; i < styleRules.length; i++) {
39140   var styleRule = styleRules[i];
39141   if(styleRule && element.style.cssText.indexOf(styleRule) !== -1)
39142    element.style.cssText = element.style.cssText.replace(styleRule, "");
39143  }
39144  element.style.cssText = element.style.cssText.replace(new RegExp(";+"), ";");
39145 },
39146 Import: function(element) {
39147  if(element.className.length > 0)
39148   this.AddClassName(element.className);
39149  var cssText = element.style.cssText;
39150  if(cssText.length > 0) {
39151   var pos = cssText.length - 1;
39152   while(pos > -1 && cssText.charAt(pos) == " ")
39153    --pos;
39154   if(cssText.charAt(pos) != ";")
39155    cssText += ";";
39156   this.cssText += cssText;
39157  }
39158 },
39159 AddClassName: function(className) {
39160  if(this.className.length > 1)
39161   this.className += " ";
39162  this.className += className;
39163 },
39164});
39165var ASPxClientCalendarSelectionEventArgs = ASPx.CreateClass(ASPxClientProcessingModeEventArgs, {
39166 constructor: function(processOnServer, selection){
39167  this.constructor.prototype.constructor.call(this, processOnServer);
39168  this.selection = selection;
39169 }
39170});
39171var ASPxDaysSelectingOnMouseOverEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
39172 constructor: function (overDate) {
39173  this.constructor.prototype.constructor.call(this);
39174  this.overDate = overDate;
39175 }
39176});
39177var ASPxClientCalendarCellClickEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
39178 constructor: function(date) {
39179  this.constructor.prototype.constructor.call(this);
39180  this.date = date;
39181 }
39182});
39183function aspxCalDocMouseUp(evt) {
39184 var target = ASPx.Evt.GetEventSource(evt);
39185 if(ASPx.activeCalendar != null && ASPx.IsExistsElement(target)) {
39186  ASPx.activeCalendar.forceMouseDown = false;
39187  if(ASPx.activeCalendar.isMouseDown) {
39188   var activeViews = ASPx.activeCalendar.GetActiveViews();
39189   for(var key in activeViews) {
39190    if(activeViews.hasOwnProperty(key)) {
39191     var view = activeViews[key];
39192     if(!view.isASPxClientCalendarView || view.isNavigationView) continue;
39193     var monthCell = view.GetDateCellContainer();
39194     var parent = target.parentNode;
39195     while(ASPx.IsExistsElement(parent)) {
39196      if(parent == monthCell)
39197       return;
39198      parent = parent.parentNode;
39199     }
39200    }
39201   }
39202   ASPx.activeCalendar.OnSelectionCancelled();   
39203  }
39204  ASPx.activeCalendar = null;
39205 }
39206}
39207function aspxCalCancelSelect() {
39208 if(ASPx.activeCalendar != null) {
39209  ASPx.activeCalendar.forceMouseDown = false;
39210  ASPx.activeCalendar.OnSelectionCancelled();  
39211 }
39212}
39213ASPx.CalFNYShuffle = function(name, offset) {
39214 var edit = ASPx.GetControlCollection().Get(name);
39215 if(edit != null)
39216  edit.fastNavigation.OnYearShuffle(offset);
39217};
39218ASPx.CalFNBClick = function(name, action) {
39219 var edit = ASPx.GetControlCollection().Get(name);
39220 if(edit != null) {
39221  switch(action) {
39222   case "ok":
39223    if(edit.fastNavigation)
39224     edit.fastNavigation.ApplyChanges();
39225    break;
39226   case "cancel":
39227    edit.CancelFastNavigation();
39228    break;
39229  }    
39230 }
39231};
39232window.ASPxClientCalendar = ASPxClientCalendar;
39233window.ASPxClientCalendarCustomDisabledDateEventArgs = ASPxClientCalendarCustomDisabledDateEventArgs;
39234window.ASPxClientCalendarSelection = ASPxClientCalendarSelection;
39235window.ASPxClientCalendarDateDisabledHelper = ASPxClientCalendarDateDisabledHelper;
39236window.ASPxClientCalendarStyleInfo = ASPxClientCalendarStyleInfo;
39237window.ASPxClientCalendarSelectionEventArgs = ASPxClientCalendarSelectionEventArgs;
39238})();
39239
39240(function(dx) {
39241 var BootstrapClientCalendar = ASPx.CreateClass(ASPxClientCalendar, {
39242  constructor: function(name) {
39243   this.constructor.prototype.constructor.call(this, name);
39244   this.needToSetCursor = false;
39245   this.needFocusedStyleDecoration = !this.isDateEditCalendar;
39246   this.feedbackRenderHelper = new ASPx.BootstrapEditFeedbackRenderHelper(this);
39247  },
39248  InlineInitialize: function() {
39249   if(!this.isDateEditCalendar)
39250    this.RequireStyleDecoration();
39251   ASPxClientCalendar.prototype.InlineInitialize.call(this);
39252   if(ASPx.Browser.TouchUI && !this.GetIsValid())
39253    this.UpdateErrorText();
39254  },
39255  InitializeEvents: function() {
39256   ASPxClientCalendar.prototype.InitializeEvents.call(this);
39257   if(ASPx.Browser.MacOSMobilePlatform) {
39258    var errorImage = this.GetErrorImage();
39259    if(errorImage)
39260     ASPx.Evt.AttachEventToElement(errorImage, "touchstart", function() { });
39261   }
39262  },
39263  CreateAdaptivityCssRules: function() {
39264   if (this.switchToSingleMonthAtWindowInnerWidth <= 0)
39265    return;
39266   var styleSheet = ASPx.GetCurrentStyleSheet();
39267   if (!styleSheet || !styleSheet.insertRule) return;
39268   var lastColumn = this.columns - 1;
39269   var rule =
39270    "@media all and (max-width: " + this.switchToSingleMonthAtWindowInnerWidth + "px) { " +
39271    "#" + this.name + " ." + CALENDAR_VIEW_CLASS + ":not(.view-visible) { display: none; }" +
39272    ".view-visible #" + this.name + "_" + this.GetArrowButtonID("M", true, "0x0") + " > *," +
39273    ".view-visible #" + this.name + "_" + this.GetArrowButtonID("M", false, "0x" + lastColumn) + " > *," +
39274    ".view-visible #" + this.name + "_" + this.GetArrowButtonID("Y", true, "0x0") + " > *," +
39275    ".view-visible #" + this.name + "_" + this.GetArrowButtonID("Y", false, "0x" + lastColumn) + " > *," +
39276    ".view-visible #" + this.name + "_" + this.GetArrowButtonID("TP", true, "0x0") + " > *," +
39277    ".view-visible #" + this.name + "_" + this.GetArrowButtonID("TP", false, "0x" + lastColumn) + " > *" +
39278    " { visibility: visible!important; } " +
39279    "}";
39280   styleSheet.insertRule(rule, styleSheet.cssRules.length);
39281  },
39282  CreateFastNavigation: function() {
39283   return new ASPx.BootstrapCalendarFastNavigation(this);
39284  },
39285  EnsureHideFastNavigation: function() {
39286   if(this.fastNavigation && this.showFastPopup)
39287    this.fastNavigation.Hide();
39288   else if(this.IsInlineFastNavigationActive())
39289    this.ChangeView(this.pickerType);
39290  },
39291  ChangeEnabledAttributes: function(enabled) {
39292   ASPxClientCalendar.prototype.ChangeEnabledAttributes.call(this, enabled);
39293   if(!this.isDateEditCalendar) {
39294    var focusableElement = this.GetCalendarContainerElement();
39295    if(focusableElement) {
39296     var changeMethod = enabled ? ASPx.Attr.RestoreTabIndexAttribute : ASPx.Attr.SaveTabIndexAttributeAndReset;
39297     changeMethod(focusableElement);
39298    }
39299   }
39300  },
39301  GetChangeButtonEnabledAttributesMethod: function(enabled) {
39302   return enabled ? ASPx.RemoveClassNameFromElement : ASPx.AddClassNameToElement;
39303  },
39304  ChangeButtonEnabledAttributes: function(element, method) {
39305   method(element, ASPx.BootstrapCssSelectors.Disabled);
39306  },
39307  GetDayInRangeClassName: function() {
39308   return [DAY_IN_RANGE_CLASS, ASPx.BootstrapCssSelectors.Backgroun
39308dLight].join(" ");
39309  },
39310  NeedApplySelectionToDayInRange: function() {
39311   return ASPx.BootstrapCore.IsBootstrap3;
39312  },
39313  ImportEtalonStyle: function(info, suffix) {
39314   var className = "";
39315   switch(suffix) {
39316    case "FNMS":
39317    case "FNYS":
39318    case "FNIS":
39319    case "MYS":
39320     className = ASPx.BootstrapCore.IsBootstrap3 ? ASPx.BootstrapCssSelectors.Active : ASPx.BootstrapCssSelectors.TableActive;
39321     break;
39322    case "FNM":
39323    case "FNY":
39324     className = this.cssClasses && this.cssClasses.fni;
39325     break;
39326    case "MY":
39327     className = "dxbs-fast-nav-item";
39328     break;
39329    case "MYA":
39330     className = "text-muted";
39331     break;
39332    case "MYDD":
39333     className = ASPx.BootstrapCssSelectors.Disabled;
39334     break;
39335    default:
39336     className = this.cssClasses && this.cssClasses[suffix.toLowerCase()];
39337     break;
39338   }
39339   if(className && className.length) {
39340    var currentClassNameParts = info.className.replace(/^\s+|\s+$/g, '').split(/\s+/);
39341    if(currentClassNameParts && currentClassNameParts.length) {
39342     var classNameParts = className.replace(/^\s+|\s+$/g, '').split(/\s+/);
39343     var resultClassNameParts = [];
39344     for(var i = 0; i < classNameParts.length; i++) {
39345      if(currentClassNameParts.indexOf(classNameParts[i]) < 0)
39346       resultClassNameParts.push(classNameParts[i]);
39347     }
39348     className = ASPx.Str.Trim(resultClassNameParts.join(" "));
39349    }
39350    if(className.length)
39351     info.className += (info.className.length > 1 ? " " : "") + className;
39352   }
39353  },
39354  CanApplyDayCellStyle: function(suffix, isCurrentMonthDay) {
39355   return isCurrentMonthDay || suffix != "DW" && suffix != "DT";
39356  },
39357  GetCalendarRowElements: function() {
39358   return ASPx.GetChildNodesByClassName(this.GetCalendarContainerElement(), CALENDAR_ROW_CLASS);
39359  },
39360  GetCalendarViewCellElements: function(rowElement) {
39361   return ASPx.GetChildNodesByPartialClassName(rowElement, CALENDAR_VIEW_CLASS);
39362  },
39363  GetMonthCell: function(viewIdPostfix) {
39364   return ASPx.GetParentByClassName(this.GetMonthTable(viewIdPostfix), ASPx.BootstrapCssSelectors.PanelBody);
39365  },
39366  GetMonthTable: function(viewIdPostfix) {
39367   var calendarContainer = this.GetCalendarContainerElement();
39368   return viewIdPostfix && viewIdPostfix.length ? ASPxClientCalendar.prototype.GetMonthTable.call(this, viewIdPostfix)
39369    : calendarContainer && calendarContainer.querySelectorAll("." + MONTH_TABLE_CLASS)[0];
39370  },
39371  GetViewCell: function(viewIdPostfix) {
39372   return ASPx.GetParentByClassName(this.GetMonthTable(viewIdPostfix), CALENDAR_VIEW_CLASS);
39373  },
39374  GetFooter: function() {
39375   return ASPx.GetChildNodesByQuerySelector(this.GetMainElement(), "." + ASPx.BootstrapCssSelectors.PanelFooter)[0];
39376  },
39377  GetArrowButtonID: function(type, isNext, viewID) {
39378   var id = (isNext ? "N" : "P") + type.toUpperCase() + "C";
39379   if (this.columns > 1 && viewID === undefined)
39380    id += "_0x" + (isNext ? this.columns - 1 : 0);
39381   else if (viewID)
39382    id += "_" + viewID;
39383   return id;
39384  },
39385  SetMonthTableCellContent: function(cell, content, isWeekNumber) {
39386   var contentContainerTagName = isWeekNumber ? "small" : "a";
39387   ASPx.Security.setInnerHtml(cell, "<" + contentContainerTagName + ">" + content + "</" + contentContainerTagName + ">", ASPx.Security.DataType.Trusted);
39388  },
39389  PopulateStyleDecorationPostfixes: function() {
39390   this.styleDecoration.AddPostfix("");
39391  },
39392  CreateStyleDecoration: function () {
39393   return new ASPx.BootstrapEditorStyleDecoration(this);
39394  },
39395  GetLoadingPanelElement: function() {
39396   return ASPx.BootstrapLoadingPanelManager.getLoadingPanel(this.name, this.loadingPanel);
39397  },
39398  GetLoadingDiv: function() {
39399   return ASPx.BootstrapLoadingPanelManager.getLoadingDiv(this.name, this.loadingPanel);
39400  },
39401  GetCalendarContainerElement: function() {
39402   var mainElement = this.GetMainElement();
39403   return !mainElement || ASPx.ElementHasCssClass(mainElement, "dxbs-calendar") ? mainElement : mainElement.querySelector(".dxbs-calendar");
39404  },
39405  FindInputElement: function() {
39406   return this.isDateEditCalendar ? ASPxClientCalendar.prototype.FindInputElement.call(this) : this.GetCalendarContainerElement();
39407  },
39408  GetControlCell: function() {
39409   return this.GetCalendarContainerElement();
39410  },
39411  EnsureControlCellStylesLoaded: function() { },
39412  ClearControlCellStyles: function() { },
39413  RestoreControlCellStyles: function() { },
39414  GetElementRequiredForErrorFrame: function() {
39415   return this.GetMainElement();
39416  },
39417  GetErrorImage: function() {
39418   return this.feedbackRenderHelper.getErrorImage();
39419  },
39420  UpdateErrorText: function() {
39421   this.feedbackRenderHelper.updateErrorText();
39422  },
39423  ChangeErrorCellVisibility: function(visible, useVisibilityAttribute) {
39424   this.feedbackRenderHelper.setErrorControlVisible(visible);
39425  },
39426  GetCaptionCell: function() {
39427   return ASPx.CacheHelper.GetCachedElement(this, "captionElement",
39428    function() {
39429     var editCaptionCssClass = "dxbs-edit-caption";
39430     var mainElement = this.GetMainElement();
39431     if(!mainElement)
39432      return null;
39433     var captionElement = mainElement.querySelector("." + editCaptionCssClass);
39434     if(!captionElement && mainElement === this.GetCalendarContainerElement()) {
39435      if(mainElement.previousSibling && ASPx.ElementHasCssClass(mainElement.previousSibling, editCaptionCssClass))
39436       captionElement = mainElement.previousSibling;
39437      else if(mainElement.nextSibling && ASPx.ElementHasCssClass(mainElement.nextSibling, editCaptionCssClass))
39438       captionElement = mainElement.nextSibling;
39439     }
39440     return captionElement;
39441    }
39442   );
39443  },
39444  getCaptionTextNode: function() {
39445   return ASPx.GetNormalizedTextNode(this.GetCaptionCell());
39446  },
39447  getCaptionRelatedCellCount: function() {
39448   return undefined;
39449  },
39450  IsVisible: function() {
39451   if(this.isDateEditCalendar) {
39452    var element = this.GetMainElement();
39453    return element && ASPx.IsElementVisible(element.parentNode, true);
39454   }
39455   return ASPxClientCalendar.prototype.IsVisible.call(this);
39456  },
39457  SetVisible: function(visible) {
39458   if(this.clientVisible != visible && this.GetMainElement() === this.GetCalendarContainerElement())
39459    ASPx.SetElementDisplay(this.GetCaptionCell(), visible);
39460   ASPxClientCalendar.prototype.SetVisible.call(this, visible);
39461  },
39462  SetElementVisible: function(element, visible) {
39463   if(element && ASPx.ElementHasCssClass(element, ASPx.BootstrapCssSelectors.Hidden) == visible) {
39464    var action = visible ? ASPx.RemoveClassNameFromElement : ASPx.AddClassNameToElement;
39465    action(element, ASPx.BootstrapCssSelectors.Hidden);
39466   }
39467   if(ASPx.GetElementDisplay(element) != visible)
39468    ASPxClientCalendar.prototype.SetElementVisible.call(this, element, visible);
39469  },
39470  IsElementBelongToInputElement: function(element) {
39471   return this.isDateEditCalendar ? ASPxClientCalendar.prototype.IsElementBelongToInputElement.call(this, element) : this.IsEditorElement(element);
39472  },
39473  SetViewMainElementParentsVisibility: function(monthViewMainElement, yearViewMainElement, showMonthCell) { },
39474  IsPopupFastNavigationActive: function() {
39475   return this.showFastPopup && this.fastNavigation && this.fastNavigation.IsActive();
39476  }
39477 });
39478 var BootstrapCalendarFastNavigation = ASPx.CreateClass(ASPx.ASPxClientCalendarFastNavigation, {
39479  constructor: function(calendar) {
39480   this.constructor.prototype.constructor.call(this, calendar);   
39481  },
39482  GetMonthItem: function(month) {
39483   var t = this.GetChildElement("m");
39484   if(!ASPx.IsExistsElement(t))
39485    return null;
39486   var colIndex = month % 4;
39487   var rowIndex = (month - colIndex) / 4;
39488   return t.rows[rowIndex].cells[colIndex];
39489  },
39490  GetYearItem: function(index) {
39491   var t = this.GetChildElement("y");
39492   if(!ASPx.IsExistsElement(t) || index < 0 || index > 9)
39493    return null;
39494   var colIndex = index % 5;
39495   var rowIndex = (index - colIndex) / 5;
39496   if(rowIndex == 0)
39497    colIndex++;
39498   return t.rows[rowIndex].cells[colIndex];
39499  },
39500  InitializeUI: function() {
39501   var item;
39502   var prefix = this.GetId();
39503   for(var m = 0; m < 12; m++) {
39504    item = this.GetMonthItem(m);
39505    if(!ASPx.IsExistsElement(item))
39506     break;
39507    item.id = prefix + "_M" + m;
39508    ASPx.Evt.AttachEventToElement(item, "click", ASPxClientCalendar.AnonymousHandlers.FastNavMonthClick(this.calendar.name, m));
39509   }
39510   var itemsCount = 10;
39511   for(var i = 0; i < itemsCount; i++) {
39512    item = this.GetYearItem(i);
39513    if(!ASPx.IsExistsElement(item))
39514     break;
39515    item.id = prefix + "_Y" + i;
39516    ASPx.Evt.AttachEventToElement(item, "click", ASPxClientCalendar.AnonymousHandlers.FastNavYearClick(this.calendar.name, i));
39517   }   
39518   var cancelChangesHandler = function() { this.calendar.CancelFastNavigation(); }.bind(this);
39519   ASPx.Evt.AttachEventToElement(this.GetPopupWindowElement(), "click", ASPxClientCalendar.AnonymousHandlers.MainElementClick(this.calendar.name));
39520   var prevYearButton = this.GetPopup().querySelector("." + FAST_NAV_PREV_YEAR_CLASS);
39521   if(prevYearButton)
39522    ASPx.Evt.AttachEventToElement(prevYearButton, "click", function() { this.OnYearShuffle(-10); }.bind(this));
39523   var nextYearButton = this.GetPopup().querySelector("." + FAST_NAV_NEXT_YEAR_CLASS);
39524   if(nextYearButton)
39525    ASPx.Evt.AttachEventToElement(nextYearButton, "click", function() { this.OnYearShuffle(10); }.bind(this));
39526   var okButton = this.GetChildElement("BO");
39527   if(okButton)
39528    ASPx.Evt.AttachEventToElement(okButton, "click", function() { this.ApplyChanges(); }.bind(this));
39529   var cancelButton = this.GetChildElement("BC");
39530   if(cancelButton)
39531    ASPx.Evt.AttachEventToElement(cancelButton, "click", cancelChangesHandler);
39532  },
39533  IsActive: function() {
39534   return ASPx.GetElementDisplay(this.GetPopup());
39535  },
39536  GetPopup: function() {
39537   return this.calendar.GetChildElement(this.partialId);
39538  },
39539  GetPopupWindowElement: function() {
39540   return this.GetPopup();
39541  },
39542  Show: function() {
39543   this.Prepare();
39544   if(!this.calendar.focused && !this.calendar.isDateEditCalendar)
39545    this.calendar.SetFocus();
39546   ASPx.BootstrapPopupManager.registerVisiblePopup(this.getPopupElements(), function(){ this.OnHide(); }.aspxBind(this));
39547   ASPx.BootstrapPopupManager.correctPopupPositionForClientWindow(this.getPopupElements(), "LeftSides", 0,
39548    "Below", -ASPx.GetClientTop(this.getOriginElement()));
39549   ASPx.Attr.Aria.SetExpanded(this.getOriginElement(), true);
39550  },
39551  Hide: function() {
39552   ASPx.BootstrapPopupManager.unregisterVisiblePopup(this.getPopupElements());
39553  },
39554  OnHide: function() {
39555   ASPx.Attr.Aria.SetExpanded(this.getOriginElement(), false);
39556   this.Hide();
39557  },
39558  getOriginElement: function() {
39559   return this.activeView.GetTitleElement();
39560  },
39561  getPopupElements: function() {
39562   return [this.GetPopup(), this.getOriginElement()];
39563  }
39564 });
39565 ASPx.BootstrapCalendarFastNavigation = BootstrapCalendarFastNavigation;
39566 var CALENDAR_ROW_CLASS = "calendar-row",
39567  CALENDAR_VIEW_CLASS = "calendar-view",
39568  MONTH_TABLE_CLASS = "dxbs-month-table",
39569  DAY_IN_RANGE_CLASS = "dxbs-in-range",
39570  FAST_NAV_PREV_YEAR_CLASS = "prev-year",
39571  FAST_NAV_NEXT_YEAR_CLASS = "next-year";
39572 dx.BootstrapClientCalendar = BootstrapClientCalendar;
39573}
39573)(dx || (dx = {}));
39574(function () {
39575var ASPxClientCallback = ASPx.CreateClass(ASPxClientComponent, {
39576 constructor: function (name) {
39577  this.constructor.prototype.constructor.call(this, name);
39578  this.CallbackComplete = new ASPxClientEvent();
39579 },
39580 SendCallback: function (parameter) {
39581  this.PerformCallback(parameter);
39582 },
39583 PerformCallback: function (parameter, onSuccess) {
39584  if (!ASPx.IsExists(parameter)) parameter = "";
39585  this.CreateCallback(parameter, null, onSuccess);
39586 },
39587 OnCallback: function (result) {
39588  result.parameter = ASPx.Str.DecodeHtmlViaTextArea(result.parameter);
39589  var args = new ASPxClientCallbackCompleteEventArgs(result.parameter, result.data);
39590  this.CallbackComplete.FireEvent(this, args);
39591 }
39592});
39593ASPxClientCallback.Cast = ASPxClientControl.Cast;
39594var ASPxClientCallbackCompleteEventArgs = ASPx.CreateClass(ASPxClientEventArgs, {
39595 constructor: function (parameter, result) {
39596  this.constructor.prototype.constructor.call(this);
39597  this.parameter = parameter;
39598  this.result = result;
39599 }
39600});
39601window.ASPxClientCallback = ASPxClientCallback;
39602window.ASPxClientCallbackCompleteEventArgs = ASPxClientCallbackCompleteEventArgs;
39603})();
39604
39605(function(dx) {
39606 var BootstrapClientCallbackPanel = ASPx.CreateClass(ASPxClientControl, {
39607  constructor: function(name) {
39608   this.constructor.prototype.constructor.call(this, name);
39609   this.hideContentOnCallback = true;
39610   this.isLoadingPanelTextEmpty = false;
39611   this.touchUIScroller = null;
39612  },
39613  Initialize: function(){
39614   ASPxClientControl.prototype.Initialize.call(this);
39615   this.touchUIScroller = ASPx.TouchUIHelper.makeScrollableIfRequired(this.GetMainElement());
39616  },
39617  OnCallback: function(result) {
39618   ASPx.Security.setInnerHtml(this.getContentElement(), result, ASPx.Security.DataType.Trusted);
39619   if(this.touchUIScroller)
39620    this.touchUIScroller.ChangeElement(this.getContentElement());
39621  },
39622  ShowLoadingPanel: function() {
39623   var element = this.getContentElement();
39624   var mainElement = (element.tagName == "TD") ? this.GetMainElement() : element;
39625   if(!this.hideContentOnCallback)
39626    this.CreateLoadingPanelWithAbsolutePosition(this.GetMainElement().parentNode, mainElement);
39627   else
39628    this.CreateLoadingPanelInsideContainer(element, true, true, false);
39629  },
39630  ShowLoadingDiv: function() {
39631   this.CreateLoadingDiv(this.GetMainElement().parentNode, this.getContentElement());
39632  },
39633  GetCallbackAnimationElement: function() {
39634   return this.getContentElement();
39635  },
39636  PerformCallback: function(parameter, onSuccess) {
39637   this.CreateCallback(parameter, null, null, onSuccess);
39638  },
39639  CreateCallback: function(arg, command, callbackInfo, handler) {
39640   this.ShowLoadingElements();
39641   ASPxClientControl.prototype.CreateCallback.call(this, arg, command, handler);
39642  },
39643  GetLoadingPanelElement: function() {
39644   return ASPx.BootstrapLoadingPanelManager.getLoadingPanel(this.name, this.loadingPanel);
39645  },
39646  GetLoadingDiv: function() {
39647   return ASPx.BootstrapLoadingPanelManager.getLoadingDiv(this.name, this.loadingPanel);
39648  },
39649  GetContentHtml: function(){
39650   return this.getContentElement().innerHTML;
39651  },
39652  SetContentHtml: function(html, useAnimation) {
39653   ASPx.Security.setInnerHtml(this.getContentElement(), html, ASPx.Security.DataType.Trusted);
39654   if(this.touchUIScroller)
39655    this.touchUIScroller.ChangeElement(this.getContentElement());
39656   if(useAnimation && typeof (ASPx.AnimationHelper) != "undefined")
39657    ASPx.AnimationHelper.fadeIn(this.getContentElement());
39658  },
39659  getContentElement: function() {
39660   return this.GetMainElement();
39661  }
39662 });
39663 dx.BootstrapClientCallbackPanel = BootstrapClientCallbackPanel;
39664})(dx || (dx = {}));
39665(function() {
39666  var CONST = {
39667  POSTFIX: {
39668   BUTTON_PANEL: "DXButtonPanel",
39669   BUTTONS_CONTAINER: "DXButtonsContainer",
39670   BUTTONS_SHADER: "DXButtonsShader",
39671   DISABLED_COVER: "DXDisabledCover",
39672   CANCEL_BUTTON: "DXCancelButton",
39673   DELETE_BUTTON: "DXDeleteButton",
39674   DROP_ZONE: "DXDropZone",
39675   EMPTY_VALUE_PLACEHOLDER: "EVP",
39676   EMPTY_VALUE_IMAGE: "EVI",
39677   IMAGE_CONTAINER: "DXImageContainer",
39678   OPEN_DIALOG_BUTTON: "DXOpenDialogButton",    
39679   PREVIEW_CONTROL: "DXPreview",
39680   PROGRESS_BAR: "DXProgressBar",
39681   PROGRESS_PANEL: "DXProgressPanel",
39682   UPLOAD_CONTROL: "DXUploadEditor",       
39683   VALUE_KEY_INPUT: "DXValueKeyInput"
39684  },
39685  CALLBACK_PREFIX: {
39686   CUSTOM_CALLBACK: "BICC",
39687  }
39688 };
39689 var ButtonPanelVisibilityEnum = {
39690  None: 0,
39691  Faded: 1,
39692  OnMouseOver: 2,
39693  Always: 3
39694 };
39695 var getChildElement = function(editor, postfix) {
39696  var name = editor ? editor.name || editor.id : '';
39697  var id = name + '_' + postfix;
39698  return document.getElementById(id);
39699 };
39700 var getChildControl = function(editor, postfix) {
39701  return ASPx.GetControlCollection().Get(editor.name + '_' + postfix);
39702 };
39703 var formatCallbackArg = function(prefix, arg) { 
39704  arg = arg ? arg.toString() : '';
39705  return prefix + "|" + arg.length + ';' + arg + ';';
39706 };
39707 var ASPxClientBinaryImage = ASPx.CreateClass(ASPxClientEdit, {
39708  KeyPlaceHolder: "||dxbiKey||",
39709  constructor: function(name) {
39710   this.constructor.prototype.constructor.call(this, name);
39711   this.Click = new ASPxClientEvent();
39712   this.imageWidth = "";
39713   this.imageHeight = "";
39714   this.buttonPanelVisibility = null;
39715   this.enableEditing = false;
39716   this.imageContainerSizeIsValid = false;
39717   this.emptyImageContainerSizeIsValid = false;
39718   this.showLoadingImage = false;
39719   this.loadingImageData = null;
39720   this.isASPxClientBinaryImage = true;
39721   this.imageUrlTemplate = "";
39722   this.onDeleteButtonClick = this.OnDeleteButtonClick.aspxBind(this);
39723   this.onButtonPanelTouchUp = this.OnButtonPanelTouchUp.aspxBind(this);
39724   this.onCancelButtonClick = this.OnCancelButtonClick.aspxBind(this);
39725  },
39726  Initialize: function() {
39727   ASPxClientEdit.prototype.Initialize.call(this);
39728   if(this.enableEditing) {
39729    this.ShowValueDisplayElement();
39730    this.InitializeButtonPanel();
39731    this.InitializeProgressPanel();
39732    this.InitializeUploadControl();
39733   }
39734  },
39735  InitializeButtonPanel: function() {
39736   var buttonPanel = this.GetButtonPanel();
39737   if(!buttonPanel)
39738    return;
39739   this.UpdateDeleteButtonDisplay();
39740   if(this.buttonPanelVisibility != ButtonPanelVisibilityEnum.Always)
39741    this.InitializeButtonPanelEvents();
39742  },
39743  InitializeButtonPanelEvents: function() {
39744   if(ASPx.Browser.TouchUI) 
39745    this.InitializeButtonPanelTouchEvents();
39746   else
39747    this.InitializeButtonPanelMouseEvents();
39748  },
39749  InitializeButtonPanelMouseEvents: function() {
39750   ASPx.Evt.AttachMouseEnterToElement(this.GetMainElement(), this.OnButtonPanelMouseOver.aspxBind(this), this.OnButtonPanelMouseOut.aspxBind(this));
39751  },
39752  InitializeButtonPanelTouchEvents: function() {
39753   ASPx.Evt.AttachEventToElement(this.GetMainElement(),ASPx.TouchUIHelper.touchMouseUpEventName, this.onButtonPanelTouchUp);
39754  },
39755  InitializeProgressPanel: function() {
39756   this.InitializeProgressPanelEvents();
39757  },
39758  InitializeProgressPanelEvents: function() {
39759   cancelButton = this.GetCancelButton();
39760   if(cancelButton)
39761    ASPx.Evt.AttachEventToElement(cancelButton, "click", this.onCancelButtonClick);
39762  },
39763  InitializeUploadControl: function() {
39764   var uploadControl = this.GetUploadControl();
39765   if(this.allowDropOnPreview) {
39766    uploadControl.DropZoneEnter.AddHandler(function() {
39767     if(!this.GetEnabled())
39768      return;
39769     var buttonPanel = this.GetButtonPanel();
39770     if(buttonPanel)
39771      ASPx.SetElementDisplay(buttonPanel, false);
39772     ASPx.SetElementDisplay(this.GetImageContainer(), false);
39773     ASPx.SetElementDisplay(this.GetEmptyValuePlaceholder(), false);
39774     ASPx.SetElementDisplay(this.GetDropZone(), true);
39775    }.aspxBind(this));
39776    uploadControl.DropZoneLeave.AddHandler(function() {
39777     if(!this.GetEnabled())
39778      return;
39779     var buttonPanel = this.GetButtonPanel();
39780     if(buttonPanel)
39781      ASPx.SetElementDisplay(buttonPanel, true);
39782     this.ShowValueDisplayElement();
39783     ASPx.SetElementDisplay(this.GetDropZone(), false);
39784    }.aspxBind(this));
39785   }
39786   uploadControl.FileUploadComplete.AddHandler(function(s, e) {
39787    this.OnEndUpload(e);
39788   }.aspxBind(this));
39789   uploadControl.UploadingProgressChanged.AddHandler(function(s, e) {
39790    this.OnUploadProgressChanged(e);
39791   }.aspxBind(this));
39792   uploadControl.FilesUploadStart.AddHandler(function() {
39793    this.OnStartUpload();
39794   }.aspxBind(this));
39795  },
39796  AdjustControl: function() {
39797   ASPxClientEdit.prototype.AdjustControl.call(this);
39798   if(this.enableEditing) 
39799    this.ShowValueDisplayElement();
39800  },
39801  OnClick: function(htmlEvent) {
39802   this.RaiseClick(this.GetMainElement(), htmlEvent);
39803  },
39804  RaiseClick: function(htmlElement, htmlEvent){
39805   if(!this.Click.IsEmpty()){
39806    var args = new ASPxClientEditClickEventArgs(htmlElement, htmlEvent);
39807    this.Click.FireEvent(this, args);
39808   }
39809  }, 
39810  ChangeEnabledAttributes: function(enabled) {
39811   if(!this.enableEditing)
39812    return;
39813   this.ChangeElementsEnabledAttributes(ASPx.Attr.ChangeAttributesMethod(enabled));   
39814   this.ChangeEnabledEventsAttributes(ASPx.Attr.ChangeEventsMethod(enabled));
39815   this.ChangeDialogTriggerID(enabled);
39816   this.ChangeDropZoneID(enabled);
39817   ASPx.SetElementDisplay(this.GetDisabledCover(), !enabled);
39818  },
39819  ChangeElementsEnabledAttributes: function(method){
39820   method(this.GetImageElement(), "onclick");
39821   method(this.GetEmptyValuePlaceholder(), "onclick");
39822  },
39823  ChangeEnabledEventsAttributes: function(method){
39824   var deleteButton = this.GetDeleteButton();
39825   if (deleteButton)
39826    method(deleteButton, "click", this.onDeleteButtonClick);
39827  },
39828  ChangeDialogTriggerID: function(enabled){
39829   var openButton = this.GetOpenDialogButton();
39830   if (openButton) {
39831    var id = enabled ? openButton.id : "";
39832    this.GetUploadControl().SetDialogTriggerID(id);
39833   }
39834  },
39835  ChangeDropZoneID: function(enabled){
39836   var id = enabled ? this.GetMainElement().id : "";
39837   this.GetUploadControl().SetExternalDropZoneID(id);
39838  },
39839  GetWidth: function(){
39840   return this.GetSize(true);
39841  },
39842  GetHeight: function(){
39843   return this.GetSize(false);
39844  },
39845  SetWidth: function(width) {
39846   this.SetSize(width, this.GetHeight());
39847  },
39848  SetHeight: function(height) {
39849   this.SetSize(this.GetWidth(), height);
39850  },
39851  SetSize: function(width, height){
39852   this.imageWidth = width + "px";
39853   this.imageHeight = height + "px";
39854   var mainElement = this.GetMainElement();
39855   if(ASPx.IsExistsElement(mainElement))
39856    ASPx.ImageUtils.SetSize(mainElement, width, height);
39857   if(this.enableEditing) {
39858    this.imageContainerSizeIsValid = false;
39859    this.emptyImageContainerSizeIsValid = false;
39860    this.ShowValueDisplayElement();
39861   }
39862  },
39863  GetSize: function(isWidth){
39864   var image = this.GetMainElement();
39865   if(ASPx.IsExistsElement(image))
39866    return ASPx.ImageUtils.GetSize(image, isWidth);
39867   return -1;
39868  },
39869  FadeButtonPanelOpacity: function(show) {
39870   if(!this.IsAnimationEnabled() || !this.GetButtonPanel())
39871    return;
39872   var element = this.GetButtonPanelAnimatedElement();
39873   ASPx.AnimationHelper.fadeTo(element, {
39874    from: show ? this.GetButtonPanelMinOpacity() : 1, 
39875    to: show ? 1 : this.GetButtonPanelMinOpacity(),
39876    duration: 100
39877   });
39878   this.FadeButtonsOpacity(show);
39879  },
39880  FadeButtonsOpacity: function(show) {
39881   var maxButtonOpacity = 0.75;
39882   var options = {
39883    animationEngineType: ASPx.AnimationEngineType.JS,     
39884    property: "opacity",
39885    duration: 100,
39886    from: show ? this.GetButtonPanelMinOpacity() : maxButtonOpacity,
39887    to: show ? maxButtonOpacity : this.GetButtonPanelMinOpacity()
39888   };
39889   this.FadeButtonOpacity(this.GetDeleteButton(), options);
39890   this.FadeButtonOpacity(this.GetOpenDialogButton(), options);
39891  },
39892  FadeButtonOpacity: function (element, options) {
39893   if(!ASPx.IsExistsElement(element))
39894    return;
39895   var transition = ASPx.AnimationHelper.createAnimationTransition(element, options);
39896   transition.Start(options.from, options.to);
39897  },
39898  IsAnimationEnabled: function() {
39899   return this.GetEnabled();
39900  },
39901  OnCancelButtonClick: function() {
39902   var uploadControl = this.GetUploadControl();
39903   if(uploadControl && uploadControl.isInCallback)
39904    uploadControl.Cancel();
39905   this.UpdateElementsVisibility();
39906  },
39907  OnDeleteButtonClick: function() {
39908   this.Clear();
39909  },
39910  OnButtonPanelMouseOver: function() {
39911   this.FadeButtonPanelOpacity(true);
39912  },
39913  OnButtonPanelMouseOut: function() {
39914   this.FadeButtonPanelOpacity();
39915  },
39916  OnButtonPanelTouchUp: function() {
39917   var show = ASPx.GetElementOpacity(this.GetButtonPanelAnimatedElement()) == this.GetButtonPanelMinOpacity();
39918   this.FadeButtonPanelOpacity(show);
39919  },
39920  GetButtonPanel: function() {
39921   return getChildElement(this, CONST.POSTFIX.BUTTON_PANEL);
39922  },
39923  GetButtonPanelAnimatedElement: function() {
39924   return this.buttonPanelVisibility == ButtonPanelVisibilityEnum.Faded ? this.GetButtonsShader(): this.GetButtonPanel();
39925  },
39926  GetButtonsContainer: function() {
39927   return getChildElement(this.GetButtonPanel(), CONST.POSTFIX.BUTTONS_CONTAINER);
39928  },
39929  GetButtonsShader: function() {
39930   return getChildElement(this.GetButtonPanel(), CONST.POSTFIX.BUTTONS_SHADER);
39931  },
39932  GetButtonPanelMinOpacity: function() {
39933   return this.buttonPanelVisibility == ButtonPanelVisibilityEnum.Faded ? 0.6 : 0;
39934  },
39935  GetCancelButton: function() {
39936   return getChildElement(this, CONST.POSTFIX.CANCEL_BUTTON);
39937  },
39938  GetDeleteButton: function() {
39939   return getChildElement(this.GetButtonPanel(), CONST.POSTFIX.DELETE_BUTTON);
39940  },
39941  GetDisabledCover: function() {
39942   return getChildElement(this, CONST.POSTFIX.DISABLED_COVER);
39943  },  
39944  GetDropZone: function() {
39945   return getChildElement(this, CONST.POSTFIX.DROP_ZONE);
39946  },
39947  GetImageContainer: function() {
39948   return getChildElement(this, CONST.POSTFIX.IMAGE_CONTAINER);
39949  },
39950  GetImageElement: function() {
39951   return getChildElement(this, CONST.POSTFIX.PREVIEW_CONTROL);
39952  },
39953  GetEmptyValuePlaceholder: function() {
39954   return getChildElement(this, CONST.POSTFIX.EMPTY_VALUE_PLACEHOLDER);
39955  },
39956  GetEmptyValueImage: function() {
39957   return getChildElement(this, CONST.POSTFIX.EMPTY_VALUE_IMAGE);
39958  },
39959  GetOpenDialogButton: function() {
39960   return getChildElement(this.GetButtonPanel(), CONST.POSTFIX.OPEN_DIALOG_BUTTON);   
39961  },
39962  GetProgressBar: function() { 
39963   return getChildControl(this, CONST.POSTFIX.PROGRESS_BAR); 
39964  },
39965  GetProgressPanel: function() { 
39966   return getChildElement(this, CONST.POSTFIX.PROGRESS_PANEL);   
39967  },  
39968  GetValueHiddenField: function() {
39969   return getChildElement(this, CONST.POSTFIX.VALUE_KEY_INPUT);
39970  },
39971  GetStateInput: function() {
39972   return this.GetValueHiddenField();
39973  },
39974  GetUploadControl: function() {
39975   return getChildControl(this, CONST.POSTFIX.UPLOAD_CONTROL);
39976  },
39977  GetValue: function() {
39978   return this.GetValueKey();
39979  },
39980  GetValueKey: function() {
39981   var dataKeyElem = this.GetValueHiddenField();
39982   if(ASPx.IsExistsElement(dataKeyElem))
39983    return dataKeyElem.value;
39984   return "";
39985  },
39986  GetText: function() {
39987   return this.GetValue();
39988  },
39989  GetImageUrl: function() { return ASPx.ImageUtils.GetImageSrc(this.GetImageElement()); },
39990  SetProgressPanelVisibility: function(show) {
39991   var progressPanel = this.GetProgressPanel();
39992   var progressBar = this.GetProgressBar();
39993   if(progressPanel){
39994    ASPx.SetElementDisplay(progressPanel, show);
39995   }
39996   if(progressBar && show){
39997    progressBar.AdjustControlCore();
39998   }
39999  },
40000  SetDataKeyValue: function(value, forceValueChanged) {   
40001   if(!ASPx.IsExists(value))
40002    value = "";
40003   var dataKeyElem = this.GetValueHiddenField();
40004   dataKeyElem.value = value;
40005   if(forceValueChanged)
40006    this.OnValueChanged();
40007  },
40008  SetProgressBarPosition: function(pos) {
40009   var progressBar = this.GetProgressBar();
40010   if(progressBar)
40011    progressBar.SetPosition(pos);
40012  },
40013  SetValue: function(value) {
40014   this.SetValueKey(value);
40015  },
40016  SetValueKey: function(key) {
40017   if(this.enableEditing)
40018      this.UpdateImageByKey(key);
40019  },
40020  UpdateImageByInfo: function(info) {
40021   if(ASPx.IsExists(info))
40022    this.UpdateImageCore(info.Key, info.ImageUrl, info.FileName);
40023  },
40024  UpdateImageByKey: function(key) {
40025   if(this.NeedServerUpdate())
40026    this.UpdateImageFromServer(key);
40027   else
40028    this.UpdateImageCore(key, this.GetImageUrlByKey(key));
40029  },
40030  NeedServerUpdate: function() { return !this.imageUrlTemplate ;},
40031  GetImageUrlByKey: function(key) {
40032   if(!key || !this.imageUrlTemplate)
40033    return ASPx.EmptyImageUrl;
40034   return this.imageUrlTemplate.replace(this.KeyPlaceHolder, key);
40035  },
40036  UpdateImageCore: function(key, imageUrl, uploadedFileName) {
40037   this.SetUploadedFileName(uploadedFileName);
40038   this.SetDataKeyValue(key, true);
40039   var image = this.GetImageElement();
40040   image.onload = image.onerror = image.onabort = function() {
40041    this.UpdateElementsVisibility();
40042    this.ShowValueDisplayElement();
40043   }.aspxBind(this);
40044   ASPx.ImageUtils.SetImageSrc(image, imageUrl || ASPx.EmptyImageUrl);
40045  },
40046  UpdateImageFromServer: function(key) {
40047   this.SetDataKeyValue(key);
40048   this.PerformCallbackInternal();
40049  },
40050  UpdateElementsVisibility: function(startUpload){
40051   ASPx.SetElementDisplay(this.GetButtonPanel(), !startUpload);
40052   this.UpdateDeleteButtonDisplay();
40053   this.SetProgressPanelVisibility(startUpload);
40054   ASPx.SetElementDisplay(this.GetEmptyValuePlaceholder(), !startUpload && !this.GetValue());
40055  },
40056  UpdateDeleteButtonDisplay: function() {
40057   ASPx.SetElementDisplay(this.GetDeleteButton(), !!this.GetValue());
40058  },
40059  Clear: function() {
40060   this.UpdateImageCore();
40061  },
40062  GetUploadedFileName: function() {    
40063   return this.stateObject && this.stateObject.uploadedFileName ? this.stateObject.uploadedFileName : "";
40064  },
40065  SetUploadedFileName: function(fileName) {
40066   if(!ASPx.IsExists(fileName))
40067    fileName = "";
40068   this.UpdateStateObjectWithObject({ uploadedFileName: fileName });
40069  },
40070  PerformCallback: function(parameter, onSuccess) {
40071   if (!ASPx.IsExists(parameter)) parameter = "";
40072   parameter = formatCallbackArg(CONST.CALLBACK_PREFIX.CUSTOM_CALLBACK, parameter);
40073   this.PerformCallbackInternal(parameter, onSuccess);
40074  },
40075  PerformCallbackInternal: function(parameter, handler) {
40076   this.CreateCallback(parameter, null, handler);
40077  },
40078  OnCallback: function(result) {
40079   if(this.enableEditing)
40080    this.UpdateImageByInfo(result);
40081  },
40082  OnStartUpload: function() {
40083   this.SetProgressBarPosition(0);
40084   this.UpdateElementsVisibility(true);
40085  },
40086  OnEndUpload: function(args) {
40087   if(args.errorText){
40088    ASPx.ShowErrorAlert(args.errorText);
40089    this.UpdateElementsVisibility();
40090    return;
40091   }
40092   if(this.showLoadingImage) {
40093    this.RecreateImageElement();
40094   }
40095   var obj = eval(args.callbackData);
40096   this.UpdateImageByInfo(obj.info);
40097  },
40098  RecreateImageElement: function () {
40099   this.RemoveImageElement();
40100   this.CreateImageElement();
40101  },
40102  RemoveImageElement: function() {
40103   if(this.enableEditing) {
40104    ASPx.RemoveElement(this.GetImageElement());
40105   }
40106  },
40107  CreateImageElement: function() {
40108   if(!this.enableEditing)
40109    return;
40110   var container = this.GetImageContainer();
40111   var img = document.createElement('IMG');
40112   img.id = this.name + '_' + CONST.POSTFIX.PREVIEW_CONTROL;
40113   img.style.height = 'auto';
40114   img.style.width = 'auto';
40115   if(this.showLoadingImage) {
40116    for(var i = 0;
40116 i < this.loadingImageData.cssClasses.length; i++) {
40117     var cssClass = this.loadingImageData.cssClasses[i];
40118     img.className += ' ' + cssClass;
40119    }
40120    if(this.loadingImageData.loadingImage) {
40121     img.style.backgroundImage =  this.loadingImageData.loadingImage.replace(/"/g, "'");
40122    }
40123    var loadingImage = this.loadingImageData.loadingImage;
40124    var backgroundImageUrl = this.loadingImageData.backgroundImageUrl;
40125    var onLoad = function() {
40126     this.OnImageLoad(img, loadingImage, false, backgroundImageUrl);
40127    }.aspxBind(this);
40128    ASPx.Evt.AttachEventToElement(img, "load", onLoad);
40129    ASPx.Evt.AttachEventToElement(img, "onabort", onLoad);
40130    ASPx.Evt.AttachEventToElement(img, "onerror", onLoad);
40131   }
40132   container.appendChild(img);
40133   this.CalculateImageElementSizes();
40134  },
40135  OnImageLoad: function (img, loadingImage, isOldBrowser, backgroundImageUrl) {
40136   ASPx.ASPxImageLoad.OnLoad(img, loadingImage, isOldBrowser, backgroundImageUrl);
40137  },
40138  OnUploadProgressChanged: function(args) {
40139   this.SetProgressBarPosition(args.progress);
40140  },
40141  ShowValueDisplayElement: function() {
40142   if(!ASPx.IsElementVisible(this.GetMainElement()))
40143    return;
40144   if(this.GetValue()) {
40145    this.ShowPreview();
40146   } else {
40147    this.ShowPlaceholder();
40148   }
40149  },
40150  ShowPreview: function() {
40151   ASPx.SetElementDisplay(this.GetEmptyValuePlaceholder(), false);
40152   var imageContainer = this.GetImageContainer();
40153   if(!this.imageContainerSizeIsValid) 
40154    this.CalculateImageElementSizes();
40155   ASPx.SetElementDisplay(imageContainer, true);
40156  },
40157  CalculateImageElementSizes: function() {
40158   var imageContainer = this.GetImageContainer();
40159   var imageElement = this.GetImageElement();
40160   ASPx.SetElementDisplay(imageElement, false);
40161   ASPx.SetElementDisplay(imageContainer, false);
40162   imageContainer.style.height = this.GetMainElementHeightForInnerContainer();
40163   imageContainer.style.width = this.GetMainElementWidthForInnerContainer();
40164   ASPx.SetElementDisplay(imageContainer, true);
40165   imageContainer.style['line-height'] = this.GetMainElementHeightForInnerContainer();
40166   ASPx.SetElementDisplay(imageElement, true);
40167   this.imageContainerSizeIsValid = true;
40168  },
40169  ShowPlaceholder: function() {
40170   var emptyImage = this.GetEmptyValueImage();
40171   if(emptyImage && ASPx.GetElementDisplay(emptyImage) && !this.emptyImageContainerSizeIsValid){
40172    var emptyImageContainer = emptyImage.parentElement;
40173    emptyImageContainer.style.height = this.GetMainElementHeightForInnerContainer();
40174    emptyImageContainer.style.width = this.GetMainElementWidthForInnerContainer();   
40175    this.emptyImageContainerSizeIsValid = true;
40176   }
40177   ASPx.SetElementDisplay(this.GetImageContainer(), false);
40178   ASPx.SetElementDisplay(this.GetEmptyValuePlaceholder(), true);
40179  },
40180  GetMainElementHeightForInnerContainer: function() {
40181   var mainElement = this.GetMainElement();
40182   if(ASPx.IsPercentageSize(mainElement.style.height))
40183    return "100%";
40184   if(window.getComputedStyle)
40185    return window.getComputedStyle(mainElement).height;
40186   return mainElement.clientHeight + "px";
40187  },
40188  GetMainElementWidthForInnerContainer: function() {
40189   var mainElement = this.GetMainElement();
40190   if(ASPx.IsPercentageSize(mainElement.style.width))
40191    return "100%";
40192   if(window.getComputedStyle)
40193    return window.getComputedStyle(mainElement).width;
40194   return mainElement.clientWidth + "px";
40195  },
40196  RequireInputElementToValidate: function() {
40197   return false;
40198  }
40199 });
40200 window.ASPxClientBinaryImage = ASPxClientBinaryImage;
40201 ASPxClientBinaryImage.Cast = ASPxClientControl.Cast;
40202 ASPx.Ident.IsStaticASPxClientBinaryImage = function(obj) {
40203  return !!obj.isASPxClientBinaryImage && !obj.enableEditing;
40204 };
40205})();
40206
40207},1);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.