user2471366
user2471366

Reputation: 73

JF2 Dynamic form element doesn't remember input and page refreshes every time I add element

I am trying to make a form with options to add rows. However, after I type in some input and click the add button again, the input I enter disappears. I'm not sure what is wrong with my code. In addition, when I click the add button, the page refreshes. Is there way to stop this page refresh?

Person.java

public class Person{

    private List<String> guys = new ArrayList<String>();

public List<String> getGuys() {
    return guys;
}
public void setGuys(List<String> guys) {
    this.guys = guys;

public void addNewItem(){
    guys.add("");
}
}

form.xhtml

      <h:form>
        <h:panelGrid columns="2">              
          <h:outputText value="Guys: " />
          <h:dataTable value="#{person.guys}" var="men">
            <h:column>
              <p:inputText value="#{men}" />
            </h:column>
          </h:dataTable>
          <h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
        </h:panelGrid>
        <br />
        <h:commandButton name="submit" type="submit" value="Submit"></h:commandButton>
  </h:form>

Upvotes: 1

Views: 158

Answers (3)

BalusC
BalusC

Reputation: 1109272

Provided that the bean is placed in the right scope for the functional requirement, the view scope, the only major mistake left is that you're expecting that the String class has some magic setter method.

It hasn't. The String class is immutable. The following will never work on a String:

<p:inputText value="#{men}" />

You have 2 options:

  1. Create a real model class. You can find complete examples in the following answers:


  2. Set the value by row index instead:

    <h:dataTable binding="#{table}" value="#{person.guys}">
        <h:column>
            <p:inputText value="#{person.guys[table.rowIndex]}" />
        </h:column>
    </h:dataTable>
    

    (note: no additional bean property necessary for the table! the code is as-is)

    This does basically a person.getGuys().add(table.getRowIndex(), submittedValue). I.e. the setter is invoked on the List itself, which works perfectly fine. See also the following related answers concerning ui:repeat:

Upvotes: 3

danRod
danRod

Reputation: 113

You never update your list, you are just adding empty items. You should do something like this: Person.java (viewscoped)

public class Person implements Serializable {
  private List<String> guys = new ArrayList<String>();
  private HtmlDataTable dtGuys;

  public void addNewItem() {
    guys.add("");
  }

  public void addToList(ValueChangeEvent e) {
    guys.set(dtGuys.getRowIndex(), e.getNewValue().toString());
  }

  public String save() {
    System.out.println("saving...");
    for (String item : guys) {
        System.out.println("item= " + item);
    }
    return null;
  }
  //gettes and setters
}

form.xhtml

<h:form id="frmPrincipal">
  <h:panelGrid columns="2">
    <h:outputText value="Guys: " />
    <h:dataTable value="#{person.guys}" var="men" binding="#{person.dtGuys}" >
      <h:column>
        <p:inputText value="#{men}" valueChangeListener="#{person.addToList}" />
      </h:column>
    </h:dataTable>
    <h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
  </h:panelGrid>
  <br />
  <h:commandButton id="submit" name="submit" value="Submit" action="#{person.save}"/>
</h:form>

Using jsf 2.0.10 and primefaces 3.5

Upvotes: 0

rekiem87
rekiem87

Reputation: 1573

Its because you don't have an scope for that bean, so its request scoped, so when you call the action the bean is created again, you can fix this using a sessionScope or conversationScope

Upvotes: -1

Related Questions