Hello Mike,

On Mon, 2006-12-11 at 15:37 -0500, Mike Kienenberger wrote:
> I think you made the facelets tag handler harder that necessary.  Not
> sure about the "void.class" syntax below, but you can probably figure
> out the correct syntax.
Thanx a lot, this is a great simplification! (and the void.class is
correct :))
I wrote the tag handler according to what I've seen in the facelets
sources, knew (read) nothing about MethodRule :)

Thanx again,
cheers,
Martin


> 
> 
> private static final String ACTION_LISTENER_ATT_NAME =
> "toggleDetailActionListener";
> 
>     public final static Class[] ACTION_LISTENER_SIG = new Class[] {
> ActionEvent.class };
>     protected final static MethodRule actionListenerTagRule
>       = new MethodRule(ACTION_LISTENER_ATT_NAME, void.class,
> ACTION_LISTENER_SIG);
> 
> public CustomHtmlDataTableHandler(ComponentConfig config) {
>         super( config );
>     }
> 
>     protected MetaRuleset createMetaRuleset(Class type)
>     {
>         MetaRuleset m = super.createMetaRuleset(type);
> 
>         m.addRule(actionListenerTagRule);
> 
>         return m;
>     }
> 
> On 12/11/06, Martin Grotzke <[EMAIL PROTECTED]> wrote:
> > On Mon, 2006-12-11 at 20:37 +0100, Martin Grotzke wrote:
> > > On Mon, 2006-12-11 at 09:44 -0700, Andrew Robinson wrote:
> > > > "When myBean.myModel.myOptions is invoked the first time, I do some
> > > > lazy
> > > > initialization, this might cause errors..."
> > > >
> > > > I would recommend that you load this data in the on load method of
> > > > your page. This way, if it fails, you can handle the error in any way
> > > > you want, including redirecting to an error page.
> > > I cannot do this, because I have to initialize the detailStamps of
> > > all rows separately: the details of one item cause several backend
> > > requests that might cost money, and they definitively need time
> > > to return (several seconds per request).
> > >
> > > Now I wrote a CustomHtmlDataTable (extending HtmlDataTable) that
> > > provides an additional MethodBinding "toggleDetailActionListener".
> >
> > Btw, I just posted the complete example here:
> > http://www.javakaffee.de/blog/2006/12/11/how-to-add-a-new-attribute-to-an-existing-jsf-component-using-facelets/
> >
> > Perhaps it's useful for someone...
> >
> > Cheers,
> > Martin
> >
> >
> > >
> > >
> > > The toggleDetail method is extended so that it invokes also the method
> > > binding if it's provided.
> > >
> > > The hardest thing was to write the facelets MetaTagHandler that sets
> > > the attribute on the CustomHtmlDataTable:
> > >
> > > public final class CustomHtmlDataTableHandler extends ComponentHandler {
> > >
> > >     public CustomHtmlDataTableHandler(ComponentConfig config) {
> > >         super( config );
> > >     }
> > >
> > >     protected MetaRuleset createMetaRuleset(Class type) {
> > >         return super.createMetaRuleset(type).addRule( 
> > > ActionSourceRule.Instance );
> > >     }
> > >
> > >     static final class ActionSourceRule extends MetaRule {
> > >
> > >         private static final String ACTION_LISTENER_ATT_NAME = 
> > > "toggleDetailActionListener";
> > >
> > >         public final static Class[] ACTION_LISTENER_SIG = new Class[] { 
> > > ActionEvent.class };
> > >
> > >         final static class ActionListenerMapper extends Metadata {
> > >
> > >             private final TagAttribute attr;
> > >
> > >             public ActionListenerMapper(TagAttribute attr) {
> > >                 this.attr = attr;
> > >             }
> > >
> > >             public void applyMetadata(FaceletContext ctx, Object 
> > > instance) {
> > >                 ((CustomHtmlDataTable) instance)
> > >                         .setToggleDetailActionListener( new 
> > > LegacyMethodBinding(this.attr
> > >                                 .getMethodExpression(ctx, null,
> > >                                         
> > > ActionSourceRule.ACTION_LISTENER_SIG)));
> > >             }
> > >
> > >         }
> > >
> > >         public final static ActionSourceRule Instance = new 
> > > ActionSourceRule();
> > >
> > >         public ActionSourceRule() {
> > >             super();
> > >         }
> > >
> > >         public Metadata applyRule(String name, TagAttribute attribute,
> > >                 MetadataTarget meta) {
> > >             if (meta.isTargetInstanceOf(CustomHtmlDataTable.class)) {
> > >
> > >                 if (ACTION_LISTENER_ATT_NAME.equals(name)) {
> > >                     return new ActionListenerMapper(attribute);
> > >                 }
> > >             }
> > >             return null;
> > >         }
> > >     }
> > >
> > > }
> > >
> > >
> > > I hope this is basically the correct approach...
> > >
> > > Cheers,
> > > Martin
> > >
> > >
> > >
> > > >  Use one of these technologies:
> > > >
> > > > 1) JBoss-Seam. Set the action to run in the pages.xml file. Example:
> > > >
> > > >   <page view-id="/index.xhtml"
> > > >     action="#{welcomeBean.onLoad}" />
> > > >
> > > > 2) On-load from jsf-comp:
> > > > http://jsf-comp.sourceforge.net/components/onload/index.html
> > > >
> > > > 3) or use Shale (I have no experience with this one):
> > > > http://shale.apache.org/shale-view/index.html
> > > >
> > > > -Andrew
> > > >
> > > > On 12/11/06, Martin Grotzke <[EMAIL PROTECTED]> wrote:
> > > >         On Mon, 2006-12-11 at 10:29 -0500, Simon Lessard wrote:
> > > >         > Hello Martin,
> > > >         >
> > > >         > Can you provide a mopre explicit example of the use case
> > > >         please?
> > > >         Sorry for the few words, if you think about a problem for
> > > >         several days
> > > >         to you it seems just too clear ;)
> > > >
> > > >         What I have is a datatable in a template with the detailStamp
> > > >         facet:
> > > >
> > > >         <table jsfc="t:dataTable"
> > > >                 ...
> > > >                 value="#{myBean.myModel}"
> > > >                 var="myItem"
> > > >                 varDetailToggler="detailToggler">
> > > >
> > > >                 ... some columns ...
> > > >
> > > >                 <span jsfc="f:facet" name="detailStamp">
> > > >                         <ui:include src=" itemdetails.xhtml">
> > > >                                 <ui:param name="item"
> > > >         value="#{myItem}"/>
> > > >                         </ui:include>
> > > >                 </span>
> > > >         </table>
> > > >
> > > >         The itemdetails.xhtml displays details to the item, e.g. it
> > > >         iterates
> > > >         over some detail options like the following:
> > > >
> > > >         <ui:repeat var="option" value="#{item.myOptions}">
> > > >                 #{option.description}
> > > >         </ui:repeat>
> > > >
> > > >         So the the myBean.myModel.myOptions method is requested when
> > > >         the detailStamp
> > > >         is displayed for one item, this method is invoked when
> > > >         rendering happens.
> > > >
> > > >         When myBean.myModel.myOptions is invoked the first time, I do
> > > >         some lazy
> > > >         initialization, this might cause errors...
> > > >
> > > >         I do not see how I could do the processing in the invoke
> > > >         application, because
> > > >         the detailStamp is shown via HtmlDataTable.toggleDetail, which
> > > >         is invoked
> > > >         during invoke-application, but there's no possibility of
> > > >         specifying a listener
> > > >         that is invoked when toggleDetail is invoked...
> > > >
> > > >         I hope this clarifies the problem a little bit, if s.th. is
> > > >         missing please
> > > >         let me know!
> > > >
> > > >         Thanx a lot,
> > > >         cheers,
> > > >         Martin
> > > >
> > > >
> > > >
> > > >         > Why can't you do the processing in the invoke application
> > > >         phase?
> > > >         > Without more details, all I could suggest is to use a render
> > > >         response
> > > >         > phase listener and add your logic in the beforePhase
> > > >         method.
> > > >         >
> > > >         >
> > > >         > Regards,
> > > >         >
> > > >         > ~ Simon
> > > >         >
> > > >         > On 12/11/06, Martin Grotzke <[EMAIL PROTECTED]>
> > > >         wrote:
> > > >         >         Hi all,
> > > >         >
> > > >         >         I have a case where I perform some logic during the
> > > >         >         RENDER_RESPONSE
> > > >         >         phase where an error might occurs and I want to
> > > >         display some
> > > >         >         error
> > > >         >         message - which is unfortunately not displayed
> > > >         directly. But
> > > >         >         with the
> > > >         >         next request/response the error message is
> > > >         displayed. I asume
> > > >         >         that this
> > > >         >         is the case because the h:messages component is
> > > >         already
> > > >         >         rendered - so
> > > >         >         the behavior should basically be correct.
> > > >         >
> > > >         >         Do you have any suggestions how to handle this?
> > > >         >
> > > >         >         The concrete case is when the details of a dataTable
> > > >         (facet
> > > >         >         detailStamp)
> > > >         >         are displayed - just comes into my mind to use a
> > > >         >         CustomHtmlDataTable
> > > >         >         component that overrides the toggleDetail method...
> > > >         What do
> > > >         >         you think?
> > > >         >
> > > >         >         Thanx in advance,
> > > >         >         cheers,
> > > >         >         Martin
> > > >         >
> > > >         >
> > > >         >
> > > >         >
> > > >         >
> > > >         >
> > > >         --
> > > >         Martin Grotzke
> > > >         http://www.javakaffee.de/blog/
> > > >
> > > >
> > > >
> > --
> > Martin Grotzke
> > http://www.javakaffee.de/blog/
> >
> >
> >
> 
-- 
Martin Grotzke
http://www.javakaffee.de/blog/

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to