Ajax keyup event doesn't work after render - ajax

I have problem with JSF and Ajax. I used Ajax keyup event to filter selectOneListbox. It's working fine if I render all on start. When I hide panel with this component and render it when I select appropriate option in selectOneRadio, keyup event doesn't work.
JSF code:
<h:form id="form">
Client type: <h:selectOneRadio id="client_type" value="#{testBean.clientType}" styleClass="radio">
<f:selectItem itemValue="N" itemLabel="New client" />
<f:selectItem itemValue="E" itemLabel="Existing client" />
<f:ajax event="change" execute="#this" render="clientPanel" />
</h:selectOneRadio>
<br /><br />
<h:panelGroup id="clientPanel">
<h:panelGroup id="existedClient" rendered="#{testBean.clientType eq 'E'}">
<p style="font-weight: bold;">Existed client</p>
Search: <h:inputText id="in" value="#{testBean.clientSearchPattern}" autocomplete="off">
<f:ajax event="keyup" listener="#{testBean.clientChanged}" render="client_select" />
</h:inputText>
Client: <h:selectOneListbox id="client_select" value="#{testBean.complaint.client.id}" required="true"
style="width: 200px; font-family: 'Ubuntu'; font-size: 14.6667px; font-style: normal;">
<f:selectItems value="#{testBean.clients}" var="client"
itemLabel="#{client.name} #{client.surname}" itemValue="#{client.id}" />
</h:selectOneListbox>
</h:panelGroup>
<br /><br />
<h:panelGroup id="newClient" rendered="#{testBean.clientType eq 'N'}">
<p style="font-weight: bold;">New client</p>
Name: <h:inputText id="name" value="#{testBean.clientSearchPattern}" />
</h:panelGroup>
</h:panelGroup>
</h:form>
Java code:
#Named
#RequestScoped
public class TestBean {
#Inject
private ClientService clientService;
private String clientType = "N";
private String clientSearchPattern;
private List<Client> clients;
private Complaint complaint = new Complaint();
#PostConstruct
public void init() {
clients = clientService.list();
}
public void clientChanged() {
clients = clientService.search(clientSearchPattern);
}
public String getClientSearchPattern() {
return clientSearchPattern;
}
public void setClientSearchPattern(String clientSearchPattern) {
this.clientSearchPattern = clientSearchPattern;
}
public List<Client> getClients() {
return clients;
}
public Complaint getComplaint() {
return complaint;
}
public void setComplaint(Complaint complaint) {
this.complaint = complaint;
}
public String getClientType() {
return clientType;
}
public void setClientType(String clientType) {
this.clientType = clientType;
}
}
Thanks in advance!

Related

Modal edit dialog on Primefaces with JSF

I'm trying to create some CRUD JSF application with edit/new screen implemented as a modal dialog. The problem is that I can't find a way how to make new and edit operation done by this dialog performed with ajax. With delete all was very simple (just ajax="true" option).
Here is a code of button which is used to show the dialog
<h:form id="dataForm">
<div class="ui-g">
<div class="ui-g-12 ui-md-9">
<p:dataGrid var="product" value="#{products.productList}" columns="3" layout="grid"
rows="12" paginator="true" id="products"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="6,12,16">
<f:event type="preRenderView" listener="#{products.preloadProductList}" />
<f:facet name="header">
Products
</f:facet>
<p:panel header="#{product.name}" style="text-align:center">
<h:panelGrid columns="1" style="width:100%">
<h:outputText value="#{product.name}"/>
<h:outputText value="#{product.price}"/>
<%-- Here new/edit dialog window is opened --%>
<p:commandLink update=":dataForm:productDetail" oncomplete="PF('productDialog').show()">
Edit
<f:setPropertyActionListener value="#{product}" target="#{products.product}"/>
</p:commandLink>
<p:commandLink update=":dataForm" action="#{products.deleteAction(product)}" ajax="true">
Delete
</p:commandLink>
</h:panelGrid>
</p:panel>
</p:dataGrid>
<ui:include src="WEB-INF/dialogs/edit_product.xhtml"/>
</div>
</div>
</h:form>
Here is dialog window which is moved to separete file edit_product.xhtml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<p:dialog header="Product Info" widgetVar="productDialog" modal="true" showEffect="fade"
hideEffect="fade"
resizable="false">
<p:outputPanel id="productDetail" style="text-align:center;">
<p:panelGrid columns="2" rendered="#{not empty products.product}"
columnClasses="label,value">
<h:outputText value="Id:"/>
<h:outputText value="#{products.id}"/>
<h:outputText value="Name"/>
<h:inputText value="#{products.name}"/>
<h:outputText value="Price"/>
<h:inputText value="#{products.price}"/>
</p:panelGrid>
<h:commandButton value="Save" action="#{products.saveProduct}"/>
</p:outputPanel>
</p:dialog>
</ui:composition>
Here is Managed bean which is used by the Product dataGrid and dialog window.
#ManagedBean(name = "products")
#SessionScoped
public class ProductsBean {
private static final Logger logger = LoggerFactory.getLogger(ProductsBean.class);
#Inject
private ProductRepository productRepository;
private Product product;
private Collection<Product> productList;
public void preloadProductList(ComponentSystemEvent event) throws AbortProcessingException {
productList = productRepository.getAll();
}
public String getId() {
return String.valueOf(product.getId());
}
public void setId(String id) {
product.setId(Long.valueOf(id));
}
public String getName() {
return product.getName();
}
public void setName(String name) {
product.setName(name);
}
public int getPrice() {
return product.getPrice();
}
public void setPrice(int price) {
product.setPrice(price);
}
public Product getProduct() {
return this.product;
}
public void setProduct(Product product) {
this.product = product;
}
public Collection<Product> getProductList() {
logger.info("Get product list");
return productList;
}
public void newProductAction() {
this.product = new Product();
}
public void deleteAction(Product product) {
logger.info("Delete product");
productRepository.remove(product);
}
public void saveProduct() {
productRepository.merge(product);
}
}
No matter if I add ajax option or not the whole window is reloaded after Save button is pressed. Could you show me the right direction for the implementation, please?
P.S. If you need more code to answer you can find it here:
Main page with Product table https://github.com/usharik/GeekBrainsJavaEE/blob/master/lesson5-jpa/src/main/webapp/index.xhtml
Edit/New dialog https://github.com/usharik/GeekBrainsJavaEE/blob/master/lesson5-jpa/src/main/webapp/WEB-INF/dialogs/edit_product.xhtml

Implement callback method in JSF composite component

I'd like to implement a "callback" feature in my composite component. This method would be called from the backing component when necessary.
The XHTML part is:
<cc:interface componentType="partnerSelComp">
<cc:attribute name="value" type="com.app.data.Partner"/>
<cc:attribute name="callback" method-signature="void notify(java.lang.Long)"/>
</cc:interface>
<cc:implementation>
<span id="#{cc.clientId}">
<p:inputText id="code" binding="#{cc.partnerCode}">
<p:ajax event="blur" update="code name msg" listener="#{cc.validate}" />
</p:inputText>
<p:outputLabel id ="name" binding="#{cc.partnerName}"/>
<p:message id="msg" for="code"/>
</span>
</cc:implementation>
The relevant part of backing component is:
#FacesComponent("partnerSelComp")
public class PartnerSelComp extends UIInput implements NamingContainer {
private InputText partnerCode;
private OutputLabel partnerName;
#Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
public void validate() {
...
MethodExpression exp = (MethodExpression) getAttributes().get("callback");
...
}
...
}
Above the exp gets null value. How can I get the callback attribute, and how can I execute it?
A solution (Java 1.8) to call a function with no args.
Component:
<composite:interface>
<composite:attribute name="buttonCallback" type="java.util.function.Consumer"/>
</composite:interface>
<composite:implementation>
<p:commandButton value="Submit" action="#{cc.attrs.buttonCallback.accept(null)}"/>
<composite:implementation>
Usage in view:
<mycomp:myCC buttonCallback="#{myBackingBean.myCallback}"/>
Usage in backing bean:
private Consumer<Void> myCallback;
#PostConstruct
public void init() {
myCallback= this::myFunction;
}
public void myFunction(Void v) { //... }

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!

capture selected text from inputTextArea primefaces jsf

I want to capture selected text from inputTextArea on ajax dblclick or select event.How can I do this ?
The code below selects everything in the text area (which I don't want). Thank you very much.
<h:form id="form">
<p:panel header="Select Text">
<h:panelGrid columns="3" cellpadding="5">
<h:outputText value="Text: " />
<p:inputTextarea id="textarea"
value="#{selectedTextBean.selectedText}">
<p:ajax event="select" update="selectedText" />
</p:inputTextarea>
<h:outputText id="selectedText"
value="#{selectedTextBean.selectedText}" />
</h:panelGrid>
</p:panel>
</h:form>
Here is SelectedTextBean
#ManagedBean
#ViewScoped
public class SelectedTextBean {
public SelectedTextBean() {
}
private String selectedText;
public String getSelectedText() {
return selectedText;
}
public void setSelectedText(String selectedText) {
this.selectedText = selectedText;
}
}
You can use this plugin jquery-textrange.
xhtml
<p:inputTextarea onselect="setSelectedText()" />
<p:remoteCommand name="setSelectedTextCommand"
actionListener="#{mainBean.setSelectedText()}"
update="currentSelectedText" />
Selected Text is:
<h:outputText value="#{mainBean.selectedTextInArea}"
id="currentSelectedText" />
<h:outputScript library="js" name="jquery-textrange.js" />
<script>
function setSelectedText() {
var range = $('.ui-inputtextarea').textrange();// general selector
setSelectedTextCommand([{name: 'selectedText', value: range.text}]);
}
</script>
Bean
private String selectedTextInArea;
public void setSelectedText() {
FacesContext context = FacesContext.getCurrentInstance();
Map map = context.getExternalContext().getRequestParameterMap();
selectedTextInArea = (String) map.get("selectedText");
}
public String getSelectedTextInArea() {
return selectedTextInArea;
}
public void setSelectedTextInArea(String selectedTextInArea) {
this.selectedTextInArea = selectedTextInArea;
}
And Here's a live demo on Primefaces TextArea Selection, and on github.
You can do that sending a parameter to a remote command as follows:
The View
<h:form id="form">
<p:panel header="Select Text">
<h:panelGrid columns="3" cellpadding="5">
<h:outputText value="Text: " />
<h:panelGroup>
<p:inputTextarea id="textarea"
value="#{selectedTextBean.selectedText}" onselect="processSelection();" />
<p:remoteCommand name="sendSelection" actionListener="#{selectedTextBean.onSelect}" update="selectedText" process="#this" />
</h:panelGroup>
<h:outputText id="selectedText"
value="#{selectedTextBean.selectedText}" />
</h:panelGrid>
</p:panel>
</h:form>
<script>
function processSelection() {
var selectedText = (!!document.getSelection) ? document.getSelection() :
(!!window.getSelection) ? window.getSelection() :
document.selection.createRange().text;
sendSelection([{name: 'selectedText', value: selectedText}]);
}
</script>
Note that the text selection changes depending on the browser.
The Bean
import java.io.Serializable;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
#ManagedBean
#ViewScoped
public class SelectedTextBean implements Serializable {
public SelectedTextBean() {
}
private String selectedText;
public void onSelect() {
FacesContext context = FacesContext.getCurrentInstance();
Map map = context.getExternalContext().getRequestParameterMap();
selectedText = (String) map.get("selectedText");
}
public String getSelectedText() {
return selectedText;
}
public void setSelectedText(String selectedText) {
this.selectedText = selectedText;
}
}

Two ajax updates with h:selectOneMenu f:ajax

In short, if a component has been updated by Ajax, it can not launch new events Ajax
I have three h:selectOneMenu: A, B and C.
When I fire change event in A, then update the B h:selectOneMenu.
When I fire change event in B, then update the C h:selectOneMenu.
The problem is that when the content of B h:selectOneMenu is updated, the ajax in B don't work and C never can't be updated.
<h:selectOneMenu id="A" value="#{paqueteBean.mes}" label="a">
<f:selectItem itemLabel="Seleccione..." itemValue="" />
<f:selectItem itemLabel="Enero" itemValue="ENERO" />
<f:selectItem itemLabel="Febrero" itemValue="FEBRERO" />
<f:ajax listener="#{paqueteBean.changeMes}" render="B" />
</h:selectOneMenu>
<h:selectOneMenu id="B" value="#{paqueteBean.origen}" label="b">
<f:selectItem itemLabel="Seleccione..." itemValue="" />
<f:selectItems value="#{paqueteBean.origenes}" />
<f:ajax listener="#{paqueteBean.changeOrigen}" render="C"/>
</h:selectOneMenu>
<h:selectOneMenu id="C" value="#{paqueteBean.zona}" label="c">
<f:selectItem itemLabel="Seleccione..." itemValue="" />
<f:selectItems value="#{paqueteBean.zonas}" />
</h:selectOneMenu>
The ajax response is good, but simply don't work after the update:
<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1"><changes><update id="B"><![CDATA[<select id="B" name="b" size="1" onchange="mojarra.ab(this,event,'valueChange','#this','C')"> <option value="">Seleccione...</option>
<option value="BUE">Ezeiza o Aeroparque</option>
</select>]]></update><update id="j_id1:javax.faces.ViewState:0"><![CDATA[-2984590031183218074:6198891110668113457]]></update></changes></partial-response>
UPDATE!
With PrimeFaces I have the same behavior:
<h:form id="filtro">
<p:selectOneMenu id="A" value="#{paqueteBean.mes}">
<f:selectItem itemLabel="Seleccione..." itemValue="" />
<f:selectItem itemLabel="Enero" itemValue="ENERO" />
<f:selectItem itemLabel="Febrero" itemValue="FEBRERO" />
<f:selectItem itemLabel="Marzo" itemValue="MARZO" />
<p:ajax listener="#{paqueteBean.changeMes}" update="B" />
</p:selectOneMenu>
<p:selectOneMenu id="B" value="#{paqueteBean.origen}"
disabled="#{empty paqueteBean.mes}">
<f:selectItem itemLabel="Seleccione..." itemValue="" />
<f:selectItems value="#{paqueteBean.origenes}" />
<p:ajax listener="#{paqueteBean.changeOrigen}" update="C"
process="origen mesSalida" />
</p:selectOneMenu>
<p:selectOneMenu id="C" value="#{paqueteBean.zona}"
disabled="#{empty paqueteBean.mes or empty paqueteBean.origen}">
<f:selectItem itemLabel="Seleccione..." itemValue="" />
<f:selectItems value="#{paqueteBean.zonas}" />
</p:selectOneMenu>
When I change some A values, the method in backing bean is fired, but when I change some B value, the method in backing bean is not fired.
The most strange is that for items that existed in B before the ajax update, the backing bean is called.
Backing Bean, nothing special:
public void changeMes(){
logger.debug("en changeMes el Mes es: " + this.mes);
this.origenes = new HashMap<String, String>();
this.origenes.put("Ezeiza o Aeroparque", "BUE");
}
public void changeOrigen(){
logger.debug("Mes: " + this.mes);
logger.debug("Origen" + this.origen);
this.zonas = new HashMap<String, String>();
this.zonas.put("Argentina", "AR");
this.zonas.put("Brasil", "BR");
}
public void changeZona(){
logger.debug("Mes: " + this.mes);
logger.debug("Origen" + this.origen);
logger.debug("Zona" + this.zona);
this.destinos = new HashMap<>();
this.destinos.put("Mar del Plata", "MDQ");
this.destinos.put("Punta Lara", "LTA");
}
UPDATE:
here is a working example:
Bean:
import java.util.ArrayList;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.model.SelectItem;
#ManagedBean(name="myBean")
#SessionScoped
public class MyBean {
private boolean bDisabled;
private boolean cDisabled;
private String selectedA;
private String selectedB;
private String selectedC;
private ArrayList<SelectItem> aItems;
private ArrayList<SelectItem> bItems;
private ArrayList<SelectItem> cItems;
public MyBean() {
}
#PostConstruct
public void init(){
try{
this.bDisabled = new Boolean(true);
this.cDisabled = new Boolean(true);
this.aItems = new ArrayList<SelectItem>();
this.bItems = new ArrayList<SelectItem>();
this.cItems = new ArrayList<SelectItem>();
this.aItems.add(new SelectItem("NONE", "---?"));
this.aItems.add(new SelectItem("A1", "A 1"));
this.aItems.add(new SelectItem("A1", "A 1"));
this.aItems.add(new SelectItem("A1", "A 1"));
this.bItems.add(new SelectItem("NONE", "---?"));
this.cItems.add(new SelectItem("NONE", "---?"));
}catch(Exception e){
e.printStackTrace();
}
}
public final void selectA(final AjaxBehaviorEvent event){
try{
System.out.println(this.selectedA);
this.bItems.clear();
this.bItems.add(new SelectItem("NONE", "---?"));
if(this.selectedA.equals("NONE") ){
this.setbDisabled(true);
return;
}
this.bItems.add(new SelectItem("B1","B 1"));
this.setbDisabled(false);
}catch(Exception ex){
ex.printStackTrace();
}
}
public final void selectB(final AjaxBehaviorEvent event){
try{
System.out.println(this.selectedB);
this.cItems.clear();
this.cItems.add(new SelectItem("NONE", "---?"));
if(this.selectedB.equals("NONE") ){
this.setcDisabled(true);
return;
}
this.cItems.add(new SelectItem("C1","C 1"));
this.setcDisabled(false);
}catch(Exception ex){
ex.printStackTrace();
}
}
public final void selectC(final AjaxBehaviorEvent event){
try{
System.out.println(this.selectedC);
}catch(Exception ex){
ex.printStackTrace();
}
}
public String getSelectedA() {
return selectedA;
}
public void setSelectedA(String selectedA) {
this.selectedA = selectedA;
}
public String getSelectedB() {
return selectedB;
}
public void setSelectedB(String selectedB) {
this.selectedB = selectedB;
}
public String getSelectedC() {
return selectedC;
}
public void setSelectedC(String selectedC) {
this.selectedC = selectedC;
}
public ArrayList<SelectItem> getaItems() {
return aItems;
}
public void setaItems(ArrayList<SelectItem> aItems) {
this.aItems = aItems;
}
public ArrayList<SelectItem> getbItems() {
return bItems;
}
public void setbItems(ArrayList<SelectItem> bItems) {
this.bItems = bItems;
}
public ArrayList<SelectItem> getcItems() {
return cItems;
}
public void setcItems(ArrayList<SelectItem> cItems) {
this.cItems = cItems;
}
public boolean isbDisabled() {
return bDisabled;
}
public void setbDisabled(boolean bDisabled) {
this.bDisabled = bDisabled;
}
public boolean iscDisabled() {
return cDisabled;
}
public void setcDisabled(boolean cDisabled) {
this.cDisabled = cDisabled;
}
}
XHTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:head>
<meta charset="UTF-8" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Test</title>
</h:head>
<body>
<f:view>
<h:form id="dataForm">
<h:selectOneMenu value="#{myBean.selectedA}" style="width: 100%;">
<f:selectItems value="#{myBean.aItems}" />
<f:ajax execute="#form" render="#form" listener="#{myBean.selectA}" />
</h:selectOneMenu>
<h:selectOneMenu disabled="#{myBean.bDisabled}" value="#{myBean.selectedB}" style="width: 100%;">
<f:selectItems value="#{myBean.bItems}" />
<f:ajax execute="#form" render="#form" listener="#{myBean.selectB}" />
</h:selectOneMenu>
<h:selectOneMenu disabled="#{myBean.cDisabled}" value="#{myBean.selectedC}" style="width: 100%;">
<f:selectItems value="#{myBean.cItems}" />
<f:ajax execute="#form" render="#form" listener="#{myBean.selectC}" />
</h:selectOneMenu>
</h:form>
</f:view>
</body>
</html>
Instead of using <f:ajax/> you can also use the PrimeFaces-Ajax-Element <p:ajax> which offers you a update-attribute:
<p:ajax update="elementID"/>
Another possibility I can recommend: Have you tried to put your SelectOneMenus in a <h:form>-Element? It looks like you didn't use a form. Do so, then you can always update the form in order to make the menues change. Worked good for me at my projects.
I had the same mistake.
For the second selectonemenu i miss a setter.
In your code it was the setter for myBean.selectedB.
Check all your getter and setter. Maybe there is the problem

Resources