1
votes

I have a page in my application that uses a PrimeFaces DataTable to display a list of people with a small image of each person in the first column. When the user clicks on the small image which is part of a p:commandLink, I use ajax to update a p:graphicImage in a p:dialog with the path to the selected image and use the commandLink's oncomplete to display the dialog. Finally, I use the dialog's onShow to center the dialog on the page. The following is the xhtml:

.
.
.
<p:commandLink
    update="portrait"
    oncomplete="PF('portrait-dialog').show());">
    <f:setPropertyActionListener
        value="#{portrait}"
        target="#{portraits.portrait}" />
    <p:graphicImage
        value="/files#{portrait.path}"
        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.path}"
        onclick="PF('portrait-dialog').hide();" />
</p:dialog> 

The above code works perfectly but uses a single image file for the small image in the list and the big image in the dialog. I decided to use different image files for the small and big image so created the following code.

.
.
.
<p:commandLink
    update="portrait"
    oncomplete="PF('portrait-dialog').show();">
    <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>

Unfortunately, the above code does not center the dialog on the page correctly the first time the user selects the small image. If the user closes the dialog and then selects the small image again, the dialog is centered correctly on the page. I suspected that this had something to do with the large image not being downloaded completely before the dialog was diplayed so I add a 50ms delay to the oncomplete as shown below.

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

This resolved the issue in most cases but sometimes the dialog is still not centered correctly on the first selection.

How do I wait for an image to load before displaying a p:dialog?

1

1 Answers

1
votes

I resolved this issue by moving the dialog show from the commandLink's oncomplete to an onload passthrough attribute of the dialog's imageGraphic as shown below.

.
.
.
<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>

Now my dialog waits for the image file to download before displaying and centering and all is well.

The following is a link to my original question in the PrimeFaces forum.

https://forum.primefaces.org/viewtopic.php?f=3&t=53248