tags:

views:

26

answers:

1

I'm currently developing an additional page to an already existing website. Actually that part isn't really that important - the page performs it's own separate functions.

Anyway, originally, this "page" consisted of two pages controlled by one jpdl pageflow. Everything worked correctly, except when referencing the second page. The user would input whatever they liked into the fields and click submit. Everything functioned as expected, except the set methods were never called. Despite reading existing values from the Backing Bean, it the setters were never called. I wrote some Seam tests and discovered that I could craft my own FacesRequest that would call setValue() on the same EL Expression and it worked fine, which pointed me to something failing on the JSF side. Still I never figured it out and moved on. Of course, now I've had to come back to it.

Code in question looks like... (irrelevant parts removed. There's a lot of cruft as these are pretty general and are in use in a lot of places):

@Name("user")
@Install(precedence = Install.DEPLOYMENT)
@Scope(ScopeType.CONVERSATION)
@AutoCreate
public class UserBean{
    private String username;
    public void setUsername(String username){this.username = username;}
    public String getUsername(){return username;}
}

And a basic snippet of page "users.xhtml"...

<h:form id="modifyUsersForm">
    <rich:panel>
        <rich:dataTable id="userTable" value="#{users}" var="myUser">
            <rich:column style="text-align:center">
                <h:commandButton id="modifyButton" type="submit" value="Modify" action="modify">
                    <f:setPropertyActionListener target="#{user.id}" value="#{myUser.id}"/>
                </h:commandButton>
            </rich:column>
        </rich:dataTable>
    </rich:panel>
    <s:button id="modifyUserCancelButton" value="Cancel" action="cancel"/>
    </s:fragment>
</h:form>

users is a bean that extends LinkedList<UserBean>. All that basically does is creates a table of buttons that say "Modify"

A basic snippet of page "user.xhtml"...

<h:form id="modifyUserForm">
    <rich:panel>
        <h:inputText id="username" value="#{user.username}"/>
        <div style="clear: both"/>
    </rich:panel>
    <s:button id="modifyUserCancelButton" value="Cancel" action="cancel"/>
    <s:button id="modifyUserModifyButton" value="Modify" action="doModify"/>
</h:form>

"users.pageflow.jpdl.xml" of...

<pageflow-definition xmlns="http://jboss.com/products/seam/pageflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="users">

    <start-page name="start" view-id="/users.xhtml" no-conversation-view-id="/users.xhtml">
        <transition name="cancel" to="cancelled"/>
        <transition name="retrieve" to="retrieve"/>
    </start-page>

    <decision name="retrieve_agent" expression="#{action.retrieve}">
        <transition name="success" to="retrieved"/>
        <transition name="failure" to="start"/>
    </decision>

    <page name="retrieved" view-id="/users.xhtml" no-conversation-view-id="/users.xhtml">
        <transition name="modify" to="retrieve_user"/>
        <transition name="cancel" to="cancelled"/>
    </page>

    <decision name="retrieve_user" expression="#{action.retrieveUser}">
        <transition name="success" to="modify"/>
        <transition name="failure" to="start"/>
    </decision>

    <page name="modify" view-id="/user.xhtml" no-conversation-view-id="/user.xhtml">
        <transition name="cancel" to="cancelled"/>
        <transition name="doModify" to="doModify"/>
    </page>

    <decision name="doModify" expression="#{action.modifyUser}">
        <transition name="success" to="start"/>
        <transition name="failure" to="modify"/>
    </decision>

    <page name="cancelled" view-id="/users.xhtml">
        <end-conversation before-redirect="true"/>
        <redirect/>
    </page>
</pageflow-definition>

So what am I missing? Why isn't setUsername being called on user.xhtml during as part of the JSF lifecycle, when it's successfully calling getUsername on the same page? We're using Java 1.6.0_07, Seam 2.2.1, JSF 1.1 (I believe. Small chance it could be 1.2), and deploying into JBoss 4.2.3.

+1  A: 

Have you tried with h:commandButton? s:button performs a GET, and not POST. Perhaps that will help.

Shervin
I'll certainly give that a try. My understanding is that since it can correctly read the variable from that UserBean through the getter on the second page, it should be able to also write to that variable through the setter. However, I don't understand the intricacies GET/POST. Well to be honest, I don't even know the basics ;)
JBirch
You are right. It will use the setter when you do a POST. It will post the form. Using GET, you can for instance send the object as parameter to some action method, and use it there. You definitely should read up on HTML before doing this kind of stuff.
Shervin
I know right? Thrown into this stuff headfirst >.< That being said, your idea was the correct solution, and I had actually used `h:commandButton` in most other places - in fact in other sections of this page which I had omitted. I fact I'm not entirely sure where the use of `s:button` came from :/
JBirch