User tests: Successful: Unsuccessful:
A request was made to have a character count when entering a meta description. As a Proof of Concept I have done this and applied it to the Site Meta Description in the global configuration as shown in the screenshot. (If accepted it is quick to add it to all the meta description fields)
This can be applied to any textarea field by adding charcounter="true"
to the field definition in the xml.
The character count has a default maximum of 200 characters but this can be configured in the field xml by adding maxlength="160"
(this is the setting for this POC)
Accessibility is obviously very important and this PR addresses this as well. The meta description text is announced when the user focuses on the input together with the string to indicate the characters used. Obviously a live count announced by the screenreader would be distracting so it waits 2000 milliseconds before updating the user with the screen reader user with the current count.
The string 86 characters remaining of 160 characters.
is a regular joomla language string except the numbers are replaced by the script. In this example I chose
"{remaining} characters remaining of {maxlength} characters."
. Available placeholders are {remaining}, {maxlength}, {length}
Needs updating to document the new charcounter option
Status | New | ⇒ | Pending |
Category | ⇒ | Administration com_config Language & Strings Repository Layout NPM Change |
Pretty sure my code is much simpler than your clever solution.
YMMV. Your's might be a bit more explicit, but if you integrate it right into the textarea field as an option instead of relying on a new layout it's a smaller footprint (and the bulk of this diff is the CS changes that are going to be asked if this were used).
diff --git a/layouts/joomla/form/field/textarea.php b/layouts/joomla/form/field/textarea.php
index ae184a0dd0..54236e4eaf 100644
--- a/layouts/joomla/form/field/textarea.php
+++ b/layouts/joomla/form/field/textarea.php
@@ -14,34 +14,35 @@ extract($displayData);
/**
* Layout variables
* -----------------
- * @var string $autocomplete Autocomplete attribute for the field.
- * @var boolean $autofocus Is autofocus enabled?
- * @var string $class Classes for the input.
- * @var string $description Description of the field.
- * @var boolean $disabled Is this field disabled?
- * @var string $group Group the field belongs to. <fields> section in form XML.
- * @var boolean $hidden Is this field hidden in the form?
- * @var string $hint Placeholder for the field.
- * @var string $id DOM id of the field.
- * @var string $label Label of the field.
- * @var string $labelclass Classes to apply to the label.
- * @var boolean $multiple Does this field support multiple values?
- * @var string $name Name of the input field.
- * @var string $onchange Onchange attribute for the field.
- * @var string $onclick Onclick attribute for the field.
- * @var string $pattern Pattern (Reg Ex) of value of the form field.
- * @var boolean $readonly Is this field read only?
- * @var boolean $repeat Allows extensions to duplicate elements.
- * @var boolean $required Is this field required?
- * @var integer $size Size attribute of the input.
- * @var boolean $spellcheck Spellcheck state for the form field.
- * @var string $validate Validation rules to apply.
- * @var string $value Value attribute of the field.
- * @var array $checkedOptions Options that will be set as checked.
- * @var boolean $hasValue Has this field a value assigned?
- * @var array $options Options available for this field.
- * @var array $inputType Options available for this field.
- * @var string $accept File types that are accepted.
+ * @var string $autocomplete Autocomplete attribute for the field.
+ * @var boolean $autofocus Is autofocus enabled?
+ * @var string $class Classes for the input.
+ * @var string $description Description of the field.
+ * @var boolean $disabled Is this field disabled?
+ * @var string $group Group the field belongs to. <fields> section in form XML.
+ * @var boolean $hidden Is this field hidden in the form?
+ * @var string $hint Placeholder for the field.
+ * @var string $id DOM id of the field.
+ * @var string $label Label of the field.
+ * @var string $labelclass Classes to apply to the label.
+ * @var boolean $multiple Does this field support multiple values?
+ * @var string $name Name of the input field.
+ * @var string $onchange Onchange attribute for the field.
+ * @var string $onclick Onclick attribute for the field.
+ * @var string $pattern Pattern (Reg Ex) of value of the form field.
+ * @var boolean $readonly Is this field read only?
+ * @var boolean $repeat Allows extensions to duplicate elements.
+ * @var boolean $required Is this field required?
+ * @var integer $size Size attribute of the input.
+ * @var boolean $spellcheck Spellcheck state for the form field.
+ * @var string $validate Validation rules to apply.
+ * @var string $value Value attribute of the field.
+ * @var array $checkedOptions Options that will be set as checked.
+ * @var boolean $hasValue Has this field a value assigned?
+ * @var array $options Options available for this field.
+ * @var array $inputType Options available for this field.
+ * @var string $accept File types that are accepted.
+ * @var boolean $charactercounter Whether this field supports a character counter.
*/
// Initialize some field attributes.
@@ -65,6 +66,13 @@ $attributes = array(
$maxlength ? $maxlength: ''
);
+
+if ($charactercounter)
+{
+ // Load the js file
+ Factory::getDocument()->getWebAssetManager()->enableAsset('short-and-sweet');
+ Factory::getDocument()->addScriptDeclaration("document.addEventListener('DOMContentLoaded', function() { shortAndSweet('textarea', {counterClassName: 'small text-muted'}); });");
+}
?>
<textarea name="<?php
echo $name; ?>" id="<?php
diff --git a/libraries/src/Form/Field/TextareaField.php b/libraries/src/Form/Field/TextareaField.php
index 8abd91d90a..34a53481b8 100644
--- a/libraries/src/Form/Field/TextareaField.php
+++ b/libraries/src/Form/Field/TextareaField.php
@@ -53,6 +53,14 @@ class TextareaField extends FormField
*/
protected $maxlength;
+ /**
+ * Whether this field supports a character counter.
+ *
+ * @var boolean
+ * @since __DEPLOY_VERSION__
+ */
+ protected $charactercounter = false;
+
/**
* Name of the layout being used to render the field
*
@@ -77,6 +85,7 @@ class TextareaField extends FormField
case 'rows':
case 'columns':
case 'maxlength':
+ case 'charactercounter':
return $this->$name;
}
@@ -103,6 +112,10 @@ class TextareaField extends FormField
$this->$name = (int) $value;
break;
+ case 'charactercounter':
+ $this->charactercounter = strtolower($value) === 'yes';
+ break;
+
default:
parent::__set($name, $value);
}
@@ -128,9 +141,10 @@ class TextareaField extends FormField
if ($return)
{
- $this->rows = isset($this->element['rows']) ? (int) $this->element['rows'] : false;
- $this->columns = isset($this->element['cols']) ? (int) $this->element['cols'] : false;
- $this->maxlength = isset($this->element['maxlength']) ? (int) $this->element['maxlength'] : false;
+ $this->rows = isset($this->element['rows']) ? (int) $this->element['rows'] : false;
+ $this->columns = isset($this->element['cols']) ? (int) $this->element['cols'] : false;
+ $this->maxlength = isset($this->element['maxlength']) ? (int) $this->element['maxlength'] : false;
+ $this->charactercounter = isset($this->element['charactercounter']) ? strtolower($this->element['charactercounter']) === 'yes' : false;
}
return $return;
@@ -167,9 +181,10 @@ class TextareaField extends FormField
$maxlength = $this->maxlength ? ' maxlength="' . $this->maxlength . '"' : '';
$extraData = array(
- 'maxlength' => $maxlength,
- 'rows' => $rows,
- 'columns' => $columns
+ 'maxlength' => $maxlength,
+ 'rows' => $rows,
+ 'columns' => $columns,
+ 'charactercounter' => $this->charactercounter,
);
return array_merge($data, $extraData);
Labels |
Added:
?
NPM Resource Changed
?
|
Category | Administration com_config Language & Strings Repository Layout NPM Change | ⇒ | Administration com_config Language & Strings Repository Layout Libraries NPM Change |
Category | Administration com_config Language & Strings Repository Layout NPM Change Libraries | ⇒ | Administration com_config Language & Strings JavaScript Repository Layout Libraries NPM Change |
@brianteeman if you're updating the package.json file you need to update the package-lock.json file too please
Thanks for the info. Any idea on fixing hound
I have tested this item
After the patch, the global configuration is messed up:
I tried to recompile the js and css files but got the following error:
Without the patch, 'npm i' and 'npm ci' work normal.
@Wolf-Rost This PR here is not ready for test. It has conflicting files as shown at the bottom on GitHub. That does not mean the PR is wrong, it is just a bit older and meanwhile there have been changes made in 4.0-dev to which this PR has to be adapted. After that it makes sense to test it. Please reset your test result in the issue tracker to "I have not tested this item".
@brianteeman Could you resolve conflicts and update to latest 4.0-dev? Today is a good day for getting testers because of PBF.
I have not tested this item.
I have not tested this item.
I have tested this item
I have the same issue: global configuration messed up
#PBF19es
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2019-12-28 14:45:19 |
Closed_By | ⇒ | brianteeman |
Instead of using the
layout
attribute, introduce a new attribute (charactercounter="yes"
maybe?) and have the textarea field dynamically set the layout, or if possible add an if conditional in the existing textarea layout to load the JS; seems like a bit of extra overhead to add another layout just to conditionally register a new script.Otherwise, it's a really simple thing, makes sense to add it to me.