You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2014/11/03 21:46:35 UTC
svn commit: r1636437 [1/3] - in
/ofbiz/trunk/framework/widget/src/org/ofbiz/widget: form/ html/ screen/
Author: adrianc
Date: Mon Nov 3 20:46:34 2014
New Revision: 1636437
URL: http://svn.apache.org/r1636437
Log:
Extract rendering code from ModelForm.java to rendering classes.
Added:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/Paginator.java
Modified:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormWrapper.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlScreenRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java?rev=1636437&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java (added)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java Mon Nov 3 20:46:34 2014
@@ -0,0 +1,1215 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.widget.form;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.GenericEntity;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.widget.ModelWidgetAction;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.form.ModelForm.FieldGroup;
+import org.ofbiz.widget.form.ModelForm.FieldGroupBase;
+
+/**
+ * A form rendering engine.
+ *
+ */
+public class FormRenderer {
+
+ /*
+ * ----------------------------------------------------------------------- *
+ * DEVELOPERS PLEASE READ
+ * ----------------------------------------------------------------------- *
+ *
+ * An instance of this class is created by each thread for each form that
+ * is rendered. If you need to keep track of things while rendering, then
+ * this is the place to do it. In other words, feel free to modify this
+ * object's state (except for the final fields of course).
+ *
+ */
+
+ public static final String module = FormRenderer.class.getName();
+
+ public static String getCurrentContainerId(ModelForm modelForm, Map<String, Object> context) {
+ 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())) {
+ return retVal + modelForm.getItemIndexSeparator() + itemIndex.intValue();
+ }
+ return retVal;
+ }
+
+ public static String getCurrentFormName(ModelForm modelForm, Map<String, Object> context) {
+ Integer itemIndex = (Integer) context.get("itemIndex");
+ String formName = (String) context.get("formName");
+ if (UtilValidate.isEmpty(formName)) {
+ formName = modelForm.getName();
+ }
+ if (itemIndex != null && "list".equals(modelForm.getType())) {
+ return formName + modelForm.getItemIndexSeparator() + itemIndex.intValue();
+ } else {
+ return formName;
+ }
+ }
+
+ private final ModelForm modelForm;
+ private final FormStringRenderer formStringRenderer;
+
+ public FormRenderer(ModelForm modelForm, FormStringRenderer formStringRenderer) {
+ this.modelForm = modelForm;
+ this.formStringRenderer = formStringRenderer;
+ }
+
+ private Collection<List<ModelFormField>> getFieldListsByPosition(List<ModelFormField> modelFormFieldList) {
+ Map<Integer, List<ModelFormField>> fieldsByPosition = new TreeMap<Integer, List<ModelFormField>>();
+ for (ModelFormField modelFormField : modelFormFieldList) {
+ Integer position = Integer.valueOf(modelFormField.getPosition());
+ List<ModelFormField> fieldListByPosition = fieldsByPosition.get(position);
+ if (fieldListByPosition == null) {
+ fieldListByPosition = new LinkedList<ModelFormField>();
+ fieldsByPosition.put(position, fieldListByPosition);
+ }
+ fieldListByPosition.add(modelFormField);
+ }
+ return fieldsByPosition.values();
+ }
+
+ private List<ModelFormField> getHiddenIgnoredFields(Map<String, Object> context, Set<String> alreadyRendered,
+ List<ModelFormField> fieldList, int position) {
+ /*
+ * Method does not reference internal state - should be moved to another class.
+ */
+ List<ModelFormField> hiddenIgnoredFieldList = new LinkedList<ModelFormField>();
+ for (ModelFormField modelFormField : fieldList) {
+ // with position == -1 then gets all the hidden fields
+ if (position != -1 && modelFormField.getPosition() != position) {
+ continue;
+ }
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+
+ // render hidden/ignored field widget
+ switch (fieldInfo.getFieldType()) {
+ case ModelFormField.FieldInfo.HIDDEN:
+ case ModelFormField.FieldInfo.IGNORED:
+ if (modelFormField.shouldUse(context)) {
+ hiddenIgnoredFieldList.add(modelFormField);
+ if (alreadyRendered != null)
+ alreadyRendered.add(modelFormField.getName());
+ }
+ break;
+
+ case ModelFormField.FieldInfo.DISPLAY:
+ case ModelFormField.FieldInfo.DISPLAY_ENTITY:
+ ModelFormField.DisplayField displayField = (ModelFormField.DisplayField) fieldInfo;
+ if (displayField.getAlsoHidden() && modelFormField.shouldUse(context)) {
+ hiddenIgnoredFieldList.add(modelFormField);
+ // don't add to already rendered here, or the display won't ger rendered: if (alreadyRendered != null) alreadyRendered.add(modelFormField.getName());
+ }
+ break;
+
+ case ModelFormField.FieldInfo.HYPERLINK:
+ ModelFormField.HyperlinkField hyperlinkField = (ModelFormField.HyperlinkField) fieldInfo;
+ if (hyperlinkField.getAlsoHidden() && modelFormField.shouldUse(context)) {
+ hiddenIgnoredFieldList.add(modelFormField);
+ // don't add to already rendered here, or the hyperlink won't ger rendered: if (alreadyRendered != null) alreadyRendered.add(modelFormField.getName());
+ }
+ break;
+ }
+ }
+ return hiddenIgnoredFieldList;
+ }
+
+ private List<FieldGroupBase> getInbetweenList(FieldGroup startFieldGroup, FieldGroup endFieldGroup) {
+ ArrayList<FieldGroupBase> inbetweenList = new ArrayList<FieldGroupBase>();
+ boolean firstFound = false;
+ String startFieldGroupId = null;
+ String endFieldGroupId = null;
+ if (endFieldGroup != null) {
+ endFieldGroupId = endFieldGroup.getId();
+ }
+ if (startFieldGroup == null) {
+ firstFound = true;
+ } else {
+ startFieldGroupId = startFieldGroup.getId();
+ }
+ Iterator<FieldGroupBase> iter = modelForm.getFieldGroupList().iterator();
+ while (iter.hasNext()) {
+ FieldGroupBase obj = iter.next();
+ if (obj instanceof ModelForm.Banner) {
+ if (firstFound)
+ inbetweenList.add(obj);
+ } else {
+ FieldGroup fieldGroup = (FieldGroup) obj;
+ String fieldGroupId = fieldGroup.getId();
+ if (!firstFound) {
+ if (fieldGroupId.equals(startFieldGroupId)) {
+ firstFound = true;
+ continue;
+ }
+ }
+ if (firstFound) {
+ if (fieldGroupId.equals(endFieldGroupId)) {
+ break;
+ } else {
+ inbetweenList.add(fieldGroup);
+ }
+ }
+ }
+ }
+ return inbetweenList;
+ }
+
+ /**
+ * Renders this form to a String, i.e. in a text format, as defined with the
+ * FormStringRenderer implementation.
+ *
+ * @param writer The Writer that the form text will be written to
+ * @param context Map containing the form context; the following are
+ * reserved words in this context: parameters (Map), isError (Boolean),
+ * itemIndex (Integer, for lists only, otherwise null), bshInterpreter,
+ * formName (String, optional alternate name for form, defaults to the
+ * value of the name attribute)
+ * @param formStringRenderer An implementation of the FormStringRenderer
+ * interface that is responsible for the actual text generation for
+ * different form elements; implementing your own makes it possible to
+ * use the same form definitions for many types of form UIs
+ */
+ public void render(Appendable writer, Map<String, Object> context)
+ throws Exception {
+ // increment the paginator, only for list and multi forms
+ if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) {
+ WidgetWorker.incrementPaginatorNumber(context);
+ }
+
+ // Populate the viewSize and viewIndex so they are available for use during form actions
+ context.put("viewIndex", Paginator.getViewIndex(modelForm, context));
+ context.put("viewSize", Paginator.getViewSize(modelForm, context));
+
+ modelForm.runFormActions(context);
+
+ // if this is a list form, don't useRequestParameters
+ if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) {
+ context.put("useRequestParameters", Boolean.FALSE);
+ }
+
+ // find the highest position number to get the max positions used
+ int positions = 1;
+ for (ModelFormField modelFormField : modelForm.getFieldList()) {
+ int curPos = modelFormField.getPosition();
+ if (curPos > positions) {
+ positions = curPos;
+ }
+ ModelFormField.FieldInfo currentFieldInfo = modelFormField.getFieldInfo();
+ if (currentFieldInfo != null) {
+ ModelFormField fieldInfoFormField = currentFieldInfo.getModelFormField();
+ if (fieldInfoFormField != null) {
+ // FIXME
+ //fieldInfoFormField.setModelForm(this);
+ }
+ } else {
+ throw new IllegalArgumentException(
+ "Error rendering form, a field has no FieldInfo, ie no sub-element for the type of field for field named: "
+ + modelFormField.getName());
+ }
+ }
+
+ if ("single".equals(modelForm.getType())) {
+ this.renderSingleFormString(writer, context, positions);
+ } else if ("list".equals(modelForm.getType())) {
+ this.renderListFormString(writer, context, positions);
+ } else if ("multi".equals(modelForm.getType())) {
+ this.renderMultiFormString(writer, context, positions);
+ } else if ("upload".equals(modelForm.getType())) {
+ this.renderSingleFormString(writer, context, positions);
+ } else {
+ if (UtilValidate.isEmpty(modelForm.getType())) {
+ throw new IllegalArgumentException("The form 'type' tag is missing or empty on the form with the name "
+ + modelForm.getName());
+ } else {
+ throw new IllegalArgumentException("The form type " + modelForm.getType()
+ + " is not supported for form with name " + modelForm.getName());
+ }
+ }
+ }
+
+ private int renderHeaderRow(Appendable writer, Map<String, Object> context)
+ throws IOException {
+ int maxNumOfColumns = 0;
+
+ // We will render one title/column for all the fields with the same name
+ // in this model: we can have more fields with the same name when use-when
+ // conditions are used or when a form is extended or when the fields are
+ // automatically retrieved by a service or entity definition.
+ List<ModelFormField> tempFieldList = new LinkedList<ModelFormField>();
+ tempFieldList.addAll(modelForm.getFieldList());
+ for (int j = 0; j < tempFieldList.size(); j++) {
+ ModelFormField modelFormField = tempFieldList.get(j);
+ for (int i = j + 1; i < tempFieldList.size(); i++) {
+ ModelFormField curField = tempFieldList.get(i);
+ if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) {
+ tempFieldList.remove(i--);
+ }
+ }
+ }
+
+ // ===========================
+ // Preprocessing
+ // ===========================
+ // We get a sorted (by position, ascending) set of lists;
+ // each list contains all the fields with that position.
+ Collection<List<ModelFormField>> fieldListsByPosition = this.getFieldListsByPosition(tempFieldList);
+ List<Map<String, List<ModelFormField>>> fieldRowsByPosition = new LinkedList<Map<String, List<ModelFormField>>>(); // this list will contain maps, each one containing the list of fields for a position
+ for (List<ModelFormField> mainFieldList : fieldListsByPosition) {
+ int numOfColumns = 0;
+
+ List<ModelFormField> innerDisplayHyperlinkFieldsBegin = new LinkedList<ModelFormField>();
+ List<ModelFormField> innerFormFields = new LinkedList<ModelFormField>();
+ List<ModelFormField> innerDisplayHyperlinkFieldsEnd = new LinkedList<ModelFormField>();
+
+ // render title for each field, except hidden & ignored, etc
+
+ // start by rendering all display and hyperlink fields, until we
+ //get to a field that should go into the form cell, then render
+ //the form cell with all non-display and non-hyperlink fields, then
+ //do a start after the first form input field and
+ //render all display and hyperlink fields after the form
+
+ // prepare the two lists of display and hyperlink fields
+ // the fields in the first list will be rendered as columns before the
+ // combined column for the input fields; the fields in the second list
+ // will be rendered as columns after it
+ boolean inputFieldFound = false;
+ for (ModelFormField modelFormField : mainFieldList) {
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+
+ // if the field's title is explicitly set to "" (title="") then
+ // the header is not created for it; this is useful for position list
+ // where one line can be rendered with more than one row, and we
+ // only want to display the title header for the main row
+ String modelFormFieldTitle = modelFormField.getTitle(context);
+ if ("".equals(modelFormFieldTitle)) {
+ continue;
+ }
+ // don't do any header for hidden or ignored fields
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+
+ if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY
+ && fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY_ENTITY
+ && fieldInfo.getFieldType() != ModelFormField.FieldInfo.HYPERLINK) {
+ inputFieldFound = true;
+ continue;
+ }
+
+ // separate into two lists the display/hyperlink fields found before and after the first input fields
+ if (!inputFieldFound) {
+ innerDisplayHyperlinkFieldsBegin.add(modelFormField);
+ } else {
+ innerDisplayHyperlinkFieldsEnd.add(modelFormField);
+ }
+ numOfColumns++;
+ }
+
+ // prepare the combined title for the column that will contain the form/input fields
+ for (ModelFormField modelFormField : mainFieldList) {
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+
+ // don't do any header for hidden or ignored fields
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+
+ // skip all of the display/hyperlink fields
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY_ENTITY
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.HYPERLINK) {
+ continue;
+ }
+
+ innerFormFields.add(modelFormField);
+ }
+ if (innerFormFields.size() > 0) {
+ numOfColumns++;
+ }
+
+ if (maxNumOfColumns < numOfColumns) {
+ maxNumOfColumns = numOfColumns;
+ }
+
+ Map<String, List<ModelFormField>> fieldRow = UtilMisc.toMap("displayBefore", innerDisplayHyperlinkFieldsBegin,
+ "inputFields", innerFormFields, "displayAfter", innerDisplayHyperlinkFieldsEnd, "mainFieldList",
+ mainFieldList);
+ fieldRowsByPosition.add(fieldRow);
+ }
+ // ===========================
+ // Rendering
+ // ===========================
+ for (Map<String, List<ModelFormField>> listsMap : fieldRowsByPosition) {
+ List<ModelFormField> innerDisplayHyperlinkFieldsBegin = listsMap.get("displayBefore");
+ List<ModelFormField> innerFormFields = listsMap.get("inputFields");
+ List<ModelFormField> innerDisplayHyperlinkFieldsEnd = listsMap.get("displayAfter");
+ List<ModelFormField> mainFieldList = listsMap.get("mainFieldList");
+
+ int numOfCells = innerDisplayHyperlinkFieldsBegin.size() + innerDisplayHyperlinkFieldsEnd.size()
+ + (innerFormFields.size() > 0 ? 1 : 0);
+ int numOfColumnsToSpan = maxNumOfColumns - numOfCells + 1;
+ if (numOfColumnsToSpan < 1) {
+ numOfColumnsToSpan = 1;
+ }
+
+ if (numOfCells > 0) {
+ formStringRenderer.renderFormatHeaderRowOpen(writer, context, modelForm);
+
+ if (modelForm.getGroupColumns()) {
+ Iterator<ModelFormField> innerDisplayHyperlinkFieldsBeginIt = innerDisplayHyperlinkFieldsBegin.iterator();
+ while (innerDisplayHyperlinkFieldsBeginIt.hasNext()) {
+ ModelFormField modelFormField = innerDisplayHyperlinkFieldsBeginIt.next();
+ // span columns only if this is the last column in the row (not just in this first list)
+ if (innerDisplayHyperlinkFieldsBeginIt.hasNext() || numOfCells > innerDisplayHyperlinkFieldsBegin.size()) {
+ formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, modelForm, modelFormField, 1);
+ } else {
+ formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, modelForm, modelFormField,
+ numOfColumnsToSpan);
+ }
+ formStringRenderer.renderFieldTitle(writer, context, modelFormField);
+ formStringRenderer.renderFormatHeaderRowCellClose(writer, context, modelForm, modelFormField);
+ }
+ if (innerFormFields.size() > 0) {
+ // TODO: manage colspan
+ formStringRenderer.renderFormatHeaderRowFormCellOpen(writer, context, modelForm);
+ Iterator<ModelFormField> innerFormFieldsIt = innerFormFields.iterator();
+ while (innerFormFieldsIt.hasNext()) {
+ ModelFormField modelFormField = innerFormFieldsIt.next();
+
+ if (modelForm.getSeparateColumns() || modelFormField.getSeparateColumn()) {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, context, modelForm, modelFormField, 1);
+ }
+
+ // render title (unless this is a submit or a reset field)
+ formStringRenderer.renderFieldTitle(writer, context, modelFormField);
+
+ if (modelForm.getSeparateColumns() || modelFormField.getSeparateColumn()) {
+ formStringRenderer.renderFormatItemRowCellClose(writer, context, modelForm, modelFormField);
+ }
+
+ if (innerFormFieldsIt.hasNext()) {
+ // TODO: determine somehow if this is the last one... how?
+ if (!modelForm.getSeparateColumns() && !modelFormField.getSeparateColumn()) {
+ formStringRenderer.renderFormatHeaderRowFormCellTitleSeparator(writer, context, modelForm,
+ modelFormField, false);
+ }
+ }
+ }
+ formStringRenderer.renderFormatHeaderRowFormCellClose(writer, context, modelForm);
+ }
+ Iterator<ModelFormField> innerDisplayHyperlinkFieldsEndIt = innerDisplayHyperlinkFieldsEnd.iterator();
+ while (innerDisplayHyperlinkFieldsEndIt.hasNext()) {
+ ModelFormField modelFormField = innerDisplayHyperlinkFieldsEndIt.next();
+ // span columns only if this is the last column in the row (not just in this first list)
+ if (innerDisplayHyperlinkFieldsEndIt.hasNext() || numOfCells > innerDisplayHyperlinkFieldsEnd.size()) {
+ formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, modelForm, modelFormField, 1);
+ } else {
+ formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, modelForm, modelFormField,
+ numOfColumnsToSpan);
+ }
+ formStringRenderer.renderFieldTitle(writer, context, modelFormField);
+ formStringRenderer.renderFormatHeaderRowCellClose(writer, context, modelForm, modelFormField);
+ }
+ } else {
+ Iterator<ModelFormField> mainFieldListIter = mainFieldList.iterator();
+ while (mainFieldListIter.hasNext()) {
+ ModelFormField modelFormField = mainFieldListIter.next();
+
+ // don't do any header for hidden or ignored fields
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+
+ // span columns only if this is the last column in the row (not just in this first list)
+ if (mainFieldListIter.hasNext() || numOfCells > mainFieldList.size()) {
+ formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, modelForm, modelFormField, 1);
+ } else {
+ formStringRenderer.renderFormatHeaderRowCellOpen(writer, context, modelForm, modelFormField,
+ numOfColumnsToSpan);
+ }
+ formStringRenderer.renderFieldTitle(writer, context, modelFormField);
+ formStringRenderer.renderFormatHeaderRowCellClose(writer, context, modelForm, modelFormField);
+ }
+ }
+
+ formStringRenderer.renderFormatHeaderRowClose(writer, context, modelForm);
+ }
+ }
+
+ return maxNumOfColumns;
+ }
+
+ private void renderHiddenIgnoredFields(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer,
+ List<ModelFormField> fieldList) throws IOException {
+ for (ModelFormField modelFormField : fieldList) {
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+
+ // render hidden/ignored field widget
+ switch (fieldInfo.getFieldType()) {
+ case ModelFormField.FieldInfo.HIDDEN:
+ case ModelFormField.FieldInfo.IGNORED:
+ modelFormField.renderFieldString(writer, context, formStringRenderer);
+ break;
+
+ case ModelFormField.FieldInfo.DISPLAY:
+ case ModelFormField.FieldInfo.DISPLAY_ENTITY:
+ case ModelFormField.FieldInfo.HYPERLINK:
+ formStringRenderer.renderHiddenField(writer, context, modelFormField, modelFormField.getEntry(context));
+ break;
+ }
+ }
+ }
+
+ // The fields in the three lists, usually created in the preprocessing phase
+ // of the renderItemRows method are rendered: this will create a visual representation
+ // of one row (corresponding to one position).
+ private void renderItemRow(Appendable writer, Map<String, Object> localContext, FormStringRenderer formStringRenderer,
+ boolean formPerItem, List<ModelFormField> hiddenIgnoredFieldList,
+ List<ModelFormField> innerDisplayHyperlinkFieldsBegin, List<ModelFormField> innerFormFields,
+ List<ModelFormField> innerDisplayHyperlinkFieldsEnd, List<ModelFormField> mainFieldList, int position,
+ int numOfColumns) throws IOException {
+ int numOfCells = innerDisplayHyperlinkFieldsBegin.size() + innerDisplayHyperlinkFieldsEnd.size()
+ + (innerFormFields.size() > 0 ? 1 : 0);
+ int numOfColumnsToSpan = numOfColumns - numOfCells + 1;
+ if (numOfColumnsToSpan < 1) {
+ numOfColumnsToSpan = 1;
+ }
+
+ // render row formatting open
+ formStringRenderer.renderFormatItemRowOpen(writer, localContext, modelForm);
+ Iterator<ModelFormField> innerDisplayHyperlinkFieldsBeginIter = innerDisplayHyperlinkFieldsBegin.iterator();
+ Map<String, Integer> fieldCount = new HashMap<String, Integer>();
+ while (innerDisplayHyperlinkFieldsBeginIter.hasNext()) {
+ ModelFormField modelFormField = innerDisplayHyperlinkFieldsBeginIter.next();
+ if (fieldCount.containsKey(modelFormField.getFieldName())) {
+ fieldCount.put(modelFormField.getFieldName(), fieldCount.get(modelFormField.getFieldName()) + 1);
+ } else {
+ fieldCount.put(modelFormField.getFieldName(), 1);
+ }
+ }
+
+ if (modelForm.getGroupColumns()) {
+ // do the first part of display and hyperlink fields
+ Iterator<ModelFormField> innerDisplayHyperlinkFieldIter = innerDisplayHyperlinkFieldsBegin.iterator();
+ while (innerDisplayHyperlinkFieldIter.hasNext()) {
+ boolean cellOpen = false;
+ ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next();
+ // span columns only if this is the last column in the row (not just in this first list)
+ if (fieldCount.get(modelFormField.getName()) < 2) {
+ if ((innerDisplayHyperlinkFieldIter.hasNext() || numOfCells > innerDisplayHyperlinkFieldsBegin.size())) {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField, 1);
+ } else {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField,
+ numOfColumnsToSpan);
+ }
+ cellOpen = true;
+ }
+ if ((!"list".equals(modelForm.getType()) && !"multi".equals(modelForm.getType()))
+ || modelFormField.shouldUse(localContext)) {
+ if ((fieldCount.get(modelFormField.getName()) > 1)) {
+ if ((innerDisplayHyperlinkFieldIter.hasNext() || numOfCells > innerDisplayHyperlinkFieldsBegin.size())) {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField, 1);
+ } else {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField,
+ numOfColumnsToSpan);
+ }
+ cellOpen = true;
+ }
+ modelFormField.renderFieldString(writer, localContext, formStringRenderer);
+ }
+ if (cellOpen) {
+ formStringRenderer.renderFormatItemRowCellClose(writer, localContext, modelForm, modelFormField);
+ }
+ }
+
+ // The form cell is rendered only if there is at least an input field
+ if (innerFormFields.size() > 0) {
+ // render the "form" cell
+ formStringRenderer.renderFormatItemRowFormCellOpen(writer, localContext, modelForm); // TODO: colspan
+
+ if (formPerItem) {
+ formStringRenderer.renderFormOpen(writer, localContext, modelForm);
+ }
+
+ // do all of the hidden fields...
+ this.renderHiddenIgnoredFields(writer, localContext, formStringRenderer, hiddenIgnoredFieldList);
+
+ Iterator<ModelFormField> innerFormFieldIter = innerFormFields.iterator();
+ while (innerFormFieldIter.hasNext()) {
+ ModelFormField modelFormField = innerFormFieldIter.next();
+ if (modelForm.getSeparateColumns() || modelFormField.getSeparateColumn()) {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField, 1);
+ }
+ // render field widget
+ if ((!"list".equals(modelForm.getType()) && !"multi".equals(modelForm.getType()))
+ || modelFormField.shouldUse(localContext)) {
+ modelFormField.renderFieldString(writer, localContext, formStringRenderer);
+ }
+
+ if (modelForm.getSeparateColumns() || modelFormField.getSeparateColumn()) {
+ formStringRenderer.renderFormatItemRowCellClose(writer, localContext, modelForm, modelFormField);
+ }
+ }
+
+ if (formPerItem) {
+ formStringRenderer.renderFormClose(writer, localContext, modelForm);
+ }
+
+ formStringRenderer.renderFormatItemRowFormCellClose(writer, localContext, modelForm);
+ }
+
+ // render the rest of the display/hyperlink fields
+ innerDisplayHyperlinkFieldIter = innerDisplayHyperlinkFieldsEnd.iterator();
+ while (innerDisplayHyperlinkFieldIter.hasNext()) {
+ ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next();
+ // span columns only if this is the last column in the row
+ if (innerDisplayHyperlinkFieldIter.hasNext()) {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField, 1);
+ } else {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField,
+ numOfColumnsToSpan);
+ }
+ if ((!"list".equals(modelForm.getType()) && !"multi".equals(modelForm.getType()))
+ || modelFormField.shouldUse(localContext)) {
+ modelFormField.renderFieldString(writer, localContext, formStringRenderer);
+ }
+ formStringRenderer.renderFormatItemRowCellClose(writer, localContext, modelForm, modelFormField);
+ }
+ } else {
+ // do all of the hidden fields...
+ this.renderHiddenIgnoredFields(writer, localContext, formStringRenderer, hiddenIgnoredFieldList);
+
+ Iterator<ModelFormField> mainFieldIter = mainFieldList.iterator();
+ while (mainFieldIter.hasNext()) {
+ ModelFormField modelFormField = mainFieldIter.next();
+
+ // don't do any header for hidden or ignored fields inside this loop
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+
+ // span columns only if this is the last column in the row
+ if (mainFieldIter.hasNext()) {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField, 1);
+ } else {
+ formStringRenderer.renderFormatItemRowCellOpen(writer, localContext, modelForm, modelFormField,
+ numOfColumnsToSpan);
+ }
+ if ((!"list".equals(modelForm.getType()) && !"multi".equals(modelForm.getType()))
+ || modelFormField.shouldUse(localContext)) {
+ modelFormField.renderFieldString(writer, localContext, formStringRenderer);
+ }
+ formStringRenderer.renderFormatItemRowCellClose(writer, localContext, modelForm, modelFormField);
+ }
+ }
+
+ // render row formatting close
+ formStringRenderer.renderFormatItemRowClose(writer, localContext, modelForm);
+ }
+
+ private void renderItemRows(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer,
+ boolean formPerItem, int numOfColumns) throws IOException {
+ String lookupName = modelForm.getListName();
+ if (UtilValidate.isEmpty(lookupName)) {
+ Debug.logError("No value for list or iterator name found.", module);
+ return;
+ }
+ Object obj = context.get(lookupName);
+ if (obj == null) {
+ if (Debug.verboseOn())
+ Debug.logVerbose("No object for list or iterator name [" + lookupName + "] found, so not rendering rows.", module);
+ return;
+ }
+ // if list is empty, do not render rows
+ Iterator<?> iter = null;
+ if (obj instanceof Iterator<?>) {
+ iter = (Iterator<?>) obj;
+ } else if (obj instanceof List<?>) {
+ iter = ((List<?>) obj).listIterator();
+ }
+
+ // set low and high index
+ Paginator.getListLimits(modelForm, context, obj);
+
+ int listSize = ((Integer) context.get("listSize")).intValue();
+ int lowIndex = ((Integer) context.get("lowIndex")).intValue();
+ int highIndex = ((Integer) context.get("highIndex")).intValue();
+
+ // we're passed a subset of the list, so use (0, viewSize) range
+ if (modelForm.isOverridenListSize()) {
+ lowIndex = 0;
+ highIndex = ((Integer) context.get("viewSize")).intValue();
+ }
+
+ if (iter != null) {
+ // render item rows
+ int itemIndex = -1;
+ Object item = null;
+ context.put("wholeFormContext", context);
+ Map<String, Object> previousItem = new HashMap<String, Object>();
+ while ((item = safeNext(iter)) != null) {
+ itemIndex++;
+ if (itemIndex >= highIndex) {
+ break;
+ }
+
+ // TODO: this is a bad design, for EntityListIterators we should skip to the lowIndex and go from there, MUCH more efficient...
+ if (itemIndex < lowIndex) {
+ continue;
+ }
+
+ // reset/remove the BshInterpreter now as well as later because chances are there is an interpreter at this level of the stack too
+ this.resetBshInterpreter(context);
+
+ Map<String, Object> itemMap = UtilGenerics.checkMap(item);
+ MapStack<String> localContext = MapStack.create(context);
+ if (UtilValidate.isNotEmpty(modelForm.getListEntryName())) {
+ localContext.put(modelForm.getListEntryName(), item);
+ } else {
+ if (itemMap instanceof GenericEntity) {
+ // Rendering code might try to modify the GenericEntity instance,
+ // so we make a copy of it.
+ Map<String, Object> genericEntityClone = UtilGenerics.cast(((GenericEntity) itemMap).clone());
+ localContext.push(genericEntityClone);
+ } else {
+ localContext.push(itemMap);
+ }
+ }
+
+ // reset/remove the BshInterpreter now as well as later because chances are there is an interpreter at this level of the stack too
+ this.resetBshInterpreter(localContext);
+ localContext.push();
+ localContext.put("previousItem", previousItem);
+ previousItem = new HashMap<String, Object>();
+ previousItem.putAll(itemMap);
+
+ ModelWidgetAction.runSubActions(modelForm.getRowActions(), localContext);
+
+ localContext.put("itemIndex", Integer.valueOf(itemIndex - lowIndex));
+ if (UtilValidate.isNotEmpty(context.get("renderFormSeqNumber"))) {
+ localContext.put("formUniqueId", "_" + context.get("renderFormSeqNumber"));
+ }
+
+ this.resetBshInterpreter(localContext);
+
+ if (Debug.verboseOn())
+ Debug.logVerbose("In form got another row, context is: " + localContext, module);
+
+ // Check to see if there is a field, same name and same use-when (could come from extended form)
+ List<ModelFormField> tempFieldList = new LinkedList<ModelFormField>();
+ tempFieldList.addAll(modelForm.getFieldList());
+ for (int j = 0; j < tempFieldList.size(); j++) {
+ ModelFormField modelFormField = tempFieldList.get(j);
+ if (!modelFormField.isUseWhenEmpty()) {
+ boolean shouldUse1 = modelFormField.shouldUse(localContext);
+ for (int i = j + 1; i < tempFieldList.size(); i++) {
+ ModelFormField curField = tempFieldList.get(i);
+ if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) {
+ boolean shouldUse2 = curField.shouldUse(localContext);
+ if (shouldUse1 == shouldUse2) {
+ tempFieldList.remove(i--);
+ }
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+
+ // Each single item is rendered in one or more rows if its fields have
+ // different "position" attributes. All the fields with the same position
+ // are rendered in the same row.
+ // The default position is 1, and represents the main row:
+ // it contains the fields that are in the list header (columns).
+ // The positions lower than 1 are rendered in rows before the main one;
+ // positions higher than 1 are rendered after the main one.
+
+ // We get a sorted (by position, ascending) set of lists;
+ // each list contains all the fields with that position.
+ Collection<List<ModelFormField>> fieldListsByPosition = this.getFieldListsByPosition(tempFieldList);
+ //List hiddenIgnoredFieldList = getHiddenIgnoredFields(localContext, null, tempFieldList);
+ for (List<ModelFormField> fieldListByPosition : fieldListsByPosition) {
+ // For each position (the subset of fields with the same position attribute)
+ // we have two phases: preprocessing and rendering
+
+ List<ModelFormField> innerDisplayHyperlinkFieldsBegin = new LinkedList<ModelFormField>();
+ List<ModelFormField> innerFormFields = new LinkedList<ModelFormField>();
+ List<ModelFormField> innerDisplayHyperlinkFieldsEnd = new LinkedList<ModelFormField>();
+
+ // Preprocessing:
+ // all the form fields are evaluated and the ones that will
+ // appear in the form are put into three separate lists:
+ // - hyperlink fields that will appear at the beginning of the row
+ // - fields of other types
+ // - hyperlink fields that will appear at the end of the row
+ Iterator<ModelFormField> innerDisplayHyperlinkFieldIter = fieldListByPosition.iterator();
+ int currentPosition = 1;
+ while (innerDisplayHyperlinkFieldIter.hasNext()) {
+ ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next();
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+
+ // don't do any header for hidden or ignored fields
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+
+ if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY
+ && fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY_ENTITY
+ && fieldInfo.getFieldType() != ModelFormField.FieldInfo.HYPERLINK) {
+ // okay, now do the form cell
+ break;
+ }
+
+ // if this is a list or multi form don't skip here because we don't want to skip the table cell, will skip the actual field later
+ if (!"list".equals(modelForm.getType()) && !"multi".equals(modelForm.getType())
+ && !modelFormField.shouldUse(localContext)) {
+ continue;
+ }
+ innerDisplayHyperlinkFieldsBegin.add(modelFormField);
+ currentPosition = modelFormField.getPosition();
+ }
+ Iterator<ModelFormField> innerFormFieldIter = fieldListByPosition.iterator();
+ while (innerFormFieldIter.hasNext()) {
+ ModelFormField modelFormField = innerFormFieldIter.next();
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+
+ // don't do any header for hidden or ignored fields
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+
+ // skip all of the display/hyperlink fields
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.DISPLAY_ENTITY
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.HYPERLINK) {
+ continue;
+ }
+
+ // if this is a list or multi form don't skip here because we don't want to skip the table cell, will skip the actual field later
+ if (!"list".equals(modelForm.getType()) && !"multi".equals(modelForm.getType())
+ && !modelFormField.shouldUse(localContext)) {
+ continue;
+ }
+ innerFormFields.add(modelFormField);
+ currentPosition = modelFormField.getPosition();
+ }
+ while (innerDisplayHyperlinkFieldIter.hasNext()) {
+ ModelFormField modelFormField = innerDisplayHyperlinkFieldIter.next();
+ ModelFormField.FieldInfo fieldInfo = modelFormField.getFieldInfo();
+
+ // don't do any header for hidden or ignored fields
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+
+ // skip all non-display and non-hyperlink fields
+ if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY
+ && fieldInfo.getFieldType() != ModelFormField.FieldInfo.DISPLAY_ENTITY
+ && fieldInfo.getFieldType() != ModelFormField.FieldInfo.HYPERLINK) {
+ continue;
+ }
+
+ // if this is a list or multi form don't skip here because we don't want to skip the table cell, will skip the actual field later
+ if (!"list".equals(modelForm.getType()) && !"multi".equals(modelForm.getType())
+ && !modelFormField.shouldUse(localContext)) {
+ continue;
+ }
+ innerDisplayHyperlinkFieldsEnd.add(modelFormField);
+ currentPosition = modelFormField.getPosition();
+ }
+ List<ModelFormField> hiddenIgnoredFieldList = getHiddenIgnoredFields(localContext, null, tempFieldList,
+ currentPosition);
+
+ // Rendering:
+ // the fields in the three lists created in the preprocessing phase
+ // are now rendered: this will create a visual representation
+ // of one row (for the current position).
+ if (innerDisplayHyperlinkFieldsBegin.size() > 0 || innerFormFields.size() > 0
+ || innerDisplayHyperlinkFieldsEnd.size() > 0) {
+ this.renderItemRow(writer, localContext, formStringRenderer, formPerItem, hiddenIgnoredFieldList,
+ innerDisplayHyperlinkFieldsBegin, innerFormFields, innerDisplayHyperlinkFieldsEnd,
+ fieldListByPosition, currentPosition, numOfColumns);
+ }
+ } // iteration on positions
+ } // iteration on items
+
+ // reduce the highIndex if number of items falls short
+ if ((itemIndex + 1) < highIndex) {
+ highIndex = itemIndex + 1;
+ // if list size is overridden, use full listSize
+ context.put("highIndex", Integer.valueOf(modelForm.isOverridenListSize() ? listSize : highIndex));
+ }
+ context.put("actualPageSize", Integer.valueOf(highIndex - lowIndex));
+
+ if (iter instanceof EntityListIterator) {
+ try {
+ ((EntityListIterator) iter).close();
+ } catch (GenericEntityException e) {
+ Debug.logError(e, "Error closing list form render EntityListIterator: " + e.toString(), module);
+ }
+ }
+ }
+ }
+
+ private void renderListFormString(Appendable writer, Map<String, Object> context,
+ int positions) throws IOException {
+ // render list/tabular type forms
+
+ // prepare the items iterator and compute the pagination parameters
+ Paginator.preparePager(modelForm, context);
+
+ // render formatting wrapper open
+ formStringRenderer.renderFormatListWrapperOpen(writer, context, modelForm);
+
+ int numOfColumns = 0;
+ // ===== render header row =====
+ if (!modelForm.getHideHeader()) {
+ numOfColumns = this.renderHeaderRow(writer, context);
+ }
+
+ // ===== render the item rows =====
+ this.renderItemRows(writer, context, formStringRenderer, true, numOfColumns);
+
+ // render formatting wrapper close
+ formStringRenderer.renderFormatListWrapperClose(writer, context, modelForm);
+
+ }
+
+ private void renderMultiFormString(Appendable writer, Map<String, Object> context,
+ int positions) throws IOException {
+ if (!modelForm.getSkipStart()) {
+ formStringRenderer.renderFormOpen(writer, context, modelForm);
+ }
+
+ // prepare the items iterator and compute the pagination parameters
+ Paginator.preparePager(modelForm, context);
+
+ // render formatting wrapper open
+ formStringRenderer.renderFormatListWrapperOpen(writer, context, modelForm);
+
+ int numOfColumns = 0;
+ // ===== render header row =====
+ if (!modelForm.getHideHeader()) {
+ numOfColumns = this.renderHeaderRow(writer, context);
+ }
+
+ // ===== render the item rows =====
+ this.renderItemRows(writer, context, formStringRenderer, false, numOfColumns);
+
+ formStringRenderer.renderFormatListWrapperClose(writer, context, modelForm);
+
+ if (!modelForm.getSkipEnd()) {
+ formStringRenderer.renderMultiFormClose(writer, context, modelForm);
+ }
+
+ }
+
+ private void renderSingleFormString(Appendable writer, Map<String, Object> context,
+ int positions) throws IOException {
+ List<ModelFormField> tempFieldList = new LinkedList<ModelFormField>();
+ tempFieldList.addAll(modelForm.getFieldList());
+
+ // Check to see if there is a field, same name and same use-when (could come from extended form)
+ for (int j = 0; j < tempFieldList.size(); j++) {
+ ModelFormField modelFormField = tempFieldList.get(j);
+ if (modelForm.getUseWhenFields().contains(modelFormField.getName())) {
+ boolean shouldUse1 = modelFormField.shouldUse(context);
+ for (int i = j + 1; i < tempFieldList.size(); i++) {
+ ModelFormField curField = tempFieldList.get(i);
+ if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) {
+ boolean shouldUse2 = curField.shouldUse(context);
+ if (shouldUse1 == shouldUse2) {
+ tempFieldList.remove(i--);
+ }
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+
+ Set<String> alreadyRendered = new TreeSet<String>();
+ FieldGroup lastFieldGroup = null;
+ // render form open
+ if (!modelForm.getSkipStart())
+ formStringRenderer.renderFormOpen(writer, context, modelForm);
+
+ // render all hidden & ignored fields
+ List<ModelFormField> hiddenIgnoredFieldList = this.getHiddenIgnoredFields(context, alreadyRendered, tempFieldList, -1);
+ this.renderHiddenIgnoredFields(writer, context, formStringRenderer, hiddenIgnoredFieldList);
+
+ // render formatting wrapper open
+ // This should be covered by fieldGroup.renderStartString
+ //formStringRenderer.renderFormatSingleWrapperOpen(writer, context, this);
+
+ // render each field row, except hidden & ignored rows
+ Iterator<ModelFormField> fieldIter = tempFieldList.iterator();
+ ModelFormField lastFormField = null;
+ ModelFormField currentFormField = null;
+ ModelFormField nextFormField = null;
+ if (fieldIter.hasNext()) {
+ currentFormField = fieldIter.next();
+ }
+ if (fieldIter.hasNext()) {
+ nextFormField = fieldIter.next();
+ }
+
+ FieldGroup currentFieldGroup = null;
+ String currentFieldGroupName = null;
+ String lastFieldGroupName = null;
+ if (currentFormField != null) {
+ currentFieldGroup = (FieldGroup) modelForm.getFieldGroupMap().get(currentFormField.getFieldName());
+ if (currentFieldGroup == null) {
+ currentFieldGroup = modelForm.getDefaultFieldGroup();
+ }
+ if (currentFieldGroup != null) {
+ currentFieldGroupName = currentFieldGroup.getId();
+ }
+ }
+
+ boolean isFirstPass = true;
+ boolean haveRenderedOpenFieldRow = false;
+ while (currentFormField != null) {
+ // do the check/get next stuff at the beginning so we can still use the continue stuff easily
+ // don't do it on the first pass though...
+ if (isFirstPass) {
+ isFirstPass = false;
+ List<FieldGroupBase> inbetweenList = getInbetweenList(lastFieldGroup, currentFieldGroup);
+ for (FieldGroupBase obj : inbetweenList) {
+ if (obj instanceof ModelForm.Banner) {
+ ((ModelForm.Banner) obj).renderString(writer, context, formStringRenderer);
+ }
+ }
+ if (currentFieldGroup != null && (lastFieldGroup == null || !lastFieldGroupName.equals(currentFieldGroupName))) {
+ currentFieldGroup.renderStartString(writer, context, formStringRenderer);
+ lastFieldGroup = currentFieldGroup;
+ }
+ } else {
+ if (fieldIter.hasNext()) {
+ // at least two loops left
+ lastFormField = currentFormField;
+ currentFormField = nextFormField;
+ nextFormField = fieldIter.next();
+ } else if (nextFormField != null) {
+ // okay, just one loop left
+ lastFormField = currentFormField;
+ currentFormField = nextFormField;
+ nextFormField = null;
+ } else {
+ // at the end...
+ lastFormField = currentFormField;
+ currentFormField = null;
+ // nextFormField is already null
+ break;
+ }
+ currentFieldGroup = null;
+ if (currentFormField != null) {
+ currentFieldGroup = (FieldGroup) modelForm.getFieldGroupMap().get(currentFormField.getName());
+ }
+ if (currentFieldGroup == null) {
+ currentFieldGroup = modelForm.getDefaultFieldGroup();
+ }
+ currentFieldGroupName = currentFieldGroup.getId();
+
+ if (lastFieldGroup != null) {
+ lastFieldGroupName = lastFieldGroup.getId();
+ if (!lastFieldGroupName.equals(currentFieldGroupName)) {
+ if (haveRenderedOpenFieldRow) {
+ formStringRenderer.renderFormatFieldRowClose(writer, context, modelForm);
+ haveRenderedOpenFieldRow = false;
+ }
+ lastFieldGroup.renderEndString(writer, context, formStringRenderer);
+
+ List<FieldGroupBase> inbetweenList = getInbetweenList(lastFieldGroup, currentFieldGroup);
+ for (FieldGroupBase obj : inbetweenList) {
+ if (obj instanceof ModelForm.Banner) {
+ ((ModelForm.Banner) obj).renderString(writer, context, formStringRenderer);
+ }
+ }
+ }
+ }
+
+ if (lastFieldGroup == null || !lastFieldGroupName.equals(currentFieldGroupName)) {
+ currentFieldGroup.renderStartString(writer, context, formStringRenderer);
+ lastFieldGroup = currentFieldGroup;
+ }
+ }
+
+ ModelFormField.FieldInfo fieldInfo = currentFormField.getFieldInfo();
+ if (fieldInfo.getFieldType() == ModelFormField.FieldInfo.HIDDEN
+ || fieldInfo.getFieldType() == ModelFormField.FieldInfo.IGNORED) {
+ continue;
+ }
+ if (alreadyRendered.contains(currentFormField.getName())) {
+ continue;
+ }
+ //Debug.logInfo("In single form evaluating use-when for field " + currentFormField.getName() + ": " + currentFormField.getUseWhen(), module);
+ if (!currentFormField.shouldUse(context)) {
+ if (UtilValidate.isNotEmpty(lastFormField)) {
+ currentFormField = lastFormField;
+ }
+ continue;
+ }
+ alreadyRendered.add(currentFormField.getName());
+
+ boolean stayingOnRow = false;
+ if (lastFormField != null) {
+ if (lastFormField.getPosition() >= currentFormField.getPosition()) {
+ // moving to next row
+ stayingOnRow = false;
+ } else {
+ // staying on same row
+ stayingOnRow = true;
+ }
+ }
+
+ int positionSpan = 1;
+ Integer nextPositionInRow = null;
+ if (nextFormField != null) {
+ if (nextFormField.getPosition() > currentFormField.getPosition()) {
+ positionSpan = nextFormField.getPosition() - currentFormField.getPosition() - 1;
+ nextPositionInRow = Integer.valueOf(nextFormField.getPosition());
+ } else {
+ positionSpan = positions - currentFormField.getPosition();
+ if (!stayingOnRow && nextFormField.getPosition() > 1) {
+ // TODO: here is a weird case where it is setup such
+ //that the first position(s) in the row are skipped
+ // not sure what to do about this right now...
+ }
+ }
+ }
+
+ if (stayingOnRow) {
+ // no spacer cell, might add later though...
+ //formStringRenderer.renderFormatFieldRowSpacerCell(writer, context, currentFormField);
+ } else {
+ if (haveRenderedOpenFieldRow) {
+ // render row formatting close
+ formStringRenderer.renderFormatFieldRowClose(writer, context, modelForm);
+ haveRenderedOpenFieldRow = false;
+ }
+
+ // render row formatting open
+ formStringRenderer.renderFormatFieldRowOpen(writer, context, modelForm);
+ haveRenderedOpenFieldRow = true;
+ }
+
+ //
+ // It must be a row open before rendering a field. If not, open it
+ //
+ if (!haveRenderedOpenFieldRow) {
+ formStringRenderer.renderFormatFieldRowOpen(writer, context, modelForm);
+ haveRenderedOpenFieldRow = true;
+ }
+
+ // render title formatting open
+ formStringRenderer.renderFormatFieldRowTitleCellOpen(writer, context, currentFormField);
+
+ // render title (unless this is a submit or a reset field)
+ if (fieldInfo.getFieldType() != ModelFormField.FieldInfo.SUBMIT
+ && fieldInfo.getFieldType() != ModelFormField.FieldInfo.RESET) {
+ formStringRenderer.renderFieldTitle(writer, context, currentFormField);
+ } else {
+ formStringRenderer.renderFormatEmptySpace(writer, context, modelForm);
+ }
+
+ // render title formatting close
+ formStringRenderer.renderFormatFieldRowTitleCellClose(writer, context, currentFormField);
+
+ // render separator
+ formStringRenderer.renderFormatFieldRowSpacerCell(writer, context, currentFormField);
+
+ // render widget formatting open
+ formStringRenderer.renderFormatFieldRowWidgetCellOpen(writer, context, currentFormField, positions, positionSpan,
+ nextPositionInRow);
+
+ // render widget
+ currentFormField.renderFieldString(writer, context, formStringRenderer);
+
+ // render widget formatting close
+ formStringRenderer.renderFormatFieldRowWidgetCellClose(writer, context, currentFormField, positions, positionSpan,
+ nextPositionInRow);
+
+ }
+ // render row formatting close after the end if needed
+ if (haveRenderedOpenFieldRow) {
+ formStringRenderer.renderFormatFieldRowClose(writer, context, modelForm);
+ }
+
+ if (lastFieldGroup != null) {
+ lastFieldGroup.renderEndString(writer, context, formStringRenderer);
+ }
+ // render formatting wrapper close
+ // should be handled by renderEndString
+ //formStringRenderer.renderFormatSingleWrapperClose(writer, context, this);
+
+ // render form close
+ if (!modelForm.getSkipEnd())
+ formStringRenderer.renderFormClose(writer, context, modelForm);
+
+ }
+
+ private void resetBshInterpreter(Map<String, Object> context) {
+ context.remove("bshInterpreter");
+ }
+
+ private static <X> X safeNext(Iterator<X> iterator) {
+ try {
+ return iterator.next();
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ }
+}
Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java?rev=1636437&r1=1636436&r2=1636437&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java Mon Nov 3 20:46:34 2014
@@ -558,7 +558,8 @@ public final class MacroFormRenderer imp
}
}
String id = modelFormField.getCurrentContainerId(context);
- String formName = modelFormField.getModelForm().getCurrentFormName(context);
+ ModelForm modelForm = modelFormField.getModelForm();
+ String formName = FormRenderer.getCurrentFormName(modelForm, context);
String timeDropdown = dateTimeField.getInputMethod();
String timeDropdownParamName = "";
String classString = "";
@@ -1068,7 +1069,7 @@ public final class MacroFormRenderer imp
String title = modelFormField.getTitle(context);
String name = modelFormField.getParameterName(context);
String buttonType = submitField.getButtonType();
- String formName = modelForm.getCurrentFormName(context);
+ String formName = FormRenderer.getCurrentFormName(modelForm, context);
String imgSrc = submitField.getImageLocation(context);
String confirmation = submitField.getConfirmation(context);
String className = "";
@@ -1079,7 +1080,7 @@ public final class MacroFormRenderer imp
alert = "true";
}
}
- String formId = modelForm.getCurrentContainerId(context);
+ String formId = FormRenderer.getCurrentContainerId(modelForm, context);
List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSubmitUpdateAreas();
// This is here for backwards compatibility. Use on-event-update-area
// elements instead.
@@ -1297,14 +1298,14 @@ public final class MacroFormRenderer imp
}
String formType = modelForm.getType();
String targetWindow = modelForm.getTargetWindow(context);
- String containerId = modelForm.getCurrentContainerId(context);
+ String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
String containerStyle = modelForm.getContainerStyle();
String autocomplete = "";
- String name = modelForm.getCurrentFormName(context);
+ String name = FormRenderer.getCurrentFormName(modelForm, context);
String viewIndexField = modelForm.getMultiPaginateIndexField(context);
String viewSizeField = modelForm.getMultiPaginateSizeField(context);
- int viewIndex = modelForm.getViewIndex(context);
- int viewSize = modelForm.getViewSize(context);
+ int viewIndex = Paginator.getViewIndex(modelForm, context);
+ int viewSize = Paginator.getViewSize(modelForm, context);
boolean useRowSubmit = modelForm.getUseRowSubmit();
if (!modelForm.getClientAutocompleteFields()) {
autocomplete = "off";
@@ -1341,8 +1342,8 @@ public final class MacroFormRenderer imp
public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
String focusFieldName = modelForm.getfocusFieldName();
- String formName = modelForm.getCurrentFormName(context);
- String containerId = modelForm.getCurrentContainerId(context);
+ String formName = FormRenderer.getCurrentFormName(modelForm, context);
+ String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
String hasRequiredField = "";
for (ModelFormField formField : modelForm.getFieldList()) {
if (formField.getRequiredField()) {
@@ -1903,7 +1904,8 @@ public final class MacroFormRenderer imp
StringBuilder imgSrc = new StringBuilder();
// add calendar pop-up button and seed data IF this is not a "time" type date-find
if (!"time".equals(dateFindField.getType())) {
- formName = modelFormField.getModelForm().getCurrentFormName(context);
+ ModelForm modelForm = modelFormField.getModelForm();
+ formName = FormRenderer.getCurrentFormName(modelForm, context);
defaultDateTimeString = UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context)));
this.appendContentUrl(imgSrc, "/images/cal.gif");
}
@@ -2024,7 +2026,8 @@ public final class MacroFormRenderer imp
boolean readonly = lookupField.readonly;
// add lookup pop-up button
String descriptionFieldName = lookupField.getDescriptionFieldName();
- String formName = modelFormField.getModelForm().getCurrentFormName(context);
+ ModelForm modelForm = modelFormField.getModelForm();
+ String formName = FormRenderer.getCurrentFormName(modelForm, context);
StringBuilder targetParameterIter = new StringBuilder();
StringBuilder imgSrc = new StringBuilder();
// FIXME: refactor using the StringUtils methods
@@ -2183,12 +2186,12 @@ public final class MacroFormRenderer imp
int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
- int viewIndex = modelForm.getViewIndex(context);
- int viewSize = modelForm.getViewSize(context);
- int listSize = modelForm.getListSize(context);
- int lowIndex = modelForm.getLowIndex(context);
- int highIndex = modelForm.getHighIndex(context);
- int actualPageSize = modelForm.getActualPageSize(context);
+ int viewIndex = Paginator.getViewIndex(modelForm, context);
+ int viewSize = Paginator.getViewSize(modelForm, context);
+ int listSize = Paginator.getListSize(context);
+ int lowIndex = Paginator.getLowIndex(context);
+ int highIndex = Paginator.getHighIndex(context);
+ int actualPageSize = Paginator.getActualPageSize(context);
// needed for the "Page" and "rows" labels
Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
String pageLabel = "";
@@ -2935,8 +2938,9 @@ public final class MacroFormRenderer imp
int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
String viewIndexField = modelFormField.modelForm.getMultiPaginateIndexField(context);
String viewSizeField = modelFormField.modelForm.getMultiPaginateSizeField(context);
- int viewIndex = modelFormField.modelForm.getViewIndex(context);
- int viewSize = modelFormField.modelForm.getViewSize(context);
+ ModelForm modelForm = modelFormField.modelForm;
+ int viewIndex = Paginator.getViewIndex(modelForm, context);
+ int viewSize = Paginator.getViewSize(modelForm, context);
if (viewIndexField.equals("viewIndex" + "_" + paginatorNumber)) {
viewIndexField = "VIEW_INDEX" + "_" + paginatorNumber;
}