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; } |
Free forum by Nabble | Edit this page |