1
votes

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

2

2 Answers

4
votes

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>
1
votes

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}