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?