You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by br...@apache.org on 2007/01/21 15:39:50 UTC
svn commit: r498327 - in
/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources:
./ js/ js/templates/
Author: bruno
Date: Sun Jan 21 06:39:49 2007
New Revision: 498327
URL: http://svn.apache.org/viewvc?view=rev&rev=498327
Log:
Make the CForms MultiValueEditor into a dojo widget.
Added:
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js (with props)
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html
Modified:
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/__package__.js
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/forms-lib.js
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/manifest.js
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl?view=diff&rev=498327&r1=498326&r2=498327
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl Sun Jan 21 06:39:49 2007
@@ -178,42 +178,27 @@
<xsl:variable name="values" select="fi:values/fi:value/text()"/>
<div id="{$id}">
- <input name="{$id}:entry" id="{$id}:entry">
- <xsl:if test="fi:styling/@size">
- <xsl:attribute name="size"><xsl:value-of select="fi:styling/@size"/></xsl:attribute>
- </xsl:if>
- </input>
- <br/>
<table>
<tr>
<td>
- <select name="{$id}" id="{$id}:input" size="5" multiple="multiple" style="width: 150px">
- <xsl:for-each select="$values">
- <option value="{.}"><xsl:value-of select="."/></option>
- </xsl:for-each>
- </select>
+ <div dojoType="forms:MultiValueEditor" id="{$id}:widget" cformsIdPrefix="{$id}">
+ <!-- Data is supplied to the widget using this table -->
+ <table>
+ <tbody>
+ <xsl:for-each select="$values">
+ <tr>
+ <td><xsl:value-of select="."/></td>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </div>
</td>
<td>
- <!-- strangely, IE adds an extra blank line if there only a button on a line. So we surround it with nbsp -->
- <xsl:text> </xsl:text>
- <input type="image" id="{$id}:delete" src="{$resources-uri}/forms/img/delete.gif"/>
- <xsl:text> </xsl:text>
- <br/>
- <xsl:text> </xsl:text>
- <input type="image" id="{$id}:up" src="{$resources-uri}/forms/img/move_up.gif"/>
- <xsl:text> </xsl:text>
- <br/>
- <xsl:text> </xsl:text>
- <input type="image" id="{$id}:down" src="{$resources-uri}/forms/img/move_down.gif"/>
- <xsl:text> </xsl:text>
- <br/>
<xsl:apply-templates select="." mode="common"/>
</td>
</tr>
</table>
- <script type="text/javascript">
- new FormsMultiValueEditor("<xsl:value-of select="$id"/>");
- </script>
</div>
</xsl:template>
Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js?view=auto&rev=498327
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js Sun Jan 21 06:39:49 2007
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+dojo.provide("cocoon.forms.MultiValueEditor");
+
+/**
+ * A free-entry multivalue field editor.
+ *
+ * Some functionality that's not visible at first sight:
+ * - items can be moved around using ctrl+up and ctrl+down.
+ * - an item can be replaced/updated by pressing ctrl+enter in the input box
+ */
+dojo.widget.defineWidget(
+ // widget name and class
+ "cocoon.forms.MultiValueEditor",
+
+ // superclass
+ dojo.widget.HtmlWidget,
+
+ function() {
+ },
+
+ // properties and methods
+ {
+ isContainer: false,
+
+ cformsIdPrefix: "id-prefix-not-set",
+
+ resourcesUri: cocoon.resourcesUri, // to make this available to the template
+
+ templatePath: cocoon.resourcesUri + "/forms/js/templates/MultiValueEditor.html",
+
+ fillInTemplate: function(args, frag) {
+ cocoon.forms.MultiValueEditor.superclass.fillInTemplate(this, args, frag);
+
+ dojo.event.connect(this.entry, "onkeypress", this, "_processInputKey");
+ dojo.event.connect(this.select, "onkeydown", this, "_processSelectKey");
+ dojo.event.connect(this.select, "onchange", this, "_processSelectChange");
+
+ dojo.event.connect(this.deleteButton, "onclick", this, "_deleteValues");
+ dojo.event.connect(this.moveUpButton, "onclick", this, "_moveUp");
+ dojo.event.connect(this.moveDownButton, "onclick", this, "_moveDown");
+
+ dojo.event.connect(this, "addedTo", this, "_addOnSubmitHandler");
+
+ this._readData(this.getFragNodeRef(frag));
+ },
+
+ /**
+ * Reads the data for the select-list from a table in the original widget-defining element.
+ */
+ _readData: function(origFrag) {
+ var table = dojo.dom.getFirstChildElement(origFrag, "table");
+ if (table != null) {
+ var tbody = dojo.dom.firstElement(table, "tbody");
+ if (tbody != null) {
+ var tr = dojo.dom.firstElement(tbody, "tr");
+ while (tr != null) {
+ var td = dojo.dom.firstElement(tr, "td");
+ if (td != null) {
+ var text = dojo.dom.textContent(td);
+ this.select.options[this.select.options.length] = new Option(text, text);
+ }
+ tr = dojo.dom.nextElement(tr, "tr");
+ }
+ }
+ } else {
+ dojo.debug("MultiValueEditor: no data table found");
+ }
+ },
+
+ _addOnSubmitHandler: function(parent) {
+ var form = this._getForm(this);
+ if (form != null) {
+ var onSubmitHandler = {};
+ onSubmitHandler.forms_onsubmit = dojo.lang.hitch(this, "_selectAll");
+ cocoon.forms.addOnSubmitHandler(form, onSubmitHandler);
+ } else {
+ dojo.debug("MultiValueEditor is not being added to a form -- no onSubmitHandler then.");
+ }
+ },
+
+ /**
+ * Finds the HTML form to which a widget belongs.
+ * The widget is passed as an argument since this might become a generic
+ * utility function outside of this wiget.
+ */
+ _getForm: function(widget) {
+ do {
+ if (widget.domNode != null && widget.domNode.tagName != null && widget.domNode.tagName.toLowerCase() == "form") {
+ return widget.domNode;
+ }
+ widget = widget.parent; // parent property points to the parent widget
+ } while (widget != null)
+ return null;
+ },
+
+ /**
+ * Key event handler for keypresses in the input box.
+ */
+ _processInputKey: function(event) {
+ if (event.keyCode == 13 || event.keyCode == 10) {
+ dojo.event.browser.stopEvent(event);
+ var entry = this.entry;
+ var select = this.select;
+ var newItem = entry.value;
+ if (newItem == null || newItem == "")
+ return;
+ // if ctrl+enter is pressed, the first selected item is replaced with the new value
+ // (otherwise, the new value is appended at the end of the list)
+ var replace = event.ctrlKey;
+ var newItemPos = -1;
+ for (var i = 0; i < select.options.length; i++) {
+ if (select.options[i].selected && replace && newItemPos == -1)
+ newItemPos = i;
+ select.options[i].selected = false;
+ }
+ if (newItemPos == -1)
+ newItemPos = select.options.length;
+ select.options[newItemPos] = new Option(newItem, newItem, false, true);
+ entry.value = "";
+ }
+ },
+
+ /**
+ * Key event handler for keypresses in the select list.
+ */
+ _processSelectKey: function(event) {
+ // 46 = delete key
+ if (event.keyCode == 46) {
+ dojo.event.browser.stopEvent(event);
+ this._deleteValues();
+ } else if (event.ctrlKey && event.keyCode == 38) {
+ dojo.event.browser.stopEvent(event);
+ // key up = 38
+ this._moveUp();
+ } else if (event.ctrlKey && event.keyCode == 40) {
+ dojo.event.browser.stopEvent(event);
+ // key down = 40
+ this._moveDown();
+ }
+ },
+
+ _deleteValues: function(event) {
+ if (event) dojo.event.browser.stopEvent(event);
+ var options = this.select.options;
+ var i = 0;
+ var lastRemovedItem = -1;
+ while (i < options.length) {
+ if (options[i].selected) {
+ options[i] = null;
+ lastRemovedItem = i;
+ } else {
+ i++;
+ }
+ }
+
+ if (lastRemovedItem != -1) {
+ if (options.length > lastRemovedItem) {
+ options[lastRemovedItem].selected = true;
+ } else if (lastRemovedItem - 1 >= 0) {
+ options[lastRemovedItem - 1].selected = true;
+ }
+ }
+ },
+
+ _processSelectChange: function(event) {
+ if (event) dojo.event.browser.stopEvent(event);
+ var options = this.select.options;
+ for (var i = 0; i < options.length; i++) {
+ if (options[i].selected) {
+ this.entry.value = options[i].value;
+ break;
+ }
+ }
+ },
+
+ _moveUp: function(event) {
+ if (event) dojo.event.browser.stopEvent(event);
+ var options = this.select.options;
+ if (options.length == 0)
+ return;
+ if (options[0].selected)
+ return;
+
+ for (var i = 0; i < options.length; i++) {
+ if (options[i].selected) {
+ var prev = this._cloneOption(options[i - 1]);
+ var current = this._cloneOption(options[i]);
+ options[i - 1] = current;
+ options[i] = prev;
+ }
+ }
+ },
+
+
+ _cloneOption: function(option) {
+ return new Option(option.text, option.value, false, option.selected);
+ },
+
+ _moveDown: function(event) {
+ if (event) dojo.event.browser.stopEvent(event);
+ var options = this.select.options;
+ if (options.length == 0)
+ return;
+ if (options[options.length - 1].selected)
+ return;
+
+ for (var i = options.length - 1; i >= 0; i--) {
+ if (options[i].selected) {
+ var next = this._cloneOption(options[i + 1]);
+ var current = this._cloneOption(options[i]);
+ options[i + 1] = current;
+ options[i] = next;
+ }
+ }
+ },
+
+ _selectAll: function() {
+ var options = this.select.options;
+ for (var i = 0; i < options.length; i++) {
+ options[i].selected = true;
+ }
+ }
+ }
+);
\ No newline at end of file
Propchange: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js
------------------------------------------------------------------------------
svn:eol-style = native
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/__package__.js
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/__package__.js?view=diff&rev=498327&r1=498326&r2=498327
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/__package__.js (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/__package__.js Sun Jan 21 06:39:49 2007
@@ -28,6 +28,7 @@
"cocoon.forms.CFormsSuggest",
"cocoon.forms.DropdownDateTimePicker",
"cocoon.forms.InfoPopup",
+ "cocoon.forms.MultiValueEditor",
"dojo.widget.InlineEditBox" // also needed by advanced-field-styling
]
});
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/forms-lib.js
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/forms-lib.js?view=diff&rev=498327&r1=498326&r2=498327
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/forms-lib.js (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/forms-lib.js Sun Jan 21 06:39:49 2007
@@ -204,160 +204,4 @@
}
}
}
-}
-
-/**
- * FormsMultiValueEditor is the implementation of the free-form multivalue field editor.
- */
-function FormsMultiValueEditor(id) {
- this.select = document.getElementById(id + ":input");
- this.entry = document.getElementById(id + ":entry");
- var self = this;
- this.entry.onkeypress = function(event) { return self.processInputKey(event); };
- this.select.onkeydown = function(event) { return self.processSelectKey(event); };
- this.select.onchange = function(event) { return self.processSelectChange(event); };
-
- var deleteEl = document.getElementById(id + ":delete");
- deleteEl.onclick = function() { self.deleteValues(); return false; };
-
- var upEl = document.getElementById(id + ":up");
- upEl.onclick = function() { self.moveUp(); return false; };
-
- var downEl = document.getElementById(id + ":down");
- downEl.onclick = function() { self.moveDown(); return false; };
-
- var onsubmitHandler = new Object();
- onsubmitHandler.forms_onsubmit = function () {
- self.selectAll();
- }
- cocoon.forms.addOnSubmitHandler(document.getElementById(id), onsubmitHandler);
-}
-
-/**
- * Key event handler for keypresses in the input box.
- */
-FormsMultiValueEditor.prototype.processInputKey = function(event) {
- if (event == null) event = window.event; // Internet Explorer
- if (event.keyCode == 13 || event.keyCode == 10) {
- var entry = this.entry;
- var select = this.select;
- var newItem = entry.value;
- if (newItem == null || newItem == "")
- return false;
- // if ctrl+enter is pressed, the first selected item is replaced with the new value
- // (otherwise, the new value is appended at the end of the list)
- var replace = event.ctrlKey;
- var newItemPos = -1;
- for (var i = 0; i < select.options.length; i++) {
- if (select.options[i].selected && replace && newItemPos == -1)
- newItemPos = i;
- select.options[i].selected = false;
- }
- if (newItemPos == -1)
- newItemPos = select.options.length;
- select.options[newItemPos] = new Option(newItem, newItem, false, true);
- entry.value = "";
- return false;
- } else {
- return true;
- }
-}
-
-/**
- * Key event handler for keypresses in the select list.
- */
-FormsMultiValueEditor.prototype.processSelectKey = function(event) {
- if (event == null) event = window.event; // Internet Explorer
- // 46 = delete key
- if (event.keyCode == 46) {
- this.deleteValues();
- return false;
- } else if (event.ctrlKey && event.keyCode == 38) {
- // key up = 38
- this.moveUp();
- return false;
- } else if (event.ctrlKey && event.keyCode == 40) {
- // key down = 40
- this.moveDown();
- return false;
- }
-}
-
-
-FormsMultiValueEditor.prototype.deleteValues = function() {
- var options = this.select.options;
- var i = 0;
- var lastRemovedItem = -1;
- while (i < options.length) {
- if (options[i].selected) {
- options[i] = null;
- lastRemovedItem = i;
- } else {
- i++;
- }
- }
-
- if (lastRemovedItem != -1) {
- if (options.length > lastRemovedItem) {
- options[lastRemovedItem].selected = true;
- } else if (lastRemovedItem - 1 >= 0) {
- options[lastRemovedItem - 1].selected = true;
- }
- }
-}
-
-FormsMultiValueEditor.prototype.processSelectChange = function() {
- var options = this.select.options;
- for (var i = 0; i < options.length; i++) {
- if (options[i].selected) {
- this.entry.value = options[i].value;
- break;
- }
- }
-}
-
-FormsMultiValueEditor.prototype.moveUp = function() {
- var options = this.select.options;
- if (options.length == 0)
- return;
- if (options[0].selected)
- return;
-
- for (var i = 0; i < options.length; i++) {
- if (options[i].selected) {
- var prev = this.cloneOption(options[i - 1]);
- var current = this.cloneOption(options[i]);
- options[i - 1] = current;
- options[i] = prev;
- }
- }
-}
-
-FormsMultiValueEditor.prototype.cloneOption = function(option) {
- return new Option(option.text, option.value, false, option.selected);
-}
-
-FormsMultiValueEditor.prototype.moveDown = function() {
- var options = this.select.options;
- if (options.length == 0)
- return;
- if (options[options.length - 1].selected)
- return;
-
- for (var i = options.length - 1; i >= 0; i--) {
- if (options[i].selected) {
- var next = this.cloneOption(options[i + 1]);
- var current = this.cloneOption(options[i]);
- options[i + 1] = current;
- options[i] = next;
- }
- }
-}
-
-FormsMultiValueEditor.prototype.selectAll = function() {
- var options = this.select.options;
- for (var i = 0; i < options.length; i++) {
- options[i].selected = true;
- }
-}
-
+}
\ No newline at end of file
Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html?view=auto&rev=498327
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html Sun Jan 21 06:39:49 2007
@@ -0,0 +1,21 @@
+<div id="${this.widgetId}">
+ <input name="${this.cformsIdPrefix}:entry" id="${this.cformsIdPrefix}:entry"
+ dojoAttachPoint="entry"/>
+ <table>
+ <tr>
+ <td>
+ <select name="${this.cformsIdPrefix}" id="${this.cformsIdPrefix}:input" size="5" multiple="multiple" style="width: 150px"
+ dojoAttachPoint="select">
+ </select>
+ </td>
+ <td width="20px">
+ <input dojoAttachPoint="deleteButton" type="image" src="${this.resourcesUri}/forms/img/delete.gif"/>
+ <br/>
+ <input dojoAttachPoint="moveUpButton" type="image" src="${this.resourcesUri}/forms/img/move_up.gif"/>
+ <br/>
+ <input dojoAttachPoint="moveDownButton" type="image" src="${this.resourcesUri}/forms/img/move_down.gif"/>
+ <br/>
+ </td>
+ </tr>
+ </table>
+</div>
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/manifest.js
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/manifest.js?view=diff&rev=498327&r1=498326&r2=498327
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/manifest.js (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/manifest.js Sun Jan 21 06:39:49 2007
@@ -41,7 +41,8 @@
"cformsrepeater" : "cocoon.forms.CFormsRepeater",
"cformssuggest" : "cocoon.forms.CFormsSuggest",
"dropdowndatetimepicker" : "cocoon.forms.DropdownDateTimePicker",
- "infopopup" : "cocoon.forms.InfoPopup"
+ "infopopup" : "cocoon.forms.InfoPopup",
+ "multivalueeditor" : "cocoon.forms.MultiValueEditor"
// register new Widgets in the cocoon.forms namespace here
},
svg: {