PageSourceSearch

https://www.quebec.ca/_assets/8b5470729627060287ec80151aeaf598/Jav…/Solr/suggest_controller.js?1790696784

js quebec.ca collected 2026-10-01 07:14:04 UTC 12,797 bytes, 279 lines download raw bytes

1function SuggestController() {
2
3    this.init = function () {
4      console.log("suggest init")
5      // Créer un widget personnalisé pour redéfinir le rendu des items
6      $.widget("custom.autocomplete", $.ui.autocomplete, {
7        _resizeMenu: function() {
8          // pour donner au panneau des suggestions la largeur de la barre de recherche
9          let component = this.element.closest("qc-search-bar");
10          if (component.length == 0) {
11            component = this.element;
12          }
13          this.menu.element.outerWidth(component.outerWidth());
14        },
15        _renderItem: function(ul, item) {
16          var currentValue = this.term;
17          var pattern = new RegExp('(' + $.ui.autocomplete.escapeRegex(currentValue.trim()) + ')', "gi");
18
19          // Si c'est une suggestion de recherche
20          // Fonction pour formater le texte : applique le remplacement du pattern avec une balise,
21// échappe les caractères HTML puis restaure la balise de mise en forme.
22          function formatText(text, pattern, tag) {
23            var highlighted = text.replace(pattern, '<' + tag + '>$1</' + tag + '>');
24            var escaped = highlighted
25              .replace(/&/g, '&amp;')
26              .replace(/</g, '&lt;')
27              .replace(/>/g, '&gt;')
28              .replace(/"/g, '&quot;');
29            var regex = new RegExp('&lt;(\\/?' + tag + ')&gt;', 'g');
30            return escaped.replace(regex, '<$1>');
31          }
32
33          if (item.category === 'suggestion') {
34            var formatted = formatText(item.label, pattern, 'strong');
35            return this._getListItemElement(item, formatted)
36                    .appendTo(ul);
37          } else {
38            var formatted = formatText(item.data.title, pattern, 'em');
39            var html = '<div class="' + item.data.type + '">'
40              + (item.data.previewImage ? '<figure ' + (item.data.hasVideo ? 'class="hasVideo"' : '') + '>'
41                + '<img src="' + item.data.previewImage + '" />'
42                + '</figure>' : '')
43              + '<a href="' + item.data.link + '" class="internal-link">' + formatted + '</a>'
44              + '</div>';
45            return $("<li>")
46              .append(html)
47
48          }
49
50        }
51      });
52
53        jQuery('form[data-suggest]').each(function () {
54            var $form = $(this),
55              $searchBox = $form.find('.tx-solr-suggest'),
56              $formAutoComplete;
57
58            if ($searchBox.length === 0 ) {
59              return;
60            }
61
62
63            if ($form.find('.tx-solr-autocomplete').length > 0){
64                $formAutoComplete = $form.find('.tx-solr-autocomplete');
65            } else {
66                // Utiliser le qc-search-bar parent comme conteneur pour le panneau
67                // afin d'éviter un décalage de positionnement quand appendTo est body
68                var $searchBar = $searchBox.closest('qc-search-bar');
69                $formAutoComplete = $searchBar.length > 0 ? $searchBar : $('body');
70            }
71
72            $form.find('.tx-solr-suggest-focus').focus();
73
74
75            // when no specific container found, use the form as container
76            if ($searchBox.length === 0) {
77                $searchBox = $form;
78            }
79            // Positionnement relatif : sur le searchBar si présent, sinon sur le searchBox (comportement d'origine)
80            if ($searchBar && $searchBar.length > 0) {
81                $formAutoComplete.css('position', 'relative');
82            } else {
83                $searchBox.css('position', 'relative');
84            }
85
86          $searchBox.autocomplete({
87            delay: 500, // équivalent de deferRequestBy
88            minLength: 2,
89            // Utilisation d'une fonction source pour appeler votre service JSONP
90            source: function(request, response) {
91              let maxResults = this.option("maxResults")
92              console.log("maxResults", maxResults, this.option("foobar"))
93              $.ajax({
94                url: $form.data('suggest'),
95                dataType: 'json',
96                data: { 'tx_solr[queryString]': request.term },
97                success: function(data) {
98                  var results = [];
99                  var firstSuggestion;
100                  console.log(this)
101                  // Traitement des suggestions simples
102                  if (data.suggestions) {
103                    let
104                      start = 0
105                    ;
106                    $.each(data.suggestions, function(suggestion, count) {
107                      if (++start > maxResults) return
108                      if (!firstSuggestion) firstSuggestion = suggestion;
109                      results.push({
110                        label: suggestion,
111                        value: suggestion,
112                        category: 'suggestion',
113                        data: { count: count }
114                      });
115
116                    });
117                  }
118                  // Traitement des documents (résultats enrichis)
119                  if (data.documents) {
120                    $.each(data.documents, function(key, value) {
121                      var defaultGroup = $form.data('suggest-header') || 'Top results';
122                      value.category = value.group ? ($form.data('suggest-header-' + value.group) || value.group) : defaultGroup;
123                      results.push({
124                        label: firstSuggestion,
125                        value: firstSuggestion,
126                        data: value
127                      });
128                    });
129                  }
130                  response(results);
131                }
132              });
133            },
134            autoFocus: false, // équivalent de autoSelectFirst: false
135            appendTo: $formAutoComplete,
136            select: function(event, ui) {
137              // Comportement lors de la sélection d'un item
138              if (ui.item.data.link) {
139                if (ui.item.data.link.indexOf('https://www.youtube.com') === 0) {
140                  openVideoOverlay(ui.item.data.link);
141                } else {
142                  location.href = ui.item.data.link;
143                }
144              } else {
145                $form.trigger('submit');
146              }
147            },
148            open: function(event, ui) {
149              // Ajout d'une classe active et ajustement de la largeur
150              $searchBox.parent().addClass("autocomplete-active").fadeIn();
151              // $(this).autocomplete("widget").css("width", $searchBox.outerWidth() * 0.66);
152              // Si besoin de supprimer un header de groupe, vous pouvez le faire ici
153            },
154            close: function(event, ui) {
155              $searchBox.parent().removeClass("autocomplete-active");
156            }
157          })
158            .on('blur', function() {
159              // Fermer le menu au blur
160              $(this).autocomplete("close");
161            });
162          $searchBox.autocomplete("option", "maxResults", 5)
163            // $form.find('.tx-solr-suggest').devbridgeAutocomplete({
164            //     deferRequestBy: 500,
165            //     serviceUrl: $form.data('suggest'),
166            //     dataType: 'jsonp',
167            //     paramName: 'tx_solr[queryString]',
168            //     groupBy: 'category',
169            //     maxHeight: 1000,
170            //     appendTo: $formAutoComplete,
171            //     autoSelectFirst: false,
172            //     triggerSelectOnValidInput: false,
173            //     width: $searchBox.outerWidth() * 0.66,
174            //     onSelect: function (suggestion) {
175            //         // go to link when selecting found result
176            //         if (suggestion.data.link) {
177            //             // Open youtube in overlay
178            //             if (suggestion.data.link.indexOf('https://www.youtube.com') === 0) {
179            //                 openVideoOverlay(suggestion.data.link);
180            //             } else {
181            //                 location.href = suggestion.data.link;
182            //             }
183            //             // else trigger form submit (do search)
184            //         } else {
185            //             $form.trigger('submit');
186            //         }
187            //     },
188            //     transformResult: function (response) {
189            //         if (!response.suggestions) return {suggestions: []};
190            //         var firstSuggestion, result = {
191            //             suggestions: $.map(response.suggestions, function (count, suggestion) {
192            //                 if (!firstSuggestion) firstSuggestion = suggestion;
193            //                 return {value: suggestion, data: {category: 'suggestion', count: count}};
194            //             })
195            //         };
196            //
197            //         $.each(response.documents, function (key, value) {
198            //             var dataObject = value;
199            //
200            //             var defaultGroup = $form.data('suggest-header') ? $form.data('suggest-header') : 'Top results';
201            //             dataObject.category = defaultGroup;
202            //
203            //             // if a group is set we try to get a label
204            //             if(dataObject.group) {
205            //                 dataObject.category = $form.data('suggest-header-' + dataObject.group) ? $form.data('suggest-header-' + dataObject.group) : dataObject.group;
206            //             }
207            //
208            //             result.suggestions.push(
209            //                 {
210            //                     value: firstSuggestion,
211            //                     data: dataObject
212            //                 }
213            //             );
214            //         });
215            //
216            //         return result;
217            //     },
218            //     beforeRender: function (container) {
219            //         // remove first group header
220            //         container.find('.autocomplete-group:first').remove();
221            //         container.addClass('tx-solr-autosuggest');
222            //
223            //         // add active class to container
224            //         $searchBox.parent().addClass('autocomplete-active').fadeIn();
225            //     },
226            //     formatResult: function (suggestion, currentValue) {
227            //         // Do not replace anything if there current value is empty
228            //         if (!currentValue) {
229            //             return suggestion.value;
230            //         }
231            //         var pattern = '(' + $.Autocomplete.utils.escapeRegExChars(currentValue.trim()) + ')';
232            //         // normal suggestion
233            //         if (suggestion.data.category === 'suggestion') {
234            //             return suggestion.value
235            //                 .replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>')
236            //                 .replace(/&/g, '&amp;')
237            //                 .replace(/</g, '&lt;')
238            //                 .replace(/>/g, '&gt;')
239            //                 .replace(/"/g, '&quot;')
240            //                 .replace(/&lt;(\/?strong)&gt;/g, '<$1>');
241            //
242            //             // results
243            //         } else {
244            //             var title = suggestion.data.title
245            //                 .replace(new RegExp(pattern, 'gi'), '<em>$1<\/em>')
246            //                 .replace(/&/g, '&amp;')
247            //                 .replace(/</g, '&lt;')
248            //                 .replace(/>/g, '&gt;')
249            //                 .replace(/"/g, '&quot;')
250            //                 .replace(/&lt;(\/?em)&gt;/g, '<$1>');
251            //
252            //             return '<div class="' + suggestion.data.type + '">' +
253            //                 (!!suggestion.data.previewImage ? '<figure ' + (!!suggestion.data.hasVideo ? 'class="hasVideo"' : '') + '>
253<img src="' + suggestion.data.previewImage + '" /></figure>' : '') +
254            //                 '<a href="' + suggestion.data.link + '" class="internal-link">' + title + '</a>' +
255            //                 '</div>';
256            //         }
257            //
258            //     }
259            // }).on('blur', function () {
260            //     $searchBox.parent().removeClass('autocomplete-active');
261            //     var $box = $(this);
262            //     setTimeout(function () {
263            //         $box.devbridgeAutocomplete('hide');
264            //     }, 200);
265            // });
266        });
267    };
268}
269
270jQuery(document).ready(function() {
271    /** solr search autocomplete **/
272    var solrSuggestController = new SuggestController();
273    solrSuggestController.init();
274
275    jQuery("body").on("tx_solr_updated", function() {
276        solrSuggestController.init();
277    });
278});
279

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.