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 2005/10/20 15:04:03 UTC

svn commit: r326897 - in /cocoon/blocks/forms/trunk: java/org/apache/cocoon/forms/formmodel/ java/org/apache/cocoon/forms/resources/ java/org/apache/cocoon/forms/resources/js/ samples/forms/

Author: bruno
Date: Thu Oct 20 06:03:52 2005
New Revision: 326897

URL: http://svn.apache.org/viewcvs?rev=326897&view=rev
Log:
Removed the restriction that multivalue fields cannot have a selection list
+ added a rendering for multivalue fields that do not have a selection list
+ added a sample of this.

Modified:
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueField.java
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueFieldDefinition.java
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-page-styling.xsl
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/forms-lib.js
    cocoon/blocks/forms/trunk/samples/forms/form1.xml
    cocoon/blocks/forms/trunk/samples/forms/form1_template.xml
    cocoon/blocks/forms/trunk/samples/forms/form1_template_action.xml
    cocoon/blocks/forms/trunk/samples/forms/form1_template_action_jx-macro.xml

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueField.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueField.java?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueField.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueField.java Thu Oct 20 06:03:52 2005
@@ -161,8 +161,9 @@
         }
         contentHandler.endElement(FormsConstants.INSTANCE_NS, VALUES_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUES_EL);
 
-        // the selection list (a MultiValueField has per definition always a SelectionList)
-        this.selectionList.generateSaxFragment(contentHandler, locale);
+        // the selection list
+        if (this.selectionList != null)
+            this.selectionList.generateSaxFragment(contentHandler, locale);
 
         // validation message element
         if (validationError != null) {

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueFieldDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueFieldDefinition.java?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueFieldDefinition.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/MultiValueFieldDefinition.java Thu Oct 20 06:03:52 2005
@@ -31,9 +31,6 @@
      */
     public void checkCompleteness() throws IncompletenessException {
     	super.checkCompleteness();
-    	
-    	if (getSelectionList() == null)
-            throw new IncompletenessException("Error: multivaluefield always require a selectionlist!", this);
     }
     
 	public void setRequired(boolean required) {

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl Thu Oct 20 06:03:52 2005
@@ -179,4 +179,51 @@
 
   <xsl:template match="fi:multivaluefield/fi:styling[@list-type='double-listbox']/@submit-on-change" mode="styling"/>
 
+  <!--+
+      | fi:multivaluefield without a selection list
+      +-->
+  <xsl:template match="fi:multivaluefield[not(fi:selection-list)]">
+    <xsl:variable name="id" select="@id"/>
+    <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>
+          </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>&#160;</xsl:text>
+            <input type="image" id="{$id}.delete" src="{$resources-uri}/forms/img/delete.gif"/>
+            <xsl:text>&#160;</xsl:text>
+            <br/>
+            <xsl:text>&#160;</xsl:text>
+            <input type="image" id="{$id}.up" src="{$resources-uri}/forms/img/move_up.gif"/>
+            <xsl:text>&#160;</xsl:text>
+            <br/>
+            <xsl:text>&#160;</xsl:text>
+            <input type="image" id="{$id}.down" src="{$resources-uri}/forms/img/move_down.gif"/>
+            <xsl:text>&#160;</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>
+
 </xsl:stylesheet>

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-page-styling.xsl
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-page-styling.xsl?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-page-styling.xsl (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-page-styling.xsl Thu Oct 20 06:03:52 2005
@@ -342,7 +342,7 @@
   </xsl:template>
 
   <!-- double-list multivaluefield : lists under the label -->
-  <xsl:template match="fi:multivaluefield[fi:styling/@list-type='double-listbox']"
+  <xsl:template match="fi:multivaluefield[fi:styling/@list-type='double-listbox' or not(fi:selection-list)]"
                 mode="group-columns-content">
     <tr>
       <td colspan="2"><xsl:apply-templates select="." mode="label"/></td>

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/forms-lib.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/forms-lib.js?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/forms-lib.js (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/forms-lib.js Thu Oct 20 06:03:52 2005
@@ -201,3 +201,159 @@
         }
     }
 }
+
+/**
+ * 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();
+    }
+    forms_onsubmitHandlers.push(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;
+    }
+}
+

Modified: cocoon/blocks/forms/trunk/samples/forms/form1.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/form1.xml?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/form1.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/form1.xml Thu Oct 20 06:03:52 2005
@@ -149,6 +149,11 @@
       </fd:selection-list>
     </fd:multivaluefield>
   
+    <fd:multivaluefield id="freemv">
+      <fd:label>Here you can enter values freely:</fd:label>
+      <fd:datatype base="string"/>
+    </fd:multivaluefield>
+
     <fd:aggregatefield id="visa" required="true">
       <fd:label>Enter your (16-digit) visa number (without spaces)
         <br/>Your credit card will be billed.

Modified: cocoon/blocks/forms/trunk/samples/forms/form1_template.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/form1_template.xml?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/form1_template.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/form1_template.xml Thu Oct 20 06:03:52 2005
@@ -71,9 +71,20 @@
               <fi:label>Boolean fields</fi:label>
               <fi:items>
                 <ft:widget id="somebool"/>
+              </fi:items>
+            </fi:group>
+
+            <fi:group>
+              <fi:styling layout="columns"/>
+              <fi:label>Multivalue fields</fi:label>
+              <fi:items>
                 <ft:widget id="drinks">
-                  <fi:styling list-type="listbox" listbox-size="4"/>
+                  <fi:styling list-type="double-listbox">
+                    <fi:available-label>Available drinks</fi:available-label>
+                    <fi:selected-label>Your selection</fi:selected-label>
+                  </fi:styling>
                 </ft:widget>
+                <ft:widget id="freemv"/>
               </fi:items>
             </fi:group>
           </fi:items>

Modified: cocoon/blocks/forms/trunk/samples/forms/form1_template_action.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/form1_template_action.xml?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/form1_template_action.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/form1_template_action.xml Thu Oct 20 06:03:52 2005
@@ -67,12 +67,20 @@
               <fi:label>Boolean fields</fi:label>
               <fi:items>
                 <ft:widget id="somebool"/>
+              </fi:items>
+            </fi:group>
+
+            <fi:group>
+              <fi:styling layout="columns"/>
+              <fi:label>Multivalue fields</fi:label>
+              <fi:items>
                 <ft:widget id="drinks">
                   <fi:styling list-type="double-listbox">
                     <fi:available-label>Available drinks</fi:available-label>
                     <fi:selected-label>Your selection</fi:selected-label>
                   </fi:styling>
                 </ft:widget>
+                <ft:widget id="freemv"/>
               </fi:items>
             </fi:group>
           </fi:items>

Modified: cocoon/blocks/forms/trunk/samples/forms/form1_template_action_jx-macro.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/form1_template_action_jx-macro.xml?rev=326897&r1=326896&r2=326897&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/form1_template_action_jx-macro.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/form1_template_action_jx-macro.xml Thu Oct 20 06:03:52 2005
@@ -70,12 +70,20 @@
               <fi:label>Boolean fields</fi:label>
               <fi:items>
                 <ft:widget id="somebool"/>
+              </fi:items>
+            </fi:group>
+
+            <fi:group>
+              <fi:styling layout="columns"/>
+              <fi:label>Multivalue fields</fi:label>
+              <fi:items>
                 <ft:widget id="drinks">
                   <fi:styling list-type="double-listbox">
                     <fi:available-label>Available drinks</fi:available-label>
                     <fi:selected-label>Your selection</fi:selected-label>
                   </fi:styling>
                 </ft:widget>
+                <ft:widget id="freemv"/>
               </fi:items>
             </fi:group>
           </fi:items>