diff --git a/extension/qfq/qfq/AbstractBuildForm.php b/extension/qfq/qfq/AbstractBuildForm.php
index 3f609589a76d2eb75c97ab2623efe13e72dd1a2a..0a863bcbcf02469899050a3920fb2bde68f4eb91 100644
--- a/extension/qfq/qfq/AbstractBuildForm.php
+++ b/extension/qfq/qfq/AbstractBuildForm.php
@@ -84,6 +84,7 @@ abstract class AbstractBuildForm {
      * @param array $formSpec
      * @param array $feSpecAction
      * @param array $feSpecNative
+     * @param array $db
      */
     public function __construct(array $formSpec, array $feSpecAction, array $feSpecNative, array $db) {
         $this->formSpec = $formSpec;
@@ -165,11 +166,13 @@ abstract class AbstractBuildForm {
      *
      * @param string $mode FORM_LOAD | FORM_UPDATE | FORM_SAVE
      *
-     * @return string|array   $mode=LOAD_FORM: The whole form as HTML, $mode=FORM_UPDATE: array of all
+     * @param bool $htmlElementNameIdZero
+     * @param array $latestFeSpecNative
+     * @return array|string $mode=LOAD_FORM: The whole form as HTML, $mode=FORM_UPDATE: array of all
      *                        formElement.dynamicUpdate-yes  values/states
      * @throws CodeException
      * @throws DbException
-     * @throws \qfq\UserFormException
+     * @throws UserFormException
      */
     public function process($mode, $htmlElementNameIdZero = false, $latestFeSpecNative = array()) {
         $htmlHead = '';
@@ -1094,8 +1097,6 @@ abstract class AbstractBuildForm {
             $attribute .= Support::doAttribute('data-match', '[name=' . str_replace(':', '\\:', $htmlFormElementNamePrimary) . ']');
         }
 
-        $this->adjustMaxLength($formElement);
-
         if ($formElement[FE_MAX_LENGTH] > 0 && $value !== '') {
             // crop string only if it's not empty (substr returns false on empty strings)
             $value = substr($value, 0, $formElement[FE_MAX_LENGTH]);
@@ -1267,186 +1268,6 @@ abstract class AbstractBuildForm {
         return $sql;
     }
 
-    /**
-     * Calculates the maxlength of an input field, based on formElement type, formElement user definition and
-     * table.field definition.
-     *
-     * @param array $formElement
-     */
-    private function adjustMaxLength(array &$formElement) {
-
-        // MIN( $formElement['maxLength'], tabledefinition)
-        $maxLength = $this->getColumnSize($formElement);
-
-        $feMaxLength = false;
-        switch ($formElement[FE_TYPE]) {
-            case 'date':
-                $feMaxLength = 10;
-                break;
-            case 'datetime':
-                $feMaxLength = 19;
-                break;
-            case 'time':
-                $feMaxLength = 8;
-                break;
-        }
-
-        // In case there is no limit of the underlying table column, or a non primary table column, and the FE_TYPE is date/time.
-        if ($maxLength === false && $feMaxLength !== false) {
-            $maxLength = $feMaxLength;
-        }
-
-        // In case the underlying table column is not of type date/time, the $maxLength might be to high: correct
-        if ($feMaxLength !== false && $maxLength !== false && $feMaxLength < $maxLength) {
-            $maxLength = $feMaxLength;
-        }
-
-        // date/datetime
-        if ($maxLength !== false) {
-            if (is_numeric($formElement['maxLength']) && $formElement['maxLength'] != 0) {
-                if ($formElement['maxLength'] > $maxLength) {
-                    $formElement['maxLength'] = $maxLength;
-                }
-            } else {
-                $formElement['maxLength'] = $maxLength;
-            }
-        }
-    }
-
-    /**
-     * Get column spec from tabledefinition and parse size of it. If nothing defined, return false.
-     *
-     * @param $formElement
-     * @return bool|int a) 'false' if there is no length definition, b) length definition, c)
-     *                   date|time|datetime|timestamp use hardcoded length
-     *
-     */
-    private function getColumnSize(array &$formElement) {
-
-        $column = $formElement[FE_NAME];
-        $matches = array();
-        $inputType = 'number';
-
-        $typeSpec = $this->store->getVar($column, STORE_TABLE_COLUMN_TYPES);
-        switch ($typeSpec) {
-            case 'date': // yyyy-mm-dd
-                return 10;
-            case 'datetime': // yyyy-mm-dd hh:mm:ss
-            case 'timestamp': // yyyy-mm-dd hh:mm:ss
-                return 19;
-            case 'time': // hh:mm:ss
-                return 8;
-            default:
-                if (substr($typeSpec, 0, 4) === 'set(' || substr($typeSpec, 0, 5) === 'enum(') {
-                    return $this->maxLengthSetEnum($typeSpec);
-                }
-                break;
-        }
-
-        // $typeSpec = 'tinyint(3) UNSIGNED NOT NULL' | 'int(11) NOT NULL'
-        $arr = explode(' ', $typeSpec, 2);
-        if (empty($arr[1])) {
-            $sign = 'signed';
-        } else {
-            $arr = explode(' ', $arr[1], 2);
-            $sign = $arr[0] == 'unsigned' ? 'unsigned' : 'signed';
-        }
-
-        $arr = explode('(', $typeSpec, 2);
-        $token = $arr[0];
-
-        # s: signed, u: unsigned.
-        # s-min, s-max, s-checktype, u-min, u-max, u-checktype
-        $control = [
-            'tinyint' => [-128, 127, SANITIZE_ALLOW_NUMERICAL, 0, 255, SANITIZE_ALLOW_DIGIT],
-            'smallint' => [-32768, 32767, SANITIZE_ALLOW_NUMERICAL, 0, 65535, SANITIZE_ALLOW_DIGIT],
-            'mediumint' => [-8388608, 8388607, SANITIZE_ALLOW_NUMERICAL, 0, 16777215, SANITIZE_ALLOW_DIGIT],
-            'int' => [0, 4294967295, SANITIZE_ALLOW_NUMERICAL, -2147483648, 2147483647, SANITIZE_ALLOW_DIGIT],
-            'bigint' => [-9223372036854775808, 9223372036854775807, SANITIZE_ALLOW_NUMERICAL, 0, 18446744073709551615, SANITIZE_ALLOW_DIGIT],
-        ];
-
-        $min = false;
-        $max = false;
-        $checkType = false;
-        switch ($token) {
-            case 'tinyint':
-            case 'smallint':
-            case 'mediumint':
-            case 'int':
-            case 'bigint':
-                $arr = $control[$token];
-                if ($sign == 'signed') {
-                    $min = $arr[0];
-                    $max = $arr[1];
-                    $checkType = $arr[2];
-                } else {
-                    $min = $arr[3];
-                    $max = $arr[4];
-                    $checkType = $arr[5];
-                }
-                break;
-
-            case 'decimal':
-            case 'float':
-            case 'double':
-                $checkType = SANITIZE_ALLOW_NUMERICAL;
-            $inputType = 'text';
-                break;
-            case 'bit':
-                $checkType = SANITIZE_ALLOW_DIGIT;
-                break;
-        }
-
-        if ($min !== false && $formElement[FE_MIN] == '') {
-            $formElement[FE_MIN] = $min;
-        }
-
-        if ($max !== false && $formElement[FE_MAX] == '') {
-            $formElement[FE_MAX] = $max;
-        }
-
-        // if given, force Checktype
-        if ($checkType !== false) {
-            $formElement[FE_CHECK_TYPE] = $checkType;
-
-            if (empty($formElement[FE_INPUT_TYPE])) {
-                $formElement[FE_INPUT_TYPE] = $inputType;
-            }
-        }
-
-        // e.g.: string(64) >> 64, enum('yes','no') >> false
-        if (1 === preg_match('/\((.+)\)/', $typeSpec, $matches)) {
-            if (is_numeric($matches[1]))
-                return $matches[1];
-        }
-
-        return false;
-    }
-
-    /**
-     * Get the strlen of the longest element in enum('val1','val2',...,'valn') or set('val1','val2',...,'valn')
-     *
-     * @param string $typeSpec
-     *
-     * @return int
-     */
-    private function maxLengthSetEnum($typeSpec) {
-        $startPos = (substr($typeSpec, 0, 4) === 'set(') ? 4 : 5;
-        $max = 0;
-
-        $valueList = substr($typeSpec, $startPos, strlen($typeSpec) - $startPos - 1);
-        $valueArr = explode(',', $valueList);
-        foreach ($valueArr as $value) {
-            $value = trim($value, "'");
-            $len = strlen($value);
-            if ($len > $max) {
-                $max = $len;
-            }
-        }
-
-        return $max;
-    }
-
     /**
      * Builds a HTML attribute list, based on  $attributeList.
      *
@@ -3136,7 +2957,6 @@ abstract class AbstractBuildForm {
         $attribute .= Support::doAttribute('name', $htmlFormElementName);
         $attribute .= Support::doAttribute('class', 'form-control');
 
-        $this->adjustMaxLength($formElement);
         $showTime = ($formElement[FE_TYPE] == 'time' || $formElement[FE_TYPE] == 'datetime') ? 1 : 0;
         if ($value == 'CURRENT_TIMESTAMP') {
             $value = date('Y-m-d H:i:s');
@@ -3282,7 +3102,6 @@ abstract class AbstractBuildForm {
 //                throw new UserFormException("Checktype not applicable for date/time: '" . $formElement['checkType'] . "'", ERROR_NOT_APPLICABLE);
 //        }
 
-        $this->adjustMaxLength($formElement);
         $showTime = ($formElement[FE_TYPE] == 'time' || $formElement[FE_TYPE] == 'datetime') ? 1 : 0;
         $value = Support::convertDateTime($value, $formElement[FE_DATE_FORMAT], $formElement[FE_SHOW_ZERO], $showTime, $formElement[FE_SHOW_SECONDS]);
 
@@ -3331,8 +3150,6 @@ abstract class AbstractBuildForm {
 
         //TODO plugin autoresize nutzen um Editorgroesse anzugeben
 
-        $this->adjustMaxLength($formElement);
-
         $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
         $attribute .= Support::doAttribute('name', $htmlFormElementName);
 //        $attribute .= Support::doAttribute('id', $htmlFormElementName);
diff --git a/extension/qfq/qfq/Constants.php b/extension/qfq/qfq/Constants.php
index 2ccb7903cec82678599e6b2d731c1bc8b9a5e7dc..42e245a34c487204f45ccc65ad88d2e8d26362a6 100644
--- a/extension/qfq/qfq/Constants.php
+++ b/extension/qfq/qfq/Constants.php
@@ -65,6 +65,7 @@ const NAME_TG_COPIES = '_tgCopies';  // Number of templatesGroup copies to creat
 const FE_TG_INDEX = '_tgIndex'; // Index of the current copy of a templateGroup FE.
 
 // SANITIZE Classifier
+const SANITIZE_ALLOW_AUTO = "auto"; // Default for FormElements
 const SANITIZE_ALLOW_ALNUMX = "alnumx";
 const SANITIZE_ALLOW_DIGIT = "digit";
 const SANITIZE_ALLOW_NUMERICAL = "numerical";
@@ -72,7 +73,7 @@ const SANITIZE_ALLOW_EMAIL = "email";
 const SANITIZE_ALLOW_PATTERN = "pattern";
 const SANITIZE_ALLOW_ALLBUT = "allbut";
 const SANITIZE_ALLOW_ALL = "all";
-const SANITIZE_DEFAULT = SANITIZE_ALLOW_DIGIT;
+const SANITIZE_DEFAULT = SANITIZE_ALLOW_DIGIT; // for {{variable}} expressions without checkType
 
 const SANITIZE_EXCEPTION = 'exception';
 const SANITIZE_EMPTY_STRING = 'empty string';
diff --git a/extension/qfq/qfq/helper/Support.php b/extension/qfq/qfq/helper/Support.php
index c936930ef9f156d6bedb2b6be79175dbc0cb84a2..fc484ae1633819f7a0f67e6b258fac07c85513c8 100644
--- a/extension/qfq/qfq/helper/Support.php
+++ b/extension/qfq/qfq/helper/Support.php
@@ -681,7 +681,6 @@ class Support {
      */
     public static function mergeUrlComponents($host, $hostOrPath, $query) {
         $url = '';
-        $pre = '';
 
 
         if ($host != '' && substr($host, -1, 1) != '/') {
@@ -775,13 +774,133 @@ class Support {
         self::setIfNotSet($formElement, FE_MIN);
         self::setIfNotSet($formElement, FE_MAX);
 
-        // decimalFormat
+        self::setIfNotSet($formElement, FE_DECIMAL_FORMAT);
+
+        self::setIfNotSet($formElement, F_FE_DATA_PATTERN_ERROR);
+
+        $fieldTypeDefinition = $store->getVar($formElement[FE_NAME], STORE_TABLE_COLUMN_TYPES);
+        self::adjustFeToColumnDefinition($formElement, $fieldTypeDefinition);
+
+        return $formElement;
+    }
+
+    /**
+     * Adjusts several FE parameters using smart guesses based on the table column definition and other parameters.
+     *
+     * @param array $formElement
+     * @param $typeSpec
+     * @throws UserFormException
+     */
+    private function adjustFeToColumnDefinition(array &$formElement, $typeSpec) {
+
+        self::adjustMaxLength($formElement, $typeSpec);
+        self::adjustDecimalFormat($formElement, $typeSpec);
+
+        // Make educated guesses about the desired $min, $max, $checkType, and $inputType
+
+        // $typeSpec = 'tinyint(3) UNSIGNED NOT NULL' | 'int(11) NOT NULL'
+        $arr = explode(' ', $typeSpec, 2);
+        if (empty($arr[1])) {
+            $sign = 'signed';
+        } else {
+            $arr = explode(' ', $arr[1], 2);
+            $sign = $arr[0] == 'unsigned' ? 'unsigned' : 'signed';
+        }
+
+        $arr = explode('(', $typeSpec, 2);
+        $token = $arr[0];
+
+        # s: signed, u: unsigned.
+        # s-min, s-max, s-checktype, u-min, u-max, u-checktype
+        $control = [
+            'tinyint' => [-128, 127, SANITIZE_ALLOW_NUMERICAL, 0, 255, SANITIZE_ALLOW_DIGIT],
+            'smallint' => [-32768, 32767, SANITIZE_ALLOW_NUMERICAL, 0, 65535, SANITIZE_ALLOW_DIGIT],
+            'mediumint' => [-8388608, 8388607, SANITIZE_ALLOW_NUMERICAL, 0, 16777215, SANITIZE_ALLOW_DIGIT],
+            'int' => [0, 4294967295, SANITIZE_ALLOW_NUMERICAL, -2147483648, 2147483647, SANITIZE_ALLOW_DIGIT],
+            'bigint' => [-9223372036854775808, 9223372036854775807, SANITIZE_ALLOW_NUMERICAL, 0, 18446744073709551615, SANITIZE_ALLOW_DIGIT],
+        ];
+
+        $min = '';
+        $max = '';
+        $checkType = false;
+        $inputType = '';
+
+        switch ($token) {
+            case 'tinyint':
+            case 'smallint':
+            case 'mediumint':
+            case 'int':
+            case 'bigint':
+                $inputType = 'number';
+                $arr = $control[$token];
+                if ($sign == 'signed') {
+                    $min = $arr[0];
+                    $max = $arr[1];
+                    $checkType = $arr[2];
+                } else {
+                    $min = $arr[3];
+                    $max = $arr[4];
+                    $checkType = $arr[5];
+                }
+                break;
+
+            case 'decimal':
+            case 'float':
+            case 'double':
+                $checkType = SANITIZE_ALLOW_NUMERICAL;
+                break;
+
+            case 'bit':
+                $inputType = 'number';
+                $checkType = SANITIZE_ALLOW_DIGIT;
+                break;
+
+            case 'text':
+            case 'varchar':
+            case 'tinytext':
+            case 'mediumtext':
+            case 'longtext':
+                if ($formElement[FE_ENCODE] === FE_ENCODE_SPECIALCHAR)
+                    $checkType = SANITIZE_ALLOW_ALL;
+                else
+                    $checkType = SANITIZE_ALLOW_ALNUMX;
+                break;
+        }
+
+        if (!empty($formElement[FE_TYPEAHEAD_SQL])) {
+            $inputType = '';
+            $checkType = SANITIZE_ALLOW_ALNUMX;
+        }
+
+        // Set parameters if not set by user
+
+        if ($formElement[FE_CHECK_TYPE] === SANITIZE_ALLOW_AUTO) {
+            if ($checkType === false) {
+                $formElement[FE_CHECK_TYPE] = SANITIZE_ALLOW_ALNUMX; // fallback
+            } else {
+                $formElement[FE_CHECK_TYPE] = $checkType;
+            }
+        }
+
+        self::setIfNotSet($formElement, FE_MIN, $min);
+        self::setIfNotSet($formElement, FE_MAX, $max);
+        self::setIfNotSet($formElement, FE_INPUT_TYPE, $inputType);
+    }
+
+    /**
+     * Sets the decimalFormat of a FormElement based on the parameter definition and table.field definition
+     * Affected FormElement fields: FE_DECIMAL_FORMAT
+     *
+     * @param array $formElement
+     * @param $typeSpec
+     * @throws UserFormException
+     */
+    private function adjustDecimalFormat(array &$formElement, $typeSpec) {
         if (isset($formElement[FE_DECIMAL_FORMAT])) {
             if ($formElement[FE_DECIMAL_FORMAT] === '') {
                 // Get decimal format from column definition
-                $fieldTypeDefinition = $store->getVar($formElement[FE_NAME], STORE_TABLE_COLUMN_TYPES);
-                if ($fieldTypeDefinition !== false) {
-                    $fieldTypeInfoArray = preg_split("/[()]/", $fieldTypeDefinition);
+                if ($typeSpec !== false) {
+                    $fieldTypeInfoArray = preg_split("/[()]/", $typeSpec);
                     if ($fieldTypeInfoArray[0] === 'decimal')
                         $formElement[FE_DECIMAL_FORMAT] = $fieldTypeInfoArray[1];
                 }
@@ -792,15 +911,118 @@ class Support {
                     $decimalFormatArray = explode(',', $formElement[FE_DECIMAL_FORMAT]);
                     $isValidDecimalFormat = $decimalFormatArray[0] >= $decimalFormatArray[1];
                 }
-                if (!$isValidDecimalFormat)
-                    throw new UserFormException("Invalid decimalFormat.", ERROR_INVALID_DECIMAL_FORMAT);
+                if (!$isValidDecimalFormat) {
+                    throw new UserFormException("Invalid decimalFormat: '" . $formElement[FE_DECIMAL_FORMAT] . "'", ERROR_INVALID_DECIMAL_FORMAT);
+                }
             }
         }
-        self::setIfNotSet($formElement, FE_DECIMAL_FORMAT);
+    }
 
-        self::setIfNotSet($formElement, F_FE_DATA_PATTERN_ERROR);
+    /**
+     * Calculates the maxLength of an input field, based on formElement type, formElement user definition and
+     * table.field definition.
+     * Affected formElement fields: FE_MAX_LENGTH
+     *
+     * @param array $formElement
+     * @param $typeSpec
+     */
+    private function adjustMaxLength(array &$formElement, $typeSpec) {
 
-        return $formElement;
+        // MIN( $formElement['maxLength'], table definition)
+        $maxLength = self::getColumnSize($typeSpec);
+
+        $feMaxLength = false;
+        switch ($formElement[FE_TYPE]) {
+            case 'date':
+                $feMaxLength = 10;
+                break;
+            case 'datetime':
+                $feMaxLength = 19;
+                break;
+            case 'time':
+                $feMaxLength = 8;
+                break;
+        }
+
+        // In case there is no limit of the underlying table column, or a non primary table column, and the FE_TYPE is date/time.
+        if ($maxLength === false && $feMaxLength !== false) {
+            $maxLength = $feMaxLength;
+        }
+
+        // In case the underlying table column is not of type date/time, the $maxLength might be too high: correct
+        if ($feMaxLength !== false && $maxLength !== false && $feMaxLength < $maxLength) {
+            $maxLength = $feMaxLength;
+        }
+
+        // date/datetime
+        if ($maxLength !== false) {
+            if (is_numeric($formElement[FE_MAX_LENGTH]) && $formElement[FE_MAX_LENGTH] != 0) {
+                if ($formElement[FE_MAX_LENGTH] > $maxLength) {
+                    $formElement[FE_MAX_LENGTH] = $maxLength;
+                }
+            } else {
+                $formElement[FE_MAX_LENGTH] = $maxLength;
+            }
+        }
+    }
+
+    /**
+     * Get column spec from table definition and parse size of it. If nothing defined, return false.
+     *
+     * @param $typeSpec
+     * @return bool|int a) 'false' if there is no length definition, b) length definition, c)
+     *                   date|time|datetime|timestamp use hardcoded length
+     */
+    private function getColumnSize($typeSpec) {
+
+        $matches = array();
+
+        switch ($typeSpec) {
+            case 'date': // yyyy-mm-dd
+                return 10;
+            case 'datetime': // yyyy-mm-dd hh:mm:ss
+            case 'timestamp': // yyyy-mm-dd hh:mm:ss
+                return 19;
+            case 'time': // hh:mm:ss
+                return 8;
+            default:
+                if (substr($typeSpec, 0, 4) === 'set(' || substr($typeSpec, 0, 5) === 'enum(') {
+                    return self::maxLengthSetEnum($typeSpec);
+                }
+                break;
+        }
+
+        // e.g.: string(64) >> 64, enum('yes','no') >> false
+        if (1 === preg_match('/\((.+)\)/', $typeSpec, $matches)) {
+            if (is_numeric($matches[1]))
+                return $matches[1];
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the strlen of the longest element in enum('val1','val2',...,'valn') or set('val1','val2',...,'valn')
+     *
+     * @param string $typeSpec
+     *
+     * @return int
+     */
+    private function maxLengthSetEnum($typeSpec) {
+        $startPos = (substr($typeSpec, 0, 4) === 'set(') ? 4 : 5;
+        $max = 0;
+
+        $valueList = substr($typeSpec, $startPos, strlen($typeSpec) - $startPos - 1);
+        $valueArr = explode(',', $valueList);
+        foreach ($valueArr as $value) {
+            $value = trim($value, "'");
+            $len = strlen($value);
+            if ($len > $max) {
+                $max = $len;
+            }
+        }
+
+        return $max;
     }
 
     /**
diff --git a/extension/qfq/sql/formEditor.sql b/extension/qfq/sql/formEditor.sql
index 028095558ae051fde3a41608bd56b567ae6b1d62..c5f0fb6cb822b06112896987765478307d3cfc7a 100644
--- a/extension/qfq/sql/formEditor.sql
+++ b/extension/qfq/sql/formEditor.sql
@@ -83,7 +83,7 @@ CREATE TABLE IF NOT EXISTS `FormElement` (
                             'afterSave', 'afterInsert', 'afterUpdate', 'afterDelete', 'sendMail', 'paste')                  NOT NULL  DEFAULT 'text',
   `subrecordOption`    SET('edit', 'delete', 'new')                                                                         NOT NULL  DEFAULT '',
   `encode`             ENUM('none', 'specialchar')                                                                          NOT NULL  DEFAULT 'specialchar',
-  `checkType`          ENUM('alnumx', 'digit', 'numerical', 'email', 'pattern', 'allbut', 'all') NOT NULL  DEFAULT 'alnumx',
+  `checkType`          ENUM('auto', 'alnumx', 'digit', 'numerical', 'email', 'pattern', 'allbut', 'all') NOT NULL  DEFAULT 'auto',
   `checkPattern`       VARCHAR(255)                                                                                         NOT NULL  DEFAULT '',
 
   `onChange`           VARCHAR(255)                                                                                         NOT NULL  DEFAULT '',