0

I'm trying to create Primefaces UIComponents programmatically and somehow I'm not able to get the data to the Backing Bean. Not sure if it's the Ajax or the value I set for the InputText. My code that I want to write programmatically:

<p:inputText id="id_test" value="#{myBean.value}">
    <p:ajax />
</p:inputText>

This is how I tried to solve the problem:

private String value; // Getter&Setter


public void buildComponent(){
    FacesContext fc = FacesContext.getCurrentInstance();
    Application ap = fc.getApplication();

    InputText inputText = (InputText) ap.createComponent(fc, "org.primefaces.component.InputText", "org.primefaces.component.InputTextRenderer")
    inputText.setValue(value);
    inputText.setId("id_test");

    AjaxBehavior ajaxBehavior = (AjaxBehavior) ap.createBehavior(AjaxBehavior.BEHAVIOR_ID);
    inputText.addClientBehavior(inputText.getDefaultEventName(), behavior);
}
JavaFan
  • 65
  • 4
  • 1
    You have set a concrete String value to `InputText.setValue()`, but you need to provide an actual ValueExpression. – Selaron Nov 26 '18 at 12:50
  • 1
    Thanks that solved it for me. – JavaFan Nov 26 '18 at 13:05
  • 2
    So the actual problem solved here does not relate to Primefaces nor AJAX and could be reduced to a question duplicate to https://stackoverflow.com/questions/3510614/how-to-create-dynamic-jsf-form-fields – Selaron Nov 26 '18 at 13:23
  • @Selaron Yes you are right. Apologies for my ignorance! – JavaFan Nov 27 '18 at 15:05
  • Not a problem, wasn't a judgement but a conclusion only. We developers keep searching into the most complex directions even if the root cause is as simple as a typo ;-) – Selaron Nov 27 '18 at 15:29

2 Answers2

2

You will need to create a ValueExpression that resolves to your bean property. How else should your dynamic input know where to send input values to?

Instead of:

inputText.setValue(value);

Do this:

ExpressionFactory expressionFactory = FacesContext.getCurrentInstance()
  .getApplication().getExpressionFactory();
ValueExpression veBinding = expressionFactory.createValueExpression("#{myBean.value}", String.class);
inputText.setValueExpression("value", veBinding);
Selaron
  • 6,105
  • 4
  • 31
  • 39
1

I'm not sure what you intend to do, but it might be better to render the component dynamically instead of creating it. Something like that:

<p:inputText id="id_test" value="#{myBean.value}" rendered="#{myBean.isSomeCondition">
    <p:ajax />
</p:inputText>  

or

<p:inputText id="id_test" value="#{myBean.value}" rendered="#{myBean.value != 'whatever'">
    <p:ajax />
</p:inputText>  
Cleo
  • 181
  • 6
  • Thanks but the problem I'm facing is that I don't know the number or type of the input components that I need. – JavaFan Nov 26 '18 at 12:51