Primefaces dropdown not setting value - drop-down-menu

I am trying to delete an image which belongs to an album.
I provide 2 drop downs, the first allows to select the album the second to select an image of the album. The first when changes sets the second.
Then the remove button calls a remove method.
I have debugged it a number of times but the values are always null.
Do you know why? how can I make it work?
note: when I set the first drop down the value is present but after I set the second they both become null.
Thanks
<h:form>
<h:panelGrid>
<h:outputLabel value="#{diaryMB.selectedAlbum}"/>
<p:selectOneMenu
id="albums" value="#{diaryMB.selectedAlbum}" effect="drop">
<f:selectItem itemLabel="Select An Album" itemValue="-1" />
<f:selectItems value="#{diaryMB.albums}" var="album"
itemLabel="#{album}" itemValue="#{album}" />
<p:ajax event="change" listener="#{diaryMB.updateImage()}" update="images"/>
</p:selectOneMenu>
<h:outputLabel value="#{diaryMB.selectedImage}" />
<p:selectOneMenu
id="images" value="#{diaryMB.selectedImage}" effect="drop">
<f:selectItem itemLabel="Select An Image" itemValue="-1" />
<f:selectItems value="#{diaryMB.images}" var="image"
itemLabel="#{image}" itemValue="#{image}" />
</p:selectOneMenu>
<p:commandButton id="removeImageButton" value="Remove" ajax="false" action="#{diaryMB.removeImage()}"/>
</h:panelGrid>
</h:form>
public String removeImage(){
System.out.println("I am selected image:"+selectedImage);
System.out.println("I am slected album "+selectedAlbum);
if(selectedImage!=null && !selectedImage.equals("-1"))
{diaryManager.removeImageFromAlbum(diaryOwner, selectedAlbum, selectedImage);
return "Friends";}
else
return "Home";
}

It might be beacuase your managed bean is RequestScoped and is being recreated after every ajax request. Try using ViewScoped or SessionScoped and see if the values remain.

Related

How can I update twice during JSF Ajax event

Given the following code:
<p:column headerText="#{text.article}">
<h:panelGroup>
<p:autoComplete id="relationArticle"
value="#{relation.article}"
completeMethod="#{articleRelationsModel.findArticles}"
queryDelay="#{text.query_delay}"
minQueryLength="#{text.artikkel_min_query_length}"
var="article"
itemLabel="#{article.articleNo} #{article.text1}"
itemValue="#{article}"
converter="#{articleConverter}"
scrollHeight="150"
forceSelection="true"
styleClass="ui-autocomplete-big">
<p:ajax event="itemSelect" update="relationUnit" process="#this"/>
</p:autoComplete>
<p:message for="relationArticle"/>
</h:panelGroup>
</p:column>
<p:column headerText="#{text.unit}" style="width: 80px;">
<h:selectOneMenu id="relationUnit" value="#{relation.unit}" converter="#{articleUnitConverter}">
<f:selectItem itemLabel="<< #{text.search}" noSelectionOption="true" itemDisabled="#{relation.article != null}"/>
<f:selectItems value="#{articleRelationsModel.getUnits(relation)}" var="unit" itemLabel="#{unit.code}" itemValue="#{unit}"/>
<p:ajax event="change" process="#this" update="#this"/>
</h:selectOneMenu>
<p:message for="relationUnit"/>
</p:column>
How can I refresh the "relationUnit" component after the user has selected a value in the "relationArticle" component?
What happens now, is that after the autcompete itemSelect event has fired, the "relationUnit" component gets updated with new content using #{articleRelationsModel.getUnits(relation)}. During this update, the relation object is updated with one of the options from the resulting list. This, however, is not reflected in the "relationUnit" component after the update. But if I manually do another update after this, it gets selected.
How can I achieve the wanted result here?
You can use p:remoteCommand, which is usually used to call the ManagedBean Methods from Javascript.
While it serves the above purpose you can use it to update other components also.
You can call the p:remoteCommand from p:ajax's oncomplete attribute.
<p:autoComplete id="relationArticle" ...>
<p:ajax event="itemSelect" update="relationUnit" onComplete="updateRelationUnit()" process="#this"/>
</p:autoComplete>
<p:remoteCommand name="updateRelationUnit" update="relationUnit" process="#this" />
Now p:ajax will update relationUnit once and then calls the p:remoteCommand which in-turn relationUnit again.
I don't know why you want this strange behavior, but the above strategy and code servers your purpose just fine.

Ajax listener and Converter on multiple fields - new value not passed to listener

I need to update 'pickupdate' based on the value selected in 'pickuphour'.
My problem is that when the update listener is called, the newly selected 'pickuphour' value is not available in the listener method.
It appears the listener is called before the converter updates my bean 'pickuptime' value.
(I used the DatePartConverter here:Binding more than one input field to a backing bean property by using Java Server Faces?)
How do I get the newly selected hour value before or while in the listener method?
<h:panelGroup>
<h:form id="pickuptime">
<p:selectOneMenu id="pickupdate" widgetVar="pickupdate" value="#{journeyCRUD.pickuptime}" immediate="true">
<f:selectItem itemLabel="Today" itemValue="#{journeyCRUD.dateList[0]}" noSelectionOption="true"/>
<f:selectItem itemLabel="Tomorrow" itemValue="#{journeyCRUD.dateList[1]}" />
<f:selectItems value="#{util:subList(journeyCRUD.dateList, 2, 30)}" var="date" itemValue="#{date}" itemLabel="#{util:formatDate(date, 'EEE dd MMM yyyy','EEE dd MMM')}"/>
<f:converter converterId="datePartConverter"/>
<f:attribute name="part" value="date"/>
<f:ajax execute="#this pickuphour pickupmin"/>
</p:selectOneMenu>
<p:selectOneMenu id="pickuphour" widgetVar="pickuphour" value="#{journeyCRUD.pickuptime}" immediate="true" >
<f:selectItems value="#{journeyCRUD.hourList}"/>
<f:converter converterId="datePartConverter"/>
<f:attribute name="part" value="hour"/>
<f:ajax event="change" listener="#{journeyCRUD.updatePickupDate}" execute="#this pickupmin" render="pickupdate" immediate="true"/>
</p:selectOneMenu>
<p:selectOneMenu id="pickupmin" widgetVar="pickupmin" value="#{journeyCRUD.pickuptime}" immediate="true">
<f:selectItems value="#{journeyCRUD.minuteList}"/>
<f:converter converterId="datePartConverter"/>
<f:attribute name="part" value="minutes"/>
</p:selectOneMenu>
</h:form>
</h:panelGroup>
This converter only returns the updated model value after all values have been set. If you want to keep using this converter, your best bet is to extract it straight from the component which is available by <f:ajax listener> argument.
public updatePickupDate(AjaxBehaviorEvent event) {
UIInput component = (UIInput) event.getComponent();
Object value = Component.getValue();
// ...
}

p:selectOneRadio not updating model in event "change" with p:ajax

I'm using an p:selectOneRadio with p:ajax and the value of another component (p:inputText), not binding its value in my bean.
If I use p:selectBooleanCheckbox instead the behavior is exactly what I need, update the bean before calling the method in ajax. Is this a bug in p:selectOneRadio or is this its default behavior?
I'm using JSF2, PrimeFaces 4
The xhtml code:
<p:selectOneRadio id="enumId" value="#{xyzController.entity.enumValor}"
disabled="#{disabled}" required="true" plain="true">
<f:selectItems value="#{xyzController.enum}" var="item"
itemLabel="#{messages[ELUtils.evaluateExpression(itemLabelEL)]}"
itemValue="#{item}" />
<p:ajax event="change" listener="#{xyzController.aoTrocar}"
update="panelDominioFields" process="#form" />
</p:selectOneRadio>
<p:outputPanel layout="inline" id="panelDominioFields">
<p:inputText id="valorId"
value="#{xyzController.entity.valorNumericoValido}"
rendered="#{xyzController.mostrarCampoDominioNumerico}"
required="true">
<f:convertNumber type="number" locale="#{localeController.locale}"
currencyCode="#{localeController.currencyCode}" />
</p:inputText>
</p:outputPanel>
Get rid of event="change", it's the wrong event. It defaults to click and is the right one already.
<p:ajax listener="#{xyzController.aoTrocar}"
update="panelDominioFields" process="#form" />
Radio button values never change. They're only selected by click. In turn, selected values are submitted, but unselected values not.

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.

Ajax update part of panelGrid

I have a panel grid with 2 columns, the first containing a label and the second a component.
The listener backingBean.onFunktionChange sets the value of backingBean.functionGraduand to true. So the label and the menue for the degree are rendered in this case.
The problem is that if I first select a city in the menu for city and then change the value in the menu "function", the whole panel is updated and thus the city menu is reset.
However, in case of function change I want to to keep the preselected city.
If I wrap the label and component for function and degree in a panelGroup with id=panelFunction lets say and only update this panel, destroys the two column layout.
Is there any possibility to only update a part of the panelGrid without affecting the layout of the panelGrid?
<h:panelGrid columns="2" id="panel">
<label>#{function}</label>
<p:selectOneMenu id="menuFunction" value="#{...}" >
<p:ajax event="change" process="menuFunction"
update="panel"
listener="#{backingBean.onFunctionChange}" />
<f:selectItems .../>
</p:selectOneMenu>
<h:outputLabel id="labelDegree" for="menuDegree"
value="#{msgs.degree}"
rendered="#{backingBean.functionGraduand}" />
<p:selectOneMenu id="menuDegree" value="#{...}" rendered="#{backingBean.functionGraduand}">
<f:selectItems .../>
</p:selectOneMenu>
<label class="required">#{msgs.city}</label>
<p:selectOneMenu value="#{...}" id ="city">
<f:selectItems .../>
</p:selectOneMenu>
</h:panelGrid>
I solved this by processing the whole panel in the ajax request:
...
<p:ajax event="change" process="panel"
update="panel"
listener="#{backingBean.onFunctionChange}" />
...

Resources