简体   繁体   中英

JSF 2.0 backing bean method not executed for programmatically created UI element

I am using JSF's java classes to create UI elements for a simple HTML page as shown below. However the methods Bean::save() and Item.setValue(...) aren't executed.

item.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Test</title>
    </h:head>
    <h:body>
        <h:panelGroup binding="#{bean.htmlPanelGroup}" />
    </h:body>
</html>

Bean.java

@ManagedBean(name="bean")
@ViewScoped
public class Bean implements Serializable {
    private final Item item = new Item(1L, "hello");

    public void save() {
        // this method is not executed when the save button created below is clicked.
        System.out.println("item.value = " + item.getValue());
    }

    public Item getItem() { return this.item; }

    transient HtmlPanelGroup htmlPanelGroup;

    public void setHtmlPanelGroup(HtmlPanelGroup htmlPanelGroup) {
        this.htmlPanelGroup = htmlPanelGroup;
    }
    public HtmlPanelGroup getHtmlPanelGroup() {
        if (htmlPanelGroup == null) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            htmlPanelGroup = new HtmlPanelGroup();
            HtmlForm editForm = new HtmlForm();
            HtmlInputText value = new HtmlInputText();
            ValueExpression valueExpr = facesContext.getApplication().getExpressionFactory()
            .createValueExpression(facesContext.getELContext(), "#{bean.item.value}", String.class);
            value.setValueExpression("value", valueExpr);
            editForm.getChildren().add(value);
            HtmlCommandButton save = new HtmlCommandButton();
            save.setValue("save");
            MethodExpression methodExpr = facesContext.getApplication().getExpressionFactory()
            .createMethodExpression(facesContext.getELContext(), "#{bean.save}", String.class, new Class<?>[]{});
            save.setActionExpression(methodExpr);
            editForm.getChildren().add(save);
            htmlPanelGroup.getChildren().add(editForm);
        }
        return htmlPanelGroup;
    }
}

Item.java

public class Item implements Serializable {
    private long id;
    private String value;

    public Item(long id, String value) {
        this.id = id;
        this.value = value;
    }

    public String getValue() { return value; }

    public void setValue(String value) { this.value = value; }

    public long getId() { return id; }

    public void setId(long id) { this.id = id; }
}

All programmatically created JSF UIForm , UIInput and UICommand components needs to have a fixed ID set, otherwise JSF would autogenerate one which doesn't get saved and then JSF won't be able to extract the submitted values based on those IDs from the request parameter map.

So, in your particular case, you need to add the following lines (the ID is fully free to your choice):

editForm.setId("form");
// ...
value.setId("value");
// ...
save.setId("save");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM