Website : rimsha.abasa.com
backdoor
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
lib
/
jenkins
/
war
/
scripts
/
Filename :
combobox.js
back
Copy
/* * The MIT License * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ if (typeof UTILITIES_VERSION == "undefined" || UTILITIES_VERSION < 0.1) { console.log("A suitable version of the Utilities class is not available"); } COMBOBOX_VERSION = 0.1; /* Sample CSS for the combobox .comboBoxList { padding: 0px; border: 1px solid #999; background-color: #f7f7ff; overflow: visible; } .comboBoxItem { margin: 0px; padding: 2px 5px; background-color: inherit; cursor: default; } .comboBoxSelectedItem { background-color: #ddf; } */ /** * I create a new combobox, using the specified text input field and * population callback. The item list is styled with three CSS * classes: comboBoxList, comboBoxItem, and comboBoxSelectedItem, which * are for the containing DIV, the individual item DIVs, and for the * currently selected item DIV. Note that the selected item has both * the item and selectedItem classes applied. Sample CSS is available * in a comment at the top of the implementation file. * * The 'config' argument allows passing of additional parameters that * further govern the behaviour of the combo box. Supported parameters * are listed here: * allowMultipleValues - whether the form field should allow multiple * values to be provided. Each individual value will get it's own * separate dropdown with, so a field value such as "dog,ca" would * operate as if the value were just "ca" (i.e. just "ca" would be * passed to the callback, and a selection choice would only * replace the "ca"). Defaults to false. * valueDelimiter - if allowMultipleValues is set to true, this is the * character used to delimit the values. Defaults to a comma. * * @param idOrField The ID of the text field the combobox is based around, or the field itself. * @param callback The function to call when the typed value changes. * The function will be passed the current value of the field, and * must return an array of values to display in the dropdown. * @param config additional config parameters, as explained above. * @param config An object containing configuration parameters for the * instance. */ function ComboBox(idOrField, callback, config) { var self = this; // instance variables this.config = config || new Object(); this.callback = callback; this.availableItems = new Array(); this.selectedItemIndex = -1; this.field = typeof idOrField == "string" ? document.getElementById(idOrField) : idOrField; if (typeof this.field == "undefined") { alert( "You have specified an invalid id for the field you want to turn into a combo box", ); } this.dropdown = document.createElement("div"); this.isDropdownShowing = false; this.oldonsubmit = null; // configure the dropdown div this.dropdown.className = "comboBoxList"; document.body.appendChild(this.dropdown); this.dropdown.style.position = "absolute"; this.moveDropdown(); this.hideDropdown(); // initialize the field this.field.comboBox = this; this.field.oldValue = this.field.value; this.field.onkeyup = ComboBox.onKeyUp; this.field.moveCaretToEnd = function () { if (this.createTextRange) { var range = this.createTextRange(); range.collapse(false); range.select(); } else if (this.setSelectionRange) { this.focus(); var length = this.value.length; this.setSelectionRange(length, length); } }; this.field.onfocus = function () { this.comboBox.oldonsubmit = this.form.onsubmit; this.form.onsubmit = function () { if (self.isDropdownShowing) { return false; } if (self.oldonsubmit) { self.oldonsubmit.call(this); } return true; }; // repopulate and display the dropdown this.comboBox.valueChanged(); }; this.field.onblur = function () { var cb = this.comboBox; this.hideTimeout = setTimeout(function () { cb.hideDropdown(); }, 100); this.form.onsubmit = cb.oldonsubmit; }; // privileged methods this.getConfigParam = function (name, defVal) { return self.config[name] || defVal; }; } /** * I am the onKeyDown listener that gets installed on the input field * that is the core of the ComboBox. I handle action operations. * * @param e The event object on Mozilla browsers, null on IE */ ComboBox.onKeyDown = function (e) { if (!e) { e = window.event; } var capture = function () { e.cancelBubble = true; if (e.stopPropagation) { e.stopPropagation(); } }; switch (e.keyCode) { case 13: // enter case 9: // tab this.comboBox.chooseSelection(); capture(); return false; case 27: // escape this.comboBox.hideDropdown(); capture(); break; case 38: // up arrow this.comboBox.selectPrevious(); capture(); break; case 40: // down arrow this.comboBox.selectNext(); capture(); break; } }; /** * I am the onKeyUp listener that gets installed on the input field * that is the core of the ComboBox. I handle value-change operations. * * @param e The event object on Mozilla browsers, null on IE */ ComboBox.onKeyUp = function (e) { if (!e) { e = window.event; } var capture = function () { e.cancelBubble = true; if (e.stopPropagation) { e.stopPropagation(); } }; switch (e.keyCode) { case 38: // up arrow case 40: // down arrow this.moveCaretToEnd(); capture(); break; default: if (this.value != this.oldValue) { this.comboBox.valueChanged(); this.oldValue = this.value; } capture(); } }; /** * I am called by the onKeyUp listener when the entered value changes, * and am responsible for invoking the application callback function * and repopulating the dropdown, if appropriate. */ ComboBox.prototype.valueChanged = function () { var value = this.field.value; if (this.getConfigParam("allowMultipleValues", false)) { value = value.split(this.getConfigParam("valueDelimiter", ",")); value = value[value.length - 1].replace(/^ +/, "").replace(/ +$/, ""); } var a = this.callback(value, this); if (typeof a == "undefined") { // to catch null returns return; } this.setItems(a); }; /** * I can be called at any time with a new set of items to display in * the dropdown. * * @param items The array of items that should be used for the dropdown * values. */ ComboBox.prototype.setItems = function (items) { if (typeof items != "object") { alert("setItems wasn't passed a valid array: " + typeof a); return; } this.availableItems = items; this.populateDropdown(); }; /** * I am called to repopulate the dropdown. There should never be a * need to invoke me externally. */ ComboBox.prototype.populateDropdown = function () { if (this.availableItems.length > 0) { Utilities.removeChildren(this.dropdown); for (var i = 0; i < this.availableItems.length; i++) { var item = document.createElement("div"); item.className = "comboBoxItem"; item.innerText = this.availableItems[i]; item.id = "item_" + this.availableItems[i]; item.comboBox = this; item.comboBoxIndex = i; item.onmouseover = function () { this.comboBox.select(this.comboBoxIndex); }; item.onmousedown = function () { this.comboBox.choose(this.comboBoxIndex); }; this.dropdown.appendChild(item); } this.selectedItemIndex = 0; this.updateSelection(); this.showDropdown(); } else { this.selectedItemIndex = -1; this.hideDropdown(); } }; /** * I am called by a mouse listener on the dropdown items to choose a * specific item straight away. * * @param index The index of the item to choose */ ComboBox.prototype.choose = function (index) { if (this.select(index)) { this.chooseSelection(); } }; /** * I am called by the onKeyUp listener to indicate that the user wants * to use the current selection as the new value of the field. */ ComboBox.prototype.chooseSelection = function () { var i = this.selectedItemIndex; var a = this.availableItems; if (i >= 0 && i < a.length) { var valueToAdd = a[i].replace(/<[^>]+>/g, ""); if (this.getConfigParam("allowMultipleValues", false)) { var currentValue = ""; var delim = this.getConfigParam("valueDelimiter", ","); var values = this.field.value.split(delim); for (var j = 0; j < values.length - 1; j++) { currentValue = Utilities.listAppend(currentValue, values[j], delim); } this.field.value = Utilities.listAppend(currentValue, valueToAdd, delim); } else { this.field.value = valueToAdd; } this.field.oldValue = this.field.value; this.field.focus(); this.field.moveCaretToEnd(); this.hideDropdown(); } }; /** * I am called by a mouse listener on the dropdown items to select a * specific item straight away. * * @param index The index of the item to select * @return whether the selection happened (the index was valid) */ ComboBox.prototype.select = function (index) { if (index < 0 || index >= this.availableItems.length) { return false; } this.selectedItemIndex = index; this.updateSelection(); return true; }; /** * I am called by the onKeyUp listener to indicate that the user wants * to select the next option in the dropdown. */ ComboBox.prototype.selectNext = function () { if (this.selectedItemIndex >= this.availableItems.length - 1) { return false; } this.selectedItemIndex++; this.updateSelection(); return true; }; /** * I am called by the onKeyUp listener to indicate that the user wants * to select the previous option in the dropdown. */ ComboBox.prototype.selectPrevious = function () { if (this.selectedItemIndex <= 0) { return false; } this.selectedItemIndex--; this.updateSelection(); }; /** * I show the dropdown DIV. */ ComboBox.prototype.showDropdown = function () { this.moveDropdown(); clearTimeout(this.field.hideTimeout); this.dropdown.style.display = "block"; this.field.onkeydown = ComboBox.onKeyDown; this.isDropdownShowing = true; }; /** * I hide the dropdown DIV. */ ComboBox.prototype.hideDropdown = function () { var self = this; setTimeout(function () { self.isDropdownShowing = false; }, 100); this.field.onkeydown = null; this.dropdown.style.display = "none"; }; ComboBox.prototype.moveDropdown = function () { var offsets = Utilities.getOffsets(this.field); this.dropdown.style.top = offsets.y + (this.field.offsetHeight ? this.field.offsetHeight : 22) + "px"; this.dropdown.style.left = offsets.x + "px"; this.dropdown.style.width = (this.field.offsetWidth ? this.field.offsetWidth : 100) + "px"; }; /** * I update the dropdown so that the display reflects the internally * selected item, */ ComboBox.prototype.updateSelection = function () { for (var i = 0; i < this.dropdown.childNodes.length; i++) { if (i == this.selectedItemIndex) { this.dropdown.childNodes[i].className += " comboBoxSelectedItem"; } else { this.dropdown.childNodes[i].className = this.dropdown.childNodes[ i ].className.replace(/ *comboBoxSelectedItem */g, ""); } } };