How to update component with ajax when selecting a p:selectOneRadio? - ajax

I'm trying to use ajax to update a component in my jsf page when selecting a radio button.
The managed bean is the following:
#SessionScoped
#ManagedBean
public class TestMB {
ArrayList<String> domande;
String[] risposte = new String[3];
public TestMB() {
domande = new ArrayList<String>();
domande.add("Domanda1");
domande.add("Domanda2");
domande.add("Domanda3");
}
public ArrayList<String> getDomande() {
return domande;
}
public void setDomande(ArrayList<String> domande) {
this.domande = domande;
}
public String[] getRisposte() {
return risposte;
}
public void setRisposte(String[] risposte) {
this.risposte = risposte;
}
public void asserta() {
System.out.println(risposte[0]);
}
}
The JSF page is this one:
<h:form id="label">
<p:panelGrid columns="1" layout="grid" styleClass="showcase-text-align-center">
<p:repeat var="domanda" value="#{testMB.domande}" varStatus="status">
<h1>#{domanda}</h1>
<p:selectOneRadio value="#{testMB.risposte[status.index]}">
<f:selectItem itemLabel="1" itemValue="1"></f:selectItem>
<f:selectItem itemLabel="2" itemValue="2"></f:selectItem>
<f:selectItem itemLabel="3" itemValue="3"></f:selectItem>
</p:selectOneRadio>
</p:repeat>
</p:panelGrid>
<p:outputLabel value="#{testMB.risposte[0]}"></p:outputLabel>
<p:commandButton update="label" value="Si" />
</h:form>>
I would like to update the form when I change option in the tag.
If I press the commandButton everything is ok but how to implement the same behavior in the radio button selection?
Thanks in advance!

You have the <p:ajax> component. Try something like this:
<p:selectOneRadio value="#{testMB.risposte[status.index]}">
<f:selectItem itemLabel="1" itemValue="1"></f:selectItem>
<f:selectItem itemLabel="2" itemValue="2"></f:selectItem>
<f:selectItem itemLabel="3" itemValue="3"></f:selectItem>
<p:ajax update="label" />
</p:selectOneRadio>

Related

primefaces cascade selectonemenu

I have 3 dropdowns, the second has to be loaded based on the selected option of the first. And the third based on the selected option of the second.
This is the page:
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="Empresa:" for="selectCompany" />
<p:selectOneMenu id="selectCompany" value="#{dropdownBean.company}"
converter="entityConverter" effect="fade" effectSpeed="200"
var="company">
<p:ajax process="#this" event="change"
update="selectBranch, selectVendor" />
<f:selectItems value="#{dropdownBean.companies}" var="companyItem"
itemLabel="#{companyItem.corporateName}" itemValue="#{companyItem}" />
<p:column>
<h:outputText value="#{company.corporateName}" />
</p:column>
</p:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="Surcursal:" for="#selectBranch" />
<p:selectOneMenu id="#selectBranch" value="#{dropdownBean.branch}"
converter="entityConverter" effect="fade" effectSpeed="200"
var="branch">
<p:ajax process="#this" event="change" update="#selectVendor" />
<f:selectItem itemLabel="SELECCIONE SUCURSAL" itemValue=""
noSelectionOption="true" />
<f:selectItems value="#{dropdownBean.branches}" var="branchItem"
itemLabel="#{branchItem.branchName}" itemValue="#{branchItem}" />
<p:column>
<h:outputText value="#{branch.branchName}" />
</p:column>
</p:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="Vendedor: " for="#selectVendor" />
<p:selectOneMenu id="#selectVendor" value="#{dropdownBean.vendor}"
converter="entityConverter" effect="fade" effectSpeed="200"
var="vendor">
<f:selectItem itemLabel="SELECCIONE VENDEDOR" itemValue=""
noSelectionOption="true" />
<f:selectItems value="#{dropdownBean.vendors}" var="vendorItem"
itemLabel="#{vendorItem.vendorName}" itemValue="#{vendorItem}" />
<p:column>
<h:outputText value="#{vendor.vendorName}" />
</p:column>
</p:selectOneMenu>
</h:panelGrid>
And the backbean:
#ManagedBean
public class DropdownBean {
#Inject
private CompanyBC companyBC;
#Inject
private BranchBC branchBC;
#Inject
private VendorBC vendorBC;
private V_Companies company;
private V_Branches branch;
private V_Vendors vendor;
private List<V_Companies> companies;
private List<V_Branches> branches;
private List<V_Vendors> vendors;
#PostConstruct
public void allCompanies() {
companies = companyBC.allCompanies();
}
public List<V_Companies> getCompanies() {
return companies;
}
public void setCompanies(List<V_Companies> companies) {
this.companies = companies;
}
public List<V_Branches> getBranches() {
if(company!=null)
branches = branchBC.allCompanyBranches(company.getCompanyId());
return branches;
}
public void setBranches(List<V_Branches> branches) {
this.branches = branches;
}
public List<V_Vendors> getVendors() {
if(company!=null && branch!=null)
vendors = vendorBC.allBranchVendors(company.getCompanyId(), branch.getBranchId());
return vendors;
}
public void setVendors(List<V_Vendors> vendors) {
this.vendors = vendors;
}
public V_Companies getCompany() {
return company;
}
public void setCompany(V_Companies company) {
this.company = company;
}
public V_Branches getBranch() {
return branch;
}
public void setBranch(V_Branches branch) {
this.branch = branch;
}
public V_Vendors getVendor() {
return vendor;
}
public void setVendor(V_Vendors vendor) {
this.vendor = vendor;
}
}
The first two dropdowns work great but the last one does not. Apparently cannot be more than one p:ajax for the same event or something like that. Any suggestions please?
adding a listener worked:
<p:ajax process="#this" listener="#{userEditMB.onBranchChange}" event="change" update="selectVendor" />
public void onBranchChange(AjaxBehaviorEvent event) {
setBranch((V_Branches) ((UIOutput) event.getSource()).getValue());
vendors = vendorBC.allBranchVendors(getBranch().getCompanyId(),
getBranch().getBranchId());
}
I tried listener before but passing the Id's as parameters. Passing AjaxBehaviorEvent and casting to the object was the answer for me. I hope helps someone
Thanks!

Ajax in JSF with selectManyCheckbox

I have a datatable and two checkboxes. The content of the datatable is rendered considering which of the checkboxes are selected. I have the following functional code which renders the datable content when pressing the submit button:
<h:form>
<h:selectManyCheckbox value="#{myBean.selections}">
<f:selectItem itemValue="expired" itemLabel="Expired" />
<f:selectItem itemValue="active" itemLabel="Active" />
</h:selectManyCheckbox>
<h:commandButton id="submit" value="Select"
action="#{myBean.getList}" />
</h:form>
<h:form>
<h:dataTable ... />
</h:form>
However, I want to replace the submit button with an ajax call using the f:ajax tag. I tried something like:
<h:selectManyCheckbox value="#{myBean.selections}">
<f:selectItem itemValue="expired" itemLabel="Expired" />
<f:selectItem itemValue="active" itemLabel="Active" />
<f:ajax event="click" render="#form" listener="#{myBean.getList}" />
</h:selectManyCheckbox>
<h:form>
<h:dataTable .... />
</h:form>
But the content is not rendered. What am I doing wrong?
Bean:
public String[] selections = { "expired", "active" };
public String[] getSelections() {
return selections;
}
public void setSelections(String[] selections) {
this.selections = selections;
}
public void getList() {
for (String option : selections) {
// add expired
if (option.equals("expired"))
showExpired();
// add active
else if (option.equals("active"))
showActive();
}
//return Arrays.toString(selections);
}

JSF page does not retrieve values from back bean

I'm doing a dynamic view according to a dropdown selection:
there's the code:
<h:selectOneMenu value="#{controller.type}" >
<p:ajax listener="#{controller.switchPanels}" update="panels" />
<f:selectItem itemValue="1" itemLabel="option 1" />
<f:selectItem itemValue="2" itemLabel="option 2" />
</h:selectOneMenu>
<h:panelGroup layout="block" id="panels">
<h:panelGroup layout="block" rendered="#{controller.type == '1'}" >
<h:inputText value="#{controller.value}" >
<f:validateRegex pattern="^[0-9a-zA-Z ]*$" />
</h:inputText>
</h:panelGroup>
<h:panelGroup layout="block" rendered="#{controller.type == '2'}" >
Panel 2
</h:panelGroup>
</h:panelGroup>
<h:commandLink action="#{controller.go}">Go</h:commandLink>
The controller:
#ViewScoped
#ManagedBean
public class Controller {
String type = "1";
String value;
// getters and setters
public void switchPanels(AjaxBehaviorEvent event) {
this.value = "";
}
public void go(){
}
...
}
Try this scenario:
- write special characters in the value field
- press Go (causes the validation message to popup)
- try changing the selection and reselect the same panel again
The result is that the field is not cleared even though I clear it in the switchPanels method
Please any explanation would be helpful
Thank you

AjaxBehaviorEvent primefaces3.2

My problem is that the following code returns null but if I look when debuging source then submittedValue has the correct date.
Java:
public void changeOneMenuP(AjaxBehaviorEvent event) {
String id = (String) event.getComponent().getAttributes().get("value");
if(id != null) {
listEntity = escDao.findByxxxx(id, true);
}
}
XHTML:
<h:selectOneMenu id="idSelect" immediate="true" style="width:120px" value="#EntityBB.idUni}" label="#{bundleComunes.unidad}">
<f:selectItem itemLabel="#{bundleComunes.seleccionar}..." itemValue="" />
<f:selectItems value="#{configuracionBB.listEntity}" var="lUni" itemValue="#lUni.id}" itemLabel="#{lUni.desc}" />
<p:ajax event="change" update="sisArm" listener="#{entityBB.changeOneMenuP}" />
</h:selectOneMenu>
Any Idea????
better don't mix primefaces p:ajax with Pure JSF
try using f:ajax
<f:ajax event="change" render="sisArm" listener="#{entityBB.changeOneMenuP}" />
Also , you better access your id like this
public void changeOneMenuP(AjaxBehaviorEvent event) {
listEntity = escDao.findByxxxx(getidUni(), true);//or just idUni
}

3 cascading dropdown menus with Ajax

I want to modify the example "ajaxify select" in PrimeFaces showcase application and introduce a third p:selectOneMenu with chooses depending on selection of second p:selectOneMenu.
Here is the modified code :
<h:form>
<p:growl id="msgs" showDetail="true"/>
<p:panel header="Double Combo" style="margin-bottom:10px;">
<h:panelGrid columns="3" cellpadding="5">
<p:selectOneMenu id="city" value="#{pprBean.city}">
<f:selectItem itemLabel="Select City" itemValue="" />
<f:selectItems value="#{pprBean.cities}" />
<p:ajax update="suburbs"
listener="#{pprBean.handleCityChange}" />
</p:selectOneMenu>
<p:selectOneMenu id="suburbs" value="#{pprBean.suburb}">
<f:selectItem itemLabel="Select Suburb" itemValue="" />
<f:selectItems value="#{pprBean.suburbs}" />
<p:ajax update="subsuburbs"
listener="#{pprBean.handleSuburbChange}" />
</p:selectOneMenu>
<p:selectOneMenu id="subsuburbs" value="#{pprBean.subsuburb}">
<f:selectItem itemLabel="Select Subsuburb" itemValue="" />
<f:selectItems value="#{pprBean.subsuburbs}" />
</p:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit" update="msgs"
actionListener="#{pprBean.displayLocation}"/>
</p:panel>
</h:form>
But the listener function #{pprBean.handleSuburbChange} is never executed. I saw in another forum that the dynamic code in ajax response don't include tag other that tag indicated in update attribute, but how can I do then?
In PPRBean code I added:
#Named("pprBean")
#RequestScoped
public class PPRBean implements Serializable {
// ...
public void handleSuburbChange() {
if (suburb != null && !suburb.equals("")) {
subsuburbs = subsuburbsData.get(suburb);
} else {
subsuburbs = new HashMap<String, String>();
}
log.info("subsuburbs:" + subsuburbs);
}
// ...
The listener won't be invoked if the selected item cannot be processed. You've put the bean in the request scope which means that it's garbaged when the response associated with the request is finished (i.e. when the browser is finished loading the page). So, when you submit the form, a new request will be fired and a brand new bean is created which in your case apparently doesn't prepare/prefill the list of suburbs in the (post)constructor in order to find the selected item (and execute the listener).
To fix this, you'd normally need to put the bean in the view scope by the JSF #ViewScoped annotation along with #ManagedBean.
#ManagedBean
#ViewScoped
public class Bean {
// ...
}
This way the bean instance will live as long as you're interacting with the same view. But as you're using CDI to manage the beans instead of JSF, you'd need to use #ConversationScoped instead and control the Conversation yourself.
#Named
#ConversationScoped
public class Bean {
#Inject
private Conversation conversation;
#PostConstruct
public void init() {
conversation.begin();
// ...
}
public void submit() {
// ...
conversation.end();
}
}

Resources