RichFaces
  1. RichFaces
  2. RF-12177

"data-*" attributes in JSF components

    Details

    • Type: Feature Request Feature Request
    • Status: Resolved Resolved (View Workflow)
    • Priority: Minor Minor
    • Resolution: Out of Date Out of Date
    • Affects Version/s: 4.2.0.Final
    • Fix Version/s: None
    • Component/s: component
    • Security Level: Public (Everyone can see)
    • Labels:
    • Environment:
      Any
    • Similar Issues:
      Show 10 results 

      Description

      Hi there,

      First of all, sorry for all native English speakers, maybe your eyes will suffer from my grammar...

      A few days ago, I tried to use Bootstrap with JSF and faced quite an issue by not having any "data-*" attributes in JSF composents. Since Bootstrap, and more generally HTML5, relies a lot on this type of attribute, I was thinking it would be great to have them in JSF.

      My first tought was to propose the idea to RichFaces but then I aimed directly to JSF spec and here we are : http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1089

      Still, if you are okay for it, it would be great to discuss about this issue (maybe during a RichFaces meeting) in order to propose something more documented than just an idea to JSF spec. I could try to do that alone, but having feedback from JSF experts would be really better and result in more precise and clever proposal.

      So far, here are my thoughts about the problem :

      1) Only one new attribute "data" in JSF tags but it will create several "data-*" attributs in the HTML tag rendered depending on its value.

      2) Using JSON format to provide all key => value pairs. For example :

      data="{key1:'value1', key2:'value2'}"

      will generate data-key1="value1" data-key2="value2" in the HTML tag.

      3) Nesting attributes is allowed :

      data="{key1:{sub1:'value11',sub2:'value12'}, key2:'value2'}"

      will generate data-key1-sub1="value11" data-key1-sub2="value12" data-key2="value2"

      4) Wait, that means there is no way to have both data-key1="value1" and data-key1-sub1="value11" since "key1" key can only have one value : a real value (like "value1") or an array for nesting purpose (like

      "{sub1:'value11',sub2:'value12'}"

      .

      I think the best way to solve this is to have a specific key that will add no suffix even in a nested array. Let's call this key 'nil' or 'null' or wathever. So

      data="{key1:{nil:'value1', sub1:'value11', sub2:'value12'}}

      would generate data-key1="value1" data-key1-sub1="value11" data-key1-sub2="value12"

      Warning : this special key should no accept an array as value. Or conflicts would appears really quickly. Like having :

      data="{key1:{nil:{sub1:'value1'}, sub1:'value2'}}"

      would generate data-key1-sub1="value1" data-key1-sub1="value2"... Error !

      5) Of course, EL is allowed inside the JSON format. So, this is correct:

      data="{key1:{sub1:'#{bean.subvalue1}',sub2:'value12'}, key2:'#{bean.value2}'}"

      The return type of the EL must be String. But it can be plain String for a real value or an array in JSON format for nesting purpose.

      If bean.subvalue1 = "value11" and {{bean.value2 = "

      {sub1:'value21'}

      "}}, then the precedent example will generate : data-key1-sub1="value11" data-key1-sub2="value12" data-key2-sub1="value21"

      6) That was the first part. Next, what about a more Java centric approach ? "data" attribut could also accept a Map<String, Object> as value. For each Entry<String,Object>, it would add the String key as a suffix of "data" and calling Object#toString() method for the value. Only exception : if Object is an instance of Map, then it will nest the Map. The special key for non-suffix adding could be null value or an empty String.

      7) Perhaps, also, try to do combos ! Like having

      data="{key1:#{bean.value}}"

      where bean.value is a Map<String,Object> that should be interpreted as a JSON array for nesting purpose.

      8) Or combo fusion ! Having the possibility to add several entry point on the "data" attribute, separated by whitespace, before merging them all.

      For exemple, having :

      data="#{bean.jsonArray} #{bean.firstMap} #{bean.secondMap}"

      ,

      where bean.jsonArray is a String with JSON format, and bean.firstMap and bean.secondMap are Map<String,Object>. But it would be open door to unique attribute name conflicts.

      That's all. I'm really looking forward to any feedback or brainstorming in Irc. Maybe, just another idea, if I have time (or anyone else), try to submit some code doing that to RichFaces. It could help people who are using RichFaces 4 but won't be able to migrate to JSF 2.2 yet and still need "data-*" attributes.

      Thanks for reading.

        Activity

        Hide
        Lukáš Fryč
        added a comment - - edited

        We can easily achieve CSS-looking syntax:

        data="key1: 'value1'; key2: 'value2'"

        with making starting

        { and ending }

        symbols optional.

        Paul, are there any other frameworks, which allows you to use JSON to define data-* attributes?
        I'm curious if nesting attributes is common requirement. Could you point to some use case?

        Show
        Lukáš Fryč
        added a comment - - edited We can easily achieve CSS-looking syntax: data= "key1: 'value1'; key2: 'value2'" with making starting { and ending } symbols optional. Paul, are there any other frameworks, which allows you to use JSON to define data-* attributes? I'm curious if nesting attributes is common requirement. Could you point to some use case?
        Hide
        Paul Dijou
        added a comment -

        Thanks a lot for the better formatting Lukáš.

        HAML syntax is using quite a similar approach. It's not exactly JSON, but not far away. For example, having :

        %a{:data => {:tooltip => "A tooltip", :properties => {:effect => "fade", :positon => "bottom"} } }
        

        will generate :

        <a data-tooltip="A tooltip" data-properties-effect="fade" data-properties-position="bottom">
        

        See reference documentation : http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#html5_custom_data_attributes

        I don't know any other framework / syntax using JSON in "data" attribute so far.

        I guess nesting attributes are not the most important part. But still, can be great if you use the .data() method of jQuery (see : http://api.jquery.com/data/ ) since it will split all your "data-*" attributes around "-" caracter and make nested arrays.

        Also, it would allow you to write :

        data="key1: #{bean.allKey1subProperties}"
        
        Show
        Paul Dijou
        added a comment - Thanks a lot for the better formatting Lukáš. HAML syntax is using quite a similar approach. It's not exactly JSON, but not far away. For example, having : %a{:data => {:tooltip => "A tooltip" , :properties => {:effect => "fade" , :positon => "bottom" } } } will generate : <a data-tooltip= "A tooltip" data-properties-effect= "fade" data-properties-position= "bottom" > See reference documentation : http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#html5_custom_data_attributes I don't know any other framework / syntax using JSON in "data" attribute so far. I guess nesting attributes are not the most important part. But still, can be great if you use the .data() method of jQuery (see : http://api.jquery.com/data/ ) since it will split all your "data-*" attributes around "-" caracter and make nested arrays. Also, it would allow you to write : data= "key1: #{bean.allKey1subProperties}"
        Hide
        Lukáš Fryč
        added a comment - - edited

        Thanks Paul, it means that some people might be already familiar with the syntax.
        I would like have syntax as close as possible to other available implementations.

        The best would be reuse current parsers.

        In RichFaces, we already have JSON generator/parser, which could be reused.

        Show
        Lukáš Fryč
        added a comment - - edited Thanks Paul, it means that some people might be already familiar with the syntax . I would like have syntax as close as possible to other available implementations . The best would be reuse current parsers . In RichFaces, we already have JSON generator/parser , which could be reused.
        Hide
        Lukáš Fryč
        added a comment - - edited

        I'm thinking for which components we should actually enable support of data attributes.

        Should it be generically any components?
        Does it actually make sense to attach data-* e.g. to rich:calendar?

        Paul, what are your thoughts?

        Show
        Lukáš Fryč
        added a comment - - edited I'm thinking for which components we should actually enable support of data attributes. Should it be generically any components? Does it actually make sense to attach data-* e.g. to rich:calendar ? Paul, what are your thoughts?
        Hide
        Paul Dijou
        added a comment - - edited

        Since this type of attribute can be use for nearly anything, I think it would be hard to be sure that a component will never need such an attribute. Even the rich:calendar might need it for tooltip purpose using Bootstrap for example.

        The only components that might never need them are components that don't have any direct HTML generated (like a4j:repeat or a4j:poll) since the only purpose of the JSF "data" attribute would be to generate "data-*" attributes in the corresponding HTML tag. No HTML tag generated means no "data-*" attributes means no need for JSF "data" attribute.

        I agree with using current parsers if it's enough for what we want. I'm thinking about supporting EL and, maybe, using Map.

        Show
        Paul Dijou
        added a comment - - edited Since this type of attribute can be use for nearly anything, I think it would be hard to be sure that a component will never need such an attribute. Even the rich:calendar might need it for tooltip purpose using Bootstrap for example. The only components that might never need them are components that don't have any direct HTML generated (like a4j:repeat or a4j:poll ) since the only purpose of the JSF "data" attribute would be to generate "data-*" attributes in the corresponding HTML tag. No HTML tag generated means no "data-*" attributes means no need for JSF "data" attribute. I agree with using current parsers if it's enough for what we want. I'm thinking about supporting EL and, maybe, using Map.
        Hide
        Lukáš Fryč
        added a comment -

        Considering we should allow to attach data attribute nearly to any component, we could solve it generically: let CDK to generate data attribute to each component.

        But CDK don't know on which place in the generated DOM should be data attributes placed. It doesn't have to be root of the component's DOM.

        Thus we should attach the data attributes specifically, but serve them in unified manner - using newly introduced CDK attribute e.g. cdk:unfoldDataAttribute.

        cdk-template.xml
        <div id="..." cdk:unfoldDataAttribute="data">
            <span cdk:unfoldDataAttribute="anotherData" />
        </div>
        

        the attribute could be introduced to component code simply by extending interface, e.g. DataAttribute:

        AbstractMyComponent.java
        abstract class AbstractMyComponent implements DataAttribute {
            
            // or via another data attribute
            public abstract Object getAnotherData();
        }
        
        interface DataAttribute {
           Object getData();
        }
        

        the type of Object could be actually MethodExpression, String, or some JSON object (TBD).

        Show
        Lukáš Fryč
        added a comment - Considering we should allow to attach data attribute nearly to any component, we could solve it generically: let CDK to generate data attribute to each component. But CDK don't know on which place in the generated DOM should be data attributes placed. It doesn't have to be root of the component's DOM. Thus we should attach the data attributes specifically, but serve them in unified manner - using newly introduced CDK attribute e.g. cdk:unfoldDataAttribute . cdk-template.xml <div id= "..." cdk:unfoldDataAttribute= "data" > <span cdk:unfoldDataAttribute= "anotherData" /> </div> the attribute could be introduced to component code simply by extending interface, e.g. DataAttribute : AbstractMyComponent.java abstract class AbstractMyComponent implements DataAttribute { // or via another data attribute public abstract Object getAnotherData(); } interface DataAttribute { Object getData(); } the type of Object could be actually MethodExpression , String , or some JSON object (TBD).
        Hide
        Lukáš Fryč
        added a comment -

        We were discussing this idea on team meeting 2012-04-17, see 3. "data-* attributes in JSF" in minutes [1].

        We agreed on starting with a prototype: a simple sandbox input component, where we can try out some possibilities.

        [1] http://transcripts.jboss.org/meeting/irc.freenode.org/richfaces/2012/richfaces.2012-04-17-14.00.html

        Show
        Lukáš Fryč
        added a comment - We were discussing this idea on team meeting 2012-04-17, see 3. "data-* attributes in JSF" in minutes [1] . We agreed on starting with a prototype: a simple sandbox input component, where we can try out some possibilities. [1] http://transcripts.jboss.org/meeting/irc.freenode.org/richfaces/2012/richfaces.2012-04-17-14.00.html
        Hide
        Lukáš Fryč
        added a comment -

        AGREED: we will wait on the JSF support for data-* attributes (bleathem, 17:18:21)
        http://transcripts.jboss.org/meeting/irc.freenode.org/richfaces/2012/richfaces.2012-05-16-16.54.html

        Show
        Lukáš Fryč
        added a comment - AGREED: we will wait on the JSF support for data-* attributes (bleathem, 17:18:21) http://transcripts.jboss.org/meeting/irc.freenode.org/richfaces/2012/richfaces.2012-05-16-16.54.html
        Hide
        Brian Leathem
        added a comment -

        This is being addressed in JSF 2.2

        Show
        Brian Leathem
        added a comment - This is being addressed in JSF 2.2

          People

          • Assignee:
            Unassigned
            Reporter:
            Paul Dijou
          • Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: