📄 listsearchbehavior.js
字号:
if(!element || !promptDiv) {
return;
}
this._originalIndex = element.selectedIndex;
if(this._showingPromptText) {
promptDiv.innerHTML = '';
this._searchText = '';
this._showingPromptText = false;
this._binarySearch = this._checkIfSorted(element.options); // Delayed until required
}
// Backspace not passed to keyPressed event in IE, so handle it here
if(e.keyCode == Sys.UI.Key.backspace) {
e.preventDefault();
e.stopPropagation();
this._removeCharacterFromPromptDiv();
this._searchForTypedText(element);
if(!this._searchText || this._searchText.length == 0) {
this._stopTimer();
}
} else if(e.keyCode == Sys.UI.Key.esc) {
e.preventDefault();
e.stopPropagation();
promptDiv.innerHTML = '';
this._searchText = '';
this._searchForTypedText(element);
this._stopTimer();
} else if(e.keyCode == Sys.UI.Key.enter && !this._raiseImmediateOnChange && this._focusIndex != element.selectedIndex) {
this._focusIndex = element.selectedIndex; // So that OnChange is not fired again when the list loses focus
this._raiseOnChange(element);
}
},
_onKeyUp : function(e) {
/// <summary>
/// Handler for the Select's KeyUp event. We need this because Firefox shifts the selected option even though
/// we preventDefault and preventPropagation in _onKeyPress
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">
/// Event info
/// </param>
var element = this.get_element();
var promptDiv = this._promptDiv;
if(!element || !promptDiv) {
return;
}
if(this._newIndex == -1 || !element || !promptDiv || promptDiv.innerHTML == '') {
this._newIndex = -1;
return;
}
element.selectedIndex = this._newIndex;
this._newIndex = -1;
},
_onKeyPress : function(e) {
/// <summary>
/// Handler for the Select's KeyPress event.
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">
/// Event info
/// </param>
var element = this.get_element();
var promptDiv = this._promptDiv;
if(!element || !promptDiv) {
return;
}
if(!this._isNormalChar(e)) {
if(e.charCode == Sys.UI.Key.backspace) {
e.preventDefault();
e.stopPropagation();
if(this._searchText && this._searchText.length == 0) {
this._stopTimer();
}
}
return;
}
e.preventDefault();
e.stopPropagation();
// Add key pressed to the displayed DIV and search for it
this._addCharacterToPromptDiv(e.charCode);
this._searchForTypedText(element);
this._stopTimer();
// start auto reset timer only if search text is not empty
if(this._searchText && this._searchText.length != 0) {
this._startTimer();
}
},
_isNormalChar : function(e) {
/// <summary>
/// Returns true if the specified charCode is a key rather than a normal (displayable) character
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">
/// Event info
/// </param>
/// <returns type="Boolean" />
// Walking through Sys.UI.Keys won't work -- Ampersand is code 38 which matches
if (Sys.Browser.agent == Sys.Browser.Firefox && e.rawEvent.keyCode) {
return false;
}
if (Sys.Browser.agent == Sys.Browser.Opera && e.rawEvent.which == 0) {
return false;
}
if (e.charCode && (e.charCode < Sys.UI.Key.space || e.charCode > 6000)) {
return false;
}
return true;
},
_updatePromptDiv : function(newText) {
/// <summary>
/// Updates the text in the promptDiv.
/// </summary>
/// <param name="newText" type="String">
/// The new text to be displayed in the promptDiv. Optional. If not specified then uses the _searchText member.
/// </param>
///
var promptDiv = this._promptDiv;
if(!promptDiv || !this.get_element()) {
return;
}
var text = typeof(newText) === 'undefined' ? this._searchText : newText;
var textNode = promptDiv.firstChild;
if(!textNode) {
textNode = document.createTextNode(text);
promptDiv.appendChild(textNode);
} else {
textNode.nodeValue = text;
}
if(promptDiv.scrollWidth <= promptDiv.offsetWidth && promptDiv.scrollHeight <= promptDiv.offsetHeight) {
return; // Already fit
}
// Remove characters until they fit
for(var maxFit = text.length - 1; maxFit > 0 && (promptDiv.scrollWidth > promptDiv.offsetWidth || promptDiv.scrollHeight > promptDiv.offsetHeight); maxFit--) {
textNode.nodeValue = this._ellipsis + text.substring(text.length - maxFit, text.length);
}
},
_addCharacterToPromptDiv : function (charCode) {
/// <summary>
/// Adds the specified character to the promptDiv.
/// </summary>
/// <param name="charCode" type="Int">
/// The charCode of the character to be added
/// </param>
this._searchText += String.fromCharCode(charCode);
this._updatePromptDiv();
},
_removeCharacterFromPromptDiv : function () {
/// <summary>
/// Removes a character from the end of the promptDiv.
/// </summary>
if(this._searchText && this._searchText != '') {
this._searchText = this._searchText.substring(0, this._searchText.length - 1);
this._updatePromptDiv();
}
},
_searchForTypedText : function(element) {
/// <summary>
/// Searches for the text typed so far in the Select
/// </summary>
/// <param name="element" type="Sys.UI.DomElement" domElement="true">
/// Select associated with the behavior
/// </param>
var searchText = this._searchText;
var options = element.options;
var text = searchText ? searchText.toLowerCase() : "";
this._matchFound = false;
if(text.length == 0) { // Probably hit delete -- select the first option
if(options.length > 0) {
element.selectedIndex = 0;
this._newIndex = 0;
}
} else {
var selectedIndex = -1;
if(this._binarySearch && (this._queryPattern == AjaxControlToolkit.ListSearchQueryPattern.StartsWith)) {
selectedIndex = this._doBinarySearch(options, text, 0, options.length - 1);
} else {
selectedIndex = this._doLinearSearch(options, text, 0, options.length - 1);
}
// If nothing is found then stick with the current option
if(selectedIndex == -1) {
// Need this because firefox has aleady changed the current option based on the character typed
this._newIndex = this._originalIndex;
} else { // Otherwise move to the new option
element.selectedIndex = selectedIndex;
this._newIndex = selectedIndex;
this._matchFound = true;
}
}
if(this._raiseImmediateOnChange && this._originalIndex != element.selectedIndex) {
// Fire an OnChange
this._raiseOnChange(element);
}
},
_raiseOnChange : function(element) {
/// <summary>
/// Fires a OnChange event
/// </summary>
/// <param name="element" type="Sys.UI.DomElement" domElement="true">
/// Select associated with the behavior
/// </param>
if (document.createEvent) {
var onchangeEvent = document.createEvent('HTMLEvents');
onchangeEvent.initEvent('change', true, false);
element.dispatchEvent(onchangeEvent);
} else if( document.createEventObject ) {
element.fireEvent('onchange');
}
},
_compareStrings : function(strA, strB) {
/// <summary>
/// Compare two strings
/// </summary>
/// <param name="strA" type="String">
/// The first string
/// </param>
/// <param name="strB" type="String">
/// The second string
/// </param>
/// <returns type="Number" Integer="true">
/// 0 if equal, -1 if strA < strB, 1 otherwise
/// </returns>
return ((strA == strB) ? 0 : ((strA < strB) ? -1 : 1))
},
_doBinarySearch : function(options, value, left, right) {
/// <summary>
/// Does a binary search for a value in the Select's options
/// </summary>
/// <param name="options" type="Object">
/// The collection of options in the Select
/// </param>
/// <param name="value" type="String">
/// The value being searched for
/// </param>
/// <param name="left" type="Int">
/// The left bounds of the search
/// </param>
/// <param name="right" type="Right">
/// The right bounds of the search
/// </param>
while (left <= right) {
var mid = Math.floor((left+right)/2);
var option = options[mid].text.toLowerCase().substring(0, value.length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -