if the component does not have an id
you can olso do follwing:

in the mixin... add an arbitrary hidden element before the component
set id for that element and use:
var anchor = document.getElementById("idOfElement");
var compDomNode = anchor.nextSibling;

you can do that also by putting an element after the component,
and thus use this approach only when id is not available

I dislike using explicit ids in my js app at all, but that's just the way
I like it...


Davor Hrg


On Tue, Apr 15, 2008 at 11:13 AM, Chris Lewis <[EMAIL PROTECTED]>
wrote:

> The goal
> ---------------------
> To create a mixin that will attach a client-side javascript object to
> the mixing component. This mixin should not know anything about the
> component and remain completely genereic, needing only a DOM id to
> provide to the JS object.
>
>
> Requirements
> ---------------------
> To attach JS behavior, you need a DOM id. Therefore the mixin must be
> able to obtain this value from the component.
>
>
> Problems
> ---------------------
> Not all components generate DOM ids, in which case you have to provide
> one informally.
> For a mixin to be able to attach a JS object to an element generated by
> a component, it has to be able to obtain that id.
>
> Digging through api I have found 2 possible ways to obtain the DOM id.
> 1) If the component implements ClientElement, then
> ClientElement#getClientId is the correct way.
> 2) If the component has used the MarkupWriter
> (
> http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry/MarkupWriter.html
> )
> to create the exact element from which we need the DOM id, then we can
> use MarkupWriter#getElement to get that element before it is closed.
> With that Element
> (
> http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry/dom/Element.html
> )
> we can see if a DOM id has been set by using Element#getAttribute (and
> passing "id" as the argument).
>
>
> Last notes
> ---------------------
> Perhaps I'm a bit delusional on this issue. At first I thought that the
> DOM id was so important that there should be a more intimate handling of
> it, perhaps moving the getClientId from ClientElement to
> ComponentResourcesCommon, so that _every_ component has one. The problem
> is that a component can be arbitrarily complex, generating markup of an
> unknown hierachical depth of elements. In addition, the component body
> may be constructed primarily by it's template.
>
> I'm still thinking on this, but it seems like attaching a mixin to a
> component's dom id will require explicitly telling it what that is.
>
> Input still welcome :-)
>
> chris
>
> --
> http://thegodcode.net
>
>
>
> Josh Canfield wrote:
> > Ah, id with no t: is just a parameter like any other. Try this mixin:
> >
> > import org.apache.tapestry.MarkupWriter;
> > import org.apache.tapestry.annotations.Parameter;
> >
> > public class Title {
> >
> >     @Parameter(defaultPrefix="literal")
> >     private String _id;
> >
> >     void beginRender(MarkupWriter writer)
> >     {
> >         writer.attributes("title", "You're id is " + _id);
> >     }
> > }
> >
> >
> > The downside is if the component you are mixing into already has the
> > id parameter define, your mixin gets null. I'm not sure why they can't
> > share... the docs say
> >
> > "If the component and a mix both define a parameter with the same
> > name, then the component wins: the component's parameter will be
> > bound, and the mixin's parameter will be unbound."
> >
> > but I'm not clear why that is the case.
> >
> > Does that help?
> > Josh
> >
> > On Thu, Apr 10, 2008 at 9:57 PM, Chris Lewis <[EMAIL PROTECTED]>
> wrote:
> >
> >> Hi Josh,
> >>
> >> Indeed t:id does work, but apart from the fact that I'm not entirely
> >> sure what T5 does with that value as opposed to the un-namespaced
> >> version (id), it doesn't fully work. The reason is because the Any
> >> component, like many in the core lib, do not explicitly write a DOM id
> >> in the HTML of the resulting element. So while this allows me to get
> >> some id in java code (which I need), it doesn't address the problem of
> >> their not being a DOM id, so of course my JS fails. The only ways
> around
> >> this that I know are:
> >>
> >> 1) Explicitly provide the id as the normal 'id' attribute in the
> >> template as an informal parameter and provide another one in the t:
> >> namespace, to be passed to the component. The problem with this is I
> >> have to provide it twice, which aside from being annoying is
> error-prone.
> >>
> >> 2) Have the mixin explicitly write a HTML id attribute to the tag of
> the
> >> containing component. This would be horrible in my opinion, because
> >> without intimate knowledge of the component using the mixin, or any
> >> other mixins coordinating behavior, you can't know be sure you won't
> >> damage something (overwriting an id attribute already created, writing
> a
> >> second id attribute (which would be wrong), etc). And of course if the
> >> mixin requires intimate knowledge then it's not a good mixin.
> >>
> >> Thanks - any other ideas? :-)
> >>
> >> chris
> >>
> >>
> >> Josh Canfield wrote:
> >>
> >>> Hey Chris,
> >>>
> >>> t:id="my_div" seems to do what you want. I haven't looked closely at
> >>> un-namespaced id works in Tapestry, I've just always used the t:id
> >>> variety...
> >>>
> >>> Josh
> >>>
> >>> On Thu, Apr 10, 2008 at 5:36 AM, Chris Lewis <
> [EMAIL PROTECTED]> wrote:
> >>>
> >>>
> >>>> Dear list,
> >>>>
> >>>> I decided to throw together an app detailing how JS works with T5
> (how
> >>>> to connect behavior from a component or mixin, the important inner
> >>>> workings, etc). I created a mixin that attaches behavior (mouse
> overs)
> >>>> to an HTML element (and doing this requires the DOM id of that
> element).
> >>>> For a simple demo I just wanted to attach it to a styled <div
> >>>> id="my_div">, so I had to use a <div t:type="any" id="my_div">. No
> >>>> problem. Now I need that DOM id in my java code (mixin) so I can pass
> it
> >>>> to the instantiation string of my JS object. Here's what I tried:
> >>>>
> >>>>    @Parameter(value = "prop:componentResources.id", defaultPrefix =
> >>>> TapestryConstants.LITERAL_BINDING_PREFIX)
> >>>>    private String clientId;
> >>>>
> >>>> This is the 'usual' way of getting the client side id of the
> component,
> >>>> at least when that component outputs it in the html element body.
> Since
> >>>> Any does not, it appears to interpret (or rather ignore) the id
> >>>> attribute and treat it as an informal. The problem with that is there
> is
> >>>> no way, at least that I know of, to get my hands on that value in
> java
> >>>> code. So what I'm having to do in my template code is explicitly
> declare
> >>>> the t:clientId parameter:
> >>>>
> >>>> <div t:type="any" t:mixins="hoverhighlight" id="my_box"
> t:clientId="my_box">
> >>>>
> >>>> This works, but it's annoying that T5 can't know what the client side
> id
> >>>> will be. Components that actually produce a T5-generated client side
> id
> >>>> generally implement ClientElement#getClientId and explicitly insert
> the
> >>>> html id attribute with that as a value. I realize that it wouldn't
> make
> >>>> sense for _every_ component to do this, but IMO there should be a way
> to
> >>>> get at this id in the situations where it's been provided. Perhaps
> I've
> >>>> missed something, but unless I've missed something there's no current
> >>>> way to do this and get the dom id in code:
> >>>>
> >>>> <div t:type="any" t:mixins="hoverhighlight" id="my_box">
> >>>>
> >>>> Thanks for any input you can offer.
> >>>>
> >>>> chris
> >>>>
> >>>> --
> >>>> http://thegodcode.net
> >>>>
> >>>>
> >>>> ---------------------------------------------------------------------
> >>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >> --
> >> http://thegodcode.net
> >>
> >>
> >>
> >
> >
> >
> >
>
> --
> http://thegodcode.net
>
>

Reply via email to