5 Replies Latest reply on Sep 21, 2007 3:51 PM by phpguy99

    Custom component development

    dhalupa

      Hi there,
      I am having problem with my simple custom component which consists of two a4j buttons. I have left out most of the code for simplicity. The output is quite strange. Two buttons are rendered without any html layout, and after that the same buttons are rendered again but this time, the table layout defined in encodeEnd method is also outputed. I have attached output further down the post. What am I doing wrong? Is it even possible to create custom components this way or do I have to use CDK?

      public class UIButtonPanel extends UICommand implements ActionListener {
       public static final String COMPONENT_TYPE = "hr.virtus.ButtonPanel";
      
      
       @Override
       public void encodeEnd(FacesContext context) throws IOException {
       if (task != null && getChildCount() == 0) {
       generateButton("btnSave", "Save");
       generateButton("btnCancel", "Cancel");
       }
       ResponseWriter out = context.getResponseWriter();
       out.startElement("div",this);
       out.writeAttribute("id", getClientId(context), null);
       if (getChildCount() != 0) {
       out.write("<table cellpading='4' cellspacing='0'>");
       for (Object button : getChildren()) {
       out.write("<tr><td>");
       ((UIComponent)button).encodeEnd(context);
       out.write("</td></tr>");
       }
       out.write("</table>");
       }
       out.endElement("div");
      
       }
      
       @SuppressWarnings("unchecked")
       private void generateButton(String id, String label) {
       HtmlAjaxCommandButton btn = new HtmlAjaxCommandButton();
       btn.setId(id);
       btn.addActionListener(this);
       btn.setValue(label);
       btn.setStyle("width:150px");
       getChildren().add(btn);
       }
      
       public void processAction(ActionEvent actionEvent)
       throws AbortProcessingException {
      
       }
      }
      


      Output...
      
      <html>
      <head>
      <script type='text/javascript' src='/alfresco/faces/a4j_3_1_0org.ajax4jsf.javascript.AjaxScript'></script>
      </head>
      <body>
      <td valign="top"><input id="browse:btnSave" name="browse:btnSave"
       onclick="A4J.AJAX.Submit('_viewRoot',null,event,{'parameters':{'browse:btnSave':'browse:btnSave'} ,'actionUrl':'/alfresco/faces/jsp/task-management/test.jspx'} );return false;"
       value="Save" style="width: 150px" type="button" /><input id="browse:btnCancel" name="browse:btnCancel"
       onclick="A4J.AJAX.Submit('_viewRoot',null,event,{'parameters':{'browse:btnCancel':'browse:btnCancel'} ,'actionUrl':'/alfresco/faces/jsp/task-management/test.jspx'} );return false;"
       value="Cancel" style="width: 150px" type="button" />
      <div id="button-panel">
      <table cellpading='4' cellspacing='0'>
       <tr>
       <td><input id="browse:btnSave" name="browse:btnSave"
       onclick="A4J.AJAX.Submit('_viewRoot',null,event,{'parameters':{'browse:btnSave':'browse:btnSave'} ,'actionUrl':'/alfresco/faces/jsp/task-management/test.jspx'} );return false;"
       value="Save" style="width: 150px" type="button" /></td>
       </tr>
       <tr>
       <td><input id="browse:btnCancel" name="browse:btnCancel"
       onclick="A4J.AJAX.Submit('_viewRoot',null,event,{'parameters':{'browse:btnCancel':'browse:btnCancel'} ,'actionUrl':'/alfresco/faces/jsp/task-management/test.jspx'} );return false;"
       value="Cancel" style="width: 150px" type="button" /></td>
       </tr>
      </table>
      </div>
      </td>
      <!-- MYFACES JAVASCRIPT -->
      
      </body>
      </html>


        • 1. Re: Custom component development
          alexsmirnov

          JSF call encodeChildren() method for encode children components ( this is a first encoding of the buttons ), you call encode methods again in the encodeEnd() .
          For a properly encoding, try to use encodeBegin/encodeChildren/encodeEnd methode, or, for a JSF 1.2 - encodeAll.
          As a other workaround , use facets map instead of children.

          • 2. Re: Custom component development
            dhalupa

            Thanks a lot for pushing me through this one.. I guess I was suffering from some kind of blackout, sinci I was totally convinced that encodeChildren does not gets called unless rendersChildren is explicitly set to true.

            Thanks again,

            Denis

            • 3. Re: Custom component development
              phpguy99

              I hope this is not off-topic. I have a general question regarding custom component development.
              How difficult is it to develop one? Say that I want to develop a calendar component that supports both date and time. And the assumption is I know javascript/html very well and fair knowledge of java. And in your experience what obstacles will I face? thanks so much.

              • 4. Re: Custom component development

                 

                "phpguy99" wrote:
                I hope this is not off-topic. I have a general question regarding custom component development.
                How difficult is it to develop one? Say that I want to develop a calendar component that supports both date and time. And the assumption is I know javascript/html very well and fair knowledge of java. And in your experience what obstacles will I face? thanks so much.


                This depends of the concrete component complexity and and the methodology you use.

                Some kind of achievement table. Using our CDK we made:
                rich:insert in 2 hours
                rich:virtualEarth in 1 day
                rich:effect in 2 days

                At the same time, the rich:calendar took 1.5 month ; rich:scrollableDataGrid - about 5 months

                If the component has pure output type - it is just a toy. Especially with CDK. No special knowledge is required. However, if component has input, Ajax interactivity, state saving and other attributes JSF component, the requirements to the Developer are increases significantly. And, this is not about Javascript and Java. It is about expertise in the JSF. Knowledge in the area that end application developers never face with.

                If you develop the component for particular project and the set of requirements is predetermined, you can shortcut the way. However, if you start to thing about unification, the time will increase.

                In many cases if you want to implement the particular functionality for the concrete project, using a composition approach might be a choice.
                Composition is something that you build from the existing components.
                Facelets help a lot to create compositions. Using composition does not strongly require to decouple the logic of its implementation from the rest logic of the application. It might be bad or good depends of the particular case.


                • 5. Re: Custom component development
                  phpguy99

                  Thank you so much - your answer really gives me some idea. :)