How to set default value of h:selectOneRadio button - jsf

I am unable to set the default value of h:selectOneRadio as i need radio button to be pre selected
<h:selectOneRadio id="myRadio" value="#{Externalbean.addressFlag}" >
<f:selectItem itemValue="1" itemLabel="Yes"/>
<f:selectItem itemValue="0" itemLabel="No"/>
</h:selectOneRadio>
and my backing bean is
private String addressFlag="0";
public String getAddressFlag() {
return addressFlag;
}
public void setAddressFlag(String addressFlag) {
this.addressFlag = addressFlag;
}
but no luck

You need to set the default value in the init method of your backing bean:
#ManagedBean
public class YourBackingBean implements Serializable {
private String addressFlag;
#PostConstruct
public void init() {
addressFlag = "0";
}
public String getAddressFlag() {
return addressFlag;
}
public void setAddressFlag(String addressFlag) {
this.addressFlag = addressFlag;
}
}

I did a little test, it works just fine as expected, but I also observed that when you leave out the <h:form> tag, the behaviour of radio buttons is unpredictable and dependent on the webbrowser. The JSF-generated HTML output looks correct, but the webbrowser would in the view only select the button which was actually selected by the user in the previous request on the same page. If the cache is empty, none of the buttons is selected. At least, that was the case in FF.
So, it look like that you have forgotten to put a <h:form> around it.

Only use that <h:selectOneRadio required="true"> :
<h:selectOneRadio required="true" id="myRadio" value="#{Externalbean.addressFlag}" >
<f:selectItem itemValue="1" itemLabel="Yes"/>
<f:selectItem itemValue="0" itemLabel="No"/>
</h:selectOneRadio>

Did you try to set the addressFlag as an Integer?
private Integer addressFlag = 0;
public Integer getAddressFlag() {
return addressFlag;
}
public void setAddressFlag(Integer addressFlag) {
this.addressFlag = addressFlag;
}

Related

jsf selectOneMenu value does not change

I have a selectOneMenu that have the correct values (a list of string) however when I select a value it does not trigger the setSelectedValue from the bean.
<h:selectOneMenu layout="lineDirection" id="myMenu" value="#{dwrBean.selectedValue}">
<f:selectItems value="#{Bean.values}"/>
</h:selectOneMenu>
Bean:
private String selectedValue = "";
private List<String> values = new LinkedList<String>();
...
public String getSelectedValue() {
return this.selectedValue;
}
public void setSelectedValue(String selectedValue) {
LOGGER.debug("Try to set selected value" + selectedValue);
if (!selectedValue.isEmpty()){
this.selectedValue = selectedValue ;
}
}
There is nothing in the logs.
I've tried to add a listener:
<h:selectOneMenu layout="lineDirection" id="myMenu" value="#{dwrBean.selectedValue}" valueChangeListener="#{dwrBean.statusChanged}" >
<f:selectItems value="#{dwrBean.values}"/>
</h:selectOneMenu>
Here the statusChanged is triggered but the newValue is null, the oldValue is correct, but it is always the same.
public void statusChanged(ValueChangeEvent event) {
LOGGER.debug("new" + event.getNewValue());
LOGGER.debug("old" + event.getOldValue());
if (event.getNewValue() != null &&
!((String) event.getNewValue()).isEmpty()) {
LOGGER.debug("OK");
}
}
I really don't understand.
Actually the selectOneMenu is within a popup.
I've moved the selectOneMenu outside of the popup and it works. Do I have to change the scope of the Bean ?
Non-working configuration:
<h:form>
<rich:popupPanel>
<h:selectOneMenu>
...
</h:selectOneMenu>
<rich:popupPanel>
<h:form>
Working configuration:
<h:form>
<h:selectOneMenu>
...
</h:selectOneMenu>
<rich:popupPanel>
<rich:popupPanel>
<h:form>
below method invoke when you subbmit form
public void setSelectedValue(String selectedValue) {
LOGGER.debug("Try to set selected value" + selectedValue);
if (!selectedValue.isEmpty()){
this.selectedValue = selectedValue ;
}
}
You need to use AJAX to do a partial form submission when the value changes. The valueChangeListener is a hook that provides your code with notification when the value has changed and the form has been submitted.
The code below will register an AJAX event for the onchange event for selectOneMenu. The value changes it will then execute the menu (submit the value to the bean).
<h:selectOneMenu layout="lineDirection" id="myMenu" value="#{dwrBean.selectedValue}">
<f:selectItems value="#{dwrBean.values}"/>
<f:ajax/>
</h:selectOneMenu>

#ConversationScoped is spoiling the filtering and sorting options in form, #ViewScoped works fine

I'm working on a small course passing project, and I have a problem.
The manager.xhtml is a JSF page, it is used to view the data from database, sort them, filter them, delete entries and edit those entries. When I'm using #ViewScoped in Manager.java - everything EXCEPT the edit part works just fine. The "Edit" link is sending the user to another page - edit.xhtml. After I used #ConversationScoped to be able to read data send from manager.xhml in edit.xhtml. After using #ConversationScoped the entry editing option worked flawlessly, but it started making errors in some of the filtering/sorting options - sorting by CATEGORY started pulling out errors like "Name is null", filtering by price - the same.
Here is the code.
manager.xhtml
Here is the form in which the problems start to occur while using #ConversationScoped
<h:form>
<h:panelGrid id="filterPanel" columns="7">
<f:ajax render="filterValue" event="change" execute="filterValue">
#{text.sort}
<h:selectOneMenu value="#{manager.order}">
<f:selectItem itemValue="cargoName" itemLabel="#{text.cargo_name}"/>
<f:selectItem itemValue="price" itemLabel="#{text.cargo_price}"/>
<f:selectItem itemValue="category" itemLabel="#{text.cargo_category}"/>
</h:selectOneMenu>
<h:selectOneMenu id="filterType" value="#{manager.filterType}">
<f:selectItem itemValue="CARGO_NAME" itemLabel="#{text.cargo_name}"/>
<f:selectItem itemValue="PRICE" itemLabel="#{text.cargo_price_filter}"/>
<f:selectItem itemValue="CATEGORY" itemLabel="#{text.cargo_category}"/>
</h:selectOneMenu>
<h:panelGroup id="filterValue">
<h:panelGroup id="filterValues">
<h:inputText id="filterValueInput" value="#{manager.filterValue}" rendered="#{manager.filterType == 'CARGO_NAME'
or manager.filterType == 'PRICE'}"
required="#{manager.filterType == 'PRICE'}"/>
<h:message for="filterValueInput"/>
<h:inputText id="filterValueInput2" value="#{manager.filterValue2}" rendered="#{manager.filterType == 'PRICE'}"
required="#{manager.filterType == 'PRICE'}"/>
<h:message for="filterValueInput2"/>
</h:panelGroup>
<h:selectOneMenu id="cargoForm" value="#{manager.filterValue}" rendered="#{manager.filterType == 'CATEGORY'}">
<f:selectItem itemLabel="#{text.cargo_text_BOOKS}" itemValue="BOOKS"/>
<f:selectItem itemLabel="#{text.cargo_text_CALENDARS}" itemValue="CALENDARS"/>
<f:selectItem itemLabel="#{text.cargo_text_CD}" itemValue="CD"/>
<f:selectItem itemLabel="#{text.cargo_text_EBOOKS}" itemValue="EBOOKS"/>
<f:selectItem itemLabel="#{text.cargo_text_OFFICE}" itemValue="OFFICE"/>
<f:selectItem itemLabel="#{text.cargo_text_VINYL}" itemValue="VINYL"/>
</h:selectOneMenu>
</h:panelGroup>
</f:ajax>
<h:commandButton action="#{manager.filter}" value="#{text.button_refresh}"/>
<h:commandButton action="#{manager.reset}" value="#{text.button_reset}"/>
</h:panelGrid>
edit.xhtml
The edition form - it's filled with the data of selected entry ONLY when using #ConversationScoped:
Getting the ID sent by manager.xhtml
<h:inputHidden value="#{manager.editCargo.id}"/>
In the form the data is taken from manager like this:
<h:inputText id="cargoName" value="#{manager.editCargo.cargoName}" required="true">
</h:inputText>
button to save changes:
<h:commandButton value="#{text.edit_button}" action="#{manager.update}"/>
Manager.java - unnecesary code removed.
#ConversationScoped
#ManagedBean
public class Manager implements Serializable {
#Inject
private CargoRepository repository; // tworzy nową instancję objektu CargoRepository
private List<Cargo> cargos; // tworzy listę obiektów Cargo
private String order = CARGO_NAME; // musi istnieć by zainicjować jakąś zmienną order, ponieważ manager.xhtml już na starcie sortuje po order więc nie może być null.
private FilterType filterType = FilterType.CARGO_NAME;
private String filterValue;
private String filterValue2;
#Inject
private Conversation conversation;
Getters and setters removed...
#PostConstruct
public void init() {
cargos = repository.getAll(order);
editCargo = new Cargo();
}
public void filter() {
if (filterType == FilterType.PRICE) {
cargos = repository.getAll(filterType, filterValue, filterValue2, order);
} else {
cargos = repository.getAll(filterType, filterValue, order);
}
}
public void resetFilterValue() {
filterValue = "";
filterValue2 = "";
}
public String edit(Cargo cargo) {
conversation.start();
editCargo = cargo;
return "edit";
}
public String update() {
conversation.end();
repository.update(editCargo);
System.out.println(editCargo.toString());
init();
return "manager";
}
}
I've managed to repair the problem.
Instead of:
#ConversationScoped
#ManagedBean
I have used
#Named
#SessionScoped
The #SessionScoped was imported from
import javax.enterprise.context.SessionScoped;
I removed EVERYTHING related to #ConversationScoped including
#Inject
private Conversation conversation;
and every usage of
conversation.start();
conversation.end();
Everything is working flawlessly now.

p:selectOneMenu value still required

In my xhtml page i have two dependant selectOneMenu, with the second one being filled in an ajax call. Here's the jsf code fragment:
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel value="Dirección:" for="direccion"/>
<p:inputText id="direccion" value="#{datosInstitucion.institucion.direccion}" required="true" label="Dirección"/>
<h:outputLabel value="Departamento:" for="departamento"/>
<p:selectOneMenu id="departamento" value="#{datosInstitucion.idDepartamento}" required="true" label="Departamento">
<f:selectItem itemLabel="Seleccione el departamento" itemValue="#{null}"/>
<c:forEach items="#{datosInstitucion.departamentos}" var="departamento">
<f:selectItem itemLabel="#{departamento.nombre}" itemValue="#{departamento.id}"/>
</c:forEach>
<f:ajax render="municipio" listener="#{datosInstitucion.cargarMunicipios()}"/>
</p:selectOneMenu>
<h:outputLabel value="Municipio:" for="municipio"/>
<p:selectOneMenu id="municipio" value="#{datosInstitucion.idMunicipio}" required="true" label="Municipio">
<f:selectItem itemLabel="Seleccione el municipio" itemValue="#{null}"/>
<c:forEach items="#{datosInstitucion.municipios}" var="municipio">
<f:selectItem itemLabel="#{municipio.nombre}" itemValue="#{municipio.id}"/>
</c:forEach>
</p:selectOneMenu>
</h:panelGrid>
This fragment of code is inside a primefaces wizard component, so when the 'next' button is pressed a validation error is caused for the second selectOneMenu even when there's a value set.
What could be causing this behavior?
Relevant backing bean code:
#ManagedBean(name = "datosInstitucion")
#ViewScoped
public class DatosInstitucion implements Serializable{
#EJB
private Instituciones instituciones;
#EJB
private Parametros parametros;
#Inject
private Mensajes mensajes;
private List<Departamento> departamentos;
private List<Municipio> municipios;
private Map<Integer, Departamento> mapaDepartamentos;
private Integer idDepartamento;
private Integer idMunicipio;
private Institucion institucion;
#PostConstruct
private void inicializar(){
this.mapaDepartamentos = new HashMap<>();
this.departamentos = parametros.consultarDepartamentos();
for(Departamento departamento : departamentos){
this.mapaDepartamentos.put(departamento.getId(), departamento);
}
this.prepararInstitucion();
}
private void prepararInstitucion(){
this.institucion = new Institucion();
this.institucion.setResponsable(new Persona());
}
public Institucion getInstitucion() {
return institucion;
}
public List<Departamento> getDepartamentos(){
return departamentos;
}
public TipoIdentificacion[] getTiposIdentificacion(){
return TipoIdentificacion.deResponsables();
}
public Integer getIdDepartamento() {
return idDepartamento;
}
public void setIdDepartamento(Integer idDepartamento) {
this.idDepartamento = idDepartamento;
}
public Integer getIdMunicipio() {
return idMunicipio;
}
public void setIdMunicipio(Integer idMunicipio) {
this.idMunicipio = idMunicipio;
}
public void cargarMunicipios(){
idMunicipio = null;
if(idDepartamento != null){
this.municipios = mapaDepartamentos.get(idDepartamento).getMunicipios();
}else{
this.municipios = Collections.emptyList();
}
}
public List<Municipio> getMunicipios() {
return municipios;
}
public void confirmar(){
this.instituciones.guardar(institucion);
this.mensajes.exito("La institución ha sido registrada en el sistema");
this.prepararInstitucion();
}
}
This is because you are using JSTL <c:foreach> with JSF. The life cycle of JSTL vs JSF matters. JSTL is executed when the view is being built, while JSF is executed when the view is being rendered. The two do not work in synch with each other. In your case, you need to use <f:selectItems> instead of <c:foreach>
Replace:
<c:forEach items="#{datosInstitucion.municipios}" var="municipio">
<f:selectItem itemLabel="#{municipio.nombre}" itemValue="#{municipio.id}"/>
</c:forEach>
with:
<f:selectItems value="#{datosInstitucion.municipios}"
var="municipio" itemLabel="#{municipio.nombre}"
itemValue="#{municipio.id}"/>
For more reading, I suggest you to read the following answer

Disabling items with PrimeFaces SelectOneMenu with custom content / p:column

it seems as if it is not possible to disable items in a SelectOneMenu from PrimeFaces (3.3) when using the custom content (as shown at http://www.primefaces.org/showcase-labs/ui/selectOneMenu.jsf).
The testcase is simple, just take the following:
<h:form>
<p:selectOneMenu value="#{testBean.selected}">
<f:selectItems value="#{testBean.options}" var="t"
itemLabel="#{t.label}" itemValue="#{t}"
itemDisabled="#{t.value % 2 == 0 ? 'true' : 'false'}" />
</p:selectOneMenu>
<p:selectOneMenu value="#{testBean.selected}" var="x">
<f:selectItems value="#{testBean.options}" var="t"
itemLabel="#{t.label}" itemValue="#{t}"
itemDisabled="#{t.value % 2 == 0 ? 'true' : 'false'}" />
<p:column>
#{x.label} -- #{x.label}
</p:column>
</p:selectOneMenu>
</h:form>
and the following Java files:
Bean:
#Named
public class TestBean {
private TestObject selected;
// getter/setter
public List<TestObject> getOptions() {
return Arrays.asList(new TestObject("1"), new TestObject("2")); }
}
Object:
public class TestObject {
private Integer value;
// getter/setter
public TestObject() {}
public TestObject(String s) {
this.setLabel(s);
}
public String getLabel() {return "label: " + value;}
public void setLabel(String l) {this.value = new Integer(l);}
}
The first dropdown works fine, the second one doesn't. Any idea on how to solve that?

JSF- passing a parameter to valuechangelistener

I have a litte radiobutton like this :
<h:selectOneRadio value="#{test.answer}" valueChangeListener="#{TestService.changeanswer}" immediate="true" id="answer">
<f:selectItem itemValue="A" itemLabel="Absolutely True"/>
<f:selectItem itemValue="B" itemLabel="True"/>
<f:selectItem itemValue="C" itemLabel="Partially True"/>
<f:selectItem itemValue="D" itemLabel="Not True"/>
<f:selectItem itemValue="E" itemLabel="Definitely Not True"/>
<f:ajax event="change" process="answer"></f:ajax></h:selectOneRadio>
And my listener is like that :
public void changeanswer(ValueChangeEvent vcEvent) {
System.out.println("comeon= " + vcEvent.getOldValue());
System.out.println("comeon= " + vcEvent.getNewValue());}
I would like to pass a parameter to the changeanswer method.For example I want to pass the questionid to the changeanswer function. I need to make some arrangements in it.
How can I do that?
Many many many thanks in advance.
Brad - the Rookie..
You can use the f:attribute tag to send any data to the ValueChangeListener:
<h:selectOneRadio value="#{test.answer}"
valueChangeListener="#{TestService.changeanswer}"
immediate="true" id="answer">
<f:attribute name="myattribute" value="#{test.questionid}" />
<f:selectItem itemValue="A" itemLabel="Absolutely True"/>
...
</h:selectOneRadio>
If we suppose questionId is an Integer, then you can receive the data the following way:
public void changeanswer(ValueChangeEvent vcEvent) {
Integer questionId =
(Integer) ((UIInput) vcEvent.getSource()).getAttributes().get("myattribute");
Seeing how the component values are bound, I bet that it's inside a datatable. If that is indeed the case, you can use DataModel#getRowData() to obtain the current row. Add a DataModel property to the TestService bean like follows:
private List<Question> questions;
private DataModel<Question> questionModel;
#PostConstruct
public void init() {
questions = getItSomehow();
questionModel = new ListDataModel<Question>(questions);
}
public void change(ValueChangeEvent event) {
Question currentQuestion = questionModel.getRowData();
// ...
}
and change the view as follows:
<h:dataTable value="#{TestService.questionModel}" var="test">
That said, I'd suggest to use more sensible variable names than TestService, test and change(), like Questionaire, question and changeAnswer() respectively. This makes the code more self-documenting.

Resources