diff --git a/extension/qfq/qfq/AbstractBuildForm.php b/extension/qfq/qfq/AbstractBuildForm.php index 849b0f73fafde49df56a29b4903721c72f26be43..cca8fb65333f92ada2c2c70adca78e200537a075 100644 --- a/extension/qfq/qfq/AbstractBuildForm.php +++ b/extension/qfq/qfq/AbstractBuildForm.php @@ -727,6 +727,7 @@ abstract class AbstractBuildForm { $textarea = ''; $attribute = ''; $class = 'form-control'; + $elementCharacterCount = ''; $typeAheadUrlParam = $this->typeAheadBuildParam($formElement); if ($typeAheadUrlParam != '') { @@ -737,15 +738,43 @@ abstract class AbstractBuildForm { $attribute .= Support::doAttribute(DATA_TYPEAHEAD_MINLENGTH, $formElement[FE_TYPEAHEAD_MINLENGTH]); } + if (isset($formElement[FE_CHARACTER_COUNT_WRAP])) { + $class .= ' ' . CLASS_CHARACTER_COUNT; + $attribute .= Support::doAttribute(DATA_CHARACTER_COUNT_ID, $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_CHARACTER_COUNT); + $attributeCC = Support::doAttribute('id', $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_CHARACTER_COUNT); + + $classCC = ($formElement[FE_CHARACTER_COUNT_WRAP] == '') ? Support::doAttribute('class', 'qfq-cc-style') : ''; + $elementCharacterCount = "<span $attributeCC $classCC></span>"; + + if ($formElement[FE_CHARACTER_COUNT_WRAP] != '') { + $arr = explode('|', $formElement[FE_CHARACTER_COUNT_WRAP], 2); + $arr[] = ''; + $arr[] = ''; //skip check that at least 2 elements exist + $elementCharacterCount = $arr[0] . $elementCharacterCount . $arr[1]; + } + } + $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]); $attribute .= Support::doAttribute('name', $htmlFormElementName); $attribute .= Support::doAttribute('class', $class); + if (isset($formElement[FE_RETYPE_SOURCE_NAME])) { $htmlFormElementNamePrimary = str_replace(RETYPE_FE_NAME_EXTENSION, '', $htmlFormElementName); $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]); + } + // 'maxLength' needs an upper 'L': naming convention for DB tables! + if ($formElement[FE_MAX_LENGTH] > 0) { + $attribute .= Support::doAttribute('maxlength', $formElement[FE_MAX_LENGTH], false); + } + // Check for input type 'textarea'. $colsRows = explode(',', $formElement['size'], 2); if (count($colsRows) === 2) { @@ -759,15 +788,7 @@ abstract class AbstractBuildForm { } else { $htmlTag = '<input'; - $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]); - } - - // 'maxLength' needs an upper 'L': naming convention for DB tables! - $attribute .= $this->getAttributeList($formElement, ['type', 'size', 'maxLength']); + $attribute .= $this->getAttributeList($formElement, ['type', 'size']); $attribute .= Support::doAttribute('value', htmlentities($value), false); } @@ -781,7 +802,7 @@ abstract class AbstractBuildForm { $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement); - return "$htmlTag $attribute>$textarea" . $this->getHelpBlock(); + return "$htmlTag $attribute>$textarea" . $elementCharacterCount . $this->getHelpBlock(); } diff --git a/extension/qfq/tests/phpunit/BuildFormPlainTest.php b/extension/qfq/tests/phpunit/BuildFormPlainTest.php index 2546d02f120e43f0802fb743a3e7699e334b2bae..c9553ae3f737389c0332349aa68be5c3307de382 100644 --- a/extension/qfq/tests/phpunit/BuildFormPlainTest.php +++ b/extension/qfq/tests/phpunit/BuildFormPlainTest.php @@ -83,32 +83,32 @@ class BuildFormPlainTest extends AbstractDatabaseTest { $label['123-l'][API_ELEMENT_CONTENT] = '<label for="name:1" class="control-label" >Name</label>'; $result = $build->buildInput($formElement, 'name:1', '', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="255" type="input" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', API_ELEMENT_UPDATE => $label], $json); // CheckType $formElement['checkType'] = SANITIZE_ALLOW_MIN_MAX; $formElement['checkPattern'] = '1|10'; $result = $build->buildInput($formElement, 'name:1', '', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" min="1" max="10" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="255" type="input" value="" min="1" max="10" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); $formElement['checkType'] = SANITIZE_ALLOW_PATTERN; $formElement['checkPattern'] = '^[a-z]*$'; $result = $build->buildInput($formElement, 'name:1', '', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" pattern="^[a-z]*$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="255" type="input" value="" pattern="^[a-z]*$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); $formElement['checkType'] = SANITIZE_ALLOW_DIGIT; $formElement['checkPattern'] = ''; $result = $build->buildInput($formElement, 'name:1', '', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" pattern="^[\d]*$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="255" type="input" value="" pattern="^[\d]*$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); $formElement['checkType'] = SANITIZE_ALLOW_EMAIL; $formElement['checkPattern'] = ''; $result = $build->buildInput($formElement, 'name:1', '', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="255" type="input" value="" pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); $formElement['checkType'] = ''; @@ -119,13 +119,13 @@ class BuildFormPlainTest extends AbstractDatabaseTest { $formElement['size'] = 40; $formElement['maxLength'] = 40; $result = $build->buildInput($formElement, 'name:1', '', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" size="40" maxlength="40" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="40" type="input" size="40" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); // maxlength bigger than physical spec: $formElement['maxLength'] = 1000; $result = $build->buildInput($formElement, 'name:1', '', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" size="40" maxlength="255" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="255" type="input" size="40" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); // no size, no maxlength and column not in primary table @@ -139,7 +139,7 @@ class BuildFormPlainTest extends AbstractDatabaseTest { // no size, given maxlength and column not in primary table $formElement2['maxLength'] = '10'; $result = $build->buildInput($formElement2, 'specialname:1', '', $json); - $this->assertEquals('<input id="123" name="specialname:1" class="form-control" type="input" maxlength="10" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="specialname:1" class="form-control" maxlength="10" type="input" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); // size given, no maxlength and column not in primary table $formElement2['maxLength'] = ''; @@ -151,25 +151,26 @@ class BuildFormPlainTest extends AbstractDatabaseTest { $formElement2['maxLength'] = '20'; $formElement2['size'] = '10'; $result = $build->buildInput($formElement2, 'specialname:1', '', $json); - $this->assertEquals('<input id="123" name="specialname:1" class="form-control" type="input" size="10" maxlength="20" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="specialname:1" class="form-control" maxlength="20" type="input" size="10" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); // Explicit: further $formElement['tooltip'] = 'Nice Tooltip'; $formElement['placeholder'] = 'Please type a name'; $result = $build->buildInput($formElement, 'name:1', 'Hello World', $json); - $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" size="40" maxlength="255" value="Hello World" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<input id="123" name="name:1" class="form-control" maxlength="255" type="input" size="40" value="Hello World" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); // textarea $formElement['size'] = '40,10'; $result = $build->buildInput($formElement, 'name:1', 'Hello World', $json); - $this->assertEquals('<textarea id="123" name="name:1" class="form-control" cols="40" rows="10" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" >Hello World</textarea><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<textarea id="123" name="name:1" class="form-control" maxlength="255" cols="40" rows="10" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" >Hello World</textarea><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); $formElement['size'] = ' 40 , 10 '; $result = $build->buildInput($formElement, 'name:1', 'Hello World', $json); - $this->assertEquals('<textarea id="123" name="name:1" class="form-control" cols="40" rows="10" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" >Hello World</textarea><div class="help-block with-errors hidden"></div>', $result); + $this->assertEquals('<textarea id="123" name="name:1" class="form-control" maxlength="255" cols="40" rows="10" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" >Hello World</textarea><div class="help-block with-errors hidden"></div>', $result); $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json); }