jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [jsr372-experts mirror] [49-JsClientId] JS function for "give me the clientId"

From: Kito Mann <kito.mann_at_virtua.com>
Date: Thu, 15 Jan 2015 09:26:10 -0500

On Thursday, January 15, 2015, Cagatay Civici <cagatay.civici_at_gmail.com>
wrote:

> Hi,
>
> Having a standard function to return the client id of the component via an
> EL would be good, all 3rd party libs have it. We have
> #{p:component(’server_id’)}.
>

+1

>
> About widgets, standard h:* components have no widgets so I don’t see much
> of a point in creating something for it.
>

Unless we decide to create standard JS bindings (for example, standardize
the relationship between a server-side component and a client-side widget),
I agree.

>
> Also having script block before the element has use cases like if the
> component is a container like tab, panel, accordion. Then there may be
> cases where it has to be initialised before its children.
>
> <script of parent>
> <content of parent>
> <script of child>
> <content of child>
>
> If it is like following;
>
> <content of parent>
> <script of child>
> <content of child>
> <script of parent>
>
> If the children needs access to their parent, then it will fail so I’ve
> experienced use cases so we should not make any assumption.
>
> So I’m +1 for a standard server function to return client id, it is very
> useful for client side scripting but a standard javascript is probably not
> needed, it is simple to access the element with javascript using the server
> side function that gives the client id.
>
> Regards,
>
> Cagatay Civici
> PrimeFaces Lead
> PrimeTek Informatics
> www.primefaces.org
>
> On Thursday 15 January 2015 at 09:28, Bauke Scholtz wrote:
>
> I don't consider that part to be a problem which needs to be covered by
> JSF spec. This is just JS specific. A sane JS developer should for long
> know that the DOM element is only accessible once it has been inserted in
> the DOM. A sane JS developer would just use <h:outputScript target="body">
> or window.addEventListener("load", func) or even $(document).ready(func).
>
> If you really need it to be part of JSF spec, just specify that it must be
> rendered like <h:outputScript target="body">.
>
> Cheers, B
>
> On Wed, Jan 14, 2015 at 8:26 PM, Leonardo Uribe <leonardo.uribe_at_irian.at
> <javascript:_e(%7B%7D,'cvml','leonardo.uribe_at_irian.at');>> wrote:
>
> Hi
>
> Yes. The point is if there is a known solution to a problem that
> every third-party vendor has its own variant and is widely used,
> that problem is a good candidate to be included in the
> standard.
>
> The important thing is include something to get access to the
> client-side counterpart of a component from the client, for
> the components that has a client side counterpart or "widget".
> Not all components fall under that category of course, but
> a lot of components in JSF third party libraries has that
> structure.
>
> regards,
>
> Leonardo Uribe
>
> 2015-01-14 13:44 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com
> <javascript:_e(%7B%7D,'cvml','balusc_at_gmail.com');>>:
> > Of course, whether the HTML element itself is available is a second (and
> > unrelated to JSF), but the point was that #{foo.clientId} works
> regardless
> > of the location in the view.
> >
> > Cheers, B
> >
> > On Wed, Jan 14, 2015 at 7:39 PM, Leonardo Uribe <leonardo.uribe_at_irian.at
> <javascript:_e(%7B%7D,'cvml','leonardo.uribe_at_irian.at');>>
> > wrote:
> >>
> >> Hi
> >>
> >> MR>> What if you put the script section before the <h:someComponent>,
> >> which is perfectly legal?
> >>
> >> BS>> It'll work because it's printed during render view, not build view.
> >>
> >> I guess the element will not be found when the javascript is called,
> >> because the page has not been loaded.
> >>
> >> But anyway, it is a matter about how you write the javascript:
> >>
> >> <script>
> >> jQuery(document).ready(function() {
> >> var foo = document.getElementById('#{foo.clientId}');
> >> });
> >> </script>
> >> <h:someComponent id="foo" binding="#{foo}" />
> >>
> >> In fact there is a small lifecycle:
> >>
> >> - Load the page / Widget initialization
> >> - invoke load functions
> >>
> >> We could create a custom jsf javascript function for that stuff
> >> if required.
> >>
> >> But I can't imagine why someone would put the script before
> >> the tag.
> >>
> >> regards,
> >>
> >> Leonardo Uribe
> >>
> >> 2015-01-14 13:03 GMT-05:00 manfred riem <manfred.riem_at_oracle.com
> <javascript:_e(%7B%7D,'cvml','manfred.riem_at_oracle.com');>>:
> >> > Hi all,
> >> >
> >> > On 1/14/15, 11:58 AM, Bauke Scholtz wrote:
> >> >
> >> > Not a chicken-egg problem.
> >> >
> >> > I disagree cordially ;)
> >> >
> >> > PrimeFaces #{p:component('componentId')} already does exactly this:
> >> >
> >> >
> http://www.primefaces.org/docs/vdl/5.0/core/primefaces-p/component.fn.html
> >> >
> >> > RichFaces also has several since ages:
> >> >
> >> >
> http://docs.jboss.org/richfaces/latest_4_5_X/Component_Reference/en-US/html/chap-Component_Reference-Functions.html
> >> >
> >> > I myself just use component binding, but this is not always clearly
> >> > understood by starters (who usually also don't always clearly see the
> >> > wall
> >> > between server side and client side).
> >> >
> >> > <h:someComponent id="foo" binding="#{foo}" />
> >> > <script>var foo = document.getElementById('#{foo.clientId}');</script>
> >> >
> >> > What if you put the script section before the <h:someComponent>, which
> >> > is
> >> > perfectly legal?
> >> >
> >> > Cheers, B
> >> >
> >> > On Wed, Jan 14, 2015 at 6:42 PM, Leonardo Uribe
> >> > <leonardo.uribe_at_irian.at
> <javascript:_e(%7B%7D,'cvml','leonardo.uribe_at_irian.at');>>
> >> > wrote:
> >> >>
> >> >> Hi
> >> >>
> >> >> I just forgot to say that the clientId is used a an identifier bound
> >> >> to the HTML "id" attribute, and in that way it follows the rules that
> >> >> HTML says. But the widgetVar is an identifier for javascript,
> >> >> but its purpose is client side only.
> >> >>
> >> >> regards,
> >> >>
> >> >> Leonardo Uribe
> >> >>
> >> >> 2015-01-14 12:30 GMT-05:00 Leonardo Uribe <leonardo.uribe_at_irian.at
> <javascript:_e(%7B%7D,'cvml','leonardo.uribe_at_irian.at');>>:
> >> >> > Hi
> >> >> >
> >> >> > There is a relationship between the widgetVar and the clientId. For
> >> >> > example in primefaces if no widgetVar is set, by default it uses:
> >> >> >
> >> >> > "widget_" + clientId.replace(/:/g, "_")
> >> >> >
> >> >> > Use widgetVar has the advantage that you can use it directly on the
> >> >> > javascript. For example:
> >> >> >
> >> >> > myDialogWidget.doSomething();
> >> >> >
> >> >> > The disadvantage with widgetVar is if you have two components with
> >> >> > the
> >> >> > same widgetVar, it will be a conflict in javascript, so it affects
> >> >> > code reusal (a component with a widgetVar set will not work well
> >> >> > inside a dataTable). But on the other side, it is cleaner for
> >> >> > javascript users, because sometimes you need just to add a couple
> of
> >> >> > lines.
> >> >> >
> >> >> > The alternative is use a EL function and mix it with javascript:
> >> >> >
> >> >> > #{myLib:toJavascriptVar('myClientId')}.doSomething();
> >> >> >
> >> >> > This works well from reusal perspective, because the javascript
> >> >> > variable is generated at render time, but note facelets compiler
> >> >> > needs
> >> >> > to parse the javascript.
> >> >> >
> >> >> > It is a fact that if you have a component enhanced with javascript,
> >> >> > you need to create a javascript object, no matter how is called and
> >> >> > that javascript object will be associated with a html tag. The
> >> >> > current
> >> >> > clientId has the problem that it uses ':', so it is not a valid
> >> >> > javascript variable name. The need is have something that
> generates a
> >> >> > valid javascript name that can be associated with the component in
> a
> >> >> > unique way. In other words a javascript variable name "derived"
> from
> >> >> > the clientId.
> >> >> >
> >> >> > From JSF perspective, this is something related to the RenderKit,
> but
> >> >> > this is a common concept and looks like a good idea to standarize
> it.
> >> >> > Why? because sometimes a parent component could need a way to
> >> >> > reference its children not on the server but on the client to do
> >> >> > something (invoke a client side javascript function for example).
> >> >> >
> >> >> > The justification for this feature looks solid in my opinion. +1
> >> >> >
> >> >> > regards,
> >> >> >
> >> >> > Leonardo Uribe
> >> >> >
> >> >> >
> >> >> > 2015-01-14 10:40 GMT-05:00 Kito Mann <kito.mann_at_virtua.com
> <javascript:_e(%7B%7D,'cvml','kito.mann_at_virtua.com');>>:
> >> >> >> I like the widgetVar and clientKey approaches, but they assume
> >> >> >> there's
> >> >> >> a
> >> >> >> client-side JS widget for each component, which isn't the case for
> >> >> >> the
> >> >> >> standard components....
> >> >> >>
> >> >> >> On Tue, Jan 13, 2015 at 7:22 PM, Neil Griffin
> >> >> >> <neil.griffin_at_portletfaces.org
> <javascript:_e(%7B%7D,'cvml','neil.griffin_at_portletfaces.org');>> wrote:
> >> >> >>>
> >> >> >>> Liferay Faces has a similar feature that uses the attribute name
> >> >> >>> "clientKey" since it refers to a lookup in a key/value map in the
> >> >> >>> client-side JS.
> >> >> >>>
> >> >> >>> For example:
> >> >> >>>
> >> >> >>> <alloy:button
> onclick="Liferay.component('dialogKey1').toggle();">
> >> >> >>> <alloy:dialog clientKey="dialogKey1">
> >> >> >>> ...
> >> >> >>> </alloy:dialog>
> >> >> >>> </alloy:button>
> >> >> >>>
> >> >> >>>
> >> >> >>> On Jan 13, 2015, at 3:44 PM, manfred riem <
> manfred.riem_at_oracle.com
> <javascript:_e(%7B%7D,'cvml','manfred.riem_at_oracle.com');>>
> >> >> >>> wrote:
> >> >> >>>
> >> >> >>> Hi Çağatay,
> >> >> >>>
> >> >> >>> You willing and able to research on how to standardize this and
> >> >> >>> contribute
> >> >> >>> it back to the RI?
> >> >> >>>
> >> >> >>> Manfred
> >> >> >>>
> >> >> >>> On 1/13/15, 1:50 PM, Josh Juneau wrote:
> >> >> >>>
> >> >> >>> To All-
> >> >> >>>
> >> >> >>> I agree that a solution to this issue would require some
> assumption
> >> >> >>> on
> >> >> >>> how
> >> >> >>> things are structured. I prefer the technique utilized in
> >> >> >>> PrimeFaces,
> >> >> >>> whereby you are able to reference components via their widgetVar,
> >> >> >>> rather
> >> >> >>> than by ID. If effort were to be spent on some resolution to
> this
> >> >> >>> issue,
> >> >> >>> I'd rather see a standardized implementation of the widgetVar
> >> >> >>> solution
> >> >> >>> that
> >> >> >>> is present in the PrimeFaces JavaScript API.
> >> >> >>>
> >> >> >>> Just my 2 cents.
> >> >> >>>
> >> >> >>> Best Regards
> >> >> >>>
> >> >> >>> Josh Juneau
> >> >> >>> juneau001_at_gmail.com
> <javascript:_e(%7B%7D,'cvml','juneau001_at_gmail.com');>
> >> >> >>> http://jj-blogger.blogspot.com
> >> >> >>> https://www.apress.com/index.php/author/author/view/id/1866
> >> >> >>>
> >> >> >>>
> >> >> >>> On Mon, Jan 12, 2015 at 11:46 AM, manfred riem
> >> >> >>> <manfred.riem_at_oracle.com
> <javascript:_e(%7B%7D,'cvml','manfred.riem_at_oracle.com');>>
> >> >> >>> wrote:
> >> >> >>>>
> >> >> >>>> Hi Kito,
> >> >> >>>>
> >> >> >>>> It took it as the JavaScript functions getClientId() or
> >> >> >>>> getClientId('whatever') as it is said to be JS function.
> >> >> >>>>
> >> >> >>>> Regards,
> >> >> >>>> Manfred
> >> >> >>>>
> >> >> >>>>
> >> >> >>>>
> >> >> >>>> On 1/12/15, 11:33 AM, Kito Mann wrote:
> >> >> >>>>
> >> >> >>>> Is the JIRA issue just asking about EL evaluation (as the
> example
> >> >> >>>> implies), or is it referring to a real JavaScript function?
> >> >> >>>>
> >> >> >>>> In other words, are they asking about this:
> >> >> >>>>
> >> >> >>>> <h:button id="button1"
> >> >> >>>> onclick="button_setEnabled(#{getClientId('button2')},
> >> >> >>>> false);button_clicked(#{getClientId('button1')};return"... />
> >> >> >>>>
> >> >> >>>> or:
> >> >> >>>>
> >> >> >>>> <h:button id="button1"
> >> >> >>>> onclick="button_setEnabled(getClientId('button2'),
> >> >> >>>> false);button_clicked(getClientId('button1');return"... />
> >> >> >>>>
> >> >> >>>>
> >> >> >>>>
> >> >> >>>> On Mon, Jan 12, 2015 at 12:27 PM, manfred riem
> >> >> >>>> <manfred.riem_at_oracle.com
> <javascript:_e(%7B%7D,'cvml','manfred.riem_at_oracle.com');>>
> >> >> >>>> wrote:
> >> >> >>>>>
> >> >> >>>>> Hi Kito,
> >> >> >>>>>
> >> >> >>>>> Ughh, as you pointed out the client id is already there. My
> brain
> >> >> >>>>> just
> >> >> >>>>> stopped working :(.
> >> >> >>>>>
> >> >> >>>>> However I still want to mark this issue as "Won't fix" as there
> >> >> >>>>> is
> >> >> >>>>> no
> >> >> >>>>> way of knowing how a specific component is being rendered and
> >> >> >>>>> which
> >> >> >>>>> HTML
> >> >> >>>>> element corresponds to the client id of the component. And no I
> >> >> >>>>> don't want
> >> >> >>>>> to make any assumption on how it is structured.
> >> >> >>>>>
> >> >> >>>>> Thoughts?
> >> >> >>>>> Manfred
> >> >> >>>>>
> >> >> >>>>>
> >> >> >>>>> On 1/12/15, 11:13 AM, Kito Mann wrote:
> >> >> >>>>>
> >> >> >>>>> Manfred, can you articulate your objection more clearly? We
> >> >> >>>>> definitely
> >> >> >>>>> know the client id before the JavaScript executes, since it
> >> >> >>>>> executes
> >> >> >>>>> on the
> >> >> >>>>> client :-).
> >> >> >>>>>
> >> >> >>>>> ___
> >> >> >>>>>
> >> >> >>>>> Kito D. Mann | @kito99 | Author, JSF in Action
> >> >> >>>>> Virtua, Inc. | http://www.virtua.com | JSF/Java EE training
> and
> >> >> >>>>> consulting
> >> >> >>>>> http://www.JSFCentral.com | @jsfcentral
> >> >> >>>>> +1 203-998-0403
> >> >> >>>>>
> >> >> >>>>> * Listen to the Enterprise Java Newscast:
> >> >> >>>>> http://enterprisejavanews.com
> >> >> >>>>> * JSFCentral Interviews Podcast:
> >> >> >>>>> http://www.jsfcentral.com/resources/jsfcentralpodcasts/
> >> >> >>>>> * Sign up for the JSFCentral Newsletter:
> >> >> >>>>> http://oi.vresp.com/?fid=ac048d0e17
> >> >> >>>>>
> >> >> >>>>> On Mon, Jan 12, 2015 at 12:00 PM, manfred riem
> >> >> >>>>> <manfred.riem_at_oracle.com
> <javascript:_e(%7B%7D,'cvml','manfred.riem_at_oracle.com');>>
> >> >> >>>>> wrote:
> >> >> >>>>>>
> >> >> >>>>>> Hi all,
> >> >> >>>>>>
> >> >> >>>>>> I like to close
> >> >> >>>>>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-49
> as
> >> >> >>>>>> "Won't fix"
> >> >> >>>>>> as this request suffers from the chicken and the egg problem.
> In
> >> >> >>>>>> this
> >> >> >>>>>> particular case we cannot make sure the client id is rendered
> >> >> >>>>>> before the
> >> >> >>>>>> JavaScript executes.
> >> >> >>>>>>
> >> >> >>>>>> Thoughts?
> >> >> >>>>>> Manfred
> >> >> >>>>>>
> >> >> >>>>>
> >> >> >>>>
> >> >> >>>
> >> >> >>>
> >> >> >>
> >> >
> >> >
> >
> >
>
>
>
>

-- 
___
Kito D. Mann | @kito99 | Author, JSF in Action
Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and consulting
http://www.JSFCentral.com | @jsfcentral
+1 203-998-0403
* Listen to the Enterprise Java Newscast: *http://
<http://blogs.jsfcentral.com/JSFNewscast/>enterprisejavanews.com
<http://ww.enterprisejavanews.com>*
* JSFCentral Interviews Podcast:
http://www.jsfcentral.com/resources/jsfcentralpodcasts/
* Sign up for the JSFCentral Newsletter: http://oi.vresp.com/?fid=ac048d0e17