dev@jsftemplating.java.net

Re: JSFTemplating: Aggregating JSF components into a JSFT component

From: Jaco Prinsloo <jacolists_at_gmail.com>
Date: Tue, 24 Jun 2008 20:39:17 +0200

On Tue, Jun 24, 2008 at 7:00 PM, Ken Paulsen <Ken.Paulsen_at_sun.com> wrote:

>
>
> 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}" />
> </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.
>

Wow, thanks Ken.
Sounds like it will do exactly what I need - will test it tomorrow.
Thanks for taking the time and implementing the feature. Once I get a better
feel of the source code I might stop bothering you and do it myself ;)


>
> 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
>

After rereading my question I can see that it was somewhat ambiguous,
however, you still managed to answer it with your second example.
Thanks!


>
>
> Thank you,
> Jaco
>
>