[FEATURE] Show remaining characters below text fields 65/38165/6
authorAndreas Fernandez <a.fernandez@scripting-base.de>
Sat, 21 Mar 2015 22:37:18 +0000 (23:37 +0100)
committerBenjamin Mack <benni@typo3.org>
Fri, 27 Mar 2015 00:53:23 +0000 (01:53 +0100)
If a field has the TCA definition "max", show the amount of characters left
below the textfield if it has the focus.

Resolves: #66029
Releases: master
Change-Id: Ib8c4409f60f82da6d40956a0008008ea781bda6f
Reviewed-on: http://review.typo3.org/38165
Reviewed-by: Jan Helke <typo3@helke.de>
Tested-by: Jan Helke <typo3@helke.de>
Reviewed-by: Daniel Sattler <sattler@b13.de>
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
typo3/sysext/backend/Classes/Form/FormEngine.php
typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js
typo3/sysext/core/Documentation/Changelog/master/Feature-66029-ShowRemainingCharactersBelowTextFields.rst [new file with mode: 0644]
typo3/sysext/lang/locallang_core.xlf

index 62b13fb..e5e99b0 100644 (file)
@@ -2007,6 +2007,7 @@ class FormEngine {
                        TBE_EDITOR.labels.maxItemsAllowed = ' . GeneralUtility::quoteJSvalue($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.maxItemsAllowed')) . ';
                        TBE_EDITOR.labels.refresh_login = ' . GeneralUtility::quoteJSvalue($languageService->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login')) . ';
                        TBE_EDITOR.labels.onChangeAlert = ' . GeneralUtility::quoteJSvalue($languageService->sL('LLL:EXT:lang/locallang_core.xlf:mess.onChangeAlert')) . ';
+                       TBE_EDITOR.labels.remainingCharacters = ' . GeneralUtility::quoteJSvalue($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.remainingCharacters')) . ';
                        evalFunc.USmode = ' . ($GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? '1' : '0') . ';
                        TBE_EDITOR.backend_interface = "' . $beUserAuth->uc['interfaceSetup'] . '";
 
index 217fd61..61dc6ec 100644 (file)
@@ -553,11 +553,13 @@ define('TYPO3/CMS/Backend/FormEngine', ['jquery'], function ($) {
                        }
                });
 
+               FormEngine.initializeRemainingCharacterViews();
+
                // in multi-select environments with two (e.g. "Access"), on click the item from the right should go to the left
                $(document).on('click', '.t3js-formengine-select-itemstoselect', function(evt) {
                        var $el = $(this)
-                                       ,fieldName = $el.data('relatedfieldname')
-                                       ,exclusiveValues = $el.data('exclusivevalues');
+                               ,fieldName = $el.data('relatedfieldname')
+                               ,exclusiveValues = $el.data('exclusivevalues');
 
                        if (fieldName) {
                                // try to add each selected field to the "left" select field
@@ -569,6 +571,61 @@ define('TYPO3/CMS/Backend/FormEngine', ['jquery'], function ($) {
                });
        };
 
+       /**
+        * Initializes the remaining character views based on the fields' maxlength attribute
+        */
+       FormEngine.initializeRemainingCharacterViews = function() {
+               // all fields with a "maxlength" attribute
+               var $maxlengthElements = $('[maxlength]');
+               $maxlengthElements.on('focus', function(e) {
+                       var $field = $(this),
+                               $parent = $field.parents('.t3js-formengine-field-item'),
+                               maxlengthProperties = FormEngine.getCharacterCounterProperties($field);
+
+                       // append the counter only at focus to avoid cluttering the DOM
+                       $parent.append($('<div />', {'class': 't3js-charcounter'}).append(
+                               $('<span />', {'class': maxlengthProperties.labelClass}).text(TBE_EDITOR.labels.remainingCharacters.replace('{0}', maxlengthProperties.remainingCharacters))
+                       ));
+               }).on('blur', function() {
+                       var $field = $(this),
+                               $parent = $field.parents('.t3js-formengine-field-item');
+                       $parent.find('.t3js-charcounter').remove();
+               }).on('keyup', function() {
+                       var $field = $(this),
+                               $parent = $field.parents('.t3js-formengine-field-item'),
+                               maxlengthProperties = FormEngine.getCharacterCounterProperties($field);
+
+                       // change class and value
+                       $parent.find('.t3js-charcounter span').removeClass().addClass(maxlengthProperties.labelClass).text(TBE_EDITOR.labels.remainingCharacters.replace('{0}', maxlengthProperties.remainingCharacters))
+               });
+       };
+
+       /**
+        * Get the properties required for proper rendering of the character counter
+        */
+       FormEngine.getCharacterCounterProperties = function($field) {
+               var fieldText = $field.val(),
+                       maxlength = $field.attr('maxlength'),
+                       currentFieldLength = fieldText.length,
+                       numberOfLineBreaks = (fieldText.match(/\n/g)||[]).length, // count line breaks
+                       remainingCharacters = maxlength - currentFieldLength - numberOfLineBreaks,
+                       threshold = 15, // hard limit of remaining characters when the label class changes
+                       labelClass = '';
+
+               if (remainingCharacters < threshold) {
+                       labelClass = 'label-danger';
+               } else if(remainingCharacters < threshold * 2) {
+                       labelClass = 'label-warning';
+               } else {
+                       labelClass = 'label-info';
+               }
+
+               return {
+                       remainingCharacters: remainingCharacters,
+                       labelClass: 'label ' + labelClass
+               };
+       };
+
        /**
         * select field filter functions, see TCA option "enableMultiSelectFilterTextfield"
         * and "multiSelectFilterItems"
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-66029-ShowRemainingCharactersBelowTextFields.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-66029-ShowRemainingCharactersBelowTextFields.rst
new file mode 100644 (file)
index 0000000..9a501f7
--- /dev/null
@@ -0,0 +1,15 @@
+=============================================================
+Feature: #66029 - Show remaining characters below text fields
+=============================================================
+
+Description
+===========
+
+The amount of remaining characters is displayed below text fields.
+
+Impact
+======
+
+When focusing a form field, the amount of remaining characters gets
+rendered below the form field, if a TCA field definition has the "max"
+definition.
\ No newline at end of file
index 2763dd7..3b627f3 100644 (file)
@@ -76,6 +76,9 @@
                                <source>There are unsaved changes in the form!
 Do you want to continue WITHOUT saving?</source>
                        </trans-unit>
+                       <trans-unit id="labels.remainingCharacters" xml:space="preserve">
+                               <source>Remaining characters: {0}</source>
+                       </trans-unit>
                        <trans-unit id="labels.maxItemsAllowed" xml:space="preserve">
                                <source>A maximum of {0} child records are allowed.</source>
                        </trans-unit>