You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Ole Ersoy <ol...@gmail.com> on 2007/12/15 03:07:54 UTC

Adding a property to a component and rendering it ... the magic way?

Hi,

I have a attribute that I just need to get passed through to the corresponding html element.  For example:

<h:form id="registrationForm"
	anAdditionalAttribute="I need to get through to the form element">
</h:form>


In the rendered output I would like:

<form 
	...
	anAdditionalAttribute="I need to get through to the form element">
</form>


I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.  

Does anyone know if there's a quicker/magic way to get the job done?

Thanks,
- Ole



Re: Adding a property to a component and rendering it ... the magic way?

Posted by Ole Ersoy <ol...@gmail.com>.
Hey Guys,

I tried hacking the org.apache.myfaces.shared.renderkit.html.HTML constants contained in 

      <dependency>
        <groupId>org.apache.myfaces.shared</groupId>
        <artifactId>myfaces-shared-core</artifactId>
        <version>3.0.0</version>
        <scope>compile</scope>
      </dependency>

to see if I could add pass through attributes.  I did do a quick test to make sure the COMMON_PASSTHROUGH_ATTRIBUTES contained the new attributes, but it was still unsuccessful.

Which I think goes with 1.2.0?  My main reason for trying this is that it would save having to re-implement encodeBegin on the renderer which I think is necessary if I simply wanted to add another attribute and render it the normal way.

I'll probably just create a new component/renderer pair, since it seems to be the least amount of change to manage in the short run.

One thing that might save effort here is if the myfaces library had encodeBeginStartTag and encodeBeginEndTag template methods that could be overridden.  That way new attributes could be inserted without reimplementing all code in encodeBegin...Anyone like this idea?  Thus inside encodeBegin we would call these:

encodeBegin()
{
	encodeBeginStartTag(component, responseWriter)
	encodeBeginEndTag(component, responseWriter)
}

Then the subclassing renderer would just override encodeBeginStartTag and call it first.  Then renderer the additional attribute.  

The main rationale for doing stuff like this is that quickly adding attributes like "dojoType" would enable a client side javascript component to wrap the rendered element, enabling us to have both a server side and client side component tree.

Cheers,
- Ole


Re: Adding a property to a component and rendering it ... the magic way?

Posted by Ole Ersoy <ol...@gmail.com>.
Hi Simon and Andrew,

Thanks for the excellent advice.  The <f:attribute> type of tag sounds like the right way to go, especially coupled with modification suggested on the response writer.  I'll probably try to hack that in, assuming that <f:attribute> can be used with tags beside UICommand.  If it can't then I guess I'll have to create a new component that does the same, but with any subclass of UIComponent.   

In JSF in Action I think Kito recommended creating a HTMLRenderer parent class that has a utility method for rendering the UIComponent.attributes list / the pass through attributes.  Do you know if myfaces has something like this built in...that could be turned on via configuration.  This would save the renderer implementation as well.  To be safe I'm thinking it should be handled at the tag level.  So if the component tag had a renderPassThroughAttributes="true", then the renderer would render the pass through attributes.  Otherwise, we would get the current default behavior.  Thoughts?

Thanks again,
- Ole




simon wrote:
> On Fri, 2007-12-14 at 20:07 -0600, Ole Ersoy wrote:
>> Hi,
>>
>> I have a attribute that I just need to get passed through to the corresponding html element.  For example:
>>
>> <h:form id="registrationForm"
>> 	anAdditionalAttribute="I need to get through to the form element">
>> </h:form>
>>
>>
>> In the rendered output I would like:
>>
>> <form 
>> 	...
>> 	anAdditionalAttribute="I need to get through to the form element">
>> </form>
>>
>>
>> I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.  
>>
>> Does anyone know if there's a quicker/magic way to get the job done?
> 
> Every component has an "attributes" property that is a map that anything
> can be stored in. It is common for properties that are not used by the
> component itself (just the renderer) to be stored in this map, rather
> than be on the component. The renderer can then retrieve them by:
>   component.getAttributes().get("anAdditionalAttribute");
> 
> So that saves subclassing the component...
> 
> But the hard part is that to allow the tag to accept another attribute,
> you need to subclass the tag class, and create a new taglib. Then your
> page will need to use
>   <foo:form ...>
> rather than
>   <h:form ...>
> 
> An alternative would be to write a custom tag that can be used to store
> values into the attributes map of its enclosing component. Then
> something like:
>   <h:form ....>
>     <foo:attribute name="anAdditionalAttribute" value="I need.."/>
> could be used rather than creating a special tag for it.
> 
> As it happens, in MyFaces the standard f:attribute tag currently does
> exactly this. Interestingly, it possibly shouldn't: the official JSF
> docs say that it should only affect:
>   "the closest parent UIComponent custom action"
> which I guess means it should walk up the component tree to find a
> subclass of UICommand. I'll investigate what the Sun RI implementation
> does...
> 
> If using f:attribute is acceptable to you, that avoids creating a new
> tag class too, leaving just the renderer code to be done.
> 
> Regards,
> 
> Simon
> 
> 

Re: Adding a property to a component and rendering it ... the magic way?

Posted by simon <si...@chello.at>.
On Fri, 2007-12-14 at 20:07 -0600, Ole Ersoy wrote:
> Hi,
> 
> I have a attribute that I just need to get passed through to the corresponding html element.  For example:
> 
> <h:form id="registrationForm"
> 	anAdditionalAttribute="I need to get through to the form element">
> </h:form>
> 
> 
> In the rendered output I would like:
> 
> <form 
> 	...
> 	anAdditionalAttribute="I need to get through to the form element">
> </form>
> 
> 
> I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.  
> 
> Does anyone know if there's a quicker/magic way to get the job done?

Every component has an "attributes" property that is a map that anything
can be stored in. It is common for properties that are not used by the
component itself (just the renderer) to be stored in this map, rather
than be on the component. The renderer can then retrieve them by:
  component.getAttributes().get("anAdditionalAttribute");

So that saves subclassing the component...

But the hard part is that to allow the tag to accept another attribute,
you need to subclass the tag class, and create a new taglib. Then your
page will need to use
  <foo:form ...>
rather than
  <h:form ...>

An alternative would be to write a custom tag that can be used to store
values into the attributes map of its enclosing component. Then
something like:
  <h:form ....>
    <foo:attribute name="anAdditionalAttribute" value="I need.."/>
could be used rather than creating a special tag for it.

As it happens, in MyFaces the standard f:attribute tag currently does
exactly this. Interestingly, it possibly shouldn't: the official JSF
docs say that it should only affect:
  "the closest parent UIComponent custom action"
which I guess means it should walk up the component tree to find a
subclass of UICommand. I'll investigate what the Sun RI implementation
does...

If using f:attribute is acceptable to you, that avoids creating a new
tag class too, leaving just the renderer code to be done.

Regards,

Simon


Re: Adding a property to a component and rendering it ... the magic way?

Posted by Ole Ersoy <ol...@gmail.com>.
Hi Guys,

I've been doing a little more investigating.  The myfaces HtmlFormRenderer
has this method in it:

HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_PASSTHROUGH_ATTRIBUTES);

So I'm assuming this method will let any attribute that is contained in HTML.FORMPASSTHROUGH_ATTRIBUTES
pass through.  I'm also assuming any tag attribute that the View compiler cannot match to a component property is stored on the UIComponent.attributes list...which makes me wonder why <f:attribute> is needed...I'm hoping it's there just in case an implementation wanted to support a very strict Page compiler policy of only setting declared component properties.

So I'm going to try appending the attribute to the HTML.COMMON_PASSTHROUGH_ATTRIBUTES, which are included
in HTML.FORMPASSTHROUGH_ATTRIBUTES and see if that lets it get through.  All fingers crossed, as this would make life reel easy.

Cheers,
- Ole





simon wrote:
> Hmm..interesting suggestion, Andrew.
> 
> So a custom responsewriter could potentially be written to allow the
> insertion of new attributes onto the html tag for any component?
> 
> Is this what you were thinking of?
> 
> startElement(String ename, UIComponent component) {
>    // start xml element
>    // if (component not in already-processed list)
>    //   for each key in component.getAttributes()
>    //     if key.startsWith("tunnelledAttribute:")
>    //       output (key, value) as xml attributes
>    // store component in already-processed list
> }
> 
> Then:
>   <h:someTag ..>
>     <f:attribute name="tunnelledAttribute:foo" value="bar"/>
> 
> That might be interesting to add to the standard MyFaces
> ResponseWriter...
> 
> Regards,
> 
> Simon
> 
> On Fri, 2007-12-14 at 19:54 -0700, Andrew Robinson wrote:
>> Most renderers will not give you access to the root element to be able
>> to add attributes. However, if the renderers are correctly using the
>> response writer, they should be calling startElement(String,
>> UIComponent). By subclassing this, you can trap the call, look for you
>> attributes and add them to the element.
>>
>> -Andrew
>>
>> On Dec 14, 2007 7:07 PM, Ole Ersoy <ol...@gmail.com> wrote:
>>> Hi,
>>>
>>> I have a attribute that I just need to get passed through to the corresponding html element.  For example:
>>>
>>> <h:form id="registrationForm"
>>>         anAdditionalAttribute="I need to get through to the form element">
>>> </h:form>
>>>
>>>
>>> In the rendered output I would like:
>>>
>>> <form
>>>         ...
>>>         anAdditionalAttribute="I need to get through to the form element">
>>> </form>
>>>
>>>
>>> I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.
>>>
>>> Does anyone know if there's a quicker/magic way to get the job done?
>>>
>>> Thanks,
>>> - Ole
>>>
>>>
>>>
> 
> 

Re: Adding a property to a component and rendering it ... the magic way?

Posted by Ole Ersoy <ol...@gmail.com>.
Hi Simon,

simon wrote:
> Hi Ole,
> 
> It is good to know that Facelets adds attributes automatically.

Yes it's great.  Kudos to Jacob!

> 
> Yes, I guess it would be possible to modify
>   HtmlRendererUtils.renderHtmlAttributes
> to also look into the component it is passed for extra attributes that
> it should write. It does mean retrieving the FacesContext from the
> current thread and using that to get the configuration data (the names
> of "magic" attributes) but that doesn't seem too evil to me.
> 
> But a ResponseWriter-based approach can do very much the same thing.

Would that work sort of like this (99% your and Andrew's material I think):

//responseWriter.startFormElement...
//write the normal form attributes
//call responseWriter.writeAdditionalAttributes()
//close starting Element

And I think you indicated that the response writer would know how to write the the additional attribute because it would have a namespace prefix like "additionalAttribute:".  I guess this prefix could be made configurable?  Also what if the whole attribute name was configurable.  So if the attribute entry was keyed with name "ajaxComponent"...then send it through.

> 
> The advantage of doing it in HtmlRenderUtils is that it should work
> better for components that output multiple HTML tags. In this case, the
> renderer would normally invoke this method only for the "main" element.
> 
If I understand correctly, it now seems that the HtmlRendererUtils is fine doing what it's doing currently, and that the renderers should just do a responseWriter.writeAdditionalAttributes() inside encodeBegin, which would take care of this "Developer Use Case" entirely.

> However the advantage of doing it in ResponseWriter is that it will work
> for all JSF components, not just the MyFaces ones. I think that is
> extremely useful..

Indeed.  I'd like to give this a shot and would be delighted if it became part of the core or if it became useful in general...assuming I get it?

I think the task plan would be something like this:

- Understand how to configure a new ResponseWriter for JSF (We need to plugin a new one right?)
- Subclass the existing response writer
- Add the renderAdditionalAttributes() method.
- Figure out where the ResponseWriter gets it's configuration from...web.xml?
- Pass the necessary configuration so that renderAdditionalAttributes() has access.

And the rest is pretty easy I think...

Thanks again for the "Brain Jumping",
- Ole

Re: Adding a property to a component and rendering it ... the magic way?

Posted by Ole Ersoy <ol...@gmail.com>.
Hey Simon,

You're a saint.  Bet you never heard that before.  Thanks you so much (Martin and Andrew as well) for all the help.  I did this:

svn co http://svn.apache.org/repos/asf/myfaces/core/branches/1_2_0 myfaces_core_1.2.0
svn co http://svn.apache.org/repos/asf/myfaces/shared/branches/3_0_0 myfaces_shared_3.0.0

Added my passthrough attributes to COMMON_PASSTHROUGH_ATTRIBUTES on the HTML constants.

Rebuilt shared then core, and now the additional attributes are coming through as expected.  This takes care of my requirements, but I'd still be happy to collaborate on getting the response writer gig working.  I could also send a note about it out on the developer list if you think it's a good idea.

Thanks again,
- Ole



simon wrote:
> Hi Ole,
> 
> It is good to know that Facelets adds attributes automatically.
> 
> Yes, I guess it would be possible to modify
>   HtmlRendererUtils.renderHtmlAttributes
> to also look into the component it is passed for extra attributes that
> it should write. It does mean retrieving the FacesContext from the
> current thread and using that to get the configuration data (the names
> of "magic" attributes) but that doesn't seem too evil to me.
> 
> But a ResponseWriter-based approach can do very much the same thing.
> 
> The advantage of doing it in HtmlRenderUtils is that it should work
> better for components that output multiple HTML tags. In this case, the
> renderer would normally invoke this method only for the "main" element.
> 
> However the advantage of doing it in ResponseWriter is that it will work
> for all JSF components, not just the MyFaces ones. I think that is
> extremely useful..
> 
> Regards,
> 
> Simon
> 
> On Mon, 2007-12-17 at 00:22 -0600, Ole Ersoy wrote:
>> Good News - The tag attributes are automatically added to the UIComponent.attributes map (At least they are by facelets).  That means it's possible to skip adding <f:attribute> tags.
>>
>> WRT the responseWriter feature, I think it would be sweet if we could configure valid pass through attribute keys.  So for example:
>>
>> <application>
>>     <passthroughAttributes>
>> 	<attribute name="comingOnThroughBeibe"/>
>>     </passthroughAttributes>
>> </application>
>>
>> Then if the responseWriter saw the "comingOnThroughBeibe" key on one of the UIComponent.getAttributes() entries it would render it.
>>
>> I think that would have to be implemented on the HtmlRenderer utility methods though (Moving away from the custom response writer idea a bit)?  A custom utility method would be used by the renderer developer to pass through attributes that are "Hard Coded" for pass through, as is currently done with the HTML constants, + any configured pass through attributes.
>>
>> Thoughts?
>>
>> Cheers,
>> - Ole
>>
>>
>>
>>
>> simon wrote:
>>> Hmm..interesting suggestion, Andrew.
>>>
>>> So a custom responsewriter could potentially be written to allow the
>>> insertion of new attributes onto the html tag for any component?
>>>
>>> Is this what you were thinking of?
>>>
>>> startElement(String ename, UIComponent component) {
>>>    // start xml element
>>>    // if (component not in already-processed list)
>>>    //   for each key in component.getAttributes()
>>>    //     if key.startsWith("tunnelledAttribute:")
>>>    //       output (key, value) as xml attributes
>>>    // store component in already-processed list
>>> }
>>>
>>> Then:
>>>   <h:someTag ..>
>>>     <f:attribute name="tunnelledAttribute:foo" value="bar"/>
>>>
>>> That might be interesting to add to the standard MyFaces
>>> ResponseWriter...
>>>
>>> Regards,
>>>
>>> Simon
>>>
>>> On Fri, 2007-12-14 at 19:54 -0700, Andrew Robinson wrote:
>>>> Most renderers will not give you access to the root element to be able
>>>> to add attributes. However, if the renderers are correctly using the
>>>> response writer, they should be calling startElement(String,
>>>> UIComponent). By subclassing this, you can trap the call, look for you
>>>> attributes and add them to the element.
>>>>
>>>> -Andrew
>>>>
>>>> On Dec 14, 2007 7:07 PM, Ole Ersoy <ol...@gmail.com> wrote:
>>>>> Hi,
>>>>>
>>>>> I have a attribute that I just need to get passed through to the corresponding html element.  For example:
>>>>>
>>>>> <h:form id="registrationForm"
>>>>>         anAdditionalAttribute="I need to get through to the form element">
>>>>> </h:form>
>>>>>
>>>>>
>>>>> In the rendered output I would like:
>>>>>
>>>>> <form
>>>>>         ...
>>>>>         anAdditionalAttribute="I need to get through to the form element">
>>>>> </form>
>>>>>
>>>>>
>>>>> I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.
>>>>>
>>>>> Does anyone know if there's a quicker/magic way to get the job done?
>>>>>
>>>>> Thanks,
>>>>> - Ole
>>>>>
>>>>>
>>>>>
>>>
> 
> 

Re: Adding a property to a component and rendering it ... the magic way?

Posted by simon <si...@chello.at>.
Hi Ole,

It is good to know that Facelets adds attributes automatically.

Yes, I guess it would be possible to modify
  HtmlRendererUtils.renderHtmlAttributes
to also look into the component it is passed for extra attributes that
it should write. It does mean retrieving the FacesContext from the
current thread and using that to get the configuration data (the names
of "magic" attributes) but that doesn't seem too evil to me.

But a ResponseWriter-based approach can do very much the same thing.

The advantage of doing it in HtmlRenderUtils is that it should work
better for components that output multiple HTML tags. In this case, the
renderer would normally invoke this method only for the "main" element.

However the advantage of doing it in ResponseWriter is that it will work
for all JSF components, not just the MyFaces ones. I think that is
extremely useful..

Regards,

Simon

On Mon, 2007-12-17 at 00:22 -0600, Ole Ersoy wrote:
> Good News - The tag attributes are automatically added to the UIComponent.attributes map (At least they are by facelets).  That means it's possible to skip adding <f:attribute> tags.
> 
> WRT the responseWriter feature, I think it would be sweet if we could configure valid pass through attribute keys.  So for example:
> 
> <application>
>     <passthroughAttributes>
> 	<attribute name="comingOnThroughBeibe"/>
>     </passthroughAttributes>
> </application>
> 
> Then if the responseWriter saw the "comingOnThroughBeibe" key on one of the UIComponent.getAttributes() entries it would render it.
> 
> I think that would have to be implemented on the HtmlRenderer utility methods though (Moving away from the custom response writer idea a bit)?  A custom utility method would be used by the renderer developer to pass through attributes that are "Hard Coded" for pass through, as is currently done with the HTML constants, + any configured pass through attributes.
> 
> Thoughts?
> 
> Cheers,
> - Ole
> 
> 
> 
> 
> simon wrote:
> > Hmm..interesting suggestion, Andrew.
> > 
> > So a custom responsewriter could potentially be written to allow the
> > insertion of new attributes onto the html tag for any component?
> > 
> > Is this what you were thinking of?
> > 
> > startElement(String ename, UIComponent component) {
> >    // start xml element
> >    // if (component not in already-processed list)
> >    //   for each key in component.getAttributes()
> >    //     if key.startsWith("tunnelledAttribute:")
> >    //       output (key, value) as xml attributes
> >    // store component in already-processed list
> > }
> > 
> > Then:
> >   <h:someTag ..>
> >     <f:attribute name="tunnelledAttribute:foo" value="bar"/>
> > 
> > That might be interesting to add to the standard MyFaces
> > ResponseWriter...
> > 
> > Regards,
> > 
> > Simon
> > 
> > On Fri, 2007-12-14 at 19:54 -0700, Andrew Robinson wrote:
> >> Most renderers will not give you access to the root element to be able
> >> to add attributes. However, if the renderers are correctly using the
> >> response writer, they should be calling startElement(String,
> >> UIComponent). By subclassing this, you can trap the call, look for you
> >> attributes and add them to the element.
> >>
> >> -Andrew
> >>
> >> On Dec 14, 2007 7:07 PM, Ole Ersoy <ol...@gmail.com> wrote:
> >>> Hi,
> >>>
> >>> I have a attribute that I just need to get passed through to the corresponding html element.  For example:
> >>>
> >>> <h:form id="registrationForm"
> >>>         anAdditionalAttribute="I need to get through to the form element">
> >>> </h:form>
> >>>
> >>>
> >>> In the rendered output I would like:
> >>>
> >>> <form
> >>>         ...
> >>>         anAdditionalAttribute="I need to get through to the form element">
> >>> </form>
> >>>
> >>>
> >>> I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.
> >>>
> >>> Does anyone know if there's a quicker/magic way to get the job done?
> >>>
> >>> Thanks,
> >>> - Ole
> >>>
> >>>
> >>>
> > 
> > 


Re: Adding a property to a component and rendering it ... the magic way?

Posted by Ole Ersoy <ol...@gmail.com>.
Good News - The tag attributes are automatically added to the UIComponent.attributes map (At least they are by facelets).  That means it's possible to skip adding <f:attribute> tags.

WRT the responseWriter feature, I think it would be sweet if we could configure valid pass through attribute keys.  So for example:

<application>
    <passthroughAttributes>
	<attribute name="comingOnThroughBeibe"/>
    </passthroughAttributes>
</application>

Then if the responseWriter saw the "comingOnThroughBeibe" key on one of the UIComponent.getAttributes() entries it would render it.

I think that would have to be implemented on the HtmlRenderer utility methods though (Moving away from the custom response writer idea a bit)?  A custom utility method would be used by the renderer developer to pass through attributes that are "Hard Coded" for pass through, as is currently done with the HTML constants, + any configured pass through attributes.

Thoughts?

Cheers,
- Ole




simon wrote:
> Hmm..interesting suggestion, Andrew.
> 
> So a custom responsewriter could potentially be written to allow the
> insertion of new attributes onto the html tag for any component?
> 
> Is this what you were thinking of?
> 
> startElement(String ename, UIComponent component) {
>    // start xml element
>    // if (component not in already-processed list)
>    //   for each key in component.getAttributes()
>    //     if key.startsWith("tunnelledAttribute:")
>    //       output (key, value) as xml attributes
>    // store component in already-processed list
> }
> 
> Then:
>   <h:someTag ..>
>     <f:attribute name="tunnelledAttribute:foo" value="bar"/>
> 
> That might be interesting to add to the standard MyFaces
> ResponseWriter...
> 
> Regards,
> 
> Simon
> 
> On Fri, 2007-12-14 at 19:54 -0700, Andrew Robinson wrote:
>> Most renderers will not give you access to the root element to be able
>> to add attributes. However, if the renderers are correctly using the
>> response writer, they should be calling startElement(String,
>> UIComponent). By subclassing this, you can trap the call, look for you
>> attributes and add them to the element.
>>
>> -Andrew
>>
>> On Dec 14, 2007 7:07 PM, Ole Ersoy <ol...@gmail.com> wrote:
>>> Hi,
>>>
>>> I have a attribute that I just need to get passed through to the corresponding html element.  For example:
>>>
>>> <h:form id="registrationForm"
>>>         anAdditionalAttribute="I need to get through to the form element">
>>> </h:form>
>>>
>>>
>>> In the rendered output I would like:
>>>
>>> <form
>>>         ...
>>>         anAdditionalAttribute="I need to get through to the form element">
>>> </form>
>>>
>>>
>>> I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.
>>>
>>> Does anyone know if there's a quicker/magic way to get the job done?
>>>
>>> Thanks,
>>> - Ole
>>>
>>>
>>>
> 
> 

Re: Adding a property to a component and rendering it ... the magic way?

Posted by Andrew Robinson <an...@gmail.com>.
Yes, that is basically what I was thinking of. It would be better to
use clientId instead of the component for the already processed list
though as you would want to support looping components like dataTable.

If this were to be made generic, being able to add a listener would be
awesome, so people could inject HTML before a tag or into the
attributes.

-Andrew

On Dec 15, 2007 4:42 AM, simon <si...@chello.at> wrote:
> Hmm..interesting suggestion, Andrew.
>
> So a custom responsewriter could potentially be written to allow the
> insertion of new attributes onto the html tag for any component?
>
> Is this what you were thinking of?
>
> startElement(String ename, UIComponent component) {
>    // start xml element
>    // if (component not in already-processed list)
>    //   for each key in component.getAttributes()
>    //     if key.startsWith("tunnelledAttribute:")
>    //       output (key, value) as xml attributes
>    // store component in already-processed list
> }
>
> Then:
>   <h:someTag ..>
>     <f:attribute name="tunnelledAttribute:foo" value="bar"/>
>
> That might be interesting to add to the standard MyFaces
> ResponseWriter...
>
> Regards,
>
> Simon
>
>
> On Fri, 2007-12-14 at 19:54 -0700, Andrew Robinson wrote:
> > Most renderers will not give you access to the root element to be able
> > to add attributes. However, if the renderers are correctly using the
> > response writer, they should be calling startElement(String,
> > UIComponent). By subclassing this, you can trap the call, look for you
> > attributes and add them to the element.
> >
> > -Andrew
> >
> > On Dec 14, 2007 7:07 PM, Ole Ersoy <ol...@gmail.com> wrote:
> > > Hi,
> > >
> > > I have a attribute that I just need to get passed through to the corresponding html element.  For example:
> > >
> > > <h:form id="registrationForm"
> > >         anAdditionalAttribute="I need to get through to the form element">
> > > </h:form>
> > >
> > >
> > > In the rendered output I would like:
> > >
> > > <form
> > >         ...
> > >         anAdditionalAttribute="I need to get through to the form element">
> > > </form>
> > >
> > >
> > > I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.
> > >
> > > Does anyone know if there's a quicker/magic way to get the job done?
> > >
> > > Thanks,
> > > - Ole
> > >
> > >
> > >
>
>

Re: Adding a property to a component and rendering it ... the magic way?

Posted by simon <si...@chello.at>.
Hmm..interesting suggestion, Andrew.

So a custom responsewriter could potentially be written to allow the
insertion of new attributes onto the html tag for any component?

Is this what you were thinking of?

startElement(String ename, UIComponent component) {
   // start xml element
   // if (component not in already-processed list)
   //   for each key in component.getAttributes()
   //     if key.startsWith("tunnelledAttribute:")
   //       output (key, value) as xml attributes
   // store component in already-processed list
}

Then:
  <h:someTag ..>
    <f:attribute name="tunnelledAttribute:foo" value="bar"/>

That might be interesting to add to the standard MyFaces
ResponseWriter...

Regards,

Simon

On Fri, 2007-12-14 at 19:54 -0700, Andrew Robinson wrote:
> Most renderers will not give you access to the root element to be able
> to add attributes. However, if the renderers are correctly using the
> response writer, they should be calling startElement(String,
> UIComponent). By subclassing this, you can trap the call, look for you
> attributes and add them to the element.
> 
> -Andrew
> 
> On Dec 14, 2007 7:07 PM, Ole Ersoy <ol...@gmail.com> wrote:
> > Hi,
> >
> > I have a attribute that I just need to get passed through to the corresponding html element.  For example:
> >
> > <h:form id="registrationForm"
> >         anAdditionalAttribute="I need to get through to the form element">
> > </h:form>
> >
> >
> > In the rendered output I would like:
> >
> > <form
> >         ...
> >         anAdditionalAttribute="I need to get through to the form element">
> > </form>
> >
> >
> > I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.
> >
> > Does anyone know if there's a quicker/magic way to get the job done?
> >
> > Thanks,
> > - Ole
> >
> >
> >


Re: Adding a property to a component and rendering it ... the magic way?

Posted by Andrew Robinson <an...@gmail.com>.
Most renderers will not give you access to the root element to be able
to add attributes. However, if the renderers are correctly using the
response writer, they should be calling startElement(String,
UIComponent). By subclassing this, you can trap the call, look for you
attributes and add them to the element.

-Andrew

On Dec 14, 2007 7:07 PM, Ole Ersoy <ol...@gmail.com> wrote:
> Hi,
>
> I have a attribute that I just need to get passed through to the corresponding html element.  For example:
>
> <h:form id="registrationForm"
>         anAdditionalAttribute="I need to get through to the form element">
> </h:form>
>
>
> In the rendered output I would like:
>
> <form
>         ...
>         anAdditionalAttribute="I need to get through to the form element">
> </form>
>
>
> I think the process for doing this (Excluding component registration, etc.) is first to subclass the form component and add the "anAdditionalAttribute" to the subclass.  Then subclass the corresponding renderer and render this attribute.
>
> Does anyone know if there's a quicker/magic way to get the job done?
>
> Thanks,
> - Ole
>
>
>