You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by "matthew c. mead" <m-...@goof.com> on 2005/02/11 19:39:04 UTC

Unable to resolve expression in form rewind

I'm trying to do a double-nested loop within a page to generate a form 
for each of a high level object productGroup, and for each of its 
productVersions, display a select/option list.

I'm running into a null on form rewind that I can't figure out.

getActiveProductGroups() iterates my domain model to figure out which 
product groups are active and builds a list of the ones that are.
The @Foreach component should iterate through said list and call 
setProductGroup(value) for each of them as it iterates through.  This 
appears to happen properly when the page is rendered to display the form 
to the user, as the labels for the product groups show up correctly.  
During rewind however, productGroup is null!?!?

The inner "loop" on this is the selectProductVersion component, a 
PropertySelection.  getProductVersionSelectionModel() populates an 
IPropertySelectionModel with the list of ProductVersion objects by using 
the value of getProductGroup() to generate a list of ProductVersions.

Any ideas why @Foreach would not set the productGroup during rewind?

More info below on the exception and my component definition/template.

Thanks!


-matt


Here's the exception:
Unable to resolve expression 'productGroup.label' for 
pages.catalog.ProductGroups$Enhance_0@e4abfb[Catalog.ProductGroups].
binding: 	ExpressionBinding[Catalog.ProductGroups productGroup.label]
location: 	context:/WEB-INF/Catalog/ProductGroups.html, line


ognl.OgnlException
source is null for getProperty(null, "label")


The stack trace is during the form rewind after I click a submit.

Here's how I've set things up:

=== page spec ===
<page-specification class="pages.catalog.ProductGroups">
  <property name="roles">DOWNLOADING</property>
 
  <component id="selectProductVersion" type="PropertySelection">
    <binding name="model" expression="productVersionSelectionModel"/>
    <binding name="value" expression="productVersion"/>
  </component>

  <property-specification name="productGroup" 
type="com.ase.rhdl.software.ProductGroup" />
  <property-specification name="productVersion" 
type="com.ase.rhdl.software.ProductVersion" />
 
  <context-asset name="stylesheet" path="style.css"/>
</page-specification>
=== end page spec ===

== template ==
   <span jwcid="@Foreach" source="ognl:activeProductGroups" 
value="ognl:productGroup">
   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion">
    <tr valign="middle" align="left">
      <td bgcolor="#333333" class="textbold" width="252" valign="middle" 
align="left" ><span jwcid="@Insert" value="ognl:productGroup.label"/>
      </td>
      <td bgcolor="#666666" width="350">
             <span jwcid="selectProductVersion"/>
      </td>
    </tr>

    <tr valign="middle" align="left">
      <td bgcolor="#dddddd" width="" colspan="2" align="center">
        <input type="Submit" name="" value="Submit">
      </td>
    </tr>
   </form>
   <tr>
    <td bgcolor="#FFFFFF" width="252" valign="middle" 
align="left">&nbsp;</td>
    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
   </tr>
   </span>
=== template ===


-- 
matthew c. mead

http://www.goof.com/

Re: Unable to resolve expression in form rewind

Posted by "matthew c. mead" <m-...@goof.com>.
I had originally tried using a nested ListEdit component.  It had 
problems on form rewind.  I don't recall why - perhaps eclipse workspace 
history can get me back to it.

The Java code ended up much cleaner for this setup, however, since 
ListEdit must be within a single form, I have to have some way to 
differentiate between the multiple select lists that show up and decide 
which one the user intended (based on the submit).

I'm not sure how to do this, since even if I were to attach listeners to 
the submit buttons, all three select lists appear to use the same html 
object name - how would the single property in my page class end up with 
the right value?

Thanks, Paul.


-matt

Paul Ferraro wrote:

> Look at the FormConditional and ListEdit components.  They were 
> designed to specifically address these issues.
> The rule is:
> - if you are generating form fields within a loop and there is a 
> possibility that the list will change between requests, use the 
> ListEdit component instead of a Foreach.
> - if you are conditionally displaying a form field and there is a 
> possibility that the condition will change between requests, use the 
> FormConditional component instead of a Conditional.
>
> Paul
>
> matthew c. mead wrote:
>
>> Wow, thanks for the help and explanation!
>>
>> This leads me to another question...  I've been reading Tapestry in 
>> Action, the online Developer's Guide and Component Reference.
>>
>> I see a lot of mention about forms generated dynamically based on 
>> domain models being very fragile to changes in the model taking place 
>> between template render and template rewind.
>>
>> Is there a simple set of rules one can follow to truly avoid these 
>> issues?
>>
>> Thanks again.
>>
>>
>> -matt
>>
>> Paul Ferraro wrote:
>>
>>> Since your Form component resides within a Foreach, it needs to use 
>>> the ActionService so that the full page is rewound (and your 
>>> productGroup property will be bound).
>>> Details here: 
>>> http://jakarta.apache.org/tapestry/doc/ComponentReference/Form.html
>>>
>>> e.g.
>>> <form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
>>> direct="ognl:false">
>>> ...
>>> </form>
>>>
>>> matthew c. mead wrote:
>>>
>>>> I'm trying to do a double-nested loop within a page to generate a 
>>>> form for each of a high level object productGroup, and for each of 
>>>> its productVersions, display a select/option list.
>>>>
>>>> I'm running into a null on form rewind that I can't figure out.
>>>>
>>>> getActiveProductGroups() iterates my domain model to figure out 
>>>> which product groups are active and builds a list of the ones that 
>>>> are.
>>>> The @Foreach component should iterate through said list and call 
>>>> setProductGroup(value) for each of them as it iterates through.  
>>>> This appears to happen properly when the page is rendered to 
>>>> display the form to the user, as the labels for the product groups 
>>>> show up correctly.  During rewind however, productGroup is null!?!?
>>>>
>>>> The inner "loop" on this is the selectProductVersion component, a 
>>>> PropertySelection.  getProductVersionSelectionModel() populates an 
>>>> IPropertySelectionModel with the list of ProductVersion objects by 
>>>> using the value of getProductGroup() to generate a list of 
>>>> ProductVersions.
>>>>
>>>> Any ideas why @Foreach would not set the productGroup during rewind?
>>>>
>>>> More info below on the exception and my component definition/template.
>>>>
>>>> Thanks!
>>>>
>>>>
>>>> -matt
>>>>
>>>>
>>>> Here's the exception:
>>>> Unable to resolve expression 'productGroup.label' for 
>>>> pages.catalog.ProductGroups$Enhance_0@e4abfb[Catalog.ProductGroups].
>>>> binding:     ExpressionBinding[Catalog.ProductGroups 
>>>> productGroup.label]
>>>> location:     context:/WEB-INF/Catalog/ProductGroups.html, line
>>>>
>>>>
>>>> ognl.OgnlException
>>>> source is null for getProperty(null, "label")
>>>>
>>>>
>>>> The stack trace is during the form rewind after I click a submit.
>>>>
>>>> Here's how I've set things up:
>>>>
>>>> === page spec ===
>>>> <page-specification class="pages.catalog.ProductGroups">
>>>>  <property name="roles">DOWNLOADING</property>
>>>>
>>>>  <component id="selectProductVersion" type="PropertySelection">
>>>>    <binding name="model" expression="productVersionSelectionModel"/>
>>>>    <binding name="value" expression="productVersion"/>
>>>>  </component>
>>>>
>>>>  <property-specification name="productGroup" 
>>>> type="com.ase.rhdl.software.ProductGroup" />
>>>>  <property-specification name="productVersion" 
>>>> type="com.ase.rhdl.software.ProductVersion" />
>>>>
>>>>  <context-asset name="stylesheet" path="style.css"/>
>>>> </page-specification>
>>>> === end page spec ===
>>>>
>>>> == template ==
>>>>   <span jwcid="@Foreach" source="ognl:activeProductGroups" 
>>>> value="ognl:productGroup">
>>>>   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion">
>>>>    <tr valign="middle" align="left">
>>>>      <td bgcolor="#333333" class="textbold" width="252" 
>>>> valign="middle" align="left" ><span jwcid="@Insert" 
>>>> value="ognl:productGroup.label"/>
>>>>      </td>
>>>>      <td bgcolor="#666666" width="350">
>>>>             <span jwcid="selectProductVersion"/>
>>>>      </td>
>>>>    </tr>
>>>>
>>>>    <tr valign="middle" align="left">
>>>>      <td bgcolor="#dddddd" width="" colspan="2" align="center">
>>>>        <input type="Submit" name="" value="Submit">
>>>>      </td>
>>>>    </tr>
>>>>   </form>
>>>>   <tr>
>>>>    <td bgcolor="#FFFFFF" width="252" valign="middle" 
>>>> align="left">&nbsp;</td>
>>>>    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
>>>>   </tr>
>>>>   </span>
>>>> === template ===
>>>>
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>>> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>

-- 
matthew c. mead

http://www.goof.com/

Re: Unable to resolve expression in form rewind

Posted by Paul Ferraro <pm...@columbia.edu>.
The "selected" parameter of the Option component is updated upon rewind 
of the form.  You need to bind it to some object property that has both 
a mutator and accessor method.

Paul

matthew c. mead wrote:

> I decided to rollback in order to try to use ListEdit components.
>
> Here's the error I'm getting during rewind:
>
> Binding value may not be updated.
> binding:     ExpressionBinding[Catalog.ProductGroups false 
> cachedValue=false]
> location:     context:/WEB-INF/Catalog/ProductGroups.html, line 27
> Stack Trace:
>
>    * 
> org.apache.tapestry.binding.AbstractBinding.createReadOnlyBindingException(AbstractBinding.java:241) 
>
>
>    * 
> org.apache.tapestry.binding.ExpressionBinding.setObject(ExpressionBinding.java:549) 
>
>
>    * 
> org.apache.tapestry.binding.ExpressionBinding.setBoolean(ExpressionBinding.java:267) 
>
>
>    * org.apache.tapestry.form.Option.renderComponent(Option.java:67)
>
>
> Here's the specification and template.  The error is on the line with 
> @Option.
>
> Any ideas?
>
> Thanks!
>
>
> -matt
>
>
> === page spec ===
> <page-specification class="pages.catalog.DisplayProductGroups">
>  <property name="roles">DOWNLOADING</property>
>
>  <component id="groupListEdit" type="ListEdit">
>    <binding name="source" expression="outerListEditMap.keys"/>
>    <binding name="value" expression="outerListEditMap.key"/>
>    <binding name="listener" 
> expression="listeners.synchronizeProductGroup"/>
>  </component>
>
>  <component id="versionListEdit" type="ListEdit">
>    <binding name="source" expression="innerListEditMap.keys"/>
>    <binding name="value" expression="innerListEditMap.key"/>
>    <binding name="listener" 
> expression="listeners.synchronizeProductVersion"/>
>  </component>
>
>
>  <property-specification name="outerListEditMap" 
> type="org.apache.tapestry.form.ListEditMap"/>
>  <property-specification name="productGroup" 
> type="software.ProductGroup"/>
>  <property-specification name="innerListEditMap" 
> type="org.apache.tapestry.form.ListEditMap"/>
>  <property-specification name="productVersion" 
> type="software.ProductVersion"/>
>
>  <property-specification name="errorMessage" type="java.lang.String"/>
>
>  <context-asset name="stylesheet" path="style.css"/>
> </page-specification>
> === end page spec ===
>
> === page template ===
>   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
> direct="ognl:false">
>   <span jwcid="groupListEdit">
>    <tr valign="middle" align="left">
>      <td bgcolor="#333333" class="textbold" width="252" 
> valign="middle" align="left" >
>                <span jwcid="@Insert" value="ognl:productGroup.label"/>
>      </td>
>      <td bgcolor="#666666" width="350">
>        <select jwcid="@Select" multiple="ognl:false">
>          <span jwcid="versionListEdit">
>            <option jwcid="@Option" selected="ognl:false" 
> label="ognl:productVersion.productLabel"/>
>          </span>
>        </select>
>      </td>
>    </tr>
>
>    <tr valign="middle" align="left">
>      <td bgcolor="#dddddd" width="" colspan="2" align="center">
>        <input type="Submit" name="" value="Submit">
>      </td>
>    </tr>
>   <tr>
>    <td bgcolor="#FFFFFF" width="252" valign="middle" 
> align="left">&nbsp;</td>
>    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
>   </tr>
>   </span>
>
>
>
>
>
>    <tr valign="bottom" align="left">
>      <td width="603" colspan="2" class="tablebody" height="33" ><p><a 
> href="http://dii-sw.ncr.disa.mil/Del/netlic.html" target="_blank">DoD
>          License Page</a></p>
>        <p>&nbsp;</p>
>
>                       <p align="center"><img src="images/line.gif" 
> alt="-" name="line" width="600" height="25" border="0"><a 
> jwcid="@PageLink" page="Main" class="textboldcolor">
>                Login
>          Main </a></td>
>    </tr>
>   </form>
> === end page template ===
>
> Paul Ferraro wrote:
>
>> Look at the FormConditional and ListEdit components.  They were 
>> designed to specifically address these issues.
>> The rule is:
>> - if you are generating form fields within a loop and there is a 
>> possibility that the list will change between requests, use the 
>> ListEdit component instead of a Foreach.
>> - if you are conditionally displaying a form field and there is a 
>> possibility that the condition will change between requests, use the 
>> FormConditional component instead of a Conditional.
>>
>> Paul
>>
>> matthew c. mead wrote:
>>
>>> Wow, thanks for the help and explanation!
>>>
>>> This leads me to another question...  I've been reading Tapestry in 
>>> Action, the online Developer's Guide and Component Reference.
>>>
>>> I see a lot of mention about forms generated dynamically based on 
>>> domain models being very fragile to changes in the model taking 
>>> place between template render and template rewind.
>>>
>>> Is there a simple set of rules one can follow to truly avoid these 
>>> issues?
>>>
>>> Thanks again.
>>>
>>>
>>> -matt
>>>
>>> Paul Ferraro wrote:
>>>
>>>> Since your Form component resides within a Foreach, it needs to use 
>>>> the ActionService so that the full page is rewound (and your 
>>>> productGroup property will be bound).
>>>> Details here: 
>>>> http://jakarta.apache.org/tapestry/doc/ComponentReference/Form.html
>>>>
>>>> e.g.
>>>> <form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
>>>> direct="ognl:false">
>>>> ...
>>>> </form>
>>>>
>>>> matthew c. mead wrote:
>>>>
>>>>> I'm trying to do a double-nested loop within a page to generate a 
>>>>> form for each of a high level object productGroup, and for each of 
>>>>> its productVersions, display a select/option list.
>>>>>
>>>>> I'm running into a null on form rewind that I can't figure out.
>>>>>
>>>>> getActiveProductGroups() iterates my domain model to figure out 
>>>>> which product groups are active and builds a list of the ones that 
>>>>> are.
>>>>> The @Foreach component should iterate through said list and call 
>>>>> setProductGroup(value) for each of them as it iterates through.  
>>>>> This appears to happen properly when the page is rendered to 
>>>>> display the form to the user, as the labels for the product groups 
>>>>> show up correctly.  During rewind however, productGroup is null!?!?
>>>>>
>>>>> The inner "loop" on this is the selectProductVersion component, a 
>>>>> PropertySelection.  getProductVersionSelectionModel() populates an 
>>>>> IPropertySelectionModel with the list of ProductVersion objects by 
>>>>> using the value of getProductGroup() to generate a list of 
>>>>> ProductVersions.
>>>>>
>>>>> Any ideas why @Foreach would not set the productGroup during rewind?
>>>>>
>>>>> More info below on the exception and my component 
>>>>> definition/template.
>>>>>
>>>>> Thanks!
>>>>>
>>>>>
>>>>> -matt
>>>>>
>>>>>
>>>>> Here's the exception:
>>>>> Unable to resolve expression 'productGroup.label' for 
>>>>> pages.catalog.ProductGroups$Enhance_0@e4abfb[Catalog.ProductGroups].
>>>>> binding:     ExpressionBinding[Catalog.ProductGroups 
>>>>> productGroup.label]
>>>>> location:     context:/WEB-INF/Catalog/ProductGroups.html, line
>>>>>
>>>>>
>>>>> ognl.OgnlException
>>>>> source is null for getProperty(null, "label")
>>>>>
>>>>>
>>>>> The stack trace is during the form rewind after I click a submit.
>>>>>
>>>>> Here's how I've set things up:
>>>>>
>>>>> === page spec ===
>>>>> <page-specification class="pages.catalog.ProductGroups">
>>>>>  <property name="roles">DOWNLOADING</property>
>>>>>
>>>>>  <component id="selectProductVersion" type="PropertySelection">
>>>>>    <binding name="model" expression="productVersionSelectionModel"/>
>>>>>    <binding name="value" expression="productVersion"/>
>>>>>  </component>
>>>>>
>>>>>  <property-specification name="productGroup" 
>>>>> type="com.ase.rhdl.software.ProductGroup" />
>>>>>  <property-specification name="productVersion" 
>>>>> type="com.ase.rhdl.software.ProductVersion" />
>>>>>
>>>>>  <context-asset name="stylesheet" path="style.css"/>
>>>>> </page-specification>
>>>>> === end page spec ===
>>>>>
>>>>> == template ==
>>>>>   <span jwcid="@Foreach" source="ognl:activeProductGroups" 
>>>>> value="ognl:productGroup">
>>>>>   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion">
>>>>>    <tr valign="middle" align="left">
>>>>>      <td bgcolor="#333333" class="textbold" width="252" 
>>>>> valign="middle" align="left" ><span jwcid="@Insert" 
>>>>> value="ognl:productGroup.label"/>
>>>>>      </td>
>>>>>      <td bgcolor="#666666" width="350">
>>>>>             <span jwcid="selectProductVersion"/>
>>>>>      </td>
>>>>>    </tr>
>>>>>
>>>>>    <tr valign="middle" align="left">
>>>>>      <td bgcolor="#dddddd" width="" colspan="2" align="center">
>>>>>        <input type="Submit" name="" value="Submit">
>>>>>      </td>
>>>>>    </tr>
>>>>>   </form>
>>>>>   <tr>
>>>>>    <td bgcolor="#FFFFFF" width="252" valign="middle" 
>>>>> align="left">&nbsp;</td>
>>>>>    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
>>>>>   </tr>
>>>>>   </span>
>>>>> === template ===
>>>>>
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>>>> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Unable to resolve expression in form rewind

Posted by "matthew c. mead" <m-...@goof.com>.
I decided to rollback in order to try to use ListEdit components.

Here's the error I'm getting during rewind:

Binding value may not be updated.
binding: 	ExpressionBinding[Catalog.ProductGroups false cachedValue=false]
location: 	context:/WEB-INF/Catalog/ProductGroups.html, line 27
Stack Trace:

    * org.apache.tapestry.binding.AbstractBinding.createReadOnlyBindingException(AbstractBinding.java:241)

    * org.apache.tapestry.binding.ExpressionBinding.setObject(ExpressionBinding.java:549)

    * org.apache.tapestry.binding.ExpressionBinding.setBoolean(ExpressionBinding.java:267)

    * org.apache.tapestry.form.Option.renderComponent(Option.java:67)


Here's the specification and template.  The error is on the line with 
@Option.

Any ideas?

Thanks!


-matt


=== page spec ===
<page-specification class="pages.catalog.DisplayProductGroups">
  <property name="roles">DOWNLOADING</property>
 
  <component id="groupListEdit" type="ListEdit">
    <binding name="source" expression="outerListEditMap.keys"/>
    <binding name="value" expression="outerListEditMap.key"/>
    <binding name="listener" 
expression="listeners.synchronizeProductGroup"/>
  </component>
 
  <component id="versionListEdit" type="ListEdit">
    <binding name="source" expression="innerListEditMap.keys"/>
    <binding name="value" expression="innerListEditMap.key"/>
    <binding name="listener" 
expression="listeners.synchronizeProductVersion"/>
  </component>


  <property-specification name="outerListEditMap" 
type="org.apache.tapestry.form.ListEditMap"/>
  <property-specification name="productGroup" type="software.ProductGroup"/>
  <property-specification name="innerListEditMap" 
type="org.apache.tapestry.form.ListEditMap"/>
  <property-specification name="productVersion" 
type="software.ProductVersion"/>

  <property-specification name="errorMessage" type="java.lang.String"/>

  <context-asset name="stylesheet" path="style.css"/>
</page-specification>
=== end page spec ===

=== page template ===
   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
direct="ognl:false">
   <span jwcid="groupListEdit">
    <tr valign="middle" align="left">
      <td bgcolor="#333333" class="textbold" width="252" valign="middle" 
align="left" >
                <span jwcid="@Insert" value="ognl:productGroup.label"/>
      </td>
      <td bgcolor="#666666" width="350">
        <select jwcid="@Select" multiple="ognl:false">
          <span jwcid="versionListEdit">
            <option jwcid="@Option" selected="ognl:false" 
label="ognl:productVersion.productLabel"/>
          </span>
        </select>
      </td>
    </tr>

    <tr valign="middle" align="left">
      <td bgcolor="#dddddd" width="" colspan="2" align="center">
        <input type="Submit" name="" value="Submit">
      </td>
    </tr>
   <tr>
    <td bgcolor="#FFFFFF" width="252" valign="middle" 
align="left">&nbsp;</td>
    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
   </tr>
   </span>
 
 
 


    <tr valign="bottom" align="left">
      <td width="603" colspan="2" class="tablebody" height="33" ><p><a 
href="http://dii-sw.ncr.disa.mil/Del/netlic.html" target="_blank">DoD
          License Page</a></p>
        <p>&nbsp;</p>

                
        <p align="center"><img src="images/line.gif" alt="-" name="line" 
width="600" height="25" border="0"><a jwcid="@PageLink" page="Main" 
class="textboldcolor">
                Login
          Main </a></td>
    </tr>
   </form>
=== end page template ===

Paul Ferraro wrote:

> Look at the FormConditional and ListEdit components.  They were 
> designed to specifically address these issues.
> The rule is:
> - if you are generating form fields within a loop and there is a 
> possibility that the list will change between requests, use the 
> ListEdit component instead of a Foreach.
> - if you are conditionally displaying a form field and there is a 
> possibility that the condition will change between requests, use the 
> FormConditional component instead of a Conditional.
>
> Paul
>
> matthew c. mead wrote:
>
>> Wow, thanks for the help and explanation!
>>
>> This leads me to another question...  I've been reading Tapestry in 
>> Action, the online Developer's Guide and Component Reference.
>>
>> I see a lot of mention about forms generated dynamically based on 
>> domain models being very fragile to changes in the model taking place 
>> between template render and template rewind.
>>
>> Is there a simple set of rules one can follow to truly avoid these 
>> issues?
>>
>> Thanks again.
>>
>>
>> -matt
>>
>> Paul Ferraro wrote:
>>
>>> Since your Form component resides within a Foreach, it needs to use 
>>> the ActionService so that the full page is rewound (and your 
>>> productGroup property will be bound).
>>> Details here: 
>>> http://jakarta.apache.org/tapestry/doc/ComponentReference/Form.html
>>>
>>> e.g.
>>> <form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
>>> direct="ognl:false">
>>> ...
>>> </form>
>>>
>>> matthew c. mead wrote:
>>>
>>>> I'm trying to do a double-nested loop within a page to generate a 
>>>> form for each of a high level object productGroup, and for each of 
>>>> its productVersions, display a select/option list.
>>>>
>>>> I'm running into a null on form rewind that I can't figure out.
>>>>
>>>> getActiveProductGroups() iterates my domain model to figure out 
>>>> which product groups are active and builds a list of the ones that 
>>>> are.
>>>> The @Foreach component should iterate through said list and call 
>>>> setProductGroup(value) for each of them as it iterates through.  
>>>> This appears to happen properly when the page is rendered to 
>>>> display the form to the user, as the labels for the product groups 
>>>> show up correctly.  During rewind however, productGroup is null!?!?
>>>>
>>>> The inner "loop" on this is the selectProductVersion component, a 
>>>> PropertySelection.  getProductVersionSelectionModel() populates an 
>>>> IPropertySelectionModel with the list of ProductVersion objects by 
>>>> using the value of getProductGroup() to generate a list of 
>>>> ProductVersions.
>>>>
>>>> Any ideas why @Foreach would not set the productGroup during rewind?
>>>>
>>>> More info below on the exception and my component definition/template.
>>>>
>>>> Thanks!
>>>>
>>>>
>>>> -matt
>>>>
>>>>
>>>> Here's the exception:
>>>> Unable to resolve expression 'productGroup.label' for 
>>>> pages.catalog.ProductGroups$Enhance_0@e4abfb[Catalog.ProductGroups].
>>>> binding:     ExpressionBinding[Catalog.ProductGroups 
>>>> productGroup.label]
>>>> location:     context:/WEB-INF/Catalog/ProductGroups.html, line
>>>>
>>>>
>>>> ognl.OgnlException
>>>> source is null for getProperty(null, "label")
>>>>
>>>>
>>>> The stack trace is during the form rewind after I click a submit.
>>>>
>>>> Here's how I've set things up:
>>>>
>>>> === page spec ===
>>>> <page-specification class="pages.catalog.ProductGroups">
>>>>  <property name="roles">DOWNLOADING</property>
>>>>
>>>>  <component id="selectProductVersion" type="PropertySelection">
>>>>    <binding name="model" expression="productVersionSelectionModel"/>
>>>>    <binding name="value" expression="productVersion"/>
>>>>  </component>
>>>>
>>>>  <property-specification name="productGroup" 
>>>> type="com.ase.rhdl.software.ProductGroup" />
>>>>  <property-specification name="productVersion" 
>>>> type="com.ase.rhdl.software.ProductVersion" />
>>>>
>>>>  <context-asset name="stylesheet" path="style.css"/>
>>>> </page-specification>
>>>> === end page spec ===
>>>>
>>>> == template ==
>>>>   <span jwcid="@Foreach" source="ognl:activeProductGroups" 
>>>> value="ognl:productGroup">
>>>>   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion">
>>>>    <tr valign="middle" align="left">
>>>>      <td bgcolor="#333333" class="textbold" width="252" 
>>>> valign="middle" align="left" ><span jwcid="@Insert" 
>>>> value="ognl:productGroup.label"/>
>>>>      </td>
>>>>      <td bgcolor="#666666" width="350">
>>>>             <span jwcid="selectProductVersion"/>
>>>>      </td>
>>>>    </tr>
>>>>
>>>>    <tr valign="middle" align="left">
>>>>      <td bgcolor="#dddddd" width="" colspan="2" align="center">
>>>>        <input type="Submit" name="" value="Submit">
>>>>      </td>
>>>>    </tr>
>>>>   </form>
>>>>   <tr>
>>>>    <td bgcolor="#FFFFFF" width="252" valign="middle" 
>>>> align="left">&nbsp;</td>
>>>>    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
>>>>   </tr>
>>>>   </span>
>>>> === template ===
>>>>
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>>> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>

-- 
matthew c. mead

http://www.goof.com/

Re: Unable to resolve expression in form rewind

Posted by Paul Ferraro <pm...@columbia.edu>.
Look at the FormConditional and ListEdit components.  They were designed 
to specifically address these issues.
The rule is:
- if you are generating form fields within a loop and there is a 
possibility that the list will change between requests, use the ListEdit 
component instead of a Foreach.
- if you are conditionally displaying a form field and there is a 
possibility that the condition will change between requests, use the 
FormConditional component instead of a Conditional.

Paul

matthew c. mead wrote:

> Wow, thanks for the help and explanation!
>
> This leads me to another question...  I've been reading Tapestry in 
> Action, the online Developer's Guide and Component Reference.
>
> I see a lot of mention about forms generated dynamically based on 
> domain models being very fragile to changes in the model taking place 
> between template render and template rewind.
>
> Is there a simple set of rules one can follow to truly avoid these 
> issues?
>
> Thanks again.
>
>
> -matt
>
> Paul Ferraro wrote:
>
>> Since your Form component resides within a Foreach, it needs to use 
>> the ActionService so that the full page is rewound (and your 
>> productGroup property will be bound).
>> Details here: 
>> http://jakarta.apache.org/tapestry/doc/ComponentReference/Form.html
>>
>> e.g.
>> <form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
>> direct="ognl:false">
>> ...
>> </form>
>>
>> matthew c. mead wrote:
>>
>>> I'm trying to do a double-nested loop within a page to generate a 
>>> form for each of a high level object productGroup, and for each of 
>>> its productVersions, display a select/option list.
>>>
>>> I'm running into a null on form rewind that I can't figure out.
>>>
>>> getActiveProductGroups() iterates my domain model to figure out 
>>> which product groups are active and builds a list of the ones that are.
>>> The @Foreach component should iterate through said list and call 
>>> setProductGroup(value) for each of them as it iterates through.  
>>> This appears to happen properly when the page is rendered to display 
>>> the form to the user, as the labels for the product groups show up 
>>> correctly.  During rewind however, productGroup is null!?!?
>>>
>>> The inner "loop" on this is the selectProductVersion component, a 
>>> PropertySelection.  getProductVersionSelectionModel() populates an 
>>> IPropertySelectionModel with the list of ProductVersion objects by 
>>> using the value of getProductGroup() to generate a list of 
>>> ProductVersions.
>>>
>>> Any ideas why @Foreach would not set the productGroup during rewind?
>>>
>>> More info below on the exception and my component definition/template.
>>>
>>> Thanks!
>>>
>>>
>>> -matt
>>>
>>>
>>> Here's the exception:
>>> Unable to resolve expression 'productGroup.label' for 
>>> pages.catalog.ProductGroups$Enhance_0@e4abfb[Catalog.ProductGroups].
>>> binding:     ExpressionBinding[Catalog.ProductGroups 
>>> productGroup.label]
>>> location:     context:/WEB-INF/Catalog/ProductGroups.html, line
>>>
>>>
>>> ognl.OgnlException
>>> source is null for getProperty(null, "label")
>>>
>>>
>>> The stack trace is during the form rewind after I click a submit.
>>>
>>> Here's how I've set things up:
>>>
>>> === page spec ===
>>> <page-specification class="pages.catalog.ProductGroups">
>>>  <property name="roles">DOWNLOADING</property>
>>>
>>>  <component id="selectProductVersion" type="PropertySelection">
>>>    <binding name="model" expression="productVersionSelectionModel"/>
>>>    <binding name="value" expression="productVersion"/>
>>>  </component>
>>>
>>>  <property-specification name="productGroup" 
>>> type="com.ase.rhdl.software.ProductGroup" />
>>>  <property-specification name="productVersion" 
>>> type="com.ase.rhdl.software.ProductVersion" />
>>>
>>>  <context-asset name="stylesheet" path="style.css"/>
>>> </page-specification>
>>> === end page spec ===
>>>
>>> == template ==
>>>   <span jwcid="@Foreach" source="ognl:activeProductGroups" 
>>> value="ognl:productGroup">
>>>   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion">
>>>    <tr valign="middle" align="left">
>>>      <td bgcolor="#333333" class="textbold" width="252" 
>>> valign="middle" align="left" ><span jwcid="@Insert" 
>>> value="ognl:productGroup.label"/>
>>>      </td>
>>>      <td bgcolor="#666666" width="350">
>>>             <span jwcid="selectProductVersion"/>
>>>      </td>
>>>    </tr>
>>>
>>>    <tr valign="middle" align="left">
>>>      <td bgcolor="#dddddd" width="" colspan="2" align="center">
>>>        <input type="Submit" name="" value="Submit">
>>>      </td>
>>>    </tr>
>>>   </form>
>>>   <tr>
>>>    <td bgcolor="#FFFFFF" width="252" valign="middle" 
>>> align="left">&nbsp;</td>
>>>    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
>>>   </tr>
>>>   </span>
>>> === template ===
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Unable to resolve expression in form rewind

Posted by "matthew c. mead" <m-...@goof.com>.
Wow, thanks for the help and explanation!

This leads me to another question...  I've been reading Tapestry in 
Action, the online Developer's Guide and Component Reference.

I see a lot of mention about forms generated dynamically based on domain 
models being very fragile to changes in the model taking place between 
template render and template rewind.

Is there a simple set of rules one can follow to truly avoid these issues?

Thanks again.


-matt

Paul Ferraro wrote:

> Since your Form component resides within a Foreach, it needs to use 
> the ActionService so that the full page is rewound (and your 
> productGroup property will be bound).
> Details here: 
> http://jakarta.apache.org/tapestry/doc/ComponentReference/Form.html
>
> e.g.
> <form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
> direct="ognl:false">
> ...
> </form>
>
> matthew c. mead wrote:
>
>> I'm trying to do a double-nested loop within a page to generate a 
>> form for each of a high level object productGroup, and for each of 
>> its productVersions, display a select/option list.
>>
>> I'm running into a null on form rewind that I can't figure out.
>>
>> getActiveProductGroups() iterates my domain model to figure out which 
>> product groups are active and builds a list of the ones that are.
>> The @Foreach component should iterate through said list and call 
>> setProductGroup(value) for each of them as it iterates through.  This 
>> appears to happen properly when the page is rendered to display the 
>> form to the user, as the labels for the product groups show up 
>> correctly.  During rewind however, productGroup is null!?!?
>>
>> The inner "loop" on this is the selectProductVersion component, a 
>> PropertySelection.  getProductVersionSelectionModel() populates an 
>> IPropertySelectionModel with the list of ProductVersion objects by 
>> using the value of getProductGroup() to generate a list of 
>> ProductVersions.
>>
>> Any ideas why @Foreach would not set the productGroup during rewind?
>>
>> More info below on the exception and my component definition/template.
>>
>> Thanks!
>>
>>
>> -matt
>>
>>
>> Here's the exception:
>> Unable to resolve expression 'productGroup.label' for 
>> pages.catalog.ProductGroups$Enhance_0@e4abfb[Catalog.ProductGroups].
>> binding:     ExpressionBinding[Catalog.ProductGroups productGroup.label]
>> location:     context:/WEB-INF/Catalog/ProductGroups.html, line
>>
>>
>> ognl.OgnlException
>> source is null for getProperty(null, "label")
>>
>>
>> The stack trace is during the form rewind after I click a submit.
>>
>> Here's how I've set things up:
>>
>> === page spec ===
>> <page-specification class="pages.catalog.ProductGroups">
>>  <property name="roles">DOWNLOADING</property>
>>
>>  <component id="selectProductVersion" type="PropertySelection">
>>    <binding name="model" expression="productVersionSelectionModel"/>
>>    <binding name="value" expression="productVersion"/>
>>  </component>
>>
>>  <property-specification name="productGroup" 
>> type="com.ase.rhdl.software.ProductGroup" />
>>  <property-specification name="productVersion" 
>> type="com.ase.rhdl.software.ProductVersion" />
>>
>>  <context-asset name="stylesheet" path="style.css"/>
>> </page-specification>
>> === end page spec ===
>>
>> == template ==
>>   <span jwcid="@Foreach" source="ognl:activeProductGroups" 
>> value="ognl:productGroup">
>>   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion">
>>    <tr valign="middle" align="left">
>>      <td bgcolor="#333333" class="textbold" width="252" 
>> valign="middle" align="left" ><span jwcid="@Insert" 
>> value="ognl:productGroup.label"/>
>>      </td>
>>      <td bgcolor="#666666" width="350">
>>             <span jwcid="selectProductVersion"/>
>>      </td>
>>    </tr>
>>
>>    <tr valign="middle" align="left">
>>      <td bgcolor="#dddddd" width="" colspan="2" align="center">
>>        <input type="Submit" name="" value="Submit">
>>      </td>
>>    </tr>
>>   </form>
>>   <tr>
>>    <td bgcolor="#FFFFFF" width="252" valign="middle" 
>> align="left">&nbsp;</td>
>>    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
>>   </tr>
>>   </span>
>> === template ===
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>

-- 
matthew c. mead

http://www.goof.com/

Re: Unable to resolve expression in form rewind

Posted by Paul Ferraro <pm...@columbia.edu>.
Since your Form component resides within a Foreach, it needs to use the 
ActionService so that the full page is rewound (and your productGroup 
property will be bound).
Details here: 
http://jakarta.apache.org/tapestry/doc/ComponentReference/Form.html

e.g.
<form jwcid="@Form" listener="ognl:listeners.viewProductVersion" 
direct="ognl:false">
...
</form>

matthew c. mead wrote:

> I'm trying to do a double-nested loop within a page to generate a form 
> for each of a high level object productGroup, and for each of its 
> productVersions, display a select/option list.
>
> I'm running into a null on form rewind that I can't figure out.
>
> getActiveProductGroups() iterates my domain model to figure out which 
> product groups are active and builds a list of the ones that are.
> The @Foreach component should iterate through said list and call 
> setProductGroup(value) for each of them as it iterates through.  This 
> appears to happen properly when the page is rendered to display the 
> form to the user, as the labels for the product groups show up 
> correctly.  During rewind however, productGroup is null!?!?
>
> The inner "loop" on this is the selectProductVersion component, a 
> PropertySelection.  getProductVersionSelectionModel() populates an 
> IPropertySelectionModel with the list of ProductVersion objects by 
> using the value of getProductGroup() to generate a list of 
> ProductVersions.
>
> Any ideas why @Foreach would not set the productGroup during rewind?
>
> More info below on the exception and my component definition/template.
>
> Thanks!
>
>
> -matt
>
>
> Here's the exception:
> Unable to resolve expression 'productGroup.label' for 
> pages.catalog.ProductGroups$Enhance_0@e4abfb[Catalog.ProductGroups].
> binding:     ExpressionBinding[Catalog.ProductGroups productGroup.label]
> location:     context:/WEB-INF/Catalog/ProductGroups.html, line
>
>
> ognl.OgnlException
> source is null for getProperty(null, "label")
>
>
> The stack trace is during the form rewind after I click a submit.
>
> Here's how I've set things up:
>
> === page spec ===
> <page-specification class="pages.catalog.ProductGroups">
>  <property name="roles">DOWNLOADING</property>
>
>  <component id="selectProductVersion" type="PropertySelection">
>    <binding name="model" expression="productVersionSelectionModel"/>
>    <binding name="value" expression="productVersion"/>
>  </component>
>
>  <property-specification name="productGroup" 
> type="com.ase.rhdl.software.ProductGroup" />
>  <property-specification name="productVersion" 
> type="com.ase.rhdl.software.ProductVersion" />
>
>  <context-asset name="stylesheet" path="style.css"/>
> </page-specification>
> === end page spec ===
>
> == template ==
>   <span jwcid="@Foreach" source="ognl:activeProductGroups" 
> value="ognl:productGroup">
>   <form jwcid="@Form" listener="ognl:listeners.viewProductVersion">
>    <tr valign="middle" align="left">
>      <td bgcolor="#333333" class="textbold" width="252" 
> valign="middle" align="left" ><span jwcid="@Insert" 
> value="ognl:productGroup.label"/>
>      </td>
>      <td bgcolor="#666666" width="350">
>             <span jwcid="selectProductVersion"/>
>      </td>
>    </tr>
>
>    <tr valign="middle" align="left">
>      <td bgcolor="#dddddd" width="" colspan="2" align="center">
>        <input type="Submit" name="" value="Submit">
>      </td>
>    </tr>
>   </form>
>   <tr>
>    <td bgcolor="#FFFFFF" width="252" valign="middle" 
> align="left">&nbsp;</td>
>    <td bgcolor="#FFFFFF" width="350">&nbsp;</td>
>   </tr>
>   </span>
> === template ===
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org