0

I'm trying to find the equivalent of this XHTML code:

<h:selectBooleanCheckbox value="#{sandboxBean.selected}" >
  <f:ajax listener="#{sandboxBean.handleToggle}" render="outputText" />
</h:selectBooleanCheckbox>

<br /><br />
<h:outputText value="#{sandboxBean.selected}" id="outputText"/>

for the case where the entire checkbox has to be dynamically created by the backing bean. I've managed to get some Ajax goodness with this code:

checkbox = new HtmlSelectBooleanCheckbox();
checkbox.setId(makeCheckboxId());

AjaxBehavior valueChangeAction = (AjaxBehavior)FacesContext.getCurrentInstance().getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);

valueChangeAction.addAjaxBehaviorListener(new AjaxBehaviorListener() {

  @Override
  public void processAjaxBehavior(AjaxBehaviorEvent event) throws AbortProcessingException {
    System.out.println("Ajax behavior called");     
  }
});

checkbox.addClientBehavior("valueChange", valueChangeAction);

but I can't figure out how to get the Ajax call to execute my handleToggle method, nor how to give it easy access to the outputText element that I want to render (in this cut-down example).

Also, this seems unexpectedly complicated: this all stems from a need for a table with an unknown number of columns. Am I likely just approaching this from fundamentally the wrong angle by creating the whole table in code?

Dave Mulligan
  • 1,623
  • 3
  • 19
  • 31

1 Answers1

1

but I can't figure out how to get the Ajax call to execute my handleToggle method

Your code is sensitive to some environment specific quirks. Older Mojarra implementations fail to execute a programmatically created ajax behavior listener method. Ensure that you've the latest version, or try MyFaces. Some container-specific EL implementations fail to invoke a method on an anonymous class. Ensure that you're using the latest container version, or extract it into a public class.


nor how to give it easy access to the outputText element that I want to render (in this cut-down example)

Use AjaxBehavior#setRender() method to set the render attribute.

ajaxBehavior.setRender(Collections.singletonList("outputText"));

Also, this seems unexpectedly complicated: this all stems from a need for a table with an unknown number of columns. Am I likely just approaching this from fundamentally the wrong angle by creating the whole table in code?

Yes. Just do it in the view side. You can use <c:forEach> to dynamically create <h:column> components. Or, you can grab e.g. PrimeFaces <p:columns>. See also e.g. Dynamically generate h:column based on list of hashmaps.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks. I'll give PrimeFaces a try, and also upgrade to a newer implementation. I had tried ``, but mystifyingly the complete tag was rendered into the HTML, rather than actually performing the advertised action. – Dave Mulligan Feb 06 '13 at 05:28
  • Perhaps you simply forgot or typo'ed the JSTL core taglib XML namespace? Then tags will indeed be unparsed and appear plain vanilla in the rendered HTML. The proper JSTL core taglib XML namespace is `xmlns:c="http://java.sun.com/jsp/jstl/core"`. – BalusC Feb 06 '13 at 11:02
  • I would have sworn that I had triple-checked that, but I tried it again and the is now working. Thanks – Dave Mulligan Feb 06 '13 at 23:48