Problem with component containing form

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with component containing form

Spencer W. Thomas
I've created a simple component that contains a form that I want to use
to edit a simple object.  The object is a parameter to the form.

All works fine when I draw the HTML page, but when I hit the "submit"
button on the form, the object (which is a persistent page property) is
apparently not passed into the form component during rewind, because its
value is null.

In the real case, the form component is embedded inside another
component, which is in a Foreach.  I like the component based design,
but I can't figure out how to make this one work.  Any help would be
appreciated.

I'm attaching files for a simple example that shows the behavior.  The
page has two instances of the same form -- one is loaded from a
component, and the second is embedded directly in the page.  The second
form works; the first throws an exception when I click on Submit.

The .application, .page, .html, and .jwc files should go in WEB-INF; and
the java files are in the "test" package.

(This is my first time posting to the list; if the attachments don't
come through, my apologies, and I'll repost with them in the body of the
message.)

=Spencer Thomas, JSTOR
[hidden email]


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
  "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<!-- generated by Spindle, http://spindle.sourceforge.net -->

<application name="TapestryFormComponentTest" engine-class="org.apache.tapestry.engine.BaseEngine">
   
    <description>add a description</description>
   
    <page name="Home" specification-path="Home.page"/>
   
           
   
</application>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification PUBLIC
  "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<!-- generated by Spindle, http://spindle.sourceforge.net -->
<page-specification class="test.Home">
    <description>
        add a description
    </description>
    <property-specification name="item" persistent="yes" type="test.Item"/>
    <component id="body1" type="Body" />
    <component id="itemForm" type="MyForm">
        <binding name="item" expression="item"/>
    </component>
    <component id="form1" type="Form" />
    <component id="textField1" type="TextField">
        <binding name="value" expression="item.title"/>
    </component>
    <component id="submit1" type="Submit" />
</page-specification>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE component-specification PUBLIC
  "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<component-specification class="org.apache.tapestry.BaseComponent"
    allow-body="no"
    allow-informal-parameters="no">
    <parameter name="item" type="test.Item" direction="in"/>
    <component id="form2" type="Form"/>
    <component id="textField2" type="TextField">
        <binding name="value" expression="item.title"/>
    </component>
    <component id="submit1" type="Submit"/>
</component-specification>

package test;

public class Item
{
    private String title = "title";
    public String getTitle()
    {
        return title;
    }
    public void setTitle(String title)
    {
        this.title = title;
    }
}

package test;

import org.apache.tapestry.html.BasePage;

public class Home extends BasePage
{
    private Item item = new Item();
    public Item getItem()
    {
        return item;
    }
    public void setItem(Item item)
    {
        this.item = item;
    }
}

<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
    <display-name>TapestryFormComponentTest</display-name>
    <servlet>
        <servlet-name>TapestryFormComponentTest</servlet-name>
        <servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>TapestryFormComponentTest</servlet-name>
        <url-pattern>/app</url-pattern>
    </servlet-mapping>
</web-app>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Problem with component containing form

Robert Zeigler
Change the direction of item from "in" to either of "form" or "auto".
Also, in your home page, you don't need the property accessors, unless
you need to access the property from code. If you do, then the simplest
way to make sure things work right is to make your class and those
accessors abstract.

Robert

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Problem with component containing form

Spencer W. Thomas-2
I'll try that (when I get back to work tomorrow), but I thought I had
already tried using "form" for the direction and still had the problem.  
However, now that I think about it, I was nesting my form component
inside another component.  Presumably the parameter needs to be "form"
in BOTH components?

I need the explicit getItem() because I create the value of the Item in
the Java.  And once I've made an explicit getItem(), I must also supply
setItem() or Tapestry gets upset.

=S

Robert Zeigler wrote:

>Change the direction of item from "in" to either of "form" or "auto".
>Also, in your home page, you don't need the property accessors, unless
>you need to access the property from code. If you do, then the simplest
>way to make sure things work right is to make your class and those
>accessors abstract.
>
>Robert
>  
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Problem with component containing form

Robert Zeigler
Spencer W. Thomas wrote:
> I'll try that (when I get back to work tomorrow), but I thought I had
> already tried using "form" for the direction and still had the problem.
> However, now that I think about it, I was nesting my form component
> inside another component.  Presumably the parameter needs to be "form"
> in BOTH components?

Yes, or the direction can be auto, if the parameter is either required
or has a default value.

>
> I need the explicit getItem() because I create the value of the Item in
> the Java.  And once I've made an explicit getItem(), I must also supply
> setItem() or Tapestry gets upset.

Then you'll want to read up on tapestry properties.
Tapestry page instances are pooled, so standard getter/setters are a bad
idea, unless the item is not specific to any one user.
Have you considered implementing PageRenderListener and making the
accessors abstract? Then you could set the value using the abstract
accessors inside of pageBeginRender.

Robert

>
> =S
>
> Robert Zeigler wrote:
>
>> Change the direction of item from "in" to either of "form" or "auto".
>> Also, in your home page, you don't need the property accessors, unless
>> you need to access the property from code. If you do, then the simplest
>> way to make sure things work right is to make your class and those
>> accessors abstract.
>>
>> Robert
>>  
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Problem with component containing form

Spencer W. Thomas-2


Robert Zeigler wrote:

>>I need the explicit getItem() because I create the value of the Item in
>>the Java.  And once I've made an explicit getItem(), I must also supply
>>setItem() or Tapestry gets upset.
>>    
>>
>
>Then you'll want to read up on tapestry properties.
>Tapestry page instances are pooled, so standard getter/setters are a bad
>idea, unless the item is not specific to any one user.
>Have you considered implementing PageRenderListener and making the
>accessors abstract? Then you could set the value using the abstract
>accessors inside of pageBeginRender.
>  
>
I was just wondering about that this morning as I was walking into
work.  But the Tapestry "manifesto" is that we can pretend that we are
in a single-threaded, one-user-per-object world, so it seems it should
work.  And if the property is persistent, then whatever changes one
thread makes should get persisted to the session and the initial value
restored before the next thread gets control.

But in fact, it appears that the single item is shared.

Anyway, this was just a "spike".  In the real system, there's a database
and objects are loaded using their ids, and there's none of this "create
an object in main()" stuff going on.

=S

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Problem with component containing form

Spencer W. Thomas-2
In reply to this post by Robert Zeigler
 I'm still getting the "null" value for my item after changing the
direction to "form".  It does work with "auto" and required=yes, though.

Thanks for the pointer.

=S

Robert Zeigler wrote:

>Change the direction of item from "in" to either of "form" or "auto".
>
>  
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]