0

I am learning JSF and need some help. I am trying to do a declarative validation in a page, the rendered required message however appears twice in the HTML markup.

In my managed bean i have a students field pointing to a student entity which has the following fields firstName, otherNames, surName.

this is how the Managed Bean looks like:

@ViewScoped
public Class FormController implements Serializeble{
 private List<Student> students = new ArrayList<>();

  @PostConstruct
  public void init(){
   students.add(new Student());
   students.add(new Student());
    }

  //getters and setters
}

then in my JSF Page, I have a ui:repeat that points to students in my bean with declarative validation on the input fields;

    <h:form>
      <table>
       <ui:repeat value="#{formController.students}" var="student">
        <tr>
         <td><p:outputLabel value="first name:"/></td>
         <td><p:inputText value="#{student.firstname}" 
                          required="true" 
                          requiredMessage="field cannot be blank"/></td>
         <td><p:messages/></td>
        </tr>

        <!--other input fields omitted to make code cleaner-->

       </ui:repeat>
      </table>
      <p:commandButton value="submit" 
                       action="#{formController.saveStudents()}"/>
    </h:form>

The Problem, I am facing hereof is that, the required message are generated twice for each input field in the HTML markup like this:

<span class="bf-message">
    <span class="bficon bficon-error-circle-o bf-message-icon" aria-hidden="true</span>
    <span class="bf-message-detail">this feild cant be left blank</span></span><br /><span class="bf-message">
    <span class="bficon bficon-error-circle-o bf-message-icon" aria-hidden="true"></span>
    <span class="bf-message-detail">this feild cant be left blank</span></span>


 //repeated likewise for all other input field required message,omitted to save space

This is my development Enviroment

  • GlassFish 4.1.1
  • JSF 2.2
  • Primefaaces 6.0
  • NetBeans IDE.

To add a little more details,the backing bean method that the commandButtion action points to has no FacesMessages, neither do the Field in the Entity Class have validation annotations.

basamoahjnr
  • 145
  • 11

1 Answers1

2

The problem is that you nested <p:messages /> inside a <ui:repeat>. Since the ui:repeat iterates over all students you add to the list during render response phase, you end up with one message component for each student you add. A p:messages component by default displays all messages added to the FacesContext (e.g. all validation messages).

Move the <p:messages /> out of the <ui:repeat> and the messages will only be displayed once.

Another solution, if you want the message to be displayed right at the inputText, would be to give the inputText component an id attribute and use this id attribute in your <p:messages /> as a for attribute. Of course, this id has to be unique. The for attribute makes the messages component only display messages that were added for this particular component. This, however does not work with <ui:repeat>, as ui:repeat only renders the components multiple times but does not actually create multiple components in the component tree. So you'd have to use <c:forEach> for this. Make sure to read this introduction to JSTL tags in JSF first though.

<p:inputText id="#{student.id}" ... />
<p:messages for="#{student.id}" />
Community
  • 1
  • 1
jessepeng
  • 610
  • 6
  • 21
  • @Kaizen I'm not quite sure what you are trying to achieve with that. Could you elaborate? – jessepeng Mar 02 '17 at 13:08
  • oh shoot,that was to another question wrong place. Back to yours . if i am to go by your second solution, how do i use the `for` attribute on the `inputText` when `ui:repeat` just renders the same component several times, but not creating new components in the tree. i read this http://stackoverflow.com/q/19131583/7646476 – basamoahjnr Mar 02 '17 at 13:25
  • @Kaizen you're right, I forgot about that. I updated the answer with more correct information. – jessepeng Mar 02 '17 at 13:45