Dave
Dave

Reputation: 557

navigation when bean returns objects

Beginner question concerning changing the information in a view (and not going to a different .xhtml page). My .xhtml displays a datatable (which shows a list of people), but I want the user to be able to narrow the amount of info displayed by typing in the start of someones name into an inputtext and then clicking the commandbutton. Both the commandbutton and the datatable execute the same bean method, but if the inputtext has data the sql uses Like (this uses jdbc). My form is below, the problem is that I get an "Unable to find matching navigation case with from-view-id" because my managed bean returns a list of objects, not "success" or "failure". Also, the whole form seems inefficient. This seems like a fairly common scenario - calling managed bean's method that returns objects and not navigation instructions. How do I get rid of the error messages? Is there a better way to do this?

Here is code:

<h:head>
    <h:outputStylesheet library="css" name="table-style.css"  />
</h:head>

<h:body>

    <h1>MavenWeb</h1>

    <h:form>
        <h:panelGrid columns="3">
            Select a customer:

            <h:inputText id="listName" value="#{customer.listName}" 
                size="20" >
            </h:inputText>
            <h:commandButton value="Submit"
                                         action="#customer.getCustomerList()}" />

        </h:panelGrid>



    <h:dataTable value="#{customer.getCustomerList()}" var="c"
            styleClass="order-table"
            headerClass="order-table-header"
            rowClasses="order-table-odd-row,order-table-even-row"
        >

        <h:column>
            <f:facet name="header">
                Customer ID
            </f:facet>
                #{c.customerID}
        </h:column>

        <h:column>
            <f:facet name="header">
                Name
            </f:facet>
                #{c.name}
        </h:column>

        <h:column>
            <f:facet name="header">
                Address
            </f:facet>
                #{c.address}
        </h:column>

        <h:column>
            <f:facet name="header">
                Created Date
            </f:facet>
                #{c.created_date}
        </h:column>

    </h:dataTable>
</h:form>
</h:body>

Upvotes: 0

Views: 688

Answers (1)

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

First, make sure your managed bean has ViewScope, so only the form values will be affected on every request while you're in the same view. Second, you can add ajax behavior to your <h:commandButton> and render the <h:datatable> with the new values. Third, never put business logic inside your attribute getters, because the JSF framework could make 2 or more calls of those getters (depending on your design).

Using these rules, you can remake your code like this:

@ViewScoped
@ManagedBean
public class Customer {
    private String listName;
    private List<CustomerDTO> customerList;

    public Customer() {
        listName = "";
        customerList = null; //maybe you can initialize your list here
    }

    //getters and setters...

    //look that this method returns a void (no need to return a navigation rule)
    public void fillCustomerList() {
        //your method/way to fill the customerList goes here...
        //I'll just put a code example
        customerList = new ArrayList<CustomerDTO>();
        customerList.add(new CustomerDTO(1, "Luiggi Mendoza", "Lima", new Date());
        customerList.add(new CustomerDTO(2, "StackOverflow", "Web", new Date());
    }

}

The code fragment for your page

<h:form>
    <h:panelGrid columns="3">
        Select a customer:
        <h:inputText id="listName" value="#{customer.listName}" size="20" />
        <h:commandButton value="Submit" action="#customer.fillCustomerList}">
            <f:ajax execute="@this" render="dtMyDataTable" />
        </h:commandButton>
    </h:panelGrid>

    <h:dataTable id="dtMyDataTable" value="#{customer.customerList}" var="c"
        styleClass="order-table"
        headerClass="order-table-header"
        rowClasses="order-table-odd-row,order-table-even-row">
        <h:column>
            <f:facet name="header">
                Customer ID
            </f:facet>
            #{c.customerID}
        </h:column>
        <h:column>
            <f:facet name="header">
                Name
            </f:facet>
            #{c.name}
        </h:column>
        <h:column>
            <f:facet name="header">
                Address
            </f:facet>
            #{c.address}
        </h:column>
        <h:column>
            <f:facet name="header">
                Created Date
            </f:facet>
            #{c.created_date}
        </h:column>
     </h:dataTable>
</h:form>

More info on this matter:

Upvotes: 1

Related Questions