0

I am using JSF 2.3 (Mojarra 2.3.9.SP02) and PrimeFaces 7.0 running on WildFly 17 (Ubuntu 18.04 TLS / or Windows 10). In my action method weiterBid() in the backing bean (which is a ViewScoped) I perform a check if the user has just checked a checkbox. If not, then an error message is shown in red in the component <p:panel id="errorMsgPanelId" (see below the facelet) and the user remains on the same page. This check is performed each time the user clicks on the "Next" button.

Now, my understanding is, that even when the user closes the error message panel, each time when he/she clicks on the "Next" button, the action method is invoked, and the check whether hte user has checked the checkbox is performed again and again. If the check-box has not been checked, then the error message should be shown again in the same <p:panel id="errorMsgPanelId"> component as before. Is this really the supposed behaviour? If yes, than I am having a bug that the error message is only shown on the first click on the "Next" button and is never showhn again, once the user closes the panel showing it.

The minimal working example project on github:

https://github.com/alexmivonwien/pf.error.msg

My backing bean:

    @Named("aveBidUnterlagenBean")
    @javax.faces.view.ViewScoped
    public class AveBidUnterlagenBean implements Serializable {

        private boolean confirmationDocumentsGiven;

        private FacesMessage errorMessageOnDocumentConfirmation;

        public boolean isConfirmationDocumentsGiven() {
            return confirmationDocumentsGiven;
        }

        public void setConfirmationDocumentsGiven(boolean confirmationDocumentsGiven) {
            this.confirmationDocumentsGiven = confirmationDocumentsGiven;

        }

        public String weiterBid() {
            if (!confirmationDocumentsGiven) {
                String errorMessage = "Please confirm documents for the real estate";

                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, null);
                FacesContext.getCurrentInstance().addMessage(null, message);
                this.errorMessageOnDocumentConfirmation = message;
                return null;
            }

            return null;
        }   

        public FacesMessage getErrorMessageOnDocumentConfirmation() {
            return errorMessageOnDocumentConfirmation;
        }

        public void onCloseErrorMsgPanel(CloseEvent event) {
            this.errorMessageOnDocumentConfirmation = null;
        }
    }

In the facelet I have the component

    <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <meta charset="UTF-8"/> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</h:head>
        <h:outputStylesheet name="primeicons/primeicons.css" library="primefaces"/>
        <h:form id="persDatenForm">  
                <p:panel id="errorMsgPanelId" styleClass="errorMsgPanel" closable="true" widgetVar="errorMsgPanel" rendered="#{aveBidUnterlagenBean.getErrorMessageOnDocumentConfirmation()!=null}">
                   <p:ajax event="close" listener="#{aveBidUnterlagenBean.onCloseErrorMsgPanel}" update="@parent" />
                   <h:outputText style="color:red;" value="#{aveBidUnterlagenBean.errorMessageOnDocumentConfirmation.detail}"/>
                   <p:commandLink outcome="#" style="background-color:white;" onclick="PF('errorMsgPanel').close()">
                        <i class="pi pi-times"></i>
                   </p:commandLink>
                </p:panel>
                <br/>
                <p:outputLabel value="Documents overwiev"/>
                <br/>
                <br/>
                <p:selectBooleanCheckbox value="#{aveBidUnterlagenBean.confirmationDocumentsGiven}" itemLabel="I confirm that I read the documents"/>
                <br/>
                <br/>
                <p:commandButton  icon = "pi pi-check" value="Next" action="#{aveBidUnterlagenBean.weiterBid}" update="@form"/>
         </h:form>  
</html>

Now , my problem is that if I do not check the check-box and I click on the "Next" button for the first time, the action method is invoked and the error message is shown. If I close the error message panel, and then click on the same "Next" button again, without having checked the checkbox, the error message is never shown again.

Is it a bug or a feature? How could I overcome it?

Thank you and kind regards: Alex

Alex Mi
  • 1,409
  • 2
  • 21
  • 35
  • What did you debug/check/... client-side? – Kukeltje Feb 12 '20 at 05:18
  • https://stackoverflow.com/questions/16166039/manually-adding-loading-jquery-with-primefaces-results-in-uncaught-typeerrors And it is sufficient to mention Mojarra in the question and not in a tag in cases like this. Only if e.g. something works in MyFaces but not in Mojarra, you add the mojarra tag (tags are for what is an explicit part of the *problem*). Good btw all version info etc is mentioned! – Kukeltje Feb 12 '20 at 06:38
  • or debug server side btw... I initially thought the server side method IS called each time, but re-reading your question again, I doubt that... And please try creating a [mcve]. Remove all superfluous styling, fieldset, divs, outputs etc... – Kukeltje Feb 12 '20 at 07:21
  • @Kukeltje Thank you once again for your valuable suggestions! I debugged server-side only and the action method is called every time I click on the "Next" button. The bean-values are correct. And, yep, I thought this is the minal working example, but I will simplify it further and will let you know (probably tommorrow morning) – Alex Mi Feb 12 '20 at 07:54
  • What I suspected is that removing the manual jquery include makes a difference. Do I understand correctly it did not? – Kukeltje Feb 12 '20 at 08:29
  • And in the `weiterBid` method, is the `if` statement entered? Off and you have a really strange uncommon way of showing the messages... Why not use a `h:message` or the likes? – Kukeltje Feb 12 '20 at 08:57
  • off-topic: https://stackoverflow.com/questions/31068678/which-xml-namespace-to-use-with-jsf-2-2-and-up – Kukeltje Feb 12 '20 at 10:24
  • @Kukeltje I uploaded my minimal working example on the github and gave a link to it in my summary above. I removed my jquery include, but nothing changed. And, yes, whenever I debug server side I am entering the action method weiterBid() each time, and, as long as I do not change the check-box value, the if is executed correclty ( I am entering it). What I noticed additionally: If I remove the import primeicons/primeicons.css then the error message is shown without the "clear" icon next to it, so I am not able to remove it. – Alex Mi Feb 13 '20 at 04:00
  • @Kukeltje client-side I do not see any error messages in the Browser console, just one warning to use calc instead of zoom, but this relates to a primefaces library, not to my code – Alex Mi Feb 13 '20 at 04:20
  • @Kukeltje replacing my custom error message panel with worked for me, but is still not a solution to the problem – Alex Mi Feb 13 '20 at 05:26
  • If you don't want to use a JSF/PrimeFaces messages component, why do you create a faces message then instead of using a plain string field? And if you run your application in jsf development mode , do you see warnings about enqued but not displayed messages? – Kukeltje Feb 13 '20 at 10:45
  • @Kukeltje Thank you, I will try it in the weekend and let you know! – Alex Mi Feb 14 '20 at 03:49

2 Answers2

0

The update is executed after the action. Instead, use an actionListener:

<p:commandButton  icon = "pi pi-check" value="Next" actionListener="#{aveBidUnterlagenBean.weiterBid}" update="@form"/>

update is called after actionListener but before action, I think because of that the view is already refreshed. So your beans confirmationDocumentsGiven is false, but it is never updated to the correct FacesContext.

(I didn't test this)

Ok I think the problem is

rendered="#{aveBidUnterlagenBean.getErrorMessageOnDocumentConfirmation()!=null}". 

In your onCloseErrorMsgPanel you set that errorMessage to null.

1st Visit: works, errormsg is set, close dialog -> error msg is null, update @parent -> panel rendered=false, then the action is called -> server side all values correct, however

2nd Visit: the update="@form" or generaly ajax update will skip all components with rendered=false

What to do? Use an action that sets errormsg =/= PlaceHolder.NotNull, then update is called, the panel (rendered = true because errormsg =/= null) is loaded, than with an actionlistener you set errormsg = actualValue.

By this, the panel should be updated and be contained in your DOM.

0

This is the work-around, hope it solves your problem.
<p:panel id="errorMsgPanelId" styleClass="errorMsgPanel" closable="true" widgetVar="errorMsgPanel">
<p:outputPanel id="wrapper" rendered="#{aveBidUnterlagenBean.getErrorMessageOnDocumentConfirmation() != null}">
<h:outputText style="color:red;" value="#{aveBidUnterlagenBean.errorMessageOnDocumentConfirmation.detail}"/>
<p:commandLink style="background-color:white;" actionListener="#{aveBidUnterlagenBean.onCloseErrorMsgPanel}" update="@form" process="@this">
<i class="pi pi-times"/>
</p:commandLink>
</p:outputPanel>
</p:panel>

And change the backing bean method to following:
public void onCloseErrorMsgPanel() { this.errorMessageOnDocumentConfirmation = null; }

Noah
  • 68
  • 1
  • 7