/*******************************************************************************
 * 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.html;

import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.StringUtil.SimpleEncoder;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilHttp;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.string.FlexibleStringExpander;
import org.ofbiz.base.util.template.FreeMarkerWorker;
import org.ofbiz.entity.Delegator;
import org.ofbiz.webapp.control.RequestHandler;
import org.ofbiz.webapp.taglib.ContentUrlTag;
import org.ofbiz.widget.ModelWidget;
import org.ofbiz.widget.WidgetWorker;
import org.ofbiz.widget.form.FormRenderer;
import org.ofbiz.widget.form.FormStringRenderer;
import org.ofbiz.widget.form.MacroFormRenderer;
import org.ofbiz.widget.form.ModelForm;
import org.ofbiz.widget.form.ModelFormField;
import org.ofbiz.widget.form.ModelFormField.CheckField;
import org.ofbiz.widget.form.ModelFormField.ContainerField;
import org.ofbiz.widget.form.ModelFormField.DateFindField;
import org.ofbiz.widget.form.ModelFormField.DateTimeField;
import org.ofbiz.widget.form.ModelFormField.DisplayEntityField;
import org.ofbiz.widget.form.ModelFormField.DisplayField;
import org.ofbiz.widget.form.ModelFormField.DropDownField;
import org.ofbiz.widget.form.ModelFormField.FieldInfoWithOptions;
import org.ofbiz.widget.form.ModelFormField.FileField;
import org.ofbiz.widget.form.ModelFormField.HiddenField;
import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
import org.ofbiz.widget.form.ModelFormField.IgnoredField;
import org.ofbiz.widget.form.ModelFormField.ImageField;
import org.ofbiz.widget.form.ModelFormField.LookupField;
import org.ofbiz.widget.form.ModelFormField.PasswordField;
import org.ofbiz.widget.form.ModelFormField.RadioField;
import org.ofbiz.widget.form.ModelFormField.RangeFindField;
import org.ofbiz.widget.form.ModelFormField.ResetField;
import org.ofbiz.widget.form.ModelFormField.SubmitField;
import org.ofbiz.widget.form.ModelFormField.TextField;
import org.ofbiz.widget.form.ModelFormField.TextFindField;
import org.ofbiz.widget.form.ModelFormField.TextareaField;
import org.ofbiz.widget.form.Paginator;
import org.ofbiz.widget.form.UtilHelpText;

import freemarker.template.TemplateException;

/**
 * Widget Library - HTML Form Renderer implementation
 */
public class HtmlFormRenderer extends HtmlWidgetRenderer implements FormStringRenderer {

    public static final String module = HtmlFormRenderer.class.getName();

    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected RequestHandler rh;
    protected String lastFieldGroupId = "";
    protected boolean renderPagination = true;
    protected boolean javaScriptEnabled = false;
    private SimpleEncoder internalEncoder;

    protected HtmlFormRenderer() {}

    public HtmlFormRenderer(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
        this.rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
        this.javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
        internalEncoder = StringUtil.getEncoder("string");
    }

    public boolean getRenderPagination() {
        return this.renderPagination;
    }

    public void setRenderPagination(boolean renderPagination) {
        this.renderPagination = renderPagination;
    }

    public void appendOfbizUrl(Appendable writer, String location) throws IOException {
        writer.append(this.rh.makeLink(this.request, this.response, location));
    }

    public void appendContentUrl(Appendable writer, String location) throws IOException {
        ContentUrlTag.appendContentPrefix(this.request, writer);
        writer.append(location);
    }

    public void appendTooltip(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
        // render the tooltip, in other methods too
        String tooltip = modelFormField.getTooltip(context);
        if (UtilValidate.isNotEmpty(tooltip)) {
            writer.append("<span class=\"");
            String tooltipStyle = modelFormField.getTooltipStyle();
            if (UtilValidate.isNotEmpty(tooltipStyle)) {
                writer.append(tooltipStyle);
            } else {
                writer.append("tooltip");
            }
            writer.append("\">");
            writer.append(tooltip);
            writer.append("</span>");
        }
    }

    public void addAsterisks(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {

        boolean requiredField = modelFormField.getRequiredField();
        if (requiredField) {
            String requiredStyle = modelFormField.getRequiredFieldStyle();

            if (UtilValidate.isEmpty(requiredStyle)) {
               writer.append("*");
            }
        }
    }

    public void appendClassNames(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
        String className = modelFormField.getWidgetStyle();
        if (UtilValidate.isNotEmpty(className) || modelFormField.shouldBeRed(context)) {
            writer.append(" class=\"");
            writer.append(className);
            // add a style of red if redWhen is true
            if (modelFormField.shouldBeRed(context)) {
                writer.append(" alert");
            }
            writer.append('"');
        }
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderDisplayField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DisplayField)
     */
    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
        ModelFormField modelFormField = displayField.getModelFormField();

        StringBuilder str = new StringBuilder();

        String idName = modelFormField.getCurrentContainerId(context);

        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle()) || modelFormField.shouldBeRed(context)) {
            str.append("<span class=\"");
            str.append(modelFormField.getWidgetStyle());
            // add a style of red if this is a date/time field and redWhen is true
            if (modelFormField.shouldBeRed(context)) {
                str.append(" alert");
            }
            str.append('"');
            if (UtilValidate.isNotEmpty(idName)) {
                str.append(" id=\"");
                str.append(idName+"_sp");
                str.append('"');
            }
            str.append('>');
        }

        if (str.length() > 0) {
            writer.append(str.toString());
        }
        String description = displayField.getDescription(context);
        //Replace new lines with <br/>
        description = description.replaceAll("\n", "<br/>");

        if (UtilValidate.isEmpty(description)) {
            this.renderFormatEmptySpace(writer, context, modelFormField.getModelForm());
        } else {
            writer.append(description);
        }

        if (str.length() > 0) {
            writer.append("</span>");
        }

        ModelFormField.InPlaceEditor inPlaceEditor = displayField.getInPlaceEditor();
        boolean ajaxEnabled = inPlaceEditor != null && this.javaScriptEnabled;

        if (ajaxEnabled) {
            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
            StringBuilder url = new StringBuilder(inPlaceEditor.getUrl(context));
            Map<String, Object> fieldMap = inPlaceEditor.getFieldMap(context);
            if (fieldMap != null) {
                url.append('?');
                int count = 0;
                for (Entry<String, Object> field: fieldMap.entrySet()) {
                    count++;
                    url.append(field.getKey()).append('=').append(field.getValue());
                    if (count < fieldMap.size()) {
                        url.append('&');
                    }
                }
            }
            writer.append("ajaxInPlaceEditDisplayField('");
            writer.append(idName).append("', '").append(url).append("', {");
            if (UtilValidate.isNotEmpty(inPlaceEditor.getParamName())) {
                writer.append("name: '").append(inPlaceEditor.getParamName()).append("'");
            } else {
                writer.append("name: '").append(modelFormField.getFieldName()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelControl())) {
                writer.append(", cancelControl: ");
                if (!"false".equals(inPlaceEditor.getCancelControl())) {
                    writer.append("'");
                }
                writer.append(inPlaceEditor.getCancelControl());
                if (!"false".equals(inPlaceEditor.getCancelControl())) {
                    writer.append("'");
                }
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelText())) {
                writer.append(", cancel: '").append(inPlaceEditor.getCancelText()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getClickToEditText())) {
                writer.append(", tooltip: '").append(inPlaceEditor.getClickToEditText()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getFieldPostCreation())) {
                writer.append(", fieldPostCreation: ");
                if (!"false".equals(inPlaceEditor.getFieldPostCreation())) {
                    writer.append("'");
                }
                writer.append(inPlaceEditor.getFieldPostCreation());
                if (!"false".equals(inPlaceEditor.getFieldPostCreation())) {
                    writer.append("'");
                }
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getFormClassName())) {
                writer.append(", cssclass: '").append(inPlaceEditor.getFormClassName()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getHighlightColor())) {
                writer.append(", highlightColor: '").append(inPlaceEditor.getHighlightColor()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getHighlightEndColor())) {
                writer.append(", highlightEndColor: '").append(inPlaceEditor.getHighlightEndColor()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getHoverClassName())) {
                writer.append(", hoverClassName: '").append(inPlaceEditor.getHoverClassName()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getHtmlResponse())) {
                writer.append(", htmlResponse: ").append(inPlaceEditor.getHtmlResponse());
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingClassName())) {
                writer.append(", loadingClassName: '").append(inPlaceEditor.getLoadingClassName()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingText())) {
                writer.append(", indicator: '").append(inPlaceEditor.getLoadingText()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkControl())) {
                writer.append(", submit: ");
                if (!"false".equals(inPlaceEditor.getOkControl())) {
                    writer.append("'");
                }
                writer.append(inPlaceEditor.getOkControl());
                if (!"false".equals(inPlaceEditor.getOkControl())) {
                    writer.append("'");
                }
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkText())) {
                writer.append(", okText: '").append(inPlaceEditor.getOkText()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getSavingClassName())) {
                writer.append(", savingClassName: '").append(inPlaceEditor.getSavingClassName()).append("', ");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getSavingText())) {
                writer.append(", savingText: '").append(inPlaceEditor.getSavingText()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getSubmitOnBlur())) {
                writer.append(", submitOnBlur: ").append(inPlaceEditor.getSubmitOnBlur());
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextBeforeControls())) {
                writer.append(", textBeforeControls: '").append(inPlaceEditor.getTextBeforeControls()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextAfterControls())) {
                writer.append(", textAfterControls: '").append(inPlaceEditor.getTextAfterControls()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextBetweenControls())) {
                writer.append(", textBetweenControls: '").append(inPlaceEditor.getTextBetweenControls()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getUpdateAfterRequestCall())) {
                writer.append(", updateAfterRequestCall: ").append(inPlaceEditor.getUpdateAfterRequestCall());
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getRows())) {
                writer.append(", rows: '").append(inPlaceEditor.getRows()).append("'");
            }
            if (UtilValidate.isNotEmpty(inPlaceEditor.getCols())) {
                writer.append(", cols: '").append(inPlaceEditor.getCols()).append("'");
            }
            writer.append("});");
            writer.append("</script>");
        }

        if (displayField instanceof DisplayEntityField) {
            this.makeHyperlinkString(writer, ((DisplayEntityField) displayField).getSubHyperlink(), context);
        }

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderHyperlinkField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.HyperlinkField)
     */
    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
        this.request.setAttribute("image", hyperlinkField.getImageLocation(context));
        ModelFormField modelFormField = hyperlinkField.getModelFormField();
        String description = encode(hyperlinkField.getDescription(context), modelFormField, context);
        String confirmation = encode(hyperlinkField.getConfirmation(context), modelFormField, context);
        WidgetWorker.makeHyperlinkByType(writer, hyperlinkField.getLinkType(), modelFormField.getWidgetStyle(), hyperlinkField.getTargetType(), hyperlinkField.getTarget(context),
                hyperlinkField.getParameterMap(context), description, hyperlinkField.getTargetWindow(context), confirmation, modelFormField,
                this.request, this.response, context);
        this.appendTooltip(writer, context, modelFormField);
        //appendWhitespace(writer);
    }

    public void makeHyperlinkString(Appendable writer, ModelFormField.SubHyperlink subHyperlink, Map<String, Object> context) throws IOException {
        if (subHyperlink == null) {
            return;
        }
        if (subHyperlink.shouldUse(context)) {
            writer.append(' ');
            String description = encode(subHyperlink.getDescription(context), subHyperlink.getModelFormField(), context);
            WidgetWorker.makeHyperlinkByType(writer, subHyperlink.getLinkType(), subHyperlink.getLinkStyle(), subHyperlink.getTargetType(), subHyperlink.getTarget(context),
                    subHyperlink.getParameterMap(context), description, subHyperlink.getTargetWindow(context), subHyperlink.getConfirmation(context), subHyperlink.getModelFormField(),
                    this.request, this.response, context);
        }
    }

    private String encode(String value, ModelFormField modelFormField, Map<String, Object> context) {
        if (UtilValidate.isEmpty(value)) {
            return value;
        }
        StringUtil.SimpleEncoder encoder = (StringUtil.SimpleEncoder)context.get("simpleEncoder");
        if (modelFormField.getEncodeOutput() && encoder != null) {
            value = encoder.encode(value);
        } else {
            value = internalEncoder.encode(value);
        }
        return value;
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.TextField)
     */
    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
        ModelFormField modelFormField = textField.getModelFormField();

        writer.append("<input type=\"text\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(textField.getSize()));
        writer.append('"');

        Integer maxlength = textField.getMaxlength();
        if (maxlength != null) {
            writer.append(" maxlength=\"");
            writer.append(maxlength.toString());
            writer.append('"');
        }

        String idName = modelFormField.getCurrentContainerId(context);
        if (UtilValidate.isNotEmpty(idName)) {
            writer.append(" id=\"");
            writer.append(idName);
            writer.append('"');
        }

        String event = modelFormField.getEvent();
        String action = modelFormField.getAction(context);
        if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
            writer.append(" ");
            writer.append(event);
            writer.append("=\"");
            writer.append(action);
            writer.append('"');
        }

        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
        if (!textField.getClientAutocompleteField() || ajaxEnabled) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append("/>");

        this.addAsterisks(writer, context, modelFormField);

        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);

        this.appendTooltip(writer, context, modelFormField);

        if (ajaxEnabled) {
            appendWhitespace(writer);
            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
            appendWhitespace(writer);
            writer.append("ajaxAutoCompleter('").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context)).append("');");
            appendWhitespace(writer);
            writer.append("</script>");
        }
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextareaField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.TextareaField)
     */
    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
        ModelFormField modelFormField = textareaField.getModelFormField();

        writer.append("<textarea");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        writer.append(" cols=\"");
        writer.append(Integer.toString(textareaField.getCols()));
        writer.append('"');

        writer.append(" rows=\"");
        writer.append(Integer.toString(textareaField.getRows()));
        writer.append('"');

        String idName = modelFormField.getCurrentContainerId(context);
        if (UtilValidate.isNotEmpty(idName)) {
            writer.append(" id=\"");
            writer.append(idName);
            writer.append('"');
        } else if (textareaField.getVisualEditorEnable()) {
            writer.append(" id=\"");
            writer.append("htmlEditArea");
            writer.append('"');
        }

        if (textareaField.isReadOnly()) {
            writer.append(" readonly");
        }

        writer.append('>');

        String value = modelFormField.getEntry(context, textareaField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(value);
        }

        writer.append("</textarea>");

        if (textareaField.getVisualEditorEnable()) {
            writer.append("<script language=\"javascript\" src=\"/images/jquery/plugins/elrte-1.3/js/elrte.min.js\" type=\"text/javascript\"></script>");
            writer.append("<link href=\"/images/jquery/plugins/elrte-1.3/css/elrte.min.css\" rel=\"stylesheet\" type=\"text/css\">");
            writer.append("<script language=\"javascript\" type=\"text/javascript\"> var opts = { cssClass : 'el-rte', toolbar : ");
            // define the toolsbar
            String buttons = textareaField.getVisualEditorButtons(context);
            if (UtilValidate.isNotEmpty(buttons)) {
                writer.append(buttons);
            } else {
                writer.append("maxi");
            }
            writer.append(", doctype  : '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">', //'<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\">'");
            writer.append(", cssfiles : ['/images/jquery/plugins/elrte-1.3/css/elrte-inner.css'] ");
            writer.append("}");
            // load the wysiwyg editor
            writer.append("jQuery('#");
            if (UtilValidate.isNotEmpty(idName)) {
                writer.append(idName);
            } else {
                writer.append("htmlEditArea");
            }
            writer.append("').elrte(opts);");
            writer.append("</script>");
        }

        this.addAsterisks(writer, context, modelFormField);

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderDateTimeField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DateTimeField)
     */
    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
        String macroLibraryPath = UtilProperties.getPropertyValue("widget", "screen.formrenderer");
        try {
            MacroFormRenderer macroFormRenderer = new MacroFormRenderer(macroLibraryPath, this.request, this.response);
            macroFormRenderer.renderDateTimeField(writer, context, dateTimeField);
        } catch (TemplateException e) {
            Debug.logError(e, "Error rendering screen thru ftl macro: renderDateTimeField", module);
        } catch (IOException e) {
            Debug.logError(e, "Error rendering screen thru ftl, macro: renderDateTimeField", module);
        }
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderDropDownField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DropDownField)
     */
    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
        ModelFormField modelFormField = dropDownField.getModelFormField();
        ModelForm modelForm = modelFormField.getModelForm();
        ModelFormField.AutoComplete autoComplete = dropDownField.getAutoComplete();
        boolean ajaxEnabled = autoComplete != null && this.javaScriptEnabled;
        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));

        String event = modelFormField.getEvent();
        String action = modelFormField.getAction(context);

        String currentValue = modelFormField.getEntry(context);
        // Get the current value's description from the option value. If there
        // is a localized version it will be there.
        String currentDescription = null;
        if (UtilValidate.isNotEmpty(currentValue)) {
            for (ModelFormField.OptionValue optionValue : allOptionValues) {
                if (encode(optionValue.getKey(), modelFormField, context).equals(currentValue)) {
                    currentDescription = optionValue.getDescription();
                    break;
                }
            }
        }

        if (ajaxEnabled) {
            writer.append("<input type=\"text\"");
        } else {
            writer.append("<select");
        }

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));

        String idName = modelFormField.getCurrentContainerId(context);

        if (ajaxEnabled) {
            writer.append("_description\"");

            String textFieldIdName = idName;
            if (UtilValidate.isNotEmpty(textFieldIdName)) {
                textFieldIdName += "_description";
                writer.append(" id=\"");
                writer.append(textFieldIdName);
                writer.append('"');
            }

            if (UtilValidate.isNotEmpty(currentValue)) {
                writer.append(" value=\"");
                String explicitDescription = null;
                if (currentDescription != null) {
                    explicitDescription = currentDescription;
                } else {
                    explicitDescription = dropDownField.getCurrentDescription(context);
                }
                if (UtilValidate.isEmpty(explicitDescription)) {
                    explicitDescription = FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues);
                }
                explicitDescription = encode(explicitDescription, modelFormField, context);
                writer.append(explicitDescription);
                writer.append('"');
            }
            writer.append("/>");

            appendWhitespace(writer);
            writer.append("<input type=\"hidden\" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append('"');
            if (UtilValidate.isNotEmpty(idName)) {
                writer.append(" id=\"");
                writer.append(idName);
                writer.append('"');
            }

            if (UtilValidate.isNotEmpty(currentValue)) {
                writer.append(" value=\"");
                //String explicitDescription = dropDownField.getCurrentDescription(context);
                writer.append(currentValue);
                writer.append('"');
            }

            writer.append("/>");

            appendWhitespace(writer);
            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
            appendWhitespace(writer);
            writer.append("var data = {");
            int count = 0;
            for (ModelFormField.OptionValue optionValue: allOptionValues) {
                count++;
                writer.append(optionValue.getKey()).append(": ");
                writer.append(" '").append(optionValue.getDescription()).append("'");
                if (count != allOptionValues.size()) {
                    writer.append(", ");
                }
            }
            writer.append("};");
            appendWhitespace(writer);
            writer.append("ajaxAutoCompleteDropDown('").append(textFieldIdName).append("', '").append(idName).append("', data, {autoSelect: ").append(
                    autoComplete.getAutoSelect()).append(", frequency: ").append(autoComplete.getFrequency()).append(", minChars: ").append(autoComplete.getMinChars()).append(
                    ", choices: ").append(autoComplete.getChoices()).append(", partialSearch: ").append(autoComplete.getPartialSearch()).append(
                    ", partialChars: ").append(autoComplete.getPartialChars()).append(", ignoreCase: ").append(autoComplete.getIgnoreCase()).append(
                    ", fullSearch: ").append(autoComplete.getFullSearch()).append("});");
            appendWhitespace(writer);
            writer.append("</script>");
        } else {
            writer.append('"');

            if (UtilValidate.isNotEmpty(idName)) {
                writer.append(" id=\"");
                writer.append(idName);
                writer.append('"');
            }

            if (dropDownField.isAllowMultiple()) {
                writer.append(" multiple=\"multiple\"");
            }

            int otherFieldSize = dropDownField.getOtherFieldSize();
            String otherFieldName = dropDownField.getParameterNameOther(context);
            if (otherFieldSize > 0) {
                //writer.append(" onchange=\"alert('ONCHANGE, process_choice:' + process_choice)\"");
                //writer.append(" onchange='test_js()' ");
                writer.append(" onchange=\"process_choice(this,document.");
                writer.append(modelForm.getName());
                writer.append(".");
                writer.append(otherFieldName);
                writer.append(")\" ");
            }

            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
                writer.append(" ");
                writer.append(event);
                writer.append("=\"");
                writer.append(action);
                writer.append('"');
            }

            writer.append(" size=\"").append(dropDownField.getSize()).append("\">");

            // if the current value should go first, stick it in
            if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
                writer.append("<option");
                writer.append(" selected=\"selected\"");
                writer.append(" value=\"");
                writer.append(currentValue);
                writer.append("\">");
                String explicitDescription = (currentDescription != null ? currentDescription : dropDownField.getCurrentDescription(context));
                if (UtilValidate.isNotEmpty(explicitDescription)) {
                    writer.append(encode(explicitDescription, modelFormField, context));
                } else {
                    String description = FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues);
                    writer.append(encode(description, modelFormField, context));
                }
                writer.append("</option>");

                // add a "separator" option
                writer.append("<option value=\"");
                writer.append(currentValue);
                writer.append("\">---</option>");
            }

            // if allow empty is true, add an empty option
            if (dropDownField.isAllowEmpty()) {
                writer.append("<option value=\"\">&nbsp;</option>");
            }

            // list out all options according to the option list
            for (ModelFormField.OptionValue optionValue: allOptionValues) {
                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
                writer.append("<option");
                // if current value should be selected in the list, select it
                if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) {
                    writer.append(" selected=\"selected\"");
                } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) {
                    writer.append(" selected=\"selected\"");
                }
                writer.append(" value=\"");
                writer.append(encode(optionValue.getKey(), modelFormField, context));
                writer.append("\">");
                writer.append(encode(optionValue.getDescription(), modelFormField, context));
                writer.append("</option>");
            }

            writer.append("</select>");


            // Adapted from work by Yucca Korpela
            // http://www.cs.tut.fi/~jkorpela/forms/combo.html
            if (otherFieldSize > 0) {

                String fieldName = modelFormField.getParameterName(context);
                Map<String, Object> dataMap = UtilGenerics.checkMap(modelFormField.getMap(context));
                if (dataMap == null) {
                    dataMap = context;
                }
                Object otherValueObj = dataMap.get(otherFieldName);
                String otherValue = (otherValueObj == null) ? "" : otherValueObj.toString();

                writer.append("<noscript>");
                writer.append("<input type='text' name='");
                writer.append(otherFieldName);
                writer.append("'/> ");
                writer.append("</noscript>");
                writer.append("\n<script type='text/javascript' language='JavaScript'><!--");
                writer.append("\ndisa = ' disabled';");
                writer.append("\nif (other_choice(document.");
                writer.append(modelForm.getName());
                writer.append(".");
                writer.append(fieldName);
                writer.append(")) disa = '';");
                writer.append("\ndocument.write(\"<input type=");
                writer.append("'text' name='");
                writer.append(otherFieldName);
                writer.append("' value='");
                writer.append(otherValue);
                writer.append("' size='");
                writer.append(Integer.toString(otherFieldSize));
                writer.append("' ");
                writer.append("\" +disa+ \" onfocus='check_choice(document.");
                writer.append(modelForm.getName());
                writer.append(".");
                writer.append(fieldName);
                writer.append(")'/>\");");
                writer.append("\nif (disa && document.styleSheets)");
                writer.append(" document.");
                writer.append(modelForm.getName());
                writer.append(".");
                writer.append(otherFieldName);
                writer.append(".style.visibility  = 'hidden';");
                writer.append("\n//--></script>");
            }
        }

        this.makeHyperlinkString(writer, dropDownField.getSubHyperlink(), context);

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderCheckField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.CheckField)
     */
    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
        ModelFormField modelFormField = checkField.getModelFormField();
        String currentValue = modelFormField.getEntry(context);
        Boolean allChecked = checkField.isAllChecked(context);

        List<ModelFormField.OptionValue> allOptionValues = checkField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
        String event = modelFormField.getEvent();
        String action = modelFormField.getAction(context);

        // list out all options according to the option list
        for (ModelFormField.OptionValue optionValue: allOptionValues) {

            writer.append("<input type=\"checkbox\"");

            appendClassNames(writer, context, modelFormField);

            // if current value should be selected in the list, select it
            if (Boolean.TRUE.equals(allChecked)) {
                writer.append(" checked=\"checked\"");
            } else if (Boolean.FALSE.equals(allChecked)) {
                // do nothing
            } else if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey())) {
                writer.append(" checked=\"checked\"");
            }
            writer.append(" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append('"');
            writer.append(" value=\"");
            writer.append(encode(optionValue.getKey(), modelFormField, context));
            writer.append("\"");

            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
                writer.append(" ");
                writer.append(event);
                writer.append("=\"");
                writer.append(action);
                writer.append('"');
            }

            writer.append("/>");

            writer.append(encode(optionValue.getDescription(), modelFormField, context));
        }

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderRadioField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.RadioField)
     */
    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
        ModelFormField modelFormField = radioField.getModelFormField();
        List<ModelFormField.OptionValue> allOptionValues = radioField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
        String currentValue = modelFormField.getEntry(context);
        String event = modelFormField.getEvent();
        String action = modelFormField.getAction(context);

        // list out all options according to the option list
        for (ModelFormField.OptionValue optionValue: allOptionValues) {

            writer.append("<span");

            appendClassNames(writer, context, modelFormField);

            writer.append("><input type=\"radio\"");

            // if current value should be selected in the list, select it
            String noCurrentSelectedKey = radioField.getNoCurrentSelectedKey(context);
            if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey())) {
                writer.append(" checked=\"checked\"");
            } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) {
                writer.append(" checked=\"checked\"");
            }
            writer.append(" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append('"');
            writer.append(" value=\"");
            writer.append(encode(optionValue.getKey(), modelFormField, context));
            writer.append("\"");

            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
                writer.append(" ");
                writer.append(event);
                writer.append("=\"");
                writer.append(action);
                writer.append('"');
            }

            writer.append("/>");

            writer.append(encode(optionValue.getDescription(), modelFormField, context));
            writer.append("</span>");
        }

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderSubmitField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.SubmitField)
     */
    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
        ModelFormField modelFormField = submitField.getModelFormField();
        ModelForm modelForm = modelFormField.getModelForm();
        String event = null;
        String action = null;
        String confirmation =  encode(submitField.getConfirmation(context), modelFormField, context);

        if ("text-link".equals(submitField.getButtonType())) {
            writer.append("<a");

            appendClassNames(writer, context, modelFormField);
            if (UtilValidate.isNotEmpty(confirmation)) {
                writer.append(" onclick=\"return confirm('");
                writer.append(confirmation);
                writer.append("'); \" ");
            }

            writer.append(" href=\"javascript:document.");
            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
            writer.append(".submit()\">");

            writer.append(encode(modelFormField.getTitle(context), modelFormField, context));

            writer.append("</a>");
        } else if ("image".equals(submitField.getButtonType())) {
            writer.append("<input type=\"image\"");

            appendClassNames(writer, context, modelFormField);

            writer.append(" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append('"');

            String title = modelFormField.getTitle(context);
            if (UtilValidate.isNotEmpty(title)) {
                writer.append(" alt=\"");
                writer.append(encode(title, modelFormField, context));
                writer.append('"');
            }

            writer.append(" src=\"");
            this.appendContentUrl(writer, submitField.getImageLocation(context));
            writer.append('"');

            event = modelFormField.getEvent();
            action = modelFormField.getAction(context);
            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
                writer.append(" ");
                writer.append(event);
                writer.append("=\"");
                writer.append(action);
                writer.append('"');
            }

            if (UtilValidate.isNotEmpty(confirmation)) {
                writer.append("onclick=\" return confirm('");
                writer.append(confirmation);
                writer.append("); \" ");
            }

            writer.append("/>");
        } else {
            // default to "button"

            String formId = modelForm.getContainerId();
            List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSubmitUpdateAreas();
            // This is here for backwards compatibility. Use on-event-update-area
            // elements instead.
            String backgroundSubmitRefreshTarget = submitField.getBackgroundSubmitRefreshTarget(context);
            if (UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) {
                if (updateAreas == null) {
                    updateAreas = new LinkedList<ModelForm.UpdateArea>();
                }
                updateAreas.add(new ModelForm.UpdateArea("submit", formId, backgroundSubmitRefreshTarget));
            }

            boolean ajaxEnabled = (UtilValidate.isNotEmpty(updateAreas) || UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) && this.javaScriptEnabled;
            if (ajaxEnabled) {
                writer.append("<input type=\"button\"");
            } else {
                writer.append("<input type=\"submit\"");
            }

            appendClassNames(writer, context, modelFormField);

            writer.append(" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append('"');

            String title = modelFormField.getTitle(context);
            if (UtilValidate.isNotEmpty(title)) {
                writer.append(" value=\"");
                writer.append(encode(title, modelFormField, context));
                writer.append('"');
            }


            event = modelFormField.getEvent();
            action = modelFormField.getAction(context);
            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
                writer.append(" ");
                writer.append(event);
                writer.append("=\"");
                writer.append(action);
                writer.append('"');
            } else {
                //add single click JS onclick
                // disabling for now, using form onSubmit action instead: writer.append(singleClickAction);
            }

            if (ajaxEnabled) {
                writer.append(" onclick=\"");
                if (UtilValidate.isNotEmpty(confirmation)) {
                    writer.append("if  (confirm('");
                    writer.append(confirmation);
                    writer.append(");) ");
                }
                writer.append("ajaxSubmitFormUpdateAreas('");
                writer.append(formId);
                writer.append("', '").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context));
                writer.append("')\"");
            }

            writer.append("/>");
        }

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderResetField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.ResetField)
     */
    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
        ModelFormField modelFormField = resetField.getModelFormField();

        writer.append("<input type=\"reset\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        String title = modelFormField.getTitle(context);
        if (UtilValidate.isNotEmpty(title)) {
            writer.append(" value=\"");
            writer.append(encode(title, modelFormField, context));
            writer.append('"');
        }

        writer.append("/>");

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderHiddenField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.HiddenField)
     */
    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
        ModelFormField modelFormField = hiddenField.getModelFormField();
        String value = hiddenField.getValue(context);
        this.renderHiddenField(writer, context, modelFormField, value);
    }

    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
        writer.append("<input type=\"hidden\"");

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append("/>");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderIgnoredField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.IgnoredField)
     */
    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) throws IOException {
        // do nothing, it's an ignored field; could add a comment or something if we wanted to
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFieldTitle(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
        String tempTitleText = modelFormField.getTitle(context);
        String titleText = UtilHttp.encodeAmpersands(tempTitleText);

        if (UtilValidate.isNotEmpty(titleText)) {
            // copied from MacroFormRenderer renderFieldTitle
            String displayHelpText = UtilProperties.getPropertyValue("widget.properties", "widget.form.displayhelpText");
            String helpText = null;
            if ("Y".equals(displayHelpText)) {
                Delegator delegator = WidgetWorker.getDelegator(context);
                Locale locale = (Locale)context.get("locale");
                String entityName = modelFormField.getEntityName();
                String fieldName = modelFormField.getFieldName();
                helpText = UtilHelpText.getEntityFieldDescription(entityName, fieldName, delegator, locale);
            }
            if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle()) || UtilValidate.isNotEmpty(helpText)) {
                writer.append("<span");
                if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())){
                    writer.append(" class=\"");
                    writer.append(modelFormField.getTitleStyle());
                }
                if (UtilValidate.isNotEmpty(helpText)){
                    writer.append(" title=\"");
                    writer.append(FreeMarkerWorker.encodeDoubleQuotes(helpText));
                }
                writer.append("\">");
            }
            if (" ".equals(titleText)) {
                // If the title content is just a blank then render it colling renderFormatEmptySpace:
                // the method will set its content to work fine in most browser
                this.renderFormatEmptySpace(writer, context, modelFormField.getModelForm());
            } else {
                renderHyperlinkTitle(writer, context, modelFormField, titleText);
            }

            if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
                writer.append("</span>");
            }

            //appendWhitespace(writer);
        }
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFieldTitle(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
        boolean requiredField = modelFormField.getRequiredField();
        if (requiredField) {

            String requiredStyle = modelFormField.getRequiredFieldStyle();
            if (UtilValidate.isEmpty(requiredStyle)) {
                requiredStyle = modelFormField.getTitleStyle();
            }

            if (UtilValidate.isNotEmpty(requiredStyle)) {
                writer.append("<span class=\"");
                writer.append(requiredStyle);
                writer.append("\">");
            }
            renderHyperlinkTitle(writer, context, modelFormField, modelFormField.getTitle(context));
            if (UtilValidate.isNotEmpty(requiredStyle)) {
                writer.append("</span>");
            }

            //appendWhitespace(writer);
        } else {
            renderFieldTitle(writer, context, modelFormField);
        }
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
        renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
        writer.append("<form method=\"post\" ");
        String targetType = modelForm.getTargetType();
        String targ = modelForm.getTarget(context, targetType);
        // The 'action' attribute is mandatory in a form definition,
        // even if it is empty.
        writer.append(" action=\"");
        if (UtilValidate.isNotEmpty(targ)) {
            //this.appendOfbizUrl(writer, "/" + targ);
            WidgetWorker.buildHyperlinkUrl(writer, targ, targetType, null, null, false, false, true, request, response, context);
        }
        writer.append("\" ");

        String formType = modelForm.getType();
        if (formType.equals("upload")) {
            writer.append(" enctype=\"multipart/form-data\"");
        }

        String targetWindow = modelForm.getTargetWindow(context);
        if (UtilValidate.isNotEmpty(targetWindow)) {
            writer.append(" target=\"");
            writer.append(targetWindow);
            writer.append("\"");
        }

        String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
        if (UtilValidate.isNotEmpty(containerId)) {
            writer.append(" id=\"");
            writer.append(containerId);
            writer.append("\"");
        }

        writer.append(" class=\"");
        String containerStyle =  modelForm.getContainerStyle();
        if (UtilValidate.isNotEmpty(containerStyle)) {
            writer.append(containerStyle);
        } else {
            writer.append("basic-form");
        }
        writer.append("\"");

        writer.append(" onsubmit=\"javascript:submitFormDisableSubmits(this)\"");

        if (!modelForm.getClientAutocompleteFields()) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append(" name=\"");
        writer.append(FormRenderer.getCurrentContainerId(modelForm, context));
        writer.append("\">");

        boolean useRowSubmit = modelForm.getUseRowSubmit();
        if (useRowSubmit) {
            writer.append("<input type=\"hidden\" name=\"_useRowSubmit\" value=\"Y\"/>");
        }

        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("</form>");
        String focusFieldName = modelForm.getfocusFieldName();
        if (UtilValidate.isNotEmpty(focusFieldName)) {
            appendWhitespace(writer);
            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
            appendWhitespace(writer);
            writer.append("document.").append(FormRenderer.getCurrentFormName(modelForm, context)).append(".");
            writer.append(focusFieldName).append(".focus();");
            appendWhitespace(writer);
            writer.append("</script>");
        }
        appendWhitespace(writer);
        renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        for (ModelFormField submitField: modelForm.getMultiSubmitFields()) {
            if (submitField != null) {

                // Threw this in that as a hack to keep the submit button from expanding the first field
                // Needs a more rugged solution
                // WARNING: this method (renderMultiFormClose) must be called after the
                // table that contains the list has been closed (to avoid validation errors) so
                // we cannot call here the methods renderFormatItemRowCell*: for this reason
                // they are now commented.

                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);

                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);

                submitField.renderFieldString(writer, context, this);

                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);

            }
        }
        writer.append("</form>");
        appendWhitespace(writer);

        // see if there is anything that needs to be added outside of the multi-form
        Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
        Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
        if (postMultiFormWriter != null) {
            writer.append(postMultiFormWriter.toString());
            appendWhitespace(writer);
        }

        renderEndingBoundaryComment(writer, "Form Widget - Form Element (Multi)", modelForm);
    }

    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {

        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
        if (UtilValidate.isNotEmpty(queryStringMap)) {
            inputFields.putAll(queryStringMap);
        }
        if (modelForm.getType().equals("multi")) {
            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
        }
        String queryString = UtilHttp.urlEncodeArgs(inputFields);
        context.put("_QBESTRING_", queryString);

        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);

        if (this.renderPagination) {
            this.renderNextPrev(writer, context, modelForm);
        }
        writer.append(" <table cellspacing=\"0\" class=\"");
        if (UtilValidate.isNotEmpty(modelForm.getDefaultTableStyle())) {
            writer.append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context));
        } else {
            writer.append("basic-table form-widget-table dark-grid");
        }
        writer.append("\">");
        appendWhitespace(writer);
    }

    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append(" </table>");

        appendWhitespace(writer);
        if (this.renderPagination) {
            this.renderNextPrev(writer, context, modelForm);
        }
        renderEndingBoundaryComment(writer, "Form Widget - Formal List Wrapper", modelForm);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("  <tr");
        String headerStyle = FlexibleStringExpander.expandString(modelForm.getHeaderRowStyle(), context);
        writer.append(" class=\"");
        if (UtilValidate.isNotEmpty(headerStyle)) {
            writer.append(headerStyle);
        } else {
            writer.append("header-row");
        }
        writer.append("\">");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("  </tr>");

        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField, int positionSpan)
     */
    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
        writer.append("   <td");
        String areaStyle = modelFormField.getTitleAreaStyle();
        if (positionSpan > 1) {
            writer.append(" colspan=\"");
            writer.append(Integer.toString(positionSpan));
            writer.append("\"");
        }
        if (UtilValidate.isNotEmpty(areaStyle)) {
            writer.append(" class=\"");
            writer.append(areaStyle);
            writer.append("\"");
        }
        writer.append(">");
        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
        writer.append("</td>");
        appendWhitespace(writer);
    }

    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("   <td");
        String areaStyle = modelForm.getFormTitleAreaStyle();
        if (UtilValidate.isNotEmpty(areaStyle)) {
            writer.append(" class=\"");
            writer.append(areaStyle);
            writer.append("\"");
        }
        writer.append(">");
        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowFormCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("</td>");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowFormCellTitleSeparator(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, boolean)
     */
    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {

        String titleStyle = modelFormField.getTitleStyle();
        if (UtilValidate.isNotEmpty(titleStyle)) {
            writer.append("<span class=\"");
            writer.append(titleStyle);
            writer.append("\">");
        }
        if (isLast) {
            writer.append(" - ");
        } else {
            writer.append(" - ");
        }
        if (UtilValidate.isNotEmpty(titleStyle)) {
            writer.append("</span>");
        }
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        Integer itemIndex = (Integer)context.get("itemIndex");

        writer.append("  <tr");
        if (itemIndex!=null) {

            String altRowStyles = modelForm.getStyleAltRowStyle(context);
            if (itemIndex.intValue() % 2 == 0) {
                String evenRowStyle = modelForm.getEvenRowStyle();
                if (UtilValidate.isNotEmpty(evenRowStyle)) {
                    writer.append(" class=\"");
                    writer.append(evenRowStyle);
                    if (UtilValidate.isNotEmpty(altRowStyles)) {
                        writer.append(altRowStyles);
                    }
                    writer.append("\"");
                } else {
                    if (UtilValidate.isNotEmpty(altRowStyles)) {
                        writer.append(" class=\"");
                        writer.append(altRowStyles);
                        writer.append("\"");
                    }
                }
            } else {
                String oddRowStyle = FlexibleStringExpander.expandString(modelForm.getOddRowStyle(), context);
                if (UtilValidate.isNotEmpty(oddRowStyle)) {
                    writer.append(" class=\"");
                    writer.append(oddRowStyle);
                    if (UtilValidate.isNotEmpty(altRowStyles)) {
                        writer.append(altRowStyles);
                    }
                    writer.append("\"");
                } else {
                    if (UtilValidate.isNotEmpty(altRowStyles)) {
                        writer.append(" class=\"");
                        writer.append(altRowStyles);
                        writer.append("\"");
                    }
                }
            }
        }
        writer.append(">");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("  </tr>");

        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
        writer.append("   <td");
        String areaStyle = modelFormField.getWidgetAreaStyle();
        if (positionSpan > 1) {
            writer.append(" colspan=\"");
            writer.append(Integer.toString(positionSpan));
            writer.append("\"");
        }
        if (UtilValidate.isNotEmpty(areaStyle)) {
            writer.append(" class=\"");
            writer.append(areaStyle);
            writer.append("\"");
        }
        writer.append(">");
        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
        writer.append("</td>");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowFormCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("   <td");
        String areaStyle = modelForm.getFormWidgetAreaStyle();
        if (UtilValidate.isNotEmpty(areaStyle)) {
            writer.append(" class=\"");
            writer.append(areaStyle);
            writer.append("\"");
        }
        writer.append(">");
        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowFormCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("</td>");
        appendWhitespace(writer);
    }

    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append(" <table cellspacing=\"0\"");
        if (UtilValidate.isNotEmpty(modelForm.getDefaultTableStyle())) {
            writer.append(" class=\"").append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context)).append("\"");
        }
        writer.append(">");
        appendWhitespace(writer);
    }

    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append(" </table>");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("  <tr>");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
     */
    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("  </tr>");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowTitleCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
        writer.append("   <td");
        String areaStyle = modelFormField.getTitleAreaStyle();
        if (UtilValidate.isNotEmpty(areaStyle)) {
            writer.append(" class=\"");
            writer.append(areaStyle);
            writer.append("\"");
        } else {
            writer.append(" class=\"label\"");
        }
        writer.append(">");
        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowTitleCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
        writer.append("</td>");
        appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowSpacerCell(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
     */
    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
        // Embedded styling - bad idea
        //writer.append("<td>&nbsp;</td>");

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowWidgetCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField, int)
     */
    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
//        writer.append("<td width=\"");
//        if (nextPositionInRow != null || modelFormField.getPosition() > 1) {
//            writer.append("30");
//        } else {
//            writer.append("80");
//        }
//        writer.append("%\"");
        writer.append("   <td");
        if (positionSpan > 0) {
            writer.append(" colspan=\"");
            // do a span of 1 for this column, plus 3 columns for each spanned
            //position or each blank position that this will be filling in
            writer.append(Integer.toString(1 + (positionSpan * 3)));
            writer.append("\"");
        }
        String areaStyle = modelFormField.getWidgetAreaStyle();
        if (UtilValidate.isNotEmpty(areaStyle)) {
            writer.append(" class=\"");
            writer.append(areaStyle);
            writer.append("\"");
        }
        writer.append(">");

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowWidgetCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField, int)
     */
    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
        writer.append("</td>");
        appendWhitespace(writer);
    }

    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        writer.append("&nbsp;");
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.TextFindField)
     */
    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {

        ModelFormField modelFormField = textFindField.getModelFormField();

        String defaultOption = textFindField.getDefaultOption();
        Locale locale = (Locale)context.get("locale");
        if (!textFindField.getHideOptions()) {
            String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
            String opBeginsWith = UtilProperties.getMessage("conditional", "begins_with", locale);
            String opContains = UtilProperties.getMessage("conditional", "contains", locale);
            String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
            String opNotEqual = UtilProperties.getMessage("conditional", "not_equal", locale);
            writer.append(" <select name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append("_op\" class=\"selectBox\">");
            writer.append("<option value=\"equals\"").append(("equals".equals(defaultOption)? " selected": "")).append(">").append(opEquals).append("</option>");
            writer.append("<option value=\"like\"").append(("like".equals(defaultOption)? " selected": "")).append(">").append(opBeginsWith).append("</option>");
            writer.append("<option value=\"contains\"").append(("contains".equals(defaultOption)? " selected": "")).append(">").append(opContains).append("</option>");
            writer.append("<option value=\"empty\"").append(("empty".equals(defaultOption)? " selected": "")).append(">").append(opIsEmpty).append("</option>");
            writer.append("<option value=\"notEqual\"").append(("notEqual".equals(defaultOption)? " selected": "")).append(">").append(opNotEqual).append("</option>");
            writer.append("</select>");
        } else {
            writer.append(" <input type=\"hidden\" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append("_op\" value=\"").append(defaultOption).append("\"/>");
        }

        writer.append("<input type=\"text\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        String value = modelFormField.getEntry(context, textFindField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(textFindField.getSize()));
        writer.append('"');

        Integer maxlength = textFindField.getMaxlength();
        if (maxlength != null) {
            writer.append(" maxlength=\"");
            writer.append(maxlength.toString());
            writer.append('"');
        }

        if (!textFindField.getClientAutocompleteField()) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append("/>");

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append(" <span class=\"");
            writer.append(modelFormField.getTitleStyle());
            writer.append("\">");
        }

        String ignoreCase = UtilProperties.getMessage("conditional", "ignore_case", locale);
        boolean ignCase = textFindField.getIgnoreCase();

        if (!textFindField.getHideIgnoreCase()) {
            writer.append(" <input type=\"checkbox\" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append("_ic\" value=\"Y\"").append((ignCase ? " checked=\"checked\"" : "")).append("/>");
            writer.append(ignoreCase);
        } else {
            writer.append("<input type=\"hidden\" name=\"");
            writer.append(modelFormField.getParameterName(context));
            writer.append("_ic\" value=\"").append((ignCase ? "Y" : "")).append("\"/>");
        }

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append("</span>");
        }

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderRangeFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.RangeFindField)
     */
    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {

        ModelFormField modelFormField = rangeFindField.getModelFormField();
        Locale locale = (Locale)context.get("locale");
        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
        String opGreaterThanEquals = UtilProperties.getMessage("conditional", "greater_than_equals", locale);
        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
        String opLessThanEquals = UtilProperties.getMessage("conditional", "less_than_equals", locale);
        //String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);

        writer.append("<input type=\"text\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld0_value\"");

        String value = modelFormField.getEntry(context, rangeFindField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(rangeFindField.getSize()));
        writer.append('"');

        Integer maxlength = rangeFindField.getMaxlength();
        if (maxlength != null) {
            writer.append(" maxlength=\"");
            writer.append(maxlength.toString());
            writer.append('"');
        }

        if (!rangeFindField.getClientAutocompleteField()) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append("/>");

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append(" <span class=\"");
            writer.append(modelFormField.getTitleStyle());
            writer.append("\">");
        }

        String defaultOptionFrom = rangeFindField.getDefaultOptionFrom();
        writer.append(" <select name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld0_op\" class=\"selectBox\">");
        writer.append("<option value=\"equals\"").append(("equals".equals(defaultOptionFrom)? " selected": "")).append(">").append(opEquals).append("</option>");
        writer.append("<option value=\"greaterThan\"").append(("greaterThan".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThan).append("</option>");
        writer.append("<option value=\"greaterThanEqualTo\"").append(("greaterThanEqualTo".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThanEquals).append("</option>");
        writer.append("</select>");

        writer.append("</span>");

        writer.append(" <br/> ");

        writer.append("<input type=\"text\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld1_value\"");

        value = modelFormField.getEntry(context);
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(rangeFindField.getSize()));
        writer.append('"');

        if (maxlength != null) {
            writer.append(" maxlength=\"");
            writer.append(maxlength.toString());
            writer.append('"');
        }

        if (!rangeFindField.getClientAutocompleteField()) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append("/>");

        String defaultOptionThru = rangeFindField.getDefaultOptionThru();
        writer.append(" <select name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld1_op\" class=\"selectBox\">");
        writer.append("<option value=\"lessThan\"").append(("lessThan".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThan).append("</option>");
        writer.append("<option value=\"lessThanEqualTo\"").append(("lessThanEqualTo".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThanEquals).append("</option>");
        writer.append("</select>");

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append("</span>");
        }

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderDateFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DateFindField)
     */
    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
        ModelFormField modelFormField = dateFindField.getModelFormField();

        Locale locale = (Locale)context.get("locale");
        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
        String opSameDay = UtilProperties.getMessage("conditional", "same_day", locale);
        String opGreaterThanFromDayStart = UtilProperties.getMessage("conditional",
                                                "greater_than_from_day_start", locale);
        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
        String opUpToDay = UtilProperties.getMessage("conditional", "up_to_day", locale);
        String opUpThruDay = UtilProperties.getMessage("conditional", "up_thru_day", locale);
        String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);

        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
        if (uiLabelMap == null) {
            Debug.logWarning("Could not find uiLabelMap in context", module);
        }
        String localizedInputTitle = "", localizedIconTitle = "";

        writer.append("<input type=\"text\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld0_value\"");

        // the default values for a timestamp
        int size = 25;
        int maxlength = 30;

        if ("date".equals(dateFindField.getType())) {
            size = maxlength = 10;
            if (uiLabelMap != null) {
                localizedInputTitle = uiLabelMap.get("CommonFormatDate");
            }
        } else if ("time".equals(dateFindField.getType())) {
            size = maxlength = 8;
            if (uiLabelMap != null) {
                localizedInputTitle = uiLabelMap.get("CommonFormatTime");
            }
        } else {
            if (uiLabelMap != null) {
                localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
            }
        }
        writer.append(" title=\"");
        writer.append(localizedInputTitle);
        writer.append('"');

        String value = modelFormField.getEntry(context, dateFindField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            if (value.length() > maxlength) {
                value = value.substring(0, maxlength);
            }
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(size));
        writer.append('"');

        writer.append(" maxlength=\"");
        writer.append(Integer.toString(maxlength));
        writer.append('"');

        writer.append("/>");

        // search for a localized label for the icon
        if (uiLabelMap != null) {
            localizedIconTitle = uiLabelMap.get("CommonViewCalendar");
        }
        ModelForm modelForm = modelFormField.getModelForm();
        // add calendar pop-up button and seed data IF this is not a "time" type date-find
        if (!"time".equals(dateFindField.getType())) {
            if ("date".equals(dateFindField.getType())) {
                writer.append("<a href=\"javascript:call_cal_notime(document.");
            } else {
                writer.append("<a href=\"javascript:call_cal(document.");
            }
            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
            writer.append('.');
            writer.append(modelFormField.getParameterName(context));
            writer.append("_fld0_value,'");
            writer.append(UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context))));
            writer.append("');\">");

            writer.append("<img src=\"");
            this.appendContentUrl(writer, "/images/cal.gif");
            writer.append("\" width=\"16\" height=\"16\" border=\"0\" alt=\"");
            writer.append(localizedIconTitle);
            writer.append("\" title=\"");
            writer.append(localizedIconTitle);
            writer.append("\"/></a>");
        }

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append(" <span class=\"");
            writer.append(modelFormField.getTitleStyle());
            writer.append("\">");
        }

        String defaultOptionFrom = dateFindField.getDefaultOptionFrom();
        writer.append(" <select name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld0_op\" class=\"selectBox\">");
        writer.append("<option value=\"equals\"").append(("equals".equals(defaultOptionFrom)? " selected": "")).append(">").append(opEquals).append("</option>");
        writer.append("<option value=\"sameDay\"").append(("sameDay".equals(defaultOptionFrom)? " selected": "")).append(">").append(opSameDay).append("</option>");
        writer.append("<option value=\"greaterThanFromDayStart\"").append(("greaterThanFromDayStart".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThanFromDayStart).append("</option>");
        writer.append("<option value=\"greaterThan\"").append(("greaterThan".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThan).append("</option>");
        writer.append("</select>");

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append(" </span>");
        }

        writer.append(" <br/> ");

        writer.append("<input type=\"text\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld1_value\"");

        writer.append(" title=\"");
        writer.append(localizedInputTitle);
        writer.append('"');

        value = modelFormField.getEntry(context);
        if (UtilValidate.isNotEmpty(value)) {
            if (value.length() > maxlength) {
                value = value.substring(0, maxlength);
            }
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(size));
        writer.append('"');

        writer.append(" maxlength=\"");
        writer.append(Integer.toString(maxlength));
        writer.append('"');

        writer.append("/>");

        // add calendar pop-up button and seed data IF this is not a "time" type date-find
        if (!"time".equals(dateFindField.getType())) {
            if ("date".equals(dateFindField.getType())) {
                writer.append("<a href=\"javascript:call_cal_notime(document.");
            } else {
                writer.append("<a href=\"javascript:call_cal(document.");
            }
            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
            writer.append('.');
            writer.append(modelFormField.getParameterName(context));
            writer.append("_fld1_value,'");
            writer.append(UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context))));
            writer.append("');\">");

            writer.append("<img src=\"");
            this.appendContentUrl(writer, "/images/cal.gif");
            writer.append("\" width=\"16\" height=\"16\" border=\"0\" alt=\"");
            writer.append(localizedIconTitle);
            writer.append("\" title=\"");
            writer.append(localizedIconTitle);
            writer.append("\"/></a>");
        }

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append(" <span class=\"");
            writer.append(modelFormField.getTitleStyle());
            writer.append("\">");
        }

        String defaultOptionThru = dateFindField.getDefaultOptionThru();
        writer.append(" <select name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append("_fld1_op\" class=\"selectBox\">");
        writer.append("<option value=\"lessThan\"").append(("lessThan".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThan).append("</option>");
        writer.append("<option value=\"upToDay\"").append(("upToDay".equals(defaultOptionThru)? " selected": "")).append(">").append(opUpToDay).append("</option>");
        writer.append("<option value=\"upThruDay\"").append(("upThruDay".equals(defaultOptionThru)? " selected": "")).append(">").append(opUpThruDay).append("</option>");
        writer.append("<option value=\"empty\"").append(("empty".equals(defaultOptionThru)? " selected": "")).append(">").append(opIsEmpty).append("</option>");
        writer.append("</select>");

        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
            writer.append("</span>");
        }

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderLookupField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.LookupField)
     */
    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
        ModelFormField modelFormField = lookupField.getModelFormField();

        writer.append("<input type=\"text\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        String value = modelFormField.getEntry(context, lookupField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(lookupField.getSize()));
        writer.append('"');

        Integer maxlength = lookupField.getMaxlength();
        if (maxlength != null) {
            writer.append(" maxlength=\"");
            writer.append(maxlength.toString());
            writer.append('"');
        }

        String idName = modelFormField.getCurrentContainerId(context);
        if (UtilValidate.isNotEmpty(idName)) {
            writer.append(" id=\"");
            writer.append(idName);
            writer.append('"');
        }

        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
        if (!lookupField.getClientAutocompleteField() || ajaxEnabled) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append("/>");
        ModelForm modelForm = modelFormField.getModelForm();
        // add lookup pop-up button
        String descriptionFieldName = lookupField.getDescriptionFieldName();
        if (UtilValidate.isNotEmpty(descriptionFieldName)) {
            writer.append("<a href=\"javascript:call_fieldlookup3(document.");
            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
            writer.append('.');
            writer.append(modelFormField.getParameterName(context));
            writer.append(",'");
            writer.append(descriptionFieldName);
            writer.append(",'");
        } else {
            writer.append("<a href=\"javascript:call_fieldlookup2(document.");
            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
            writer.append('.');
            writer.append(modelFormField.getParameterName(context));
            writer.append(",'");
        }
        writer.append(appendExternalLoginKey(lookupField.getFormName(context)));
        writer.append("'");
        List<String> targetParameterList = lookupField.getTargetParameterList();
        for (String targetParameter: targetParameterList) {
            // named like: document.${formName}.${targetParameter}.value
            writer.append(", document.");
            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
            writer.append(".");
            writer.append(targetParameter);
            writer.append(".value");
        }
        writer.append(");\">");
        writer.append("<img src=\"");
        this.appendContentUrl(writer, "/images/fieldlookup.gif");
        writer.append("\" width=\"15\" height=\"14\" border=\"0\" alt=\"Lookup\"/></a>");

        this.addAsterisks(writer, context, modelFormField);

        this.makeHyperlinkString(writer, lookupField.getSubHyperlink(), context);
        this.appendTooltip(writer, context, modelFormField);

        if (ajaxEnabled) {
            appendWhitespace(writer);
            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
            appendWhitespace(writer);
            writer.append("ajaxAutoCompleter('").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context)).append("');");
            appendWhitespace(writer);
            writer.append("</script>");
        }
        appendWhitespace(writer);

        //appendWhitespace(writer);
    }

    protected String appendExternalLoginKey(String target) {
        String result = target;
        String sessionId = ";jsessionid=" + request.getSession().getId();
        int questionIndex = target.indexOf("?");
        if (questionIndex == -1) {
            result += sessionId;
        } else {
            result = result.replace("?", sessionId + "?");
        }
        return result;
    }

    private int getActualPageSize(Map<String, Object> context) {
        Integer value = (Integer) context.get("actualPageSize");
        return value != null ? value.intValue() : (getHighIndex(context) - getLowIndex(context));
    }

    private int getHighIndex(Map<String, Object> context) {
        Integer value = (Integer) context.get("highIndex");
        return value != null ? value.intValue() : 0;
    }

    private int getListSize(Map<String, Object> context) {
        Integer value = (Integer) context.get("listSize");
        return value != null ? value.intValue() : 0;
    }

    private int getLowIndex(Map<String, Object> context) {
        Integer value = (Integer) context.get("lowIndex");
        return value != null ? value.intValue() : 0;
    }

    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
        boolean ajaxEnabled = false;
        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
        String targetService = modelForm.getPaginateTarget(context);
        if (this.javaScriptEnabled) {
            if (UtilValidate.isNotEmpty(updateAreas)) {
                ajaxEnabled = true;
            }
        }
        if (targetService == null) {
            targetService = "${targetService}";
        }
        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
            Debug.logWarning("Cannot paginate because TargetService is empty for the form: " + modelForm.getName(), module);
            return;
        }

        // get the parameterized pagination index and size fields
        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);

        int viewIndex = Paginator.getViewIndex(modelForm, context);
        int viewSize = Paginator.getViewSize(modelForm, context);
        int listSize = getListSize(context);

        int lowIndex = getLowIndex(context);
        int highIndex = getHighIndex(context);
        int actualPageSize = getActualPageSize(context);

        // if this is all there seems to be (if listSize < 0, then size is unknown)
        if (actualPageSize >= listSize && listSize >= 0) return;

        // needed for the "Page" and "rows" labels
        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
        String pageLabel = "";
        String commonDisplaying = "";
        if (uiLabelMap == null) {
            Debug.logWarning("Could not find uiLabelMap in context", module);
        } else {
            pageLabel = uiLabelMap.get("CommonPage");
            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
            commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
        }

        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber)) viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber)) viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;

        String str = (String) context.get("_QBESTRING_");

        // strip legacy viewIndex/viewSize params from the query string
        String queryString = UtilHttp.stripViewParamsFromQueryString(str, "" + paginatorNumber);

        // strip parametrized index/size params from the query string
        HashSet<String> paramNames = new HashSet<String>();
        paramNames.add(viewIndexParam);
        paramNames.add(viewSizeParam);
        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);

        String anchor = "";
        String paginateAnchor = modelForm.getPaginateTargetAnchor();
        if (paginateAnchor != null) anchor = "#" + paginateAnchor;

        // Create separate url path String and request parameters String,
        // add viewIndex/viewSize parameters to request parameter String
        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
        StringBuilder prepLinkBuffer = new StringBuilder();
        String prepLinkQueryString = UtilHttp.getQueryStringFromTarget(targetService);
        if (prepLinkQueryString != null) {
            prepLinkBuffer.append(prepLinkQueryString);
        }
        if (prepLinkBuffer.indexOf("?") < 0) {
            prepLinkBuffer.append("?");
        } else if (prepLinkBuffer.indexOf("?", prepLinkBuffer.length() - 1) > 0) {
            prepLinkBuffer.append("&amp;");
        }
        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
            prepLinkBuffer.append(queryString).append("&amp;");
        }
        prepLinkBuffer.append(viewSizeParam).append("=").append(viewSize).append("&amp;").append(viewIndexParam).append("=");
        String prepLinkText = prepLinkBuffer.toString();
        if (ajaxEnabled) {
            // Prepare params for prototype.js
            prepLinkText = prepLinkText.replace("?", "");
            prepLinkText = prepLinkText.replace("&amp;", "&");
        }

        writer.append("<div class=\"").append(modelForm.getPaginateStyle()).append("\">");
        appendWhitespace(writer);
        writer.append(" <ul>");
        appendWhitespace(writer);

        String linkText;

        // First button
        writer.append("  <li class=\"").append(modelForm.getPaginateFirstStyle());
        if (viewIndex > 0) {
            writer.append("\"><a href=\"");
            if (ajaxEnabled) {
                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + 0 + anchor, context)).append("')");
            } else {
                linkText = prepLinkText + 0 + anchor;
                appendOfbizUrl(writer, urlPath + linkText);
            }
            writer.append("\">").append(modelForm.getPaginateFirstLabel(context)).append("</a>");
        } else {
            // disabled button
            writer.append("-disabled\">").append(modelForm.getPaginateFirstLabel(context));
        }
        writer.append("</li>");
        appendWhitespace(writer);

        // Previous button
        writer.append("  <li class=\"").append(modelForm.getPaginatePreviousStyle());
        if (viewIndex > 0) {
            writer.append("\"><a href=\"");
            if (ajaxEnabled) {
                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex - 1) + anchor, context)).append("')");
            } else {
                linkText = prepLinkText + (viewIndex - 1) + anchor;
                appendOfbizUrl(writer, urlPath + linkText);
            }
            writer.append("\">").append(modelForm.getPaginatePreviousLabel(context)).append("</a>");
        } else {
            // disabled button
            writer.append("-disabled\">").append(modelForm.getPaginatePreviousLabel(context));
        }
        writer.append("</li>");
        appendWhitespace(writer);

        // Page select dropdown
        if (listSize > 0 && this.javaScriptEnabled) {
            writer.append("  <li>").append(pageLabel).append(" <select name=\"page\" size=\"1\" onchange=\"");
            if (ajaxEnabled) {
                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + "' + this.value", context)).append(")");
            } else {
                linkText = prepLinkText;
                if (linkText.startsWith("/")) {
                    linkText = linkText.substring(1);
                }
                writer.append("location.href = '");
                appendOfbizUrl(writer, urlPath + linkText);
                writer.append("' + this.value;");
            }
            writer.append("\">");
            // actual value
            int page = 0;
            for (int i = 0; i < listSize;) {
                if (page == viewIndex) {
                    writer.append("<option selected value=\"");
                } else {
                    writer.append("<option value=\"");
                }
                writer.append(Integer.toString(page));
                writer.append("\">");
                writer.append(Integer.toString(1 + page));
                writer.append("</option>");
                // increment page and calculate next index
                page++;
                i = page * viewSize;
            }
            writer.append("</select></li>");
        }

        //  show row count
        writer.append("<li>");
        writer.append(commonDisplaying);
        writer.append("</li>");
        appendWhitespace(writer);

        // Next button
        writer.append("  <li class=\"").append(modelForm.getPaginateNextStyle());
        if (highIndex < listSize) {
            writer.append("\"><a href=\"");
            if (ajaxEnabled) {
                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex + 1) + anchor, context)).append("')");
            } else {
                linkText = prepLinkText + (viewIndex + 1) + anchor;
                appendOfbizUrl(writer, urlPath + linkText);
            }
            writer.append("\">").append(modelForm.getPaginateNextLabel(context)).append("</a>");
        } else {
            // disabled button
            writer.append("-disabled\">").append(modelForm.getPaginateNextLabel(context));
        }
        writer.append("</li>");
        appendWhitespace(writer);

        // Last button
        writer.append("  <li class=\"").append(modelForm.getPaginateLastStyle());
        if (highIndex < listSize) {
            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
            writer.append("\"><a href=\"");
            if (ajaxEnabled) {
                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + lastIndex + anchor, context)).append("')");
            } else {
                linkText = prepLinkText + lastIndex + anchor;
                appendOfbizUrl(writer, urlPath + linkText);
            }
            writer.append("\">").append(modelForm.getPaginateLastLabel(context)).append("</a>");
        } else {
            // disabled button
            writer.append("-disabled\">").append(modelForm.getPaginateLastLabel(context));
        }
        writer.append("</li>");
        appendWhitespace(writer);

        writer.append(" </ul>");
        appendWhitespace(writer);
        writer.append("</div>");
        appendWhitespace(writer);
    }

    public void renderSortField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
        boolean ajaxEnabled = false;
        ModelForm modelForm = modelFormField.getModelForm();
        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
        String targetService = modelForm.getPaginateTarget(context);
        if (this.javaScriptEnabled) {
            if (UtilValidate.isNotEmpty(updateAreas)) {
                ajaxEnabled = true;
            }
        }
        if (targetService == null) {
            targetService = "${targetService}";
        }
        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
            Debug.logWarning("Cannot sort because TargetService is empty for the form: " + modelForm.getName(), module);
            return;
        }

        String str = (String) context.get("_QBESTRING_");
        String oldSortField = modelForm.getSortField(context);
        String sortFieldStyle = modelFormField.getSortFieldStyle();

        // if the entry-name is defined use this instead of field name
        String columnField = modelFormField.getEntryName();
        if (UtilValidate.isEmpty(columnField)) {
            columnField = modelFormField.getFieldName();
        }

        // switch beetween asc/desc order
        String newSortField = columnField;
        if (UtilValidate.isNotEmpty(oldSortField)) {
            if (oldSortField.equals(columnField)) {
                newSortField = "-" + columnField;
                sortFieldStyle = modelFormField.getSortFieldStyleDesc();
            } else if (oldSortField.equals("-" + columnField)) {
                newSortField = columnField;
                sortFieldStyle = modelFormField.getSortFieldStyleAsc();
            }
        }

        //  strip sortField param from the query string
        HashSet<String> paramName = new HashSet<String>();
        paramName.add("sortField");
        String queryString = UtilHttp.stripNamedParamsFromQueryString(str, paramName);
        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
        StringBuilder prepLinkBuffer = new StringBuilder();
        String prepLinkQueryString = UtilHttp.getQueryStringFromTarget(targetService);
        if (prepLinkQueryString != null) {
            prepLinkBuffer.append(prepLinkQueryString);
        }
        if (prepLinkBuffer.indexOf("?") < 0) {
            prepLinkBuffer.append("?");
        } else if (prepLinkBuffer.indexOf("?", prepLinkBuffer.length() - 1) > 0) {
            prepLinkBuffer.append("&amp;");
        }
        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
            prepLinkBuffer.append(queryString).append("&amp;");
        }
        prepLinkBuffer.append("sortField").append("=").append(newSortField);
        String prepLinkText = prepLinkBuffer.toString();
        if (ajaxEnabled) {
            prepLinkText = prepLinkText.replace("?", "");
            prepLinkText = prepLinkText.replace("&amp;", "&");
        }

        writer.append("<a");
        if (UtilValidate.isNotEmpty(sortFieldStyle)) {
            writer.append(" class=\"");
            writer.append(sortFieldStyle);
            writer.append("\"");
        }

        writer.append(" href=\"");
        if (ajaxEnabled) {
            writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText, context)).append("')");
        } else {
            appendOfbizUrl(writer, urlPath + prepLinkText);
        }
        writer.append("\">").append(titleText).append("</a>");
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderFileField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.FileField)
     */
    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
        ModelFormField modelFormField = textField.getModelFormField();

        writer.append("<input type=\"file\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(textField.getSize()));
        writer.append('"');

        Integer maxlength = textField.getMaxlength();
        if (maxlength != null) {
            writer.append(" maxlength=\"");
            writer.append(maxlength.toString());
            writer.append('"');
        }

        if (!textField.getClientAutocompleteField()) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append("/>");

        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderPasswordField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.PasswordField)
     */
    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
        ModelFormField modelFormField = passwordField.getModelFormField();

        writer.append("<input type=\"password\"");

        appendClassNames(writer, context, modelFormField);

        writer.append(" name=\"");
        writer.append(modelFormField.getParameterName(context));
        writer.append('"');

        String value = modelFormField.getEntry(context, passwordField.getDefaultValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" value=\"");
            writer.append(value);
            writer.append('"');
        }

        writer.append(" size=\"");
        writer.append(Integer.toString(passwordField.getSize()));
        writer.append('"');

        Integer maxlength = passwordField.getMaxlength();
        if (maxlength != null) {
            writer.append(" maxlength=\"");
            writer.append(maxlength.toString());
            writer.append('"');
        }

        String idName = modelFormField.getCurrentContainerId(context);
        if (UtilValidate.isNotEmpty(idName)) {
            writer.append(" id=\"");
            writer.append(idName);
            writer.append('"');
        }

        if (!passwordField.getClientAutocompleteField()) {
            writer.append(" autocomplete=\"off\"");
        }

        writer.append("/>");

        this.addAsterisks(writer, context, modelFormField);

        this.makeHyperlinkString(writer, passwordField.getSubHyperlink(), context);

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    /* (non-Javadoc)
     * @see org.ofbiz.widget.form.FormStringRenderer#renderImageField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.ImageField)
     */
    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
        ModelFormField modelFormField = imageField.getModelFormField();

        writer.append("<img ");

        String value = modelFormField.getEntry(context, imageField.getValue(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" src=\"");
            appendContentUrl(writer, value);
            writer.append('"');
        }
        
        value = modelFormField.getEntry(context, imageField.getStyle(context));
        if (UtilValidate.isNotEmpty(value)) {
            writer.append(" class=\"");
            appendContentUrl(writer, value);
            writer.append('"');
        }

        String event = modelFormField.getEvent();
        String action = modelFormField.getAction(context);
        if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
            writer.append(" ");
            writer.append(event);
            writer.append("=\"");
            writer.append(action);
            writer.append('"');
        }

        writer.append("/>");

        this.makeHyperlinkString(writer, imageField.getSubHyperlink(), context);

        this.appendTooltip(writer, context, modelFormField);

        //appendWhitespace(writer);
    }

    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
        String style = fieldGroup.getStyle();
        String id = fieldGroup.getId();
        FlexibleStringExpander titleNotExpanded = FlexibleStringExpander.getInstance(fieldGroup.getTitle());
        String title = titleNotExpanded.expandString(context);
        Boolean collapsed = fieldGroup.initiallyCollapsed();
        String collapsibleAreaId = fieldGroup.getId() + "_body";

        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {

            writer.append("<div class=\"fieldgroup");
            if (UtilValidate.isNotEmpty(style)) {
                writer.append(" ");
                writer.append(style);
            }
            writer.append("\"");
            if (UtilValidate.isNotEmpty(id)) {
                writer.append(" id=\"");
                writer.append(id);
                writer.append("\"");
            }
            writer.append(">");

            writer.append("<div class=\"fieldgroup-title-bar\"><table><tr><td class=\"collapse\">");

            if (fieldGroup.collapsible()) {
                String expandToolTip = null;
                String collapseToolTip = null;
                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
                //Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
                if (uiLabelMap != null) {
                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
                }

                writer.append("<ul><li class=\"");
                if (collapsed) {
                    writer.append("collapsed\"><a ");
                    writer.append("onclick=\"javascript:toggleCollapsiblePanel(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
                } else {
                    writer.append("expanded\"><a ");
                    writer.append("onclick=\"javascript:toggleCollapsiblePanel(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
                }
                writer.append(">&nbsp&nbsp&nbsp</a></li></ul>");

                appendWhitespace(writer);
            }
            writer.append("</td><td>");

            if (UtilValidate.isNotEmpty(title)) {
                writer.append("<div class=\"title\">");
                writer.append(title);
                writer.append("</div>");
            }

            writer.append("</td></tr></table></div>");

            writer.append("<div id=\"").append(collapsibleAreaId).append("\" class=\"fieldgroup-body\"");
            if (fieldGroup.collapsible() && collapsed) {
                writer.append(" style=\"display: none;\"");
            }
            writer.append(">");
        }
    }

    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
        String style = fieldGroup.getStyle();
        String id = fieldGroup.getId();
        String title = fieldGroup.getTitle();
        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {
            writer.append("</div>");
            writer.append("</div>");
        }
    }

    // TODO: Remove embedded styling
    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
        writer.append(" <table width=\"100%\">  <tr>");
        String style = banner.getStyle(context);
        String leftStyle = banner.getLeftTextStyle(context);
        if (UtilValidate.isEmpty(leftStyle)) leftStyle = style;
        String rightStyle = banner.getRightTextStyle(context);
        if (UtilValidate.isEmpty(rightStyle)) rightStyle = style;

        String leftText = banner.getLeftText(context);
        if (UtilValidate.isNotEmpty(leftText)) {
            writer.append("   <td align=\"left\">");
            if (UtilValidate.isNotEmpty(leftStyle)) {
               writer.append("<div");
               writer.append(" class=\"");
               writer.append(leftStyle);
               writer.append("\"");
               writer.append(">");
            }
            writer.append(leftText);
            if (UtilValidate.isNotEmpty(leftStyle)) {
                writer.append("</div>");
            }
            writer.append("</td>");
        }

        String text = banner.getText(context);
        if (UtilValidate.isNotEmpty(text)) {
            writer.append("   <td align=\"center\">");
            if (UtilValidate.isNotEmpty(style)) {
               writer.append("<div");
               writer.append(" class=\"");
               writer.append(style);
               writer.append("\"");
               writer.append(">");
            }
            writer.append(text);
            if (UtilValidate.isNotEmpty(style)) {
                writer.append("</div>");
            }
            writer.append("</td>");
        }

        String rightText = banner.getRightText(context);
        if (UtilValidate.isNotEmpty(rightText)) {
            writer.append("   <td align=\"right\">");
            if (UtilValidate.isNotEmpty(rightStyle)) {
               writer.append("<div");
               writer.append(" class=\"");
               writer.append(rightStyle);
               writer.append("\"");
               writer.append(">");
            }
            writer.append(rightText);
            if (UtilValidate.isNotEmpty(rightStyle)) {
                writer.append("</div>");
            }
            writer.append("</td>");
        }
        writer.append("</tr> </table>");
    }

    /**
     * Renders a link for the column header fields when there is a header-link="" specified in the <field > tag, using
     * style from header-link-style="".  Also renders a selectAll checkbox in multi forms.
     * @param writer
     * @param context
     * @param modelFormField
     * @param titleText
     */
    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
        if (UtilValidate.isNotEmpty(modelFormField.getHeaderLink())) {
            StringBuilder targetBuffer = new StringBuilder();
            FlexibleStringExpander target = FlexibleStringExpander.getInstance(modelFormField.getHeaderLink());
            String fullTarget = target.expandString(context);
            targetBuffer.append(fullTarget);
            String targetType = HyperlinkField.DEFAULT_TARGET_TYPE;
            if (UtilValidate.isNotEmpty(targetBuffer.toString()) && targetBuffer.toString().toLowerCase().startsWith("javascript:")) {
                targetType="plain";
            }
            WidgetWorker.makeHyperlinkString(writer, modelFormField.getHeaderLinkStyle(), targetType, targetBuffer.toString(), null, titleText, null, modelFormField, this.request, this.response, null, null);
        } else if (modelFormField.isSortField()) {
            renderSortField (writer, context, modelFormField, titleText);
        } else if (modelFormField.isRowSubmit()) {
            if (UtilValidate.isNotEmpty(titleText)) writer.append(titleText).append("<br/>");
            writer.append("<input type=\"checkbox\" name=\"selectAll\" value=\"Y\" onclick=\"javascript:toggleAll(this, '");
            writer.append(modelFormField.getModelForm().getName());
            writer.append("');\"/>");
        } else {
             writer.append(titleText);
        }
    }

    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
        writer.append("<div ");
        String id = containerField.getModelFormField().getIdName();
        if (UtilValidate.isNotEmpty(id)) {
            writer.append("id=\"");
            writer.append(id);
            writer.append("\" ");
        }
        String className = containerField.getModelFormField().getWidgetStyle();
        if (UtilValidate.isNotEmpty(className)) {
            writer.append("class=\"");
            writer.append(className);
            writer.append("\" ");
        }
        writer.append("/>");
    }

    /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea objects. See
     * <code>selectall.js</code>.
     * @param updateAreas
     * @param extraParams Renderer-supplied additional target parameters
     * @param context
     * @return Parameter string or empty string if no UpdateArea objects were found
     */
    public String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, String extraParams, Map<String, ? extends Object> context) {
        if (updateAreas == null) {
            return "";
        }
        StringBuilder ajaxUrl = new StringBuilder();
        boolean firstLoop = true;
        for (ModelForm.UpdateArea updateArea : updateAreas) {
            if (firstLoop) {
                firstLoop = false;
            } else {
                ajaxUrl.append(",");
            }
            String targetUrl = updateArea.getAreaTarget(context);
            String ajaxParams = getAjaxParamsFromTarget(targetUrl);
            if (UtilValidate.isNotEmpty(extraParams)) {
                if (ajaxParams.length() > 0 && !extraParams.startsWith("&")) {
                    ajaxParams += "&";
                }
                ajaxParams += extraParams;
            }
            ajaxUrl.append(updateArea.getAreaId()).append(",");
            try {
                appendOfbizUrl(ajaxUrl, UtilHttp.removeQueryStringFromTarget(targetUrl));
            } catch (IOException e) {
                throw UtilMisc.initCause(new InternalError(e.getMessage()), e);
            }
            ajaxUrl.append(",").append(ajaxParams);
        }
        return ajaxUrl.toString();
    }
}
