I am developing a system that the user choose some checkboxes and each checkbox have a currency value, and I want to change a outputText according to selected checkboxes.
Example: I have three checkboxes, each one have $10.00. If the user choose just two checkboxes, the outputText must show $20.00. If the user choose the last one, the outputText must show $30.00. And all this without reloading the page.
My code so far:
<h:form id="form">
<p:fieldset legend="Tipo base do site:" style="margin-bottom:20px">
<h:panelGrid columns="2" cellpadding="5">
<p:dataList value="#{tiposIndexView.tipos}" var="tipo"
type="ordered" >
R$
<h:outputText value="#{tipo.preco}" >
<f:convertNumber pattern="#0.00" />
</h:outputText>
</p:dataList>
<p:selectOneRadio id="tipo" value="#{tiposIndexView.tipos}"
layout="grid" columns="1">
<f:selectItems value="#{tiposIndexView.tipos}" var="tipo"
itemLabel="#{tipo.nome}" itemValue="#{tipo.nome}" />
</p:selectOneRadio>
</h:panelGrid>
</p:fieldset>
<p:fieldset legend="Sistemas adicionais:" style="margin-bottom:20px">
<h:panelGrid columns="2" cellpadding="5">
<p:dataList value="#{sistemasIndexView.sistemas}" var="sistema"
type="ordered" >
R$
<h:outputText value="#{sistema.preco}" >
<f:convertNumber pattern="#0.00" />
</h:outputText>
</p:dataList>
<p:selectManyCheckbox style="margin-top:0px;!important" id="grid" value="#{sistemasIndexView.sistemas}" layout="grid" columns="1">
<f:selectItems value="#{sistemasIndexView.sistemas}" var="sistema" itemLabel="#{sistema.nome}" itemValue="#{sistema}" />
</p:selectManyCheckbox>
</h:panelGrid>
</p:fieldset>
<p:fieldset legend="Valor total:">
<h:outputText>
R$
<f:convertNumber pattern="#0.00" />
</h:outputText>
</p:fieldset>
</h:form>
The last outputText is where I want to show the total value.
And one more question, every time that I open my site, all checkboxes starts checked and I want to all start unchecked. The code of checkboxes:
#ManagedBean
#ViewScoped
public class SistemasIndexView implements Serializable{
private static final long serialVersionUID = -2697991732915561009L;
private List<Sistema> sistemas;
#PostConstruct
public void init(){
sistemas = new ArrayList<>();
sistemas.add(new Sistema("Teste", 200));
sistemas.add(new Sistema("Exemplo", 300));
sistemas.add(new Sistema("gsdfaf", 50));
}
public List<Sistema> getSistemas() {
return sistemas;
}
public void setSistemas(List<Sistema> sistemas) {
this.sistemas = sistemas;
}
}
You need 2 lists, one for storing all checkboxes and second for selected ones. That's why you have all checkboxes selected because your selected values are the same as all possible.
Css mistake: style="margin-top:0px;!important" should be style="margin-top:0px !important;"
Things you need in your backing bean (with getters/setters):
List for selected items private List<Sistema> selectedSistemas;
Field for calculated sum private int sum
Method for calculating output public void calculateSum()
Code
<p:selectManyCheckbox style="margin-top:0px !important;" id="grid" value="#{sistemasIndexView.selectedSistemas}" layout="grid" columns="1">
<f:selectItems value="#{sistemasIndexView.sistemas}" var="sistema" itemLabel="#{sistema.nome}" itemValue="#{sistema}" />
<p:ajax process="#this" listener="#{test.calculateSum}" update="sum"/>
</p:selectManyCheckbox>
<h:outputText id="sum" value="#{test.sum}">
<f:convertNumber pattern="#0.00" />
</h:outputText>
And calculating method, you can change it but from what you have written it does the job
public void calculateSum() {
sum = selectedSistemas.size() * 10;
}
Related
I am Creating a jsf application and I need to perform CRUD. So far I have managed to delete,create,and read but am unable to update the record.So my problem is, I want when the user click the update button a dialog box to pop with the details of the selected row and update the details. Here is My sample code.
<p:panelGrid columns="2">
<h:outputLabel value="Account Id"/>
<h:inputText value="#{accCtr.acc.accountNum}" />
<h:outputLabel value="Account Bal"/>
<h:inputText value="#{accCtr.acc.balance}"/>
<h:outputLabel />
<p:commandButton action="#{accCtr.create()}" value="Enter" update="dt"/>
</p:panelGrid>
<p:dataTable value="#{accCtr.list}" var="i" id="dt" style="width: 40%;" rowStyleClass="height" rowKey="#{accCtr.acc.accountNum}" >
<p:column>
<f:facet name="header">Account Num</f:facet>
#{i.accountNum}
</p:column>
<p:column>
<f:facet name="header">Account Balance</f:facet>
#{i.balance}
</p:column>
<p:column>
<f:facet name="header">Action</f:facet>
<p:commandButton value="Remove" styleClass="height"
action="#{accCtr.removeAccount(i)}"
/>
<p:commandButton value="Edit" styleClass="height"
onclick="pop.show()"
action="#{accCtr.edit(i)}"
>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
<p:dialog widgetVar="pop" header="Account Edit">
<h:form>
<p:panelGrid columns="2">
<h:outputLabel value="Account Balance"/>
<h:inputText value="#{accCtr.acc.balance}"/>
<h:outputLabel/>
<p:commandButton value="Update"/>
</p:panelGrid>
</h:form>
</p:dialog>
can someone help me.
and my backing bean.
#ManagedBean(name="accCtr")
#SessionScoped
public class AccountController {
List<AccountTable> list=new ArrayList<>();
public AccountController() {
}
private Account_dao getDao()
{
return new Account_dao();
}
public List<AccountTable> getList() {
return getDao().findAll();
}
public void setList(List<AccountTable> list) {
this.list = list;
}
public void removeAccount(AccountTable acc) {
getDao().remove(acc);
}
public AccountTable acc=new AccountTable();
public AccountTable getAcc() {
return acc;
}
public void setAcc(AccountTable acc) {
this.acc = acc;
}
public void edit(AccountTable acc) {
setAcc(acc);
}
public String create()
{
this.acc.setUserid(10);
getDao().create(this.acc);
return "index";
}
Change your
<p:commandButton value="Edit" styleClass="height"
onclick="pop.show()"
action="#{accCtr.edit(i)}"
/>
to
<p:commandButton value="Edit" styleClass="height"
oncomplete="pop.show()"
actionListener="#{accCtr.edit(i)}"
process="#this" update=":your_dialog_form_id"
/>
A few things: In general the action atributte is used for navigation (redirect to another page for instance). Also is better to use oncomplete beacuse it gets executed when your ajax request is completed, instead of onclick that fires the action (open the dialog in your case) in the moment when you press the button, skipping validation and such things.
If your problem was, refreshing the dialog content, with the update/process (ajax) mechanism, will be updated with your current selection if you do like the second snippet.
i have a p:selectOneMenu filled with objects from database.When page is looaded first,
the default item of selectOneMenu must be "please select one" in string type( other items of selectOneMenu are in object type.) When page is loaded first, one data in object type from database is visible as default.I don't want this.how to set default item like "Please select one" in p:selectOneMenu with object from database?
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
template="layout.xhtml">
<ui:define name="pageContent">
<h:form id="silYapilandirmaForm" prependId="true">
<p:panel id="silYapilandirmaPanel" header="#{etiketler.silYapilandirma}" collapsed="true" toggleable="true" >
<p:tabView id="tabView" dynamic="false" activeIndex="0">
<p:tab title="#{etiketler.silIslemleri}" id="silIslemleriTab">
<p:outputPanel id="silIslemleriPanel">
<h:panelGrid id="eshsSecPanelGrid" columns="3" >
<h:outputText value="#{etiketler.eshsSertifika}:*" />
<p:selectOneMenu id="silYapilandirmaSelect" value="#{silYapilandirmaView.seciliEshsSertifika}" effect="fade" effectDuration="100" style="width: 205px" converter="#{entityConverter}">
<f:selectItem itemLabel="Please select one" itemValue="#{null}"/>
<f:selectItems value="#{silYapilandirmaView.eshsSertifikaList}" var="eshsSertifika"
itemLabel="#{eshsSertifika.sertifikaKodAdi}" itemValue="#{eshsSertifika}" />
<p:ajax process="#this" event="change" update="eshsSecPanelGrid,silIslemleriPanel" listener="#{silYapilandirmaView.addListener()}" />
</p:selectOneMenu>
<h:outputText value=""/>
<h:outputText value="#{etiketler.eshsSertifika}:" />
<h:inputText value="#{silYapilandirmaView.seciliEshsSertifika.sertifikaKodAdi}" disabled="true" size="30"/>
<h:outputText value=""/>
<h:outputText value="#{etiketler.silUretimBaslangicSaati}:* " />
<p:inputMask id="silUretimBaslangicSaatiInputMask" value="#{silYapilandirmaView.seciliEshsSertifika.silUretimBaslangicSaati}" mask="99:99:99" size="30" />
<p:message for="silUretimBaslangicSaatiInputMask" display="text" />
<h:outputText value="#{etiketler.silUretimBaslangicPeriyodu}:* " />
<p:inputMask maxlength="4" mask="99?99" id="periyotInputMask" size="30" value="#{silYapilandirmaView.seciliEshsSertifika.silUretimPeriyodu}" >
</p:inputMask>
<p:message for="periyotInputMask" display="text" />
</h:panelGrid>
</p:outputPanel>
</p:tab>
</p:tabView>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
i have addListener method in p:ajax in p:selectOneMenu.This method is working in this way;
you are selecting one object from selectOneMenu and this object is put in the last index of the list filling selectOneMenu ,the object in the last index of the list is put in the index of selected object.I mean you are selecting an object and the index of this object in the list is 2.In total there are five objects in the list ,let we say.selected object whose index is 2 is put in index 4 of the list.The object in index 4 of the list is put in index 2 of the list.I am sorry for my english.The aim of this addListener method,selectOneMenu displays the last item of the list as selected always.Whichever object you select,IT DISPLAYS THE LAST ITEM OF THE LIST.Therefore due to this method , the object i selected is put in the last of the list and it displays as selected to user.The method works fine.
But when page is loaded first , the last item of the list is shown as selected in p:selectOneMenu ,i want "please select" to be shown as default."
My bean class is SilYapilandirmaView.java
#ManagedBean
#ViewScoped
public class SilYapilandirmaView extends BaseView implements Serializable {
#ManagedProperty("#{commonService}")
private CommonService commonService;
private EshsSertifika seciliEshsSertifika;
private List<EshsSertifika> eshsSertifikaList;
#PostConstruct
public void init() {
seciliEshsSertifika=new EshsSertifika();
eshsSertifikaList = (List) commonService.hepsiniGetir(EshsSertifika.class);
seciliEshsSertifika = eshsSertifikaList.get(eshsSertifikaList.size() - 1);
}
public CommonService getCommonService() {
return commonService;
}
public void setCommonService(CommonService commonService) {
this.commonService = commonService;
}
public void addListener() {
if(seciliEshsSertifika ==null)
{
return;
}
int i = 0;
for (EshsSertifika eshsSert : eshsSertifikaList) {
if (seciliEshsSertifika.getId() == eshsSert.getId()) {
eshsSert = eshsSertifikaList.get(eshsSertifikaList.size() - 1);
eshsSertifikaList.set(i, eshsSert);
eshsSertifikaList.set(eshsSertifikaList.size() - 1, seciliEshsSertifika);
break;
}
i++;
}
}
public EshsSertifika getSeciliEshsSertifika() {
return seciliEshsSertifika;
}
public void setSeciliEshsSertifika(EshsSertifika seciliEshsSertifika) {
this.seciliEshsSertifika = seciliEshsSertifika;
}
public List<EshsSertifika> getEshsSertifikaList() {
return eshsSertifikaList;
}
public void setEshsSertifikaList(List<EshsSertifika> EshsSertifikaList) {
this.eshsSertifikaList = EshsSertifikaList;
}
}
When i added following code in init() method ,my code is working perfectly!
seciliEshsSertifika=null;
public void init() {
seciliEshsSertifika=new EshsSertifika();
eshsSertifikaList = (List) commonService.hepsiniGetir(EshsSertifika.class);
seciliEshsSertifika = eshsSertifikaList.get(eshsSertifikaList.size() - 1);
seciliEshsSertifika=null;
}
when page is loaded, "please select one" is visible in p:selectOneMenu,but i don't want to make "seciliEshsSertifika" object equal to null.,is there anybody else coming up with another solution?
Try this. get the object you want to set the first item. (this example i get the first object in the list)
bean.java
EshsSertifika firstItem = eshsSertifikaList.get(0);
xhtml
<f:selectItem itemLabel="#{eshsSertifika.firstItem.sertifikaKodAdi}" itemValue="#{eshsSertifika.firstItem}" />
I have a rich:dataTable and like to show details to each row in a rich:popupPanel when the user clicks on the detail button.
I do this like this
<h:panelGrid columns="3" columnClasses="titleCell">
<h:form id="form">
<rich:dataScroller for="table" maxPages="5" />
<rich:dataTable value="#{tournSelectionBean.tournaments}"
var="tourn" id="table" rows="10">
<rich:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{tourn.name}" />
</rich:column>
<rich:column>
<a4j:commandButton value="Detail"
action="#{tournSelectionBean.setCurrentTournament(tourn)}"
render=":detailpopup"
oncomplete="#{rich:component('detailpopup')}.show();" />
</rich:column>
</rich:dataTable>
<rich:dataScroller for="table" maxPages="5" />
</h:form>
</h:panelGrid>
<rich:popupPanel id="detailpopup" modal="true" resizeable="false"
autosized="true">
<f:facet name="header">
<h:outputText value="#{tournSelectionBean.currentTournament.name}" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#"
onclick="#{rich:component('detailpopup')}.hide(); return false;">
</h:outputLink>
</f:facet>
<h:panelGrid columns="2" columnClasses="titleCell">
<h:outputLabel value="City" />
<h:outputLabel
value="#{tournSelectionBean.currentTournament.city}" />
</h:panelGrid>
Close
</rich:popupPanel>
The setPropertyActionListener sets the ID correctly and the popup opens as expected. But the popup shows the details of the tournament that was in the bean when the view was created (and not the one that was set by the propertyactionlistner).
How can I achieve this?
EDIT: Updated above code and added Bean:
#Named("tournSelectionBean")
#ViewScoped
public class TournamentSelectionBean implements Serializable {
#EJB
private TournamentControllerInterface tournamentController;
private List<Tournament> tournaments;
private Tournament currentTournament;
#PostConstruct
public void init() {
tournaments = tournamentController.loadTournaments(true, false);
}
/**
* #return the tournaments
*/
public List<Tournament> getTournaments() {
return tournaments;
}
/**
* #param tournaments
* the tournaments to set
*/
public void setTournaments(List<Tournament> tournaments) {
this.tournaments = tournaments;
}
/**
* #return the currentTournament
*/
public Tournament getCurrentTournament() {
return currentTournament;
}
/**
* #param currentTournament the currentTournament to set
*/
public void setCurrentTournament(Tournament currentTournament) {
this.currentTournament = currentTournament;
}
}
You need to tell JSF to re-render the popup html before you open it:
<a4j:commandButton value="Detail"
action="#{tournSelectionBean.setCurrentTournament(tourn)}"
render=":detailpopup"
oncomplete="#{rich:component('detailpopup')}.show();" />
Be careful: if you have a <h:form> inside the popupPanel, you may have issues when you re-render the complete popup. Put everything in a <h:panelGroup> inside the form, then re-render that one.
I have two selectOneMenu. I need following:
On first menu change I need to populate second one and some form's fields with AJAX
On second menu change I need to populate only some form's fields wit AJAX.
Populating second menu and form's fields on step 1 is perfect and right after first menu change, but there is a problem with populating form on step 2.
Nothing happens when I change second menu's value. But when I returned second menu value to NoSelectionOption ajax listener invoked. It seems that AJAX listener ignores values that was added with AJAX.
Here's my code fragments:
JSF:
<h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="1">
<h:panelGrid columns="2">
<h:outputText value="Получатель:" />
<h:selectOneMenu value="#{paymentOrder.curContractor}">
<f:selectItem itemLabel="Выберите контрагента .." noSelectionOption="true" />
<f:selectItems value="#{paymentOrder.userContractors}" var="contr"
itemValue="#{contr.idcontractor}"
itemLabel="#{contr.pnamecontractor}"/>
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="#this"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="4">
<h:outputText value="ИНН"/>
<h:inputText id="idINNContractor" value="#{paymentOrder.chosenContractor.inncontractor}"/>
<h:outputText value="КПП"/>
<h:inputText id="idKPPContractor" value="#{paymentOrder.chosenContractor.kppcontractor}"/>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Получатель"/>
<h:inputTextarea id="idNameContractor" value="#{paymentOrder.chosenContractor.pnamecontractor}"/>
</h:panelGrid>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="2">
<h:outputText value="Счёт получателя:"/>
<h:selectOneMenu id="idContractorAccounts" value="#{paymentOrder.curContractorAccount}">
<f:selectItem itemLabel="Выберите счёт .." noSelectionOption="true" />
<f:selectItems value="#{paymentOrder.contractorAccounts}" var="acc"
itemValue="#{acc.naccountcontractor}"
itemLabel="#{acc.advName}"/>
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueAccountChanged}" render="idContrAcc, idNameContrBank, idBikContrBank, idAccContrBank" execute="#this"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Сч.№"/>
<h:inputText id="idContrAcc" value="#{paymentOrder.curContractorAccount}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="4">
<h:panelGrid columns="2">
<h:outputText value="Банк получателя"/>
<h:inputTextarea id="idNameContrBank" value="#{paymentOrder.chosenBank.namebank}" />
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="БИК"/>
<h:inputText id="idBikContrBank" value="#{paymentOrder.chosenBank.bikbank}"/>
<h:outputText value="Сч.№"/>
<h:inputText id="idAccContrBank" value="#{paymentOrder.chosenBank.bankkorshet}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
And my back bean fragment:
public class PaymentOrder {
#EJB(lookup="JpaBankBean/local")
private JpaBankBeanLocal jpaBean;
private Paymentdocument pDocument;
private Paymentorder pOrder;
private Klbankrf chosenBank;
private String curContractorAccount;
private String curContractorBank;
private String curContractor;
private String err;
private String chosenAccount;
private Contractor chosenContractor;
#SuppressWarnings("rawtypes")
private Set contractorAccounts;
#SuppressWarnings("rawtypes")
private List contractorBanks;
private String userName;
private Date nowDate;
public PaymentOrder() {
this.nowDate = Calendar.getInstance().getTime();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
setUserName(((UserDetails)principal).getUsername());
} else {
setUserName(principal.toString());
}
pDocument = new Paymentdocument();
pOrder = new Paymentorder();
chosenContractor = new Contractor();
chosenBank = new Klbankrf();
}
public void valueContractorChanged()
{
chosenContractor = jpaBean.getContractor(Integer.valueOf(getCurContractor()));
setContractorAccounts(jpaBean.getContractorAccounts(Integer.valueOf(getCurContractor())));
pDocument.setReceiver(chosenContractor.getPnamecontractor());
}
public List getUserContractors()
{
return jpaBean.getUserContractors(userName);
}
public void valueAccountChanged()
{
chosenBank.setNamebank("SBER");
//TODO chosenBank = jpaBean.getContractorBank(getCurContractorAccount());
//TODO setChosenAccount("012345678901234567890");
}
}
So, "SBER" appear in idNameContrBank field only if I change second menu value to somethig and then change back to NoSelectOption. It is strange to me.
I use RichFaces 4, JBoss AS 6.
I've found some information at this forum, but there is no solution.
How to make second menu to change something? Or is there my mistake? Any ideas?
Thanks in advance!
I've made some experiments.
When I change second menu to some value populated with AJAX, page gets response like that:
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="docForm:idContrAcc">
<![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" style=" width : 100%;" />]]>
</update>
<update id="docForm:idNameContrBank">
<![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;"></textarea>]]>
</update>
<update id="docForm:idBikContrBank">
<![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
</update>
<update id="docForm:idAccContrBank">
<![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
</update>
<update id="javax.faces.ViewState"><![CDATA[3312710224811729695:3995303008700914422]]>
</update>
</changes>
</partial-response>
There are no values, but right IDs! How it can be? Why?
But if I return NoSelectionOption active then page gets response
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="docForm:idContrAcc">
<![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" value="" style=" width : 100%;" />]]>
</update>
<update id="docForm:idNameContrBank">
<![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;">SBER</textarea>]]>
</update>
<update id="docForm:idBikContrBank">
<![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
</update>
<update id="docForm:idAccContrBank">
<![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
</update>
<update id="javax.faces.ViewState">
<![CDATA[3312710224811729695:3995303008700914422]]>
</update>
</changes>
</partial-response>
It's seems OK - values are presented! But why does it happen when NoSelectionOption is active?!
I suspect JSF might be overwriting your attempts since it usually calls all the setters for all the properties exposed on the page and it normally does this after the valueChangeListeners are executed. I've never seen the <a4j:ajax /> tag but you could try the <a4j:support /> tag. Instead of this:
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="#this"/>
Try this:
<a4j:support event="onchange" ajaxSingle="true" reRender="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts"/>
Since ajaxSingle="true" is included in the tag it means that only the setter for curContractor will be called (and not all the rest on the page like JSF normally does). Then you can call valueContractorChanged from the setter (or even just make it part of the setter).
If you replace all of the <a4j:ajax /> tags in this way you should get the desired result. Check out more info about the tag via the link above.
I'm trying to do a search form, depending on the selected item you can do searchs by start to end or month and year
Is it possible to do a form look like this, with Facelets?
using of preference SelectOneRadio
alt text http://img837.imageshack.us/img837/5357/imageoq.png
It's doable. You'd like to use <f:ajax> inside the <h:selectOneMenu> to rerender the form on change (click) of the radio buttons. You can use the #form identifier for this.
Then, in the input and select elements, you'd like to let disabled attribute depend on the radio button selection.
The most tricky part is probably to get it all laid out nicely since the h:selectOneRadio itself renders a HTML <table>. To group them nicely together, you'd like to split the content over cells of another table and apply CSS vertical-align: top to the td element containing the h:selectOneRadio.
Anyway, here's a full working example to get you started:
<h:form id="form">
<h:panelGrid columns="2">
<h:selectOneRadio id="type" value="#{bean.type}" layout="pageDirection" required="true">
<f:selectItems value="#{bean.types}" var="type" itemValue="${type}" itemLabel="" />
<f:ajax event="click" render="#form" />
</h:selectOneRadio>
<h:panelGrid columns="4">
<h:outputLabel for="inputStartDate" value="Start Date" />
<h:inputText id="inputStartDate" value="#{bean.startDate}" required="true" disabled="#{bean.type != 'INPUT'}">
<f:convertDateTime type="date" pattern="yyyy-MM-dd" />
</h:inputText>
<h:outputLabel for="inputEndDate" value="End Date" />
<h:inputText id="inputEndDate" value="#{bean.endDate}" required="true" disabled="#{bean.type != 'INPUT'}">
<f:convertDateTime type="date" pattern="yyyy-MM-dd" />
</h:inputText>
<h:outputLabel for="selectMonth" value="Select Month" />
<h:selectOneMenu id="selectMonth" value="#{bean.month}" required="true" disabled="#{bean.type != 'SELECT'}">
<f:selectItem itemLabel="Select One" />
<f:selectItems value="#{bean.months}" />
</h:selectOneMenu>
<h:outputLabel for="selectYear" value="Select Year" />
<h:selectOneMenu id="selectYear" value="#{bean.year}" required="true" disabled="#{bean.type != 'SELECT'}">
<f:selectItem itemLabel="Select One" />
<f:selectItems value="#{bean.years}" />
</h:selectOneMenu>
<h:panelGroup />
<h:panelGroup />
<h:commandButton value="Submit" action="#{bean.submit}" />
<h:panelGroup />
</h:panelGrid>
</h:panelGrid>
<h:messages />
</h:form>
Here's how the bean look like:
#ManagedBean
#ViewScoped
public class Bean {
private enum Type {
INPUT, SELECT
}
private Type type;
private Date startDate;
private Date endDate;
private Integer month;
private Integer year;
// All with getters and setters.
private List<Type> types = Arrays.asList(Type.values());
private List<SelectItem> months = new ArrayList<SelectItem>();
private List<Integer> years = new ArrayList<Integer>();
// All with just getters.
public Bean() {
String[] monthNames = new DateFormatSymbols().getMonths();
for (int i = 0; i < 12; i++) {
months.add(new SelectItem(i, monthNames[i]));
}
for (int i = 2000; i <= 2020; i++) {
years.add(i);
}
}
public void submit() {
switch (type) {
case INPUT:
System.out.printf("Start Date: %tF, End Date: %tF%n", startDate, endDate);
break;
case SELECT:
System.out.printf("Month: %s, Year: %d%n", months.get(month).getLabel(), year);
break;
}
}
// Getters and setters here.
}
Here's how you can apply CSS to get the radio buttons aligned at top:
#form td { vertical-align: top; }
Of course.
Create regular div/css table. where the radio buttons are displayed in one div like this:
facelet page:
<h:selectOneRadio id="searchPlace"
value="#{yourBean.selection}" onclick="enableSearch(this)" layout="pageDirection" border="1">
<f:selectItem itemValue="0" />
in the header part, add javascript:
function enableSearch(radio){
if (radio.id == 's1'){
document.getElementById('startDateText').disabled=false;
document.getElementById('endDateText').disabled=false;
}else{
document.getElementById('monthSelect').disabled=false;
document.getElementById('yearSelect').disabled=false;
}
}
in YourBean.java class:
Boolean selection;
public void setSelection(Boolean selection){
this.selection = selection;
}
public String getSelection(){
return this.selection;
}
public void savePage(){
....
if (selection)
..
}
and in savePage() use the selection param to decide the search type.