Code Duplication    Length = 361-372 lines in 2 locations

resources/assets/js/autocomplete.js 1 location

@@ 1-372 (lines=372) @@
1
$(document).ready(function() {
2
3
    /*
4
     * jQuery accessible and keyboard-enhanced autocomplete list
5
     * @version v1.6.0
6
     * Website: https://a11y.nicolas-hoffmann.net/autocomplet-list/
7
     * License MIT: https://github.com/nico3333fr/jquery-accessible-autocomplete-list-aria/blob/master/LICENSE
8
     */
9
    // loading combobox ------------------------------------------------------------------------------------------------------------
10
    // init
11
    var $js_combobox = $('.js-combobox'),
12
        $body = $('body'),
13
        // default_text_help = 'Use tabulation (or down) key to access and browse suggestions after input. Confirm your choice with enter key, or esc key to close suggestions box.',
14
        default_text_help = '',
15
        default_class_for_invisible_text = 'invisible',
16
        suggestion_single = 'There is ',
17
        suggestion_plural = 'There are ',
18
        suggestion_word = 'suggestion',
19
        suggestion_word_plural = 'suggestions',
20
        button_clear_title = 'clear this field',
21
        button_clear_text = 'X',
22
        case_sensitive = 'no',
23
        min_length = 0,
24
        limit_number_suggestions = 666,
25
        search_option = 'beginning', // or 'containing'
26
        see_more_text = 'See more results…',
27
        tablo_suggestions = [];
28
29
30
    function do_see_more_option() {
31
        var $output_content = $('#js-codeit');
32
        $output_content.html('You have to code a function or a redirection to display more results ;)');
33
    }
34
35
    if ($js_combobox.length) { // if there are at least one :)
36
37
        // init
38
        $js_combobox.each(function(index_combo) {
39
            var $this = $(this),
40
                $this_id = $this.attr('id'),
41
                $label_this = $('label[for="' + $this_id + '"]'),
42
                index_lisible = index_combo + 1,
43
                options = $this.data(),
44
                $combobox_prefix_class = typeof options.comboboxPrefixClass !== 'undefined' ? options.comboboxPrefixClass + '-' : '',
45
                $combobox_help_text = typeof options.comboboxHelpText !== 'undefined' ? options.comboboxHelpText : default_text_help,
46
                $list_suggestions = $('#' + $this.attr('list')),
47
                $combobox_button_title = typeof options.comboboxButtonTitle !== 'undefined' ? options.comboboxButtonTitle : button_clear_title,
48
                $combobox_button_text = typeof options.comboboxButtonText !== 'undefined' ? options.comboboxButtonText : button_clear_text,
49
                $combobox_case_sensitive = typeof options.comboboxCaseSensitive !== 'undefined' ? options.comboboxCaseSensitive : case_sensitive,
50
                tablo_temp_suggestions = [];
51
52
            // input
53
            $this.attr({
54
                'data-number': index_lisible,
55
                'autocorrect': 'off',
56
                'autocapitalize': 'off',
57
                'spellcheck': 'false',
58
                'autocomplete': 'off',
59
                'aria-describedby': $combobox_prefix_class + 'help-text' + index_lisible,
60
                'aria-autocomplete': 'list',
61
                'data-lastval': '',
62
                'aria-owns': $combobox_prefix_class + 'suggest_' + index_lisible
63
            });
64
            // stock into tables
65
            $list_suggestions.find('option').each(function(index_option, index_element) {
66
                tablo_temp_suggestions.push(index_element.value);
67
            });
68
            if ($combobox_case_sensitive === 'no') {
69
                // order case tablo_temp_suggestions
70
                tablo_suggestions[index_lisible] = tablo_temp_suggestions.sort(function(a, b) {
71
                    a = a.toLowerCase();
72
                    b = b.toLowerCase();
73
                    if (a == b) {
74
                        return 0;
75
                    }
76
                    if (a > b) {
77
                        return 1;
78
                    }
79
                    return -1;
80
                });
81
            } else {
82
                tablo_suggestions[index_lisible] = tablo_temp_suggestions.sort();
83
            }
84
85
            // wrap into a container
86
            $this.wrap('<div class="' + $combobox_prefix_class + 'container js-container" data-combobox-prefix-class="' + $combobox_prefix_class + '"></div>');
87
88
            var $combobox_container = $this.parent();
89
90
            // custom datalist/listbox linked to input
91
            $combobox_container.append('<div id="' + $combobox_prefix_class + 'suggest_' + index_lisible + '" class="js-suggest ' + $combobox_prefix_class + 'suggestions"><div role="listbox"></div></div>');
92
            $list_suggestions.remove();
93
94
            // status zone
95
            // $combobox_container.prepend('<div id="' + $combobox_prefix_class + 'suggestion-text' + index_lisible + '" class="js-suggestion-text ' + $combobox_prefix_class + 'suggestion-text ' + default_class_for_invisible_text + '" aria-live="assertive"></div>');
96
97
            // help text
98
            $combobox_container.prepend('<span id="' + $combobox_prefix_class + 'help-text' + index_lisible + '" class="' + $combobox_prefix_class + 'help-text ' + default_class_for_invisible_text + '">' + $combobox_help_text + '</span>');
99
100
            // label id
101
            $label_this.attr('id', 'label-id-' + $this_id);
102
103
            // button clear
104
            $this.after('<button class="js-clear-button ' + $combobox_prefix_class + 'clear-button" aria-label="' + $combobox_button_title + '" title="' + $combobox_button_title + '" aria-describedby="label-id-' + $this_id + '" type="button">' + $combobox_button_text + '</button>');
105
106
        });
107
108
109
        // listeners
110
        // keydown on field
111
        $body.on('keyup', '.js-combobox', function(event) {
112
                var $this = $(this),
113
                    options_combo = $this.data(),
114
                    $container = $this.parent(),
115
                    $form = $container.parents('form'),
116
                    options = $container.data(),
117
                    $combobox_prefix_class = typeof options.comboboxPrefixClass !== 'undefined' ? options.comboboxPrefixClass : '', // no "-"" because already generated
118
                    $suggestions = $container.find('.js-suggest div'),
119
                    //$suggestion_list = $suggestions.find('.js-suggestion'),
120
                    $suggestions_text = $container.find('.js-suggestion-text'),
121
                    $combobox_suggestion_single = typeof options_combo.suggestionSingle !== 'undefined' ? options_combo.suggestionSingle : suggestion_single,
122
                    $combobox_suggestion_plural = typeof options_combo.suggestionPlural !== 'undefined' ? options_combo.suggestionPlural : suggestion_plural,
123
                    $combobox_suggestion_word = typeof options_combo.suggestionWord !== 'undefined' ? options_combo.suggestionWord : suggestion_word,
124
                    $combobox_suggestion_word_plural = typeof options_combo.suggestionWord !== 'undefined' ? options_combo.suggestionWordPlural : suggestion_word_plural,
125
                    combobox_min_length = typeof options_combo.comboboxMinLength !== 'undefined' ? Math.abs(options_combo.comboboxMinLength) : min_length,
126
                    $combobox_case_sensitive = typeof options_combo.comboboxCaseSensitive !== 'undefined' ? options_combo.comboboxCaseSensitive : case_sensitive,
127
                    combobox_limit_number_suggestions = typeof options_combo.comboboxLimitNumberSuggestions !== 'undefined' ? Math.abs(options_combo.comboboxLimitNumberSuggestions) : limit_number_suggestions,
128
                    $combobox_search_option = typeof options_combo.comboboxSearchOption !== 'undefined' ? options_combo.comboboxSearchOption : search_option,
129
                    $combobox_see_more_text = typeof options_combo.comboboxSeeMoreText !== 'undefined' ? options_combo.comboboxSeeMoreText : see_more_text,
130
                    index_table = $this.attr('data-number'),
131
                    value_to_search = $this.val(),
132
                    text_number_suggestions = '';
133
134
                if (event.keyCode === 13) {
135
                    $form.submit();
136
                } else {
137
138
                    if (event.keyCode !== 27) { // No Escape
139
140
                        $this.attr('data-lastval', value_to_search);
141
                        // search for text suggestion in the array tablo_suggestions[index_table]
142
                        var size_tablo = tablo_suggestions[index_table].length,
143
                            i = 0,
144
                            counter = 0;
145
146
                        $suggestions.empty();
147
148
                        if (value_to_search != '' && value_to_search.length >= combobox_min_length) {
149
                            while (i < size_tablo) {
150
                                if (counter < combobox_limit_number_suggestions) {
151
                                    if (
152
                                        (
153
                                            $combobox_search_option === 'containing' &&
154
                                            (
155
                                                ($combobox_case_sensitive === 'yes' && (tablo_suggestions[index_table][i].indexOf(value_to_search) >= 0)) ||
156
                                                ($combobox_case_sensitive === 'no' && (tablo_suggestions[index_table][i].toUpperCase().indexOf(value_to_search.toUpperCase()) >= 0))
157
                                            )
158
                                        ) ||
159
                                        (
160
                                            $combobox_search_option === 'beginning' &&
161
                                            (
162
                                                ($combobox_case_sensitive === 'yes' && tablo_suggestions[index_table][i].substring(0, value_to_search.length) === value_to_search) ||
163
                                                ($combobox_case_sensitive === 'no' && tablo_suggestions[index_table][i].substring(0, value_to_search.length).toUpperCase() === value_to_search.toUpperCase())
164
                                            )
165
                                        )
166
                                    ) {
167
                                        $suggestions.append('<div id="suggestion-' + index_table + '-' + counter + '" class="js-suggestion ' + $combobox_prefix_class + 'suggestion" tabindex="-1" role="option">' + tablo_suggestions[index_table][i] + '</div>');
168
                                        counter++;
169
                                    }
170
                                }
171
                                i++;
172
                            }
173
                            if (counter >= combobox_limit_number_suggestions) {
174
                                $suggestions.append('<div id="suggestion-' + index_table + '-' + counter + '" class="js-suggestion js-seemore ' + $combobox_prefix_class + 'suggestion" tabindex="-1" role="option">' + $combobox_see_more_text + '</div>');
175
                                counter++;
176
                            }
177
                            // update number of suggestions
178
                            if (counter > 1) {
179
                                text_number_suggestions = $combobox_suggestion_plural + counter + ' ' + $combobox_suggestion_word_plural + '.';
180
                            }
181
                            if (counter === 1) {
182
                                text_number_suggestions = $combobox_suggestion_single + counter + ' ' + $combobox_suggestion_word + '.';
183
                            }
184
                            if (counter === 0) {
185
                                text_number_suggestions = $combobox_suggestion_single + counter + ' ' + $combobox_suggestion_word + '.';
186
                            }
187
                            if (counter >= 0) {
188
                                var text_number_suggestions_default = $suggestions_text.text();
189
                                if (text_number_suggestions != text_number_suggestions_default) { // @Goestu trick to make it work on all AT
190
                                    var suggestions_to_add = $("<p>").text(text_number_suggestions);
191
                                    $suggestions_text.attr('aria-live', 'polite');
192
                                    $suggestions_text.empty();
193
                                    $suggestions_text.append(suggestions_to_add);
194
                                }
195
                            }
196
197
                        }
198
199
                    }
200
                }
201
202
            })
203
            .on('click', function(event) {
204
                var $target = $(event.target),
205
                    $suggestions_text = $('.js-suggestion-text:not(:empty)'), // if a suggestion text is not empty => suggestion opened somewhere
206
                    $container = $suggestions_text.parents('.js-container'),
207
                    $input_text = $container.find('.js-combobox'),
208
                    $suggestions = $container.find('.js-suggest div');
209
210
                // if click outside => close opened suggestions 
211
                if (!$target.is('.js-suggestion') && !$target.is('.js-combobox') && $suggestions_text.length) {
212
                    $input_text.val($input_text.attr('data-lastval'));
213
                    $suggestions.empty();
214
                    $suggestions_text.empty();
215
                }
216
            })
217
            // tab + down management for autocomplete (when list of suggestion)
218
            .on('keydown', '.js-combobox', function(event) {
219
                var $this = $(this),
220
                    $container = $this.parent(),
221
                    $input_text = $container.find('.js-combobox'),
222
                    $suggestions = $container.find('.js-suggest div'),
223
                    $suggestion_list = $suggestions.find('.js-suggestion'),
224
                    $suggestions_text = $container.find('.js-suggestion-text'),
225
                    $autorise_tab_options = typeof $this.attr('data-combobox-notab-options') !== 'undefined' ? false : true,
226
                    $first_suggestion = $suggestion_list.first();
227
228
                if ((!event.shiftKey && event.keyCode == 9 && $autorise_tab_options) || event.keyCode == 40) { // tab (if authorised) or bottom
229
                    // See if there are suggestions, and yes => focus on first one
230
                    if ($suggestion_list.length) {
231
                        $input_text.val($first_suggestion.html());
232
                        $suggestion_list.first().focus();
233
                        event.preventDefault();
234
                    }
235
                }
236
                if (event.keyCode == 27 || ($autorise_tab_options === false && event.keyCode == 9)) { // esc or (tab/shift tab + notab option) = close
237
                    $input_text.val($input_text.attr('data-lastval'));
238
                    $suggestions.empty();
239
                    $suggestions_text.empty();
240
                    if (event.keyCode == 27) { // Esc prevented only, tab can go :)
241
                        event.preventDefault();
242
                        setTimeout(function() {
243
                            $input_text.focus();
244
                        }, 300); // timeout to avoid problem in suggestions display
245
                    }
246
                }
247
248
            })
249
            // tab + down management in list of suggestions
250
            .on('keydown', '.js-suggestion', function(event) {
251
                var $this = $(this),
252
                    $container = $this.parents('.js-container'),
253
                    $input_text = $container.find('.js-combobox'),
254
                    $autorise_tab_options = typeof $input_text.attr('data-combobox-notab-options') !== 'undefined' ? false : true,
255
                    $suggestions = $container.find('.js-suggest div'),
256
                    $suggestions_text = $container.find('.js-suggestion-text'),
257
                    $next_suggestion = $this.next(),
258
                    $previous_suggestion = $this.prev();
259
260
                if (event.keyCode == 27 || ($autorise_tab_options === false && event.keyCode == 9)) { // esc or (tab/shift tab + notab option) = close
261
                    if (event.keyCode == 27) { // Esc prevented only, tab can go :)
262
                        $input_text.val($input_text.attr('data-lastval'));
263
                        $suggestions.empty();
264
                        $suggestions_text.empty();
265
                        setTimeout(function() {
266
                            $input_text.focus();
267
                        }, 300); // timeout to avoid problem in suggestions display
268
                        event.preventDefault();
269
                    }
270
                    if ($autorise_tab_options === false && event.keyCode == 9) {
271
                        $suggestions.empty();
272
                        $suggestions_text.empty();
273
                        $input_text.focus();
274
                    }
275
                }
276
                if (event.keyCode == 13 || event.keyCode == 32) { // Enter or space
277
                    if ($this.hasClass('js-seemore')) {
278
                        $input_text.val($input_text.attr('data-lastval'));
279
                        $suggestions.empty();
280
                        $suggestions_text.empty();
281
                        setTimeout(function() {
282
                            $input_text.focus();
283
                        }, 300); // timeout to avoid problem in suggestions display
284
                        // go define the function you need when we click the see_more option
285
                        setTimeout(function() {
286
                            do_see_more_option();
287
                        }, 301); // timeout to avoid problem in suggestions display
288
                        event.preventDefault();
289
                    } else {
290
                        $input_text.val($this.html());
291
                        $input_text.attr('data-lastval', $this.html());
292
                        $suggestions.empty();
293
                        $suggestions_text.empty();
294
                        setTimeout(function() {
295
                            $input_text.focus();
296
                        }, 300); // timeout to avoid problem in suggestions display
297
                        event.preventDefault();
298
                    }
299
300
                }
301
                if ((!event.shiftKey && event.keyCode == 9 && $autorise_tab_options) || event.keyCode == 40) { // tab (if authorised) or bottom
302
                    if ($next_suggestion.length) {
303
                        $input_text.val($next_suggestion.html());
304
                        $next_suggestion.focus();
305
                    } else {
306
                        $input_text.val($input_text.attr('data-lastval'));
307
                        if (!event.shiftKey && event.keyCode == 9) { // tab closes the list
308
                            var e = jQuery.Event("keydown");
309
                            e.which = 27; // # Some key code value
310
                            e.keyCode = 27;
311
                            $this.trigger(e);
312
                        } else {
313
                            setTimeout(function() {
314
                                $input_text.focus();
315
                            }, 300);
316
                        } // timeout to avoid problem in suggestions display
317
318
                    }
319
                    event.preventDefault();
320
                }
321
322
                if ((event.shiftKey && event.keyCode == 9 && $autorise_tab_options) || event.keyCode == 38) { // top or Maj+tab (if authorised)
323
                    if ($previous_suggestion.length) {
324
                        $input_text.val($previous_suggestion.html());
325
                        $previous_suggestion.focus();
326
                    } else {
327
                        $input_text.val($input_text.attr('data-lastval')).focus();
328
                    }
329
                    event.preventDefault();
330
                }
331
            })
332
            // clear button
333
            .on('click', '.js-clear-button', function() {
334
                var $this = $(this),
335
                    $container = $this.parent(),
336
                    $input_text = $container.find('.js-combobox'),
337
                    $suggestions = $container.find('.js-suggest div'),
338
                    $suggestions_text = $container.find('.js-suggestion-text');
339
340
                $suggestions.empty();
341
                $suggestions_text.empty();
342
                $input_text.val('');
343
                $input_text.attr('data-lastval', '');
344
345
            })
346
            .on('click', '.js-suggestion', function() {
347
                var $this = $(this),
348
                    value = $this.html(),
349
                    $container = $this.parents('.js-container'),
350
                    $input_text = $container.find('.js-combobox'),
351
                    $suggestions = $container.find('.js-suggest div'),
352
                    $suggestions_text = $container.find('.js-suggestion-text');
353
354
                if ($this.hasClass('js-seemore')) {
355
                    $suggestions.empty();
356
                    $suggestions_text.empty();
357
                    $input_text.focus();
358
                    // go define the function you need when we click the see_more option
359
                    do_see_more_option();
360
                } else {
361
                    $input_text.val(value).focus();
362
                    $suggestions.empty();
363
                    $suggestions_text.empty();
364
                }
365
366
367
            });
368
369
370
    }
371
372
});

public/js/autocomplete.js 1 location

@@ 94-454 (lines=361) @@
91
  !*** ./resources/assets/js/autocomplete.js ***!
92
  \*********************************************/
93
/*! no static exports found */
94
/***/ (function(module, exports) {
95
96
$(document).ready(function () {
97
  /*
98
   * jQuery accessible and keyboard-enhanced autocomplete list
99
   * @version v1.6.0
100
   * Website: https://a11y.nicolas-hoffmann.net/autocomplet-list/
101
   * License MIT: https://github.com/nico3333fr/jquery-accessible-autocomplete-list-aria/blob/master/LICENSE
102
   */
103
  // loading combobox ------------------------------------------------------------------------------------------------------------
104
  // init
105
  var $js_combobox = $('.js-combobox'),
106
      $body = $('body'),
107
      // default_text_help = 'Use tabulation (or down) key to access and browse suggestions after input. Confirm your choice with enter key, or esc key to close suggestions box.',
108
  default_text_help = '',
109
      default_class_for_invisible_text = 'invisible',
110
      suggestion_single = 'There is ',
111
      suggestion_plural = 'There are ',
112
      suggestion_word = 'suggestion',
113
      suggestion_word_plural = 'suggestions',
114
      button_clear_title = 'clear this field',
115
      button_clear_text = 'X',
116
      case_sensitive = 'no',
117
      min_length = 0,
118
      limit_number_suggestions = 666,
119
      search_option = 'beginning',
120
      // or 'containing'
121
  see_more_text = 'See more results…',
122
      tablo_suggestions = [];
123
124
  function do_see_more_option() {
125
    var $output_content = $('#js-codeit');
126
    $output_content.html('You have to code a function or a redirection to display more results ;)');
127
  }
128
129
  if ($js_combobox.length) {
130
    // if there are at least one :)
131
    // init
132
    $js_combobox.each(function (index_combo) {
133
      var $this = $(this),
134
          $this_id = $this.attr('id'),
135
          $label_this = $('label[for="' + $this_id + '"]'),
136
          index_lisible = index_combo + 1,
137
          options = $this.data(),
138
          $combobox_prefix_class = typeof options.comboboxPrefixClass !== 'undefined' ? options.comboboxPrefixClass + '-' : '',
139
          $combobox_help_text = typeof options.comboboxHelpText !== 'undefined' ? options.comboboxHelpText : default_text_help,
140
          $list_suggestions = $('#' + $this.attr('list')),
141
          $combobox_button_title = typeof options.comboboxButtonTitle !== 'undefined' ? options.comboboxButtonTitle : button_clear_title,
142
          $combobox_button_text = typeof options.comboboxButtonText !== 'undefined' ? options.comboboxButtonText : button_clear_text,
143
          $combobox_case_sensitive = typeof options.comboboxCaseSensitive !== 'undefined' ? options.comboboxCaseSensitive : case_sensitive,
144
          tablo_temp_suggestions = []; // input
145
146
      $this.attr({
147
        'data-number': index_lisible,
148
        'autocorrect': 'off',
149
        'autocapitalize': 'off',
150
        'spellcheck': 'false',
151
        'autocomplete': 'off',
152
        'aria-describedby': $combobox_prefix_class + 'help-text' + index_lisible,
153
        'aria-autocomplete': 'list',
154
        'data-lastval': '',
155
        'aria-owns': $combobox_prefix_class + 'suggest_' + index_lisible
156
      }); // stock into tables
157
158
      $list_suggestions.find('option').each(function (index_option, index_element) {
159
        tablo_temp_suggestions.push(index_element.value);
160
      });
161
162
      if ($combobox_case_sensitive === 'no') {
163
        // order case tablo_temp_suggestions
164
        tablo_suggestions[index_lisible] = tablo_temp_suggestions.sort(function (a, b) {
165
          a = a.toLowerCase();
166
          b = b.toLowerCase();
167
168
          if (a == b) {
169
            return 0;
170
          }
171
172
          if (a > b) {
173
            return 1;
174
          }
175
176
          return -1;
177
        });
178
      } else {
179
        tablo_suggestions[index_lisible] = tablo_temp_suggestions.sort();
180
      } // wrap into a container
181
182
183
      $this.wrap('<div class="' + $combobox_prefix_class + 'container js-container" data-combobox-prefix-class="' + $combobox_prefix_class + '"></div>');
184
      var $combobox_container = $this.parent(); // custom datalist/listbox linked to input
185
186
      $combobox_container.append('<div id="' + $combobox_prefix_class + 'suggest_' + index_lisible + '" class="js-suggest ' + $combobox_prefix_class + 'suggestions"><div role="listbox"></div></div>');
187
      $list_suggestions.remove(); // status zone
188
      // $combobox_container.prepend('<div id="' + $combobox_prefix_class + 'suggestion-text' + index_lisible + '" class="js-suggestion-text ' + $combobox_prefix_class + 'suggestion-text ' + default_class_for_invisible_text + '" aria-live="assertive"></div>');
189
      // help text
190
191
      $combobox_container.prepend('<span id="' + $combobox_prefix_class + 'help-text' + index_lisible + '" class="' + $combobox_prefix_class + 'help-text ' + default_class_for_invisible_text + '">' + $combobox_help_text + '</span>'); // label id
192
193
      $label_this.attr('id', 'label-id-' + $this_id); // button clear
194
195
      $this.after('<button class="js-clear-button ' + $combobox_prefix_class + 'clear-button" aria-label="' + $combobox_button_title + '" title="' + $combobox_button_title + '" aria-describedby="label-id-' + $this_id + '" type="button">' + $combobox_button_text + '</button>');
196
    }); // listeners
197
    // keydown on field
198
199
    $body.on('keyup', '.js-combobox', function (event) {
200
      var $this = $(this),
201
          options_combo = $this.data(),
202
          $container = $this.parent(),
203
          $form = $container.parents('form'),
204
          options = $container.data(),
205
          $combobox_prefix_class = typeof options.comboboxPrefixClass !== 'undefined' ? options.comboboxPrefixClass : '',
206
          // no "-"" because already generated
207
      $suggestions = $container.find('.js-suggest div'),
208
          //$suggestion_list = $suggestions.find('.js-suggestion'),
209
      $suggestions_text = $container.find('.js-suggestion-text'),
210
          $combobox_suggestion_single = typeof options_combo.suggestionSingle !== 'undefined' ? options_combo.suggestionSingle : suggestion_single,
211
          $combobox_suggestion_plural = typeof options_combo.suggestionPlural !== 'undefined' ? options_combo.suggestionPlural : suggestion_plural,
212
          $combobox_suggestion_word = typeof options_combo.suggestionWord !== 'undefined' ? options_combo.suggestionWord : suggestion_word,
213
          $combobox_suggestion_word_plural = typeof options_combo.suggestionWord !== 'undefined' ? options_combo.suggestionWordPlural : suggestion_word_plural,
214
          combobox_min_length = typeof options_combo.comboboxMinLength !== 'undefined' ? Math.abs(options_combo.comboboxMinLength) : min_length,
215
          $combobox_case_sensitive = typeof options_combo.comboboxCaseSensitive !== 'undefined' ? options_combo.comboboxCaseSensitive : case_sensitive,
216
          combobox_limit_number_suggestions = typeof options_combo.comboboxLimitNumberSuggestions !== 'undefined' ? Math.abs(options_combo.comboboxLimitNumberSuggestions) : limit_number_suggestions,
217
          $combobox_search_option = typeof options_combo.comboboxSearchOption !== 'undefined' ? options_combo.comboboxSearchOption : search_option,
218
          $combobox_see_more_text = typeof options_combo.comboboxSeeMoreText !== 'undefined' ? options_combo.comboboxSeeMoreText : see_more_text,
219
          index_table = $this.attr('data-number'),
220
          value_to_search = $this.val(),
221
          text_number_suggestions = '';
222
223
      if (event.keyCode === 13) {
224
        $form.submit();
225
      } else {
226
        if (event.keyCode !== 27) {
227
          // No Escape
228
          $this.attr('data-lastval', value_to_search); // search for text suggestion in the array tablo_suggestions[index_table]
229
230
          var size_tablo = tablo_suggestions[index_table].length,
231
              i = 0,
232
              counter = 0;
233
          $suggestions.empty();
234
235
          if (value_to_search != '' && value_to_search.length >= combobox_min_length) {
236
            while (i < size_tablo) {
237
              if (counter < combobox_limit_number_suggestions) {
238
                if ($combobox_search_option === 'containing' && ($combobox_case_sensitive === 'yes' && tablo_suggestions[index_table][i].indexOf(value_to_search) >= 0 || $combobox_case_sensitive === 'no' && tablo_suggestions[index_table][i].toUpperCase().indexOf(value_to_search.toUpperCase()) >= 0) || $combobox_search_option === 'beginning' && ($combobox_case_sensitive === 'yes' && tablo_suggestions[index_table][i].substring(0, value_to_search.length) === value_to_search || $combobox_case_sensitive === 'no' && tablo_suggestions[index_table][i].substring(0, value_to_search.length).toUpperCase() === value_to_search.toUpperCase())) {
239
                  $suggestions.append('<div id="suggestion-' + index_table + '-' + counter + '" class="js-suggestion ' + $combobox_prefix_class + 'suggestion" tabindex="-1" role="option">' + tablo_suggestions[index_table][i] + '</div>');
240
                  counter++;
241
                }
242
              }
243
244
              i++;
245
            }
246
247
            if (counter >= combobox_limit_number_suggestions) {
248
              $suggestions.append('<div id="suggestion-' + index_table + '-' + counter + '" class="js-suggestion js-seemore ' + $combobox_prefix_class + 'suggestion" tabindex="-1" role="option">' + $combobox_see_more_text + '</div>');
249
              counter++;
250
            } // update number of suggestions
251
252
253
            if (counter > 1) {
254
              text_number_suggestions = $combobox_suggestion_plural + counter + ' ' + $combobox_suggestion_word_plural + '.';
255
            }
256
257
            if (counter === 1) {
258
              text_number_suggestions = $combobox_suggestion_single + counter + ' ' + $combobox_suggestion_word + '.';
259
            }
260
261
            if (counter === 0) {
262
              text_number_suggestions = $combobox_suggestion_single + counter + ' ' + $combobox_suggestion_word + '.';
263
            }
264
265
            if (counter >= 0) {
266
              var text_number_suggestions_default = $suggestions_text.text();
267
268
              if (text_number_suggestions != text_number_suggestions_default) {
269
                // @Goestu trick to make it work on all AT
270
                var suggestions_to_add = $("<p>").text(text_number_suggestions);
271
                $suggestions_text.attr('aria-live', 'polite');
272
                $suggestions_text.empty();
273
                $suggestions_text.append(suggestions_to_add);
274
              }
275
            }
276
          }
277
        }
278
      }
279
    }).on('click', function (event) {
280
      var $target = $(event.target),
281
          $suggestions_text = $('.js-suggestion-text:not(:empty)'),
282
          // if a suggestion text is not empty => suggestion opened somewhere
283
      $container = $suggestions_text.parents('.js-container'),
284
          $input_text = $container.find('.js-combobox'),
285
          $suggestions = $container.find('.js-suggest div'); // if click outside => close opened suggestions 
286
287
      if (!$target.is('.js-suggestion') && !$target.is('.js-combobox') && $suggestions_text.length) {
288
        $input_text.val($input_text.attr('data-lastval'));
289
        $suggestions.empty();
290
        $suggestions_text.empty();
291
      }
292
    }) // tab + down management for autocomplete (when list of suggestion)
293
    .on('keydown', '.js-combobox', function (event) {
294
      var $this = $(this),
295
          $container = $this.parent(),
296
          $input_text = $container.find('.js-combobox'),
297
          $suggestions = $container.find('.js-suggest div'),
298
          $suggestion_list = $suggestions.find('.js-suggestion'),
299
          $suggestions_text = $container.find('.js-suggestion-text'),
300
          $autorise_tab_options = typeof $this.attr('data-combobox-notab-options') !== 'undefined' ? false : true,
301
          $first_suggestion = $suggestion_list.first();
302
303
      if (!event.shiftKey && event.keyCode == 9 && $autorise_tab_options || event.keyCode == 40) {
304
        // tab (if authorised) or bottom
305
        // See if there are suggestions, and yes => focus on first one
306
        if ($suggestion_list.length) {
307
          $input_text.val($first_suggestion.html());
308
          $suggestion_list.first().focus();
309
          event.preventDefault();
310
        }
311
      }
312
313
      if (event.keyCode == 27 || $autorise_tab_options === false && event.keyCode == 9) {
314
        // esc or (tab/shift tab + notab option) = close
315
        $input_text.val($input_text.attr('data-lastval'));
316
        $suggestions.empty();
317
        $suggestions_text.empty();
318
319
        if (event.keyCode == 27) {
320
          // Esc prevented only, tab can go :)
321
          event.preventDefault();
322
          setTimeout(function () {
323
            $input_text.focus();
324
          }, 300); // timeout to avoid problem in suggestions display
325
        }
326
      }
327
    }) // tab + down management in list of suggestions
328
    .on('keydown', '.js-suggestion', function (event) {
329
      var $this = $(this),
330
          $container = $this.parents('.js-container'),
331
          $input_text = $container.find('.js-combobox'),
332
          $autorise_tab_options = typeof $input_text.attr('data-combobox-notab-options') !== 'undefined' ? false : true,
333
          $suggestions = $container.find('.js-suggest div'),
334
          $suggestions_text = $container.find('.js-suggestion-text'),
335
          $next_suggestion = $this.next(),
336
          $previous_suggestion = $this.prev();
337
338
      if (event.keyCode == 27 || $autorise_tab_options === false && event.keyCode == 9) {
339
        // esc or (tab/shift tab + notab option) = close
340
        if (event.keyCode == 27) {
341
          // Esc prevented only, tab can go :)
342
          $input_text.val($input_text.attr('data-lastval'));
343
          $suggestions.empty();
344
          $suggestions_text.empty();
345
          setTimeout(function () {
346
            $input_text.focus();
347
          }, 300); // timeout to avoid problem in suggestions display
348
349
          event.preventDefault();
350
        }
351
352
        if ($autorise_tab_options === false && event.keyCode == 9) {
353
          $suggestions.empty();
354
          $suggestions_text.empty();
355
          $input_text.focus();
356
        }
357
      }
358
359
      if (event.keyCode == 13 || event.keyCode == 32) {
360
        // Enter or space
361
        if ($this.hasClass('js-seemore')) {
362
          $input_text.val($input_text.attr('data-lastval'));
363
          $suggestions.empty();
364
          $suggestions_text.empty();
365
          setTimeout(function () {
366
            $input_text.focus();
367
          }, 300); // timeout to avoid problem in suggestions display
368
          // go define the function you need when we click the see_more option
369
370
          setTimeout(function () {
371
            do_see_more_option();
372
          }, 301); // timeout to avoid problem in suggestions display
373
374
          event.preventDefault();
375
        } else {
376
          $input_text.val($this.html());
377
          $input_text.attr('data-lastval', $this.html());
378
          $suggestions.empty();
379
          $suggestions_text.empty();
380
          setTimeout(function () {
381
            $input_text.focus();
382
          }, 300); // timeout to avoid problem in suggestions display
383
384
          event.preventDefault();
385
        }
386
      }
387
388
      if (!event.shiftKey && event.keyCode == 9 && $autorise_tab_options || event.keyCode == 40) {
389
        // tab (if authorised) or bottom
390
        if ($next_suggestion.length) {
391
          $input_text.val($next_suggestion.html());
392
          $next_suggestion.focus();
393
        } else {
394
          $input_text.val($input_text.attr('data-lastval'));
395
396
          if (!event.shiftKey && event.keyCode == 9) {
397
            // tab closes the list
398
            var e = jQuery.Event("keydown");
399
            e.which = 27; // # Some key code value
400
401
            e.keyCode = 27;
402
            $this.trigger(e);
403
          } else {
404
            setTimeout(function () {
405
              $input_text.focus();
406
            }, 300);
407
          } // timeout to avoid problem in suggestions display
408
409
        }
410
411
        event.preventDefault();
412
      }
413
414
      if (event.shiftKey && event.keyCode == 9 && $autorise_tab_options || event.keyCode == 38) {
415
        // top or Maj+tab (if authorised)
416
        if ($previous_suggestion.length) {
417
          $input_text.val($previous_suggestion.html());
418
          $previous_suggestion.focus();
419
        } else {
420
          $input_text.val($input_text.attr('data-lastval')).focus();
421
        }
422
423
        event.preventDefault();
424
      }
425
    }) // clear button
426
    .on('click', '.js-clear-button', function () {
427
      var $this = $(this),
428
          $container = $this.parent(),
429
          $input_text = $container.find('.js-combobox'),
430
          $suggestions = $container.find('.js-suggest div'),
431
          $suggestions_text = $container.find('.js-suggestion-text');
432
      $suggestions.empty();
433
      $suggestions_text.empty();
434
      $input_text.val('');
435
      $input_text.attr('data-lastval', '');
436
    }).on('click', '.js-suggestion', function () {
437
      var $this = $(this),
438
          value = $this.html(),
439
          $container = $this.parents('.js-container'),
440
          $input_text = $container.find('.js-combobox'),
441
          $suggestions = $container.find('.js-suggest div'),
442
          $suggestions_text = $container.find('.js-suggestion-text');
443
444
      if ($this.hasClass('js-seemore')) {
445
        $suggestions.empty();
446
        $suggestions_text.empty();
447
        $input_text.focus(); // go define the function you need when we click the see_more option
448
449
        do_see_more_option();
450
      } else {
451
        $input_text.val(value).focus();
452
        $suggestions.empty();
453
        $suggestions_text.empty();
454
      }
455
    });
456
  }
457
});