In addition to what has been suggested earlier on this thread, there's
one additional thing you might want to do if you go the "customized
renderer" route for any of your changes -- tell the JSF runtime to use
*your* renderer instead of the standard one for the standard JSP tag. 
(I haven't tried this with MyFaces yet, but it works with the RI and
is designed in to the JSF APIs).

At runtime, JSF component tags look up the appropriate renderer in the
Application object, based on a combination of the values returned by
getComponentFamily() and getRendererType() on the component instance. 
So, in your own faces-config.xml, you can replace the registration for
the standard renderer for, say, the <h:outputLabel> tag, with an entry
like this:

    <renderer>
        ...
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.Label</renderer-type>
        
<renderer-class>com.mycompany.mypackage.MyOutputLabelRenderer</renderer-class>
        ...
    </renderer>

The canonical identifiers you need are all defined in the JSF spec --
for component families, see the relevant component descriptions in
Chapter 4.  For standard renderer types, see Section 8.6.

Craig McClanahan


On Wed, 1 Dec 2004 21:42:27 -0700, David Geary <[EMAIL PROTECTED]> wrote:
> Le Dec 1, 2004, � 9:18 PM, Matt Raible a �crit :
> 
> 
> 
> > On Dec 1, 2004, at 8:40 PM, David Geary wrote:
> >
> >> Le Dec 1, 2004, � 7:33 PM, Matt Raible a �crit :
> >>
> >>> Hello all,
> >>>
> >>> I've been doing a bit of MyFaces development this week and enjoying
> >>> it for the most part.
> >>
> >> Glad to hear it Matt! 8-)
> >>
> >>>  I have a couple questions about <h:outputLabel>:
> >>>
> >>> 1. Is there anyway to modify h:outputLabel to add an asterisk for
> >>> required fields?
> >>
> >> You can do that without modifying h:outputLabel, for example:
> >>
> >>    <h:loadBundle basename="messages" var="msgs"/>
> >>    ...
> >>    <h:outputLabel for="name" value="#{msgs.requiredNamePrompt}"/>
> >>
> >> In your resource bundle:
> >>
> >>    requiredNamePrompt=*Name
> >>
> >> Of course with that solution you're assuming the required state of
> >> the field in the view. That's probably better left to business logic,
> >> so you could do this instead:
> >>
> >>    <h:outputLabel for="name" value="#{backingBean.namePrompt}"/>
> >>
> >> And BackingBean.getNamePrompt() would return the proper localized
> >> string, with an asterik if the property is required, and without an
> >> asterik otherwise.
> >>
> >> Or, you could do this:
> >>
> >> <h:panelGroup>
> >>      <h:outputText value="*" rendered="#{backingBean.nameRequired}"/>
> >>      <h:outputLabel value="#{msgs.namePrompt}"/>
> >> </h:panelGroup>
> >>
> >> And have backingBean implement a boolean method named isNameRequired
> >> that returns the required status of the property in question. The
> >> h:outputText will only render if its rendered attribute is true.
> >
> > Hmmm, sounds like I have to have a getter method for each form field
> > on my managed bean?  What a pain?
> >  Isn't there a way to look up if the field is required and just add a
> > * - a solution that's generic for all outputLabel's?  I'm willing to
> > hack source code or create components if I need to - I just need to
> > know 2 things:
> >
> > 1.  Yes/No - if I have to hack the source to make the dynamic lookup
> > possible?
> 
> No hacking is required.
> 
> > 2.  Where do I hack the source? I'm guessing there's some way to
> > lookup the validation metadata for the inputs and use that data in the
> > labels.
> 
> You could implementing a replacement for the Label renderer:
> 
> 1. In a renderer method such as encodeBegin(), get the value of the
> renderer's component (encodeBegin is passed the component. Call the
> component's getValue method). In this case, the component is the label
> and the value is the id of the labeled component.
> 
> 2. Get a reference to the labeled component. In a JSF component
> hierarchy, any component can find any other component in the hierarchy
> with the findComponent(String) method, where the String is the
> component's id. So the label can find the labeled component.
> 
> 3. Find out if the labeled component is required. Input components
> implement the editableValueHolder interface, which defines an
> isRequired method.
> 
> 4. Render according to whether the labeled component is required.
> 
> 
> david
> 
> 
> 
> >
> > Thanks,
> >
> > Matt
> >
> >>
> >>> Do I have to subclass the existing JSP Tag to do this?
> >>
> >> You hardly ever want to subclass an existing component tag, because
> >> tags are really just thin veneers for component/renderer pairs. You
> >> could, however, implement your own Label renderer and plug it into
> >> h:outputLabel. But I would opt for one of the easier solutions above.
> >>
> >>> 2. Is it possible to auto-add a colon?  I'm able to do this pretty
> >>> easily with a custom taglib and Commons Validator, but it seems
> >>> difficult with MyFaces?  With Tapestry, I can subclass the existing
> >>> component and add my own suffix (including a space before the colon
> >>> for the French locale).
> >>
> >> The same techniques for prepending an asterik will work for appending
> >> a colon. Again, you could implement your own Label renderer that does
> >> anything you want.
> >>
> >>
> >> david
> >>>
> >>> Thanks,
> >>>
> >>> Matt
> >>>
> >>
> >
> 
>

Reply via email to