Commit 60e6deff authored by Carsten  Rose's avatar Carsten Rose
Browse files

Fixes #7682. 'Input textarea auto height' - Improve detection single/multiple...

Fixes #7682. 'Input textarea auto height' - Improve detection single/multiple lines, improve doc, enhance unit tests.
parent 725352ad
Pipeline #2311 passed with stages
in 2 minutes and 49 seconds
......@@ -2868,7 +2868,7 @@ Fields:
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|Size | string | Depends on the FormElement type. E.g. visible length (and height) of input element `input-text`_ . |
| | | Might be omitted, depending on the chosen form layout. |
| | | Format: <width>[,<(min) height>[,<max height]] (in characters) _`field-size`. |
| | | Format: <width>[,<(min) height>[,<max height]] (in characters). |
+---------------------+-----------------------------+-----------------------------------------------------------------------------------------------------+
|BS Label Columns | string | Number of bootstrap grid columns. By default empty, value inherits from the form. |
| | | _`field-bsLabelColumns`. See `bs-custom-field-width`_ |
......@@ -3266,17 +3266,21 @@ Type: text
* General input for text and number.
* *FormElement.size* = [<width>[,<min height>[,<max height>]]]
* <width>:
* The 'size' parameter might have 0-3 parameter.
* If 0-2 parameter are given, the height is s
* If 3 parameter are given, the `auto height` mode is activated: the height is dynamically calculated, with respect to
given min/max height.
* Width measured in characters, height measured in lines.
* If only the width is given (no min/max height), the height becomes automatically '1'.
* In general, the *visible* width of an input element is defined by the Bootstrap column width (and *not* the width given
here). The width value here only has an impact on calculating the final height in the `auto height` mode.
* The dynamic Bootstrap width of the shown textarea element makes it hard to calculate the real needed height. The
implementation is only a 'best guess'.
* `<width>,<min height>`: with a `<min height>` > 1 the input element is of type 'textarea'.
* `<width>,<min height>,<max height>`: input element = textarea, width=`<width>`, height=`counting lines of current value`.
If a line is longer than `<width>`, the height of the line counts as `length(<line>) / <width> + 1` lines. The height
is never less than `<min height>` or greater than `<max height>`.
* Counted as character.
* If only the width is given, the height becomes automatically '1'.
* In general, the width of an input element is defined by the Bootstrap column width. The value here only has an
impact on calculating the final height in the '<width>,<min height>,<max height>' mode.
* <width>,<min height>: with a <min height> > 1 the input element is of type 'textarea', width=<width>, height=<min height>
* <width>,<min height>,<max height>: input element = textarea, width=<width>, height=`counting lines of current value`.
If a line is longer than '<width>', the line counts as `length(<line>) / <width> + 1` lines. The width is never less than
<min width> or greater than <max width>.
* *FormElement.parameter*:
......
......@@ -1265,10 +1265,6 @@ abstract class AbstractBuildForm {
$attribute .= Support::doAttribute('maxlength', $formElement[FE_MAX_LENGTH], false);
}
// Check for input type 'textarea'.
$colsRows = explode(',', $formElement[FE_SIZE], 3);
$flagTextarea = (count($colsRows) > 1);
if ($formElement[FE_HIDE_ZERO] != '0' && $value == '0') {
$value = '';
}
......@@ -1287,16 +1283,19 @@ abstract class AbstractBuildForm {
$formElement[FE_INPUT_TYPE] = 'number';
}
// Check for input type 'textarea'. Possible notation: a) '', b) '<width>', c) '<width>,<height>', d) '<width>,<min-height>,<max-height>'
$colsRows = explode(',', $formElement[FE_SIZE], 3);
// AutoHeight
$colsRows[1] = HelperFormElement::textareaAutoHeight($colsRows, $value);
$flagTextarea = ($colsRows[1] > 1);
$formElement = HelperFormElement::prepareExtraButton($formElement, !$flagTextarea);
if ($flagTextarea) {
$htmlTag = '<textarea';
// AutoHeight?
if (!empty($colsRows[2])) {
$colsRows[1] = HelperFormElement::textareaAutoHeight($colsRows, $value);
}
$attribute .= Support::doAttribute('cols', $colsRows[0]);
$attribute .= Support::doAttribute('rows', $colsRows[1]);
$textarea = htmlentities($value) . '</textarea>';
......
......@@ -531,6 +531,7 @@ EOF;
* Calculates (estimate) number of rows needed for a pre filled textarea element.
* Explode $value into lines. Check each line for number of textarea width rows. Count all and return this number.
* Apply min & max settings.
* If no <height> is given, return always 1 - easy way to detect single or multile line input/textarea.
*
* @param array $colsRows
* @param string $value
......@@ -541,7 +542,7 @@ EOF;
// Check
if (count($colsRows) < 3) {
return ($colsRows[1] ?? 0);
return (empty($colsRows[1]) ? 1 : $colsRows[1]);
}
if (empty($colsRows[0])) {
......
......@@ -204,26 +204,51 @@ class HelperFormElementTest extends TestCase {
public function testTextareaAutoHeight() {
$result = HelperFormElement::textareaAutoHeight([], '');
$this->assertEquals('0', $result);
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([1], '');
$this->assertEquals('0', $result);
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([1, 0], '');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([1, 1], '');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([1, 2], '');
$this->assertEquals('2', $result);
$result = HelperFormElement::textareaAutoHeight([], 'Expect white\nExpect white Expect white Expect white\nExpect white');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([20], 'Expect white\nExpect white Expect white Expect white\nExpect white');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([20, 0], 'Expect white\nExpect white Expect white Expect white\nExpect white');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([20, 1], 'Expect white\nExpect white Expect white Expect white\nExpect white');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([20, 2], 'Expect white\nExpect white Expect white Expect white\nExpect white');
$this->assertEquals('2', $result);
$result = HelperFormElement::textareaAutoHeight([1, 1, 1], '');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([20, 1, 10], 'one line');
$this->assertEquals('1', $result);
$result = HelperFormElement::textareaAutoHeight([20, 1, 10], "Expect white\nExpect white\nExpect white");
$this->assertEquals('3', $result);
$result = HelperFormElement::textareaAutoHeight([20, 1, 2], "Expect white\nExpect white\nExpect white");
$this->assertEquals('2', $result);
$result = HelperFormElement::textareaAutoHeight([20, 1, 10], "Expect white\nExpect white\nExpect white");
$this->assertEquals('3', $result);
$result = HelperFormElement::textareaAutoHeight([20, 1, 10], "Expect white\nExpect white Expect white Expect white\nExpect white");
$this->assertEquals('4', $result);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment