web-dev-qa-db-fra.com

Les champs de saisie ne contiennent les valeurs précédentes que si la validation échoue

Je suis venu avec un problème étrange. J'ai essayé d'isoler le problème afin de suivre mon code simplifié.

public class MyBean {

  private List<Data> dataList;
  Data selectedData;

  public MyBean() {
    dataList = new ArrayList<Data>();
    dataList.add(new Data("John", 16));
    dataList.add(new Data("William", 25));
  }

  public List<Data> getDataList() {
    return dataList;
  }

  public void edit(Data data) {
    selectedData = data;
  }
  public void newData() {
    selectedData = new Data(null, null);
  }

  public Data getSelectedData() {
    return selectedData;
  }

  public class Data {
    String name;
    Integer age;
    Data(String name, Integer age) {
      this.name = name;
      this.age = age;
    }
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name = name;
    }
    public Integer getAge() {
      return age;
    }
    public void setAge(Integer age) {
      this.age = age;
    }
  }
}

xhtml:

<rich:modalPanel id="pop">
  <h:form>
    Name: <h:inputText value="#{myBean.selectedData.name}" required="true" id="txtName"/><br/>
    Age : <h:inputText value="#{myBean.selectedData.age}" required="true" id="txtAge"/>
    <a4j:commandButton value="Save"/>
    <a4j:commandButton value="Close" onclick="Richfaces.hideModalPanel('pop');return false;"/>
    <br/>
    <rich:message for="txtName"/><br/>
    <rich:message for="txtAge"/>
  </h:form>     
</rich:modalPanel>

<h:form>
  <rich:dataTable value="#{myBean.dataList}" var="data">
    <rich:column>#{data.name}</rich:column>
    <rich:column>
      <a4j:commandLink value="Edit" action="#{myBean.edit(data)}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
    </rich:column>
  </rich:dataTable>
  <a4j:commandButton value="New" action="#{myBean.newData()}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
</h:form>

C'est le chemin de l'erreur:

  1. Charger la page
  2. Cliquez sur le lien "Modifier" dans la première ligne (la fenêtre contextuelle s'affiche)
  3. Dans la fenêtre contextuelle, effacez le champ "Age" et cliquez sur "Enregistrer". (Le message requis apparaît.)
  4. Cliquez sur annuler (sans remplir le champ "Age")
  5. Cliquez sur le deuxième lien.
  6. Maintenant, il montre des données non pertinentes (données précédentes). - C'est le problème
  7. Même lorsque je clique sur le bouton "Nouveau", il affiche des données incorrectes.

Cela se produit uniquement si une validation échoue dans la fenêtre contextuelle.
Y a-t-il une solution à cela?

12
prageeth

Ce problème dans JSF 2 est également reconnu et expliqué en détail dans la réponse suivante: Comment renseigner un champ de texte à l’aide de PrimeFaces AJAX après que des erreurs de validation se sont produites? Si vous utilisiez JSF 2, vous auriez pu utiliser OmniFaces ' ResetInputAjaxActionListener ou PrimeFaces' <p:resetInput> OU resetValues="true" pour cela.

En fait, vous devez effacer l'état du composant EditableValueHolder lorsqu'il est sur le point d'être rendu ajax, mais qu'il n'est pas inclus dans ajax-execute. Pour effacer l'état, dans JSF 2, vous auriez utilisé la méthode de commodité resetValue() , mais cette option n'est pas disponible dans JSF 1.2 et vous devez appeler les 4 méthodes individuelles setValue(null), setSubmittedValue(null), setLocalValueSet(false), setValid(true) pour effacer l'état.

Pour déterminer quels composants doivent être rendus ajax, mais n'ont pas été exécutés par ajax, dans JSF 2, vous auriez utilisé des méthodes PartialViewContext pour cela, mais cela n'est pas disponible dans JSF 1.2, qui n'a pas encore normalisé ajax. Pour comprendre cela, vous devez manipuler l'API ajax spécifique à RichFaces. Je ne peux pas le dire du haut de la tête, voici donc un exemple de coup d'envoi en supposant que vous connaissez déjà les composants à nettoyer. Imaginez que le formulaire dans votre popup ait id="popForm" et que le champ de saisie du nom ait id="nameInput", voici comment vous pouvez le supprimer dans la méthode newData():

UIInput nameInput = (UIInput) context.getViewRoot().findComponent("popForm:nameInput");
nameInput.setValue(null);
nameInput.setSubmittedValue(null);
nameInput.setLocalValueSet(false);
nameInput.setValid(true);
31
BalusC

faire une chose sur l'action cancel définir toutes les valeurs popup null. maintenant, dans votre prochain clic, toutes les valeurs définies pour être la valeur par défaut.

ou cliquez sur définir toutes les valeurs précédentes null. et définir toutes les valeurs respectives après cela.

1
durgesh6121

J'ai eu le même problème. si vous utilisez Primefaces, la solution est aussi simple que de mettre resetValues="true" sur votre p: commandLink ou p: commandButton qui charge l'élément sélectionné.

1
hendinas