Primefaces Dialog Update after it is open - ajax

I want to update content primafaces dialog after it is opened. Is it possible? My example code is below.
<p:dialog widgetVar="pictureSaveDialog" id="pictureDialog" closable="false" >
<p:outputPanel id="saveDialogPanel">
<p:selectOneRadio id="options" value="#{pictureDefinitionsView.radioValue}" >
<f:selectItem itemLabel="FILE" itemValue="FILE" />
<f:selectItem itemLabel="" itemValue="URL" />
<p:ajax update="fileUpload1 fileUpload2" event="click" process="options" />
</p:selectOneRadio>
<p:outputPanel id="fileUpload1" rendered="#{pictureDefinitionsView.selectedFileUpload}"> File </p:outputPanel>
<p:outputPanel id="fileUpload2" rendered="#{pictureDefinitionsView.selectedUrlUpload}"> URL </p:outputPanel>
</p:outputPanel id="saveDialogPanel">
Bean Methods.
public boolean isSelectedFileUpload(){
return radioValue.equals("FILE");
}
public boolean isSelectedUrlUpload(){
return !isSelectedFileUpload();
}

You can define p:remoteCommand which just update dialog, and call that command in onShow attribute:
<p:remoteCommand name="updateDialog" update="saveDialogPanel"/>
<p:dialog widgetVar="pictureSaveDialog" id="pictureDialog" closable="false" onShow="updateDialog()">
If your saveDialogPanel is in some naming container be shore to add appropriate prefix to match id of component.

You better refresh the dialog content before its being open
Your p:commandButton/p:ajax should have the following:
update="pictureDialog" onsuccess="pictureSaveDialog.show()"

Related

Validation errors in dialog not updating after failed submit in JSF

So I click a button which opens a dialog. Inside this dialog I want to fill out information in a form and submit and save it. Some of the inputTexts need to be required in order to submit. So I use the required="true" attribute. It stops the submission, but it does not update the field with a red outline of everything. Now, if I hit cancel and open up the dialog again it will show the fields that failed validation with a red outline!
I thought I could solve this by manually updating the dialog whenever I try to submit the form. This just causes the dialog to close though instead of staying open and refreshing the dialog to show the validation failures.
This is the dialog, when I hit the save button is when I submit the form
<h:form>
<p:dialog header="#{headerValue}" widgetVar="#{uniqueId}_editDialog"
modal="false" showEffect="fade" styleClass="dialogGrid"
dynamic="true" draggable="true" resizable="false">
<p:outputPanel style="text-align:center;" layout="block">
<p:messages autoUpdate="true"/>
<ui:insert name="editContent">
Edit Content Here. Use 'selectedModel.whatever'
</ui:insert>
<p:panelGrid columns="3" styleClass="buttonGrid">
<ui:insert name="saveButton">
<p:commandButton iconPos="left" value="#{msg.save}"
rendered="#{'VIEW' != selectedModel.viewState}"
process="#widgetVar(#{uniqueId}_editDialog)"
action="#{adapterInjector.add(modelList, selectedModel)}"
update="#widgetVar(#{uniqueId}_itemsDataList) #widgetVar(#{uniqueId}_addButton) #widgetVar(#{uniqueId}_editDialog)"
oncomplete="if(!args.validationFailed) PF('#{uniqueId}_editDialog').hide()"
partialSubmit="true" validateClient="true">
</p:commandButton>
</ui:insert>
<p:commandButton iconPos="right" value="#{msg.cancel}"
process="#this" oncomplete="PF('#{uniqueId}_editDialog').hide()"
resetValues="true" partialSubmit="true">
</p:commandButton>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
This is an inserted component which has the required attribute
<p:selectOneMenu id="licenseCert"
value="#{selectedModel.selectedLicenseCert}" filter="true"
required="true">
<f:selectItem itemLabel="#{msg.selectOne}" itemValue=""
noSelectionOption="true" />
<f:selectItems value="#{licCert.allLicenseCertMap.entrySet()}"
var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</p:selectOneMenu>
</p:column>
Turns out this fixed the problem.
For best practice you should:
move the <h:form> inside the dialog
process the moved <h:form> in the save button.

Dynamic accodion panel passing variable in ajax

I want to pass variable to bean method on tabClose and tabChange- i want to pass index of the tab that i clicked.
<p:accordionPanel id="layerListAccordionPanel" multiple="true" activeIndex="#{layersModelMock.activeIndex}" value="#{layersModelMock.layerCategories}" var="category">
<p:ajax event="tabClose" listener="#{layersController.deselectCategory(category.id)}" />
<p:ajax event="tabChange" listener="#{layersController.selectCategory(category.id)}" />
<p:tab id="layerPanel" title="#{category.name}" closable="true">
Test
</p:tab>
</p:accordionPanel>
When i test code above i alwayes pass '0'. I don't know how to get index of the tab and pass it through ajax?
As you can see from Primefaces Showcase you can use tab change as event in your bean
public void onTabClose(TabCloseEvent event) {
deselectCategory(event.getTab().getId());
}
public void onTabChange(TabChangeEvent event) {
selectCategory(event.getTab().getId());
}
You'll need to adapt your XHTML accordingly.
<p:accordionPanel id="layerListAccordionPanel" multiple="true" activeIndex="#{layersModelMock.activeIndex}" value="#{layersModelMock.layerCategories}" var="category">
<p:ajax event="tabClose" listener="#{layersController.onTabChange}" />
<p:ajax event="tabChange" listener="#{layersController.onTabClose}" />
<p:tab id="#{category.id}" title="#{category.name}" closable="true">
Test
</p:tab>
</p:accordionPanel>
Haven't tested it myself but according to Primefaces homepage it should work.
Edit
Tested - works.

Ajax not rendering new data for <h:selectOneMenu>

I am trying to update a selectOneMenu from the results of another selectOneMenu.
When group is selected the user menu should be updated.
I have verified that the data for the user menu is being updated. It is not being rendered however.
Currently running Primefaces 3.4.2 and JSF 2.1
<ui:composition>
<br/><br/>
<h:form id="transferForm">
<h:panelGrid columns="1" style="width: 500px;margin: auto;text-align: center" >
<h:panelGroup>
<h:outputLabel for="group" value="Group" />
<h:selectOneMenu id="group" value="#{projectBean.transferUtil.selectedTransferGroup}" >
<f:selectItems value="#{projectBean.transferUtil.transferGroups}" />
<f:ajax execute="group" render="user" />
</h:selectOneMenu>
<br />
<h:outputLabel for="user" value="User" />
<h:selectOneMenu id="user" value="#{projectBean.transferUtil.selectedTransferUser}" required="true" requiredMessage="Select User" >
<f:selectItems value="#{projectBean.transferUtil.transferUsers}" />
</h:selectOneMenu>
</h:panelGroup>
<p:commandButton id="projectTransferButton" action="#{projectBean.transferUtil.transfer}" value="Transfer" update=":projtabs,:growlForm:growlMesg">
<f:setPropertyActionListener target="#{projectBean.activeTab}" value="#{projectBean.project_tab_index}" />
</p:commandButton>
</h:panelGrid>
</h:form>
<br/><br/>
[EDIT]
Alright this is the error I am getting.
<?xml version='1.0' encoding='UTF-8'?>
<partial-response><error><error-name>class java.lang.IllegalArgumentException</error-name><error-message><![CDATA[rss02.1 OPERA]]></error-message></error></partial-response>
And this is the code in question.
<p:dataGrid var="area" value="#{projectBean.projectUtil.project.rssAreas}" columns="1">
<p:column>
<h:selectBooleanCheckbox id="rss#{area.shortName}" label="#{area.name}" value="#{area.active}" />
<h:outputText value="#{area.name}" />
</p:column>
</p:dataGrid>
You should not perform business logic in getters/setters. They are invoked multiple times in JSF lifecycle and are intented to get and set the property. You should perform business logic in action(listener) methods instead.
The following construct should work:
<h:selectOneMenu id="group" value="#{projectBean.transferUtil.selectedTransferGroup}" >
<f:selectItems value="#{projectBean.transferUtil.transferGroups}" />
<f:ajax execute="group" listener="#{projectBean.transferGroupChanged}" render="user" />
</h:selectOneMenu>
<h:selectOneMenu id="user" value="#{projectBean.transferUtil.selectedTransferUser}" required="true" requiredMessage="Select User" >
<f:selectItems value="#{projectBean.transferUtil.transferUsers}" />
</h:selectOneMenu>
With
public void transferGroupChanged(AjaxBehaviorEvent event) {
// Change the transferUsers here.
}
The getters and setters should not contain any business logic. They should merely get and set the property.
See also:
Why JSF calls getters multiple times
How to load and display dependent h:selectOneMenu on change of a h:selectOneMenu

How to display object values in text fields during on dropdown item selection

The dropdown:
<h:outputLabel value="#{build.approvedRecons}" for="reconSearchFunctionalAreaID"></h:outputLabel>
<p:selectOneMenu style="width:200px;" id="reconSearchFunctionalAreaID" >
<f:selectItem itemValue="-Select One-" itemLabel="-Select One-" />
<f:selectItems value="#{approvedReconDetailsBean.reconItemList}"/>
<p:ajax update="#form" listener="#{approvedReconDetailsBean.reconDetailsDisplay}" event="onChange"></p:ajax>
</p:selectOneMenu>............<h:outputLabel for="reconNameID" value="#{build.appvReconName}" />
<h:outputText value="#{build.colon}" />
<h:outputText value="#{approvedReconDetailsBean.reconCtxVO.reconID}" id="reconNameID" />
The listener:
public void reconDetailsDisplay(SelectEvent event){
ReconContextVO tempReconContextVO = ((ReconContextVO) event.getObject());
ReconContextVO reconCtxVO1 = new ReconContextVO();
reconCtxVO1.setReconID(tempReconContextVO.getReconID());
reconCtxVO1.setReconName(tempReconContextVO.getReconName());
reconCtxVO1.setTxnProcessingType(tempReconContextVO.getTxnProcessingType());
reconCtxVO1.setTxnProcessingType(tempReconContextVO.getTxnProcessingType());
this.setReconCtxVO(reconCtxVO1);
}
reconItemList is of type List<ReconContextVO>. In my bean I converted reconsList to reconItemList. ReconContextVO contains
private String reconName;
private String txnProcessingType;
private String txnProcessingLevel;
// and their setter & getters
Now I would like to display reconName, txnProcessingType, txnProcessingLevel in text fields on change of the dropdown. I wrote the ajax listner method like above code. I din't get any idea.
Your concrete problem is caused by incorrect usage of <p:ajax>. The event="onChange" is invalid. It should be event="change" (which is the default already and thus can safely be omitted). The listener method argument is also invalid, it should be AjaxBehaviorEvent.
But, after all, you don't need a listener method for this. You can just bind the <p:selectOneMenu value> directly to a bean property.
<p:selectOneMenu value="#{approvedReconDetailsBean.reconCtxVO}">
<f:selectItem itemValue="-Select One-" itemLabel="-Select One-" noSelectionOption="true" />
<f:selectItems value="#{approvedReconDetailsBean.reconItemList}" />
<p:ajax update="reconDetails" />
</p:selectOneMenu>
<h:panelGroup id="reconDetails">
<h:outputText value="#{approvedReconDetailsBean.reconCtxVO.reconID}" />
<h:outputText value="#{approvedReconDetailsBean.reconCtxVO.reconName}" />
<h:outputText value="#{approvedReconDetailsBean.reconCtxVO.txtProcessingType}" />
<h:outputText value="#{approvedReconDetailsBean.reconCtxVO.txnProcessingLevel}" />
</h:panelGroup>
Note that I assume that you've already a Converter for the object and that its equals() is properly implemented. You should get conversion/validation error on that if not properly done.

selectBooleanCheckbox ajax event fires but the listener is never executed

The selectBooleanCheckbox ajax event fires but the listener is never executed.
If I remove the c:forEach and just call the first one in the list it works.
<p:selectBooleanCheckbox value="#{Controller.graphFilter.get(0).checked}" >
<p:ajax listener="#{Controller.addMessage}" />
</p:selectBooleanCheckbox>
notes:
graphFilter is a list where container has the sets/gets for checked and description.
controller is a viewscoped managed bean.
addMessage public function that puts a message for the growl.
Everything is in the same form.
<h:form id="form" prependId="false">
<p:growl id="growl" showDetail="true"/>
<c:forEach items="#{Controller.graphFilter}" var="Gc">
<h:outputText value="#{Gc.description}" />
<p:selectBooleanCheckbox value="#{Gc.checked}" >
<p:ajax listener="#{Controller.addMessage}"/>
</p:selectBooleanCheckbox>
</c:forEach>
</h:form>
You should wrap your components with a p:column:
<p:column>
<h:outputText value="#{Gc.description}" />
<p:selectBooleanCheckbox value="#{Gc.checked}" >
<p:ajax listener="#{Controller.addMessage}"/>
</p:selectBooleanCheckbox>
</p:column>
But replacing the whole structure with a p:dataList would be more elegant.

Resources