19

I have an h:inputText and an h:message connected to it:

<h:inputText id="myText" value="#{myController.myText}" />
<a4j:outputPanel>
    <h:message for="myText" .../>
</a4j:outputPanel>

I want to send a message to it from java, in a manner like:

FacesContext.getCurrentInstance().addMessage(arg0, arg1);

which is sent to h:messages, but to a specific id in a specific form. How can I do this? (Without implementing validation bean or validation method - meaning without throwing validation exception).

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Benchik
  • 2,057
  • 5
  • 26
  • 44

2 Answers2

34

You need to provide the so called client id, which you'll find on UIComponent.

The following is a quick example of how to use this.

Consider the following bean:

@ManagedBean
@RequestScoped
public class ComponentMsgBean {

    private UIComponent component;

    public UIComponent getComponent() {
        return component;
    }

    public void setComponent(UIComponent component) {
        this.component = component;
    }

    public String doAction() {

        FacesContext context = FacesContext.getCurrentInstance();

        context.addMessage(component.getClientId(), new FacesMessage("Test msg"));

        return "";
    }

}

being used on the following Facelet:

<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" 
    >

    <h:body>

        <h:form>
            <h:outputText id="test" value="test component" binding="#{componentMsgBean.component}"/>
            <h:message for="test"/>

            <h:commandButton value="click me" action="#{componentMsgBean.doAction}" />
        </h:form>

    </h:body>
</html>

This will add a Faces message with content "Test msg" for the outputText component used in the example.

Jaumzera
  • 2,305
  • 1
  • 30
  • 44
Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
  • 1
    So, without binding i just need to know the generated clientId for the components' id and that's it? – Benchik Mar 13 '11 at 13:32
  • 2
    Yes, you could grab this ID from the markup being send to your browser. But depending on this is rather brittle, as this ID might change when you move your component or add other components to your view. – Arjan Tijms Mar 13 '11 at 13:36
  • 1
    OK, but i need to send messages without binding. Any easy way to find out the clientId from Id? (Without TLD functions) – Benchik Mar 13 '11 at 13:38
  • 6
    Given the (relative) id of a component you can not universally calculate the clientId. The JSF spec only requires those Ids to be unique within the scope of a naming container. If you think those relative Ids are unique enough in your application you could locate the component starting from the view root using findComponent, e.g. ``context.getViewRoot().findComponent("myText")`` – Arjan Tijms Mar 13 '11 at 13:48
  • I tried this in my page (with Layout), the message in displayed behind the layout ! and not at the place of the component with the binding attribute ! do you have an idea how to fix it ? – ThunderPhoenix Sep 06 '13 at 13:01
  • 1
    Thanks @Arjan, even after all this time you're still helping me – Mark W Jul 27 '21 at 15:25
9

Another way to do that is: give an ID to the form, like "form1", then, when add the message, the clientId is "form1:test".

Sergio Samaan
  • 95
  • 1
  • 6