summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/keyword-chooser.js162
-rw-r--r--js/util.js98
2 files changed, 260 insertions, 0 deletions
diff --git a/js/keyword-chooser.js b/js/keyword-chooser.js
new file mode 100644
index 000000000..afc90b491
--- /dev/null
+++ b/js/keyword-chooser.js
@@ -0,0 +1,162 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Keyword Chooser.
+ *
+ * The Initial Developer of the Original Code is America Online, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * Mozilla Foundation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Christopher A. Aillon <christopher@aillon.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function KeywordChooser(aParent, aChooser, aAvail, aChosen, aValidKeywords)
+{
+ // Initialization
+ this._parent = aParent;
+ this._chooser = aChooser;
+ this._available = aAvail;
+ this._chosen = aChosen;
+ this._validKeywords = aValidKeywords;
+
+ this.setInitialStyles();
+
+ // Register us, our properties, and our events
+ this._parent.chooser = this;
+ this._chooser.chooserElement = this._parent;
+}
+
+KeywordChooser.prototype =
+{
+ // chooses the selected items
+ choose: function()
+ {
+ this._swapSelected(this._available, this._chosen);
+ },
+
+ unchoose: function()
+ {
+ this._swapSelected(this._chosen, this._available);
+ },
+
+ positionChooser: function()
+ {
+ if (this._positioned) {
+ return;
+ }
+
+ var elemY = bz_findPosY(this._parent);
+ var elemX = bz_findPosX(this._parent);
+ var elemH = this._parent.offsetHeight;
+
+ this._chooser.style.left = elemX + "px";
+ this._chooser.style.top = elemY + elemH + 1 + "px";
+
+ this._positioned = true;
+ },
+
+ setInitialStyles: function()
+ {
+ this._chooser.style.display = "none";
+ this._chooser.style.position = "absolute";
+ this._positioned = false;
+ },
+
+ open: function()
+ {
+ this._chooser.style.display = "";
+ this._available.style.display = "";
+ this._chosen.style.display = "";
+ this._parent.disabled = true;
+ this.positionChooser();
+ },
+
+ ok: function()
+ {
+ var len = this._chosen.options.length;
+
+ var text = "";
+ for (var i = 0; i < len; i++) {
+ text += this._chosen.options[i].text;
+ if (i != len - 1) {
+ text += ", ";
+ }
+ }
+
+ this._parent.value = text;
+ this._parent.title = text;
+
+ this.close();
+ },
+
+ cancel: function()
+ {
+ var chosentext = this._parent.value;
+ var chosenArray = new Array();
+
+ if (chosentext != ""){
+ chosenArray = chosentext.split(", ");
+ }
+
+ var availArray = new Array();
+
+ for (var i = 0; i < this._validKeywords.length; i++) {
+ if (!bz_isValueInArray(chosenArray, this._validKeywords[i])) {
+ availArray[availArray.length] = this._validKeywords[i];
+ }
+ }
+
+ bz_populateSelectFromArray(this._available, availArray, false, true);
+ bz_populateSelectFromArray(this._chosen, chosenArray, false, true);
+ this.close();
+ },
+
+ close: function()
+ {
+ this._chooser.style.display = "none";
+ this._parent.disabled = false;
+ },
+
+ _swapSelected: function(aSource, aTarget)
+ {
+ var kNothingSelected = -1;
+ while (aSource.selectedIndex != kNothingSelected) {
+ var option = aSource.options[aSource.selectedIndex];
+ aTarget.appendChild(option);
+ option.selected = false;
+ }
+ }
+};
+
+function InitializeKeywordChooser(aValidKeywords)
+{
+ var keywords = document.getElementById("keywords");
+ var chooser = document.getElementById("keyword-chooser");
+ var avail = document.getElementById("keyword-list");
+ var chosen = document.getElementById("bug-keyword-list");
+ var chooserObj = new KeywordChooser(keywords, chooser, avail, chosen, aValidKeywords);
+}
diff --git a/js/util.js b/js/util.js
index 9d2209093..293c89a5d 100644
--- a/js/util.js
+++ b/js/util.js
@@ -20,6 +20,7 @@
*
* Contributor(s):
* Max Kanat-Alexander <mkanat@bugzilla.org>
+ * Christopher A. Aillon <christopher@aillon.com>
*
* ***** END LICENSE BLOCK ***** */
@@ -114,3 +115,100 @@ function bz_getFullWidth(fromObj)
return scrollX;
}
+
+/**
+ * Create wanted options in a select form control.
+ *
+ * @param aSelect Select form control to manipulate.
+ * @param aValue Value attribute of the new option element.
+ * @param aTextValue Value of a text node appended to the new option
+ * element.
+ * @param aOwnerDocument Owner document of the new option element. If not
+ * specified then "document" will be used.
+ * @return Created option element.
+ */
+function bz_createOptionInSelect(aSelect, aValue, aTextValue, aOwnerDocument)
+{
+ if (!aOwnerDocument) {
+ aOwnerDocument = document;
+ }
+
+ var myOption = aOwnerDocument.createElement("option");
+ myOption.setAttribute("value", aValue);
+
+ var myTextNode = aOwnerDocument.createTextNode(aTextValue)
+ myOption.appendChild(myTextNode);
+
+ aSelect.appendChild(myOption);
+
+ return myOption;
+}
+
+/**
+ * Clears all options from a select form control.
+ *
+ * @param aElm Select form control of which options to clear.
+ * @param aSkipFirst Boolean; true to skip (not clear) first option in the
+ * select and false to remove all options.
+ */
+function bz_clearOptions(aElm, aSkipFirst)
+{
+ var start = 0;
+
+ // Skip the first element? (for 'Choose One' type foo)
+ if (aSkipFirst) {
+ start = 1;
+ }
+
+ var length = aElm.options.length;
+
+ for (var run = start; run < length; run++) {
+ aElm.removeChild(aElm.options[start]);
+ }
+}
+
+/**
+ * Takes an array and moves all the values to an select.
+ *
+ * @param aSelect Select form control to populate. Will be cleared
+ * before array values are created in it.
+ * @param aArray Array with values to populate select with.
+ * @param aSkipFirst Boolean; true to skip (not touch) first option in the
+ * select and false to remove all options.
+ * @param aUseNameAsValue Boolean; true if name is used as value and false if
+ * not.
+ */
+function bz_populateSelectFromArray(aSelect, aArray, aSkipFirst, aUseNameAsValue)
+{
+ // Clear the field
+ bz_clearOptions(aSelect, aSkipFirst);
+
+ for (var run = 0; run < aArray.length; run++) {
+ if (aUseNameAsValue) {
+ bz_createOptionInSelect(aSelect, aArray[run], aArray[run]);
+ } else {
+ bz_createOptionInSelect(aSelect, aArray[run][0], aArray[run][0]);
+ }
+ }
+}
+
+/**
+ * Checks if a specified value is in the specified array.
+ *
+ * @param aArray Array to search for the value.
+ * @param aValue Value to search from the array.
+ * @return Boolean; true if value is found in the array and false if not.
+ */
+function bz_isValueInArray(aArray, aValue)
+{
+ var run = 0;
+ var len = aArray.length;
+
+ for ( ; run < len; run++) {
+ if (aArray[run] == aValue) {
+ return true;
+ }
+ }
+
+ return false;
+}