📄 zpautocomplete-core.js
字号:
* * @private * @param {object} oArg Arguments */Zapatec.AutoComplete.prototype.onKeyup = function(oArg) { // Get field if (!oArg) { return; } var oField = oArg.field; if (!oField) { return; } var sKeyword = oField.value; if (typeof sKeyword == 'undefined') { return; } // Get event var oEvent = oArg.event; if (!oEvent) { return; } // Check key switch (oEvent.keyCode) { case 27: // Esc return; case 38: // Up arrow return; case 40: // Down arrow return; } // Check length var iLen = sKeyword.length; if (iLen >= this.config.keywordLength) { // Load data from server this.loadData({ keyword: sKeyword }); } else if (!iLen) { // Hide tips this.hide(); }};/** * Field keyup event listener. * * @private * @param {object} oEvent Event object */Zapatec.AutoComplete.onKeypress = function(oEvent) { // Get target element var oField = Zapatec.Utils.getTargetElement(oEvent); if (oField) { // Call method of attached AutoComplete object Zapatec.Widget.callMethod(oField.zpAutoCompleteId, 'onKeypress', { field: oField, event: oEvent }); }};/** * Shows tips when there are at least keywordLength chars entered in the field. * * <pre> * Arguments format: * { * field: [object] Input field element, * event: [object] Event object * } * </pre> * * @private * @param {object} oArg Arguments */Zapatec.AutoComplete.prototype.onKeypress = function(oArg) { // Get field if (!oArg) { return; } var oField = oArg.field; if (!oField) { return; } // Get event var oEvent = oArg.event; if (!oEvent) { return; } // Check key switch (oEvent.keyCode) { case 13: // Enter if (!this.tip && typeof this.activeTipId == 'number') { // Select active tip this.selectTip({ field: oField, i: this.activeTipId }); // Prevent form submission Zapatec.Utils.stopEvent(oEvent); } }};/** * Reloads data from the specified source after widget is initialized. Argument * should be passed only when dataOnDemand config option is true and * callbackSource config option is defined. See description of dataOnDemand * config option for details. * * @param {object} oArg Optional. Arguments object */Zapatec.AutoComplete.prototype.loadData = function(oArg) { // Form arguments object if (this.config.dataOnDemand) { if (typeof oArg != 'object') { oArg = {}; } } // Call parent method Zapatec.AutoComplete.SUPERclass.loadData.call(this, oArg);};/** * Loads data from the JSON source. * * @private * @param {object} oData Input data object */Zapatec.AutoComplete.prototype.loadDataJson = function(oData) { // Get data if (!(oData instanceof Object)) { oData = {}; } if (!(oData.tips instanceof Array)) { oData.tips = []; } this.data = oData; // Show tips this.show();};/** * Shows box with tips. * @private */Zapatec.AutoComplete.prototype.show = function() { // Hide old tips this.hide(); // Check if there are data var oData = this.data; if (!oData) { return; } var aTips = oData.tips; if (!(aTips instanceof Array)) { return; } var iTips = aTips.length; if (!iTips) { return; } // Check if field is attached var oField = this.field; if (!oField || !oField.parentNode) { return; } var oConfig = this.config; // Reset active tip this.activeTipId = null; // Remove selected tip this.tip = null; // Create container and WCH var oContainer = this.container; var oContent = this.content; var oContainerStyle, oContentStyle; if (!oContainer) { // Create container oContainer = this.container = Zapatec.Utils.createElement('div'); oContainerStyle = oContainer.style; oContainerStyle.position = 'absolute'; oContainerStyle.display = 'none'; // Insert container oField.parentNode.insertBefore(oContainer, oField); // Correct container position oContainerStyle.top = Zapatec.Utils.getElementOffset(oField).top + oField.offsetHeight + 'px'; var oOffset = Zapatec.Utils.getElementOffset(oField); oContainerStyle.top = oOffset.top + oField.offsetHeight + 'px'; oContainerStyle.left = oOffset.left + 'px'; // Create WCH this.wch = Zapatec.Utils.createWCH(oContainer); // Put WCH under container if (this.wch) { this.wch.style.zIndex = -1; } // Create content oContent = this.content = Zapatec.Utils.createElement('div', oContainer); oContentStyle = oContent.style; oContent.className = this.getClassName({prefix: 'zpAC'}); // Setup dimensions if (oConfig.width) { if (oConfig.width == 'auto') { oContentStyle.width = oField.offsetWidth + 'px'; } else { oContentStyle.width = oConfig.width; } } if (oConfig.height) { oContentStyle.height = oConfig.height; } oContentStyle.overflow = oConfig.overflow; // Prevent loosing of focus when scrollbar is clicked in Opera and Safari // Set flag to know that selection was clicked // Doesn't work in IE and not needed there oContent.setAttribute('onmousedown', 'this.zpACClicked=true'); } else { oContainerStyle = oContainer.style; if (oContainer.parentNode != oField.parentNode) { // Move container oField.parentNode.insertBefore(oContainer, oField); // Correct container position var oOffset = Zapatec.Utils.getElementOffset(oField); oContainerStyle.top = oOffset.top + oField.offsetHeight + 'px'; oContainerStyle.left = oOffset.left + 'px'; } } var aHtml = []; // Add tips var sId = this.id.toString(); var fConvertTip = oConfig.convertTip; var iTip, oTip; for (iTip = 0; iTip < iTips; iTip++) { oTip = aTips[iTip]; aHtml.push('<div id="zpAC'); aHtml.push(sId); aHtml.push('Tip'); aHtml.push(iTip); aHtml.push('" class="zpACTip'); if (iTip % 2 == 1) { aHtml.push(' zpACTipOdd'); } else { aHtml.push(' zpACTipEven'); } aHtml.push('" onmousedown="Zapatec.Widget.callMethod('); aHtml.push(sId); aHtml.push(",'selectTip',{i:"); aHtml.push(iTip); aHtml.push('})" onmouseover="Zapatec.Widget.callMethod('); aHtml.push(sId); aHtml.push(",'setActiveTip',"); aHtml.push(iTip); aHtml.push(')" onmouseout="Zapatec.Widget.callMethod('); aHtml.push(sId); aHtml.push(",'resetActiveTip')\">"); if (typeof fConvertTip == 'function') { aHtml.push(fConvertTip(oTip)); } else { // Convert to string by default aHtml.push(oTip + ''); } aHtml.push('</div>'); } oContent.innerHTML += aHtml.join(''); // Show container oContainerStyle.display = ''; // Setup WCH Zapatec.Utils.setupWCH(this.wch, 0, 0, oContainer.offsetWidth, oContainer.offsetHeight);};/** * Hides box with tips. * @private */Zapatec.AutoComplete.prototype.hide = function() { // Reset active tip this.activeTipId = null; // Hide tips if (this.container) { // Hide container this.container.style.display = 'none'; // Remove tips this.content.innerHTML = ''; }};/** * Goes to the next tip. Used in keyboard navigation. * @private */Zapatec.AutoComplete.prototype.gotoNextTip = function() { if (!this.data || !(this.data.tips instanceof Array) || !this.data.tips.length) { return; } // Get next tip var iTip = typeof this.activeTipId == 'number' ? this.activeTipId + 1 : 0; if (iTip >= this.data.tips.length) { iTip = 0; } // Go to next tip this.setActiveTip(iTip);};/** * Goes to the previous tip. Used in keyboard navigation. * @private */Zapatec.AutoComplete.prototype.gotoPrevTip = function() { if (!this.data || !(this.data.tips instanceof Array) || !this.data.tips.length) { return; } // Get previous tip var iTip = typeof this.activeTipId == 'number' ? this.activeTipId - 1 : this.data.tips.length - 1; if (iTip < 0) { iTip = this.data.tips.length - 1; } // Go to previous tip this.setActiveTip(iTip);};/** * Sets active tip. * * @private * @param {number} iTip Index of tip to make active in the visible tips array */Zapatec.AutoComplete.prototype.setActiveTip = function(iTip) { // Reset active tip first this.resetActiveTip(); // Check tip id if (!this.data || !(this.data.tips instanceof Array) || typeof this.data.tips[iTip] == 'undefined') { return; } // Set active tip this.activeTipId = iTip; // Change className of the respective div var oDiv = document.getElementById('zpAC' + this.id + 'Tip' + iTip); if (oDiv && oDiv.className.indexOf('zpACTipActive') == -1) { if (oDiv.className.indexOf('zpACTipOdd') == -1) { // Even oDiv.className += ' zpACTipActive zpACTipActiveEven'; } else { // Odd oDiv.className += ' zpACTipActive zpACTipActiveOdd'; } }};/** * Resets active tip. * @private */Zapatec.AutoComplete.prototype.resetActiveTip = function() { // Check if there is active tip if (typeof this.activeTipId != 'number') { return; } // Change className of the respective div var oDiv = document.getElementById('zpAC' + this.id + 'Tip' + this.activeTipId); if (oDiv && oDiv.className.indexOf('zpACTipActive') != -1) { oDiv.className = oDiv.className.replace(/ zpACTipActive[^ ]*/g, ''); } // Reset active tip this.activeTipId = null;};/** * Selects one of visible tips. * * <pre> * Arguments format: * { * field: [object, optional] field object, * i: [number] index of tip to select in the visible tips array * } * </pre> * * @private * @param {object} oArg Arguments */Zapatec.AutoComplete.prototype.selectTip = function(oArg) { // Hide tips this.hide(); // Get tip if (!oArg) { return; } var oField = oArg.field; if (!oField) { oField = this.field; if (!oField) { return; } } var iTip = oArg.i; if (typeof iTip != 'number') { return; } var oData = this.data; if (!oData) { return; } var aTips = oData.tips; if (!(aTips instanceof Array)) { return; } var oTip = aTips[iTip]; if (!oTip) { return; } // Select tip this.tip = oTip; // Update field var oConfig = this.config; if (typeof oConfig.selectTip == 'function') { // Use callback function to set value oConfig.selectTip(oTip); } else if (oField && typeof oConfig.convertTip == 'function') { // Convert value using callback oField.value = oConfig.convertTip(oTip); } else if (oField) { // Convert to string oField.value = oTip + ''; }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -