Success or Error Messages are not displaying

Ehtisham Zahid, modified 7 Years ago. New Member Posts: 14 Join Date: 9/25/18 Recent Posts
Hi, 

Success and Error messages are not displaying while validation in bean.
If we submit empty form and the field is required true then the error message will appear but if i try to check duplicate or any other validation from bean and try to show error message on xhtml page, It doesnt display message.

I using Liferay 7.1 with primefaces 6.2

build.graddle:

apply plugin: 'war'

repositories {
     mavenCentral()
}

dependencies {
    compile group: 'org.primefaces', name: 'primefaces', version: '6.2'
    compile group: 'com.liferay.faces', name: 'com.liferay.faces.bridge.ext', version: '5.0.3'
    compile group: 'com.liferay.faces', name: 'com.liferay.faces.bridge.impl', version: '4.1.2'
    compile group: 'log4j', name: 'log4j', version: '1.2.14'
    runtime group: 'org.glassfish', name: 'javax.faces', version: '2.2.18'
    providedCompile group: 'javax.faces', name: 'javax.faces-api', version: '2.2'
}



bean :

package com.ba.bean;

import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

@ManagedBean(name = "billTypeBean")
@ViewScoped
public class BillTypeBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name = null;

    @PostConstruct
    public void init() {
        name = new String();
    }

    public void save() {
        FacesContext context = FacesContext.getCurrentInstance();
        if (name != null || name.equals("asd")) {
            context.addMessage("name",
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please Fill" + " " + "Name", null));
            
        } else {
            name = "dsa";
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}



xhtml page :

<?xml version="1.0"?>

<f:view xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:adm="http://github.com/adminfaces"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <h:outputStylesheet library="css" name="main.css" />
    </h:head>
    <h:body style="background-color: #afbb8abd;">

        <h:form id="form" prependId="false" enctype="multipart/form-data">


            <p:commandButton value="Save" actionListener="#{billTypeBean.save}"
                update="@form" icon="fa fa-check" ajax="false" />




            <p:spacer width="5" />

            <p:message for="name"></p:message>

            <p:separator></p:separator>
            <div class="ui-g ui-fluid">



                <div class="ui-g-12 ui-lg-5 ui-xl-1">
                    <p:outputLabel value="Name" for="name"></p:outputLabel>
                </div>
                <div class="ui-g-12 ui-lg-7 ui-xl-11">
                    <p:inputText id="name" value="#{billTypeBean.name}" required="true"
                        maxlength="100" requiredMessage="Please fill Name"></p:inputText>

                </div>

            </div>
        </h:form>
    </h:body>
</f:view>


I am also attaching the .zip file.
Kindly give some solution to this
Thanks
thumbnail
Kyle Joseph Stiemann, modified 7 Years ago. Liferay Master Posts: 760 Join Date: 1/14/13 Recent Posts
Hi Ehtisham,
Your BillTypeBean.save() method is being called correctly, but the p:message component cannot render the message you added because you added it under the wrong id. FacesContext.addMessage() takes the components fully qualified client id not just the component's id. In a portlet environment, the client id includes the portlet namespace.

​​​​​​​There are multiple ways you can fix this issue in your code:

  1. Make the error message global and change the p:message to p:messages globalOnly="true" (this may not be appropriate for your use case).
  2. Obtain the client id from the component before adding the message:

    FacesContext context = FacesContext.getCurrentInstance();
    UIViewRoot viewRoot = facesContext.getViewRoot();
    UIComponent component = viewRoot.findComponent("form:name");
    String clientId = component.getClientId(context);
    facesContext.addMessage(clientId, new FacesMessage(message));
  3. Concatenate the client id for the component yourself:

    FacesContext context = FacesContext.getCurrentInstance();
    context.getExternalContext().encodeNamespace(":name");
    String clientId = context.getExternalContext().encodeNamespace(":name");
    facesContext.addMessage(clientId, new FacesMessage(message));

    Note that while testing I discovered that PrimeFaces components and default HTML (h:) components use different values for the client id. p:inputText did not include the ":form" id (from the <h:form> NamingContainer parent) while h:inputText did include the ":form" id. So if you wanted to get the client id for an h:inputText, you would need to use context.getExternalContext().encodeNamespace(":form:name"). Because of these kinds of issues, it's safer to use method #1 or #2 to deal with this issue.
While testing this code, I also noticed that you are performing validation in the save() action listener. You might want to consider adding a custom validator (validator="my.custom.Validator") to perform validation instead.

Please let us know if that fixes your issue.

- Kyle