1

Hey to all in the forum

I use JSF Mojarra implementation, version JSF 2.2

I need desperately a help on this.

  1. I have a snippet of my page.
  2. I have a custom component "example_result.xhtml" used in the page.
  3. I have my BackingBean.java Be aware please that this code is not the real code I made. If you run it, it will be very ugly maybe because I deleted all the css classes and I kept only the hot stuff I need to show you my problem.

Everything is inside 1 form.

The 5 "h:selectManyCheckbox" (in my code I have 8 or 9)

In the form I have 5 "h:selectManyCheckbox" which are using values in the "value" attribute for different cases (javaFrameworks2Values, javaFrameworks3Values,...), and the "f:selectItems" use arrays of "SelectItem" (javaFrameworksSelectItems2, javaFrameworksSelectItems3...) created for these different cases, just to make some examples for me to understand how all the selectOne and selectMany components work. The ideas for this, about different cases were taken from these links: "https://stackoverflow.com/tags/selectonemenu/info" and "https://mkyong.com/jsf2/jsf-2-checkboxes-example".

After I have 2 commandButtons

1 for submit, and 1 for reset the values.

Display the values

After I display the results of the values of the "h:selectManyCheckbox" via the "example_result.xhtml".

You can see the 4th "h:selectManyCheckbox" that is the only one different, because it has the attribute "required" with the attribute "requiredMessage". With it there is a "h:message" to display the validation error.

In the BackingBean (which is Spring Bean, but it works perfectly good - sorry I don't want ejbs 3.x), I have initialized:

  1. The values of the SelectItems and
  2. The values of the "value" attribute, where the values of the "h:selectManyCheckbox" will be stored to be displayed later. [The code is completely castrated, to make it readable snippet].

When the page is rendered, I select checkBoxes (e.g. the 2 last, because the 2 first are initials) from all the "h:selectManyCheckbox". When I say that select from all, I mean it. And from the 4th with the "required" attribute. I try in the buttons (see in the code) the "Effort 1", or "Effort 2", or "Effort 3" (in the "f:ajax" in the buttons) and the result outputs in the last part are displayed and updated like a candy. Without any problem. To achive this with the composite component I googled and tried a lot. But I made it.

Then it comes the time to try the 4th to see the validation error of the "required" attribute.

I select again from all as before, but not from all. NOT from the 4th "h:selectManyCheckbox" this time. I select nothing from the 4th "h:selectManyCheckbox" to ckeck the validator error message ("requiredMessage"). The result is: It displays the message of error (GOOD until now), BUT this time it does not update anything from the others "h:selectManyCheckbox" to the output results at the end, and it does not reset the values as well as it was doing before (when I selected from all and from the 4th as well).

I understand that it says: as long as in the form the 4th failed with validation error, all the other "h:selectManyCheckbox" will not update the output results (something like wanting to fail all the others too).

But what really happes here?

  1. It does not give the values to the "h:selectManyCheckbox", to be updated to the output?
  2. It gives the vales to the "h:selectManyCheckbox" normally, BUT it just not updates the output?

The other efforts in the "f:ajax" in the buttons, are just efforts maybe to solve the problem but in these cases they don't even display the error message in the 4th case and of cource they don't update the other output results as well (again). But no message error as well.

I don't know if the problem is clear to you. I can explain in the discussion better so I can clarify the situation better. [To be honnet it took me 1 and half hour to write all this thing]

Thanks a lot in advance

========== Snippet from my page ==========

<h:form>
    <h:panelGrid id="smcb" columns="1">
         
        <h:selectManyCheckbox id="smcb1" value="#{myBackingBean.javaFrameworksHardCodedValues}">
            <f:selectItem itemLabel="Java Label" itemValue="Java Value"/>
            <f:selectItem itemLabel="Spring Framework Label" itemValue="Spring Framework Value"/>
            <f:selectItem itemLabel="Hibernate Label" itemValue="Hibernate Value"/>
            <f:selectItem itemLabel="JSF Framework Label" itemValue="JSF Framework Value"/>
        </h:selectManyCheckbox>
         
        <h:selectManyCheckbox id="smcb2" value="#{myBackingBean.javaFrameworks2Values}">
            <f:selectItems value="#{myBackingBean.javaFrameworksSelectItems2}"/>
        </h:selectManyCheckbox>
 
        <h:selectManyCheckbox id="smcb3" value="#{myBackingBean.javaFrameworks3Values}">
            <f:selectItems value="#{myBackingBean.javaFrameworksSelectItems3}"/>
        </h:selectManyCheckbox>
 
        <p><h:message for="smcb4" styleClass="error_messages"/></p>
        <h:selectManyCheckbox id="smcb4" value="#{myBackingBean.javaFrameworks4Values}"
                            required="true"
                            requiredMessage="The 'h:selectManyCheckbox' must have a value. Please select an item from the list!">
            <f:selectItems value="#{myBackingBean.javaFrameworksSelectItems4}"/>
        </h:selectManyCheckbox>
 
        <h:selectManyCheckbox id="smcb5" value="#{myBackingBean.javaFrameworks5Values}">
            <f:selectItems value="#{myBackingBean.javaFrameworksSelectItems5}"/>
        </h:selectManyCheckbox>
         
    </h:panelGrid>
    <br/>
 
    <h:commandButton value="Display Java Frameworks values">
        <!--
        Effort 1 - works perfectly good if I select from all the "h:selectManyCheckbox"
        <f:ajax execute="smcb1 smcb2 smcb3 smcb4 smcb5 smcb6 smcb7 smcb8"
                render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
        -->
         
        <!--
        Effort 2 - works perfectly good if I select from all the "h:selectManyCheckbox"
        <f:ajax execute="smcb" render="outputId smcb"/>
        -->
         
        <!--
        Effort 3 - works perfectly good if I select from all the "h:selectManyCheckbox"
        <f:ajax execute="@form" render="@form"/>
        -->
         
        <!--
        Not working efforts to solve my problem - but are not solving it
        <f:ajax execute="@form" render="outputId"/>-->
        <f:ajax execute="@form"
                render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
                Other combinations with the @form and the ids...
        -->
    </h:commandButton>
    <h:commandButton value="Reset Java Frameworks values" action="#{myBackingBean.resetValues}">
        <!--
        Effort 1 - works perfectly good if I select from all the "h:selectManyCheckbox"
        <f:ajax execute="smcb1 smcb2 smcb3 smcb4 smcb5"
                render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
        -->
         
        <!--
        Effort 2 - works perfectly good if I select from all the "h:selectManyCheckbox"
        <f:ajax execute="smcb" render="outputId smcb"/>
        -->
         
        <!--
        Effort 3 - works perfectly good if I select from all the "h:selectManyCheckbox"
        <f:ajax execute="@form" render="@form"/>
        -->
    </h:commandButton>
    <br/>
 
    <h:panelGrid columns="1" id="outputId">
        <mc:example_result id="outputId1"
                           example_label="1. Java Frameworks hardcoded with 'f:selectItem': "
                           example_result="#{myBackingBean.displayItemValues()}"/>
 
        <mc:example_result id="outputId2"
                           example_label="2. Java Frameworks 2: "
                           example_result="#{myBackingBean.displayItemValues()}"/>
 
        <mc:example_result id="outputId3"
                           example_label="3. Java Frameworks 3: "
                           example_result="#{myBackingBean.displayItemValues()}"/>
 
        <mc:example_result id="outputId4"
                           example_label="4. Java Frameworks 4: "
                           example_result="#{myBackingBean.displayItemValues()}"/>
 
        <mc:example_result id="outputId5"
                           example_label="5. Java Frameworks 5: "
                           example_result="#{myBackingBean.displayItemValues()}"/>
    </h:panelGrid>
</h:form>

========== My Component: "example_result.xhtml" ==========

<ui:composition ...
    xmlns:mc="http://xmlns.jcp.org/jsf/composite/mc_components">
 
    <cc:interface>
        <cc:attribute name="example_label" type="java.lang.String" required="true"/>
        <cc:attribute name="example_result" type="java.lang.String" required="true"/>
    </cc:interface>
 
    <cc:implementation>
        <div id="#{cc.clientId}">
            <h:outputText value="#{cc.attrs.example_label}" .../>
            <h:outputText value="#{cc.attrs.example_result}" .../>
        </div>
    </cc:implementation>
</ui:composition>

========== My BackingBean: "MyBackingBean.java" ==========

@org.springframework.stereotype.Component(value = "myBackingBean")
public class MyBackingBean implements Serializable {
 
    // Variables used in the "value" attribute of "HtmlSelectMany" components
    private String[] javaFrameworks2Values; // + Getters-Setters
    // All the others: javaFrameworks3Values, ...
 
    // The "HtmlSelects" components' "SelectItems" are generated by an array of "SelectItem"
    private SelectItem[] javaFrameworksSelectItems2; // +Getters
    // All the others: javaFrameworksSelectItems3, ...
     
 
    @PostConstruct
    protected void initLabelValueMapAndLabelValueArray() {
     
        // Pre-selected values of "HtmlSelectMany" components
        javaFrameworks2Values = new String[]{"Java Value", "Spring Framework Value"};
 
        // Initialization of the array of "SelectItem"
        javaFrameworksSelectItems2 = new SelectItem[4];
        javaFrameworksSelectItems2[0] = new SelectItem("Java Value", "Java Label");
        javaFrameworksSelectItems2[1] = new SelectItem("Spring Framework Value", "Spring Framework Label");
        javaFrameworksSelectItems2[2] = new SelectItem("Hibernate Value", "Hibernate Label");
        javaFrameworksSelectItems2[3] = new SelectItem("JSF Framework Value", "JSF Framework Label");
         
        // Initialization of all the others: javaFrameworks3Values, ..., javaFrameworksSelectItems3, ...
    }
     
    public String displayItemValues() {
        // return array of the result values;
    }
     
    public void resetValues() {
        // Reset the values to the initials
    }
}
Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102
Thomas_Mylonas
  • 232
  • 3
  • 12
  • If validation failed, like if a required field is empty, no values are submitted to the server, so you'll see any changes in your bean. If you need to reset the state of your component/form try to take a look at [ResetInput showcase](http://www.primefaces.org:8080/showcase/ui/misc/resetInput.xhtml?jfwid=e06d3) – WoAiNii Jun 05 '21 at 13:52
  • Hey @WoAiNii. Thanks a lot for the reply. My problem is that when the 1 field fails the validation, all others do not work, do not display the result. Like failling as well because the 1 failed. The problem is that I cannot understand why. It is easy for me to change the code and make 5 different forms for every component. But I need to learn what is happening here. – Thomas_Mylonas Jun 06 '21 at 12:20
  • [Updated] @WoAiNii... Just an update please. You said that if validation fail the values are not submitted to the server. This happens only for the field that fails, or if 1 input fail from the form, then all inputs from this form are not submitted their values to the server as well? If this is what you mean, then my problem is solved – Thomas_Mylonas Jun 06 '21 at 12:23
  • @WoAiNii if I did not explain well the following, I can try to edit the previous I wrote and explain it again. It is difficult to give to someone what you have in mind anyway! – Thomas_Mylonas Jun 06 '21 at 13:35
  • The sentence in your update is correct. since you don't have a process attribute in your button, all the form is processed and if a required or validation failed no value are sent to the server. Try to take a look [here](https://docs.oracle.com/javaee/7/tutorial/jsf-intro006.htm), or [here](https://stackoverflow.com/questions/8677985/primefaces-jsf-update-after-validation-failed-doesnt-work) or find some other docs about jsf phases – WoAiNii Jun 06 '21 at 16:08
  • Hey @WoAiNii. Sorry for the delayed response. Well. It seems that I understand the reason. But, some comments. My button is not primefaces and cannot have this process attribute. Is there any way in my f:ajax efforts to avoid this behavior? If 1 fails the validation all other don't sent to the server the values? Is there a way to change something in the f:ajax to achieve what I need? Except if the only way is to make 5 different forms with different submit buttons to achieve this? Thanks a lot – Thomas_Mylonas Jun 07 '21 at 08:04
  • Sorry, I need some time to find out a good answer and in this question [https://stackoverflow.com/questions/17450326/validate-only-specific-parts-of-the-form-instead-of-whole-form](https://stackoverflow.com/questions/17450326/validate-only-specific-parts-of-the-form-instead-of-whole-form) there's almost everything you could do and need to know about your question. – WoAiNii Jun 07 '21 at 17:08
  • @WoAiNii Hey friend. Take your time. I trust your experience. I spent on this 1 week searching, and I did not find solution. But, anyway I will study the link you sent to me. Thanks a lot the link. – Thomas_Mylonas Jun 07 '21 at 17:27
  • @WoAiNii hey friend. I do not know if you have time to reply, but I saw something. When the validation error takes place, in the backingbean the value of the required attribute is not updated of course (as we said), but the values of the other attributes who are not responsible for the error validation are updating their new values. The problem is that they fail after the error validation occurrence, to update the page. – Thomas_Mylonas Jun 14 '21 at 07:45
  • Friend WoAiNii. One more thing. About the link you sent me with the answer of @BalusC. This answer says that master forms are not good practice, which is not my case. I have 5 components that they are related together in this section. In my case, dueTo no one else wanted even to read the problem (just to say this you want to do cannot be done), I haveTo post as answer/solution: "to make 5 different forms with 5 different set of buttons for 5 not unrelated components". Personally, I thank you for your time and to answer and to read the issue. I respect and appreciate your interest. – Thomas_Mylonas Jun 14 '21 at 19:24
  • 1
    Thanks, you can post that as an answer and mark as resolved, to close this question. – WoAiNii Jun 15 '21 at 12:01

1 Answers1

1

After a lot of discussing with the only person who wanted to help to my issue here (and I thank him @WoAiNii for this a lot), I decided to post my solution:

I will make 5 different forms with 5 set of buttons (submit/reset), to make escalate this problem, for 5 so much related components in the form.

But my question is open: Why this is happening, what rule in JSF in this case is taking place and makes this situation. Anyone, who comes with an explanation, like:

  • this is a rule in JSF, or
  • is a JSF bug, or
  • this happens in these cases, or... whatever...,

I will be glad to read it here so I will learn better, and others to will learn from these ideas of yours. Thanks a lot

Thomas_Mylonas
  • 232
  • 3
  • 12