how to set to OldValue the primefaces selectOneMenu programmatically - java

Java / PrimeFaces 3.5
I would like to rollback primeFaces selectOneMenu Old Value and reload it updating the component at screen.
The selectOneMenu is loaded with FIRST, SECOND , THIRD values and default value is setted with FIRST
If I change the selectOneMenu value From FIRST to THIRD, I would like to set it to FIRST again.
<p:selectOneMenu id="statusProposta"
value="#{propostaBean.propostaComercial.proposta_Status}"
items="#{propostaBean.statusProposta}"
valueChangeListener="#{propostaBean.regraStatusProposta}" >
<p:ajax event="change"
process="statusProposta" update="statusProposta" />
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{propostaBean.statusProposta}" />
</p:selectOneMenu>
StatusProposta :
public enum StatusProposta { FIRST,SECOND and THIRD .....
Bean :
public void regraStatusProposta(ValueChangeEvent ev){
**I dont know how to set the old value and update it in screen.**
...

public void regraStatusProposta(ValueChangeEvent ev){
//get old value first
Object oldValue=ev.getOldValue();
}
More on ValueChangeEvent API

http://forum.primefaces.org/viewtopic.php?f=3&t=36447
resetinput
blog post: Reset Values for JSF 2.2
posted by Howard at primefaces forum
http://www.primefaces.org/showcase/ui/resetInput.jsf
public void reset() {
RequestContext.getCurrentInstance().reset("form:panel");
}

I've created this utility for PrimeFaces which checks if the component is visible, otherwise it would log a WARN on console.
public static void resetUIComponents(String... componentsId) {
for (String id : componentsId) {
if (FacesContext.getCurrentInstance().getViewRoot().findComponent(id) != null) {
PrimeFaces.current().resetInputs(id);
}
}
}
So you can use it like this:
ViewUtils.resetUIComponents("form:id1", "form:id2")

Related

JSF list depending on selected value returning nullPointer

In my jsf page, in a dialog, I have a list of EntityB which depends on selected EntityA in a datatable.
When I first load the page it's giving me nullPpointer exception because nothing is selected in the first place. Can anyone tell me how to prevent this?
EDIT: I added an actionlistener to the link who open the dialog
and getting this error:
Cannot convert DemandesDocsAdministratif type DemandesDocsAdministratif to class javax.faces.event.ActionEvent
JSF:
<p:commandLink value="#{demande.idDemandeDocAdministratif}"
oncomplete="PF('dlg2').show()" process="#this"
update=":form:pg" actionListener="#{gestionDemandesMB.fillEntityB}">
<f:setPropertyActionListener
target="#{gestionDemandesMB.SelectedEntityA}" value="#{demande}"
/>
</p:commandLink>
<form>
<datatable>
</datatable>
<p:dialog>
<p:selectOneMenu id="Signataires"
value="#{gestionDemandesMB.entityB}">
<f:selectItems value="#{gestionDemandesMB.listEntityB}"
var="sign" itemLabel="#{sign.libRole}"
itemValue="#{sign.idPoste}" />
</p:selectOneMenu>
</p:dialog>
</form>
Bean:
public List<EntityA> getListEntityB() {
if ( selectedentityA != null ){
return entityBService.ListByentityA(selectedEntityA)
; } else {
return Collections.emptyList() ; }
Bean listener that I'm working with now:
public void fillSignataires(ActionEvent event)
{
listB = entityBService.ListByentityA(selectedEntityA)
signaRender = true ;
}
this is the getter of entity B list, I'm looking for a way to either get an empty list or call only when I open dialog.
You could use rendered="#{not empty bean.list}" to prevent the rendering of the selectOnMenu until you have the object filled.
You can also add a f:selectItem with a "Select" label and empty itemValue such as itemValue = " ". By the way, never have a null list, list shouldn't be null but it can be empty. It's the best practice. So you can initialize your listEntityB as an empty list at post construct of your bean.
<p:selectOneMenu id="Signataires"
value="#{gestionDemandesMB.entityB}">
<f:selectItem itemLabel="Select" itemValue="" />
var="sign" itemLabel="#{sign.libRole}"
<f:selectItems value="#{gestionDemandesMB.listEntityB}"
var="sign" itemLabel="#{sign.libRole}"
itemValue="#{sign.idPoste}" />
</p:selectOneMenu>

JSF with gettable only

I'm trying to achieve a chat system through JSF. All text typed inside h:inputText will be stored after h:commandButton is pressed. After this, I have a table to print all data typed so far. This way, I have the following code for JSF:
<h:form>
<h:inputText id="id1" value="#{unicoBean.text}" />
<h:commandButton id="botao" value="Entrar" action="#{unicoBean.test}"
onclick="test()"
/>
</h:form>
<h:dataTable value="#{unicoBean.all}" var="msg">
<h:column>
#{msg.text}
</h:column>
</h:dataTable>
<script>
function test() {
alert("alert");
}
</script>
And this for backbean:
#ManagedBean
public class UnicoBean {
Facade f = new Facade();
public void setText(String s) throws Exception {
f.setText(s);
}
public List<Message> getAll() throws Exception {
return f.getAll();
}
public void test() {
System.out.println("bean called on jsf");
}
}
Inside h:inputText I want only to set values, not get them and throw back to html. Unfortunately, JSF says "Expression is not gettable", even when I don't want to get anything, only set, as exposed on my Bean. How I solve this?
It's not possible to achieve this using getter/setter strategy because is not part of JSF but Expression Language (EL). JSF only uses it to bind the data of the HTML components to the fields of a bean through proper getters and setters
However, you can use binding attribute via UIInput to pass the input field value as an argument to your action button:
<h:form>
<h:inputText id="id1" binding="#{input1}" />
<h:commandButton id="botao" value="Entrar" action="#{unicoBean.test(input1.value)}"
onclick="test()" />
</h:form>
And then receive the new value from your action method:
public void test(String value) {
System.out.println("bean called on jsf: " + value);
}

How to set a f:selectItem in a specific option after a p:commandButton action?

I have a javascript code that clears all the p:inputText (after a p:commandButton action) of the form. The problem is that the p:selectOneMenu still has the f:selectItem selected in the option it was selected. I need to put the values in the first f:selectItem of each p:selectOneMenu.
How to I do that? How can I clear the selected values?
The java script code:
<script type="text/javascript">
function limpiarForm()
{
document.getElementById("formularioAltas").reset();
}
</script>
formularioAltas is the form id.
The code of the p:commandButton:
<p:commandButton value="Guardar" action="#{altasBean.agregarRefaccion()}" oncomplete="limpiarForm()" />
And that code does not reset(I dont want to clear the values, I just want to put the first option selected) the values of the p:selectOneMenu
Here it is:
<h:outputText value="Estado de la refacción" />
<p:selectOneMenu value="#{altasBean.refaccion.estado}">
<f:selectItem itemLabel="..." itemValue="0" />
<f:selectItem itemLabel="Ok" itemValue="Ok" />
<f:selectItem itemLabel="Reparar" itemValue="Reparar" />
<f:selectItem itemLabel="Sospechoso" itemValue="Sospechoso" />
</p:selectOneMenu>
The bean:
private RefaccionBean refaccion = null;
/**
* Get the value of refaccion
*
* #return the value of refaccion
*/
public RefaccionBean getRefaccion() {
return refaccion;
}
/**
* Set the value of refaccion
*
* #param refaccion new value of refaccion
*/
public void setRefaccion(RefaccionBean refaccion) {
this.refaccion = refaccion;
}
public void agregarRefaccion() {
I did a lot of things here...
And after those things i clear the p:inputText with the javascript code
-> After that i want to set the values of the p:selectOneMenu in the fist f:selectItem
}
Josef's answer does lead you in the right direction, but since you shared some code, I will just use it in my answer.
First, make sure that your button calls your bean method and updates the selectOneMenu component after it's done. Although there's some ajax going on here, primefaces abstracts that for you.
<p:commandButton value="Guardar" action="#{altasBean.agregarRefaccion}" update="selectOneMenu" />
The update attribute is important as it will look for the component whose id matches whatever is specified there. So you need to give your selectOneMenu an id. If you need to update more than one component, you can add their ids to the update attribute separated by either space or comma.
<h:outputText value="Estado de la refacción" />
<p:selectOneMenu value="#{altasBean.refaccion.estado}" id="selectOneMenu">
<f:selectItem itemLabel="..." itemValue="0" />
<f:selectItem itemLabel="Ok" itemValue="Ok" />
<f:selectItem itemLabel="Reparar" itemValue="Reparar" />
<f:selectItem itemLabel="Sospechoso" itemValue="Sospechoso" />
</p:selectOneMenu>
Now it's just a matter of cleaning up your values inside your action method:
public void agregarRefaccion() {
//If you have other values to clean, clean them here
this.refaccion.estado="0"; //Matches the value for your first item
}
Now I'm not entirely sure if I follow you, but let me know if this helps you out at all. It's entirely JSF and I threw in some ajax. You can play around with your javascript still.
Front-end:
<p:inputText id="input" value="#{bean.value}" />
<p:commandButton value="button" action="#{bean.action}">
<f:ajax execute="input" render="output" />
</p:commandButton>
<p:selectOneMenu id="output" value="#{bean.placeValue}">
<f:selectItems value="#{bean.values}" />
</p:selectOneMenu>
Bean:
#ManagedBean
#RequestScoped
public class Bean {
private String value;
private List<String> values;
#EJB
private ValueService valueService;
#PostConstruct
public void init() {
values = valueService.list();
}
public void action() {
// ... Action taken
}
public String placeValue() {
// ... Validation and clear desired values
return value;
}
// ... (getters, setters, etc)
}

JSF access html element value in bean class

I have a JSF application in which I have a combo box.
<h:selectOneMenu id="collectorType"
value="#{activityDataSource.object.type}"
rendered="#{empty activityDataSource.object.id}"
disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}"
onchange="$('editForm:selectTypeButton').click();">
<f:ajax event="change"
execute="#this"
render="dsTransformationRule dsCorrelationRule"
listener="#{activityDataSource.handleCollectorTypeChange}" />
<f:selectItem itemValue="" itemLabel="#{msgs.select_collector_type}"/>
<f:selectItems value="#{activityDataSource.collectorTypes}"/>
</h:selectOneMenu>
And I am getting selected value of that combo box in bean class like:
public void setSelectedTransformationRule(String transformationRule)
throws GeneralException {
String collectorType = (String) getRequestParam().get("editForm:collectorType");
}
And I am successful in doing so. I am calling this method through ajax onchage event of combobox.
But if I try to get same combo box value in a different method i get null value.
public void handleCollectorTypeChange() throws GeneralException {
String collectorType = (String) getRequestParam().get("editForm:collectorType");
}
Any help !
Because Process Events happens before Update Model Values you can retrieve the value from the component, from the UIViewRoot like this:
HtmlSelectOneMenu collectorTypeSelectMenu = (HtmlSelectOneMenu) FacesContext.getCurrentInstance().getViewRoot().findComponent("editForm:collectorType");
String collectorType = (String) collectorTypeSelectMenu.getValue();
try put the attributes process and partialSubmit in your ajax call with the values you need process like this:
<f:ajax event="change"
execute="#this"
render="dsTransformationRule dsCorrelationRule"
process="#this, collectorType"
partialSubmit="true"
listener="#{activityDataSource.handleCollectorTypeChange}" />
In the process atrribute you can put all ids you need to process with the updated values (like you see in the screen.

Primefaces picklist target and source values do not change

My primefaces pickList source and target values do not change, I have followed the example in primefaces showcase
and also looked at several posts here but still am not able to solve the problem. I am using a list from the database to populate the source as follows:
private DualListModel<Course> courseModel;
public CourseBean() {
List<Course> target = new ArrayList<Course>();
List<Course> source = new ArrayList<Course>();
courseModel = new DualListModel<Course>(source, target);
}
...
//this DualListModel getter also populates the source with values from db
public DualListModel<Course> getCourseModel() {
courseModel.setSource(getCourseList());
return courseModel;
}
My converter is
import org.omnifaces.converter.SelectItemsConverter;
#FacesConverter("courseConverter")
public class CourseConverter extends SelectItemsConverter {
#Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
Integer id = (value instanceof Course) ? ((Course) value).getId()
: null;
return (id != null) ? String.valueOf(id) : null;
}
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
Course course = new Course();
course.setId(Integer.parseInt(value));
return course;
}
}
and finally my xhtml page is:
<h:form>
<p:pickList id="coursesOffered"
value="#{courseView.courseModel}" var="course"
itemValue="#{course}" itemLabel="#{course.courseTitle}"
converter="courseConverter" showSourceFilter="true"
showTargetFilter="true" filterMatchMode="contains">
<f:facet name="targetCaption">Selected</f:facet>
<f:facet name="sourceCaption">All Courses</f:facet>
<p:ajax event="transfer" listener="#{courseView.onTransfer}" />
<p:column style="width:10%">
#{course.courseCode}:
</p:column>
<p:column style="width:90%">
#{course.courseTitle}
</p:column>
</p:pickList>
<p:commandButton id="pojoSubmit" value="Submit"
update="displayPlayers" oncomplete="playerDialog.show()"
style="margin-top:5px" />
<p:dialog showEffect="fade" hideEffect="fade" widgetVar="playerDialog">
<h:panelGrid id="displayPlayers" columns="2">
<h:outputText value="Source: " style="font-weight:bold" />
<ui:repeat value="#{courseView.courseModel.source}"
var="course">
<h:outputText value="#{course.courseTitle}"
style="margin-right:5px" />
</ui:repeat>
<h:outputText value="Target: " style="font-weight:bold" />
<ui:repeat value="#{courseView.courseModel.target}"
var="course">
<h:outputText value="#{course.courseTitle}"
style="margin-right:5px" />
</ui:repeat>
</h:panelGrid>
</p:dialog>
</h:form>
The pickList is displayed correctly with source populated with values from database, however, upon clicking the button, the dialog just displays the original source list values and an empty target list even after transferring items on the interface. What am I missing?
I see some problems with your code. In the getter, you are reconstructing the DualList from the database, reseting any changes you've done so far.
try making you getter something like this:
public DualListModel<Course> getCourseModel() {
return this.courseModel;
}
Construct and load your list from the database in a method annotated #PostConstruct rather than in the constructor+getter.
public CourseBean() {}
#PostConstruct
public void init() {
List<Course> target = new ArrayList<Course>();
courseModel.setSource(getCourseList());
courseModel = new DualListModel<Course>(source, target);
}
Also annotate your bean #ViewScoped, so you dont construct a new bean with empty target-list on every request
#ManagedBean(name="courseView")
#ViewScoped
public class CourseBean {
}
Finally you also need a setter:
public void setCourseModel(DualListModel<Course> courseModel) {
this.courseModel = courseModel;
}
I have not really looked into the converter, when I did a picklist lasttime i took the converter included in primefaces showcase (Never tried the omnifaces one). Here is a link to the source: http://code.google.com/p/ind/source/browse/indicadorCensoJSF/src/ve/gob/ine/censo/beans/convert/PrimeFacesPickListConverter.java?spec=svn154&r=154
Complementary to the accepted answer, I had a problem with the Omnifaces list converter. Everything worked, except that the already picked items weren't being updated and "lost", it is, they were there in the view but the only items processed were the picked in the view, not the ones that were already set as targets in the bean, so, instead of having a target list with the picked items plus the ones that were set at the dualList constructor, the target list had just the ones picked at the view, not the previously set items.
As a solution, I also implemented a custom picklist converter for the primefaces component. Now everything works like a charm.
I'm not answering specifically the actual question because it has an accepted answer already (and i don't have the points to make a comment). I'm just complementing, as some people may have problems using primefaces 2.3 and omnifaces 3.1. I did search a lot about the problem I was facing, and did not found at least a hint of what was happening.
This site: picklist example has a tutorial on how to make the converter, if someone has doubts. ACV's answer is also valid for the converter, although it was already implemented by Silverfish, who asked the question.
To work with objects, you need a converter. This is the best answer how to implement it: https://stackoverflow.com/a/6625392/912829

Categories

Resources