-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinput2.js
294 lines (167 loc) · 8.32 KB
/
input2.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
// Eléments de paramétrage
const input2Class = 'secriVisibleAttributes'; //Class de l'input visible
const timing = 2000; //Timing pour la suppression auto
const separatorKey = 'Space';
const keyboardRegex = /[a-zA-Z0-9\'\"\=\-\_ ]/; // array de Regex d'autorisation des touches du clavier
const submitRegex = [/src=["']{1}.*/]; // array de Regex d'identification de chaînes interdites
const inputMaxLength = 20; // Longueur maximale d'une chaîne dans l'input visible
const ctaDeleteAll = 'Tout effacer';
// Objet
class Input2 {
constructor(input, separator, keys, forbiddenStrings) {
this.input = input;
this.separator = separator;
this.keys = keys;
this.forbiddenStrings = forbiddenStrings;
}
createInput2() { // Méthode qui crée les éléments HTML et les insère correctement dans le DOM
let input2 = document.createElement('input');
input2.setAttribute('type', 'text');
input2.setAttribute('class', input2Class);
if (Number.isInteger(inputMaxLength) && inputMaxLength > 0) {
input2.setAttribute('maxlength', inputMaxLength.toString());
}
input2.setAttribute('value', this.input.value);
// on met l'input 2 juste avant l'input caché dans le conteneur parent
this.input.parentNode.prepend(input2);
// On cible le parent par défaut de l'input visible, à priori un <td> par défaut sous Wordpress
let getParentNode = input2.parentNode;
// On crée le conteneur principal et on lui attribue une class
let wrapper = document.createElement('div');
wrapper.setAttribute('class', 'inputWrapper');
// On crée le conteneur secondaire destiné à recevoir les mot-clés
let keywordsWrapper = document.createElement('div');
// On crée la div action pour la fonction deleteKeyword
let actionDiv = document.createElement('div');
actionDiv.setAttribute('class', 'action');
let delButton = document.createElement('div');
delButton.textContent = ctaDeleteAll;
actionDiv.appendChild(delButton);
// On remplace l'input par le conteneur dans l'élément parent et on met l'input dans le wrapper
getParentNode.replaceChild(wrapper, input2);
wrapper.appendChild(keywordsWrapper);
wrapper.appendChild(actionDiv);
keywordsWrapper.appendChild(input2);
//on met le tout dans un conteneur générique indépendant
const globalContainer = document.createElement('div');
this.input.parentNode.prepend(globalContainer);
globalContainer.appendChild(wrapper);
globalContainer.appendChild(this.input);
//On lance l'isolation des mots clés
this.includeKeywords(this.getInitialValue());
//On assigne le gestionnaire séparateur dans l'input
this.handleSeparatorInput();
//On assigne l'écouteur des input clavier
this.handleKeyboard();
//On ajoute la gestion du bouton delete all
this.deleteAll();
}
getInitialValue() { //Récupère la value de l'input2 sous forme de tableau
let target = this.input.previousElementSibling.firstElementChild.lastElementChild;
return target.value.split(' ');
}
includeKeywords(array, autoDel='non') {
let visibleInput = this.input.previousElementSibling.firstElementChild.lastElementChild;
for (const element of array.reverse()) {
if (element != '') {
let cartouche = document.createElement('div');
if (autoDel === 'yes') {
cartouche.setAttribute('class', 'srcError');
}
cartouche.textContent = element.toLowerCase();
let fermer = document.createElement('i');
cartouche.appendChild(fermer);
this.input.previousElementSibling.firstElementChild.prepend(cartouche);
}
}
visibleInput.value = ''; // Après avoir injecté les mots clés on efface la value de l'input visible
this.deleteListener();
this.handleButtonVisibility();
if (autoDel == 'yes') {
setTimeout( () => { this.input.previousElementSibling.firstElementChild.querySelectorAll('.srcError').forEach( (element) => element.remove()); this.handleButtonVisibility(); }, timing );
} else {
this.input.value = this.pushToHiddenInput();
}
}
pushToHiddenInput() {
let keyWords = this.input.previousElementSibling.firstElementChild.querySelectorAll('div');
let tempArray = []; //Voir pour trouver un moyen plus sexy de faire le job !
for (const element of keyWords) {
tempArray.push(element.textContent);
}
return tempArray.join(' ');
}
deleteListener() {
let buttonsCollection = this.input.previousElementSibling.firstElementChild.querySelectorAll('div i');
for (const element of buttonsCollection) {
element.addEventListener('click', (event)=> { //On utilise un fonction flèche pour ne pas sortir du contexte de l'objet
event.target.parentElement.remove();
let getHiddenValue = this.input.value.split(' ');
let newHiddenValue = getHiddenValue.filter( (word) => word != event.target.parentElement.textContent );
this.input.value = newHiddenValue.join(' ');
this.handleButtonVisibility();
});
}
}
handleKeyboard() {
this.input.previousElementSibling.firstElementChild.lastElementChild.addEventListener('keydown', (event)=> { //On utilise un fonction flèche pour ne pas sortir du contexte de l'objet
if ( !event.key.match(this.keys) ) { //si l'entrée au clavier matche le séparateur
event.preventDefault();
}
if (event.code === this.separator && event.target.value.length > 0) {
for (const regex of this.forbiddenStrings) {
if ( event.target.value.match(regex) || this.checkRedundant(event.target.value) ) { //
this.includeKeywords([event.target.value], 'yes');
} else {
this.includeKeywords([event.target.value]);
}
}
}
});
}
handleSeparatorInput() {
this.input.previousElementSibling.firstElementChild.lastElementChild.addEventListener('input', (event)=> { //On utilise un fonction flèche pour ne pas sortir du contexte de l'objet
if (event.target.value === ' ') {
event.target.value = '';
return;
}
});
}
checkRedundant(string) {
const keywordsCollection = this.input.previousElementSibling.firstElementChild.querySelectorAll('div');
for (const element of keywordsCollection) {
if (string === element.textContent) {
return true;
}
}
return false;
}
deleteAll() {
this.input.previousElementSibling.lastElementChild.lastElementChild.addEventListener('click', (event)=> {
const keywordsCollection = this.input.previousElementSibling.firstElementChild.querySelectorAll('div');
for (const element of keywordsCollection) {
element.remove();
}
this.input.value = '';
this.handleButtonVisibility();
});
}
handleButtonVisibility() {
const keywordsCollection = this.input.previousElementSibling.firstElementChild.querySelectorAll('div');
if ( keywordsCollection.length > 1) {
this.input.previousElementSibling.lastElementChild.lastElementChild.style.display = 'block';
} else {
this.input.previousElementSibling.lastElementChild.lastElementChild.style.display = 'none';
}
}
}
document.addEventListener('DOMContentLoaded', function() {
let inputs = document.querySelectorAll('.secriSubmitAttributes');
let instances = {};
let inc = 0;
for (const elt of inputs) {
inc++;
instances[inc] = new Input2(elt, separatorKey, keyboardRegex, submitRegex);
instances[inc].createInput2();
}
});