Adding dynamic drop down components in JSF - jsf

My requirement is like this. I have a selectMenu with some values (Examples: Engineering, Medicine, Law etc..,) . Suppose if I select Engineering in the drop down, I want another dropdown menu created dynamically which has values related to Engineering (Example: Electronics, Computers, Electricals etc..,). How do I achieve this in JSF 2.0 ?

You need to perform an ajax request when first h:selectOneMenu's selection change. This request will update the selectable items in the second h:selectOneMenu. After the ajax request, you must render the second h:selectOneMenu again, with the updated values.
Page:
<h:selectOneMenu value="#{bean.selectedSubject}">
<f:ajax listener="#{bean.changeSubject}" render="speciality_selection" />
<f:selectItems value="#{bean.subject}" />
</h:selectOneMenu>
<h:selectOneMenu id="speciality_selection" value="#{bean.selectedSpeciality}">
<f:selectItems value="#{bean.subjectSpecialities}" />
</h:selectOneMenu>
Managed bean:
public void changeSubject(){
//Loads the specialities depending on the selected subject
subjectSpecialities = loadSpecialitiesForSubject(selectedSubject);
}

Related

Can't render SelectManyCheckbox from my SelectOneMenu with an ValueChangeListener

I have a Map (Integer, List) which I want to fill from a JSF page. I'm only using JSF, no Primefaces or such.
On my JSF page there is a selectOneMenu that displays each keys of my Map, and a selectManyBox to choose the values for each key.
I want to be able to save each state before submitting the whole Map.
See my bean:
#ManagedBean(name="myBean")
#SessionScoped
public class MyBean implements Serializable {
(...)
public void refresh(ValueChangeEvent e)
{
if (idRole==-1){ //to check if its just the first selection
setKey((int)e.getNewValue());
}
else{
myObject.getMap().put(key,listOfValuesSelected); //put current manycheckbox values in last selected key
setKey((int)e.getNewValue()); //get new key
listOfValuesSelected=MyObject.getMap().get(Key); //refresh the
//selectManyCheckbox for the newly selected key
}
}
My JSF Page
<h:selectOneMenu id="idRole" value="#{myBean.key}" onchange="submit()" valueChangeListener="#{myBean.refresh}" render="checkbox"> >
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{myBean.listKeys}" />
</h:selectOneMenu>
<fieldset id="checkbox">
<h:selectManyCheckbox value="#{myBean.listOfValuesSelected}">
<f:selectItems value="#{myBean.listeOfValues}" var="n"
itemLabel="#{n.title}" itemValue="#{n.key}"/>
</h:selectManyCheckbox>
</fieldset>
My real code is kind of a mess, I rearranged it a bit to fit the needs of my question but I can give you the real code if needed.
My problem is that the selectmanycheckbox doesn't "react" at all. I see that the listOfValuesSelected is modified when I am in debug mode.
Do you use AJAX somewhere? And what kind of form do you use?
With "doesn't react", do you mean it's not re-rendered, or that nothing happens when you select one or more items in it?
If you use AJAX then with the given code the select many checkbox will indeed not re-render (refresh). The reason is that SelectOneMenu doesn't have an attribute "render" that causes something to be re-rendered. Third party components often have such a thing, but the standard components only do that via an f:ajax tag. Also, you can't use a non-component ID as a re-render target. Fieldset is not a component.
See http://docs.oracle.com/javaee/6/tutorial/doc/gkabr.html on how to use f:ajax

Submitted values on a view scoped bean do not appear in POST-navigated page

I have a simple form.
<h:form>
<h:selectOneMenu value="#{user.siteID}" >
<f:selectItems id="vals" value="#{user.basinSiteIDs}" />
<f:ajax event="valueChange" listener="#{user.updateWithAjax(e)}"
render="all" />
</h:selectOneMenu>
<h:selectManyCheckbox id="all" value="#{user.siteIDs}" layout="pageDirection">
<f:selectItems id="sites" value="#{user.csrpSites}" />
</h:selectManyCheckbox>
<h:commandButton value="submit" action="result"/>
</h:form>
The page initially loads with a drop down and check boxes with associated values. When I make a selection from the drop down, the check box values are changed dynamically with ajax. I need to click submit button and display the user selected values in result page.
Here is the problem:
If I use #RequestScoped, clicking the submit button gives j_idt7:all: Validation Error: Value is not valid.
#ViewScoped, takes to result page but with empty/null values.
#SessionScoped, shows result page with correct values but they are gone when I click browser's back button and land in the index page. This happens only under IE and Chrome but not in Firefox.
The #ViewScoped is the right scope for the purpose of having a dependent dropdownlist which is populated by ajax. Your concrete problem is caused by binding one same view scoped bean to 2 physically different views for some reason. A view scoped bean lives as long as the view itself. If you change the view, then you'll get a new view scoped bean. If you had shown the results in the same view, then it would have worked just fine.
If you really need to keep this odd approach of 2 physically different views, then your best bet is to split the bean in two:
<h:selectOneMenu id="basin" value="#{user.basinSiteID}" >
<f:selectItems value="#{data.basinSiteIDs}" />
<f:ajax listener="#{data.loadCsrpSiteIDs}" render="csrp" />
</h:selectOneMenu>
<h:selectManyCheckbox id="csrp" value="#{user.csrpSiteID}" layout="pageDirection">
<f:selectItems value="#{data.csrpSiteIDs}" />
</h:selectManyCheckbox>
<h:commandButton value="submit" action="result"/>
(note that I did some improvements here, your initial code was somewhat dirty and particularly the attempt to pass ajax behavior event is completely wrong, it would arrive as null)
The #{user} is here request scoped and #{data} is view scoped.
See also:
How to choose the right bean scope?

Can we create textbox right next to selectonemenu component when we fire selectoneMenu valueChangeListener event

want to create textbox on the fly is it possible?
Select Report to run:
<h:selectOneMenu value="#{reportBean.selectReport}">
<f:selectItems value = "#{reportBean.allReports}" />
<f:ajax listener="#{reportBean.getReqID}" render="reqID"> </f:ajax>
</h:selectOneMenu>
Seems like you want to show/hide the <h:inputText> based on the selected value on your <h:selectOneMenu>. Yes, this can be easily achieved with plain JSF.
Note that if you use set the rendered attribute as false the component won't appear in the component tree, so there will be no way it can't be referenced for any call (not even ajax calls). In order to update it, you should wrap the component inside another component like <h:panelGroup> and render the wrapper. Basic example:
<h:form id="frmRep">
<h:selectOneMenu value="#{reportBean.selectReport}">
<f:selectItems value = "#{reportBean.allReports}" />
<!--
assuming your reportBean.getReqID method will change the value of
reportBean.showReqID attribute to render/not render it and works well
-->
<f:ajax listener="#{reportBean.getReqID}" render="pnlRepName" />
</h:selectOneMenu>
<h:panelGroup id="pnlRepName">
<h:inputText id="reqID" rendered="#{reportBean.showReqID}"
value="#{reportBean.reportName}" />
<h:panelGroup>
</h:form>
For this specific requirement instead, I won't recommend using an ajax call since it has to go to the server to only check if the component should or should not be showed to the user. I would opt for a JavaScript solution to handle this just on client side.

JSF select menu problem

I am developing a jsf,richfaces application.where i want to populate the values of second select menu on the basis of selecting the choice from the first one .How i can achieve this.
<h:outputText id="section1" value="Section" />
<h:selectOneMenu id="section2" value="#{content.sectionName}" >
<f:selectItems value="#{content.sections}" />
</h:selectOneMenu>
what exactly i want is:
I have two tables one for category and one for section.
If a user choose a category from drop down menu then the other drop down menu for section should have the values only for selected category.
Please he
As per your question history you're using Ajax4jsf/RichFaces. Better use <a4j:support> instead of valueChangeListener.
<h:selectOneMenu id="section2" value="#{content.sectionName}" >
<f:selectItems value="#{content.sections}" />
<a4j:support event="onchange" action="#{content.changeSection}" reRender="otherMenuId" />
</h:selectOneMenu>
In the changeSection() method you need to populate the select items for the 2nd menu. The otherMenuId must refer to id of the other <h:selectOneMenu> in the same <a4j:region>.
You have to define a valueChangeListener for your first selectOneMenu:
<h:selectOneMenu id="select1" valueChangeListener="#{myBean.updateSections}">
<f:selectItems value="#{myBean.sections1}" />
</h:selectOneMenu>
Inside MyBean#updateSections you have to modify the list of SelectItems the second selectOneMenu has to show according to the selection you made.
Furthermore you have to submit your form or rerender section2 to display the updated values in section2.

JSF - Populating a drop down depending on value in other drop down

I need to populate a drop down based on the selected value in another drop down. I can use AJAX requests to do that but I am searching for a solution using JSF only. The values to populate the drop down need to come from a table every time user changes his selection.
Thanks
You didn't specify the version, so I'll assume JSF 1.2. The <a4j:support> tag is part of RichFaces:
<h:selectOneMenu id="firstDropDown" value="#{bean.firstDropDownSelection}">
<f:selectItems value="#{bean.items}" />
<a4j:support event="onchange" reRender="secondDropDown"
immediate="true" action="#{bean.fetchItems2}" />
</h:selectOneMenu>
<h:selectOneMenu id="secondDropDown" value="#{bean.secondDropDownSelection}">
<f:selectItems value="#{bean.items2}" />
</h:selectOneMenu>
And in the method bean.fetchItems2 you load your collection items2 with the appropriate items.
What happens, is when the value of the first drop down changes, the second drop down is rerendered and its value is fetched from the server again.

Resources