1
votes

I'm trying to create a composite component which allows a user to toggle between a selectOneMenu and selectManyListbox. I want the toggle to be bindable to a boolean value and the selectOneMenu/selectManyListbox bindable to a list of objects in the view-scoped backing bean of the page.

I'm able to create a composite component that can read the variables easily enough. I just get the attributes within the bound @FacesComponent object via getAttributes().

How do I go about making those variables writable though?

For example, say I have the following view scoped bean:

AssetSearch.java

@ManagedBean(name = "AssetSearch")
@ViewScoped
public class AssetSearch {

    private boolean toggle;
    private List<Asset> selectedList;

}

And I want to manipulate those variables with a composite component:

index.xhtml

<my:specialList toggle="#{AssetSearch.toggle}"
                selected="#{AssetSearch.selectedList}"/>

How can I manipulate these 2 variables within my composite component backing bean?:

specialList.xhtml

<cc:interface componentType="specialList">
    <cc:attribute name="toggle" type="java.langBoolean" required="true"/>
    <cc:attribute name="selected" type="java.util.List" required="true"/>
</cc:interface/>
<cc:implementation>
    <h:selectBooleanCheckbox value=#{#cc.attrs.toggle}/>
    <h:selectOneMenu rendered="#{cc.attrs.toggle}" 
                     value="#{cc.attrs.selected}">
       ...
    <h:selectManyListbox rendered=#{! cc.attrs.toggle}"
                         value="#{cc.attrs.selected}">
       ...
</cc:implementation>

SpecialList.java

@FacesComponent(value = "specialList")
public class SpecialList extends UIInput {

    ...

}

As I said, its pretty easy to get these variables with getAttributes() but I'm really not sure how to manipulate them. I did read through:

http://balusc.blogspot.com/2013/01/composite-component-with-multiple-input.html

I could probably use getSubmitedValue/getConvertedValue to manage the selectedList but I have a bunch of other variables I need to manipulate as well.

1
Depends on the concrete functional requirement which isn't clear from the question.BalusC
@BalusC Sorry. I added a detailed explanation of what I'm trying to do @ the top of the post.wsaxton
Apart from the toggle (which you should store in view scope as answered in your previous question), you don't need additional logic to update the model values. Or are you facing a problem? That composite doesn't necessarily need to be an instance of UIInput, too.BalusC
Well, for example, in order to read the "toggle" attribute in the @FacesComponent object, I use: (Boolean) getAttributes().get("toggle"). How do I write to it though?wsaxton
In the ajax listener method? Just use put(). It's just a java.util.Map.BalusC

1 Answers

1
votes

As I said, its pretty easy to get these variables with getAttributes() but I'm really not sure how to manipulate them.

From the UIComponent#getAttributes() javadoc (emphasis mine):

Return a mutable Map representing the attributes (and properties, see below) associated wth this UIComponent, keyed by attribute name (which must be a String).

It's thus mutable. You can use the usual Map#put() method on it. Provided that you want to toggle a java.lang.Boolean attribute named "toggle", here's an example:

getAttributes().put("toggle", getAttributes().get("toggle") != Boolean.TRUE);