How do you wait for an image to load before displaying a p:dialog? - jsf

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?

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

Related

Draggable input components PrimeFaces

I tried to use draggable component https://www.primefaces.org/showcase/ui/dnd/draggable.xhtml for inputTextArea component but it does not work for me. Do you know any workarounds for making input components draggable?
My code:
<p:outputPanel>
<p:inputTextarea id="test">
</p:inputTextarea>
</p:outputPanel>
<p:draggable for="test" containment="parent" />
I don't have any errors in console. But drag function does not work as it work for p:panel, for example.
try to wrap the component in a panel and assign "for" to that panel.
<p:outputPanel>
<p:panel id="test">
<p:inputTextarea />
</p:panel>
<p:draggable for="test" containment="parent"/>
</p:outputPanel>

p:overlayPanel does not render sub-component properly

I have curious rendering problem. I'm trying to attach overlay panel with the button. When I press the button, panel is rendered. However a sub-component in the panel is not. When panel is visible and I do double click on the button, sub-component get's rendered. In the same time, when panel is not rendered and I do double click, sub-component is not rendered (and panel not displayed).
Generated html and computed CSS is the same for both painted/non-painted components.
Do you know where the problem can be? Am I missing some setting? Have I overlooked something or is it a bug?
PrimeFaces template:
<p:layoutUnit position="center">
<h:form>
<p:commandButton id="chooseLangBtn" value="Btn" type="button" />
<p:overlayPanel id="langPanel" for="chooseLangBtn" showCloseIcon="true" dismissable="true">
<p:selectOneListbox id="langSelect"
rendered="true"
value="#{selectOneLanguageView.language}"
converter="languageConverter"
var="t" filter="true"
filterMatchMode="startsWith">
<f:selectItems value="#{languageService.languages}"
var="lang"
itemLabel="#{lang.name}"
itemValue="#{lang}" />
<p:column>
<h:graphicImage width="22px" alt="#{lang.name}" library="main" name="images/flags/var/#{t.code}.svg"/>
</p:column>
<p:column>
<h:outputText value="#{t.name}" />
</p:column>
</p:selectOneListbox>
</p:overlayPanel>
</h:form>
Empty/Rendered images:
It's a bug in the Omega theme. See current status here: https://github.com/primefaces/themes/issues/10

commandButton for removing images from p:galleria

I am using Primefaces 5.0.2 with Glassfish 4 (Mojarra 2.2.0).
I've been trying to add a command button to delete/remove the selected image in a p:galleria component. I tried adding a button within the galleria component like this:
<p:galleria id="images" value="#{someBean.images}" var="image">
<p:graphicImage value="#{image}"/>
<p:commandButton icon="ui-icon-trash" title="Delete #{image}" style="position:absolute; top:0; right:0; z-index:10;"
actionListener="#{someBean.deleteImage(image)}"
update="growl images" />
</p:galleria>
I can display the image path fine within the button, but passing the image parameter in the EL Expression #{someBean.deleteImage(image)} does not work as expected.
The issue I have is that when deleteImage is called the image parameter (String) is always empty instead of containing the image name. However, title="Delete #{image}" displays fine, so I suspect image isn't resolved correctly within the actionListener or action attributes.
If I enter a literal string in the xhtml, e.g. #{someBean.deleteImage('deleteme')} it is passed correctly. Passing null also gives an empty string.
someBean.images is a List<String> (image paths).
I am at a loss :/ could anyone point me in the right direction? Is this a bug or am I doing something wrong?
I have also thought about adding a button outside the galleria component, but I am unclear as to how to determine the selected image without having to modify the p:galleria component.
There is also an unanswered question about this (1yr old) How to get the selected image from <p:galleria
Update:
Appending "test" to image using ui:param or c:set will actually give me the string "test" within the deleteImage method, but the h:outputText component correctly renders the value of image with "test" appended. This suggests to me that they are rendered at different times - and the commandButton is rendered at a time when image is null?
<p:galleria id="images" value="#{someBean.images}" var="image">
<p:graphicImage value="#{image}"/>
<ui:param name="img" value="#{image}test"/>
<h:outputText value="#{img}"/>
<p:commandButton icon="ui-icon-trash" title="Delete #{image}" style="position:absolute; top:0; right:0; z-index:10;"
actionListener="#{someBean.deleteImage(img)}"/>
</p:galleria>
Update 2
This could be related to a similar issue in Primefaces Extensions - maybe it is a bug after all. http://forum.primefaces.org/viewtopic.php?f=14&t=39992
I also started a thread in the PF forum: http://forum.primefaces.org/viewtopic.php?f=3&t=40055
<p:galleria id="photoGalleria"
panelHeight="400"
panelWidth="450"
widgetVar="photoGalleriaWidgetVar"
style="width: 100%;"
autoPlay="false"
value="#{partEditBean.selectedPart.partPictures}" var="img">
<p:panelGrid columns="1" styleClass="wf" style="text-align: center;">
<p:commandButton id="delete_pic_button"
update="#form"
value="#{msg['part_view.delete']}" process="#this"
actionListener="#{partImageEditBean.deleteListener}">
<f:param name="pic_id" value="#{img.picId}"/>
</p:commandButton>
</p:panelGrid>
<p:graphicImage styleClass="wf galleriaOver" value="#{img.picUrlPath}"
title="#{partEditBean.selectedPart.partTreeNode.partPathName}"
onclick="window.open('#{img.picUrlPath}','_blank');"/>
</p:galleria>
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("pic_id")

Render rich:extendedDataTable

I need a rich:popup that shows a rich:extendedDataTable, and when the user presses a button, the popup should be shown, and the extendedDataTable must be re-rendered, here is the code:
<rich:popupPanel id="popupId" show="false" modal="true">
<h:form>
<rich:extendedDataTable
value="#{bean.list}"
var="item" rows="5" id="table">
<rich:column>
<h:outputLabel value="#{item}" />
</rich:column>
</rich:extendedDataTable>
<a4j:commandButton value="x" immediate="true"
oncomplete="#{rich:component('popupId')}.hide(); return false;"/>
</h:form>
</rich:popupPanel>
<h:form>
<a4j:commandButton value="show"
oncomplete="#{rich:component('popupId')}.show(); return false;"
render="table" immediate="true" />
</h:form>
The first time I press the show it works fine, but when I close the panel with the X button and press again the show button, the extendedDataTable appears empty (It's rendered but appear empty, see image below).
The problem is fixed if I add an empty extendedDataTable before the popup, like this:
<rich:extendedDataTable />
<rich:popupPanel>
...
With rich:dataTable the problem doesn't exits, but I need a extendedDataTable.
And aditional extrange behaviour is when I resize the browser, the data appears.
Platform
RichFaces: 4.2.2.Final
Spring: 3.1.1.RELEASE
Cheers
Use onclick instead of oncomplete. ExtendedDataTable doesn't render properly inside invisible elements (it's a bug) so the popupPanel has to be made visible before the rerendering.
I had kinda the same issue.
I solved it in a not 100% richface correct way:
<a4j:commandButton
value="show"
action="#{actionForm.setShowEditor('true')}"
oncomplete="javascript:location.reload(true)"/>
<a4j:region layout="block" rendered="#{actionForm.showEditor}" id="panelArea">
<rich:popupPanel id="#{popupID}" modal="true" show="true" domElementAttachment="parent">
....
tabel
buttons
....
</rich:popupPanel>
</a4j:region>
The popup is always shown (show="true") inside the a4j:region.
But the a4j:region is only shown if variable to show the popup = true.
The full page refresh was in my case needed because otherwise my ckeditor had some initialisation errors. It should also work if you only rerender the a4j:region after you set the "#{actionForm.setShowEditor('true')}.

Scrollpanel's scrolls doesn't come up on first page load

I have a Dialog and there is a ScrollPanel inside it. The problem is scrolls doesn't come up on first page load and when I resize the Dialog, scrolls appears.
<p:dialog id="detailsDialog"
header="Details"
widgetVar="detailsDialog"
resizable="true"
appendToBody="true"
draggable="true"
>
<p:scrollPanel>
<h:outputText value="#{myController.html}" escape="false" />
</p:scrollPanel>
</p:dialog>
You may have to consider using scrollPanel mode 'native' as below:
<p:scrollPanel mode="native">
<h:outputText value="#{myController.html}" escape="false" />
</p:scrollPanel>

Resources