Jaco Prinsloo wrote:
> Hi All,
>
> I have a few more questions regarding JSFTemplating, but perhaps I
> should first give an example of what I'm trying to do. I want to
> create a reusable component which consists of other JSF components.
> For this purpose I need a JSFT component which will have a tag which
> looks something like this:
>
> <my:component name="Company" selectedValue="#{mybean.selectedValue}"
> tableValues="#{mybean.tableValues}" />
>
> The template for the component should look something like this
> (irrelevant parts left out):
>
> <ui:composition ...>
> <h:panelGrid>
> <h:outputText value="Selected #{name}" />
> <h:inputText value="#{selectedValue}" />
> <h:dataTable value="#{tableValues}" var="row">
> <h:column>
> <h:outputText value="#{row.name <http://row.name>}" />
> </h:column>
> </h:dataTable>
> </h:panelGrid>
> </ui:composition>
>
> I want the values which I provided to my custom component as
> attributes to be forwarded to the template, taking into considerationg
> value bindings. Now, I've managed to get the static text value of the
> 'name' attribute to display with the following code, but it doesn't
> work for value expressions:
>
> <ui:event type="beforeEncode">
> if ($property{name}) {
> setAttribute(key="name" value="$property{name}");
> }
> </ui:event>
You don't need the if () {} here, you can simply set the properties.
The "if" shouldn't hurt, though. Doing this sets a request attribute
named "name" with the value of the property "name".
>
> What do I need to do in order for my template to use the value
> expressions, so that it will also correctly update the bindings (if
> for example the user types something into the h:inputText component,
> that value should be passed on to mybean.selectedValue)?
You could get access to the property using $property{name,true} (NOTE:
"true" causes it to not only search the nearest containing UIComponent,
but also all its parents until a value is found) from your h:inputText,
however, that gives you an evaluated value of the "name" property (this
is because $property{...} is equivalent to calling
component.getAttributes().get("name")). In order to preserve the
ValueExpression, you need to call component.getValueExpression("name")
and use that (if it exists).
This feature was not supported. So I added this new feature. To use
it, you must get a new jsftemplating jar file (nightly build will build
in about 8 hours from now, or you can build it yourself), and then use
this syntax:
<h:inputText value="$copyProperty{selectedValue,true}" />
The $copyProperty{...} will look for "selectedValue" as a
ValueExpression first, if not found it will look for it as an
attribute/property. When "true" is supplied (as shown above), it will
keep searching parent components until "selectedValue" is found.
I hope this meets your needs.
> Also, if I want to associate some default behaviour with this
> component, can I use handlers for that? In this specific case I'd like
> to replace the h:outputText in the table with a h:outputLink which,
> upon being clicked, will update the h:inputText with the value
> selected. Usually I'd do this by binding to a bean's method, but I'd
> like to keep it in the JSFT component to avoid redundency.
For behavior, yes, handlers will accommodate this. For avoiding
displaying a component (i.e. "replace the h:outputText..."), this can be
done with the rendered="true|false" flag, or an <if> component. Here
are a couple examples (since I'm not sure exactly what you're trying to do):
<h:commandButton value="Click Me" action="$copyProperty{myAction,true}">
<!command
if (!$property{myAction}) {
doDefaultBehavior(...);
}
/>
</h:commandButton>
Or:
<h:outputText rendered="#{!$hasProperty{myAction}}" />
<h:commandLink rendered="$hasProperty{myAction}">
<!command
doDefaultBehavior(...);
/>
</h:commandLink>
I hope this helps!
Ken
>
> Thank you,
> Jaco