h:message为空时的默认输出

时间:2010-11-30 12:47:49

标签: jsf jsf-2 facelets

我正在寻找一种在JSF中实现以下切换的方法:

 ...
 <div>
   if empty(<h:message for="x">)
     <h:outputText value="default value" />
   else
     <h:message for="x" />
   endif
 </div>
 ....

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

PhaseListener的帮助下,这是可行的。

以下是视图的外观,而不是令人震惊的,只是<f:ajax>在每个输入组件上挂起blur事件,因此当输入字段失去焦点时立即重新呈现消息组件。 / p>

<!DOCTYPE html>
<html lang="en"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <title>Stackoverflow question 4313917</title>
        <style>.info { color: green; } .error { color: red; }</style>
    </h:head>
    <h:body>
        <h:form>
            <h:panelGrid columns="3">
                <h:outputLabel for="input1">Input 1</h:outputLabel>
                <h:inputText id="input1" value="#{bean.input1}" required="true">
                    <f:ajax event="blur" render="input1message" />
                </h:inputText>
                <h:message id="input1message" for="input1" infoClass="info" errorClass="error" />

                <h:outputLabel for="input2">Input 2</h:outputLabel>
                <h:inputText id="input2" value="#{bean.input2}" required="true">
                    <f:ajax event="blur" render="input2message" />
                </h:inputText>
                <h:message id="input2message" for="input2" infoClass="info" errorClass="error" />

                <h:outputLabel for="input3">Input 3</h:outputLabel>
                <h:inputText id="input3" value="#{bean.input3}" required="true">
                    <f:ajax event="blur" render="input3message" />
                </h:inputText>
                <h:message id="input3message" for="input3" infoClass="info" errorClass="error" />

                <h:panelGroup />
                <h:commandButton value="Submit" action="#{bean.submit}" />
                <h:panelGroup />
            </h:panelGrid>
        </h:form>
    </h:body>  
</html>

Bean说明了一切:3个属性input1input2input3以及void submit()方法。只需让IDE自动生成样板。

这是PhaseListener

package com.example;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

public class MessagePhaseListener implements PhaseListener {

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        FacesContext facesContext = event.getFacesContext();
        if (facesContext.isPostback()) {
            UIViewRoot viewRoot = facesContext.getViewRoot();
            for (String clientId : facesContext.getExternalContext().getRequestParameterMap().keySet()) {
                UIComponent component = viewRoot.findComponent(clientId);
                if (component instanceof UIInput && !facesContext.getMessages(clientId).hasNext()) {
                    facesContext.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO, "OK!", null));
                }
            }
        }
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        // NOOP. It's too late anyway.
    }

}

faces-config.xml中注册如下(不,不幸的是,没有针对phaselisteners的JSF 2.0注释)。

<lifecycle>
    <phase-listener>com.example.MessagePhaseListener</phase-listener>
</lifecycle>

您可能想要参数化“确定!” phaselistener中的消息。