Hi,
I am fairly new to Tapestry and I have a PropertySelection update
problem
in my form. Here's what I am doing:
I have a search form that I want to be able to save to a database.
So I made it serializable by creating my own ListEditMapSerializable
which contains a private ListEditMap object and knows how to read
and write it to a byte stream. It has the same interface as ListEditMap
and I use it in my form instead. So far so good.
Now, on form submit, I load in a saved form Bean (triggered by an extra
button and field labeled "Load search template:") and use it to populate
my ListEditMapSerializable objects. That works too. The problem is that
when the form appears, all PropertySelection elements are reset to their
initial first position but all text fields contain the correct values.
The overall number of elements is also correct. Seems like this thing is
basically working.
I added a @Insert near the location of the PropertySelection elements
that spits out the key/values that the ListEditMap iterator has at that
point and surely it shows the values as it suppose to do. In fact if I
set a PropertySelection by hand and submit the page then it shows the
same values.
I also verified that the Bean I store is the same that I retrieve
by using the debugger and that the form in general does behave correctly
when used in the normal way (adding rows, leaving the page and returning
to it).
What could I possibly overlook here? Why aren't the PropertySelection
elements defaulting to their corresponding values? Is there something
inside a ListEditMap loop that tells the interface elements to set
their value? I didn't see anything like that.
Any help appreciated (sorry for the long details below),
Andreas Pardeike
-------------------------
My form is dynamic and part of it looks like this:
+------+-+ +----+-+ +--------+
| Name |V| | is |V| |..text..| [+] [-] [+] [-]
+------+-+ +----+-+ +--------+
-----------------------------------------------------------
+------+-+ +----+-+ +--------+
AND | Name |V| | is |V| |..text..| [+] [-] [+] [-]
+------+-+ +----+-+ +--------+
+--------+
OR IS |..text..| [+] [-] [+] [-]
+--------+
-----------------------------------------------------------
+------+-+ +----+-+ +--------+
AND | Name |V| | is |V| |..text..| [+] [-] [+] [-]
+------+-+ +----+-+ +--------+
The whole form is stored in a Bean that contains the above as
a ListEditMapSerializable and each row is again represented as
a Bean containing three other Beans (for field, comparator and
value list). The form contains more parts like the above but that
doesn't relate to the problem.
The html to this looks like:
<table cellspacing="0" cellpadding="4" border="0">
<tr valign="top" jwcid="searchList">
<td>
<table cellspacing="0" cellpadding="4" border="0">
<tr valign="middle" jwcid="searchValues">
<span jwcid="@Conditional" condition="ognl:valueCounter ==
1">
<td>
<input jwcid="searchWhat"/>
</td>
<td>
<input jwcid="searchHow"/>
</td>
</span>
<span jwcid="@Conditional" condition="ognl:valueCounter > 1">
<td colspan="2" align="right">
<span> or </span>
</td>
</span>
<td>
<input jwcid="searchValue" style="width:200px"/>
</td>
<td align="right">
<input jwcid="removeSearchVal" style="border: 0"/>
<input jwcid="addSearchVal" style="border: 0"/>
</td>
</tr>
</table>
</td>
<td valign="bottom">
<input jwcid="removeSearchRow" style="margin-bottom:6px"/>
<input jwcid="addSearchRow" style="margin-bottom:6px"/>
</td>
</tr>
</table>
and the .page contains:
<property-specification name="searchPart"
type="Fsys.Models.FSSearchPart"/>
<property-specification name="searchValue"
type="Fsys.Models.FSSearchSubPart"/>
<property-specification name="searchPartMap"
type="Fsys.Common.ListEditMapSerializable" persistent="yes"/>
<property-specification name="valueCounter" type="int" initial-
value="0"/>
<component id="searchList" type="ListEdit">
<binding name="source" expression="searchPartMap.keys"/>
<binding name="value" expression="searchPartMap.key"/>
<static-binding name="element" value="tr"/>
<binding name="listener"
expression="listeners.synchronizeSearchPart"/>
<binding name="class" expression="beans.evenOddSearch.next"/>
</component>
<component id="searchWhat" type="PropertySelection">
<binding name="model"
expression="@[EMAIL PROTECTED]"/>
<binding name="value" expression="searchPart.what"/>
</component>
<component id="searchHow" type="PropertySelection">
<binding name="model"
expression="@[EMAIL PROTECTED]"/>
<binding name="value" expression="searchPart.how"/>
</component>
<component id="searchValues" type="ListEdit">
<binding name="source" expression="searchPart.values.keys"/>
<binding name="value" expression="searchPart.values.key"/>
<static-binding name="element" value="tr"/>
<binding name="listener"
expression="listeners.synchronizeSearchValue"/>
</component>
<component id="removeSearchVal" type="ImageSubmit">
<binding name="image" expression="assets.minusButton"/>
<binding name="disabledImage" expression="assets.minusButtonOff"/>
<binding name="listener" expression="listeners.removeSearchValue"/>
<binding name="tag" expression="searchPart.index"/>
<binding name="disabled" expression="searchPart.values.keys.size
== 1"/>
</component>
<component id="addSearchVal" type="ImageSubmit">
<binding name="image" expression="assets.plusButton"/>
<binding name="disabledImage" expression="assets.plusButtonOff"/>
<binding name="listener" expression="listeners.addSearchValue"/>
<binding name="tag" expression="searchPart.index"/>
</component>
<component id="searchValue" type="TextField">
<binding name="value" expression="searchValue.value"/>
</component>
<component id="removeSearchRow" type="ImageSubmit">
<binding name="image" expression="assets.minusButton"/>
<binding name="disabledImage" expression="assets.minusButtonOff"/>
<binding name="listener" expression="listeners.removeSearchForm"/>
<binding name="tag" expression="searchPart.index"/>
<binding name="disabled" expression="searchPartMap.keys.size == 1"/>
</component>
<component id="addSearchRow" type="ImageSubmit">
<binding name="image" expression="assets.plusButton"/>
<binding name="disabledImage" expression="assets.plusButtonOff"/>
<binding name="listener" expression="listeners.addSearchForm"/>
<binding name="tag" expression="searchPart.index"/>
</component>
my PropertySelection's are defined like this:
public static final IPropertySelectionModel fieldModel =
new Fsys.Models.FSStatisticFields.Model(
new String[][]
{
new String[] { "Customer", "cust", },
...
new String[] { "Address", "adr" }
});
and finally, my ListEditMapSerializable class:
package Fsys.Common;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.ListIterator;
import org.apache.tapestry.form.ListEditMap;
public class ListEditMapSerializable implements Serializable
{
private transient ListEditMap _map;
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
{
// write out default object
out.defaultWriteObject();
// write out current key
out.writeObject(getKey());
// write out key count (only non-deleted)
out.writeInt(getValues().size());
// write out key/value pairs (skipping deleted keys)
ListIterator it = getKeys().listIterator();
while(it.hasNext())
{
Object key = it.next();
setKey(key);
if(!isDeleted())
{
out.writeObject(key);
out.writeObject(getValue());
}
}
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
{
// create our list
_map = new ListEditMap();
// read default object
in.defaultReadObject();
// read current key
Object currentKey = in.readObject();
// read key/value count
int n = in.readInt();
// read key/value pairs
for(int i = 0; i < n; i++)
{
Object key = in.readObject();
Object val = in.readObject();
add(key, val);
}
// set current key
setKey(currentKey);
}
//
public ListEditMapSerializable() { _map = new ListEditMap(); }
public void add(Object key, Object value) { _map.add(key, value); }
public List getKeys() { return _map.getKeys(); }
public void setKey(Object key) { _map.setKey(key); }
public Object getKey() { return _map.getKey(); }
public Object getValue() { return _map.getValue(); }
public boolean isDeleted() { return _map.isDeleted(); }
public void setDeleted(boolean value) { _map.setDeleted(value); }
public List getDeletedKeys() { return _map.getDeletedKeys(); }
public List getAllValues() { return _map.getAllValues(); }
public List getValues() { return _map.getValues(); }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]