Why is my commandLink oncomplete running before update completes?

UI Components for JSF
Post Reply
RElliott
Posts: 94
Joined: 07 Feb 2014, 00:39

20 Nov 2017, 04:05

I have commandLink that updates a graphicImage in a dialog and then displays the dialog. After the dialog displays, the positionDialog function centers the dialog on the screen. The following is my code:

Code: Select all

.
.
.
<p:commandLink
    update="portrait"
    oncomplete="setTimeout(function(){PF('portrait-dialog').show();}, 50);">
    <f:setPropertyActionListener
        value="#{portrait}"
        target="#{portraits.portrait}" />
    <p:graphicImage
        value="/files#{portrait.getPath('_162x288.jpg')}"
        style="height: 192px; width: auto;" />
</p:commandLink>
.
.
.
<p:dialog
    id="portrait-dialog"
    showHeader="false"
    widgetVar="portrait-dialog"
    modal="true"
    responsive="true"
    onShow="positionDialog('portrait-dialog')">
    <p:graphicImage
        id="portrait"
        style="max-height: 85vh;"
        value="/files#{portraits.portrait.getPath('_810x1440.jpg')}"
        onclick="PF('portrait-dialog').hide();" />
</p:dialog>


If I delay the call to the dialog show method 50 ms as shown in my code, everything works well. The dialog updates with the new graphic and then when displayed is centered on the screen.

If I don't delay 50 ms, the initial dialog is only 40px wide and the positionDialog function centers the dialog based on the 40px width. Soon after the dialog is displayed and centered incorrectly, the graphic finishes downloading and the dialog expands to the new width as dictated by the graphic but the dialog is not centered.

Why is the oncomplete being called before the graphic finishes downloading as part of the update?

Is there a better way for me to respond to the change in width of the dialog and recenter than delaying 50 ms before showing?
PrimeFaces 7.0.1, Glassfish 5.1.0, Oracle JDK 8, Eclipse 2016-02

RElliott
Posts: 94
Joined: 07 Feb 2014, 00:39

21 Nov 2017, 00:48

I changed my code as shown below to wait for the img.load event before displaying the dialog. I like this better than hoping the image downloads in 50ms as I was doing previously.

Note: The a:onload is a JSF passthrough attribute.

Code: Select all

.
.
.
<p:commandLink
    update="portrait"
    oncomplete="">
    <f:setPropertyActionListener
        value="#{portrait}"
        target="#{portraits.portrait}" />
    <p:graphicImage
        value="/files#{portrait.getPath('_162x288.jpg')}"
        style="height: 192px; width: auto;" />
</p:commandLink>
.
.
.
<p:dialog
    id="portrait-dialog"
    showHeader="false"
    widgetVar="portrait-dialog"
    modal="true"
    responsive="true"
    onShow="positionDialog('portrait-dialog')">
    <p:graphicImage
        id="portrait"
        style="max-height: 85vh;"
        a:onload="PF('portrait-dialog').show();"
        value="/files#{portraits.portrait.getPath('_810x1440.jpg')}"
        onclick="PF('portrait-dialog').hide();" />
</p:dialog>
PrimeFaces 7.0.1, Glassfish 5.1.0, Oracle JDK 8, Eclipse 2016-02

kukeltje
Expert Member
Posts: 9605
Joined: 17 Jun 2010, 13:34
Location: Netherlands

21 Nov 2017, 12:53

That is because for the commandLink, updatating the DOM is complete. It cannot (and should not) know what all code inside the update is going to do. So your solution with the passthrough onload is effectively a very good one. Even worth creating a Q/A (answered by yourself) in stackoverflow. Will get my upvote!

RElliott
Posts: 94
Joined: 07 Feb 2014, 00:39

22 Nov 2017, 11:05

As requested, I created a question with answer on StackOverflow.

https://stackoverflow.com/questions/474 ... 9#47430529
PrimeFaces 7.0.1, Glassfish 5.1.0, Oracle JDK 8, Eclipse 2016-02

kukeltje
Expert Member
Posts: 9605
Joined: 17 Jun 2010, 13:34
Location: Netherlands

22 Nov 2017, 22:42

Great, thanks!

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 66 guests