8 Replies Latest reply on May 25, 2009 2:39 PM by Oguzhan YALCIN

    Dynamical Forms with Seam

    peter irmstadt Newbie

      Hi!


      I want to create a Seam project where the user can create custom forms with generic form elements (text field, text area, drop down (with extended lookup data, check boxes, ...).


      I worked a little bit with Seam yet but didn't find a beginning for that.


      How do I dynamically add controls to a page?
      What would you propose how to design the related beans?


      Thank you in advance!

        • 1. Re: Dynamical Forms with Seam
          Sascha Janz Master

          two options



          - you could generate the component tree by java code


          - you could generate a xhtml page from your program

          • 2. Re: Dynamical Forms with Seam
            peter irmstadt Newbie

            and how do I create the component tree by java code?

            • 3. Re: Dynamical Forms with Seam
              Sascha Janz Master
              use a binding for parent component

              e.g.

                             <h:panelGroup id="panelgroup"
                                  binding="#{Page.panelgroup}" style="height:800px">
                                  
                             </h:panelGroup>

              in the getter methods create your components and add them to panelgroup

              e.g.
              HtmlInputText intext =new HtmlInputText();
              panelgroup.getChildren().add(intext);
              • 4. Re: Dynamical Forms with Seam
                Oguzhan YALCIN Newbie

                Hi,
                I've used the same way with Sascha to generate a panelMenu.


                MenuHandler.java file:



                package com.taykos.helpers;
                
                import java.util.Iterator;
                import java.util.List;
                
                import javax.faces.component.UIComponent;
                import javax.persistence.EntityManager;
                import javax.persistence.PersistenceContext;
                
                import org.jboss.seam.ScopeType;
                import org.jboss.seam.annotations.In;
                import org.jboss.seam.annotations.Logger;
                import org.jboss.seam.annotations.Name;
                import org.jboss.seam.annotations.Scope;
                import org.jboss.seam.log.Log;
                import org.jboss.seam.security.Identity;
                import org.richfaces.component.html.HtmlPanelMenu;
                import org.richfaces.component.html.HtmlPanelMenuGroup;
                import org.richfaces.component.html.HtmlPanelMenuItem;
                
                import com.taykosdemo.entity.Module;
                
                @Name("menuHandler")
                @Scope(ScopeType.CONVERSATION)
                public class MenuHandler {
                
                     @In
                     PageParamHandler paramHandler;
                     @In
                     EntityManager entityManager;
                     @In
                     Identity identity;
                     
                     @Logger
                     Log log;
                
                     private HtmlPanelMenu panelMenu ;
                     
                     public void setPanelMenu(HtmlPanelMenu panelMenu) {
                          log.info("panelMenu Set");
                          this.panelMenu = panelMenu;
                     }
                
                     public HtmlPanelMenu getPanelMenu() {
                          log.info("panel Menu get");
                          panelMenu = new HtmlPanelMenu();
                          panelMenu.setExpandSingle(true);
                          panelMenu.setId("pnlMenu");
                          panelMenu.setMode("ajax");
                          panelMenu.setStyle("width:98%");
                          panelMenu.setRendered(identity.isLoggedIn());
                          panelMenu.setIconCollapsedTopGroup("triangle");
                          panelMenu.setIconExpandedTopGroup("triangleDown");
                          this.addMenu((byte)0, panelMenu);
                          return panelMenu;
                     }
                
                     private void addMenu(byte owner, UIComponent ownerComponent) {
                          @SuppressWarnings("unchecked")
                          List<Module> modules = (List<Module>)entityManager.createQuery("Select module from Module module where module.program.name=:program and module.owner=:owner").setParameter("program", paramHandler.getProgram()).setParameter("owner", owner).getResultList();
                          Iterator<Module> itModules = modules.iterator();
                          while (itModules.hasNext()) {
                               Module module = itModules.next();
                               if (module.isPlaceHolder()) {
                                    HtmlPanelMenuGroup grpPanel=new HtmlPanelMenuGroup();
                                    grpPanel.setLabel(module.getDisplayText());
                                    grpPanel.setParent(ownerComponent);
                                    this.addMenu(module.getRecordId(), grpPanel);
                                    ownerComponent.getChildren().add(grpPanel);
                               } else {
                                    HtmlPanelMenuItem itmPanel=new HtmlPanelMenuItem();
                                    itmPanel.setLabel(module.getDisplayText());
                                    itmPanel.setIcon(module.getImage());
                                    itmPanel.setParent(ownerComponent);
                                    ownerComponent.getChildren().add(itmPanel);
                               }
                          }
                
                     }
                
                }



                Menu.xhtml



                <f:view contentType="text/html" xmlns="http://www.w3.org/1999/xhtml"
                     xmlns:f="http://java.sun.com/jsf/core"
                     xmlns:rich="http://richfaces.org/rich" >
                     <rich:panelMenu binding="#{menuHandler.panelMenu}"></rich:panelMenu>
                </f:view>




                But i get this exception :



                Caused by: java.lang.IllegalStateException: Parent was not null, but this component not related
                     at javax.faces.component.UIComponentBase.eraseParent(UIComponentBase.java:524)
                     at javax.faces.component.UIComponentBase.access$300(UIComponentBase.java:92)
                     at javax.faces.component.UIComponentBase$ChildrenList.add(UIComponentBase.java:1871)
                     at javax.faces.component.UIComponentBase$ChildrenList.add(UIComponentBase.java:1846)
                     at com.taykos.helpers.MenuHandler.addMenu(MenuHandler.java:75)
                     at com.taykos.helpers.MenuHandler.addMenu(MenuHandler.java:68)
                     at com.taykos.helpers.MenuHandler.getPanelMenu(MenuHandler.java:54)
                     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                     at java.lang.reflect.Method.invoke(Method.java:597)
                     at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
                     at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
                     at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:77)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
                     at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
                     at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
                     at com.taykos.helpers.MenuHandler_$$_javassist_4.getPanelMenu(MenuHandler_$$_javassist_4.java)
                     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                     at java.lang.reflect.Method.invoke(Method.java:597)
                     at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
                     at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
                     at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
                     at org.jboss.el.parser.AstPropertySuffix.getValue(AstPropertySuffix.java:53)
                     at org.jboss.el.parser.AstValue.getValue(AstValue.java:67)
                     at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
                     at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
                     ... 84 more




                Anybody who stuck with this problem? ( and found the solution...)


                • 5. Re: Dynamical Forms with Seam
                  Ronald van Kuijk Apprentice

                  Sascha janz wrote on Mar 24, 2009 10:37:


                  two options


                  - you could generate the component tree by java code

                  - you could generate a xhtml page from your program


                  This (imo) conflicts with



                  where the user can create custom forms with generic form elements

                  I use XForms for this. Realy declarativly designing your forms

                  • 6. Re: Dynamical Forms with Seam
                    Ingo Jobling Master

                    peter irmstadt wrote on Mar 24, 2009 07:36:


                    Hi!

                    I want to create a Seam project where the user can create custom forms with generic form elements (text field, text area, drop down (with extended lookup data, check boxes, ...).

                    I worked a little bit with Seam yet but didn't find a beginning for that.

                    How do I dynamically add controls to a page?
                    What would you propose how to design the related beans?

                    Thank you in advance!


                    Hi,


                    I think you are heading for a world of pain if you try to accomplish this using Seam.


                    Have you looked at RCP (Rich Client Platform) as offered by Eclipse?



                    Ronald van Kuijk wrote on Mar 28, 2009 13:08:


                    I use XForms for this. Realy declarativly designing your forms


                    At the time of this writing, no widely used web browser supports XForms natively. However, various browser plugins and client-side extensions exist. ref




                    • 7. Re: Dynamical Forms with Seam
                      Emile Kok Newbie

                      Hi Oguzhan


                      you have a @Scope(ScopeType.CONVERSATION), but the limitation with the conversation scope is that it cannot be bound to a component in this fashion, the suggestion in the reference doc is to use event or session scope and inject the conversation.

                      • 8. Re: Dynamical Forms with Seam
                        Oguzhan YALCIN Newbie

                        I'm now working with the problem you've mentioned. But i couldn't find a proper solution for this problem. I just created another component using EVENT scope.Like the one below:



                        @Name("menu")
                        @Scope(ScopeType.EVENT)
                        public class Menu {
                             
                             private HtmlPanelMenu panelMenu=new HtmlPanelMenu();
                        
                             public void setPanelMenu(HtmlPanelMenu panelMenu) {
                                  this.panelMenu = panelMenu;
                             }
                        
                             public HtmlPanelMenu getPanelMenu() {
                                  return panelMenu;
                             }
                        
                        }



                        I have to generate the menu dynamically. I created another component with conversation scope. shown below:





                        @Name("menuHandler")
                        @Scope(ScopeType.CONVERSATION)
                        @AutoCreate
                        public class MenuHandler {
                        
                             @In
                             Identity identity;
                             
                             @In
                             EntityManager entityManager;
                             
                             @Logger
                             Log log;
                             
                             @RequestParameter
                             String process;
                        
                             @In @Out
                             Menu menu;
                        
                             
                             
                             private void addMenu(byte owner, UIComponent ownerComponent) {
                                  @SuppressWarnings("unchecked")
                                  List<Module> modules = (List<Module>) entityManager
                                            .createQuery(
                                                      "Select module from Module module where module.program.name=:program and module.owner=:owner order by module.order")
                                            .setParameter("program", this.getProgram())
                                            .setParameter("owner", owner).getResultList();
                                  Iterator<Module> itModules = modules.iterator();
                                  while (itModules.hasNext()) {
                                       Module module = itModules.next();
                                       if (module.isPlaceHolder()) {
                                            HtmlPanelMenuGroup grpPanel = new HtmlPanelMenuGroup();
                                            grpPanel.setLabel(module.getDisplayText());
                                            this.addMenu(module.getRecordId(), grpPanel);
                                            ownerComponent.getChildren().add(grpPanel);
                                            grpPanel.setParent(ownerComponent);
                                       } else {
                                            HtmlPanelMenuItem itmPanel = new HtmlPanelMenuItem();
                                            itmPanel.setLabel(module.getDisplayText());
                                            itmPanel.setIcon(module.getImage());
                                            itmPanel.setId(module.getName() + "menu");
                                            
                                            Expressions expression = Expressions.instance();
                                            HtmlActionParameter actionParam = new HtmlActionParameter();
                                            actionParam.setName("process" + module.getRecordId());
                                            actionParam.setValue(module.getName());
                                            actionParam.setAssignToBinding(expression
                                                      .createValueExpression("#{paramHandler.process}")
                                                      .toUnifiedValueExpression());
                                            HtmlConversationId conversationId=new HtmlConversationId();
                                            actionParam.getChildren().add(conversationId);
                                            conversationId.setParent(actionParam);
                                            itmPanel.setReRender("contentRegion");
                                            itmPanel.getChildren().add(actionParam);
                                            itmPanel.setDisabled(!identity.hasRole(this
                                                      .getProgram() + "-" 
                                                      + module.getName() + "-default-default"));
                                            actionParam.setParent(itmPanel);
                                            if (this.getProcess() == module.getName())
                                                 ((HtmlPanelMenuGroup) ownerComponent).setExpanded(true);
                                            ownerComponent.getChildren().add(itmPanel);
                                            itmPanel.setParent(ownerComponent);
                                       }
                                  }
                        
                             }
                        
                             @Create
                             public boolean createMenu() {
                                  HtmlPanelMenu panelMenu =new HtmlPanelMenu();
                                  panelMenu.setExpandSingle(true);
                                  panelMenu.setId("pnlMenu");
                                  panelMenu.setMode("none");
                                  panelMenu.setStyle("width:98%");
                                  panelMenu.setIconCollapsedTopGroup("triangle");
                                  panelMenu.setIconExpandedTopGroup("triangleDown");
                                  this.addMenu((byte) 0, panelMenu);
                                  panelMenu.setSelectedChild(this.getProcess() + "menu");
                                  menu.setPanelMenu(panelMenu);
                                  return true;
                             }
                             
                             public String getProgram(){
                                  HttpServletRequest request = ServletContexts.getInstance().getRequest();
                                  String Program = request.getRequestURI();
                                  int pageStart = Program.lastIndexOf("/") + 1;
                                  int pageEnd = Program.indexOf(".seam");
                                  Program = Program.substring(pageStart, pageEnd);
                                  return Program;
                             }
                             
                             public String getProcess(){
                                  if(this.process==null)return "default";
                                  else return this.process;
                             }
                        }
                        
                        
                        


                        The component above generates the menu(only if the createMenu method is called) how can I use these components for binding? I could not find a proper way. Thanks for your help.