# JSF Button - Methode wird nicht aufgerufen



## masterjule (1. Mrz 2012)

Hallo,

ich arbeite, zur Übung hauptsächlich, im Moment an einem kleinen Projekt.

Komme leider grad nicht weiter. Ich habe eine Seite mit JSF und Primefaces.
AUf der Rechten Seite sind Eingabefelder und darunter ein "Speichern"-Button.
Aber wenn ich den Button klicke, wird zwar die Seite neu geladen, aber meine save-Methode im Handler wird nicht aufgerufen.

Weis jetzt einfach nicht weiter und wende mich deshalb an euch.

Hoffentlich könnt ihr mir helfen!

index.xhtml

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">

    <f:view contentType="text/html">
        <h:head>
            <f:facet name="first">
                <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
                <title>jBook</title>
            </f:facet>

            <link type="text/css" rel="stylesheet" href="default.css" />

            <style type="text/css">
                .ui-layout-north {
                    z-index:20 !important;
                    overflow:visible !important;;
                }

                .ui-layout-north .ui-layout-unit-content {
                    overflow:visible !important;
                }
            </style>
        </h:head>


        <h:body>
            <h:form id="form" prependId="false">
            <p:layout id="mainLayout" fullPage="true" >

                <p:layoutUnit id="top" position="north" size="50">
                    
                </p:layoutUnit>

                <p:layoutUnit id="bottom" position="south" size="60">
                    
                </p:layoutUnit>

                <p:layoutUnit id="left" position="west" size="300" resizable="true" closable="true" collapsible="true" header="Options" minSize="200">
                    <h:form>
                        <p:commandButton value="Neu" action="#{derTestHandler.newBook}" ajax="false" />
                        <p:commandButton value="Neuladen" action="#{derTestHandler.reload}" ajax="false" />
                        <p:commandButton value="Testdaten" action="#{derTestHandler.generateTestData}" ajax="false" />
                        <p:commandButton value="x" actionListener="#{derTestHandler.mach}" ajax="false" />
                        
                    </h:form>
                </p:layoutUnit>

                <p:layoutUnit id="right" position="east" size="320" header="hjhjh" resizable="true" closable="true" collapsible="true" collapsed="#{derTestHandler.c}">
                    <h:form>
                        <ui:include src="inputBook.xhtml" />
                    </h:form>
                </p:layoutUnit>

                <p:layoutUnit id="center" position="center">
                    <h:form>
                        
                        <ui:include src="table.xhtml" />
                        
                    </h:form>


                </p:layoutUnit>

            </p:layout>
            </h:form>

        </h:body>

    </f:view>
</html>
```

inputBook.xhtml

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

    <h:form id="inputBook">
        
        <h:panelGrid id="test" columns="2" style="margin-bottom:10px" cellpadding="5">
             
            <h:outputText value="Titel" />
            <p:inputText id="title" value="#{derTestHandler.book.title}" required="true" />
           
            <h:outputLabel value="Autor" for="author" />
            <p:autoComplete id="author" dropdown="true" value="#{derTestHandler.book.author.name}" completeMethod="#{derTestHandler.complete}" />
            
            <h:outputText value="Regal" />
            <p:inputText id="shelf" value="#{derTestHandler.book.shelf.name}" required="true" />
            
            <h:outputText value="Gelesen" />
            <p:selectBooleanCheckbox value="#{derTestHandler.book.read}" />
            
            <p:commandButton value="Speichern" action="#{derTestHandler.save}" ajax="false" />
            <p:commandButton type="reset" value="Reset" />
            
        </h:panelGrid>
        
    </h:form>
</ui>
```

DerTestHandler.java

```
/*
 * 
 */
package com.mycompany.jbook.handler;

import com.mycompany.jbook.entities.Author;
import com.mycompany.jbook.entities.Book;
import com.mycompany.jbook.entities.Shelf;
import com.mycompany.jbook.facade.BookFacade;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.SelectEvent;

/**
 *
 */
@ManagedBean
@SessionScoped
public class DerTestHandler {
    @EJB
    private BookFacade bookFacade;
    
    private List<Book> bookList;
    private Book book = new Book();
    private List<Author> authorList;
    private double rating = 2;
    private boolean c = true;

    /**
     * Creates a new instance of DerTestHandler
     */
    public DerTestHandler() {
        book.setAuthor(new Author());
        book.setShelf(new Shelf());
    }
    
    public final void reload() {
        bookList = bookFacade.getAllBooks();
    }
    
    public void save() {
        authorList = bookFacade.getAllAuthors();
        for(Author a : authorList) {
            if(a.getName().equals(book.getAuthor().getName())) {
                book.setAuthor(a);
                break;
            }
        }
        bookFacade.save(book);
        String x = null;
    }
    
    public List<String> complete(String query) {
        initAuthorList();
        List<String> result = new ArrayList<String>();
        
        for(Author a : authorList) {
            if(a.getName().startsWith(query)) {
                result.add((a.getName()));
            }
        }
        
        return result;
    }
    
    public void newBook() {
        book = new Book();
        book.setAuthor(new Author());
        book.setShelf(new Shelf());
    }
    
    private void initAuthorList() {
        if(authorList == null) {
            authorList = bookFacade.getAllAuthors();
        }
    }

    /**
     * @return the rating
     */
    public double getRating() {
        return rating;
    }

    /**
     * @return the book
     */
    public Book getBook() {
        return book;
    }

    /**
     * @param book the book to set
     */
    public void setBook(Book book) {
        this.book = book;
    }

    /**
     * @return the bookList
     */
    public List<Book> getBookList() {
        return bookList;
    }

    public void generateTestData() {
        bookFacade.generateTestData();
    }
    
    public void onRowSelect(SelectEvent select) {
        this.book = (Book) select.getObject();
    }
    
    public void onRowUnselect() {
        newBook();
    }

    /**
     * @return the c
     */
    public boolean isC() {
        return c;
    }

    /**
     * @param c the c to set
     */
    public void setC(boolean c) {
        this.c = c;
    }
    
    public void mach() {
        Book n = book;
        if(c == true) {
            c = false;
        } else {
            c = true;
        }
    }
}
```

Gruß
Julian


----------



## nillehammer (1. Mrz 2012)

JSF ist schon etwas her. Kann sein, dass es inzwischen automatisch geht. Aber musst Du einer ManagedBean nicht irgendeinen Namen geben? Woher weiß JSF sonst, dass "derTestHandler" eine Instanz von TestHandler sein soll. So müsste es klappen:

```
@ManagedBean("derTestHandler")
```


----------



## JimPanse (1. Mrz 2012)

Das Problem ist folgender Code


```
<h:form id="form" prependId="false">
            <p:layout id="mainLayout" fullPage="true" >
                <p:layoutUnit id="left" position="west" size="300" resizable="true" closable="true" collapsible="true" header="Options" minSize="200">
                   <h:form>
                        <p:commandButton value="Neu" action="#{derTestHandler.newBook}" ajax="false" />
                        <p:commandButton value="Neuladen" action="#{derTestHandler.reload}" ajax="false" />
                        <p:commandButton value="Testdaten" action="#{derTestHandler.generateTestData}" ajax="false" />
                        <p:commandButton value="x" actionListener="#{derTestHandler.mach}" ajax="false" />
                        
                    </h:form>
                </p:layoutUnit>
       </h:form>
```

du hast zwei form Elemente in einander verschachtelt! Das ist laut HTML Spezifikation verboten:
SELFHTML: HTML/XHTML / Referenz /HTML-Elementreferenz

d.h. werden deine Buttons nicht ausgeführt. 

Greetz


----------



## imillitay (13. Mrz 2012)

nillehammer hat gesagt.:


> JSF ist schon etwas her. Kann sein, dass es inzwischen automatisch geht. Aber musst Du einer ManagedBean nicht irgendeinen Namen geben? Woher weiß JSF sonst, dass "derTestHandler" eine Instanz von TestHandler sein soll. So müsste es klappen:
> 
> ```
> @ManagedBean("derTestHandler")
> ```



Ist nicht nötig! Ab JSF2 ist die Herangehensweise von masterjule hier korrekt.


----------



## Nogothrim (14. Mrz 2012)

das mit den Forms sieht auf jeden Fall gefährlich aus, ansonsten ist mir noch der f:view Tag aufgefallen, den man bei JSF2 eigentlich auch nie braucht. Der Name der ManagedBean wird automatisch aus dem Klassennamen abgeleitet, das ist schon so richtig.


----------

