views:

1628

answers:

2

I have a Seam application originally generated by seam-gen with a view Search.xhtml.

Search.xhtml has a number of input fields, half of which are bound to the Office entity and half to the Devices entity.

For example, if you enter a hostname, it is bound to a field in Devices, if you enter a City, it is bound to a field in Office.

The destination page is going to be OfficeResult.xhtml by default, or, if a "Devices" property has been entered, to the DeviceResult.xhtml.

My question has 2 parts:

  1. What component should I use in Search.xhtml for the submit button? I assume h:commandButton, but then what do I use for the action? If I use a destination view, will that be overridden by the navigation rule in page.xml file?

  2. How to set up my Search.page.xml file? How do I condition the navigation on the parameter?

Here is Search.xhtml (pseudo code):

<h:inputText value="#{devicesList.devices.devSerialNum}" />
<h:inputText id="state" value="#{officeList.office.state}" />

<h:commandButton id="search" action="/OfficeResult.xhtml" value="Search"  />

Search.page.xml (pseudo code):

<navigation>
  <rule if devSerNum is set >
<redirect view-id="/DeviceResult.xhtml"/>
  </rule>
  <rule if state is set >
    <redirect view-id="/OfficeResult.xhtml"/>
  </rule>
</navigation>
A: 

Hi April,

I have had some difficulty understanding how the navigation works as well. I finally have mine working to some degree here are some ideas I would try:

  1. use pages.xml first with one to verify you can get your navigation working with the default, simple ruleset. /WEB-INF/pages.xml

  2. enable the trace loglevel for your application if you are unsure what is happening, chances may be Seam cannot find a component. 2.1 #{devicesList ... } may not be found if you are not importing it in your components.xml unless that component's name is devicesList. My components use their fully qualified name, com.stackoverflow ... The advantage of that is, you avoid collisions, but to access the component, you have to write out the full path or do an import as described above.

  3. verify the view id's exist (/OfficeResult.xhtml and /DeviceResult.xhtml)

  4. make sure every page is declared only once

  5. your commandButton should be an actual component from my understanding. If you have a searchAction, then it would be something like:

    #{searchAction.search}

Check out the seam examples, they work well and show you how to do many different things. You can download them in the seam source code which is about 130 MB including all of those examples.

Walter

A: 

If I'm understanding your question correctly, and based on your current design, I believe you could do something similar to this:

Your Search.xhtml file:

<h:inputText value="#{devicesList.devices.devSerialNum}" />
<h:inputText id="state" value="#{officeList.office.state}" />

<h:commandButton id="search" action="#{devicesList.isDeviceSearch()}" value="Search"  />

Add a new method to your DevicesList.java file

@Name("devicesList")
public class DevicesListImpl implements DevicesList {

    ...other properties and methods...

    public boolean isDeviceSearch() {

        boolean result;

        ...logic to determine if the search value exists...

        return result;

    }
}

And then in your Search.page.xml file:

<navigation from-action="#{devicesList.isDeviceSearch()}">
    <rule if-outcome="true">
        <redirect view-id="/DeviceResult.xhtml" />
    </rule>

    <redirect view-id="/OfficeResult.xhtml" />
</navigation>
Aaron Chambers
Actually I ended up doing something like this. But instead of adding navigation to the page.xml file, I found it much easier to simply return the view-id from the subroutine. In other words, instead of "return result;" I conditionally returned "/DeviceResult.xhtml" or "/OfficeResult.xhtml" from isDeviceSearch().
Yep, that's another way you can do it, although some would argue that you are then mixing your navigation logic with your business logic, ie, should your DevicesList class actually know about the pages and which ones should be rendered? But that's something for you to decide. Glad you got it working ;)
Aaron Chambers