danielf 2004/02/17 01:54:40
Modified: src/blocks/woody/conf woody-binding.xconf
src/blocks/woody/java/org/apache/cocoon/woody/samples
Form2Bean.java
src/blocks/woody/samples/forms form2_bind_bean.xml
form2_bind_xml.xml form2_data.xml form2_model.xml
form2_template.xml
Added: src/blocks/woody/java/org/apache/cocoon/woody/binding
MultiValueJXPathBinding.java
MultiValueJXPathBindingBuilder.java
Log:
Binding for multi value fields. The binding is modeled after the
SimpleRepeaterJXPathBinding. The XML binding and bean binding samples
are updated to illustrate multi value fields. The bean binding only
works in the load direction though, a factory class must be written as
well.
Revision Changes Path
1.7 +1 -0 cocoon-2.1/src/blocks/woody/conf/woody-binding.xconf
Index: woody-binding.xconf
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/conf/woody-binding.xconf,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- woody-binding.xconf 29 Dec 2003 06:14:48 -0000 1.6
+++ woody-binding.xconf 17 Feb 2004 09:54:40 -0000 1.7
@@ -5,6 +5,7 @@
<woody-binding logger="woody.binding">
<bindings>
<binding name="value"
src="org.apache.cocoon.woody.binding.ValueJXPathBindingBuilder"/>
+ <binding name="multi-value"
src="org.apache.cocoon.woody.binding.MultiValueJXPathBindingBuilder"/>
<binding name="context"
src="org.apache.cocoon.woody.binding.ContextJXPathBindingBuilder"/>
<binding name="repeater"
src="org.apache.cocoon.woody.binding.RepeaterJXPathBindingBuilder"/>
<binding name="simple-repeater"
src="org.apache.cocoon.woody.binding.SimpleRepeaterJXPathBindingBuilder"/>
1.1
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/MultiValueJXPathBinding.java
Index: MultiValueJXPathBinding.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.woody.binding;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import org.apache.avalon.framework.logger.Logger;
import org.apache.cocoon.woody.datatype.convertor.Convertor;
import org.apache.cocoon.woody.formmodel.MultiValueField;
import org.apache.cocoon.woody.formmodel.Widget;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
/**
* Simple binding for multi fields: on save, first deletes the target data
* before recreating it from scratch.
*
* @version CVS $Id: MultiValueJXPathBinding.java,v 1.1 2004/02/17 09:54:40
danielf Exp $
*/
public class MultiValueJXPathBinding extends JXPathBindingBase {
private final String multiValueId;
private final String multiValuePath;
private final String rowPath;
private final JXPathBindingBase updateBinding;
private final Convertor convertor;
private final Locale convertorLocale;
public MultiValueJXPathBinding(
JXPathBindingBuilderBase.CommonAttributes commonAtts, String
multiValueId,
String multiValuePath, String rowPath,
JXPathBindingBase[] updateBindings, Convertor convertor, Locale
convertorLocale) {
super(commonAtts);
this.multiValueId = multiValueId;
this.multiValuePath = multiValuePath;
this.rowPath = rowPath;
this.updateBinding = new
ComposedJXPathBindingBase(JXPathBindingBuilderBase.CommonAttributes.DEFAULT,
updateBindings);
this.convertor = convertor;
this.convertorLocale = convertorLocale;
}
public void doLoad(Widget frmModel, JXPathContext jctx) throws
BindingException {
Widget widget = frmModel.getWidget(this.multiValueId);
if (widget == null) {
throw new BindingException("The widget with the ID [" +
this.multiValueId
+ "] referenced in the binding does not exist in the form
definition.");
}
// Move to multi value context
Pointer ptr = jctx.getPointer(this.multiValuePath);
if (ptr.getNode() != null) {
// There are some nodes to load from
JXPathContext multiValueContext = jctx.getRelativeContext(ptr);
// build a jxpath iterator for pointers
Iterator rowPointers = multiValueContext.iterate(this.rowPath);
LinkedList list = new LinkedList();
while (rowPointers.hasNext()) {
Object value = rowPointers.next();
if (value != null && convertor != null) {
if (value instanceof String) {
value = convertor.convertFromString((String)value,
convertorLocale, null);
} else {
getLogger().warn("Convertor ignored on backend-value
which isn't of type String.");
}
}
list.add(value);
}
widget.setValue(list.toArray());
}
if (getLogger().isDebugEnabled())
getLogger().debug("done loading values " + toString());
}
public void doSave(Widget frmModel, JXPathContext jctx) throws
BindingException {
Widget widget = frmModel.getWidget(this.multiValueId);
Object[] values = (Object[])widget.getValue();
JXPathContext multiValueContext =
jctx.getRelativeContext(jctx.createPath(this.multiValuePath));
// Delete all that is already present
multiValueContext.removeAll(this.rowPath);
boolean update = false;
if (values != null) {
// first update the values
for (int i = 0; i < values.length; i++) {
String path = this.rowPath + '[' + (i+1) + ']';
Pointer rowPtr = multiValueContext.createPath(path);
Object value = values[i];
if (value != null && convertor != null) {
value = convertor.convertToString(value, convertorLocale,
null);
}
rowPtr.setValue(value);
}
// now perform any other bindings that need to be performed when
the value is updated
JXPathContext subContext = null;
this.updateBinding.saveFormToModel(frmModel, multiValueContext);
update = true;
}
if (getLogger().isDebugEnabled()) {
getLogger().debug("done saving " + toString() + " -- on-update ==
" + update);
}
}
public String toString() {
return "MultiValueJXPathBinding [widget=" + this.multiValueId + ",
xpath=" + this.multiValuePath + "]";
}
public void enableLogging(Logger logger) {
super.enableLogging(logger);
this.updateBinding.enableLogging(logger);
}
}
1.1
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/MultiValueJXPathBindingBuilder.java
Index: MultiValueJXPathBindingBuilder.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.woody.binding;
import java.util.Locale;
import org.apache.cocoon.woody.Constants;
import org.apache.cocoon.woody.util.DomHelper;
import org.apache.cocoon.woody.datatype.convertor.Convertor;
import org.apache.cocoon.i18n.I18nUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Element;
/**
* A simple multi field binding that will replace (i.e. delete then re-add
all) its
* content.
* <pre><code>
* <wb:multi-value id="<i>widget-id</i>"
* parent-path="<i>xpath-expression</i>">
* row-path="<i>xpath-expression</i>">
* <!-- optional child binding to be executed upon 'save' of changed
value -->
* <wb:on-update>
* <!-- any childbinding -->
* </wb:on-update>
* </wb:multi-value>
* </code></pre>
*
* @version CVS $Id: MultiValueJXPathBindingBuilder.java,v 1.1 2004/02/17
09:54:40 danielf Exp $
*/
public class MultiValueJXPathBindingBuilder
extends JXPathBindingBuilderBase {
public JXPathBindingBase buildBinding(
Element bindingElem,
JXPathBindingManager.Assistant assistant) throws BindingException {
try {
CommonAttributes commonAtts =
JXPathBindingBuilderBase.getCommonAttributes(bindingElem);
String multiValueId = DomHelper.getAttribute(bindingElem, "id");
String parentPath = DomHelper.getAttribute(bindingElem,
"parent-path");
String rowPath = DomHelper.getAttribute(bindingElem, "row-path");
Element updateWrapElement =
DomHelper.getChildElement(bindingElem,
BindingManager.NAMESPACE, "on-update");
JXPathBindingBase[] updateBindings =
assistant.makeChildBindings(updateWrapElement);
Convertor convertor = null;
Locale convertorLocale = Locale.US;
Element convertorEl = DomHelper.getChildElement(bindingElem,
Constants.WD_NS, "convertor");
if (convertorEl != null) {
String datatype = DomHelper.getAttribute(convertorEl,
"datatype");
String localeStr = convertorEl.getAttribute("datatype");
if (!localeStr.equals("")) {
convertorLocale = I18nUtils.parseLocale(localeStr);
}
convertor =
assistant.getDatatypeManager().createConvertor(datatype, convertorEl);
}
return new MultiValueJXPathBinding( commonAtts, multiValueId,
parentPath, rowPath,
updateBindings, convertor,
convertorLocale);
} catch (BindingException e) {
throw e;
} catch (Exception e) {
throw new BindingException("Error building multi value binding
defined at " + DomHelper.getLocation(bindingElem), e);
}
}
}
1.6 +14 -1
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/samples/Form2Bean.java
Index: Form2Bean.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/samples/Form2Bean.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Form2Bean.java 11 Feb 2004 10:43:32 -0000 1.5
+++ Form2Bean.java 17 Feb 2004 09:54:40 -0000 1.6
@@ -73,6 +73,7 @@
private Sex sex;
private Collection contacts = new ArrayList();
+ private Collection drinks = new ArrayList();
/**
* @return Returns the sex.
@@ -153,6 +154,18 @@
public void setChoose(boolean choose) {
this.choose = choose;
+ }
+
+ public Collection getDrinks() {
+ return drinks;
+ }
+
+ public void setDrinks(Collection drinks) {
+ this.drinks = drinks;
+ }
+
+ public void addDrink(String drink) {
+ drinks.add(drink);
}
public Collection getContacts() {
1.8 +2 -0
cocoon-2.1/src/blocks/woody/samples/forms/form2_bind_bean.xml
Index: form2_bind_bean.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form2_bind_bean.xml,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- form2_bind_bean.xml 18 Dec 2003 07:43:16 -0000 1.7
+++ form2_bind_bean.xml 17 Feb 2004 09:54:40 -0000 1.8
@@ -29,6 +29,8 @@
<wb:value id="cntr" path="phoneCountry"/>
</wb:aggregate>
+ <wb:multi-value id="drinks" parent-path="." row-path="drinks"
direction="load"/>
+
<!-- repeater requires unique identification mechanism of the row-nodes -->
<!-- (it is of course possible to implement other binding strategies) -->
<wb:repeater id="contacts"
1.8 +14 -13
cocoon-2.1/src/blocks/woody/samples/forms/form2_bind_xml.xml
Index: form2_bind_xml.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form2_bind_xml.xml,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- form2_bind_xml.xml 15 Jan 2004 00:21:26 -0000 1.7
+++ form2_bind_xml.xml 17 Feb 2004 09:54:40 -0000 1.8
@@ -5,15 +5,15 @@
| - and form_model file
-->
<wb:context
- xmlns:wb="http://apache.org/cocoon/woody/binding/1.0"
- xmlns:wd="http://apache.org/cocoon/woody/definition/1.0"
- path="/data/wrapper/context" >
+ xmlns:wb="http://apache.org/cocoon/woody/binding/1.0"
+ xmlns:wd="http://apache.org/cocoon/woody/definition/1.0"
+ path="/data/wrapper/context" >
<wb:context path="info">
- <!-- the email value will not be saved because of the @direction="load"
-->
+ <!-- the email value will not be saved because of the @direction="load"
-->
<wb:value id="email" path="email" direction="load"/>
- <!-- jxpath binds to nodes as well as to attributes -->
+ <!-- jxpath binds to nodes as well as to attributes -->
<wb:value id="number" path="number/@value">
<!-- for non-string datatypes, a convertor must be specified. These are
the same convertors as can be used in form definitions, but require an
@@ -25,9 +25,9 @@
<wd:convertor datatype="boolean"/>
</wb:value>
- <!-- one entry field in the client maps through aggregate fields -->
+ <!-- one entry field in the client maps through aggregate fields -->
<wb:aggregate id="phone" path="phone" >
- <!-- to multiple fields in the XML file -->
+ <!-- to multiple fields in the XML file -->
<wb:value id="number" path="number" />
<wb:value id="zone" path="zone" />
<wb:value id="cntr" path="@cntr" />
@@ -38,7 +38,7 @@
<wb:value id="ipaddress" path="ipaddress">
<wb:on-update>
- <!-- if the value has changed, the attribute will be set -->
+ <!-- if the value has changed, the attribute will be set -->
<wb:set-attribute name="changed" value="true"/>
</wb:on-update>
</wb:value>
@@ -51,6 +51,7 @@
</wd:convertor>
</wb:value>
+ <wb:multi-value id="drinks" parent-path="drinks" row-path="drink"/>
<!-- repeater requires unique identification mechanism of the row-nodes -->
<wb:repeater id="contacts"
@@ -67,7 +68,7 @@
as a consequence it cannot have dependent children or predicates -->
<wb:on-bind>
- <!-- executed on updates AND right after the insert -->
+ <!-- executed on updates AND right after the insert -->
<wb:value id="firstname" path="firstname" />
<wb:value id="lastname" path="lastname" />
<wb:value id="phone" path="phone/@nr" />
@@ -75,8 +76,8 @@
</wb:on-bind>
<wb:on-delete-row>
- <!-- chose on of these to test -->
- <!--
+ <!-- chose on of these to test -->
+ <!--
<wb:set-attribute name="row-state" value="deleted" />
-->
<wb:delete-node />
@@ -88,10 +89,10 @@
attribute on the insert-node element pointing to an external source
to retrieve the template from. -->
<wb:insert-node>
- <!-- template inserted by the binding for new rows (mapping new
nodes) -->
+ <!-- template inserted by the binding for new rows (mapping new
nodes) -->
<contact id="" row-state="new">
<firstname/><lastname/><phone nr=""/><email/>
- </contact>
+ </contact>
</wb:insert-node>
</wb:on-insert-row>
</wb:repeater>
1.4 +39 -30 cocoon-2.1/src/blocks/woody/samples/forms/form2_data.xml
Index: form2_data.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form2_data.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- form2_data.xml 12 Aug 2003 12:59:10 -0000 1.3
+++ form2_data.xml 17 Feb 2004 09:54:40 -0000 1.4
@@ -1,34 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
-<data><wrapper><context>
+<data>
+ <wrapper>
+ <context>
- <info>
- <email boolBindingWorks="false">[EMAIL PROTECTED]</email>
- <number value="3"/>
- <choose value="true"/>
-
- <phone cntr="32">
- <zone>2</zone>
- <number>2222222</number>
- </phone>
- </info>
-
- <ipaddress changed="false">10.34.44.78</ipaddress>
- <birthday>1960-04-10</birthday>
+ <info>
+ <email boolBindingWorks="false">[EMAIL PROTECTED]</email>
+ <number value="3"/>
+ <choose value="true"/>
+
+ <phone cntr="32">
+ <zone>2</zone>
+ <number>2222222</number>
+ </phone>
+ </info>
+
+ <ipaddress changed="false">10.34.44.78</ipaddress>
+ <birthday>1960-04-10</birthday>
+
+ <drinks>
+ <drink>Jupiler</drink>
+ <drink>Hoegaarden</drink>
+ </drinks>
- <contacts>
- <contact id="1" row-state="original">
- <firstname>Lucien</firstname>
- <lastname>Vandevelde</lastname>
- <phone nr="+32-2-2222222"/>
- <email>[EMAIL PROTECTED]</email>
- </contact>
- <contact id="2" row-state="original">
- <firstname>Joris</firstname>
- <lastname>Veldweghel</lastname>
- <phone nr="+32-59-595959"/>
- <email>[EMAIL PROTECTED]</email>
- </contact>
- </contacts>
-
-</context></wrapper></data>
+ <contacts>
+ <contact id="1" row-state="original">
+ <firstname>Lucien</firstname>
+ <lastname>Vandevelde</lastname>
+ <phone nr="+32-2-2222222"/>
+ <email>[EMAIL PROTECTED]</email>
+ </contact>
+ <contact id="2" row-state="original">
+ <firstname>Joris</firstname>
+ <lastname>Veldweghel</lastname>
+ <phone nr="+32-59-595959"/>
+ <email>[EMAIL PROTECTED]</email>
+ </contact>
+ </contacts>
+
+ </context>
+ </wrapper>
+</data>
1.13 +17 -2 cocoon-2.1/src/blocks/woody/samples/forms/form2_model.xml
Index: form2_model.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form2_model.xml,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- form2_model.xml 5 Jan 2004 15:18:32 -0000 1.12
+++ form2_model.xml 17 Feb 2004 09:54:40 -0000 1.13
@@ -82,13 +82,28 @@
<wd:field id="sex">
<wd:label>Sex</wd:label>
<wd:datatype base="enum">
- <wd:convertor type="enum">
+ <wd:convertor type="enum">
<wd:enum>org.apache.cocoon.woody.samples.Sex</wd:enum>
- </wd:convertor>
+ </wd:convertor>
</wd:datatype>
<wd:selection-list type="enum"
class="org.apache.cocoon.woody.samples.Sex"/>
</wd:field>
+ <wd:multivaluefield id="drinks">
+ <wd:label>Indicate which 2 of the following drinks you'd like to
receive:</wd:label>
+ <wd:datatype base="string"/>
+ <wd:validation>
+ <wd:value-count exact="2"/>
+ </wd:validation>
+ <wd:selection-list>
+ <wd:item value="Maes"/>
+ <wd:item value="Jupiler"/>
+ <wd:item value="Leffe"/>
+ <wd:item value="Hoegaarden"/>
+ <wd:item value="Coca Cola"/>
+ </wd:selection-list>
+ </wd:multivaluefield>
+
<wd:repeater id="contacts">
<wd:widgets>
<wd:output id="id">
1.5 +11 -3
cocoon-2.1/src/blocks/woody/samples/forms/form2_template.xml
Index: form2_template.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form2_template.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- form2_template.xml 6 Nov 2003 22:58:36 -0000 1.4
+++ form2_template.xml 17 Feb 2004 09:54:40 -0000 1.5
@@ -1,5 +1,6 @@
<?xml version="1.0"?>
-<page xmlns:wt="http://apache.org/cocoon/woody/template/1.0">
+<page xmlns:wt="http://apache.org/cocoon/woody/template/1.0"
+ xmlns:wi="http://apache.org/cocoon/woody/instance/1.0">
<title>Sample form</title>
<content>
<p>This form is used to illustrate the Woody binding framework. The
binding
@@ -9,8 +10,7 @@
<li>the email address is marked in the binding as "read-only", meaning
it
will only be bound from bean/xml to form, but not in the other
direction. So you won't see it changed in the bean or the XML.</li>
- <li>The binding doesn't support all widget types yet (e.g. the
- multivaluefield is currently not yet supported).</li>
+ <li>The binding doesn't support all widget types yet.</li>
<li>Note how, in the XML binding, the date is formatted according XML
Schema date format in the XML, while it is displayed in another
format
to the user, and is stored in the form model as a Java Date
@@ -50,6 +50,14 @@
<tr>
<td valign="top"><wt:widget-label id="sex"/></td>
<td valign="top"><wt:widget id="sex"/></td>
+ </tr>
+ <tr>
+ <td valign="top"><wt:widget-label id="drinks"/></td>
+ <td valign="top">
+ <wt:widget id="drinks">
+ <wi:styling list-type="listbox" listbox-size="4"/>
+ </wt:widget>
+ </td>
</tr>
</table>