Submit Button wird nicht enabled

Hallo,

Ich habe ein Formular in dem man eine Kategorie erstellen kann. Dazu gibt man einen Namen in den Input ein.
Der Input hat einen Validator der überprüft ob bereits eine Kategorie mit diesem Namen vorhanden ist.

Der Kategorie /Submit Button soll, solange der Validator invalid ist und kein Kategorienamen vergeben wurde disabled sein.

Ich habe das so gemacht:

                    <fieldset>
                        <h:outputLabel for="category" value="#{msg['category.create']}"/>
                        <h:inputText id="category" required="true"  label="#{msg['category.create']}" value="#{CreateCategoryBean.newCategory.name}" >
                            <f:validator validatorId="Get.Validator.CategoryValidator" />
                            <f:ajax event="keyup" render="categorymessage submit"  />
                        </h:inputText>
                        
                        <h:messages for="category" id="categorymessage"/>
<h:commandButton id="submit" value="#{msg['default.create']}" action="#{CreateCategoryBean.CreateCategory()}"
                             disabled="#{not category.valid}"   />
                    </fieldset>

Obwohl im Validator keine ValidationException geworfen wird, wird der Submit Button nicht enabled. Kann es sein, dass disabled="#{not category.valid}" nicht upgeadeted wird?

Außerdem wird zu beginn, wenn die Seite geladen wird, der Validator nicht aufgerufen. Das heißt bei <h: messages wird die Meldung “Create category: Validation Error: Value is required.” nicht ausgegeben.

Der Validator ist übrigens in diesem Post zu finden http://forum.byte-welt.net/showthread.php?t=4719

Könnt ihr mir sagen, was hier fehlt?

Du musst das Textfeld auch „abschicken“ so wird ohne den Button nichts abgeschickt:

<f:ajax event=„keyup“… execute=„@this“…/>

obwohl eigentl. is this ja Standard wenn ich mich gerade nicht vertue ^^ ich schau mal kurz

Hast Du es mal mit einem Breakpoint ausprobiert? Wird der Validator vernünftig durchlaufen? Was passiert, wenn Du einen Breakpoint in der getValid()-Methode hast?

Sry war nochmal kurz weg,… Also das hier geht auf jeden Fall:

@ViewScoped
public class Bean {
	private String text;
	
	

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}
}```

```@FacesValidator("MyValidator")
public class Validator implements javax.faces.validator.Validator{

	@Override
	public void validate(FacesContext context, UIComponent component,
			Object value) throws ValidatorException {
		
		if(!value.equals("okay")){
			throw new ValidatorException(new FacesMessage("Not"));
		}
		System.out.println("okay");
	}

}```


```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> 

<h:head></h:head>
<h:body>

    <h:form>
        <h:panelGrid>
            <h:inputText id="input" value="#{bean.text}" >
                   <f:validator validatorId="MyValidator"></f:validator>
                  <f:ajax event="keyup" execute="@this" render="mess submit" />  
            </h:inputText>
           <h:message for="input" id="mess" />
           <h:commandButton id="submit" value="Button"  disabled="#{empty bean.text or facesContext.validationFailed}"/>
        </h:panelGrid>
    </h:form>

</h:body>
</html>

Zeig mal deine ganze XHTML- Seite

Hallo,

hier der ganze Code von der View

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <body>
        <ui:composition template="./templates/template.xhtml">
             <ui:define name="content">
                <h:form>
                    <fieldset>
                        <h:outputLabel for="category" value="#{msg['category.create']}"/>
                        <h:inputText id="category" required="true"  label="#{msg['category.create']}" value="#{CreateCategoryBean.newCategory.name}" >
                            <f:validator validatorId="Get.Validator.CategoryValidator" />
                            <f:ajax event="keyup" render="categorymessage submit" execute="@this"   />
                        </h:inputText>
                        <h:messages for="category" id="categorymessage"/>                  
                        <h:commandButton id="submit" value="#{msg['default.create']}" action="#{CreateCategoryBean.CreateCategory()}"
                             disabled="#{empty CreateCategoryBean.newCategory.name or not category.valid}"   />
                    </fieldset>
                </h:form>
            </ui:define>
        </ui:composition>
    </body>
</html>

Ich habe das execute="@this" mit eingebaut, aber der Button wird trotzdem nicht enabled. Wenn ich mit dem Debugger in den Validator rein gehe, wird auch keine Validatorexception geworfen. Es sollte also passen. Eine getValid Methode habe ich nicht. Nur eine public void validate(…) Funktion. Das Interface Validator verlangt keine getValid Methode oder habe ich was übersehen? Ich werde morgen pl4gu33’s Beispiel ausprobieren und schauen ob das bei mir tut.

bau mal bei dir <h:head>…</h:head> ein und benutz <h:body>…</h:body>

Ich habe die head durch h:head ersetzt. Gleiches Ergebnis.

Ich habe dein Beispiel pl4gu33 nachgebaut. Dort funktioniert es.

Ich verwende JSF 2.1.

Du hast also mein Beispiel als eigenes Projekt ausgeführt? Und er geht weder in den Validator, o.ä ?

Dein Beispiel habe ich als eigenständiges Projekt erstellt und es funktioniert. Warum es bei meinem Projekt nicht funktioniert ist mir nicht ganz geheuer.

Ich habe das Projekt als Attachment beigefügt.

Man muss die Datasource entsprechend anpassen, damit es lauffähig ist.

Also ich hab mir jetzt ne H2 DB in den Glassfish reingehangen,… Hab aber noch kein Model-Gen, darum gibts dann ne Exception im Validator. Wenn ich die XHTML starte und dann ein Buchstaben eingebe isser direkt im Validator und schmeißt halt ne Exception. Aber Ansich funktioniert es bei mir. Der Validator wird angesprochen. Hab auch noch paar Sachen rausgeschmissen etc. hier meine Version … einfach als Archiv importieren, Data Source ändern und starten. Schau mal ob er bei dir dann in den Validator geht:

ps. hatte als Implementierung OpenJPA drin musste auch nochmal zurück ändern für dich dann.

[QUOTE=pl4gu33]Also ich hab mir jetzt ne H2 DB in den Glassfish reingehangen,… Hab aber noch kein Model-Gen, darum gibts dann ne Exception im Validator. Wenn ich die XHTML starte und dann ein Buchstaben eingebe isser direkt im Validator und schmeißt halt ne Exception. Aber Ansich funktioniert es bei mir. Der Validator wird angesprochen. Hab auch noch paar Sachen rausgeschmissen etc. hier meine Version … einfach als Archiv importieren, Data Source ändern und starten. Schau mal ob er bei dir dann in den Validator geht:

ps. hatte als Implementierung OpenJPA drin musste auch nochmal zurück ändern für dich dann.[/QUOTE]

In den Validator geht er bei mir auch, aber wenn er keine Exception wirft wird wird eben der Button nicht enabled.

okay dann hatte ich da ein bisschen missverstanden, da ich hier auf der Arbeit immer nur kurz drüber gucken kann.

Hattest du gesehen, dass ich "facesContext.validationFailed benutze und nicht dieses valid auf der Componente, weil das ging bei mir auch nicht richtig.

[QUOTE=pL4Gu333]
Hattest du gesehen, dass ich "facesContext.validationFailed benutze und nicht dieses valid auf der Componente, weil das ging bei mir auch nicht richtig. [/QUOTE]

Nein, sowas habe ich nicht in der Validator-, Beanklasse oder View gefunden.

Ich glaube ich werde es jetzt über eine Hilfsproperty lösen die angibt ob der Button disabled ist oder nicht.

Gibt es eine Möglichkeit vom Bean auf die View auf den Validator von <h:inputText id=“category” zu zugreifen, damit ich auf den status des Validator abfragen kann?

das „facesContext.validationFailed“ ist dafür da, dass du prüfen kannst, ob eine Validierung fehlgeschlagen ist. Schau dir mal meine XHTML an, dort ist es bei dem Button drin. Das kannst du einfach in JSF benutzen! :wink:

http://docs.oracle.com/javaee/6/api/javax/faces/context/FacesContext.html#isValidationFailed()

disabled="#{empty bean.text or facesContext.validationFailed}"

Danke damit funktioniert es. :slight_smile: