1

I'm showing messages from a list in my backing bean in xhtml jsf page.

I'm using ui:repeat for the loop and a reply button for each message. on the reply button, i'm calling a dialog box in which i'm showing the username displayed at the xhtml page. But it always show the name of the last message sender in the list.

Take a look at my xhtml code

<h:form>
                            <div id="messages">

                                <ui:repeat var="userMsg" value="#{messagesManagedBean.userInboxMsgs}">

                                    <p:dialog modal="true" widgetVar="messageDialog" resizable="false"  width="750" height="200" header="New Message" >  



                                        <h:panelGrid columns="2">
                                            <p:column>
                                                <h:outputLabel for="msgRecepient"  value="To"/>
                                            </p:column>
                                            <p:column>
                                                <h:outputLabel id="msgRecepient" value="#{userMsg.userFullname}"  >

                                                </h:outputLabel>
                                            </p:column>
                                            <p:column>
                                                <h:outputLabel for="msgContents"  value="Message"/>
                                            </p:column>
                                            <p:column>
                                                <p:inputTextarea id="msgContents" value="#{messagesManagedBean.msg.message}" cols="65" rows="3" />


                                            </p:column>


                                            <p:column>
                                                <p:commandButton id="msgSend" value="Send"  action="#{messagesManagedBean.sendMessage(userMsg.userId,'reply')}"   oncomplete="messageDialog.hide()"  /> 
                                            </p:column>

                                        </h:panelGrid>

                                    </p:dialog>

                                    <center><img class="h-diff" src="../images/differentiator-profile.jpg" width="437" height="1" /></center>
                                    <div class="message">
                                        <div id="senderImg">
                                            <img class="senderImg" src="../images/profile-pic.jpg" width="50" height="50" />
                                        </div>
                                        <div id="message-txt-area">

                                            <div id="senderName">
                                                <p:commandLink styleClass="senderName" value="#{userMsg.userFullname}" action="#{myProfileManagedBean.loadProfileFrontInformation(userMsg.userId)}"></p:commandLink>
                                            </div>
                                            <div class="message-txt">
                                                #{userMsg.message}
                                            </div>
                                            <div class="reply-btn">
                                                <a href="#" onclick="messageDialog.show()">Reply</a>
                                            </div>

                                        </div>
                                    </div>

                                </ui:repeat>

                            </div>
                        </h:form>

Now the problem is when i click on reply it shows the dialog box but the "To" section contains the sendername of the last message in the list.

Thanks

Mudassir Shahzad
  • 542
  • 2
  • 16
  • 32

2 Answers2

4

I think widgetVar is being overwritten since you do not specify any dynamic value for widgetVar, it stays always as messageDialog value.

I think it is a bad practice to put dialogs in a loop. I recommend reusing <p:dialog> by calling <p:commandLink> with variable value passed as parameter using <f:param> tag:

<ui:repeat var="userMsg" value="#{messagesManagedBean.userInboxMsgs}">
    ...
    <p:commandLink value="Reply" onclick="messageDialog.show()">
        <f:param name="userMsg" value="#{userMsg}" />     
    </p:commandLink>
    ...
</ui:repeat>

<p:dialog modal="true" widgetVar="messageDialog" resizable="false"
          width="750" height="200" header="New Message">
    <h:panelGrid columns="2">
        <p:column>
            <h:outputLabel for="msgRecepient" value="To"/>
        </p:column>
        <p:column>
            <h:outputLabel id="msgRecepient" value="#{userMsg.userFullname}" />
        </p:column>
        <p:column>
            <h:outputLabel for="msgContents" value="Message"/>
        </p:column>
        <p:column>
            <p:inputTextarea id="msgContents" cols="65" rows="3"
                             value="#{messagesManagedBean.msg.message}" />
        </p:column>
        <p:column>
            <p:commandButton id="msgSend" value="Send" 
            action="#{messagesManagedBean.sendMessage(userMsg.userId,'reply')}"
            oncomplete="messageDialog.hide()" />
        </p:column>
    </h:panelGrid>
</p:dialog>
d1e
  • 6,372
  • 2
  • 28
  • 41
  • @Damian what about the answer given by JMelnik... If i use his answer, i wouldn't have to use the bean variable... What do you say about this ? – Mudassir Shahzad Jun 07 '12 at 14:57
  • it didn't work :( I put that message sender id in the session because my bean is request scoped. Everytime a new request is sent to the server, it gets instantiated... Any getaround ? – Mudassir Shahzad Jun 12 '12 at 15:35
  • i can't imagine that this works, `userMsg` should be evaluated during render time not when the user clicks – wutzebaer Jul 26 '19 at 14:27
1

What you see is a expected behavior because you are doing it wrong.
First of all, move the dialog outside the ui:repeat.
Then set the ID of the h:panelGrid inside the dialog (for example: "dialogGrid")
Add an attribute in the managed bean that will be the selected message.
Replace <a href="#" onclick="messageDialog.show()">Reply</a> with the following:

<p:commandLink value="Reply" update="dialogGrid" oncomplete="messageDialog.show()" >
        <f:setPropertyActionListener target="#{messagesManagedBean.selectedMsg}" value="#{userMsg}" />
</p:commandLink>

Finally, in the dialog, instead of using #{userMsg} to reference the selected message, use #{messagesManagedBean.selectedMsg}

damian
  • 4,024
  • 5
  • 35
  • 53
  • what about the answer given by JMelnik... If i use his answer, i wouldn't have to use the bean variable... What do you say about this ? – Mudassir Shahzad Jun 07 '12 at 15:01
  • @MudassirShahzad You already have the bean variable, you call it "msg". In the f:setPropertyActionListener you can target that varialbe. The answer given by JMelnik is basically the same as mine; the only difference is that instead letting f:setPropertyActionListener set the bean variable value automatically, he sends a parameter to the method. In the method you'll have to read that parameter – damian Jun 07 '12 at 15:26
  • We use propertActionListener to set values, when they are needed in backing bean. But it depends. Well, you are using newer version of EL, where you can pass values to the method, so propertyActionListeners are not used so frequently now. – d1e Jun 08 '12 at 06:24
  • I've used both your methods, doesn't work :( server output is Jun 08, 2012 8:09:43 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute WARNING: #{messagesManagedBean.sendMessage(messagesManagedBean.selectedMessage.userId,'reply')}: java.lang.NullPointerException javax.faces.FacesException: #{messagesManagedBean.sendMessage(messagesManagedBean.selectedMessage.userId,'reply')}: java.lang.NullPointerException – Mudassir Shahzad Jun 08 '12 at 15:10
  • @JMelnik it's not setting the object by the setpropertyactionlistener method, i tried other methods as well, but not working. – Mudassir Shahzad Jun 08 '12 at 15:24
  • I forgot to mention, that my bean is RequestScoped, sorry. Now, how to tackle this problem ?? – Mudassir Shahzad Jun 08 '12 at 17:47