users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] [jsr344-experts] Re: Re: Re: [1089-HTML5-data-*attributes] PROPOSAL

From: Andy Schwartz <andy.schwartz_at_oracle.com>
Date: Fri, 18 May 2012 15:37:20 -0400

Thanks for forwarding this, Ed. (And thanks for speaking up Paul!)

I see that we've got two different use cases in mind:

1. Specifying a arbitrary number of (possibly) dynamically generated
data-* attributes.
2. Specifying a small number of known data-* attributes.

Paul's JSON-based proposal was aimed at #1.

My counter-proposal was focused on #2.

Both proposals have one thing in common: they are both targeted at
populating a Map<String, Object> that contains name/value pairs to be
rendered as data-* attributes.

Regarding:

> PD> - it's not really dynamic. If you need to have conditionnal data-*
> PD> attributes, you would need to have a "rendered" attribute in the
> PD> <f:attribute> tag, and test your condition for each tag. A bit
> PD> overkill. Easier to build your JSON string in a Java method and pass it
> PD> to the "data" attribute.

If you are building up data-* name/value pairs in Java code, why would
you want to return a JSON string rather than a map? Populating a map
seems much cleaner than converting your name/value pairs to JSON/string
form. It also avoids having to go through JSON as an intermediate form
- ie. if you hand JSF a map, there is no need to parse JSON string back
into a map.

If we're adding a "data" attribute to the standard components, I would
think that the type should be Map<String, Object>, allowing EL bindings
like:

  <h:outputText data="#{foo.superCoolData}"/>

Where the the EL expression resolves to a method of the form:

  public Map<String, Object> getSuperCoolData()

That's not to say that our tag handlers couldn't support a JSON-like
syntax for specifying literal maps, eg. we could still support:

  <h:outputText data="{paul-rocks:true,andy-rocks:false}"/>

And covert this to a Map<String, Object> either at Facelet compilation
or apply time.

I suppose it would also be possible to support EL expressions within
these literal JSON-specified maps. Main thing is that we need to ensure
that the resulting value is a Map<String, Object>.

I understand Paul's concern about wanting to be able dynamically
populate the data-* attribute map. Exposing an attribute of type
Map<String, Object> would address this case. I have mixed feelings on
whether we should allow a literal JSON-based value to be specified
instead of just using EL to get at a map. I have even more mixed
feelings about whether the literal JSON-based value should allow inline
EL expressions.

Think the bottom line is that I am not totally opposed to any of this,
though I do think that we need to be somewhat careful here as we are
setting a precedent for other Map-based attributes.

Regarding:

> PD> - there is no possibility to nest data-* attributes

I found the nesting behavior particularly weird. Maybe it's just that
Ed's example was fairly complex:

> <h:outputText data="{ a : { b : { c : { d : e, f : g }, h, { i : { j : { k : l } } } } } }" value="foo"/>
>
> This would be rendered as
>
> <span data-a-b-c-d="e" data-a-b-c-f="g" data-a-b-c="h"
> data-a-b-c-i-j-k="l">foo</span>

Paul - can you comment on whether this sort of nesting is a common use
case for data-* attributes? (You mentioned working with Bootstrap...
does this show up there?)

If we do add Map<String, Object>-based "data" attributes to the standard
tags, is anyone else worried about the name "data" being a bit
confusing? For example, I could see folks confusing this:

  <h:dataTable data="#{myTableModel}">And this:

With this:

  <h:dataTable value="#{myTableModel}">

Perhaps a more explicit name ("dataAttributes"?) would reduce the chance
of confusion?

Andy

On 5/17/12 4:08 PM, Edward Burns wrote:
> It turns out that original requestor of the feature isn't happy with
> dropping the JSON, and here's his email to
> users_at_javaserverfaces-spec-public.java.net [1].
>
> On 17 May 2012, Paul Dijou wrote:
>
> PD> +1, it would be easier to read and understand. But I think there is
> PD> also problem with this approach :
>
> PD> - it's quite verbose
> PD> - there is no possibility to nest data-* attributes
> PD> - it's not really dynamic. If you need to have conditionnal data-*
> PD> attributes, you would need to have a "rendered" attribute in the
> PD> <f:attribute> tag, and test your condition for each tag. A bit
> PD> overkill. Easier to build your JSON string in a Java method and pass it
> PD> to the "data" attribute.
> PD> - how would you explain that there is some attributes in the tag itself
> PD> and other that need to use <f:attribute> ? Why not having all of them
> PD> either on the tag itself or using <f:attribute> ?
>
> PD> So I'm fine with having the <f:attribute> (or <f:dataAttribute>), it's
> PD> easy to use it for simple case. But I would also provide the "data"
> PD> attribute supporting JSON for real world applications having complex
> PD> data-* attributes cooperating with their Javascript.
>
> PD> About other topics, I agree the "data-*" attributes should always be
> PD> generated, even without a HTML5 doctype because it can be use by
> PD> Javascript more generally (see the Twitter Bootstrap project).
>
> PD> I also think that EL should be supported inside the JSON. The following
> PD> code should be ok :
>
> PD> <h:outputText value="Test" data="{toggle: #{bean.dataToggle}, hide:
> PD> #{bean.hide}}" />
>
> PD> I was talking with RichFaces guys about "data-*" attributes. Here is a
> PD> summary of our discussion : https://issues.jboss.org/browse/RF-12177
>
> Would anyone object to adding the JSON approach back in? Too
> Kitchen-Sink like?
>
> Ed
>
> [1] http://java.net/projects/javaserverfaces-spec-public/lists/users/archive/2012-05/message/17
>