You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by Jacques Le Roux <ja...@les7arts.com> on 2015/06/18 06:21:38 UTC

Re: svn commit: r1686116 - in /ofbiz/trunk: framework/common/widget/ framework/webtools/widget/ framework/widget/dtd/ framework/widget/src/org/ofbiz/widget/artifact/ framework/widget/src/org/ofbiz/widget/model/ framework/widget/src/org/ofbiz/widget/rendere...

I very like it thanks Nicolas!

I'd also like to thanks Adam for the prior idea and effort on the grid element and Christian for pushing things :)

I wonder though if we are not missing a definitive reference for widgets like we have 
https://cwiki.apache.org/confluence/display/OFBADMIN/Mini+Language+-+minilang+-+simple-method+-+Reference
It could be built from the auto-completion, with an opportunity to complete and update it (the documentation in the XSDs is a must to get more 
collaboration from new comers on this)

Kudos guys, we are heading in the right direction. I mean to replace as much as possible FTL in backend, and even ecommerce when possible... ;)

OK seems that I have more new things to learn/review

Jacques

Le 17/06/2015 23:50, nmalin@apache.org a écrit :
> Author: nmalin
> Date: Wed Jun 17 21:50:27 2015
> New Revision: 1686116
>
> URL: http://svn.apache.org/r1686116
> Log:
> Improve widget-form with four elements : include-form, include-grid, include-menu, include-screen to offert more flexibility to define complex display. The main purpose is to complete the screen widget capacity to replace ftl screen.
> With these elements, example component have a new FindExample search screen to select the display list type with a example of :
>     * include-form : list examples with their features
>     * include-screen : list examples with their items
>     * include-grid : list examples with their status history
> The element include-menu is present on FindUtilCache screen. Also a new CommonInlineBarMenu menu type to display menu with specific purpose (in-line) is now present and with this logic adding in-line-bar css class on themes thomawak and flatgrey.
>
> This patch is combinate Issues :
>   * OFBIZ-6502 Add support for form/grid embedding within grids
>   * OFBIZ-6501 Add support for screen embedding inside grids
>   * OFBIZ-6404 Allow form/grid widget hyperlinks to be grouped into a single column
> sub-tasks of master issue OFBIZ-6314 Widget Refactoring - Placeholder issue
>
> Thanks to Christian and Adrian for their time
>
> Modified:
>      ofbiz/trunk/framework/common/widget/CommonMenus.xml
>      ofbiz/trunk/framework/webtools/widget/CacheForms.xml
>      ofbiz/trunk/framework/webtools/widget/Menus.xml
>      ofbiz/trunk/framework/widget/dtd/widget-form.xsd
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
>      ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
>      ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml
>      ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml
>      ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml
>      ofbiz/trunk/specialpurpose/example/widget/example/ExampleScreens.xml
>      ofbiz/trunk/themes/flatgrey/webapp/flatgrey/maincss.css
>      ofbiz/trunk/themes/tomahawk/webapp/tomahawk/css/style.css
>
> Modified: ofbiz/trunk/framework/common/widget/CommonMenus.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/widget/CommonMenus.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/common/widget/CommonMenus.xml (original)
> +++ ofbiz/trunk/framework/common/widget/CommonMenus.xml Wed Jun 17 21:50:27 2015
> @@ -31,4 +31,6 @@ under the License.
>             menu-container-style="button-bar tab-bar" default-selected-style="selected"/>
>   
>       <menu name="CommonButtonBarMenu" type="simple" menu-container-style="button-bar" default-widget-style="buttontext"/>
> +
> +    <menu name="CommonInlineBarMenu" type="simple" menu-container-style="in-line-bar" default-widget-style="linktext"/>
>   </menus>
>
> Modified: ofbiz/trunk/framework/webtools/widget/CacheForms.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/CacheForms.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/webtools/widget/CacheForms.xml (original)
> +++ ofbiz/trunk/framework/webtools/widget/CacheForms.xml Wed Jun 17 21:50:27 2015
> @@ -39,21 +39,7 @@ under the License.
>           <field name="useSoftReference" title="${uiLabelMap.WebtoolsUseSoftRef}" sort-field="true"><display/></field>
>           <field name="useFileSystemStore" title="${uiLabelMap.WebtoolsUseFileStore}" sort-field="true"><display/></field>
>           <field name="cacheMemory" title="${uiLabelMap.WebtoolsCacheMemory}" sort-field="true"><display/></field>
> -        <field name="administration" title=" " widget-style="buttontext" use-when="hasUtilCacheEdit">
> -            <hyperlink description="${uiLabelMap.WebtoolsElements}" target="FindUtilCacheElements">
> -                <parameter param-name="UTIL_CACHE_NAME" from-field="cacheName"/>
> -            </hyperlink>
> -        </field>
> -        <field name="admin_edit" title=" " widget-style="buttontext" use-when="hasUtilCacheEdit">
> -            <hyperlink description="${uiLabelMap.CommonEdit}" target="EditUtilCache">
> -                <parameter param-name="UTIL_CACHE_NAME" from-field="cacheName"/>
> -            </hyperlink>
> -        </field>
> -        <field name="admin_clear" title=" " widget-style="buttontext" use-when="hasUtilCacheEdit">
> -            <hyperlink description="${uiLabelMap.CommonClear}" target="FindUtilCacheClear">
> -                <parameter param-name="UTIL_CACHE_NAME" from-field="cacheName"/>
> -            </hyperlink>
> -        </field>
> +        <field name="cacheMenu" title=" " use-when="hasUtilCacheEdit"><include-menu name="ListCacheForm" location="component://webtools/widget/Menus.xml"/></field>
>       </form>
>   
>       <form name="ListCacheElements" type="list" list-name="cacheElementsList" paginate-target="FindUtilCacheElements" separate-columns="true" odd-row-style="alternate-row" default-table-style="basic-table hover-bar" header-row-style="header-row-2">
>
> Modified: ofbiz/trunk/framework/webtools/widget/Menus.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/Menus.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/webtools/widget/Menus.xml (original)
> +++ ofbiz/trunk/framework/webtools/widget/Menus.xml Wed Jun 17 21:50:27 2015
> @@ -138,6 +138,23 @@ under the License.
>               <link target="FindUtilCache"/>
>           </menu-item>
>       </menu>
> +    <menu name="ListCacheForm" extends="CommonInlineBarMenu" extends-resource="component://common/widget/CommonMenus.xml">
> +        <menu-item name="findUtilCacheElements" title="${uiLabelMap.WebtoolsElements}">
> +            <link target="FindUtilCacheElements">
> +                <parameter param-name="UTIL_CACHE_NAME" from-field="cacheName"/>
> +            </link>
> +        </menu-item>
> +        <menu-item name="EditUtilCache" title="${uiLabelMap.CommonEdit}">
> +            <link target="EditUtilCache">
> +                <parameter param-name="UTIL_CACHE_NAME" from-field="cacheName"/>
> +            </link>
> +        </menu-item>
> +        <menu-item name="FindUtilCacheClear" title="${uiLabelMap.CommonClear}">
> +            <link target="FindUtilCacheClear" link-type="hidden-form">
> +                <parameter param-name="UTIL_CACHE_NAME" from-field="cacheName"/>
> +            </link>
> +        </menu-item>
> +    </menu>
>   
>       <menu name="artifactTabBar" extends="CommonTabBarMenu" extends-resource="component://common/widget/CommonMenus.xml"
>             selected-menuitem-context-field-name="tabButtonItem">
>
> Modified: ofbiz/trunk/framework/widget/dtd/widget-form.xsd
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-form.xsd?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/dtd/widget-form.xsd (original)
> +++ ofbiz/trunk/framework/widget/dtd/widget-form.xsd Wed Jun 17 21:50:27 2015
> @@ -1459,6 +1459,30 @@ under the License.
>               </xs:attribute>
>           </xs:complexType>
>       </xs:element>
> +    <xs:element name="include-menu" substitutionGroup="AllFields">
> +        <xs:complexType>
> +            <xs:attribute type="xs:string" name="name" use="required" />
> +            <xs:attribute type="xs:string" name="location" use="required" />
> +        </xs:complexType>
> +    </xs:element>
> +    <xs:element name="include-form" substitutionGroup="AllFields">
> +        <xs:complexType>
> +            <xs:attribute type="xs:string" name="name" use="required" />
> +            <xs:attribute type="xs:string" name="location" use="required" />
> +        </xs:complexType>
> +    </xs:element>
> +    <xs:element name="include-grid" substitutionGroup="AllFields">
> +        <xs:complexType>
> +            <xs:attribute type="xs:string" name="name" use="required" />
> +            <xs:attribute type="xs:string" name="location" use="required" />
> +        </xs:complexType>
> +    </xs:element>
> +    <xs:element name="include-screen" substitutionGroup="AllFields">
> +        <xs:complexType>
> +            <xs:attribute type="xs:string" name="name" use="required" />
> +            <xs:attribute type="xs:string" name="location" use="required" />
> +        </xs:complexType>
> +    </xs:element>
>       <xs:element name="password" substitutionGroup="AllFields">
>           <xs:complexType>
>               <xs:sequence>
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java Wed Jun 17 21:50:27 2015
> @@ -58,15 +58,19 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>   import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
>   import org.ofbiz.widget.model.ModelFormField.FileField;
> +import org.ofbiz.widget.model.ModelFormField.FormField;
> +import org.ofbiz.widget.model.ModelFormField.GridField;
>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>   import org.ofbiz.widget.model.ModelFormField.ResetField;
> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>   import org.ofbiz.widget.model.ModelFormField.TextField;
>   import org.ofbiz.widget.model.ModelFormField.TextFindField;
> @@ -453,6 +457,21 @@ public final class ArtifactInfoGatherer
>           }
>   
>           @Override
> +        public void visit(MenuField menuField) {
> +            //TODO
> +        }
> +
> +        @Override
> +        public void visit(FormField formField) {
> +            //TODO
> +        }
> +
> +        @Override
> +        public void visit(GridField gridField) {
> +            //TODO
> +        }
> +
> +        @Override
>           public void visit(IgnoredField ignoredField) {
>           }
>   
> @@ -484,6 +503,11 @@ public final class ArtifactInfoGatherer
>           @Override
>           public void visit(ResetField resetField) {
>           }
> +
> +        @Override
> +        public void visit(ScreenField screenField) {
> +            //TODO
> +        }
>   
>           @Override
>           public void visit(SubmitField submitField) {
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java Wed Jun 17 21:50:27 2015
> @@ -19,8 +19,10 @@
>   package org.ofbiz.widget.model;
>   
>   import java.io.IOException;
> +import java.util.ArrayList;
>   import java.util.Collections;
>   import java.util.HashMap;
> +import java.util.List;
>   import java.util.Map;
>   
>   import org.ofbiz.base.util.Debug;
> @@ -54,6 +56,11 @@ public abstract class FieldInfo {
>       public static final int PASSWORD = 18;
>       public static final int IMAGE = 19;
>       public static final int DISPLAY_ENTITY = 20;
> +    public static final int CONTAINER = 21;
> +    public static final int MENU = 22;
> +    public static final int FORM = 23;
> +    public static final int GRID = 24;
> +    public static final int SCREEN = 25;
>       // the numbering here represents the priority of the source;
>       //when setting a new fieldInfo on a modelFormField it will only set
>       //the new one if the fieldSource is less than or equal to the existing
> @@ -62,6 +69,7 @@ public abstract class FieldInfo {
>       public static final int SOURCE_AUTO_ENTITY = 2;
>       public static final int SOURCE_AUTO_SERVICE = 3;
>       private static Map<String, Integer> fieldTypeByName = createFieldTypeMap();
> +    private static List<Integer> nonInputFieldTypeList = createNonInputFieldTypeList();
>   
>       private static Map<String, Integer> createFieldTypeMap() {
>           Map<String, Integer> fieldTypeByName = new HashMap<String, Integer>();
> @@ -86,9 +94,27 @@ public abstract class FieldInfo {
>           fieldTypeByName.put("image", Integer.valueOf(19));
>           fieldTypeByName.put("display-entity", Integer.valueOf(20));
>           fieldTypeByName.put("container", Integer.valueOf(21));
> +        fieldTypeByName.put("include-menu", Integer.valueOf(22));
> +        fieldTypeByName.put("include-form", Integer.valueOf(23));
> +        fieldTypeByName.put("include-grid", Integer.valueOf(24));
> +        fieldTypeByName.put("include-screen", Integer.valueOf(25));
>           return Collections.unmodifiableMap(fieldTypeByName);
>       }
>   
> +    private static List<Integer> createNonInputFieldTypeList() {
> +        List<Integer> nonInputFieldTypeList = new ArrayList<Integer>();
> +        nonInputFieldTypeList.add(FieldInfo.IGNORED);
> +        nonInputFieldTypeList.add(FieldInfo.HIDDEN);
> +        nonInputFieldTypeList.add(FieldInfo.DISPLAY);
> +        nonInputFieldTypeList.add(FieldInfo.DISPLAY_ENTITY);
> +        nonInputFieldTypeList.add(FieldInfo.HYPERLINK);
> +        nonInputFieldTypeList.add(FieldInfo.MENU);
> +        nonInputFieldTypeList.add(FieldInfo.FORM);
> +        nonInputFieldTypeList.add(FieldInfo.GRID);
> +        nonInputFieldTypeList.add(FieldInfo.SCREEN);
> +        return Collections.unmodifiableList(nonInputFieldTypeList);
> +    }
> +
>       public static int findFieldTypeFromName(String name) {
>           Integer fieldTypeInt = FieldInfo.fieldTypeByName.get(name);
>           if (fieldTypeInt != null) {
> @@ -98,6 +124,10 @@ public abstract class FieldInfo {
>           }
>       }
>   
> +    public static boolean isInputFieldType(Integer fieldType) {
> +        return ! nonInputFieldTypeList.contains(fieldType);
> +    }
> +
>       private final int fieldType;
>       private final int fieldSource;
>       private final ModelFormField modelFormField;
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java Wed Jun 17 21:50:27 2015
> @@ -26,15 +26,19 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.DisplayField;
>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>   import org.ofbiz.widget.model.ModelFormField.FileField;
> +import org.ofbiz.widget.model.ModelFormField.FormField;
> +import org.ofbiz.widget.model.ModelFormField.GridField;
>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>   import org.ofbiz.widget.model.ModelFormField.ResetField;
> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>   import org.ofbiz.widget.model.ModelFormField.TextField;
>   import org.ofbiz.widget.model.ModelFormField.TextFindField;
> @@ -60,6 +64,10 @@ public interface ModelFieldVisitor {
>       void visit(DropDownField dropDownField) throws Exception ;
>   
>       void visit(FileField textField) throws Exception ;
> +
> +    void visit(FormField formField) throws Exception ;
> +
> +    void visit(GridField gridField) throws Exception ;
>   
>       void visit(HiddenField hiddenField) throws Exception ;
>   
> @@ -71,6 +79,8 @@ public interface ModelFieldVisitor {
>   
>       void visit(LookupField textField) throws Exception ;
>   
> +    void visit(MenuField menuField) throws Exception ;
> +
>       void visit(PasswordField textField) throws Exception ;
>   
>       void visit(RadioField radioField) throws Exception ;
> @@ -79,6 +89,8 @@ public interface ModelFieldVisitor {
>   
>       void visit(ResetField resetField) throws Exception ;
>   
> +    void visit(ScreenField screenField) throws Exception ;
> +
>       void visit(SubmitField submitField) throws Exception ;
>   
>       void visit(TextareaField textareaField) throws Exception ;
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java Wed Jun 17 21:50:27 2015
> @@ -70,7 +70,11 @@ import org.ofbiz.widget.model.CommonWidg
>   import org.ofbiz.widget.model.CommonWidgetModels.Link;
>   import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
>   import org.ofbiz.widget.model.ModelForm.UpdateArea;
> +import org.ofbiz.widget.renderer.FormRenderer;
>   import org.ofbiz.widget.renderer.FormStringRenderer;
> +import org.ofbiz.widget.renderer.MenuStringRenderer;
> +import org.ofbiz.widget.renderer.ScreenRenderer;
> +import org.ofbiz.widget.renderer.ScreenStringRenderer;
>   import org.w3c.dom.Element;
>   
>   import bsh.EvalError;
> @@ -2100,6 +2104,164 @@ public class ModelFormField {
>               formStringRenderer.renderFileField(writer, context, this);
>           }
>       }
> +
> +    /**
> +     * Models the &lt;form&gt; element.
> +     *
> +     * @see <code>widget-form.xsd</code>
> +     */
> +    public static class FormField extends FieldInfo {
> +        private final FlexibleStringExpander formName;
> +        private final FlexibleStringExpander formLocation;
> +
> +        public FormField(Element element, ModelFormField modelFormField) {
> +            super(element, modelFormField);
> +            this.formName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
> +            this.formLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
> +        }
> +
> +        private FormField(FormField original, ModelFormField modelFormField) {
> +            super(original.getFieldSource(), original.getFieldType(), modelFormField);
> +            this.formName = original.formName;
> +            this.formLocation = original.formLocation;
> +        }
> +
> +        @Override
> +        public void accept(ModelFieldVisitor visitor) throws Exception {
> +            visitor.visit(this);
> +        }
> +
> +        @Override
> +        public FieldInfo copy(ModelFormField modelFormField) {
> +            return new FormField(this, modelFormField);
> +        }
> +
> +        public String getFormName(Map<String, Object> context) {
> +            return this.formName.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getFormName() {
> +            return formName;
> +        }
> +
> +        public String getFormLocation(Map<String, Object> context) {
> +            return this.formLocation.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getFormLocation() {
> +            return formLocation;
> +        }
> +
> +        @Override
> +        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
> +                throws IOException {
> +            // Output format might not support menus, so make menu rendering optional.
> +            ModelForm modelForm = getModelForm(context);
> +            try {
> +                FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer);
> +                renderer.render(writer, context);
> +            } catch (Exception e) {
> +                String errMsg = "Error rendering included form named [" + modelForm.getName() + "] at location [" + modelForm.getFormLocation() + "]: " + e.toString();
> +                Debug.logError(e, errMsg, module);
> +                throw new RuntimeException(errMsg + e);
> +            }
> +        }
> +
> +        public ModelForm getModelForm(Map<String, Object> context) {
> +            String name = this.getFormName(context);
> +            String location = this.getFormLocation(context);
> +            ModelForm modelForm = null;
> +            try {
> +                org.ofbiz.entity.model.ModelReader entityModelReader = ((org.ofbiz.entity.Delegator)context.get("delegator")).getModelReader();
> +                org.ofbiz.service.DispatchContext dispatchContext = ((org.ofbiz.service.LocalDispatcher)context.get("dispatcher")).getDispatchContext();
> +                modelForm = FormFactory.getFormFromLocation(location, name, entityModelReader, dispatchContext);
> +            } catch (Exception e) {
> +                String errMsg = "Error rendering form named [" + name + "] at location [" + location + "]: ";
> +                Debug.logError(e, errMsg, module);
> +                throw new RuntimeException(errMsg + e);
> +            }
> +            return modelForm;
> +        }
> +    }
> +
> +    /**
> +     * Models the &lt;grid&gt; element.
> +     *
> +     * @see <code>widget-grid.xsd</code>
> +     */
> +    public static class GridField extends FieldInfo {
> +        private final FlexibleStringExpander gridName;
> +        private final FlexibleStringExpander gridLocation;
> +
> +        public GridField(Element element, ModelFormField modelFormField) {
> +            super(element, modelFormField);
> +            this.gridName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
> +            this.gridLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
> +        }
> +
> +        private GridField(GridField original, ModelFormField modelFormField) {
> +            super(original.getFieldSource(), original.getFieldType(), modelFormField);
> +            this.gridName = original.gridName;
> +            this.gridLocation = original.gridLocation;
> +        }
> +
> +        @Override
> +        public void accept(ModelFieldVisitor visitor) throws Exception {
> +            visitor.visit(this);
> +        }
> +
> +        @Override
> +        public FieldInfo copy(ModelFormField modelFormField) {
> +            return new GridField(this, modelFormField);
> +        }
> +
> +        public String getGridName(Map<String, Object> context) {
> +            return this.gridName.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getGridName() {
> +            return gridName;
> +        }
> +
> +        public String getGridLocation(Map<String, Object> context) {
> +            return this.gridLocation.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getGridLocation() {
> +            return gridLocation;
> +        }
> +
> +        @Override
> +        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
> +                throws IOException {
> +            // Output format might not support menus, so make menu rendering optional.
> +            ModelForm modelGrid = getModelGrid(context);
> +            try {
> +                FormRenderer renderer = new FormRenderer(modelGrid, formStringRenderer);
> +                renderer.render(writer, context);
> +            } catch (Exception e) {
> +                String errMsg = "Error rendering included grid named [" + modelGrid.getName() + "] at location [" + modelGrid.getFormLocation() + "]: " + e.toString();
> +                Debug.logError(e, errMsg, module);
> +                throw new RuntimeException(errMsg + e);
> +            }
> +        }
> +
> +        public ModelForm getModelGrid(Map<String, Object> context) {
> +            String name = this.getGridName(context);
> +            String location = this.getGridLocation(context);
> +            ModelForm modelForm = null;
> +            try {
> +                org.ofbiz.entity.model.ModelReader entityModelReader = ((org.ofbiz.entity.Delegator)context.get("delegator")).getModelReader();
> +                org.ofbiz.service.DispatchContext dispatchContext = ((org.ofbiz.service.LocalDispatcher)context.get("dispatcher")).getDispatchContext();
> +                modelForm = GridFactory.getGridFromLocation(location, name, entityModelReader, dispatchContext);
> +            } catch (Exception e) {
> +                String errMsg = "Error rendering grid named [" + name + "] at location [" + location + "]: ";
> +                Debug.logError(e, errMsg, module);
> +                throw new RuntimeException(errMsg + e);
> +            }
> +            return modelForm;
> +        }
> +    }
>   
>       /**
>        * Models the &lt;hidden&gt; element.
> @@ -2957,6 +3119,81 @@ public class ModelFormField {
>           }
>       }
>   
> +    /**
> +     * Models the &lt;menu&gt; element.
> +     *
> +     * @see <code>widget-form.xsd</code>
> +     */
> +    public static class MenuField extends FieldInfo {
> +        private final FlexibleStringExpander menuName;
> +        private final FlexibleStringExpander menuLocation;
> +
> +        public MenuField(Element element, ModelFormField modelFormField) {
> +            super(element, modelFormField);
> +            this.menuName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
> +            this.menuLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
> +        }
> +
> +        private MenuField(MenuField original, ModelFormField modelFormField) {
> +            super(original.getFieldSource(), original.getFieldType(), modelFormField);
> +            this.menuName = original.menuName;
> +            this.menuLocation = original.menuLocation;
> +        }
> +
> +        @Override
> +        public void accept(ModelFieldVisitor visitor) throws Exception {
> +            visitor.visit(this);
> +        }
> +
> +        @Override
> +        public FieldInfo copy(ModelFormField modelFormField) {
> +            return new MenuField(this, modelFormField);
> +        }
> +
> +        public String getMenuName(Map<String, Object> context) {
> +            return this.menuName.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getMenuName() {
> +            return menuName;
> +        }
> +
> +        public String getMenuLocation(Map<String, Object> context) {
> +            return this.menuLocation.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getMenuLocation() {
> +            return menuLocation;
> +        }
> +
> +        @Override
> +        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
> +                throws IOException {
> +            // Output format might not support menus, so make menu rendering optional.
> +            MenuStringRenderer menuStringRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
> +            if (menuStringRenderer == null) {
> +                Debug.logVerbose("MenuStringRenderer instance not found in rendering context, menu not rendered.", module);
> +                return;
> +            }
> +            ModelMenu modelMenu = getModelMenu(context);
> +            modelMenu.renderMenuString(writer, context, menuStringRenderer);
> +        }
> +
> +        public ModelMenu getModelMenu(Map<String, Object> context) {
> +            String name = this.getMenuName(context);
> +            String location = this.getMenuLocation(context);
> +            ModelMenu modelMenu = null;
> +            try {
> +                modelMenu = MenuFactory.getMenuFromLocation(location, name);
> +            } catch (Exception e) {
> +                String errMsg = "Error rendering menu named [" + name + "] at location [" + location + "]: ";
> +                Debug.logError(e, errMsg, module);
> +                throw new RuntimeException(errMsg + e);
> +            }
> +            return modelMenu;
> +        }
> +    }
> +
>       public static abstract class OptionSource {
>   
>           private final ModelFormField modelFormField;
> @@ -3159,6 +3396,72 @@ public class ModelFormField {
>               formStringRenderer.renderResetField(writer, context, this);
>           }
>       }
> +
> +    /**
> +     * Models the &lt;grid&gt; element.
> +     *
> +     * @see <code>widget-grid.xsd</code>
> +     */
> +    public static class ScreenField extends FieldInfo {
> +        private final FlexibleStringExpander screenName;
> +        private final FlexibleStringExpander screenLocation;
> +
> +        public ScreenField(Element element, ModelFormField modelFormField) {
> +            super(element, modelFormField);
> +            this.screenName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
> +            this.screenLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
> +        }
> +
> +        private ScreenField(ScreenField original, ModelFormField modelFormField) {
> +            super(original.getFieldSource(), original.getFieldType(), modelFormField);
> +            this.screenName = original.screenName;
> +            this.screenLocation = original.screenLocation;
> +        }
> +
> +        @Override
> +        public void accept(ModelFieldVisitor visitor) throws Exception {
> +            visitor.visit(this);
> +        }
> +
> +        @Override
> +        public FieldInfo copy(ModelFormField modelFormField) {
> +            return new ScreenField(this, modelFormField);
> +        }
> +
> +        public String getScreenName(Map<String, Object> context) {
> +            return this.screenName.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getScreenName() {
> +            return screenName;
> +        }
> +
> +        public String getScreenLocation(Map<String, Object> context) {
> +            return this.screenLocation.expandString(context);
> +        }
> +
> +        public FlexibleStringExpander getScreenLocation() {
> +            return screenLocation;
> +        }
> +
> +        @Override
> +        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
> +                throws IOException {
> +            String name = this.getScreenName(context);
> +            String location = this.getScreenLocation(context);
> +            try {
> +                ScreenRenderer renderer = (ScreenRenderer)context.get("screens");
> +                if (renderer != null) {
> +                    ScreenRenderer subRenderer = new ScreenRenderer(writer, (MapStack)UtilGenerics.cast(context), renderer.getScreenStringRenderer());
> +                    writer.append(subRenderer.render(location, name));
> +                }
> +            } catch (Exception e) {
> +                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
> +                Debug.logError(e, errMsg, module);
> +                throw new RuntimeException(errMsg + e);
> +            }
> +        }
> +    }
>   
>       /**
>        * Models the &lt;option&gt; element.
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java Wed Jun 17 21:50:27 2015
> @@ -44,16 +44,20 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.DisplayField;
>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>   import org.ofbiz.widget.model.ModelFormField.FileField;
> +import org.ofbiz.widget.model.ModelFormField.FormField;
> +import org.ofbiz.widget.model.ModelFormField.GridField;
>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.OptionSource;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>   import org.ofbiz.widget.model.ModelFormField.ResetField;
> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>   import org.ofbiz.widget.model.ModelFormField.TextField;
>   import org.ofbiz.widget.model.ModelFormField.TextFindField;
> @@ -212,6 +216,14 @@ public class ModelFormFieldBuilder {
>               this.fieldInfo = new RangeFindField(childElement, null);
>           else if ("lookup".equals(this.fieldType))
>               this.fieldInfo = new LookupField(childElement, null);
> +        else if ("include-menu".equals(this.fieldType))
> +            this.fieldInfo = new MenuField(childElement, null);
> +        else if ("include-form".equals(this.fieldType))
> +            this.fieldInfo = new FormField(childElement, null);
> +        else if ("include-grid".equals(this.fieldType))
> +            this.fieldInfo = new GridField(childElement, null);
> +        else if ("include-screen".equals(this.fieldType))
> +            this.fieldInfo = new ScreenField(childElement, null);
>           else if ("file".equals(this.fieldType))
>               this.fieldInfo = new FileField(childElement, null);
>           else if ("password".equals(this.fieldType))
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java Wed Jun 17 21:50:27 2015
> @@ -31,16 +31,20 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>   import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
>   import org.ofbiz.widget.model.ModelFormField.FileField;
> +import org.ofbiz.widget.model.ModelFormField.FormField;
> +import org.ofbiz.widget.model.ModelFormField.GridField;
>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.InPlaceEditor;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>   import org.ofbiz.widget.model.ModelFormField.ResetField;
> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>   import org.ofbiz.widget.model.ModelFormField.SubHyperlink;
>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>   import org.ofbiz.widget.model.ModelFormField.TextField;
> @@ -174,6 +178,42 @@ public class XmlWidgetFieldVisitor exten
>       }
>   
>       @Override
> +    public void visit(FormField formField) throws Exception {
> +        visitModelField(formField.getModelFormField());
> +        writer.append("<include-form");
> +        visitAttribute("name", formField.getFormName());
> +        visitAttribute("location", formField.getFormLocation());
> +        writer.append("/>");
> +    }
> +
> +    @Override
> +    public void visit(GridField gridField) throws Exception {
> +        visitModelField(gridField.getModelFormField());
> +        writer.append("<include-grid");
> +        visitAttribute("name", gridField.getGridName());
> +        visitAttribute("location", gridField.getGridLocation());
> +        writer.append("/>");
> +    }
> +
> +    @Override
> +    public void visit(MenuField menuField) throws Exception {
> +        visitModelField(menuField.getModelFormField());
> +        writer.append("<include-menu");
> +        visitAttribute("name", menuField.getMenuName());
> +        visitAttribute("location", menuField.getMenuLocation());
> +        writer.append("/>");
> +    }
> +
> +    @Override
> +    public void visit(ScreenField screenField) throws Exception {
> +        visitModelField(screenField.getModelFormField());
> +        writer.append("<include-screen");
> +        visitAttribute("name", screenField.getScreenName());
> +        visitAttribute("location", screenField.getScreenLocation());
> +        writer.append("/>");
> +    }
> +
> +    @Override
>       public void visit(IgnoredField ignoredField) throws Exception {
>           visitModelField(ignoredField.getModelFormField());
>           writer.append("<ignored/></field>");
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java Wed Jun 17 21:50:27 2015
> @@ -73,7 +73,10 @@ public class FormRenderer {
>           Locale locale = UtilMisc.ensureLocale(context.get("locale"));
>           String retVal = FlexibleStringExpander.expandString(modelForm.getContainerId(), context, locale);
>           Integer itemIndex = (Integer) context.get("itemIndex");
> -        if (itemIndex != null && "list".equals(modelForm.getType())) {
> +        if (itemIndex != null/* && "list".equals(modelForm.getType())*/) {
> +            if (UtilValidate.isNotEmpty(context.get("parentItemIndex"))) {
> +                return retVal + context.get("parentItemIndex") + modelForm.getItemIndexSeparator() + itemIndex.intValue();
> +            }
>               return retVal + modelForm.getItemIndexSeparator() + itemIndex.intValue();
>           }
>           return retVal;
> @@ -340,13 +343,11 @@ public class FormRenderer {
>                       continue;
>                   }
>   
> -                if(modelFormField.shouldIgnore(context)) {
> +                if (modelFormField.shouldIgnore(context)) {
>                       continue;
>                   }
>   
> -                if (fieldInfo.getFieldType() != FieldInfo.DISPLAY
> -                        && fieldInfo.getFieldType() != FieldInfo.DISPLAY_ENTITY
> -                        && fieldInfo.getFieldType() != FieldInfo.HYPERLINK) {
> +                if (FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>                       inputFieldFound = true;
>                       continue;
>                   }
> @@ -371,9 +372,7 @@ public class FormRenderer {
>                   }
>   
>                   // skip all of the display/hyperlink fields
> -                if (fieldInfo.getFieldType() == FieldInfo.DISPLAY
> -                        || fieldInfo.getFieldType() == FieldInfo.DISPLAY_ENTITY
> -                        || fieldInfo.getFieldType() == FieldInfo.HYPERLINK) {
> +                if (!FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>                       continue;
>                   }
>   
> @@ -708,6 +707,13 @@ public class FormRenderer {
>   
>           if (iter != null) {
>               // render item rows
> +            if (UtilValidate.isNotEmpty(context.get("itemIndex"))) {
> +                if (UtilValidate.isNotEmpty(context.get("parentItemIndex"))) {
> +                    context.put("parentItemIndex", context.get("parentItemIndex") + modelForm.getItemIndexSeparator() + context.get("itemIndex"));
> +                } else {
> +                    context.put("parentItemIndex", modelForm.getItemIndexSeparator() + context.get("itemIndex"));
> +                }
> +            }
>               int itemIndex = -1;
>               Object item = null;
>               context.put("wholeFormContext", context);
> @@ -819,9 +825,7 @@ public class FormRenderer {
>                               continue;
>                           }
>   
> -                        if (fieldInfo.getFieldType() != FieldInfo.DISPLAY
> -                                && fieldInfo.getFieldType() != FieldInfo.DISPLAY_ENTITY
> -                                && fieldInfo.getFieldType() != FieldInfo.HYPERLINK) {
> +                        if (FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>                               // okay, now do the form cell
>                               break;
>                           }
> @@ -846,9 +850,7 @@ public class FormRenderer {
>                           }
>   
>                           // skip all of the display/hyperlink fields
> -                        if (fieldInfo.getFieldType() == FieldInfo.DISPLAY
> -                                || fieldInfo.getFieldType() == FieldInfo.DISPLAY_ENTITY
> -                                || fieldInfo.getFieldType() == FieldInfo.HYPERLINK) {
> +                        if (!FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>                               continue;
>                           }
>   
> @@ -871,9 +873,7 @@ public class FormRenderer {
>                           }
>   
>                           // skip all non-display and non-hyperlink fields
> -                        if (fieldInfo.getFieldType() != FieldInfo.DISPLAY
> -                                && fieldInfo.getFieldType() != FieldInfo.DISPLAY_ENTITY
> -                                && fieldInfo.getFieldType() != FieldInfo.HYPERLINK) {
> +                        if (FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>                               continue;
>                           }
>   
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java Wed Jun 17 21:50:27 2015
> @@ -30,6 +30,7 @@ import org.ofbiz.widget.model.ModelFormF
>   public interface FormStringRenderer {
>       public void renderDisplayField(Appendable writer, Map<String, Object> context, ModelFormField.DisplayField displayField) throws IOException;
>       public void renderHyperlinkField(Appendable writer, Map<String, Object> context, ModelFormField.HyperlinkField hyperlinkField) throws IOException;
> +    public void renderMenuField(Appendable writer, Map<String, Object> context, ModelFormField.MenuField menuField) throws IOException;
>   
>       public void renderTextField(Appendable writer, Map<String, Object> context, ModelFormField.TextField textField) throws IOException;
>       public void renderTextareaField(Appendable writer, Map<String, Object> context, ModelFormField.TextareaField textareaField) throws IOException;
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java Wed Jun 17 21:50:27 2015
> @@ -44,6 +44,7 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
> @@ -98,6 +99,10 @@ public class FoFormRenderer extends Html
>           appendWhitespace(writer);
>       }
>   
> +    public void renderMenuField(Appendable writer, Map<String, Object> context, MenuField menuField) throws IOException {
> +        menuField.renderFieldString(writer, context, null);
> +    }
> +
>       public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
>           ModelFormField modelFormField = textField.getModelFormField();
>           this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java Wed Jun 17 21:50:27 2015
> @@ -60,6 +60,7 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
> @@ -371,6 +372,10 @@ public class HtmlFormRenderer extends Ht
>           return value;
>       }
>   
> +    public void renderMenuField(Appendable writer, Map<String, Object> context, MenuField menuField) throws IOException {
> +        menuField.renderFieldString(writer, context, null);
> +    }
> +
>       /* (non-Javadoc)
>        * @see org.ofbiz.widget.form.FormStringRenderer#renderTextField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.TextField)
>        */
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java Wed Jun 17 21:50:27 2015
> @@ -71,6 +71,7 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
> @@ -319,6 +320,10 @@ public final class MacroFormRenderer imp
>           this.request.removeAttribute("descriptionSize");
>       }
>   
> +    public void renderMenuField(Appendable writer, Map<String, Object> context, MenuField menuField) throws IOException {
> +        menuField.renderFieldString(writer, context, null);
> +    }
> +
>       public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
>           ModelFormField modelFormField = textField.getModelFormField();
>           String name = modelFormField.getParameterName(context);
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java Wed Jun 17 21:50:27 2015
> @@ -205,11 +205,19 @@ public class MacroMenuRenderer implement
>           parameters.put("name", link.getName(context));
>           parameters.put("text", link.getText(context));
>           parameters.put("targetWindow", link.getTargetWindow(context));
> -        String uniqueItemName = menuItem.getModelMenu().getName() + "_" + menuItem.getName() + "_LF_" + UtilMisc.<String> addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE);
> -        if(menuItem.getModelMenu().getExtraIndex(context) != null){
> -			uniqueItemName += "_" + menuItem.getModelMenu().getExtraIndex(context);
> -		}
> -        parameters.put("uniqueItemName", uniqueItemName);
> +        StringBuffer uniqueItemName = new StringBuffer(menuItem.getModelMenu().getName());
> +        uniqueItemName.append("_").append(menuItem.getName()).append("_LF_").append(UtilMisc.<String> addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE));
> +        if (menuItem.getModelMenu().getExtraIndex(context) != null) {
> +            uniqueItemName.append("_").append(menuItem.getModelMenu().getExtraIndex(context));
> +        }
> +        if (context.containsKey("itemIndex")) {
> +            if (context.containsKey("parentItemIndex")) {
> +                uniqueItemName.append(context.get("parentItemIndex")).append("_").append(context.get("itemIndex"));
> +            } else {
> +                uniqueItemName.append("_").append(context.get("itemIndex"));
> +            }
> +        }
> +        parameters.put("uniqueItemName", uniqueItemName.toString());
>           String linkType = "";
>           if (UtilValidate.isNotEmpty(target)) {
>               linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java Wed Jun 17 21:50:27 2015
> @@ -42,6 +42,7 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
> @@ -92,6 +93,10 @@ public class TextFormRenderer implements
>           this.makeTextString(writer, modelFormField.getWidgetStyle(), hyperlinkField.getDescription(context));
>       }
>   
> +    public void renderMenuField(Appendable writer, Map<String, Object> context, MenuField menuField) throws IOException {
> +        menuField.renderFieldString(writer, context, null);
> +    }
> +
>       public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
>           ModelFormField modelFormField = textField.getModelFormField();
>           this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
>
> Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java (original)
> +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java Wed Jun 17 21:50:27 2015
> @@ -42,6 +42,7 @@ import org.ofbiz.widget.model.ModelFormF
>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>   import org.ofbiz.widget.model.ModelFormField.LookupField;
> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
> @@ -94,6 +95,10 @@ public class XmlFormRenderer implements
>           this.appendWhitespace(writer);
>       }
>   
> +    public void renderMenuField(Appendable writer, Map<String, Object> context, MenuField menuField) throws IOException {
> +        menuField.renderFieldString(writer, context, null);
> +    }
> +
>       public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
>           ModelFormField modelFormField = textField.getModelFormField();
>           this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
>
> Modified: ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml (original)
> +++ ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml Wed Jun 17 21:50:27 2015
> @@ -77,4 +77,17 @@ under the License.
>           <Example exampleId="EX09"/>
>       </delete>
>       <Example exampleId="EX10" exampleName="Example 10 after update"/>
> +
> +    <ExampleItem exampleId="EX01" exampleItemSeqId="00001" description="EX1-001" amount="10"/>
> +    <ExampleItem exampleId="EX01" exampleItemSeqId="00002" description="EX1-002" amount="20"/>
> +    <ExampleItem exampleId="EX02" exampleItemSeqId="00001" description="EX2-001" amount="10"/>
> +    <ExampleItem exampleId="EX02" exampleItemSeqId="00002" description="EX2-002" amount="20"/>
> +    <ExampleItem exampleId="EX02" exampleItemSeqId="00003" description="EX2-003" amount="30"/>
> +
> +    <ExampleStatus exampleId="EX01" statusDate="2010-01-02 00:00:00" statusEndDate="2011-01-02 00:00:00" statusId="EXST_IN_DESIGN"/>
> +    <ExampleStatus exampleId="EX01" statusDate="2011-01-02 00:00:01" statusEndDate="2012-01-02 00:00:00" statusId="EXST_DEFINED"/>
> +    <ExampleStatus exampleId="EX01" statusDate="2012-01-02 00:00:00" statusEndDate="2013-01-02 00:00:00" statusId="EXST_APPROVED"/>
> +    <ExampleStatus exampleId="EX02" statusDate="2010-01-02 00:00:00" statusEndDate="2011-01-02 00:00:00" statusId="EXST_IN_DESIGN"/>
> +    <ExampleStatus exampleId="EX02" statusDate="2011-01-02 00:00:01" statusEndDate="2012-01-02 00:00:00" statusId="EXST_DEFINED"/>
> +    <ExampleStatus exampleId="EX02" statusDate="2012-01-02 00:00:00" statusEndDate="2013-01-02 00:00:00" statusId="EXST_APPROVED"/>
>   </entity-engine-xml>
>
> Modified: ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml (original)
> +++ ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml Wed Jun 17 21:50:27 2015
> @@ -256,6 +256,14 @@ under the License.
>           </section>
>       </screen>
>   
> +    <screen name="SimpleDecorator">
> +        <section>
> +            <widgets>
> +                 <include-screen name="SimpleDecorator" location="component://common/widget/CommonScreens.xml"/>
> +            </widgets>
> +        </section>
> +    </screen>
> +
>       <screen name="main">
>           <!-- This is the screen for the Main page in the Example component. A common pattern
>               in OFBiz is to have each component include a Main page as a starting point for
>
> Modified: ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml (original)
> +++ ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml Wed Jun 17 21:50:27 2015
> @@ -37,6 +37,13 @@ under the License.
>                   <entity-options description="${description}" key-field-name="statusId" entity-name="ExampleStatusItem"/>
>               </drop-down>
>           </field>
> +        <field name="listOtherElements">
> +            <radio>
> +                <option key="items"/>
> +                <option key="features"/>
> +                <option key="status"/>
> +            </radio>
> +        </field>
>           <field name="searchButton" title="${uiLabelMap.CommonFind}" widget-style="smallSubmit"><submit button-type="button" image-location="/images/icons/magnifier.png"/></field>
>       </form>
>   
> @@ -66,6 +73,59 @@ under the License.
>           <field name="conditionalDesc" ignore-when="&quot;exampleName&quot;.equals(sortField)" title="my desc"><display description="${description}"/></field>
>       </form>
>   
> +    <!--example form with include an other form -->
> +    <form name="ListExamplesWithFeatures" type="list" extends="ListExamples" extends-resource="component://example/widget/example/ExampleForms.xml">
> +        <actions>
> +            <call-parent-actions/>
> +        </actions>
> +        <field name="features"><include-form name="ExampleFeaturesInLine" location="component://example/widget/example/ExampleForms.xml"/></field>
> +    </form>
> +    <form name="ExampleFeaturesInLine" type="list" default-table-style="basic-table light-grid" default-entity-name="ExampleFeatureAppl">
> +        <actions>
> +            <entity-condition entity-name="ExampleFeatureAppl">
> +                <condition-expr field-name="exampleId" from-field="exampleId"/>
> +                <order-by field-name="sequenceNum"/>
> +            </entity-condition>
> +        </actions>
> +        <auto-fields-entity entity-name="ExampleFeatureAppl" default-field-type="display"/>
> +        <field name="exampleId"><ignored/></field>
> +    </form>
> +
> +    <!--example form with include a screen -->
> +    <form name="ListExamplesWithItems" type="list" extends="ListExamples" extends-resource="component://example/widget/example/ExampleForms.xml">
> +        <actions>
> +            <call-parent-actions/>
> +        </actions>
> +        <field name="items"><include-screen name="ExampleItemsInLine" location="component://example/widget/example/ExampleScreens.xml"/></field>
> +    </form>
> +    <form name="ListExampleItemsInLine" type="list" default-table-style="basic-table light-grid">
> +        <actions>
> +            <entity-condition entity-name="ExampleItem">
> +                <condition-expr field-name="exampleId" from-field="exampleId"/>
> +            </entity-condition>
> +        </actions>
> +        <auto-fields-entity entity-name="ExampleItem" default-field-type="display"/>
> +        <field name="exampleId"><ignored/></field>
> +    </form>
> +
> +    <!--example form with include a grid -->
> +    <form name="ListExamplesWithStatus" type="list" extends="ListExamples" extends-resource="component://example/widget/example/ExampleForms.xml">
> +        <actions>
> +            <call-parent-actions/>
> +        </actions>
> +        <field name="status"><include-grid name="ExampleStatusInLine" location="component://example/widget/example/ExampleForms.xml"/></field>
> +    </form>
> +    <grid name="ExampleStatusInLine" type="list" default-table-style="basic-table light-grid" default-entity-name="ExampleStatus">
> +        <actions>
> +            <entity-condition entity-name="ExampleStatus">
> +                <condition-expr field-name="exampleId" from-field="exampleId"/>
> +                <order-by field-name="statusDate"/>
> +            </entity-condition>
> +        </actions>
> +        <auto-fields-entity entity-name="ExampleStatus" default-field-type="display"/>
> +        <field name="exampleId"><ignored/></field>
> +    </grid>
> +
>       <!-- Typically, this extended form wouldn't be necessary. The parent form (ListExamples) would
>           have these attributes.
>            For the Ajax example we want all example entities listed, so the we use the entity-condition
>
> Modified: ofbiz/trunk/specialpurpose/example/widget/example/ExampleScreens.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/widget/example/ExampleScreens.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/specialpurpose/example/widget/example/ExampleScreens.xml (original)
> +++ ofbiz/trunk/specialpurpose/example/widget/example/ExampleScreens.xml Wed Jun 17 21:50:27 2015
> @@ -28,6 +28,11 @@ under the License.
>                   <set field="headerItem" value="ExampleMenuItem"/>
>                   <set field="titleProperty" value="PageTitleFindExample"/>
>                   <set field="exampleCtx" from-field="parameters"/>
> +                <set field="formExampleListName" value="${groovy:
> +                    if (parameters.listOtherElements == 'items') return 'ListExamplesWithItems';
> +                    else if (parameters.listOtherElements == 'features') return 'ListExamplesWithFeatures';
> +                    else if (parameters.listOtherElements == 'status') return 'ListExamplesWithStatus';
> +                    else return 'ListExamples'}"/>
>               </actions>
>               <widgets>
>                   <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
> @@ -38,14 +43,14 @@ under the License.
>                               </condition>
>                               <widgets>
>                                   <decorator-screen name="FindScreenDecorator" location="component://common/widget/CommonScreens.xml">
> -                                    <decorator-section name="menu-bar">
> +                                    <decorator-section name="menu-bar"><label>${formExampleListName}</label>
>                                           <container style="button-bar"><link target="EditExampleLayer" link-type="ajax-window" height="500" width="500" text="${uiLabelMap.ExampleNewExample}" style="buttontext create"/></container>
>                                       </decorator-section>
>                                       <decorator-section name="search-options">
>                                           <include-form name="FindExamples" location="component://example/widget/example/ExampleForms.xml"/>
>                                       </decorator-section>
>                                       <decorator-section name="search-results">
> -                                        <include-form name="ListExamples" location="component://example/widget/example/ExampleForms.xml"/>
> +                                        <include-form name="${formExampleListName}" location="component://example/widget/example/ExampleForms.xml"/>
>                                       </decorator-section>
>                                   </decorator-screen>
>                               </widgets>
> @@ -128,6 +133,17 @@ under the License.
>               </widgets>
>           </section>
>       </screen>
> +
> +    <screen name="ExampleItemsInLine">
> +        <section>
> +            <widgets>
> +                 <link text="${uiLabelMap.CommonEdit}" target="EditExampleItems">
> +                     <parameter param-name="exampleId" from-field="exampleId"/>
> +                 </link>
> +                 <include-form name="ListExampleItemsInLine" location="component://example/widget/example/ExampleForms.xml"/>
> +            </widgets>
> +        </section>
> +    </screen>
>   
>       <screen name="EditExampleFeatureAppls">
>           <section>
>
> Modified: ofbiz/trunk/themes/flatgrey/webapp/flatgrey/maincss.css
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/themes/flatgrey/webapp/flatgrey/maincss.css?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/themes/flatgrey/webapp/flatgrey/maincss.css (original)
> +++ ofbiz/trunk/themes/flatgrey/webapp/flatgrey/maincss.css Wed Jun 17 21:50:27 2015
> @@ -737,6 +737,15 @@ margin-bottom: 0.5em;
>   display: table;
>   }
>   
> +/* ===== In line bar ===== */
> +.in-line-bar ul {
> +display: inline; /* IE Fix */
> +}
> +.in-line-bar ul li {
> +float : left;
> +padding : 0 0.5em;
> +}
> +
>   .tool-bar {
>   padding: 0.2em;
>   }
>
> Modified: ofbiz/trunk/themes/tomahawk/webapp/tomahawk/css/style.css
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/themes/tomahawk/webapp/tomahawk/css/style.css?rev=1686116&r1=1686115&r2=1686116&view=diff
> ==============================================================================
> --- ofbiz/trunk/themes/tomahawk/webapp/tomahawk/css/style.css (original)
> +++ ofbiz/trunk/themes/tomahawk/webapp/tomahawk/css/style.css Wed Jun 17 21:50:27 2015
> @@ -1605,6 +1605,24 @@ background-image:url(../images/tab_norma
>   background-color: none;
>   }
>   
> +/* ===== In line bar ===== */
> +.in-line-bar ul li ul{
> +    position: relative;
> +    top: 0em; left: 0;
> +    max-height: 0em;
> +    margin: 0;
> +    padding: 0;
> +    overflow: hidden;
> +    transition: 1.5s max-height 0.3s;
> +}
> +.in-line-bar > li li {
> +    position: relative;
> +    display:inline-block;
> +}
> +tr:hover td div.in-line-bar li ul {
> +    max-height: 20em;
> +}
> +
>   /* ===== Button bar decorators ===== */
>   .tool-bar {
>   background-color: #D4D0C8;
>
>
>

Re: svn commit: r1686116 - in /ofbiz/trunk: framework/common/widget/ framework/webtools/widget/ framework/widget/dtd/ framework/widget/src/org/ofbiz/widget/artifact/ framework/widget/src/org/ofbiz/widget/model/ framework/widget/src/org/ofbiz/widget/rendere...

Posted by Gavin Mabie <kw...@gmail.com>.
Good job!

I wonder though if we are not missing a definitive reference for widgets
> like we have
> https://cwiki.apache.org/confluence/display/OFBADMIN/Mini+Language+-+minilang+-+simple-method+-+Reference


+1

This will an ideal opportunity to standardise some conventions with the
view to facilitate Theme Development and to promote the use of icons in
Ofbiz. We have already seen with the Bootstrap initiative that iconisation
can be achieved fairly easily - provided that the original widgets are
defined properly.   Take for example the widget-style attribute,
specifically the "buttontext" style. Using "buttontext create", buttontext
delete", buttontext refresh" and not just supply "buttontext" makes it easy
for designers to employ vector-based icons in their designs. Where possible
the widget-style attribute should be accompanied by a meaningful descriptor
beyond the ones already used such as "update", "download", "save", "print",
"copy" etc.  I will create a separate jira where this issue can be further
explored by those interested.

Gavin





On Thu, Jun 18, 2015 at 6:21 AM, Jacques Le Roux <
jacques.le.roux@les7arts.com> wrote:

> I very like it thanks Nicolas!
>
> I'd also like to thanks Adam for the prior idea and effort on the grid
> element and Christian for pushing things :)
>
> I wonder though if we are not missing a definitive reference for widgets
> like we have
> https://cwiki.apache.org/confluence/display/OFBADMIN/Mini+Language+-+minilang+-+simple-method+-+Reference
> It could be built from the auto-completion, with an opportunity to
> complete and update it (the documentation in the XSDs is a must to get more
> collaboration from new comers on this)
>
> Kudos guys, we are heading in the right direction. I mean to replace as
> much as possible FTL in backend, and even ecommerce when possible... ;)
>
> OK seems that I have more new things to learn/review
>
> Jacques
>
> Le 17/06/2015 23:50, nmalin@apache.org a écrit :
>
>> Author: nmalin
>> Date: Wed Jun 17 21:50:27 2015
>> New Revision: 1686116
>>
>> URL: http://svn.apache.org/r1686116
>> Log:
>> Improve widget-form with four elements : include-form, include-grid,
>> include-menu, include-screen to offert more flexibility to define complex
>> display. The main purpose is to complete the screen widget capacity to
>> replace ftl screen.
>> With these elements, example component have a new FindExample search
>> screen to select the display list type with a example of :
>>     * include-form : list examples with their features
>>     * include-screen : list examples with their items
>>     * include-grid : list examples with their status history
>> The element include-menu is present on FindUtilCache screen. Also a new
>> CommonInlineBarMenu menu type to display menu with specific purpose
>> (in-line) is now present and with this logic adding in-line-bar css class
>> on themes thomawak and flatgrey.
>>
>> This patch is combinate Issues :
>>   * OFBIZ-6502 Add support for form/grid embedding within grids
>>   * OFBIZ-6501 Add support for screen embedding inside grids
>>   * OFBIZ-6404 Allow form/grid widget hyperlinks to be grouped into a
>> single column
>> sub-tasks of master issue OFBIZ-6314 Widget Refactoring - Placeholder
>> issue
>>
>> Thanks to Christian and Adrian for their time
>>
>> Modified:
>>      ofbiz/trunk/framework/common/widget/CommonMenus.xml
>>      ofbiz/trunk/framework/webtools/widget/CacheForms.xml
>>      ofbiz/trunk/framework/webtools/widget/Menus.xml
>>      ofbiz/trunk/framework/widget/dtd/widget-form.xsd
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
>>
>>  ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
>>      ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml
>>      ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml
>>      ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml
>>      ofbiz/trunk/specialpurpose/example/widget/example/ExampleScreens.xml
>>      ofbiz/trunk/themes/flatgrey/webapp/flatgrey/maincss.css
>>      ofbiz/trunk/themes/tomahawk/webapp/tomahawk/css/style.css
>>
>> Modified: ofbiz/trunk/framework/common/widget/CommonMenus.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/widget/CommonMenus.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> --- ofbiz/trunk/framework/common/widget/CommonMenus.xml (original)
>> +++ ofbiz/trunk/framework/common/widget/CommonMenus.xml Wed Jun 17
>> 21:50:27 2015
>> @@ -31,4 +31,6 @@ under the License.
>>             menu-container-style="button-bar tab-bar"
>> default-selected-style="selected"/>
>>         <menu name="CommonButtonBarMenu" type="simple"
>> menu-container-style="button-bar" default-widget-style="buttontext"/>
>> +
>> +    <menu name="CommonInlineBarMenu" type="simple"
>> menu-container-style="in-line-bar" default-widget-style="linktext"/>
>>   </menus>
>>
>> Modified: ofbiz/trunk/framework/webtools/widget/CacheForms.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/CacheForms.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> --- ofbiz/trunk/framework/webtools/widget/CacheForms.xml (original)
>> +++ ofbiz/trunk/framework/webtools/widget/CacheForms.xml Wed Jun 17
>> 21:50:27 2015
>> @@ -39,21 +39,7 @@ under the License.
>>           <field name="useSoftReference"
>> title="${uiLabelMap.WebtoolsUseSoftRef}"
>> sort-field="true"><display/></field>
>>           <field name="useFileSystemStore"
>> title="${uiLabelMap.WebtoolsUseFileStore}"
>> sort-field="true"><display/></field>
>>           <field name="cacheMemory"
>> title="${uiLabelMap.WebtoolsCacheMemory}"
>> sort-field="true"><display/></field>
>> -        <field name="administration" title=" " widget-style="buttontext"
>> use-when="hasUtilCacheEdit">
>> -            <hyperlink description="${uiLabelMap.WebtoolsElements}"
>> target="FindUtilCacheElements">
>> -                <parameter param-name="UTIL_CACHE_NAME"
>> from-field="cacheName"/>
>> -            </hyperlink>
>> -        </field>
>> -        <field name="admin_edit" title=" " widget-style="buttontext"
>> use-when="hasUtilCacheEdit">
>> -            <hyperlink description="${uiLabelMap.CommonEdit}"
>> target="EditUtilCache">
>> -                <parameter param-name="UTIL_CACHE_NAME"
>> from-field="cacheName"/>
>> -            </hyperlink>
>> -        </field>
>> -        <field name="admin_clear" title=" " widget-style="buttontext"
>> use-when="hasUtilCacheEdit">
>> -            <hyperlink description="${uiLabelMap.CommonClear}"
>> target="FindUtilCacheClear">
>> -                <parameter param-name="UTIL_CACHE_NAME"
>> from-field="cacheName"/>
>> -            </hyperlink>
>> -        </field>
>> +        <field name="cacheMenu" title=" "
>> use-when="hasUtilCacheEdit"><include-menu name="ListCacheForm"
>> location="component://webtools/widget/Menus.xml"/></field>
>>       </form>
>>         <form name="ListCacheElements" type="list"
>> list-name="cacheElementsList" paginate-target="FindUtilCacheElements"
>> separate-columns="true" odd-row-style="alternate-row"
>> default-table-style="basic-table hover-bar" header-row-style="header-row-2">
>>
>> Modified: ofbiz/trunk/framework/webtools/widget/Menus.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/Menus.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> --- ofbiz/trunk/framework/webtools/widget/Menus.xml (original)
>> +++ ofbiz/trunk/framework/webtools/widget/Menus.xml Wed Jun 17 21:50:27
>> 2015
>> @@ -138,6 +138,23 @@ under the License.
>>               <link target="FindUtilCache"/>
>>           </menu-item>
>>       </menu>
>> +    <menu name="ListCacheForm" extends="CommonInlineBarMenu"
>> extends-resource="component://common/widget/CommonMenus.xml">
>> +        <menu-item name="findUtilCacheElements"
>> title="${uiLabelMap.WebtoolsElements}">
>> +            <link target="FindUtilCacheElements">
>> +                <parameter param-name="UTIL_CACHE_NAME"
>> from-field="cacheName"/>
>> +            </link>
>> +        </menu-item>
>> +        <menu-item name="EditUtilCache" title="${uiLabelMap.CommonEdit}">
>> +            <link target="EditUtilCache">
>> +                <parameter param-name="UTIL_CACHE_NAME"
>> from-field="cacheName"/>
>> +            </link>
>> +        </menu-item>
>> +        <menu-item name="FindUtilCacheClear"
>> title="${uiLabelMap.CommonClear}">
>> +            <link target="FindUtilCacheClear" link-type="hidden-form">
>> +                <parameter param-name="UTIL_CACHE_NAME"
>> from-field="cacheName"/>
>> +            </link>
>> +        </menu-item>
>> +    </menu>
>>         <menu name="artifactTabBar" extends="CommonTabBarMenu"
>> extends-resource="component://common/widget/CommonMenus.xml"
>>             selected-menuitem-context-field-name="tabButtonItem">
>>
>> Modified: ofbiz/trunk/framework/widget/dtd/widget-form.xsd
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-form.xsd?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> --- ofbiz/trunk/framework/widget/dtd/widget-form.xsd (original)
>> +++ ofbiz/trunk/framework/widget/dtd/widget-form.xsd Wed Jun 17 21:50:27
>> 2015
>> @@ -1459,6 +1459,30 @@ under the License.
>>               </xs:attribute>
>>           </xs:complexType>
>>       </xs:element>
>> +    <xs:element name="include-menu" substitutionGroup="AllFields">
>> +        <xs:complexType>
>> +            <xs:attribute type="xs:string" name="name" use="required" />
>> +            <xs:attribute type="xs:string" name="location"
>> use="required" />
>> +        </xs:complexType>
>> +    </xs:element>
>> +    <xs:element name="include-form" substitutionGroup="AllFields">
>> +        <xs:complexType>
>> +            <xs:attribute type="xs:string" name="name" use="required" />
>> +            <xs:attribute type="xs:string" name="location"
>> use="required" />
>> +        </xs:complexType>
>> +    </xs:element>
>> +    <xs:element name="include-grid" substitutionGroup="AllFields">
>> +        <xs:complexType>
>> +            <xs:attribute type="xs:string" name="name" use="required" />
>> +            <xs:attribute type="xs:string" name="location"
>> use="required" />
>> +        </xs:complexType>
>> +    </xs:element>
>> +    <xs:element name="include-screen" substitutionGroup="AllFields">
>> +        <xs:complexType>
>> +            <xs:attribute type="xs:string" name="name" use="required" />
>> +            <xs:attribute type="xs:string" name="location"
>> use="required" />
>> +        </xs:complexType>
>> +    </xs:element>
>>       <xs:element name="password" substitutionGroup="AllFields">
>>           <xs:complexType>
>>               <xs:sequence>
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -58,15 +58,19 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>>   import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
>>   import org.ofbiz.widget.model.ModelFormField.FileField;
>> +import org.ofbiz.widget.model.ModelFormField.FormField;
>> +import org.ofbiz.widget.model.ModelFormField.GridField;
>>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>>   import org.ofbiz.widget.model.ModelFormField.ResetField;
>> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>>   import org.ofbiz.widget.model.ModelFormField.TextField;
>>   import org.ofbiz.widget.model.ModelFormField.TextFindField;
>> @@ -453,6 +457,21 @@ public final class ArtifactInfoGatherer
>>           }
>>             @Override
>> +        public void visit(MenuField menuField) {
>> +            //TODO
>> +        }
>> +
>> +        @Override
>> +        public void visit(FormField formField) {
>> +            //TODO
>> +        }
>> +
>> +        @Override
>> +        public void visit(GridField gridField) {
>> +            //TODO
>> +        }
>> +
>> +        @Override
>>           public void visit(IgnoredField ignoredField) {
>>           }
>>   @@ -484,6 +503,11 @@ public final class ArtifactInfoGatherer
>>           @Override
>>           public void visit(ResetField resetField) {
>>           }
>> +
>> +        @Override
>> +        public void visit(ScreenField screenField) {
>> +            //TODO
>> +        }
>>             @Override
>>           public void visit(SubmitField submitField) {
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java Wed
>> Jun 17 21:50:27 2015
>> @@ -19,8 +19,10 @@
>>   package org.ofbiz.widget.model;
>>     import java.io.IOException;
>> +import java.util.ArrayList;
>>   import java.util.Collections;
>>   import java.util.HashMap;
>> +import java.util.List;
>>   import java.util.Map;
>>     import org.ofbiz.base.util.Debug;
>> @@ -54,6 +56,11 @@ public abstract class FieldInfo {
>>       public static final int PASSWORD = 18;
>>       public static final int IMAGE = 19;
>>       public static final int DISPLAY_ENTITY = 20;
>> +    public static final int CONTAINER = 21;
>> +    public static final int MENU = 22;
>> +    public static final int FORM = 23;
>> +    public static final int GRID = 24;
>> +    public static final int SCREEN = 25;
>>       // the numbering here represents the priority of the source;
>>       //when setting a new fieldInfo on a modelFormField it will only set
>>       //the new one if the fieldSource is less than or equal to the
>> existing
>> @@ -62,6 +69,7 @@ public abstract class FieldInfo {
>>       public static final int SOURCE_AUTO_ENTITY = 2;
>>       public static final int SOURCE_AUTO_SERVICE = 3;
>>       private static Map<String, Integer> fieldTypeByName =
>> createFieldTypeMap();
>> +    private static List<Integer> nonInputFieldTypeList =
>> createNonInputFieldTypeList();
>>         private static Map<String, Integer> createFieldTypeMap() {
>>           Map<String, Integer> fieldTypeByName = new HashMap<String,
>> Integer>();
>> @@ -86,9 +94,27 @@ public abstract class FieldInfo {
>>           fieldTypeByName.put("image", Integer.valueOf(19));
>>           fieldTypeByName.put("display-entity", Integer.valueOf(20));
>>           fieldTypeByName.put("container", Integer.valueOf(21));
>> +        fieldTypeByName.put("include-menu", Integer.valueOf(22));
>> +        fieldTypeByName.put("include-form", Integer.valueOf(23));
>> +        fieldTypeByName.put("include-grid", Integer.valueOf(24));
>> +        fieldTypeByName.put("include-screen", Integer.valueOf(25));
>>           return Collections.unmodifiableMap(fieldTypeByName);
>>       }
>>   +    private static List<Integer> createNonInputFieldTypeList() {
>> +        List<Integer> nonInputFieldTypeList = new ArrayList<Integer>();
>> +        nonInputFieldTypeList.add(FieldInfo.IGNORED);
>> +        nonInputFieldTypeList.add(FieldInfo.HIDDEN);
>> +        nonInputFieldTypeList.add(FieldInfo.DISPLAY);
>> +        nonInputFieldTypeList.add(FieldInfo.DISPLAY_ENTITY);
>> +        nonInputFieldTypeList.add(FieldInfo.HYPERLINK);
>> +        nonInputFieldTypeList.add(FieldInfo.MENU);
>> +        nonInputFieldTypeList.add(FieldInfo.FORM);
>> +        nonInputFieldTypeList.add(FieldInfo.GRID);
>> +        nonInputFieldTypeList.add(FieldInfo.SCREEN);
>> +        return Collections.unmodifiableList(nonInputFieldTypeList);
>> +    }
>> +
>>       public static int findFieldTypeFromName(String name) {
>>           Integer fieldTypeInt = FieldInfo.fieldTypeByName.get(name);
>>           if (fieldTypeInt != null) {
>> @@ -98,6 +124,10 @@ public abstract class FieldInfo {
>>           }
>>       }
>>   +    public static boolean isInputFieldType(Integer fieldType) {
>> +        return ! nonInputFieldTypeList.contains(fieldType);
>> +    }
>> +
>>       private final int fieldType;
>>       private final int fieldSource;
>>       private final ModelFormField modelFormField;
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
>> Wed Jun 17 21:50:27 2015
>> @@ -26,15 +26,19 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.DisplayField;
>>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>>   import org.ofbiz.widget.model.ModelFormField.FileField;
>> +import org.ofbiz.widget.model.ModelFormField.FormField;
>> +import org.ofbiz.widget.model.ModelFormField.GridField;
>>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>>   import org.ofbiz.widget.model.ModelFormField.ResetField;
>> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>>   import org.ofbiz.widget.model.ModelFormField.TextField;
>>   import org.ofbiz.widget.model.ModelFormField.TextFindField;
>> @@ -60,6 +64,10 @@ public interface ModelFieldVisitor {
>>       void visit(DropDownField dropDownField) throws Exception ;
>>         void visit(FileField textField) throws Exception ;
>> +
>> +    void visit(FormField formField) throws Exception ;
>> +
>> +    void visit(GridField gridField) throws Exception ;
>>         void visit(HiddenField hiddenField) throws Exception ;
>>   @@ -71,6 +79,8 @@ public interface ModelFieldVisitor {
>>         void visit(LookupField textField) throws Exception ;
>>   +    void visit(MenuField menuField) throws Exception ;
>> +
>>       void visit(PasswordField textField) throws Exception ;
>>         void visit(RadioField radioField) throws Exception ;
>> @@ -79,6 +89,8 @@ public interface ModelFieldVisitor {
>>         void visit(ResetField resetField) throws Exception ;
>>   +    void visit(ScreenField screenField) throws Exception ;
>> +
>>       void visit(SubmitField submitField) throws Exception ;
>>         void visit(TextareaField textareaField) throws Exception ;
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
>> Wed Jun 17 21:50:27 2015
>> @@ -70,7 +70,11 @@ import org.ofbiz.widget.model.CommonWidg
>>   import org.ofbiz.widget.model.CommonWidgetModels.Link;
>>   import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
>>   import org.ofbiz.widget.model.ModelForm.UpdateArea;
>> +import org.ofbiz.widget.renderer.FormRenderer;
>>   import org.ofbiz.widget.renderer.FormStringRenderer;
>> +import org.ofbiz.widget.renderer.MenuStringRenderer;
>> +import org.ofbiz.widget.renderer.ScreenRenderer;
>> +import org.ofbiz.widget.renderer.ScreenStringRenderer;
>>   import org.w3c.dom.Element;
>>     import bsh.EvalError;
>> @@ -2100,6 +2104,164 @@ public class ModelFormField {
>>               formStringRenderer.renderFileField(writer, context, this);
>>           }
>>       }
>> +
>> +    /**
>> +     * Models the &lt;form&gt; element.
>> +     *
>> +     * @see <code>widget-form.xsd</code>
>> +     */
>> +    public static class FormField extends FieldInfo {
>> +        private final FlexibleStringExpander formName;
>> +        private final FlexibleStringExpander formLocation;
>> +
>> +        public FormField(Element element, ModelFormField modelFormField)
>> {
>> +            super(element, modelFormField);
>> +            this.formName =
>> FlexibleStringExpander.getInstance(element.getAttribute("name"));
>> +            this.formLocation =
>> FlexibleStringExpander.getInstance(element.getAttribute("location"));
>> +        }
>> +
>> +        private FormField(FormField original, ModelFormField
>> modelFormField) {
>> +            super(original.getFieldSource(), original.getFieldType(),
>> modelFormField);
>> +            this.formName = original.formName;
>> +            this.formLocation = original.formLocation;
>> +        }
>> +
>> +        @Override
>> +        public void accept(ModelFieldVisitor visitor) throws Exception {
>> +            visitor.visit(this);
>> +        }
>> +
>> +        @Override
>> +        public FieldInfo copy(ModelFormField modelFormField) {
>> +            return new FormField(this, modelFormField);
>> +        }
>> +
>> +        public String getFormName(Map<String, Object> context) {
>> +            return this.formName.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getFormName() {
>> +            return formName;
>> +        }
>> +
>> +        public String getFormLocation(Map<String, Object> context) {
>> +            return this.formLocation.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getFormLocation() {
>> +            return formLocation;
>> +        }
>> +
>> +        @Override
>> +        public void renderFieldString(Appendable writer, Map<String,
>> Object> context, FormStringRenderer formStringRenderer)
>> +                throws IOException {
>> +            // Output format might not support menus, so make menu
>> rendering optional.
>> +            ModelForm modelForm = getModelForm(context);
>> +            try {
>> +                FormRenderer renderer = new FormRenderer(modelForm,
>> formStringRenderer);
>> +                renderer.render(writer, context);
>> +            } catch (Exception e) {
>> +                String errMsg = "Error rendering included form named ["
>> + modelForm.getName() + "] at location [" + modelForm.getFormLocation() +
>> "]: " + e.toString();
>> +                Debug.logError(e, errMsg, module);
>> +                throw new RuntimeException(errMsg + e);
>> +            }
>> +        }
>> +
>> +        public ModelForm getModelForm(Map<String, Object> context) {
>> +            String name = this.getFormName(context);
>> +            String location = this.getFormLocation(context);
>> +            ModelForm modelForm = null;
>> +            try {
>> +                org.ofbiz.entity.model.ModelReader entityModelReader =
>> ((org.ofbiz.entity.Delegator)context.get("delegator")).getModelReader();
>> +                org.ofbiz.service.DispatchContext dispatchContext =
>> ((org.ofbiz.service.LocalDispatcher)context.get("dispatcher")).getDispatchContext();
>> +                modelForm = FormFactory.getFormFromLocation(location,
>> name, entityModelReader, dispatchContext);
>> +            } catch (Exception e) {
>> +                String errMsg = "Error rendering form named [" + name +
>> "] at location [" + location + "]: ";
>> +                Debug.logError(e, errMsg, module);
>> +                throw new RuntimeException(errMsg + e);
>> +            }
>> +            return modelForm;
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Models the &lt;grid&gt; element.
>> +     *
>> +     * @see <code>widget-grid.xsd</code>
>> +     */
>> +    public static class GridField extends FieldInfo {
>> +        private final FlexibleStringExpander gridName;
>> +        private final FlexibleStringExpander gridLocation;
>> +
>> +        public GridField(Element element, ModelFormField modelFormField)
>> {
>> +            super(element, modelFormField);
>> +            this.gridName =
>> FlexibleStringExpander.getInstance(element.getAttribute("name"));
>> +            this.gridLocation =
>> FlexibleStringExpander.getInstance(element.getAttribute("location"));
>> +        }
>> +
>> +        private GridField(GridField original, ModelFormField
>> modelFormField) {
>> +            super(original.getFieldSource(), original.getFieldType(),
>> modelFormField);
>> +            this.gridName = original.gridName;
>> +            this.gridLocation = original.gridLocation;
>> +        }
>> +
>> +        @Override
>> +        public void accept(ModelFieldVisitor visitor) throws Exception {
>> +            visitor.visit(this);
>> +        }
>> +
>> +        @Override
>> +        public FieldInfo copy(ModelFormField modelFormField) {
>> +            return new GridField(this, modelFormField);
>> +        }
>> +
>> +        public String getGridName(Map<String, Object> context) {
>> +            return this.gridName.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getGridName() {
>> +            return gridName;
>> +        }
>> +
>> +        public String getGridLocation(Map<String, Object> context) {
>> +            return this.gridLocation.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getGridLocation() {
>> +            return gridLocation;
>> +        }
>> +
>> +        @Override
>> +        public void renderFieldString(Appendable writer, Map<String,
>> Object> context, FormStringRenderer formStringRenderer)
>> +                throws IOException {
>> +            // Output format might not support menus, so make menu
>> rendering optional.
>> +            ModelForm modelGrid = getModelGrid(context);
>> +            try {
>> +                FormRenderer renderer = new FormRenderer(modelGrid,
>> formStringRenderer);
>> +                renderer.render(writer, context);
>> +            } catch (Exception e) {
>> +                String errMsg = "Error rendering included grid named ["
>> + modelGrid.getName() + "] at location [" + modelGrid.getFormLocation() +
>> "]: " + e.toString();
>> +                Debug.logError(e, errMsg, module);
>> +                throw new RuntimeException(errMsg + e);
>> +            }
>> +        }
>> +
>> +        public ModelForm getModelGrid(Map<String, Object> context) {
>> +            String name = this.getGridName(context);
>> +            String location = this.getGridLocation(context);
>> +            ModelForm modelForm = null;
>> +            try {
>> +                org.ofbiz.entity.model.ModelReader entityModelReader =
>> ((org.ofbiz.entity.Delegator)context.get("delegator")).getModelReader();
>> +                org.ofbiz.service.DispatchContext dispatchContext =
>> ((org.ofbiz.service.LocalDispatcher)context.get("dispatcher")).getDispatchContext();
>> +                modelForm = GridFactory.getGridFromLocation(location,
>> name, entityModelReader, dispatchContext);
>> +            } catch (Exception e) {
>> +                String errMsg = "Error rendering grid named [" + name +
>> "] at location [" + location + "]: ";
>> +                Debug.logError(e, errMsg, module);
>> +                throw new RuntimeException(errMsg + e);
>> +            }
>> +            return modelForm;
>> +        }
>> +    }
>>         /**
>>        * Models the &lt;hidden&gt; element.
>> @@ -2957,6 +3119,81 @@ public class ModelFormField {
>>           }
>>       }
>>   +    /**
>> +     * Models the &lt;menu&gt; element.
>> +     *
>> +     * @see <code>widget-form.xsd</code>
>> +     */
>> +    public static class MenuField extends FieldInfo {
>> +        private final FlexibleStringExpander menuName;
>> +        private final FlexibleStringExpander menuLocation;
>> +
>> +        public MenuField(Element element, ModelFormField modelFormField)
>> {
>> +            super(element, modelFormField);
>> +            this.menuName =
>> FlexibleStringExpander.getInstance(element.getAttribute("name"));
>> +            this.menuLocation =
>> FlexibleStringExpander.getInstance(element.getAttribute("location"));
>> +        }
>> +
>> +        private MenuField(MenuField original, ModelFormField
>> modelFormField) {
>> +            super(original.getFieldSource(), original.getFieldType(),
>> modelFormField);
>> +            this.menuName = original.menuName;
>> +            this.menuLocation = original.menuLocation;
>> +        }
>> +
>> +        @Override
>> +        public void accept(ModelFieldVisitor visitor) throws Exception {
>> +            visitor.visit(this);
>> +        }
>> +
>> +        @Override
>> +        public FieldInfo copy(ModelFormField modelFormField) {
>> +            return new MenuField(this, modelFormField);
>> +        }
>> +
>> +        public String getMenuName(Map<String, Object> context) {
>> +            return this.menuName.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getMenuName() {
>> +            return menuName;
>> +        }
>> +
>> +        public String getMenuLocation(Map<String, Object> context) {
>> +            return this.menuLocation.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getMenuLocation() {
>> +            return menuLocation;
>> +        }
>> +
>> +        @Override
>> +        public void renderFieldString(Appendable writer, Map<String,
>> Object> context, FormStringRenderer formStringRenderer)
>> +                throws IOException {
>> +            // Output format might not support menus, so make menu
>> rendering optional.
>> +            MenuStringRenderer menuStringRenderer = (MenuStringRenderer)
>> context.get("menuStringRenderer");
>> +            if (menuStringRenderer == null) {
>> +                Debug.logVerbose("MenuStringRenderer instance not found
>> in rendering context, menu not rendered.", module);
>> +                return;
>> +            }
>> +            ModelMenu modelMenu = getModelMenu(context);
>> +            modelMenu.renderMenuString(writer, context,
>> menuStringRenderer);
>> +        }
>> +
>> +        public ModelMenu getModelMenu(Map<String, Object> context) {
>> +            String name = this.getMenuName(context);
>> +            String location = this.getMenuLocation(context);
>> +            ModelMenu modelMenu = null;
>> +            try {
>> +                modelMenu = MenuFactory.getMenuFromLocation(location,
>> name);
>> +            } catch (Exception e) {
>> +                String errMsg = "Error rendering menu named [" + name +
>> "] at location [" + location + "]: ";
>> +                Debug.logError(e, errMsg, module);
>> +                throw new RuntimeException(errMsg + e);
>> +            }
>> +            return modelMenu;
>> +        }
>> +    }
>> +
>>       public static abstract class OptionSource {
>>             private final ModelFormField modelFormField;
>> @@ -3159,6 +3396,72 @@ public class ModelFormField {
>>               formStringRenderer.renderResetField(writer, context, this);
>>           }
>>       }
>> +
>> +    /**
>> +     * Models the &lt;grid&gt; element.
>> +     *
>> +     * @see <code>widget-grid.xsd</code>
>> +     */
>> +    public static class ScreenField extends FieldInfo {
>> +        private final FlexibleStringExpander screenName;
>> +        private final FlexibleStringExpander screenLocation;
>> +
>> +        public ScreenField(Element element, ModelFormField
>> modelFormField) {
>> +            super(element, modelFormField);
>> +            this.screenName =
>> FlexibleStringExpander.getInstance(element.getAttribute("name"));
>> +            this.screenLocation =
>> FlexibleStringExpander.getInstance(element.getAttribute("location"));
>> +        }
>> +
>> +        private ScreenField(ScreenField original, ModelFormField
>> modelFormField) {
>> +            super(original.getFieldSource(), original.getFieldType(),
>> modelFormField);
>> +            this.screenName = original.screenName;
>> +            this.screenLocation = original.screenLocation;
>> +        }
>> +
>> +        @Override
>> +        public void accept(ModelFieldVisitor visitor) throws Exception {
>> +            visitor.visit(this);
>> +        }
>> +
>> +        @Override
>> +        public FieldInfo copy(ModelFormField modelFormField) {
>> +            return new ScreenField(this, modelFormField);
>> +        }
>> +
>> +        public String getScreenName(Map<String, Object> context) {
>> +            return this.screenName.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getScreenName() {
>> +            return screenName;
>> +        }
>> +
>> +        public String getScreenLocation(Map<String, Object> context) {
>> +            return this.screenLocation.expandString(context);
>> +        }
>> +
>> +        public FlexibleStringExpander getScreenLocation() {
>> +            return screenLocation;
>> +        }
>> +
>> +        @Override
>> +        public void renderFieldString(Appendable writer, Map<String,
>> Object> context, FormStringRenderer formStringRenderer)
>> +                throws IOException {
>> +            String name = this.getScreenName(context);
>> +            String location = this.getScreenLocation(context);
>> +            try {
>> +                ScreenRenderer renderer =
>> (ScreenRenderer)context.get("screens");
>> +                if (renderer != null) {
>> +                    ScreenRenderer subRenderer = new
>> ScreenRenderer(writer, (MapStack)UtilGenerics.cast(context),
>> renderer.getScreenStringRenderer());
>> +                    writer.append(subRenderer.render(location, name));
>> +                }
>> +            } catch (Exception e) {
>> +                String errMsg = "Error rendering included screen named
>> [" + name + "] at location [" + location + "]: " + e.toString();
>> +                Debug.logError(e, errMsg, module);
>> +                throw new RuntimeException(errMsg + e);
>> +            }
>> +        }
>> +    }
>>         /**
>>        * Models the &lt;option&gt; element.
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
>> Wed Jun 17 21:50:27 2015
>> @@ -44,16 +44,20 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.DisplayField;
>>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>>   import org.ofbiz.widget.model.ModelFormField.FileField;
>> +import org.ofbiz.widget.model.ModelFormField.FormField;
>> +import org.ofbiz.widget.model.ModelFormField.GridField;
>>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.OptionSource;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>>   import org.ofbiz.widget.model.ModelFormField.ResetField;
>> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>>   import org.ofbiz.widget.model.ModelFormField.TextField;
>>   import org.ofbiz.widget.model.ModelFormField.TextFindField;
>> @@ -212,6 +216,14 @@ public class ModelFormFieldBuilder {
>>               this.fieldInfo = new RangeFindField(childElement, null);
>>           else if ("lookup".equals(this.fieldType))
>>               this.fieldInfo = new LookupField(childElement, null);
>> +        else if ("include-menu".equals(this.fieldType))
>> +            this.fieldInfo = new MenuField(childElement, null);
>> +        else if ("include-form".equals(this.fieldType))
>> +            this.fieldInfo = new FormField(childElement, null);
>> +        else if ("include-grid".equals(this.fieldType))
>> +            this.fieldInfo = new GridField(childElement, null);
>> +        else if ("include-screen".equals(this.fieldType))
>> +            this.fieldInfo = new ScreenField(childElement, null);
>>           else if ("file".equals(this.fieldType))
>>               this.fieldInfo = new FileField(childElement, null);
>>           else if ("password".equals(this.fieldType))
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
>> Wed Jun 17 21:50:27 2015
>> @@ -31,16 +31,20 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.DropDownField;
>>   import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
>>   import org.ofbiz.widget.model.ModelFormField.FileField;
>> +import org.ofbiz.widget.model.ModelFormField.FormField;
>> +import org.ofbiz.widget.model.ModelFormField.GridField;
>>   import org.ofbiz.widget.model.ModelFormField.HiddenField;
>>   import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.InPlaceEditor;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>>   import org.ofbiz.widget.model.ModelFormField.ResetField;
>> +import org.ofbiz.widget.model.ModelFormField.ScreenField;
>>   import org.ofbiz.widget.model.ModelFormField.SubHyperlink;
>>   import org.ofbiz.widget.model.ModelFormField.SubmitField;
>>   import org.ofbiz.widget.model.ModelFormField.TextField;
>> @@ -174,6 +178,42 @@ public class XmlWidgetFieldVisitor exten
>>       }
>>         @Override
>> +    public void visit(FormField formField) throws Exception {
>> +        visitModelField(formField.getModelFormField());
>> +        writer.append("<include-form");
>> +        visitAttribute("name", formField.getFormName());
>> +        visitAttribute("location", formField.getFormLocation());
>> +        writer.append("/>");
>> +    }
>> +
>> +    @Override
>> +    public void visit(GridField gridField) throws Exception {
>> +        visitModelField(gridField.getModelFormField());
>> +        writer.append("<include-grid");
>> +        visitAttribute("name", gridField.getGridName());
>> +        visitAttribute("location", gridField.getGridLocation());
>> +        writer.append("/>");
>> +    }
>> +
>> +    @Override
>> +    public void visit(MenuField menuField) throws Exception {
>> +        visitModelField(menuField.getModelFormField());
>> +        writer.append("<include-menu");
>> +        visitAttribute("name", menuField.getMenuName());
>> +        visitAttribute("location", menuField.getMenuLocation());
>> +        writer.append("/>");
>> +    }
>> +
>> +    @Override
>> +    public void visit(ScreenField screenField) throws Exception {
>> +        visitModelField(screenField.getModelFormField());
>> +        writer.append("<include-screen");
>> +        visitAttribute("name", screenField.getScreenName());
>> +        visitAttribute("location", screenField.getScreenLocation());
>> +        writer.append("/>");
>> +    }
>> +
>> +    @Override
>>       public void visit(IgnoredField ignoredField) throws Exception {
>>           visitModelField(ignoredField.getModelFormField());
>>           writer.append("<ignored/></field>");
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -73,7 +73,10 @@ public class FormRenderer {
>>           Locale locale = UtilMisc.ensureLocale(context.get("locale"));
>>           String retVal =
>> FlexibleStringExpander.expandString(modelForm.getContainerId(), context,
>> locale);
>>           Integer itemIndex = (Integer) context.get("itemIndex");
>> -        if (itemIndex != null && "list".equals(modelForm.getType())) {
>> +        if (itemIndex != null/* && "list".equals(modelForm.getType())*/)
>> {
>> +            if (UtilValidate.isNotEmpty(context.get("parentItemIndex")))
>> {
>> +                return retVal + context.get("parentItemIndex") +
>> modelForm.getItemIndexSeparator() + itemIndex.intValue();
>> +            }
>>               return retVal + modelForm.getItemIndexSeparator() +
>> itemIndex.intValue();
>>           }
>>           return retVal;
>> @@ -340,13 +343,11 @@ public class FormRenderer {
>>                       continue;
>>                   }
>>   -                if(modelFormField.shouldIgnore(context)) {
>> +                if (modelFormField.shouldIgnore(context)) {
>>                       continue;
>>                   }
>>   -                if (fieldInfo.getFieldType() != FieldInfo.DISPLAY
>> -                        && fieldInfo.getFieldType() !=
>> FieldInfo.DISPLAY_ENTITY
>> -                        && fieldInfo.getFieldType() !=
>> FieldInfo.HYPERLINK) {
>> +                if
>> (FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>>                       inputFieldFound = true;
>>                       continue;
>>                   }
>> @@ -371,9 +372,7 @@ public class FormRenderer {
>>                   }
>>                     // skip all of the display/hyperlink fields
>> -                if (fieldInfo.getFieldType() == FieldInfo.DISPLAY
>> -                        || fieldInfo.getFieldType() ==
>> FieldInfo.DISPLAY_ENTITY
>> -                        || fieldInfo.getFieldType() ==
>> FieldInfo.HYPERLINK) {
>> +                if
>> (!FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>>                       continue;
>>                   }
>>   @@ -708,6 +707,13 @@ public class FormRenderer {
>>             if (iter != null) {
>>               // render item rows
>> +            if (UtilValidate.isNotEmpty(context.get("itemIndex"))) {
>> +                if
>> (UtilValidate.isNotEmpty(context.get("parentItemIndex"))) {
>> +                    context.put("parentItemIndex",
>> context.get("parentItemIndex") + modelForm.getItemIndexSeparator() +
>> context.get("itemIndex"));
>> +                } else {
>> +                    context.put("parentItemIndex",
>> modelForm.getItemIndexSeparator() + context.get("itemIndex"));
>> +                }
>> +            }
>>               int itemIndex = -1;
>>               Object item = null;
>>               context.put("wholeFormContext", context);
>> @@ -819,9 +825,7 @@ public class FormRenderer {
>>                               continue;
>>                           }
>>   -                        if (fieldInfo.getFieldType() !=
>> FieldInfo.DISPLAY
>> -                                && fieldInfo.getFieldType() !=
>> FieldInfo.DISPLAY_ENTITY
>> -                                && fieldInfo.getFieldType() !=
>> FieldInfo.HYPERLINK) {
>> +                        if
>> (FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>>                               // okay, now do the form cell
>>                               break;
>>                           }
>> @@ -846,9 +850,7 @@ public class FormRenderer {
>>                           }
>>                             // skip all of the display/hyperlink fields
>> -                        if (fieldInfo.getFieldType() == FieldInfo.DISPLAY
>> -                                || fieldInfo.getFieldType() ==
>> FieldInfo.DISPLAY_ENTITY
>> -                                || fieldInfo.getFieldType() ==
>> FieldInfo.HYPERLINK) {
>> +                        if
>> (!FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>>                               continue;
>>                           }
>>   @@ -871,9 +873,7 @@ public class FormRenderer {
>>                           }
>>                             // skip all non-display and non-hyperlink
>> fields
>> -                        if (fieldInfo.getFieldType() != FieldInfo.DISPLAY
>> -                                && fieldInfo.getFieldType() !=
>> FieldInfo.DISPLAY_ENTITY
>> -                                && fieldInfo.getFieldType() !=
>> FieldInfo.HYPERLINK) {
>> +                        if
>> (FieldInfo.isInputFieldType(fieldInfo.getFieldType())) {
>>                               continue;
>>                           }
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -30,6 +30,7 @@ import org.ofbiz.widget.model.ModelFormF
>>   public interface FormStringRenderer {
>>       public void renderDisplayField(Appendable writer, Map<String,
>> Object> context, ModelFormField.DisplayField displayField) throws
>> IOException;
>>       public void renderHyperlinkField(Appendable writer, Map<String,
>> Object> context, ModelFormField.HyperlinkField hyperlinkField) throws
>> IOException;
>> +    public void renderMenuField(Appendable writer, Map<String, Object>
>> context, ModelFormField.MenuField menuField) throws IOException;
>>         public void renderTextField(Appendable writer, Map<String,
>> Object> context, ModelFormField.TextField textField) throws IOException;
>>       public void renderTextareaField(Appendable writer, Map<String,
>> Object> context, ModelFormField.TextareaField textareaField) throws
>> IOException;
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -44,6 +44,7 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>> @@ -98,6 +99,10 @@ public class FoFormRenderer extends Html
>>           appendWhitespace(writer);
>>       }
>>   +    public void renderMenuField(Appendable writer, Map<String, Object>
>> context, MenuField menuField) throws IOException {
>> +        menuField.renderFieldString(writer, context, null);
>> +    }
>> +
>>       public void renderTextField(Appendable writer, Map<String, Object>
>> context, TextField textField) throws IOException {
>>           ModelFormField modelFormField = textField.getModelFormField();
>>           this.makeBlockString(writer, modelFormField.getWidgetStyle(),
>> modelFormField.getEntry(context, textField.getDefaultValue(context)));
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -60,6 +60,7 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>> @@ -371,6 +372,10 @@ public class HtmlFormRenderer extends Ht
>>           return value;
>>       }
>>   +    public void renderMenuField(Appendable writer, Map<String, Object>
>> context, MenuField menuField) throws IOException {
>> +        menuField.renderFieldString(writer, context, null);
>> +    }
>> +
>>       /* (non-Javadoc)
>>        * @see org.ofbiz.widget.form.FormStringRenderer#renderTextField(
>> java.io.Writer, java.util.Map,
>> org.ofbiz.widget.model.ModelFormField.TextField)
>>        */
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -71,6 +71,7 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>> @@ -319,6 +320,10 @@ public final class MacroFormRenderer imp
>>           this.request.removeAttribute("descriptionSize");
>>       }
>>   +    public void renderMenuField(Appendable writer, Map<String, Object>
>> context, MenuField menuField) throws IOException {
>> +        menuField.renderFieldString(writer, context, null);
>> +    }
>> +
>>       public void renderTextField(Appendable writer, Map<String, Object>
>> context, TextField textField) throws IOException {
>>           ModelFormField modelFormField = textField.getModelFormField();
>>           String name = modelFormField.getParameterName(context);
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -205,11 +205,19 @@ public class MacroMenuRenderer implement
>>           parameters.put("name", link.getName(context));
>>           parameters.put("text", link.getText(context));
>>           parameters.put("targetWindow", link.getTargetWindow(context));
>> -        String uniqueItemName = menuItem.getModelMenu().getName() + "_"
>> + menuItem.getName() + "_LF_" + UtilMisc.<String>
>> addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE);
>> -        if(menuItem.getModelMenu().getExtraIndex(context) != null){
>> -                       uniqueItemName += "_" +
>> menuItem.getModelMenu().getExtraIndex(context);
>> -               }
>> -        parameters.put("uniqueItemName", uniqueItemName);
>> +        StringBuffer uniqueItemName = new
>> StringBuffer(menuItem.getModelMenu().getName());
>> +
>> uniqueItemName.append("_").append(menuItem.getName()).append("_LF_").append(UtilMisc.<String>
>> addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE));
>> +        if (menuItem.getModelMenu().getExtraIndex(context) != null) {
>> +
>> uniqueItemName.append("_").append(menuItem.getModelMenu().getExtraIndex(context));
>> +        }
>> +        if (context.containsKey("itemIndex")) {
>> +            if (context.containsKey("parentItemIndex")) {
>> +
>> uniqueItemName.append(context.get("parentItemIndex")).append("_").append(context.get("itemIndex"));
>> +            } else {
>> +
>> uniqueItemName.append("_").append(context.get("itemIndex"));
>> +            }
>> +        }
>> +        parameters.put("uniqueItemName", uniqueItemName.toString());
>>           String linkType = "";
>>           if (UtilValidate.isNotEmpty(target)) {
>>               linkType =
>> WidgetWorker.determineAutoLinkType(link.getLinkType(), target,
>> link.getUrlMode(), request);
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -42,6 +42,7 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>> @@ -92,6 +93,10 @@ public class TextFormRenderer implements
>>           this.makeTextString(writer, modelFormField.getWidgetStyle(),
>> hyperlinkField.getDescription(context));
>>       }
>>   +    public void renderMenuField(Appendable writer, Map<String, Object>
>> context, MenuField menuField) throws IOException {
>> +        menuField.renderFieldString(writer, context, null);
>> +    }
>> +
>>       public void renderTextField(Appendable writer, Map<String, Object>
>> context, TextField textField) throws IOException {
>>           ModelFormField modelFormField = textField.getModelFormField();
>>           this.makeTextString(writer, modelFormField.getWidgetStyle(),
>> modelFormField.getEntry(context, textField.getDefaultValue(context)));
>>
>> Modified:
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> ---
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
>> (original)
>> +++
>> ofbiz/trunk/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
>> Wed Jun 17 21:50:27 2015
>> @@ -42,6 +42,7 @@ import org.ofbiz.widget.model.ModelFormF
>>   import org.ofbiz.widget.model.ModelFormField.IgnoredField;
>>   import org.ofbiz.widget.model.ModelFormField.ImageField;
>>   import org.ofbiz.widget.model.ModelFormField.LookupField;
>> +import org.ofbiz.widget.model.ModelFormField.MenuField;
>>   import org.ofbiz.widget.model.ModelFormField.PasswordField;
>>   import org.ofbiz.widget.model.ModelFormField.RadioField;
>>   import org.ofbiz.widget.model.ModelFormField.RangeFindField;
>> @@ -94,6 +95,10 @@ public class XmlFormRenderer implements
>>           this.appendWhitespace(writer);
>>       }
>>   +    public void renderMenuField(Appendable writer, Map<String, Object>
>> context, MenuField menuField) throws IOException {
>> +        menuField.renderFieldString(writer, context, null);
>> +    }
>> +
>>       public void renderTextField(Appendable writer, Map<String, Object>
>> context, TextField textField) throws IOException {
>>           ModelFormField modelFormField = textField.getModelFormField();
>>           this.makeTextString(writer, modelFormField.getWidgetStyle(),
>> modelFormField.getEntry(context, textField.getDefaultValue(context)));
>>
>> Modified: ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> --- ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml (original)
>> +++ ofbiz/trunk/specialpurpose/example/data/ExampleDemoData.xml Wed Jun
>> 17 21:50:27 2015
>> @@ -77,4 +77,17 @@ under the License.
>>           <Example exampleId="EX09"/>
>>       </delete>
>>       <Example exampleId="EX10" exampleName="Example 10 after update"/>
>> +
>> +    <ExampleItem exampleId="EX01" exampleItemSeqId="00001"
>> description="EX1-001" amount="10"/>
>> +    <ExampleItem exampleId="EX01" exampleItemSeqId="00002"
>> description="EX1-002" amount="20"/>
>> +    <ExampleItem exampleId="EX02" exampleItemSeqId="00001"
>> description="EX2-001" amount="10"/>
>> +    <ExampleItem exampleId="EX02" exampleItemSeqId="00002"
>> description="EX2-002" amount="20"/>
>> +    <ExampleItem exampleId="EX02" exampleItemSeqId="00003"
>> description="EX2-003" amount="30"/>
>> +
>> +    <ExampleStatus exampleId="EX01" statusDate="2010-01-02 00:00:00"
>> statusEndDate="2011-01-02 00:00:00" statusId="EXST_IN_DESIGN"/>
>> +    <ExampleStatus exampleId="EX01" statusDate="2011-01-02 00:00:01"
>> statusEndDate="2012-01-02 00:00:00" statusId="EXST_DEFINED"/>
>> +    <ExampleStatus exampleId="EX01" statusDate="2012-01-02 00:00:00"
>> statusEndDate="2013-01-02 00:00:00" statusId="EXST_APPROVED"/>
>> +    <ExampleStatus exampleId="EX02" statusDate="2010-01-02 00:00:00"
>> statusEndDate="2011-01-02 00:00:00" statusId="EXST_IN_DESIGN"/>
>> +    <ExampleStatus exampleId="EX02" statusDate="2011-01-02 00:00:01"
>> statusEndDate="2012-01-02 00:00:00" statusId="EXST_DEFINED"/>
>> +    <ExampleStatus exampleId="EX02" statusDate="2012-01-02 00:00:00"
>> statusEndDate="2013-01-02 00:00:00" statusId="EXST_APPROVED"/>
>>   </entity-engine-xml>
>>
>> Modified:
>> ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> --- ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml
>> (original)
>> +++ ofbiz/trunk/specialpurpose/example/widget/example/CommonScreens.xml
>> Wed Jun 17 21:50:27 2015
>> @@ -256,6 +256,14 @@ under the License.
>>           </section>
>>       </screen>
>>   +    <screen name="SimpleDecorator">
>> +        <section>
>> +            <widgets>
>> +                 <include-screen name="SimpleDecorator"
>> location="component://common/widget/CommonScreens.xml"/>
>> +            </widgets>
>> +        </section>
>> +    </screen>
>> +
>>       <screen name="main">
>>           <!-- This is the screen for the Main page in the Example
>> component. A common pattern
>>               in OFBiz is to have each component include a Main page as a
>> starting point for
>>
>> Modified:
>> ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml?rev=1686116&r1=1686115&r2=1686116&view=diff
>>
>> ==============================================================================
>> --- ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml
>> (original)
>> +++ ofbiz/trunk/specialpurpose/example/widget/example/ExampleForms.xml
>> Wed Jun 17 21:50:27 2015
>> @@ -37,6 +37,13 @@ under the License.
>>                   <entity-options description="${description}"
>> key-field-name="statusId" entity-name="ExampleStatusItem"/>
>>               </drop-down>
>>           </field>
>> +        <field name="listOtherElements">
>> +            <radio>
>> +                <option key="items"/>
>> +                <option key="features"/>
>> +                <option key="status"/>
>> +            </radio>
>> +        </field>
>>           <field name="searchButton" title="${uiLabelMap.CommonFind}"
>> widget-style="smallSubmit"><submit button-type="button"
>> image-location="/images/icons/magnifier.png"/></field>
>>       </form>
>>   @@ -66,6 +73,59 @@ under the License.
>>           <field name="conditionalDesc"
>> ignore-when="&quot;exampleName&quot;.equals(sortField)" title="my
>> desc"><display description="${description}"/></field>
>>       </form>
>>   +    <!--example form with include an other form -->
>> +    <form name="ListExamplesWithFeatures" type="list"
>> extends="ListExamples"
>> extends-resource="component://example/widget/example/ExampleForms.xml">
>> +        <actions>
>> +            <call-parent-actions/>
>> +        </actions>
>> +        <field name="features"><include-form
>> name="ExampleFeaturesInLine"
>> location="component://example/widget/example/ExampleForms.xml"/></field>
>> +    </form>
>> +    <form name="ExampleFeaturesInLine" type="list"
>> default-table-style="basic-table light-grid"
>> default-entity-name="ExampleFeatureAppl">
>> +        <actions>
>> +            <entity-condition entity-name="ExampleFeatureAppl">
>> +                <condition-expr field-name="exampleId"
>> from-field="exampleId"/>
>> +                <order-by field-name="sequenceNum"/>
>> +            </entity-condition>
>> +        </actions>
>> +        <auto-fields-entity entity-name="ExampleFeatureAppl"
>> default-field-type="display"/>
>> +        <field name="exampleId"><ignored/></field>
>> +    </form>
>> +
>> +    <!--example form with include a screen -->
>> +    <form name="ListExamplesWithItems" type="list"
>> extends="ListExamples"
>> extends-resource="component://example/widget/example/ExampleForms.xml">
>> +        <actions>
>> +            <call-parent-actions/>
>> +        </actions>
>> +        <field name="items"><include-screen name="ExampleItemsInLine"
>> location="component://example/widget/example/ExampleScreens.xml"/></field>
>> +    </form>
>> +    <form name="ListExampleItemsInLine" type="list"
>> default-table-style="basic-table light-grid">
>> +        <actions>
>> +            <entity-condition entity-name="ExampleItem">
>> +                <condition-expr field-name="exampleId"
>> from-field="exampleId"/>
>> +            </entity-condition>
>> +        </actions>
>> +        <auto-fields-entity entity-name="ExampleItem"
>> default-field-type="display"/>
>> +        <field name="exampleId"><ignored/></field>
>> +    </form>
>> +
>> +    <!--example form with include a grid -->
>> +    <form name="ListExamplesWithStatus" type="list"
>> extends="ListExamples"
>> extends-resource="component://example/widget/example/ExampleForms.xml">
>> +        <actions>
>> +            <call-parent-actions/>
>> +        </actions>
>> +        <field name="status"><include-grid name="ExampleStatusInLine"
>> location="component://example/widget/example/ExampleForms.xml"/></field>
>> +    </form>
>> +    <grid name="ExampleStatusInLine" type="list"
>> default-table-style="basic-table light-grid"
>> default-entity-name="ExampleStatus">
>> +        <actions>
>> +            <entity-condition entity-name="ExampleStatus">
>> +                <condition-expr field-name="exampleId"
>> from-field="exampleId"/>
>> +                <order-by field-name="statusDate"/>
>> +            </entity-condition>
>> +        </actions>
>> +        <auto-fields-entity entity-name="ExampleStatus"
>> default-field-type="display"/>
>> +        <field name="exampleId"><ignored/></field>
>> +    </grid>
>> +
>>       <!-- Typically, this extended form wouldn't be necessary. The
>> parent form (ListExamples) would
>
>