wake-up-neo.com

JSF überspringen Required-Validation ohne sofort = true

Ich habe mehrere Formulare, in denen ich Pflichtfelder und optionale Felder habe.

Für submit ein solches Formular muss die Validierung des erforderlichen Attributs ausgeführt werden, was gut funktioniert. _. Für Cancel ein solches Formular verwende ich das Attribut immediate="true" für den p:commandbutton , was seine Aktion während der hier angesprochenen Apply Request Values ​​ -Phase bewirkt: Wie kann die Validierung übersprungen werden, wenn eine bestimmte Schaltfläche angeklickt wird?

Bei großen Formularen möchte ich dem Benutzer jedoch eine Schaltfläche zum Speichern geben, damit er später fortfahren kann.

Um nur den aktuellen Zustand zu speichern, möchte ich auch die Überprüfung des erforderlichen Attributs ignorieren. Die Verwendung von immediate="true" funktioniert jedoch nicht, da meine Save-Methode einfach nichts speichert, da der JSF-Lebenszyklus niemals die "UpdateModelValues" -Phase trifft. (Gemäß http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html )

Wie kann man also die erforderliche Prüfung umgehen, aber nicht den halben Lebenszyklus überspringen? 

39
dognose

Jede Schaltfläche erstellt einen Eintrag in der Param-Liste, solange sie Mitglied des Formulars ist. Also habe ich einfach überprüft, ob dieser Eintrag vorhanden ist, und zwar für den Parameter "required":

<h:form id="form" prependId="true">
...
<p:inputText id="someId"
    required="#{param['form:save']==null}" ... />
...
<p:commandButton id="save" value="Save" />
<p:commandButton id="submit" value="Submit" />
<p:commandButton id="cancel" value="Cancel" immediate="true" />
</h:form>

Wenn ich auf "Senden" klicke, ist der param['form:save']NULL, der den Ausdruck in true umwandelt, so dass die Validierung ausgeführt wird.

Wenn ich auf "Speichern" klicke, ist der param['form:save']NOT NULL (aber leer!), Der in false aufgelöst wird, so dass die Überprüfung ignoriert wird. (Oder nehmen wir an, JSF hält es für nicht erforderlich, da der Ausdruck als false ausgewertet wird.)

62
dognose

wenn Sie die Validierung beim Klicken auf die Schaltfläche überspringen möchten, fügen Sie der Schaltfläche dort, wo Sie sie überspringen möchten, Parameter hinzu. Beispiel:

<p:commandButton value="button1" action="#{bean.action()}" >
   <f:param name="skipValidator" value="true"/>
</p:commandButton>

Dann können Sie in validator diesen Parameter lesen und wenn es wahr ist, dann überspringen Sie es:

@FacesValidator("com.validators.MyValidator")
public class MyValidator implements Validator{

  public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException { 
    if(!continueValidation()){
      return;
    }
    // validation process
  }

protected boolean continueValidation() {
    String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator");
    if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) {
      return false;
    }
    return true;
  } 
}
5
Juraj

Dies ist eine ausgezeichnete Frage und eine sehr hilfreiche Antwort. Dieser Ansatz spart mit immediate="true" viel Ärger.

Ich möchte diese Informationen hinzufügen (darf aber noch nicht kommentieren). Ihre Codebeispiele scheinen JSF 2.0 oder höher zu erfordern (korrigieren Sie mich). Wenn Sie, wie ich es verdammt habe, JSF 1.1/1.2 zu verwenden, bedenken Sie diese Änderungen/Ergänzungen:

<h:form id="form">
...
<p:inputText id="someId" required="#{!empty param['save']}" ... />
...
<p:commandButton id="save" value="Save" />
</h:form>
  • In JSF 1.1 gibt es kein Attribut prependId
  • Daher müssen Sie im param [...] nur die Schaltflächen-ID angeben
  • Sie verwenden eine ="{true and ...}"-Syntax, die möglicherweise ein Fehler ist (kein #)?
  • Wie Sie aus Ihrer eigenen Bearbeitungshistorie sehen können, ist die "Null- oder Nicht-Null" -Logik nicht sehr intuitiv :) Deswegen hat mir die !empty ...-Version sofort gefallen, als ich darauf gestoßen bin.
4
SebastianH

Eine Alternative zu den anderen vorgeschlagenen Verfahren ist die Verwendung einer benutzerdefinierten BeanValidator, mit der das Formular überprüft wird. Jede andere Schaltfläche, die nicht implizit für die Validierung definiert ist, wird nicht validiert, sondern übermittelt nur Ihre verfügbaren Daten. Finden Sie das vollständige schöne und saubere Beispiel hier

1
Given Nyauyanga

In meinem Fall habe ich die clientId der Schaltfläche in den Parametern nicht gefunden, aber ich fand diese param['javax.faces.source'] = buttonClientId in der Requestmap. Der Wert ist die clientId der angeklickten Schaltfläche.

0
Shady Aziz

Ich benutze skipValidators für einen solchen Fall (vorausgesetzt, alle Validierungen werden übersprungen). Code aus omnifaces

<h:form>
  <h:dataTable value="#{bean.items}" var="item">
    <h:column>
        <h:inputText value="#{item.value}" required="true" />
    </h:column>
  </h:dataTable>
  <h:commandButton value="add new row" action="#{bean.add}">
    <o:skipValidators />
  </h:commandButton>
  <h:commandButton value="save all data" action="#{bean.save}" />
  <h:messages />
</h:form>
0
dr0ps