1

I have a dynamically generated Datatable, like this

    DataTable dataTable = new DataTable();
    dataTable.setValue(relatorioVOList);
    dataTable.setVar("rVO");

    Column checkBoxColumn = new Column();
    checkBoxColumn.getChildren().add(this.viewComponentBuilder.createExpressionTextWithLink("#{rVO.iRelatorio}","#{rVO.nNome}"));
    dataTable.getColumns().add(checkBoxColumn);


public HtmlForm createExpressionTextWithLink(String iRelatorioExpressionValue, String valueExpressionValue) {
    HtmlForm form = new HtmlForm();
    HtmlCommandLink link = new HtmlCommandLink();

    //config
    FacesContext context = FacesContext.getCurrentInstance(); 
    Application application = context.getApplication();
    ExpressionFactory ef = application.getExpressionFactory();
    ELContext elc = context.getELContext();

    //value that is the reports name
    ValueExpression nameValueExp = ef.createValueExpression(elc, valueExpressionValue, Object.class);
    link.setValueExpression("value", nameValueExp);

    //action that goes to method teste when link is clicked
    MethodExpression methodExpression = createMethodExpression("#{componenteC.teste(rVO.iRelatorio)}", String.class, Integer.class);
    link.setActionExpression(methodExpression);

    form.getChildren().add(link);
    return form;
}

private static MethodExpression createMethodExpression(String expression, Class<?> returnType, Class<?>... parameterTypes) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    return facesContext.getApplication().getExpressionFactory().createMethodExpression(
            facesContext.getELContext(), expression, returnType, parameterTypes);
}

In ComponenteC, a RequestScopedBean, the teste function

public String teste(Integer iRelatorio) {
    System.out.println("cheguei");
    return "componente";
}

The goal is that the teste function will generate an url according to the iRelatorio parameter. The issue here is that the function is never called. I tried replacing the rVO.iRelatorio with an explicit 10, "#{componenteC.teste(10)}" and even then the action seems to not be fired. The report name is displayed correctly.

Rita
  • 1,233
  • 2
  • 14
  • 23
  • This seems unusual to me. Normally we would look at your backing bean and facelets page to debug this issue, but since you're programmatically generating the form, something I have have never seen used, I'm not sure how to help. I suggest either reconsidering your approach and generate the table on the Facelets page, or spend more time writing a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) so that someone has a better chance of helping you. – DavidS Apr 09 '15 at 16:59

1 Answers1

8

Dynamically created UIInput, UICommand and UINamingContainer components must have a fixed id assigned. Otherwise it will get an autogenerated one which is not necessarily the same when the view is restored. The component ID is used in request parameter names in submitted form data, which JSF would then use to collect the submitted input values and identify the invoked commands during apply request values phase. If the component ID changes, then JSF won't be able to perform the apply request values phase as intented.

Thus, act accordingly:

dataTable.setId("tableId");
// ...
form.setId("formId");
// ...
link.setId("linkId");

There are other potential causes, but they are not visible in the information provided so far in the question. To cover that, take your time to carefully read the following related answers on "dynamically" creating components/views:

That said, you're really better off using XHTML to declare and create components instead of all that Java code mess. XHTML(+XML) is much more declarative and readable and therefore better understandable and maintainable. JSTL may be very helpful in this all.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I've tried adding IDs to all the components and it still fails. Unfortunately, this has to be JAVA-coded since it's a requisite. Thank you. – Rita Apr 09 '15 at 20:07
  • Then go through the given links. Doublecheck the way and the moment you're populating the component tree. The last link of the list contains concrete examples. Otherwise you've to update the question to include a true MCVE. – BalusC Apr 09 '15 at 20:08
  • The last link contained the solution! Instead of binding I used and now the function is called! Thank you very much! :) – Rita Apr 09 '15 at 21:04