sylvain 2003/09/25 10:37:31
Modified: src/blocks/woody/java/org/apache/cocoon/woody/datatype
SelectionList.java StaticSelectionList.java
src/blocks/woody/java/org/apache/cocoon/woody/event
ValueChangedEvent.java
src/blocks/woody/java/org/apache/cocoon/woody/flow/javascript
woody2.js
src/blocks/woody/java/org/apache/cocoon/woody/formmodel
AbstractDatatypeWidgetDefinition.java
AbstractDatatypeWidgetDefinitionBuilder.java
AggregateField.java Field.java Form.java
src/blocks/woody/samples sitemap.xmap
src/blocks/woody/samples/flow binding_example.js
woody_flow_example.js
src/blocks/woody/samples/forms car-db.xml
carselector_form.xml carselector_success.xsp
carselector_template.xml form1.xml
form1_template_flow.xml
src/blocks/woody/samples/resources woody-field-styling.xsl
src/blocks/woody/samples/xsl carfilter.xsl
Log:
Bug fixes, improved samples, new Field.setSelectionList(uri)
Revision Changes Path
1.3 +4 -0
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/datatype/SelectionList.java
Index: SelectionList.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/datatype/SelectionList.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SelectionList.java 3 Sep 2003 12:26:23 -0000 1.2
+++ SelectionList.java 25 Sep 2003 17:37:30 -0000 1.3
@@ -60,6 +60,10 @@
*/
public interface SelectionList {
+ public static final String SELECTION_LIST_EL = "selection-list";
+ public static final String ITEM_EL = "item";
+ public static final String LABEL_EL = "label";
+
Datatype getDatatype();
void generateSaxFragment(ContentHandler contentHandler, Locale locale)
throws SAXException;
1.5 +0 -4
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/datatype/StaticSelectionList.java
Index: StaticSelectionList.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/datatype/StaticSelectionList.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- StaticSelectionList.java 26 Aug 2003 15:13:37 -0000 1.4
+++ StaticSelectionList.java 25 Sep 2003 17:37:30 -0000 1.5
@@ -76,10 +76,6 @@
private List items = new ArrayList();
private XMLByteStreamInterpreter interpreter = new
XMLByteStreamInterpreter();
- private static final String SELECTION_LIST_EL = "selection-list";
- private static final String ITEM_EL = "item";
- private static final String LABEL_EL = "label";
-
public StaticSelectionList(Datatype datatype) {
this.datatype = datatype;
}
1.2 +2 -0
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/event/ValueChangedEvent.java
Index: ValueChangedEvent.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/event/ValueChangedEvent.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ValueChangedEvent.java 24 Sep 2003 20:47:05 -0000 1.1
+++ ValueChangedEvent.java 25 Sep 2003 17:37:30 -0000 1.2
@@ -64,6 +64,8 @@
public ValueChangedEvent(Widget source, Object oldValue, Object
newValue) {
super(source);
+ this.oldValue = oldValue;
+ this.newValue = newValue;
}
public Object getOldValue() {
1.2 +2 -2
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/flow/javascript/woody2.js
Index: woody2.js
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/flow/javascript/woody2.js,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- woody2.js 24 Sep 2003 20:47:06 -0000 1.1
+++ woody2.js 25 Sep 2003 17:37:30 -0000 1.2
@@ -148,7 +148,7 @@
if (this.validator == null) {
this.isValid = true;
} else {
- this.isValid = validator(this.form, bizData);
+ this.isValid = this.validator(this.form, bizData);
finished = this.isValid;
}
}
1.3 +21 -2
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/AbstractDatatypeWidgetDefinition.java
Index: AbstractDatatypeWidgetDefinition.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/AbstractDatatypeWidgetDefinition.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractDatatypeWidgetDefinition.java 24 Sep 2003 20:47:06 -0000
1.2
+++ AbstractDatatypeWidgetDefinition.java 25 Sep 2003 17:37:30 -0000
1.3
@@ -50,20 +50,29 @@
*/
package org.apache.cocoon.woody.formmodel;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.woody.datatype.Datatype;
+import org.apache.cocoon.woody.datatype.DynamicSelectionList;
import org.apache.cocoon.woody.datatype.SelectionList;
-import org.apache.cocoon.woody.event.WidgetEventMulticaster;
import org.apache.cocoon.woody.event.ValueChangedEvent;
import org.apache.cocoon.woody.event.ValueChangedListener;
+import org.apache.cocoon.woody.event.WidgetEventMulticaster;
/**
* Base class for WidgetDefinitions that use a Datatype and SelectionList.
*/
-public abstract class AbstractDatatypeWidgetDefinition extends
AbstractWidgetDefinition {
+public abstract class AbstractDatatypeWidgetDefinition extends
AbstractWidgetDefinition implements Serviceable {
private Datatype datatype;
private SelectionList selectionList;
private ValueChangedListener listener;
+ private ServiceManager manager;
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ }
+
public Datatype getDatatype() {
return datatype;
}
@@ -82,6 +91,15 @@
return selectionList;
}
+ /**
+ * Builds a dynamic selection list from a url. This is a helper method
for widget instances whose selection
+ * list source has to be changed dynamically, and it does not modify
this definition's selection list,
+ * if any.
+ */
+ public SelectionList buildSelectionList(String uri) {
+ return new DynamicSelectionList(datatype, uri, this.manager);
+ }
+
public void addValueChangedListener(ValueChangedListener listener) {
this.listener = WidgetEventMulticaster.add(this.listener, listener);
}
@@ -95,4 +113,5 @@
public boolean hasValueChangedListeners() {
return this.listener != null;
}
+
}
1.3 +4 -0
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/AbstractDatatypeWidgetDefinitionBuilder.java
Index: AbstractDatatypeWidgetDefinitionBuilder.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/AbstractDatatypeWidgetDefinitionBuilder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractDatatypeWidgetDefinitionBuilder.java 24 Sep 2003 20:47:06
-0000 1.2
+++ AbstractDatatypeWidgetDefinitionBuilder.java 25 Sep 2003 17:37:30
-0000 1.3
@@ -70,6 +70,10 @@
* @return true if a selectionlist has actually been build.
*/
protected boolean buildSelectionList(Element widgetElement,
AbstractDatatypeWidgetDefinition widget) throws Exception {
+ // FIXME: pass the manager to the definition as a side effect.
Should be removed
+ // when definition are managed like components.
+ widget.service(this.serviceManager);
+
Element selectionListElement =
DomHelper.getChildElement(widgetElement, Constants.WD_NS, "selection-list");
if (selectionListElement != null) {
SelectionList selectionList;
1.7 +1 -0
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/AggregateField.java
Index: AggregateField.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/AggregateField.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- AggregateField.java 24 Sep 2003 20:47:06 -0000 1.6
+++ AggregateField.java 25 Sep 2003 17:37:30 -0000 1.7
@@ -96,6 +96,7 @@
protected void addField(Field field) {
fields.add(field);
+ field.setParent(this);
fieldsById.put(field.getId(), field);
}
1.11 +19 -5
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/Field.java
Index: Field.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/Field.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Field.java 24 Sep 2003 20:47:06 -0000 1.10
+++ Field.java 25 Sep 2003 17:37:30 -0000 1.11
@@ -164,8 +164,12 @@
"\" (expected " + definition.getDatatype().getTypeClass() +
", got " + newValue.getClass() + ".");
Object oldValue = this.value;
- // Do something only if value is different
- if (! (oldValue == null ? "" : oldValue).equals(newValue == null ?
"" : newValue) ) {
+
+ boolean changed = ! (oldValue == null ? "" :
oldValue).equals(newValue == null ? "" : newValue);
+
+ // Do something only if value is different or null
+ // (null allows to reset validation error)
+ if (changed || newValue == null) {
this.value = newValue;
@@ -176,7 +180,9 @@
this.enteredValue =
definition.getDatatype().convertToString(newValue, getForm().getLocale());
- getForm().addWidgetEvent(new ValueChangedEvent(this, oldValue,
newValue));
+ if (changed) {
+ getForm().addWidgetEvent(new ValueChangedEvent(this,
oldValue, newValue));
+ }
}
}
@@ -287,9 +293,17 @@
}
public void setSelectionList(SelectionList selectionList) {
- if (selectionList != null && selectionList.getDatatype() !=
definition.getDatatype())
+ if (selectionList != null &&
+ selectionList.getDatatype() != null &&
+ selectionList.getDatatype() != definition.getDatatype()) {
+
throw new RuntimeException("Tried to assign a SelectionList that
is not associated with this widget's datatype.");
+ }
this.selectionList = selectionList;
+ }
+
+ public void setSelectionList(String uri) {
+ setSelectionList(this.definition.buildSelectionList(uri));
}
public Datatype getDatatype() {
1.9 +4 -4
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/Form.java
Index: Form.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/formmodel/Form.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Form.java 24 Sep 2003 20:47:06 -0000 1.8
+++ Form.java 25 Sep 2003 17:37:30 -0000 1.9
@@ -166,6 +166,9 @@
if (this.submitWidget != null && this.submitWidget != widget) {
throw new IllegalStateException("SubmitWidget can only be set
once.");
}
+ if (!(widget instanceof Action)) {
+ endProcessing(true);
+ }
this.submitWidget = widget;
}
@@ -248,9 +251,6 @@
}
setSubmitWidget(submit);
- if (!(submit instanceof Action)) {
- endProcessing(true);
- }
}
doReadFromRequest(formContext);
1.18 +35 -11 cocoon-2.1/src/blocks/woody/samples/sitemap.xmap
Index: sitemap.xmap
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/samples/sitemap.xmap,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- sitemap.xmap 24 Sep 2003 20:47:07 -0000 1.17
+++ sitemap.xmap 25 Sep 2003 17:37:30 -0000 1.18
@@ -286,7 +286,7 @@
<map:match pattern="cars">
<map:generate src="forms/car-db.xml"/>
<map:transform src="xsl/carfilter.xsl">
- <map:parameter name="type" value="makes"/>
+ <map:parameter name="list" value="makes"/>
</map:transform>
<map:serialize type="xml"/>
</map:match>
@@ -294,22 +294,34 @@
<map:match pattern="cars/*">
<map:generate src="forms/car-db.xml"/>
<map:transform src="xsl/carfilter.xsl">
- <map:parameter name="type" value="models"/>
+ <map:parameter name="list" value="types"/>
<map:parameter name="make" value="{1}"/>
</map:transform>
<map:serialize type="xml"/>
</map:match>
+
+ <map:match pattern="cars/*/*">
+ <map:generate src="forms/car-db.xml"/>
+ <map:transform src="xsl/carfilter.xsl">
+ <map:parameter name="list" value="models"/>
+ <map:parameter name="make" value="{1}"/>
+ <map:parameter name="type" value="{2}"/>
+ </map:transform>
+ <map:serialize type="xml"/>
+ </map:match>
<map:match pattern="carselector">
<map:select type="request-method">
<map:when test="GET">
- <map:act type="woody-make-form">
+ <map:call function="selectCar"/>
+ <!--map:act type="woody-make-form">
<map:parameter name="form-definition"
value="forms/carselector_form.xml"/>
<map:parameter name="attribute-name" value="carselectorform"/>
- </map:act>
+ </map:act-->
</map:when>
<map:when test="POST">
- <map:act type="woody-handle-form-submit">
+ <map:call continuation="{request-param:continuation-id}"/>
+ <!--map:act type="woody-handle-form-submit">
<map:parameter name="form-definition"
value="forms/carselector_form.xml"/>
<map:parameter name="attribute-name" value="carselectorform"/>
<map:parameter name="formhandler"
value="org.apache.cocoon.woody.samples.CarSelectorHandler"/>
@@ -323,21 +335,33 @@
<map:parameter name="remove" value="{../0}"/>
</map:transform>
<map:serialize/>
- </map:act>
+ </map:act-->
</map:when>
<map:otherwise>
<!-- todo: do something here -->
</map:otherwise>
</map:select>
-
+ </map:match>
+
+ <map:match pattern="carselector-view">
<map:generate src="forms/carselector_template.xml"/>
- <map:transform type="woody">
- <map:parameter name="attribute-name" value="carselectorform"/>
- </map:transform>
+ <map:transform type="woody"/>
<map:transform type="i18n">
<map:parameter name="locale" value="en-US"/>
</map:transform>
- <map:transform src="xsl/html/woody-default.xsl"/>
+ <map:transform
src="context://samples/common/style/xsl/html/simple-page2html.xsl">
+ <map:parameter name="contextPath" value="{request:contextPath}"/>
+ <map:parameter name="servletPath" value="{request:servletPath}"/>
+ <map:parameter name="sitemapURI" value="{request:sitemapURI}"/>
+ <map:parameter name="file" value="forms/registration_success.xsp"/>
+ <map:parameter name="remove" value="{0}"/>
+ </map:transform>
+ <map:transform src="resources/woody-samples-styling.xsl"/>
+ <map:serialize/>
+ </map:match>
+
+ <map:match pattern="carselector-success">
+ <map:generate type="serverpages" src="forms/carselector_success.xsp"/>
<map:transform
src="context://samples/common/style/xsl/html/simple-page2html.xsl">
<map:parameter name="contextPath" value="{request:contextPath}"/>
<map:parameter name="servletPath" value="{request:servletPath}"/>
1.10 +0 -1
cocoon-2.1/src/blocks/woody/samples/flow/binding_example.js
Index: binding_example.js
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/flow/binding_example.js,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- binding_example.js 24 Sep 2003 20:47:07 -0000 1.9
+++ binding_example.js 25 Sep 2003 17:37:30 -0000 1.10
@@ -101,7 +101,6 @@
form.save(bean);
cocoon.sendPage("form2bean-success-pipeline", { "form2bean": bean });
- form.finish();
}
/**
1.6 +10 -0
cocoon-2.1/src/blocks/woody/samples/flow/woody_flow_example.js
Index: woody_flow_example.js
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/flow/woody_flow_example.js,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- woody_flow_example.js 24 Sep 2003 20:47:07 -0000 1.5
+++ woody_flow_example.js 25 Sep 2003 17:37:30 -0000 1.6
@@ -24,7 +24,17 @@
} else {
print("Form is not valid");
}
+ // Store the form as a request attribute, as the view is not
+ // flow-aware.
+ cocoon.request.setAttribute("form1", form.getWidget());
cocoon.sendPage("form1-success-pipeline");
+}
+
+function selectCar() {
+ var form = new Form("forms/carselector_form.xml");
+ form.showForm("carselector-view");
+ cocoon.request.setAttribute("carselectorform", form.getWidget());
+ cocoon.sendPage("carselector-success");
}
function determineLocale() {
1.2 +61 -15 cocoon-2.1/src/blocks/woody/samples/forms/car-db.xml
Index: car-db.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/car-db.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- car-db.xml 28 Jul 2003 16:00:28 -0000 1.1
+++ car-db.xml 25 Sep 2003 17:37:30 -0000 1.2
@@ -1,26 +1,72 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<cars>
+ <!-- Enhancements to this list are welcome !
+ Types with no models will automatically be filled with dumb values.
-->
+
<make name="Audi">
- <model name="A2"/>
- <model name="A3"/>
- <model name="A4"/>
- <model name="A6"/>
- <model name="A8"/>
- <model name="TT"/>
- <model name="Cabriolet"/>
+ <!-- found on http://www.audi.fr/ -->
+ <type name="A2">
+ <model name="1.4 75"/>
+ <model name="1.4 TDI"/>
+ <model name="1.4 75 Pack"/>
+ <model name="1.4 TDI Pack"/>
+ <model name="1.6 FSI 110 Pack"/>
+ <model name="1.4 75 Pack Plus"/>
+ <model name="1.6 FSI 110 Pack Plus"/>
+ </type>
+ <type name="A3">
+ <model name="1.6 Attration 102"/>
+ <model name="2.0 FSI Attractin 150"/>
+ <model name="1.6 Ambiente 102"/>
+ <model name="2.0 FSI Ambiente 150"/>
+ <model name="2.0 FSI Ambiente 150 tiptronic"/>
+ <model name="1.6 Ambition 102"/>
+ <model name="2.0 FSI Ambition 150"/>
+ <model name="2.0 FSI Ambition 150 tiptronic"/>
+ <model name="2.0 FSI Ambition Luxe 150"/>
+ </type>
+ <type name="A4">
+ <model name="Berline 1.9 TDI 101"/>
+ <model name="Berline 2.5 TDI 163"/>
+ <model name="Berline 2.5 TDI 163 multitronic"/>
+ <model name="Berline 2.5 TDI 180 quattro"/>
+ <model name="Berline 2.5 TDI 180 quattro tiptronic"/>
+ <model name="Avant 1.9 TDI 101"/>
+ <model name="Avant 1.9 TDI 130"/>
+ <model name="Avant 2.5 TDI 163"/>
+ <model name="Avant 2.5 TDI 163 multitronic"/>
+ <model name="Avant 2.5 TDI 180 quattro"/>
+ <model name="Avant 2.5 TDI 180 tiptronic quattro"/>
+ </type>
+ <type name="A6">
+ </type>
+ <type name="A8">
+ </type>
+ <type name="TT">
+ </type>
+ <type name="Allroad Quattro">
+ </type>
</make>
<make name="Volkswagen">
- <model name="Golf"/>
- <model name="Passat"/>
- <model name="Bora"/>
+ <type name="Golf">
+ </type>
+ <type name="Passat">
+ </type>
+ <type name="Bora">
+ </type>
</make>
<make name="Mercedes">
- <model name="CLK"/>
- <model name="SLK"/>
+ <type name="CLK">
+ </type>
+ <type name="SLK">
+ </type>
</make>
<make name="Renault">
- <model name="Twingo"/>
- <model name="Senic"/>
- <model name="Espace"/>
+ <type name="Twingo">
+ </type>
+ <type name="Scenic">
+ </type>
+ <type name="Espace">
+ </type>
</make>
</cars>
1.3 +89 -3
cocoon-2.1/src/blocks/woody/samples/forms/carselector_form.xml
Index: carselector_form.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/carselector_form.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- carselector_form.xml 3 Sep 2003 08:21:52 -0000 1.2
+++ carselector_form.xml 25 Sep 2003 17:37:30 -0000 1.3
@@ -8,20 +8,106 @@
<wd:label>Make:</wd:label>
<wd:datatype base="string"/>
<wd:selection-list src="cocoon:/cars" dynamic="true"/>
+ <wd:on-value-changed>
+ <javascript>
+ java.lang.System.err.println("maker changed from " + event.oldValue
+ " to " + event.newValue);
+ var value = event.source.value;
+ var typewidget = event.source.parent.getWidget("type");
+ if (value != null) {
+ // Get the corresponding type list
+ typewidget.setSelectionList("cocoon:/cars/" + value);
+ } else {
+ // Reset the value (will clear validation error)
+ event.source.setValue(null);
+ // Set an empty selection list
+ typewidget.setSelectionList(new
Packages.org.apache.cocoon.woody.datatype.EmptySelectionList("Select a maker
first"));
+ }
+ // Always set the type value to null. Note that it will also fire an
event on the "type"
+ // widget if it already had a value.
+ typewidget.setValue(null);
+
+ // Fun with messages...
+ var msg = event.source.parent.getWidget("message");
+ if (value == null) {
+ msg.value = "Yep. Choosing a maker is not that easy...";
+ } else {
+ if (event.oldValue == null) {
+ msg.value = "Good. " + value + " makes good cars!";
+ } else {
+ msg.value = "Why not? " + value + " also makes good cars!";
+ }
+ }
+ </javascript>
+ </wd:on-value-changed>
</wd:field>
+ <wd:field id="type" required="true">
+ <wd:label>Type:</wd:label>
+ <wd:datatype base="string"/>
+ <wd:selection-list>
+ <wd:item value="">
+ <wd:label>Select a maker first</wd:label>
+ </wd:item>
+ </wd:selection-list>
+ <wd:on-value-changed>
+ <javascript>
+ java.lang.System.err.println("type changed to " +
event.source.value);
+ var value = event.source.value;
+ var modelwidget = event.source.parent.getWidget("model");
+ var makewidget = event.source.parent.getWidget("make");
+ if (value != null) {
+ modelwidget.setSelectionList("cocoon:/cars/" + makewidget.value +
"/" + value);
+ } else {
+ // Reset the value (will clear validation error)
+ event.source.setValue(null);
+ // Set an empty selection list
+ modelwidget.setSelectionList(new
Packages.org.apache.cocoon.woody.datatype.EmptySelectionList("Select a type
first"));
+ }
+
+ // Always set the model value to null. Note that it will also fire
an event on the "model"
+ // widget if it already had a value.
+ modelwidget.setValue(null);
+
+ // Fun with messages...
+ if (value != null) {
+ var msg = event.source.parent.getWidget("message");
+ if (event.oldValue == null) {
+ msg.value = "A " + makewidget.value + " " + value + " is a very
good choice.";
+ } else {
+ msg.value = "So you prefer a " + value + " ?";
+ }
+ }
+ </javascript>
+ </wd:on-value-changed>
+ </wd:field>
+
<wd:field id="model" required="true">
<wd:label>Model:</wd:label>
<wd:datatype base="string"/>
<wd:selection-list>
<wd:item value="">
- <wd:label>select a make first</wd:label>
+ <wd:label>Select a type first</wd:label>
</wd:item>
</wd:selection-list>
+ <wd:on-value-changed>
+ <javascript>
+ var value = event.source.value;
+ if (value != null) {
+ event.source.parent.getWidget("message").setValue("Model " + value
+ " is a great car!");
+ } else {
+ // Reset value
+ event.source.value = null;
+ }
+ </javascript>
+ </wd:on-value-changed>
</wd:field>
- <wd:action id="updatemodels" action-command="updatemodels">
+ <wd:output id="message">
+ <wd:datatype base="string"/>
+ </wd:output>
+
+ <!--wd:action id="updatemodels" action-command="updatemodels">
<wd:label>Update models</wd:label>
- </wd:action>
+ </wd:action-->
</wd:form>
1.2 +4 -1
cocoon-2.1/src/blocks/woody/samples/forms/carselector_success.xsp
Index: carselector_success.xsp
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/carselector_success.xsp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- carselector_success.xsp 28 Jul 2003 16:00:28 -0000 1.1
+++ carselector_success.xsp 25 Sep 2003 17:37:30 -0000 1.2
@@ -13,10 +13,13 @@
// get reference to form and some of the widgets on it
Form form = (Form)request.getAttribute("carselectorform");
Field make = (Field)form.getWidget("make");
+ Field type = (Field)form.getWidget("type");
Field model = (Field)form.getWidget("model");
</xsp:logic>
- You selected: <xsp:expr>make.getValue()</xsp:expr>
<xsp:expr>model.getValue()</xsp:expr>
+ You selected: maker <xsp:expr>make.getValue()</xsp:expr>,
+ type <xsp:expr>type.getValue()</xsp:expr>,
+ model <xsp:expr>model.getValue()</xsp:expr>
</content>
</page>
</xsp:page>
1.2 +37 -12
cocoon-2.1/src/blocks/woody/samples/forms/carselector_template.xml
Index: carselector_template.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/carselector_template.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- carselector_template.xml 28 Jul 2003 16:00:28 -0000 1.1
+++ carselector_template.xml 25 Sep 2003 17:37:30 -0000 1.2
@@ -1,32 +1,57 @@
<?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>Car selector</title>
<para>This example illustrates how you can programmatically update the
- content of a selection list. See the code in the "CarSelectorHandler"
class
- to see how this is done.</para>
- <para>After selecting a make, press the "Update models" button to see the
- corresponding models. It would be nice to do this with an automatic
submit
- when the make list changes, but no effort has been done yet in Woody to
- standarize Javascript-integration, so I've left that out for now.</para>
+ content of a selection list.</para>
+ <para>
+ This sample illustrates event-handling in Woody and how selection lists
can be changed
+ programmatically.
+ </para>
+ <para>
+ Event-handlers are defined in the form definition to update the
selection lists and set
+ the comment text below the table. This requires only a few lines of
server-side JavaScript.
+ Selection widgets also have a "submit-on-change" attribute set in the
form template so that
+ changes are considered immediately by the server.
+ </para>
+ <para>
+ See "carselector_form.xml" and "carselector_template.xml" to see how
this is done.
+ </para>
<content>
<wt:form-template action="carselector" method="POST">
+ <wt:continuation-id/>
<table border="1">
<tr>
<td valign="top"><wt:widget-label id="make"/></td>
- <td valign="top"><wt:widget id="make"/></td>
+ <td valign="top">
+ <wt:widget id="make">
+ <wi:styling submit-on-change="true"/>
+ </wt:widget>
+ </td>
</tr>
<tr>
- <td colspan="2">
- <wt:widget id="updatemodels"/>
+ <td valign="top"><wt:widget-label id="type"/></td>
+ <td valign="top">
+ <wt:widget id="type">
+ <wi:styling submit-on-change="true"/>
+ </wt:widget>
</td>
</tr>
<tr>
<td valign="top"><wt:widget-label id="model"/></td>
- <td valign="top"><wt:widget id="model"/></td>
+ <td valign="top">
+ <wt:widget id="model">
+ <wi:styling submit-on-change="true"/>
+ </wt:widget>
+ </td>
</tr>
</table>
- <input type="submit"/>
+ <br/>
+ <wt:widget id="message"/>
+ <br/>
+ <br/>
+
+ <input type="submit" value="Buy it!"/>
</wt:form-template>
</content>
</page>
1.14 +3 -2 cocoon-2.1/src/blocks/woody/samples/forms/form1.xml
Index: form1.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form1.xml,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- form1.xml 24 Sep 2003 20:47:07 -0000 1.13
+++ form1.xml 25 Sep 2003 17:37:30 -0000 1.14
@@ -59,7 +59,8 @@
</wd:field>
<wd:field id="number1" required="true">
- <wd:label>Please enter a number:</wd:label>
+ <wd:label>Please enter a number<br/>
+ <small>(will automatically set a correct value below if
needed)</small>:</wd:label>
<wd:datatype base="long"/>
<wd:on-value-changed>
<javascript>
@@ -105,7 +106,7 @@
<wd:aggregatefield id="visa" required="true">
<wd:label>Enter your (16-digit) visa number (without spaces)
<br/>Your credit card will be billed.
- <br/>Valid test number is: 4111111111111111</wd:label>
+ <br/><small>Valid test number is: 4111111111111111</small></wd:label>
<wd:split pattern="([0-9]{4})([0-9]{4})([0-9]{4})([0-9]{4})">
<wd:map group="1" field="part1"/>
<wd:map group="2" field="part2"/>
1.6 +3 -1
cocoon-2.1/src/blocks/woody/samples/forms/form1_template_flow.xml
Index: form1_template_flow.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form1_template_flow.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- form1_template_flow.xml 5 Sep 2003 17:11:49 -0000 1.5
+++ form1_template_flow.xml 25 Sep 2003 17:37:30 -0000 1.6
@@ -34,7 +34,9 @@
<wi:label>Number fields</wi:label>
<wi:styling layout="columns"/>
<wi:items>
- <wt:widget id="number1"/>
+ <wt:widget id="number1">
+ <wi:styling submit-on-change="true"/>
+ </wt:widget>
<wt:widget id="number2"/>
<wt:widget id="account"/>
<wt:widget id="cowheight">
1.2 +2 -2
cocoon-2.1/src/blocks/woody/samples/resources/woody-field-styling.xsl
Index: woody-field-styling.xsl
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/resources/woody-field-styling.xsl,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- woody-field-styling.xsl 24 Sep 2003 20:47:08 -0000 1.1
+++ woody-field-styling.xsl 25 Sep 2003 17:37:30 -0000 1.2
@@ -27,7 +27,7 @@
if (form == null) {
alert("Cannot find form for " + element);
} else {
- form["woody_submit_id"] = name;
+ form["woody_submit_id"].value = name;
form.submit();
}
}
@@ -146,7 +146,7 @@
<!--
wi:field with @type 'textarea'
-->
- <xsl:template match="wi:[EMAIL PROTECTED]'textarea']">
+ <xsl:template match="wi:field[wi:[EMAIL PROTECTED]'textarea']]">
<textarea name="[EMAIL PROTECTED]" title="{wi:help}">
<xsl:if test="wi:styling/@submit-on-change='true'">
<xsl:attribute name="onchange">woody_submitForm(this)</xsl:attribute>
1.2 +38 -5 cocoon-2.1/src/blocks/woody/samples/xsl/carfilter.xsl
Index: carfilter.xsl
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/samples/xsl/carfilter.xsl,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- carfilter.xsl 28 Jul 2003 16:01:26 -0000 1.1
+++ carfilter.xsl 25 Sep 2003 17:37:31 -0000 1.2
@@ -3,33 +3,66 @@
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="http://apache.org/cocoon/woody/definition/1.0">
- <xsl:param name="type"/>
+ <xsl:param name="list"/>
<xsl:param name="make"/>
+ <xsl:param name="type"/>
<xsl:template match="/">
<xsl:choose>
- <xsl:when test="$type = 'makes'">
+ <xsl:when test="$list = 'makes'">
<xsl:call-template name="makes-list"/>
</xsl:when>
+ <xsl:when test="$list = 'models'">
+ <xsl:call-template name="models-list"/>
+ </xsl:when>
<xsl:otherwise>
- <xsl:call-template name="model-list"/>
+ <xsl:call-template name="types-list"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="makes-list">
<wd:selection-list>
+ <wd:item value="">
+ <wd:label>-- Choose maker --</wd:label>
+ </wd:item>
<xsl:for-each select="cars/make">
<wd:item value="[EMAIL PROTECTED]"/>
</xsl:for-each>
</wd:selection-list>
</xsl:template>
- <xsl:template name="model-list">
+ <xsl:template name="types-list">
<wd:selection-list>
- <xsl:for-each select="cars/[EMAIL PROTECTED]/model">
+ <wd:item value="">
+ <wd:label>-- Choose type --</wd:label>
+ </wd:item>
+ <xsl:for-each select="cars/[EMAIL PROTECTED]/type">
<wd:item value="[EMAIL PROTECTED]"/>
</xsl:for-each>
+ </wd:selection-list>
+ </xsl:template>
+
+ <xsl:template name="models-list">
+ <wd:selection-list>
+ <wd:item value="">
+ <wd:label>-- Choose model --</wd:label>
+ </wd:item>
+ <xsl:choose>
+ <xsl:when test="cars/[EMAIL PROTECTED]/[EMAIL PROTECTED]/model">
+ <xsl:for-each select="cars/[EMAIL PROTECTED]/[EMAIL
PROTECTED]/model">
+ <wd:item value="[EMAIL PROTECTED]"/>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- dummy list -->
+ <wd:item value="{$type} model 1"/>
+ <wd:item value="{$type} model 2"/>
+ <wd:item value="{$type} model 3"/>
+ <wd:item value="{$type} model 4"/>
+ <wd:item value="{$type} model 5"/>
+ </xsl:otherwise>
+ </xsl:choose>
</wd:selection-list>
</xsl:template>