tags:

views:

6802

answers:

5

Hi all, i'm new to JSF and for the application i'm woriking on i've to do a multiple field input form.

In few words the user should have an inputText when he inputs his data and an "add" button which add a new input text in order to input another data. When the user is done, he pushes another submit button. I looked for something already done, but i haven't found anything, so i decided to create my own custom jsf component

The idea was to create a component combining a dataTable containing an inputText for each row in datatable, plus a button that add a row to the collection binded to the datatable.

I'm looking through the jsf documentation and books, but i'm a bit confused and i'm not sure if is it possible to create such a component... Can somebody help me? TIA

+3  A: 

It is possible to do everything you want.


You can build something close to what you want using existing controls. A good way to get the most out of JSF is to tailor the model for the view. For example, this view displays edit options that allow you to add values to a data table.

<f:view>
 <h:form>
  <h:dataTable value="#{people.list}" var="row">
   <h:column>
    <f:facet name="header">
     <h:outputText value="#" />
    </f:facet>
    <h:selectBooleanCheckbox value="#{row.selected}" />
   </h:column>
   <h:column>
    <f:facet name="header">
     <h:outputText value="First Name" />
    </f:facet>
    <h:inputText value="#{row.firstname}" />
   </h:column>
   <h:column>
    <f:facet name="header">
     <h:outputText value="Last Name" />
    </f:facet>
    <h:inputText value="#{row.lastname}" />
   </h:column>
   <f:facet name="footer">
    <h:panelGroup>
     <h:commandButton value="Add Row" action="#{people.addPerson}" />
     <h:commandButton value="Delete Selected"
      action="#{people.deleteSelected}" />
     <h:commandButton value="Finish" action="#{people.finish}" />
    </h:panelGroup>
   </f:facet>
  </h:dataTable>
 </h:form>
</f:view>

People bean:

public class People implements Serializable {

    private static final long serialVersionUID = 1L;

    private List<Person> people = new ArrayList<Person>();

    public People() {
     // initialise with one entry
     people.add(new Person());
    }

    public List<Person> getList() {
     return people;
    }

    public String addPerson() {
     people.add(new Person());
     return null;
    }

    public String deleteSelected() {
     Iterator<Person> entries = people.iterator();
     while (entries.hasNext()) {
      Person person = entries.next();
      if (person.isSelected()) {
       entries.remove();
      }
     }
     return null;
    }

    public String finish() {
     System.out.println(people);
     return "someNavigationRule";
    }

}

Person bean:

public class Person implements Serializable {

    private static final long serialVersionUID = 1L;

    private String firstname;
    private String lastname;
    private transient boolean selected = false;

    public String getFirstname() {
     return firstname;
    }

    public void setFirstname(String firstname) {
     this.firstname = firstname;
    }

    public String getLastname() {
     return lastname;
    }

    public void setLastname(String lastname) {
     this.lastname = lastname;
    }

    public boolean isSelected() {
     return selected;
    }

    public void setSelected(boolean selected) {
     this.selected = selected;
    }

}

faces-config.xml:

<managed-bean>
 <managed-bean-name>people</managed-bean-name>
 <managed-bean-class>addmultiple.People</managed-bean-class>
 <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

This approach is quite flexible and with some CSS, can look quite good. With a few changes to the view and model, you can have only the last row editable, for example.


If the resultant experience isn't rich enough or if you need something you can reuse, you can create a custom control. It is difficult to get into the specifics without knowing exactly what you want, but you probably would need:

  1. A new Renderer for emitting HTML and decoding form requests.
  2. (Maybe) a new component, probably extending UIData, and a concrete form for exposing renderkit-specific (e.g. HTML) attributes.
  3. A new JSP tag class for allowing the control to be used in JSPs.
  4. Definitions for all of the above in a faces-config.xml (see spec).
McDowell
A: 

McDowell thanks a lot!!!! I found the first solution easier for me, i followed it and i think that fits very well, the reusable approach seems the best choice, but is difficult for me to implement at this moment.

Thanks again

A: 

We have to use scope session???

You don't. And if you do need some state of some params use something like t:saveState (Tomahawk).
Jurgen H
A: 

Nice post, McDowell.

It would also be nice to add a lable for each inputText in the dataTable, but then you need to provide an id for the inputText. But in the id field, no EL can be used, so using something like this is impossible:

Any ideas? Thanx

Jurgen H
I found out in the meantime. For the id's of the input fields, a fixed value can be used. JSF itself creates an indexed prefix for each row.
Jurgen H
A: 

Hi, I am new to JSF. I am using the mentioned h:commandButton inside a4j:form and during this I am getting an js error. But if I use the same as a4j:commandButton the row is not added. Please help me...

jsf overload
Open a new question for your problem and post your errors
Damo