Search code examples
javajsfvaluechangelistener

valueChangeListener never called


I have the following bits of code:

 <h:panelGroup rendered="#{userTypeController.permissionItemsUserType.contains(item)}">
                    <h:selectBooleanCheckbox valueChangeListener="#{userTypeController.permissionChanged(this)}" value="#{true}"/> 
                    <h:outputText value="#{item.getAction()}" />
                </h:panelGroup>
                <h:panelGroup rendered="#{!userTypeController.permissionItemsUserType.contains(item)}">
                    <h:selectBooleanCheckbox value="#{false}"/> 
                    <h:outputText value="#{item.getAction()}" />
                </h:panelGroup>

But for some reason the permissionChanged method is never called. Any ideas of what might be going wrong?

My permissionChanged method:

    public void PermissionChanged(ValueChangeEvent event) {
    System.out.println("test");
}

Solution

  • There are three problems:

    1. Your listener method call in EL is wrong. You should not pass the current component along it.

      Replace

      valueChangeListener="#{userTypeController.permissionChanged(this)}"
      

      by

      valueChangeListener="#{userTypeController.permissionChanged}"
      
    2. Your method signature in backing bean is wrong. It should conform the Java naming conventions.

      Replace

      public void PermissionChanged(ValueChangeEvent event) {
      

      by

      public void permissionChanged(ValueChangeEvent event) {
      
    3. You seem to be expecting that it fires immediately when you click the checkbox (otherwise you'd have seen an ELException). This expectation is not true. It will only be fired when you submit the form. Using onclick="submit()" is a common hack/workaround for this.

    That said, there are likely better ways for this. As the functional requirement is unclear, it is not possible to propose the right solution. I think that the <f:ajax> is what you're looking for if all you want is immediate and asynchronous feedback and re-render. Although the JSF 2.0 tag is missing from your question, based on your question history you're using JSF 2.0, so <f:ajax> should work for you.