How to set JSF composite component attribute to ManagedBean property?
Asked Answered
A

2

5

So I made a composite component FileAdder.xhtml

<composite:interface>
    <composite:attribute name="type" value="#{editoriCompositeController.typeString}"/>
</composite:interface>

<composite:implementation>
    <h:form>
        <p:editor id="editor" widgetVar="editorWidget" value="some text" width="600" />
    </h:form>
</composite:implementation>

And then I have the EditoriCompositeController ManagedBean:

@ViewScoped
@ManagedBean
public class EditoriCompositeController {

    String typeString;

    public void setTypeString(String typeStringParameter) {
        this.typeString = typeStringParameter;
    }

    public String getTypeString() {
        return typeString;
    }

}

And then in my fileattachmentsview.xhtml I use the component:

    <owncomponents:fileadder type="MEMO" />

But that is not setting the typeString value in the backing bean as "MEMO". It remains as null I tested it with a button that prints the value.

How can I make the backing bean get the value for typeString I set to the composite component's type-attribute as "MEMO"? Why it's null and not "MEMO"?

Allen answered 20/5, 2016 at 12:25 Comment(1)
I want to make a reusable editor-component, where there's a "type" attribute for the component, because the application has editors in multiple places and each of them are supposed to persist different types of documents to the database. I'd like it to be so, that as soon as the component is rendered the backing bean would get the value of the "type" attribute of the composite component as the value of it's typeString property for persisting purposes later as the user submits the contents of the editor. The composite also has boolean attributes which determine whether to render certain buttonsAllen
D
7

You have to pass the target bean/model as another composite attribute. Then you can inside the composite use <c:set> to set a property on it.

<cc:interface>
    <cc:attribute name="bean" type="com.example.Bean" />
    <cc:attribute name="type" type="java.lang.String" />
</cc:interface>
<cc:implementation>
    <c:set target="#{cc.attrs.bean}" property="type" value="#{cc.attrs.type}" />
    <p:editor value="#{cc.attrs.bean.text}" />
</cc:implementation>    

Usage:

public class Bean {

    private String text;
    private String type; // I suggest to make it an enum.

    // ...
}
<h:form>
    <your:composite bean="#{bean}" type="MEMO" />
    <p:commandButton action="#{bean.submit}" />
</h:form>

Note that I factored the form outside the composite. Having a form inside a composite is poor practice.

See also:

Devotion answered 27/5, 2016 at 7:33 Comment(1)
That's a better solution and a detailed, great answer. Thanks for the link too. I'm new with JSF and went too confidently with the composite component while not yet knowing what I was doing :)Allen
A
1

I solved it by manually getting the "type" attribute from the component in the backing bean by:

String typeString = (String) component.getAttributes().get("type");
Allen answered 27/5, 2016 at 6:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.