-
Notifications
You must be signed in to change notification settings - Fork 0
/
widget.lengthchecker.js
120 lines (100 loc) · 4.38 KB
/
widget.lengthchecker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* Text length checker widget handling.
*/
(function (Drupal) {
'use strict';
Drupal.behaviors.reliefwebFormLengthChecker = {
attach: function (context, settings) {
// Check support.
if (!document.addEventListener) {
return;
}
// Translations.
var t = Drupal.t;
// Prepare the messages with the range values.
function prepareMessages(range) {
var messages = {
length: t('Length: _length_ characters'),
short: t('The text appears to be too short. It is recommended to have between _low_ and _high_ characters.'),
long: t('The text appears to be too long. It is recommended to have between _low_ and _high_ characters.'),
ok: t('The text is in the recommended range of _low_ and _high_ characters. Thank you.')
};
var statuses = ['short', 'long', 'ok'];
for (var i = 0, l = statuses.length; i < l; i++) {
var status = statuses[i];
messages[status] = messages[status]
.replace('_low_', range[0])
.replace('_high_', range[1]);
}
return messages;
}
// Check the length against the range and return its status.
function getLengthStatus(length, low, high) {
if (length < low) {
return 'short';
}
if (length > high) {
return 'long';
}
return 'ok';
}
// Create an indicator to show the status of the text length.
function createIndicator(element, messages, low, high) {
// Get the initial length and status.
var length = element.value.length;
var status = getLengthStatus(length, low, high);
// Text node to store the length status message.
var message = document.createTextNode(messages[status]);
// Split the length so we can simply update the length text node to
// improve performances.
var offset = messages.length.indexOf('_length_');
var prefix = messages.length.substr(0, offset);
var suffix = messages.length.substr(offset + 8);
// Text node to store the length.
var indicator = document.createTextNode(length);
// Indicator container.
var container = document.createElement('div');
container.setAttribute('aria-assertive', 'polite');
container.setAttribute('data-lengthchecker-status', status);
// Create the text elements.
container.appendChild(document.createTextNode(prefix));
container.appendChild(indicator);
container.appendChild(document.createTextNode(suffix));
container.appendChild(document.createTextNode(' - '));
container.appendChild(message);
// Insert the indicator after the textarea/input element.
element.parentNode.insertBefore(container, element.nextSibling);
// Update the message when the text changes.
element.addEventListener('input', function (event) {
var length = event.target.value.length;
var status = getLengthStatus(length, low, high);
// Update the length indicator.
indicator.nodeValue = length;
// Update the status and message only if the status changed.
if (container.getAttribute('data-lengthchecker-status') !== status) {
container.setAttribute('data-lengthchecker-status', status);
message.nodeValue = messages[status];
}
});
}
// Enable length checker.
function enableLengthChecker(element) {
var range = element.getAttribute('data-with-lengthchecker').split('-');
var messages = prepareMessages(range);
// Find the first text input or textarea if element is not one.
if (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA') {
element = element.querySelector('input[type="text"], textarea');
}
// Create the length indicator.
createIndicator(element, messages, parseInt(range[0], 10), parseInt(range[1], 10));
}
// Enable length checker on relevant textarea fields.
var elements = context.querySelectorAll('[data-with-lengthchecker]:not([data-with-lengthchecker-processed])');
for (var i = 0, l = elements.length; i < l; i++) {
var element = elements[i];
element.setAttribute('data-with-lengthchecker-processed', '');
enableLengthChecker(element);
}
}
};
})(Drupal);