// (c) Copyright Microsoft Corporation. // This source is subject to the Microsoft Permissive License. // See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. // All other rights reserved. Type.registerNamespace('AjaxControlToolkit'); AjaxControlToolkit.PopupControlBehavior = function(element) { /// /// The PopupControlBehavior opens a popup window next to the target element /// /// /// DOM element associated with the behavior /// AjaxControlToolkit.PopupControlBehavior.initializeBase(this, [element]); // Properties this._popupControlID = null; this._commitProperty = null; this._commitScript = null; this._position = null; this._offsetX = 0; this._offsetY = 0; this._extenderControlID = null; // Variables this._popupElement = null; this._popupBehavior = null; this._popupVisible = false; this._focusHandler = null; this._popupKeyDownHandler = null; this._popupClickHandler = null; this._bodyClickHandler = null; } AjaxControlToolkit.PopupControlBehavior.prototype = { initialize : function() { /// /// Initialize the behavior /// AjaxControlToolkit.PopupControlBehavior.callBaseMethod(this, 'initialize'); // Identify popup element from control id var e = this.get_element(); this._popupElement = $get(this._popupControlID); // Hook up a PopupBehavior this._popupBehavior = $create(AjaxControlToolkit.PopupBehavior, { 'id':this.get_id()+'PopupBehavior', 'parentElement':e }, null, null, this._popupElement); // Create delegates this._focusHandler = Function.createDelegate(this, this._onFocus); this._popupClickHandler = Function.createDelegate(this, this._onPopupClick); this._bodyClickHandler = Function.createDelegate(this, this._onBodyClick); this._popupKeyDownHandler = Function.createDelegate(this, this._onPopupKeyDown); // Attach events $addHandler(e, 'focus', this._focusHandler); $addHandler(e, 'click', this._focusHandler); // So that a dismissed popup can be more easily re-popped $addHandler(document.body, 'click', this._bodyClickHandler); $addHandler(this._popupElement, 'click', this._popupClickHandler); $addHandler(this._popupElement, 'keydown', this._popupKeyDownHandler); // Need to know when partial updates complete this.registerPartialUpdateEvents(); // If this popup was visible before what seems to have been a partial update, // make it visible again now if(AjaxControlToolkit.PopupControlBehavior.__VisiblePopup && (this.get_id() == AjaxControlToolkit.PopupControlBehavior.__VisiblePopup.get_id())) { this._onFocus(null); } }, dispose : function() { /// /// Dispose the behavior /// var e = this.get_element(); if (this._popupBehavior) { this._popupBehavior.dispose(); this._popupBehavior = null; } if (this._focusHandler) { $removeHandler(e, 'focus', this._focusHandler); $removeHandler(e, 'click', this._focusHandler); this._focusHandler = null; } if (this._bodyClickHandler) { $removeHandler(document.body, 'click', this._bodyClickHandler); this._bodyClickHandler = null; } if (this._popupClickHandler) { $removeHandler(this._popupElement, 'click', this._popupClickHandler); this._popupClickHandler = null; } if (this._popupKeyDownHandler) { $removeHandler(this._popupElement, 'keydown', this._popupKeyDownHandler); this._popupKeyDownHandler = null; } AjaxControlToolkit.PopupControlBehavior.callBaseMethod(this, 'dispose'); }, showPopup : function() { /// /// Display the popup /// var old = AjaxControlToolkit.PopupControlBehavior.__VisiblePopup; if (old && old._popupBehavior) { old.hidePopup(); } AjaxControlToolkit.PopupControlBehavior.callBaseMethod(this, 'populate'); this._popupBehavior.set_x(this._getLeftOffset()); this._popupBehavior.set_y(this._getTopOffset()); this._popupBehavior.show(); this._popupVisible = true; AjaxControlToolkit.PopupControlBehavior.__VisiblePopup = this; }, hidePopup : function() { /// /// Hide the popup /// this._popupBehavior.hide(); this._popupVisible = false; AjaxControlToolkit.PopupControlBehavior.__VisiblePopup = null; }, _onFocus : function(e) { /// /// Show the popup when its control is focused /// /// /// Event info /// // Set the popup position and display it if (!this._popupVisible) { this.showPopup(); } if (e) { e.stopPropagation(); } }, _onPopupKeyDown : function(e) { /// /// Handle key presses in the popup element /// /// /// Event info /// // Handle key presses in the popup element if (this._popupVisible && e.keyCode == 27 /* Escape */) { // Return focus to the control this.get_element().focus(); } }, _onPopupClick : function(e) { /// /// Click handler for the popup /// /// /// Event info /// e.stopPropagation(); }, _onBodyClick : function() { /// /// Handler for the HTML body tag's click event /// // Hide the popup if something other than our target or popup // was clicked (since each of these stop the event from bubbling // up to the body) if (this._popupVisible) { this.hidePopup(); } }, // Called automatically when a page load/postback happens _close : function(result) { /// /// Close the popup /// /// /// Result obtained from committing the popup /// // Look at result of popup var e = this.get_element(); if (null != result) { if ('$$CANCEL$$' != result) { // Result is to be committed if (this._commitProperty) { // Use the specified property e[this._commitProperty] = result; } else if ('text' == e.type) { // Use the default property e.value = result; } else { Sys.Debug.assert(false, 'No default property supported for control ' + e.id + ' of type ' + e.type + '.'); } // Additionally run commit script if present if (this._commitScript) { eval(this._commitScript); } } // Hide the popup this.hidePopup(); } }, _partialUpdateEndRequest : function(sender, endRequestEventArgs) { /// /// Handler for UpdatePanel partial postback notifications /// /// /// Sender /// /// /// Event arguments /// AjaxControlToolkit.PopupControlBehavior.callBaseMethod(this, '_partialUpdateEndRequest', [sender, endRequestEventArgs]); if (this.get_element()) { // Look up result by element's ID var result = endRequestEventArgs.get_dataItems()[this.get_element().id]; // If unsuccessful, look up result by proxy ID if ((undefined === result) && AjaxControlToolkit.PopupControlBehavior.__VisiblePopup && (this.get_id() == AjaxControlToolkit.PopupControlBehavior.__VisiblePopup.get_id())) { result = endRequestEventArgs.get_dataItems()["_PopupControl_Proxy_ID_"]; } // If result available, apply it if (undefined !== result) { this._close(result); } } }, _getLeftOffset : function() { /// /// Get the left offset for the popup /// /// /// Left offset for the popup /// // Get the left offset for the popup if (AjaxControlToolkit.PopupControlPopupPosition.Left == this._position) { return (-1 * this.get_element().offsetWidth) + this._offsetX; } else if (AjaxControlToolkit.PopupControlPopupPosition.Right == this._position) { return this.get_element().offsetWidth + this._offsetX; } else { return this._offsetX; } }, _getTopOffset : function() { /// /// Get the top offset for the popup /// /// /// Top offset for the popup /// // Get the top offset for the popup var yoffSet; if(AjaxControlToolkit.PopupControlPopupPosition.Top == this._position) { yoffSet = (-1 * this.get_element().offsetHeight) + this._offsetY; } else if (AjaxControlToolkit.PopupControlPopupPosition.Bottom == this._position) { yoffSet = this.get_element().offsetHeight + this._offsetY; } else { yoffSet = this._offsetY; } return yoffSet; }, get_PopupControlID : function() { /// /// The ID of the control to display /// return this._popupControlID; }, set_PopupControlID : function(value) { if (this._popupControlID != value) { this._popupControlID = value; this.raisePropertyChanged('PopupControlID'); } }, get_CommitProperty : function() { /// /// The property on the control being extended that should be set with the result of the popup /// return this._commitProperty; }, set_CommitProperty : function(value) { if (this._commitProperty != value) { this._commitProperty = value; this.raisePropertyChanged('CommitProperty'); } }, get_CommitScript : function() { /// /// Additional script to run after setting the result of the popup /// return this._commitScript; }, set_CommitScript : function(value) { if (this._commitScript != value) { this._commitScript = value; this.raisePropertyChanged('CommitScript'); } }, get_Position : function() { /// /// Where the popup should be positioned relative to the target control. (Left, Right, Top, Bottom, Center) /// return this._position; }, set_Position : function(value) { if (this._position != value) { this._position = value; this.raisePropertyChanged('Position'); } }, // TODO: Is this used anywhere? get_ExtenderControlID : function() { /// /// ID of the extender control /// return this._extenderControlID; }, set_ExtenderControlID : function(value) { if (this._extenderControlID != value) { this._extenderControlID = value; this.raisePropertyChanged('ExtenderControlID'); } }, get_OffsetX : function() { /// /// The number of pixels to horizontally offset the Popup from its default position /// return this._offsetX; }, set_OffsetX : function(value) { if (this._offsetX != value) { this._offsetX = value; this.raisePropertyChanged('OffsetX'); } }, get_OffsetY : function() { /// /// The number of pixels to vertically offset the Popup from its default position /// return this._offsetY; }, set_OffsetY : function(value) { if (this._offsetY != value) { this._offsetY = value; this.raisePropertyChanged('OffsetY'); } }, get_PopupVisible : function() { /// /// Whether the popup control is currently visible /// return this._popupVisible; } } // This global variable tracks the currently visible popup. Automatically // hiding the popup when focus is lost does not work with our mechanism to // hide the popup when something else is clicked... So we will instead go for // the weaker strategy of letting at most one popup be visible at a time. AjaxControlToolkit.PopupControlBehavior.__VisiblePopup = null; AjaxControlToolkit.PopupControlBehavior.registerClass('AjaxControlToolkit.PopupControlBehavior', AjaxControlToolkit.DynamicPopulateBehaviorBase); // getDescriptor : function() { // var td = AjaxControlToolkit.PopupControlBehavior.callBaseMethod(this, 'getDescriptor'); // // Add custom properties // td.addProperty('PopupControlID', String); // td.addProperty('CommitProperty', String); // td.addProperty('CommitScript', String); // td.addProperty('Position', String); // td.addProperty('OffsetX', Number); // td.addProperty('OffsetY', Number); // td.addProperty('ExtenderControlID', String); // return td; // }, AjaxControlToolkit.PopupControlPopupPosition = function() { /// /// Position of the popup relative to the target control /// /// /// /// /// /// throw Error.invalidOperation(); } AjaxControlToolkit.PopupControlPopupPosition.prototype = { Center : 0, Top : 1, Left : 2, Bottom : 3, Right : 4 } AjaxControlToolkit.PopupControlPopupPosition.registerEnum("AjaxControlToolkit.PopupControlPopupPosition", false); if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();