📄 listsearchbehavior.js
字号:
// (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.
/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="MicrosoftAjaxTimer.debug.js" />
/// <reference name="MicrosoftAjaxWebForms.debug.js" />
/// <reference path="../ExtenderBase/BaseScripts.js" />
/// <reference path="../Common/Common.js" />
/// <reference path="../DynamicPopulate/DynamicPopulateBehavior.js" />
/// <reference path="../Compat/Timer/Timer.js" />
/// <reference path="../Animation/Animations.js" />
/// <reference path="../Animation/AnimationBehavior.js" />
/// <reference path="../PopupExtender/PopupBehavior.js" />
/// <reference path="../PopupControl/PopupControlBehavior.js" />
// ListSearchExtender originally created by Damian Mehers http://damianblog.com
Type.registerNamespace('AjaxControlToolkit');
AjaxControlToolkit.ListSearchBehavior = function(element) {
/// <summary>
/// The ListSearchBehavior allows users to search incrementally within a Select
/// </summary>
/// <param name="element" type="Sys.UI.DomElement" domElement="true">
/// Select associated with the behavior
/// </param>
AjaxControlToolkit.ListSearchBehavior.initializeBase(this, [element]);
// Properties
this._promptCssClass = null;
this._promptText = AjaxControlToolkit.Resources.ListSearch_DefaultPrompt;
this._offsetX = 0;
this._offsetY = 0;
this._promptPosition = AjaxControlToolkit.ListSearchPromptPosition.Top;
this._raiseImmediateOnChange = false;
this._queryPattern = AjaxControlToolkit.ListSearchQueryPattern.StartsWith;
this._isSorted = false;
// Variables
this._popupBehavior = null;
this._onShowJson = null;
this._onHideJson = null;
this._originalIndex = 0; // Index of the selected option when a key is first hit (before it is changed by the browser)
this._newIndex = -1; // New index to which we want to move. We need this because Firefox shifts the selected option even though we preventDefault and preventPropagation in _onKeyPress.
this._showingPromptText = false;
this._searchText = ''; // Actual search text (text displayed in the PromptDiv may be clipped)
this._ellipsis = String.fromCharCode(0x2026);
this._binarySearch = false;
this._applicationLoadDelegate = null;
this._focusIndex = 0; // Selected Index when the list is initially given focus
this._queryTimeout = 0; // Timeout in milliseconds after which search text will be cleared
this._timer = null; // Holds the opaque ID returned by setTimeout function. Needed to correctly clear the timeout reference.
this._matchFound = false; // Set to true means an item was selected after searching. False means no item match search criteria
this._focusHandler = null;
this._blurHandler = null;
this._keyDownHandler = null;
this._keyUpHandler = null;
this._keyPressHandler = null;
}
AjaxControlToolkit.ListSearchBehavior.prototype = {
initialize : function() {
/// <summary>
/// Initialize the behavior
/// </summary>
AjaxControlToolkit.ListSearchBehavior.callBaseMethod(this, 'initialize');
var element = this.get_element();
// Check for a SELECT since a ControlAdapter could have rendered the ListBox or DropDown as something else
if(element && element.tagName === 'SELECT') {
this._focusHandler = Function.createDelegate(this, this._onFocus);
this._blurHandler = Function.createDelegate(this, this._onBlur);
this._keyDownHandler = Function.createDelegate(this, this._onKeyDown);
this._keyUpHandler = Function.createDelegate(this, this._onKeyUp);
this._keyPressHandler = Function.createDelegate(this, this._onKeyPress);
$addHandler(element, "focus", this._focusHandler);
$addHandler(element, "blur", this._blurHandler);
$addHandler(element, "keydown", this._keyDownHandler);
$addHandler(element, "keyup", this._keyUpHandler);
$addHandler(element, "keypress", this._keyPressHandler);
// We use the load event to determine whether the control has focus and display prompt text. We can't do it here.
this._applicationLoadDelegate = Function.createDelegate(this, this._onApplicationLoad);
Sys.Application.add_load(this._applicationLoadDelegate);
}
},
dispose : function() {
/// <summary>
/// Dispose the behavior
/// </summary>
var element = this.get_element();
$removeHandler(element, "keypress", this._keyPressHandler);
$removeHandler(element, "keyup", this._keyUpHandler);
$removeHandler(element, "keydown", this._keyDownHandler);
$removeHandler(element, "blur", this._blurHandler);
$removeHandler(element, "focus", this._focusHandler);
this._onShowJson = null;
this._onHideJson = null;
this._disposePopupBehavior();
if(this._applicationLoadDelegate) {
Sys.Application.remove_load(this._applicationLoadDelegate);
this._applicationLoadDelegate = null;
}
if(this._timer) {
this._stopTimer();
}
AjaxControlToolkit.ListSearchBehavior.callBaseMethod(this, 'dispose');
},
_onApplicationLoad : function(sender, applicationLoadEventArgs) {
/// <summary>
/// Handler called automatically when a all scripts are loaded and controls are initialized
/// Called after all scripts have been loaded and controls initialized. If the current Select is the one that has
/// focus then it shows the prompt text. We cannot do this in the initialize method because the second pass initialization
/// of the popup behavior hides it.
/// </summary>
/// <param name="sender" type="Object">
/// Sender
/// </param>
/// <param name="applicationLoadEventArgs" type="Sys.ApplicationLoadEventArgs">
/// Event arguments
/// </param>
// Determine if this SELECT is focused initially
var hasInitialFocus = false;
var clientState = AjaxControlToolkit.ListSearchBehavior.callBaseMethod(this, 'get_ClientState');
if (clientState != null && clientState != "") {
hasInitialFocus = (clientState === "Focused");
AjaxControlToolkit.ListSearchBehavior.callBaseMethod(this, 'set_ClientState', null);
}
if(hasInitialFocus) {
this._handleFocus();
}
},
_checkIfSorted : function(options) {
/// <summary>
/// Checks to see if the list is sorted to see if we can do the fast binary search or the slower linear search
/// </summary>
/// <param name="options" type="Object">
/// Collections of options in a SELECT
/// </param>
if (this._isSorted) {
// we assume this is sorted
return true;
} else {
// it is not known if elements list is sorted, so check it by itself
var previousOptionValue = null;
var optionsLength = options.length;
for(var index = 0; index < optionsLength; index++) {
var optionValue = options[index].text.toLowerCase();
if(previousOptionValue && this._compareStrings(optionValue, previousOptionValue) < 0) {
return false;
}
previousOptionValue = optionValue;
}
return true;
}
},
_onFocus : function(e) {
/// <summary>
/// Handler for the Select's focus event
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">
/// Event info
/// </param>
this._handleFocus();
},
_handleFocus : function() {
/// <summary>
/// Utility method called when the form is loaded if the Select has the default focus, or when it is explicitly focused
/// </summary>
var element = this.get_element();
this._focusIndex = element.selectedIndex;
if(!this._promptDiv) {
this._promptDiv = document.createElement('div');
this._promptDiv.id = element.id + '_promptDiv';
// Need to initialize _promptDiv here even though it is set below by _updatePromptDiv because otherwise both
// FireFox and IE bomb -- I guess there needs to be some content in the Div. We need a value, which will be overwritten
// below anyway.
this._promptDiv.innerHTML = this._promptText && this._promptText.length > 0 ? this._promptText : AjaxControlToolkit.Resources.ListSearch_DefaultPrompt;
this._showingPromptText = true;
if(this._promptCssClass) {
this._promptDiv.className = this._promptCssClass;
}
element.parentNode.insertBefore(this._promptDiv, element.nextSibling);
this._promptDiv.style.overflow = 'hidden';
this._promptDiv.style.height = this._promptDiv.offsetHeight + 'px';
this._promptDiv.style.width = element.offsetWidth + 'px';
}
// Hook up a PopupBehavior to the promptDiv
if(!this._popupBehavior) {
this._popupBehavior = $create(AjaxControlToolkit.PopupBehavior, { parentElement : element }, {}, {}, this._promptDiv);
}
if (this._promptPosition && this._promptPosition == AjaxControlToolkit.ListSearchPromptPosition.Bottom) {
this._popupBehavior.set_positioningMode(AjaxControlToolkit.PositioningMode.BottomLeft);
} else {
this._popupBehavior.set_positioningMode(AjaxControlToolkit.PositioningMode.TopLeft);
}
// Create the animations (if they were set before the behavior was created)
if (this._onShowJson) {
this._popupBehavior.set_onShow(this._onShowJson);
}
if (this._onHideJson) {
this._popupBehavior.set_onHide(this._onHideJson);
}
this._popupBehavior.show();
this._updatePromptDiv(this._promptText);
},
_onBlur : function() {
/// <summary>
/// Handle the Select's blur event
/// </summary>
this._disposePopupBehavior();
// Remove the DIV showing the text typed so far
var promptDiv = this._promptDiv;
var element = this.get_element();
if(promptDiv) {
this._promptDiv = null;
element.parentNode.removeChild(promptDiv);
}
if(!this._raiseImmediateOnChange && this._focusIndex != element.selectedIndex) {
this._raiseOnChange(element);
}
},
_disposePopupBehavior : function() {
/// <summary>
/// Utilty function to dispose of the popup behavior, called when the Select loses focus or when the extender is being disposed
/// </summary>
if (this._popupBehavior) {
this._popupBehavior.dispose();
this._popupBehavior = null;
}
},
_onKeyDown : function(e) {
/// <summary>
/// Handler for the Select's KeyDown event
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">
/// Event info
/// </param>
var element = this.get_element();
var promptDiv = this._promptDiv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -