a4j:commandButton actionListener Facelets composition
fotakis May 13, 2011 2:10 PMHello all,
I am struggling to get my head around JSF 2 the lifecycle, the new default view handler Facelets and of course RichFaces 4 . I did do a project about 2 years ago with the same stack, but other versions.
My biggest issue with all of this, is that when you read over the docummentation and how things are "supposed" to work, just don't, you are thrown entirelly out of your learning curve. Well this is what is going on with me right now.
I am attempting to abstract the well know rich:modalPanel in to a custom xhtml source Facelet taglib.
My Modal Panel - modalPanel.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:c="http://java.sun.com/jstl/core" > <ui:composition> <rich:popupPanel id="modalPanel_#{id}" modal="true" autosized="false" minWidth="#{width}" > <!----> <a4j:outputPanel> <h:form id="modalPanel_#{id}_form"> <ui:insert /> <a4j:commandButton value="Cancel" immediate="true" actionListener="#{item[cancelAction]}"> <rich:componentControl target="modalPanel_#{id}" event="onclick" operation="hide" /> </a4j:commandButton> <a4j:commandButton value="Save" actionListener="#{item[saveAction]}" oncomplete="Existanze.modalPanel.doclose(#{empty facesContext.maximumSeverity},'#{id}')" render="#{rerender}" /> <script type="text/javascript"> //do all the logic here under our namespace if (typeof Existanze == 'undefined') var Existanze= {}; if (!Existanze.modalPanel) Existanze.modalPanel= {}; Existanze.modalPanel.doclose = function(valid, id) { var modalId = 'modalPanel_'+id; if(valid){ /* https://issues.jboss.org/browse/RF-10221 */ RichFaces.$(modalId).hide(); } }; </script> </h:form> </a4j:outputPanel> </rich:popupPanel> </ui:composition> </html>
The problem I am facing is with the aj4:commandButton actionListener method. This is giving a PropertyNotFoundException for the 'item' identifier, which makes me realize that the #{item} parameter is not being properly set.
I include the above template into a simple view like so.
<ui:composition template="/WEB-INF/facelets/layout.xhtml" 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" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xmlns:ex="http://www.existanze.com/jsf"> <ui:define name="title">this is a complete facelets page</ui:define> <ui:define name="header"> </ui:define> <ui:define name="body"> <h1> <h:form> Bus Services <a4j:commandButton image="/static/images/ui/add.png" onclick="#{rich:component('modalPanel_addService')}.show()" > </a4j:commandButton> </h:form> </h1> <ex:modalPanel id="addService" item="#{serviceServicesBean}" cancelAction="resetBean" saveAction="addBean" width="200" rerender="detailsTablePanel" > <h:inputText id="serviceName" value="#{serviceServicesBean.simpleBean.message}" label="Service Name"/> <rich:message for="serviceName" ajaxRendered="true"/> </ex:modalPanel> </ui:define> </ui:composition>
The serviceServicesBean is a ViewScope bean, and it is very simple.
@Component @Scope("view") public class ServiceServicesBean implements Serializable{ private Logger logger = LoggerFactory.getLogger(ServiceServicesBean.class); SimpleBean simpleBean; @Autowired ServicesService servicesService; @PostConstruct public void initBean(){ logger.debug("Initializing ServiceServicesbean"); simpleBean = new SimpleBean(); } public SimpleBean getSimpleBean() { return simpleBean; } //this is now an action public void addBean(){ logger.debug("Action called"); try{ List<Service> failed = servicesService.addServices(Service.generate(null, simpleBean.getMessage())); simpleBean=new SimpleBean(); //if it is successfull we should let the session bean know }catch (DataIntegrityViolationException e){ FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Duplicate Value", "This is a duplication value"); FacesContext.getCurrentInstance().addMessage("modalPanel_addService_form:serviceName", fm); } } public void resetBean(){ logger.debug("Resetting Bean"); simpleBean = new SimpleBean(); } }
I have read over every possible forum link, and jira bugs, which had the exact same problem and the ones bellow seem to be the most relevant, by I still have problems with this:
https://issues.jboss.org/browse/RF-10781
http://community.jboss.org/thread/164032?tstart=0
Note that if I call #{item[cancelAction]} in action instead of actionListener, the action in the bean is called.
Please I am about to pull my hair out, any insight will be much appreciated.
Best Regards,
Fotis