0

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>
Dave
  • 545
  • 3
  • 14
  • 29

1 Answers1

1

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:

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Thanks Luiggi. I made the changes but get: malformed xml unable to get value of the property removechild object is null or undefined. Any ideas? – Dave Jul 27 '12 at 15:19
  • It's a very odd error. Try to detect which part of your xhtml is giving you this error by commenting part of the code, then uncomment (maybe the error is not in the code fragment I've posted). When you detect the real error, update your question and leave a comment to give you a better guidance. – Luiggi Mendoza Jul 27 '12 at 15:25
  • From the internet I see that it is related to the f:ajax statement. I removed that and the exception disappears. By the way, I'm viewing the page in Eclipse, not IE9. – Dave Jul 27 '12 at 15:36
  • Try changing your ajax like this: `` – Luiggi Mendoza Jul 27 '12 at 15:47
  • Nope, I get: contains an unknown id ':dtMyDataTable' - cannot locate it in the context of the component j_idt11 – Dave Jul 27 '12 at 15:56
  • `` should work fine the first time, I don't understand why is giving you problems. – Luiggi Mendoza Jul 27 '12 at 16:00
  • I get the malformedXML message the first time I click the commandButton. Note, I removed the ":" in front of dtMyDataTable. But other than Ajax not working, everything else is. – Dave Jul 27 '12 at 16:16
  • Very strange. For your problem, just remove the ajax tag and it should be working, if you want to add ajax behavior, you could use a third party library like [PrimeFaces](http://www.primefaces.org) or [RichFaces](http://www.jboss.org/richfaces/) – Luiggi Mendoza Jul 27 '12 at 16:21