All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.camunda.bpm.engine.impl.form.engine.AbstractRenderFormDelegate Maven / Gradle / Ivy

There is a newer version: 7.22.0-alpha1
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. Camunda licenses this file to you under the Apache License,
 * Version 2.0; 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.camunda.bpm.engine.impl.form.engine;

import org.camunda.bpm.engine.form.FormData;
import org.camunda.bpm.engine.form.FormField;
import org.camunda.bpm.engine.form.FormFieldValidationConstraint;
import org.camunda.bpm.engine.form.FormProperty;
import org.camunda.bpm.engine.impl.form.type.BooleanFormType;
import org.camunda.bpm.engine.impl.form.type.DateFormType;
import org.camunda.bpm.engine.impl.form.type.EnumFormType;
import org.camunda.bpm.engine.impl.form.type.StringFormType;

import java.util.List;
import java.util.Map;

/**
 * @author Askar Akhmerov
 */
public abstract class AbstractRenderFormDelegate {
  /* elements */
  protected static final String FORM_ELEMENT = "form";
  protected static final String DIV_ELEMENT = "div";
  protected static final String SPAN_ELEMENT = "span";
  protected static final String LABEL_ELEMENT = "label";
  protected static final String INPUT_ELEMENT = "input";
  protected static final String BUTTON_ELEMENT = "button";
  protected static final String SELECT_ELEMENT = "select";
  protected static final String OPTION_ELEMENT = "option";
  protected static final String I_ELEMENT = "i";
  protected static final String SCRIPT_ELEMENT = "script";

  /* attributes */
  protected static final String NAME_ATTRIBUTE = "name";
  protected static final String CLASS_ATTRIBUTE = "class";
  protected static final String ROLE_ATTRIBUTE = "role";
  protected static final String FOR_ATTRIBUTE = "for";
  protected static final String VALUE_ATTRIBUTE = "value";
  protected static final String TYPE_ATTRIBUTE = "type";
  protected static final String SELECTED_ATTRIBUTE = "selected";

  /* datepicker attributes*/
  protected static final String IS_OPEN_ATTRIBUTE = "is-open";
  protected static final String DATEPICKER_POPUP_ATTRIBUTE = "datepicker-popup";

  /* camunda attributes */
  protected static final String CAM_VARIABLE_TYPE_ATTRIBUTE = "cam-variable-type";
  protected static final String CAM_VARIABLE_NAME_ATTRIBUTE = "cam-variable-name";
  protected static final String CAM_SCRIPT_ATTRIBUTE = "cam-script";

  /* angular attributes*/
  protected static final String NG_CLICK_ATTRIBUTE = "ng-click";
  protected static final String NG_IF_ATTRIBUTE = "ng-if";
  protected static final String NG_SHOW_ATTRIBUTE = "ng-show";

  /* classes */
  protected static final String FORM_GROUP_CLASS = "form-group";
  protected static final String FORM_CONTROL_CLASS = "form-control";
  protected static final String INPUT_GROUP_CLASS = "input-group";
  protected static final String INPUT_GROUP_BTN_CLASS = "input-group-btn";
  protected static final String BUTTON_DEFAULT_CLASS = "btn btn-default";
  protected static final String HAS_ERROR_CLASS = "has-error";
  protected static final String HELP_BLOCK_CLASS = "help-block";

  /* input[type] */
  protected static final String TEXT_INPUT_TYPE = "text";
  protected static final String CHECKBOX_INPUT_TYPE = "checkbox";

  /* button[type] */
  protected static final String BUTTON_BUTTON_TYPE = "button";

  /* script[type] */
  protected static final String TEXT_FORM_SCRIPT_TYPE = "text/form-script";

  /* glyphicons */
  protected static final String CALENDAR_GLYPHICON = "glyphicon glyphicon-calendar";

  /* generated form name */
  protected static final String GENERATED_FORM_NAME = "generatedForm";
  protected static final String FORM_ROLE = "form";

  /* error types */
  protected static final String REQUIRED_ERROR_TYPE = "required";
  protected static final String DATE_ERROR_TYPE = "date";

  /* form element selector */
  protected static final String FORM_ELEMENT_SELECTOR = "this." + GENERATED_FORM_NAME + ".%s";

  /* expressions */
  protected static final String INVALID_EXPRESSION = FORM_ELEMENT_SELECTOR + ".$invalid";
  protected static final String DIRTY_EXPRESSION = FORM_ELEMENT_SELECTOR + ".$dirty";
  protected static final String ERROR_EXPRESSION = FORM_ELEMENT_SELECTOR + ".$error";
  protected static final String DATE_ERROR_EXPRESSION = ERROR_EXPRESSION + ".date";
  protected static final String REQUIRED_ERROR_EXPRESSION = ERROR_EXPRESSION + ".required";
  protected static final String TYPE_ERROR_EXPRESSION = ERROR_EXPRESSION + ".camVariableType";

  /* JavaScript snippets */
  protected static final String DATE_FIELD_OPENED_ATTRIBUTE = "dateFieldOpened%s";
  protected static final String OPEN_DATEPICKER_SNIPPET = "$scope.open%s = function ($event) { $event.preventDefault(); $event.stopPropagation(); $scope.dateFieldOpened%s = true; };";
  protected static final String OPEN_DATEPICKER_FUNCTION_SNIPPET = "open%s($event)";

  /* date format */
  protected static final String DATE_FORMAT = "dd/MM/yyyy";

  /* messages */
  protected static final String REQUIRED_FIELD_MESSAGE = "Required field";
  protected static final String TYPE_FIELD_MESSAGE = "Only a %s value is allowed";
  protected static final String INVALID_DATE_FIELD_MESSAGE = "Invalid date format: the date should have the pattern '" + DATE_FORMAT + "'";

  protected String renderFormData(FormData formData) {

    if(formData == null
        || (formData.getFormFields() == null || formData.getFormFields().isEmpty())
        && (formData.getFormProperties() == null || formData.getFormProperties().isEmpty())) {
      return null;

    } else {
      HtmlElementWriter formElement = new HtmlElementWriter(FORM_ELEMENT)
          .attribute(NAME_ATTRIBUTE, GENERATED_FORM_NAME)
          .attribute(ROLE_ATTRIBUTE, FORM_ROLE);

      HtmlDocumentBuilder documentBuilder = new HtmlDocumentBuilder(formElement);

      // render fields
      for (FormField formField : formData.getFormFields()) {
        renderFormField(formField, documentBuilder);
      }

      // render deprecated form properties
      for (FormProperty formProperty : formData.getFormProperties()) {
        renderFormField(new FormPropertyAdapter(formProperty), documentBuilder);
      }

      // end document element
      documentBuilder.endElement();

      return documentBuilder.getHtmlString();

    }
  }

  protected void renderFormField(FormField formField, HtmlDocumentBuilder documentBuilder) {
    // start group
    HtmlElementWriter divElement = new HtmlElementWriter(DIV_ELEMENT)
        .attribute(CLASS_ATTRIBUTE, FORM_GROUP_CLASS);

    documentBuilder.startElement(divElement);

    String formFieldId = formField.getId();
    String formFieldLabel = formField.getLabel();

    // write label
    if (formFieldLabel != null && !formFieldLabel.isEmpty()) {

      HtmlElementWriter labelElement = new HtmlElementWriter(LABEL_ELEMENT)
          .attribute(FOR_ATTRIBUTE, formFieldId)
          .textContent(formFieldLabel);

      // 
      documentBuilder.startElement(labelElement).endElement();
    }

    // render form control
    if(isEnum(formField)) {
      // 
      renderInputField(formField, documentBuilder);

    }

    renderInvalidMessageElement(formField, documentBuilder);

    // end group
    documentBuilder.endElement();
  }

  protected HtmlElementWriter createInputField(FormField formField) {
    HtmlElementWriter inputField = new HtmlElementWriter(INPUT_ELEMENT, true);

    addCommonFormFieldAttributes(formField, inputField);

    inputField.attribute(TYPE_ATTRIBUTE, TEXT_INPUT_TYPE);

    return inputField;
  }

  protected void renderDatePicker(FormField formField, HtmlDocumentBuilder documentBuilder) {
    boolean isReadOnly = isReadOnly(formField);

    // start input-group
    HtmlElementWriter inputGroupDivElement = new HtmlElementWriter(DIV_ELEMENT)
        .attribute(CLASS_ATTRIBUTE, INPUT_GROUP_CLASS);

    String formFieldId = formField.getId();

    // 
documentBuilder.startElement(inputGroupDivElement); // input field HtmlElementWriter inputField = createInputField(formField); if(!isReadOnly) { inputField .attribute(DATEPICKER_POPUP_ATTRIBUTE, DATE_FORMAT) .attribute(IS_OPEN_ATTRIBUTE, String.format(DATE_FIELD_OPENED_ATTRIBUTE, formFieldId)); } // documentBuilder .startElement(inputField) .endElement(); // if form field is read only, do not render date picker open button if(!isReadOnly) { // input addon HtmlElementWriter addonElement = new HtmlElementWriter(DIV_ELEMENT) .attribute(CLASS_ATTRIBUTE, INPUT_GROUP_BTN_CLASS); //
documentBuilder.startElement(addonElement); // button to open date picker HtmlElementWriter buttonElement = new HtmlElementWriter(BUTTON_ELEMENT) .attribute(TYPE_ATTRIBUTE, BUTTON_BUTTON_TYPE) .attribute(CLASS_ATTRIBUTE, BUTTON_DEFAULT_CLASS) .attribute(NG_CLICK_ATTRIBUTE, String.format(OPEN_DATEPICKER_FUNCTION_SNIPPET, formFieldId)); // documentBuilder.endElement(); //
documentBuilder.endElement(); HtmlElementWriter scriptElement = new HtmlElementWriter(SCRIPT_ELEMENT) .attribute(CAM_SCRIPT_ATTRIBUTE, null) .attribute(TYPE_ATTRIBUTE, TEXT_FORM_SCRIPT_TYPE) .textContent(String.format(OPEN_DATEPICKER_SNIPPET, formFieldId, formFieldId)); // documentBuilder .startElement(scriptElement) .endElement(); } //
documentBuilder.endElement(); } protected void renderInputField(FormField formField, HtmlDocumentBuilder documentBuilder) { HtmlElementWriter inputField = new HtmlElementWriter(INPUT_ELEMENT, true); addCommonFormFieldAttributes(formField, inputField); String inputType = !isBoolean(formField) ? TEXT_INPUT_TYPE : CHECKBOX_INPUT_TYPE; inputField.attribute(TYPE_ATTRIBUTE, inputType); // add default value Object defaultValue = formField.getDefaultValue(); if(defaultValue != null) { inputField.attribute(VALUE_ATTRIBUTE, defaultValue.toString()); } // documentBuilder.startElement(inputField).endElement(); } protected void renderSelectBox(FormField formField, HtmlDocumentBuilder documentBuilder) { HtmlElementWriter selectBox = new HtmlElementWriter(SELECT_ELEMENT, false); addCommonFormFieldAttributes(formField, selectBox); // documentBuilder.endElement(); } protected void renderSelectOptions(FormField formField, HtmlDocumentBuilder documentBuilder) { EnumFormType enumFormType = (EnumFormType) formField.getType(); Map values = enumFormType.getValues(); for (Map.Entry value : values.entrySet()) { //
documentBuilder.startElement(divElement); if (!isDate(formField)) { renderInvalidValueMessage(formField, documentBuilder); renderInvalidTypeMessage(formField, documentBuilder); } else { renderInvalidDateMessage(formField, documentBuilder); } documentBuilder.endElement(); } protected void renderInvalidValueMessage(FormField formField, HtmlDocumentBuilder documentBuilder) { HtmlElementWriter divElement = new HtmlElementWriter(DIV_ELEMENT); String formFieldId = formField.getId(); String expression = String.format(REQUIRED_ERROR_EXPRESSION, formFieldId); divElement .attribute(NG_SHOW_ATTRIBUTE, expression) .attribute(CLASS_ATTRIBUTE, HELP_BLOCK_CLASS) .textContent(REQUIRED_FIELD_MESSAGE); documentBuilder .startElement(divElement) .endElement(); } protected void renderInvalidTypeMessage(FormField formField, HtmlDocumentBuilder documentBuilder) { HtmlElementWriter divElement = new HtmlElementWriter(DIV_ELEMENT); String formFieldId = formField.getId(); String expression = String.format(TYPE_ERROR_EXPRESSION, formFieldId); String typeName = formField.getTypeName(); if (isEnum(formField)) { typeName = StringFormType.TYPE_NAME; } divElement .attribute(NG_SHOW_ATTRIBUTE, expression) .attribute(CLASS_ATTRIBUTE, HELP_BLOCK_CLASS) .textContent(String.format(TYPE_FIELD_MESSAGE, typeName)); documentBuilder .startElement(divElement) .endElement(); } protected void renderInvalidDateMessage(FormField formField, HtmlDocumentBuilder documentBuilder) { String formFieldId = formField.getId(); HtmlElementWriter firstDivElement = new HtmlElementWriter(DIV_ELEMENT); String firstExpression = String.format(REQUIRED_ERROR_EXPRESSION + " && !" + DATE_ERROR_EXPRESSION, formFieldId, formFieldId); firstDivElement .attribute(NG_SHOW_ATTRIBUTE, firstExpression) .attribute(CLASS_ATTRIBUTE, HELP_BLOCK_CLASS) .textContent(REQUIRED_FIELD_MESSAGE); documentBuilder .startElement(firstDivElement) .endElement(); HtmlElementWriter secondDivElement = new HtmlElementWriter(DIV_ELEMENT); String secondExpression = String.format(DATE_ERROR_EXPRESSION, formFieldId); secondDivElement .attribute(NG_SHOW_ATTRIBUTE, secondExpression) .attribute(CLASS_ATTRIBUTE, HELP_BLOCK_CLASS) .textContent(INVALID_DATE_FIELD_MESSAGE); documentBuilder .startElement(secondDivElement) .endElement(); } protected void addCommonFormFieldAttributes(FormField formField, HtmlElementWriter formControl) { String typeName = formField.getTypeName(); if (isEnum(formField) || isDate(formField)) { typeName = StringFormType.TYPE_NAME; } typeName = typeName.substring(0, 1).toUpperCase() + typeName.substring(1); String formFieldId = formField.getId(); formControl .attribute(CLASS_ATTRIBUTE, FORM_CONTROL_CLASS) .attribute(NAME_ATTRIBUTE, formFieldId) .attribute(CAM_VARIABLE_TYPE_ATTRIBUTE, typeName) .attribute(CAM_VARIABLE_NAME_ATTRIBUTE, formFieldId); // add validation constraints for (FormFieldValidationConstraint constraint : formField.getValidationConstraints()) { String constraintName = constraint.getName(); String configuration = (String) constraint.getConfiguration(); formControl.attribute(constraintName, configuration); } } // helper ///////////////////////////////////////////////////////////////////////////////////// protected boolean isEnum(FormField formField) { return EnumFormType.TYPE_NAME.equals(formField.getTypeName()); } protected boolean isDate(FormField formField) { return DateFormType.TYPE_NAME.equals(formField.getTypeName()); } protected boolean isBoolean(FormField formField) { return BooleanFormType.TYPE_NAME.equals(formField.getTypeName()); } protected boolean isReadOnly(FormField formField) { List validationConstraints = formField.getValidationConstraints(); if(validationConstraints != null) { for (FormFieldValidationConstraint validationConstraint : validationConstraints) { if(HtmlFormEngine.CONSTRAINT_READONLY.equals(validationConstraint.getName())){ return true; } } } return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy