8 Replies Latest reply on Aug 3, 2007 9:03 PM by amontobin

    Ajax Simple Calculator ie dynamic ajax

    amontobin

      Hi,

      I would like to develop my Ajax simple calculator but i've got some troubles with HtmlAjaxSupport. How do you use it ?
      i've called theses methods setReRender, setEvent, setParent but nothing is done.
      My Ajax Button (HtmlAjaxCommandButton) seems to work.

      Thank for your help,

      Sebastien Boutte

      Here is my code :

      // Calculator with Ajax

      <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
      <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
      <html>
       <head>
       <title>Hello World</title>
       </head>
       <body>
       <f:view>
       <h:form id="form">
       <h:panelGrid binding="#{CalculatorBeanWithAjax.buttonPanelGrid}"/>
       <h:panelGrid id="panel" binding="#{CalculatorBeanWithAjax.panelGrid}"/>
       <h:panelGrid id="panel1" binding="#{CalculatorBeanWithAjax.totalPanelGrid}"/>
       </h:form>
       </f:view>
       </body>
      </html>
      


      package com.calculator;
      
      import java.util.HashMap;
      import java.util.Iterator;
      import java.util.Set;
      
      import javax.faces.application.Application;
      import javax.faces.component.html.HtmlCommandButton;
      import javax.faces.component.html.HtmlInputText;
      import javax.faces.component.html.HtmlOutputText;
      import javax.faces.component.html.HtmlPanelGrid;
      import javax.faces.context.FacesContext;
      import javax.faces.el.MethodBinding;
      
      import org.ajax4jsf.ajax.html.HtmlAjaxCommandButton;
      import org.ajax4jsf.ajax.html.HtmlAjaxSupport;
      
      public class CalculatorBeanWithAjax extends Object {
       private HtmlPanelGrid buttonGrid;
      
       private HtmlPanelGrid grid;
      
       private HtmlPanelGrid totalGrid;
      
       private HashMap data = new HashMap();
       private int i = 0;
      
       public HtmlPanelGrid getButtonPanelGrid() {
       if (buttonGrid == null) {
       Application app = FacesContext.getCurrentInstance().getApplication();
       buttonGrid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
      
       MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding("#{CalculatorBeanWithAjax.add}", null);
      
       HtmlAjaxCommandButton button1 = (HtmlAjaxCommandButton) app.createComponent(HtmlAjaxCommandButton.COMPONENT_TYPE);
       button1.setValue("Add");
       button1.setAction(mb);
       button1.setType("submit");
       button1.setReRender("form:panel");
      
       HtmlCommandButton button2 = (HtmlCommandButton) app.createComponent(HtmlCommandButton.COMPONENT_TYPE);
       button2.setValue("Remove");
       button2.setAction(mb);
      
       buttonGrid.getChildren().add(button1);
       buttonGrid.getChildren().add(button2);
       }
       return buttonGrid;
       }
      
       public String add() {
       Application app = FacesContext.getCurrentInstance().getApplication();
       HtmlInputText text = (HtmlInputText) app.createComponent(HtmlInputText.COMPONENT_TYPE);
       text.setValueBinding("value", app.createValueBinding("#{CalculatorBeanWithAjax.data['" + i + "']}"));
      
       HtmlAjaxSupport ajaxSupport = (HtmlAjaxSupport) app.createComponent(HtmlAjaxSupport.COMPONENT_TYPE);
       ajaxSupport.setEvent("onchange");
       ajaxSupport.setReRender("form:panel1");
       ajaxSupport.setParent(text);
      
       getPanelGrid().getChildren().add(text);
       data.put(Integer.toString(i), 0);
       i++;
       return null;
       }
      
       public HtmlPanelGrid getPanelGrid() {
       if (grid == null) {
       Application app = FacesContext.getCurrentInstance().getApplication();
       grid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
       }
       return grid;
       }
      
       public void setPanelGrid(HtmlPanelGrid grid) {
       this.grid = grid;
       }
      
       public HtmlPanelGrid getTotalPanelGrid() {
       if (totalGrid == null) {
       Application app = FacesContext.getCurrentInstance().getApplication();
       totalGrid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
      
       HtmlOutputText text = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
       text.setValueBinding("value", app.createValueBinding("#{CalculatorBeanWithoutAjax.total}"));
      
       totalGrid.getChildren().add(text);
       }
       return totalGrid;
       }
      
       public int getTotal() {
       int total = 0;
       Set s = getData().keySet();
       for (Iterator i = s.iterator(); i.hasNext();) {
       String key = (String) i.next();
       total += ((Integer) getData().get(key)).intValue();
       }
       return total;
       }
      
       public void setTotalPanelGrid(HtmlPanelGrid totalGrid) {
       this.totalGrid = totalGrid;
       }
      
       public HashMap getData() {
       return data;
       }
      }
      


        • 1. Re: Ajax Simple Calculator ie dynamic ajax

          Very first impression without digging into the code.
          You have to define the id's of the input component (as well as command component) explicitly if you create those component dynamically. Otherwise, they will not be processed. This is true also for naming containers components that contain the input component.
          This is not about Ajax, but about JSF in general.

          • 2. Re: Ajax Simple Calculator ie dynamic ajax
            amontobin

            Hi Sergey,

            I try what you say with defining an id for each dynamic object created.
            (UIViewRoot.createUniqueId()).
            But the second time, i push the add button, i've got this exception :
            javax.faces.el.EvaluationException: AjaxUpdate component not found for id: :form:_id4
            I found that this one comes from the id assigned to HTMLAjaxSupport component.
            Have you any idea ?

            Thanks,

            Sebastien

            <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
            <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
            <html>
             <head>
             <title>Hello World</title>
             </head>
             <body>
             <f:view>
             <h:form id="form">
             <h:panelGrid id="panel1" binding="#{CalculatorBeanWithAjax.buttonPanelGrid}"/>
             <h:panelGrid id="panel2" binding="#{CalculatorBeanWithAjax.panelGrid}"/>
             <h:panelGrid id="panel3" binding="#{CalculatorBeanWithAjax.totalPanelGrid}"/>
             </h:form>
             </f:view>
             </body>
            </html>
            


            package com.calculator;
            
            import java.util.HashMap;
            import java.util.Iterator;
            import java.util.Set;
            
            import javax.faces.application.Application;
            import javax.faces.component.UIViewRoot;
            import javax.faces.component.html.HtmlCommandButton;
            import javax.faces.component.html.HtmlInputText;
            import javax.faces.component.html.HtmlOutputText;
            import javax.faces.component.html.HtmlPanelGrid;
            import javax.faces.context.FacesContext;
            import javax.faces.el.MethodBinding;
            
            import org.ajax4jsf.ajax.html.HtmlAjaxCommandButton;
            import org.ajax4jsf.ajax.html.HtmlAjaxSupport;
            
            public class CalculatorBeanWithAjax extends Object {
             private HtmlPanelGrid buttonGrid;
            
             private HtmlPanelGrid grid;
            
             private HtmlPanelGrid totalGrid;
            
             private HashMap data = new HashMap();
             private int i = 0;
            
             public HtmlPanelGrid getButtonPanelGrid() {
             if (buttonGrid == null) {
             UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
             Application app = FacesContext.getCurrentInstance().getApplication();
             buttonGrid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
             //buttonGrid.setId(uiViewRoot.createUniqueId());
            
             MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding("#{CalculatorBeanWithAjax.add}", null);
            
             HtmlAjaxCommandButton button1 = (HtmlAjaxCommandButton) app.createComponent(HtmlAjaxCommandButton.COMPONENT_TYPE);
             button1.setValue("Add");
             button1.setAction(mb);
             button1.setType("submit");
             button1.setReRender("form:panel2");
             button1.setId(uiViewRoot.createUniqueId());
            
             HtmlCommandButton button2 = (HtmlCommandButton) app.createComponent(HtmlCommandButton.COMPONENT_TYPE);
             button2.setValue("Remove");
             button2.setAction(mb);
             button2.setId(uiViewRoot.createUniqueId());
            
             buttonGrid.getChildren().add(button1);
             buttonGrid.getChildren().add(button2);
             }
             return buttonGrid;
             }
            
             public String add() {
             UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
             Application app = FacesContext.getCurrentInstance().getApplication();
             HtmlInputText text = (HtmlInputText) app.createComponent(HtmlInputText.COMPONENT_TYPE);
             text.setId(uiViewRoot.createUniqueId());
             text.setValueBinding("value", app.createValueBinding("#{CalculatorBeanWithAjax.data['" + i + "']}"));
            
             HtmlAjaxSupport ajaxSupport = (HtmlAjaxSupport) app.createComponent(HtmlAjaxSupport.COMPONENT_TYPE);
             ajaxSupport.setEvent("onchange");
             ajaxSupport.setReRender("form:panel3");
             ajaxSupport.setParent(text);
             ajaxSupport.setId(uiViewRoot.createUniqueId());
            
             getPanelGrid().getChildren().add(text);
             data.put(Integer.toString(i), 0);
             i++;
             return null;
             }
            
             public HtmlPanelGrid getPanelGrid() {
             if (grid == null) {
             UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
             Application app = FacesContext.getCurrentInstance().getApplication();
             grid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
             //grid.setId(uiViewRoot.createUniqueId());
             }
             return grid;
             }
            
             public void setPanelGrid(HtmlPanelGrid grid) {
             this.grid = grid;
             }
            
             public HtmlPanelGrid getTotalPanelGrid() {
             if (totalGrid == null) {
             UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
             Application app = FacesContext.getCurrentInstance().getApplication();
             totalGrid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
             //totalGrid.setId(uiViewRoot.createUniqueId());
            
             HtmlOutputText text = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
             text.setValueBinding("value", app.createValueBinding("#{CalculatorBeanWithoutAjax.total}"));
             text.setId(uiViewRoot.createUniqueId());
            
             totalGrid.getChildren().add(text);
             }
             return totalGrid;
             }
            
             public int getTotal() {
             int total = 0;
             Set s = getData().keySet();
             for (Iterator i = s.iterator(); i.hasNext();) {
             String key = (String) i.next();
             total += ((Integer) getData().get(key)).intValue();
             }
             return total;
             }
            
             public void setTotalPanelGrid(HtmlPanelGrid totalGrid) {
             this.totalGrid = totalGrid;
             }
            
             public HashMap getData() {
             return data;
             }
            }
            


            • 3. Re: Ajax Simple Calculator ie dynamic ajax

               

              "amontobin" wrote:
              d for each dynamic object created.
              (UIViewRoot.createUniqueId()).
              But the second time, i push the add button, i've got this exception :
              javax.faces.el.EvaluationException: AjaxUpdate component not found for id: :form:_id4


              This is exactly the problem I speak about. You should not use UIViewRoot.createUniqueId(), but define your own ids.

              • 4. Re: Ajax Simple Calculator ie dynamic ajax
                amontobin

                Ok. I understand , i try to create my own ids but i've got the same exception.
                The first time i click on the button, the first dynamic text field is displayed.
                The second time, i've got an exception telling that the id of the first HtmlAjaxSupport dynamic component is not found.

                • 5. Re: Ajax Simple Calculator ie dynamic ajax
                  amontobin

                  Ok found. the solution the line below was missing.

                  getPanelGrid().getChildren().add(ajaxSupport);

                  Now, it works. I can add dynamically all text fields.
                  But when i change the value of one of them, the total is not recalulated.

                  Any idea ?

                  • 6. Re: Ajax Simple Calculator ie dynamic ajax
                    amontobin

                    Is there somewhere an example with source code on how to use ajax with dynmaic components ?
                    Found nothing on google

                    • 7. Re: Ajax Simple Calculator ie dynamic ajax
                      amontobin

                      up

                      • 8. Re: Ajax Simple Calculator ie dynamic ajax
                        amontobin

                        Just found the error, it works perfectly now :
                        I forgot to change a value binding in the code.

                        Sergey, i think it would be valuable to have a such example in your online demos.

                        As i've not found any source code on how to create dynamic components and especially dynamic ajax component, i post the code below :

                        <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
                        <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
                        <html>
                         <head>
                         <title>Hello World</title>
                         </head>
                         <body>
                         <f:view>
                         <h:form id="form">
                         <h:panelGrid id="panel1" binding="#{CalculatorBeanWithAjax.buttonPanelGrid}"/>
                         <h:panelGrid id="panel2" binding="#{CalculatorBeanWithAjax.panelGrid}"/>
                         <h:panelGrid id="panel3" binding="#{CalculatorBeanWithAjax.totalPanelGrid}"/>
                         </h:form>
                         </f:view>
                         </body>
                        </html>
                        


                        package com.calculator;
                        
                        import java.util.HashMap;
                        import java.util.Iterator;
                        import java.util.Set;
                        
                        import javax.faces.application.Application;
                        import javax.faces.component.UIViewRoot;
                        import javax.faces.component.html.HtmlCommandButton;
                        import javax.faces.component.html.HtmlInputText;
                        import javax.faces.component.html.HtmlOutputText;
                        import javax.faces.component.html.HtmlPanelGrid;
                        import javax.faces.context.FacesContext;
                        import javax.faces.el.MethodBinding;
                        
                        import org.ajax4jsf.ajax.html.HtmlAjaxCommandButton;
                        import org.ajax4jsf.ajax.html.HtmlAjaxSupport;
                        
                        public class CalculatorBeanWithAjax extends Object {
                         private HtmlPanelGrid buttonGrid;
                        
                         private HtmlPanelGrid grid;
                        
                         private HtmlPanelGrid totalGrid;
                        
                         private HashMap data = new HashMap();
                         private int i = 0;
                        
                         private HtmlOutputText text1;
                        
                         public HtmlPanelGrid getButtonPanelGrid() {
                         if (buttonGrid == null) {
                         UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
                         Application app = FacesContext.getCurrentInstance().getApplication();
                         buttonGrid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
                         // buttonGrid.setId(uiViewRoot.createUniqueId());
                        
                         MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding("#{CalculatorBeanWithAjax.add}", null);
                        
                         HtmlAjaxCommandButton button1 = (HtmlAjaxCommandButton) app.createComponent(HtmlAjaxCommandButton.COMPONENT_TYPE);
                         button1.setValue("Add");
                         button1.setAction(mb);
                         button1.setType("submit");
                         button1.setReRender("form:panel2");
                         button1.setId("id1");
                        
                         HtmlCommandButton button2 = (HtmlCommandButton) app.createComponent(HtmlCommandButton.COMPONENT_TYPE);
                         button2.setValue("Remove");
                         button2.setAction(mb);
                         button2.setId("id2");
                        
                         buttonGrid.getChildren().add(button1);
                         buttonGrid.getChildren().add(button2);
                         }
                         return buttonGrid;
                         }
                        
                         public String add() {
                         UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
                         Application app = FacesContext.getCurrentInstance().getApplication();
                         HtmlInputText text = (HtmlInputText) app.createComponent(HtmlInputText.COMPONENT_TYPE);
                         text.setId("ida" + i);
                         text.setValueBinding("value", app.createValueBinding("#{CalculatorBeanWithAjax.data['" + i + "']}"));
                        
                         MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding("#{CalculatorBeanWithAjax.test}", null);
                        
                         HtmlAjaxSupport ajaxSupport = (HtmlAjaxSupport) app.createComponent(HtmlAjaxSupport.COMPONENT_TYPE);
                         ajaxSupport.setEvent("onchange");
                         ajaxSupport.setReRender("form:id3");
                         ajaxSupport.setParent(text);
                         //ajaxSupport.setAction(mb);
                         ajaxSupport.setId("idb" + i);
                        
                         getPanelGrid().getChildren().add(text);
                         text.getChildren().add(ajaxSupport);
                         data.put(Integer.toString(i), 0);
                         i++;
                         return null;
                         }
                        
                         public String test() {
                         text1.setValue("1000");
                         return null;
                         }
                        
                         public HtmlPanelGrid getPanelGrid() {
                         if (grid == null) {
                         UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
                         Application app = FacesContext.getCurrentInstance().getApplication();
                         grid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
                         // grid.setId(uiViewRoot.createUniqueId());
                         }
                         return grid;
                         }
                        
                         public void setPanelGrid(HtmlPanelGrid grid) {
                         this.grid = grid;
                         }
                        
                         public HtmlPanelGrid getTotalPanelGrid() {
                         if (totalGrid == null) {
                         UIViewRoot uiViewRoot = FacesContext.getCurrentInstance().getViewRoot();
                         Application app = FacesContext.getCurrentInstance().getApplication();
                         totalGrid = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
                         // totalGrid.setId(uiViewRoot.createUniqueId());
                        
                         text1 = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
                         text1.setValueBinding("value", app.createValueBinding("#{CalculatorBeanWithAjax.total}"));
                         text1.setId("id3");
                         totalGrid.getChildren().add(text1);
                         }
                         return totalGrid;
                         }
                        
                         public int getTotal() {
                         int total = 0;
                         Set s = getData().keySet();
                         for (Iterator i = s.iterator(); i.hasNext();) {
                         String key = (String) i.next();
                         total += ((Integer) getData().get(key)).intValue();
                         }
                         return total;
                         }
                        
                         public void setTotalPanelGrid(HtmlPanelGrid totalGrid) {
                         this.totalGrid = totalGrid;
                         }
                        
                         public HashMap getData() {
                         return data;
                         }
                        
                        
                        }