4

I have created a custom component. I add a dynamic input text box to it (from the encode function).

The component is correctly is rendered as HTML.

But I want to bind the value of the text box to some property on the Managed Bean. So some other developer can use the component on his jsp with his managed bean.

I want to know, what should I do, so that the value entered in the text box (which my component dynamically creates) is set to the some Managed bean property.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Apurv
  • 3,723
  • 3
  • 30
  • 51

2 Answers2

4

You need to ensure that your custom component class extends UIInput and that you're in the encodeEnd() method of your renderer writing the component's client ID as name attribute of the HTML input element. Then you can in the overriden decode() method of your renderer just grab the submitted value from the request parameter map with the component's client ID as parameter name and set it as UIInput#setSubmittedValue() and let JSF do the remnant of the job of converting, validating and updating the model value.

@Override
public void decode(FacesContext context, UIComponent component) {
    // Do if necessary first validation on disabled="true" or readonly="true", if any.

    // Then just get the submitted value by client ID as name.
    String clientId = component.getClientId(context);
    String submittedValue = context.getExternalContext().getRequestParameterMap().get(clientId);
    ((UIInput) component).setSubmittedValue(submittedValue);
}

Unrelated to the concrete problem, are you aware of the new composite component support in JSP's successor Facelets? I have the impression that you don't necessarily need a custom component for this purpose. Or are you really restricted to using the legacy JSP as view technology in spite of that you're already on JSF 2.x? See also When to use <ui:include>, tag files, composite components and/or custom components?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks a lot, but I have written the above code. I even checked the 'submittedValue' variable of the above code and it is the one entered by the user. But still it is no reaching the Managed Bean. Can you please help me with the code required in encode method to bind the dynamic control with some Managed bean property ? The user provides some 'selectedValue' attribute value of the custom component as selectedValue = "#{TestBean.testProperty}". Now the value input by the user in the dynamic textbox should be set to 'testPoperty'. – Apurv Sep 24 '11 at 15:48
2

Well, the problem is solved.

In the encodeEnd() method I added the element as

HtmlInputHidden hidden = new HtmlInputHidden();
hidden.setParent(this);
hidden.setId("someId");
ValueExpression ve = getValueExpression("value");
hidden.setValueExpression("value", ve);
hidden.encodeBegin(context);
hidden.encodeEnd(context);

This seems to have some problem.

Then I changed this to ...

HtmlInputHidden hidden = new HtmlInputHidden();
hidden.setId("someId");
ValueExpression ve = getValueExpression("value");
hidden.setValueExpression("value", ve);
this.getChildren().add(hidden);
hidden.encodeBegin(context);
hidden.encodeEnd(context);

The use of this.getChildren().add(); solved my problem

P.S. Obviously before adding the element, it needs to be checked if the element is already present.

Apurv
  • 3,723
  • 3
  • 30
  • 51