📄 autocompletebehavior.js
字号:
},
_popupHidden : function() {
/// <summary>
/// Clean up the completion list popup after it has been hidden
/// </summary>
this._completionListElement.innerHTML = '';
this._selectIndex = -1;
this._flyoutHasFocus = false;
this.raiseHidden(Sys.EventArgs.Empty);
},
_highlightItem: function(item) {
/// <summary>
/// Highlights the specified item
/// </summary>
/// <param name="item" type="Sys.UI.DomElement" DomElement="true" mayBeNull="false" />
/// <returns />
var children = this._completionListElement.childNodes;
// Unselect any previously highlighted item
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child._highlighted) {
if (this._completionListItemCssClass) {
Sys.UI.DomElement.removeCssClass(child, this._highlightedItemCssClass);
Sys.UI.DomElement.addCssClass(child, this._completionListItemCssClass);
} else {
if (Sys.Browser.agent === Sys.Browser.Safari) {
child.style.backgroundColor = 'white';
child.style.color = 'black';
} else {
child.style.backgroundColor = this._textBackground;
child.style.color = this._textColor;
}
}
this.raiseItemOut(new AjaxControlToolkit.AutoCompleteItemEventArgs(child, child.firstChild.nodeValue, child._value));
}
}
// Highlight the new item
if(this._highlightedItemCssClass) {
Sys.UI.DomElement.removeCssClass(item, this._completionListItemCssClass);
Sys.UI.DomElement.addCssClass(item, this._highlightedItemCssClass);
} else {
if (Sys.Browser.agent === Sys.Browser.Safari) {
item.style.backgroundColor = 'lemonchiffon';
} else {
item.style.backgroundColor = 'highlight';
item.style.color = 'highlighttext';
}
}
item._highlighted = true;
this.raiseItemOver(new AjaxControlToolkit.AutoCompleteItemEventArgs(item, item.firstChild.nodeValue, item._value));
},
/// <summary>
/// Handler for the blur event on the autocomplete flyout.
/// </summary>
/// <param name="ev" type="Sys.UI.DomEvent" DomElement="false" mayBeNull="false" />
/// <returns />
_onCompletionListBlur: function(ev) {
this._hideCompletionList();
},
_onListMouseDown: function(ev) {
/// <summary>
/// Handler for the mousedown event on the autocomplete flyout.
/// </summary>
/// <param name="ev" type="Sys.UI.DomEvent" DomElement="false" mayBeNull="false" />
/// <returns />
if (ev.target !== this._completionListElement) {
this._setText(ev.target);
this._flyoutHasFocus = false;
} else { // focus is still on the flyout and we do not want to hide it
this._flyoutHasFocus = true;
}
},
_onListMouseUp: function(ev) {
/// <summary>
/// Handler for the mouseup event on the autocomplete flyout.
/// </summary>
/// <param name="ev" type="Sys.UI.DomEvent" DomElement="false" mayBeNull="false" />
/// <returns />
this.get_element().focus();
},
_onListMouseOver: function(ev) {
/// <summary>
/// Handler for the mouseover event on the autocomplete flyout.
/// </summary>
/// <param name="ev" type="Sys.UI.DomEvent" DomElement="false" mayBeNull="false" />
/// <returns />
var item = ev.target;
if(item !== this._completionListElement) {
var children = this._completionListElement.childNodes;
// make sure the selected index is updated
for (var i = 0; i < children.length; ++i) {
if (item === children[i]) {
this._highlightItem(item);
this._selectIndex = i;
break;
}
}
}
},
_onGotFocus: function(ev) {
/// <summary>
/// Handler for textbox focus event.
/// </summary>
/// <param name="ev" type="Sys.UI.DomEvent" DomElement="false" mayBeNull="false" />
/// <returns />
this._textBoxHasFocus = true;
if (this._flyoutHasFocus) {
// hide the flyout now that the focus is back on the textbox
this._hideCompletionList();
}
if ((this._minimumPrefixLength == 0) && (!this.get_element().value)) {
this._timer.set_enabled(true);
// only start the timer if the minimumprefixlength is 0
// since we would like to retrieve results even if
// the user has not entered any text and the textbox is empty.
}
},
_onKeyDown: function(ev) {
/// <summary>
/// Handler for the textbox keydown event.
/// </summary>
/// <param name="ev" type="Sys.UI.DomEvent" DomElement="false" mayBeNull="false" />
/// <returns />
this._timer.set_enabled(false);
// the last key press occured so we need to "reset" the timer.
var k = ev.keyCode ? ev.keyCode : ev.rawEvent.keyCode;
if (k === Sys.UI.Key.esc) {
this._hideCompletionList();
ev.preventDefault();
}
else if (k === Sys.UI.Key.up) {
if (this._selectIndex > 0) {
this._selectIndex--;
this._handleScroll(this._completionListElement.childNodes[this._selectIndex], this._selectIndex);
this._highlightItem(this._completionListElement.childNodes[this._selectIndex]);
ev.stopPropagation();
ev.preventDefault();
}
}
else if (k === Sys.UI.Key.down) {
if (this._selectIndex < (this._completionListElement.childNodes.length - 1)) {
this._selectIndex++;
this._handleScroll(this._completionListElement.childNodes[this._selectIndex], this._selectIndex);
this._highlightItem(this._completionListElement.childNodes[this._selectIndex]);
ev.stopPropagation();
ev.preventDefault();
}
}
else if (k === Sys.UI.Key.enter) {
if (this._selectIndex !== -1) {
this._setText(this._completionListElement.childNodes[this._selectIndex]);
ev.preventDefault();
} else {
// close the popup
this.hidePopup();
}
}
else if (k === Sys.UI.Key.tab) {
if (this._selectIndex !== -1) {
this._setText(this._completionListElement.childNodes[this._selectIndex]);
}
}
else {
this._timer.set_enabled(true);
// start the timer to retrieve results since now it is an actual key
}
},
_handleScroll : function(element, index) {
/// <summary>
/// Method to determine if an item is in view or not
/// </summary>
/// <returns />
/// <param name="element" type="Sys.UI.DomElement" DomElement="true" mayBeNull="false" />
/// <param name="index" type="Number" DomElement="false" mayBeNull="true" />
var flyout = this._completionListElement;
var elemBounds = $common.getBounds(element);
var numItems = this._completionListElement.childNodes.length;
if (((elemBounds.height * index) - (flyout.clientHeight + flyout.scrollTop)) >= 0) {
// you need to scroll down
flyout.scrollTop += (((elemBounds.height * index) - (flyout.clientHeight + flyout.scrollTop)) + elemBounds.height);
}
if (((elemBounds.height * (numItems - (index + 1))) - (flyout.scrollHeight - flyout.scrollTop)) >= 0) {
// you need to scroll up
flyout.scrollTop -= (((elemBounds.height * (numItems - (index + 1))) - (flyout.scrollHeight - flyout.scrollTop)) + elemBounds.height);
}
if (flyout.scrollTop % elemBounds.height !== 0) {
if (((elemBounds.height * (index + 1)) - (flyout.clientHeight + flyout.scrollTop)) >= 0) {
// an element is partially displayed at the bottom
flyout.scrollTop -= (flyout.scrollTop % elemBounds.height);
} else { // an element is partially displayed on the top
flyout.scrollTop += (elemBounds.height - (flyout.scrollTop % elemBounds.height));
}
}
},
_handleFlyoutFocus : function() {
/// <summary>
/// Method to handle flyout focus if textbox loses focus.
/// </summary>
/// <returns />
if(!this._textBoxHasFocus) {
if (!this._flyoutHasFocus) {
if (this._webRequest) {
// abort the web service call if we are losing focus. no sense having it delay future web requests.
this._webRequest.get_executor().abort();
this._webRequest = null;
}
// the textbox lost focus and the flyout does not have it
this._hideCompletionList();
} else {
// keep the flyout around otherwise
}
}
},
_onLostFocus: function() {
/// <summary>
/// Handler textbox blur event.
/// </summary>
/// <returns />
this._textBoxHasFocus = false;
this._timer.set_enabled(false);
/* the rest of the onblur handling will be done in
this method after a minor delay to ensure we do not close the flyout
if a user clicks on its scroll bars for example */
window.setTimeout(Function.createDelegate(this, this._handleFlyoutFocus), 500);
},
_onMethodComplete: function(result, context) {
/// <summary>
/// Handler invoked when the webservice call is completed.
/// </summary>
/// <param name="result" type="Object" DomElement="false" mayBeNull="true" />
/// <param name="context" type="String" DomElement="false" mayBeNull="true" />
/// <returns />
this._webRequest = null; // clear out our saved WebRequest object
this._update(context, result, /* cacheResults */ true);
},
_onMethodFailed: function(err, response, context) {
/// <summary>
/// Handler invoked when the webservice call fails, currently a noop
/// </summary>
/// <param name="err" type="Object" DomElement="false" mayBeNull="true" />
/// <param name="result" type="Object" DomElement="false" mayBeNull="true" />
/// <param name="context" type="String" DomElement="false" mayBeNull="true" />
/// <returns />
// clear out our saved WebRequest object
this._webRequest = null;
},
_onTimerTick: function(sender, eventArgs) {
/// <summary>
/// Handler invoked when a timer tick occurs
/// </summary>
/// <param name="sender" type="Object" mayBeNull="true"/>
/// <param name="eventArgs" type="Sys.EventArgs" mayBeNull="true" />
/// <returns />
// turn off the timer until another key is pressed.
this._timer.set_enabled(false);
if (this._servicePath && this._serviceMethod) {
var text = this._currentCompletionWord();
if (text.trim().length < this._minimumPrefixLength) {
this._currentPrefix = null;
this._update('', null, /* cacheResults */ false);
return;
}
// there is new content in the textbox or the textbox is empty but the min prefix length is 0
if ((this._currentPrefix !== text) || ((text == "") && (this._minimumPrefixLength == 0))) {
this._currentPrefix = text;
if ((text != "") && this._cache && this._cache[text]) {
this._update(text, this._cache[text], /* cacheResults */ false);
return;
}
// Raise the populating event and optionally cancel the web service invocation
var eventArgs = new Sys.CancelEventArgs();
this.raisePopulating(eventArgs);
if (eventArgs.get_cancel()) {
return;
}
// Create the service parameters and optionally add the context parameter
// (thereby determining which method signature we're expecting...)
var params = { prefixText : this._currentPrefix, count: this._completionSetCount };
if (this._useContextKey) {
params.contextKey = this._contextKey;
}
if (this._webRequest) {
// abort the previous web service call if we
// are issuing a new one and the previous one is
// active.
this._webRequest.get_executor().abort();
this._webRequest = null;
}
// Invoke the web service
this._webRequest = Sys.Net.WebServiceProxy.invoke(this.get_servicePath(), this.get_serviceMethod(), false, params,
Function.createDelegate(this, this._onMethodComplete),
Function.createDelegate(this, this._onMethodFailed),
text);
$common.updateFormToRefreshATDeviceBuffer();
}
}
},
_setText: function(item) {
/// <summary>
/// Method to set the selected autocomplete option on the textbox
/// </summary>
/// <param name="item" type="Sys.UI.DomElement" DomElement="true" mayBeNull="true">
/// Item to select
/// </param>
/// <returns />
var text = (item && item.firstChild) ? item.firstChild.nodeValue : null;
this._timer.set_enabled(false);
var element = this.get_element();
var control = element.control;
if (control && control.set_text) {
control.set_text(text);
$common.tryFireEvent(control, "change");
}
else {
element.value = text;
$common.tryFireEvent(element, "change");
}
this.raiseItemSelected(new AjaxControlToolkit.AutoCompleteItemEventArgs(item, text, item ? item._value : null));
this._currentPrefix = this._currentCompletionWord();
this._hideCompletionList();
},
_update: function(prefixText, completionItems, cacheResults) {
/// <summary>
/// Method to update the status of the autocomplete behavior
/// </summary>
/// <param name="prefixText" type="String" DomElement="false" mayBeNull="true" />
/// <param name="completionItems" type="Object" DomElement="false" mayBeNull="true" />
/// <param name="cacheResults" type="Object" DomElement="false" mayBeNull="true" />
/// <returns />
if (cacheResults && this.get_enableCaching()) {
if (!this._cache) {
this._cache = {};
}
this._cache[prefixText] = completionItems;
}
// If the target control loses focus or
// if the value in textbox has changed before the webservice returned
// completion items we don't need to show popup
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -