0

I have the next question!

I want to create inputtext dynamically from my backing bean, they would be inside of the a tabs also dynamic created which will be constructed in execution time.

I manage to add the components dynamically using the input classes corresponding.

But I have not manage to add the value tag to the component, a valueExpresion language which binds the value to the managedBean itself.

I have found some code which I can summerize like this.

  @ManagedBean
  @ViewScoped
  public MyManagedBean(){

private TabView tabsi;
    HtmlOutputLabel hol = new HtmlOutputLabel();
        InputText txt2 = new InputText();
private String value;

/* getter and setters */

    public void MyManagedBean{
    tabsi = new TabView();
            Tab tab1 = new Tab();
            tab1.setTitle("Tab1");
            Tab tab2 = new Tab();
            tab2.setTitle("Tab2");
            tabsi.getChildren().add(tab1);
            tabsi.getChildren().add(tab2);

            hol.setValue("label");
            hol.setStyleClass("label");
            txt2.setValueExpression("value",
                    TestController.getExpression("#{myManagedBean.value}"));
            txt2.setValue(value);
            tab1.getChildren().add(hol);
            tab1.getChildren().add(txt2);
    }

    public static ValueExpression getExpression(String expression) {
            FacesContext fc = FacesContext.getCurrentInstance();
            ELContext ctx = fc.getELContext();
            ExpressionFactory factory = fc.getApplication().getExpressionFactory();
            return factory.createValueExpression(ctx, expression, Object.class);
        }

public void test1() {
        System.out.println(value);
    }
    }

I successfully manage to build the components but I can not bind it to set the ValueExpression. When I call the test1 function from a button it print null

How can I bind the value to the ManagedBean???

Rob
  • 4,927
  • 12
  • 49
  • 54
  • you call the TestController.getExpression("#{myManagedBean.value}")); in the constructor of MyManagedBean. you can't get any thing from something that is under construction. it will always return null. – faissal Mar 11 '13 at 22:22
  • In the constructor I stablish the value that would be bind! So really it is not called until I fire the actionListener, in my case a button which I press. – David Agustin Almanza Gaitan Mar 11 '13 at 23:05

1 Answers1

0

I can't pinpoint the exact cause with the information provided so far, but there are at least three severe problems with this approach:

  1. An UIComponent instance is in essence request scoped. You should never ever declare it as a property of a bean in a broader scope, or you will face infamous "Duplicate component ID" errors when the very same instance is been referenced in multiple views.

  2. Using binding attribute referring a view scoped bean property breaks the view scope completely. The bean is recreated every request. This problem has essentially the same grounds as explained in detail here: JSTL in JSF2 Facelets... makes sense?

  3. A programmatically created UIInput and UICommand component must have a fixed id set via setId(), otherwise JSF won't be able to find it in the request parameter map during apply request values phase of the form submit and inherently not be able to process the submitted value and the action method respectively.

The third problem is most likely the exact cause of your current problem, but the first and the second problem may have had some influence.

Regardless of this, try to reconsider your decision to programmatically create components this way. This should be avoided as much as possible. E.g. why don't you just use rendered attribute, or view build time tags like JSTL <c:if>?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks, the third option was the winning one. Yes you are right I need to consider the scopes in which such elements are loaded, I think am gonna look more info about creating components in build time!! – David Agustin Almanza Gaitan Mar 15 '13 at 16:11