6 Replies Latest reply on Feb 21, 2011 7:45 AM by meehaw

    Trying to create a custom JSF component

    zergspirit

      Hi.


      I'm trying to create a simple (at least to begin) JSF component, but I'm having a hard time to make it work.
      I followed this tutorial but the configuration doesn't seem right.
      I tryed to dig a bit in the Wiki example but it confused me even more since I don't see any tld file in it.


      Why do you exactly need to create a JSF component then? A tld file? the 'component' lines in faces-config.xml? A Tag class or no tag class?
      At the moment, my component is simply not taking in account at all, not even generating an error.

        • 1. Re: Trying to create a custom JSF component
          zergspirit

          More specifically, here's the code I tried unsuccessfuly.


          1) I put a .tld file in my WEB-INF directory:



          <?xml version="1.0" encoding="UTF-8"?>
          <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
              version="2.0">
          
              <!--
                  THIS FILE IS NOT ACTUALLY USED at runtime.
                  Because we use Facelets (rather than JSP) all relevant definitions are in xx.taglib.xml
                  However this file enables code completion and validation for tag attributes in IDEA.
              -->
          
              <tlib-version>1.1</tlib-version>
          
              <short-name>metabook</short-name>
              <uri>myUri</uri>
          
              <tag>
                  <name>slabel</name>
                  <tag-class></tag-class><!-- No tag class needed - we aren't using JSP -->
                  <body-content>empty</body-content>
                  <attribute>
                      <name>label</name>
                  </attribute>
              </tag>
          
          </taglib>



          2) I added those lines to faces-config.xml
            


          <component>
                <component-type>simple.Label</component-type>
                <component-class>
                   com.lrb.modules.content.LabelComponent
                </component-class>
             </component>



          3) I created my component:



          public class LabelComponent extends UIOutput {
          
               private String label;
          
               public String getLabel() {
                    return label;
               }
          
               public void setLabel(String label) {
                    this.label = label;
               }
               
               @Override
               public String getRendererType() {
                    return null;
               }
               
               
               @Override
               public Object saveState(FacesContext context) {
                    Object values[] = new Object[2];
                    values[0] = super.saveState(context);
                    values[1] = label;
                    return ((Object) (values));
               }
          
               @Override
               public void restoreState(FacesContext context, Object state) {
                    Object values[] = (Object[]) state;
                    super.restoreState(context, values[0]);
                    label = (String) values[1];
               }
          
               public void encodeBegin(FacesContext context) throws IOException {
                    ResponseWriter writer = context.getResponseWriter();
                    writer.startElement("label", this);
                    writer.write(label);
                    writer.endElement("label");
                    writer.flush();
               }
               
               public String getFamily(){
                    return "simple.Label";
               }
          
          }



          4) I used my new component in a JSF page:



          <ui:composition xmlns="http://www.w3.org/1999/xhtml"
               ...
               xmlns:metabook="myUri"
               ...>
          <metabook:slabel label="TEST"/>
          
          ...
          



          Though, nothing appear, but no error occurs.
          I also tried to use a Tag class unsucessfully, by putting a tag-class property to the tld.





          • 2. Re: Trying to create a custom JSF component
            mail.micke

            Not that good at developing custom components, so I haven't really looked at the code you posted.


            But since you are using facelets you also need a taglib.xml file, tld are JSP specific. You can find examples here http://wiki.java.net/bin/view/Projects/FaceletsTaglibFiles .


            Then you'll have to register this in web.xml in the context-param facelets.LIBRARIES .


            Maybe that will fix your problem.

            • 3. Re: Trying to create a custom JSF component
              zergspirit

              Yep, that's exactly what I needed to do.
              I created a taglib file that I put in WEB-INF:



              <?xml version="1.0"?>
              <!DOCTYPE facelet-taglib PUBLIC
                      "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
                      "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
              
              <facelet-taglib>
                   <namespace>myUri</namespace>
                   <tag>
                        <tag-name>slabel</tag-name>
                      <component>
                          <component-type>simple.Label</component-type>
                      </component>
                   </tag>
              
              </facelet-taglib>



              Then I added this line in my web.xml file:


                 <context-param>
                    <param-name>facelets.LIBRARIES</param-name>
                    <param-value>/WEB-INF/metabook-taglib.xml</param-value>
                 </context-param>
              



              And that does it! Thanks!

              • 4. Re: Trying to create a custom JSF component
                dan.j.allen

                If you are developing JSF components, you should absolutely be using the Ajax4jsf CDK. In fact, it's almost insane not to use it (unless you have something that is even simpler to use, then how can one argue). It generates both JSP and Facelets taglibs.

                • 5. Re: Trying to create a custom JSF component
                  zergspirit

                  Ok, I'm going to look after that, but be ready to face some questions then maybe :)

                  • 6. Re: Trying to create a custom JSF component
                    meehaw

                    Hello,



                    Great tip,  Can you guys explain me why it works when I use it like:



                    <metabook:slabel label="TEST"/>





                    And it doesn't when used like (#{param.string} is a non empty string)




                    <metabook:slabel label="#{param.string}"/>



                    thx in advance,
                    Michal