PageSourceSearch

https://autorentvitesse.nl/DesktopModules/DnnSharp/Common/static/angular15/angucomplete-alt.js?cdv=387

js autorentvitesse.nl collected 2026-10-08 09:33:18 UTC 39,509 bytes, 920 lines download raw bytes

1(function (angular) {
2    var app = angular.module('angucomplete', ['ngSanitize']);
3    app.directive('scrolly', ['$timeout', function ($timeout) {
4        return {
5            restrict: 'A',
6            link: function (scope, element, attrs) {
7                element.bind('scroll', function () {
8                    $timeout(function () {
9                        scope.resLimit += parseInt(scope.displayNumber) ? parseInt(scope.displayNumber) : 10;
10                    }, 1500);
11                });
12            }
13        };
14    }]);
15
16    app.directive('angucomplete', ['$q', '$parse', '$http', '$sce', '$timeout', '$templateCache', '$interpolate', function ($q, $parse, $http, $sce, $timeout, $templateCache, $interpolate) {
17        // keyboard events
18        var KEY_DW = 40;
19        var KEY_RT = 39;
20        var KEY_UP = 38;
21        var KEY_LF = 37;
22        var KEY_ES = 27;
23        var KEY_EN = 13;
24        var KEY_TAB = 9;
25
26        var MIN_LENGTH = 3;
27        var MAX_LENGTH = 524288;  // the default max length per the html maxlength attribute
28        var PAUSE = 500;
29        var BLUR_TIMEOUT = 200;
30
31        // string constants
32        var REQUIRED_CLASS = 'autocomplete-required';
33        var TEXT_SEARCHING = 'Searching...';
34        var TEXT_NORESULTS = 'No results found';
35        var TEMPLATE_URL = '/angucomplete-alt/index.html';
36
37        // Set the default template for this directive
38        $templateCache.put(TEMPLATE_URL,
39            '<div class="angucomplete-holder" ng-class="{\'angucomplete-dropdown-visible\': showDropdown}" ng-cloak>' +
40            '<input id="{{id}}" name="{{id}}" data-val="{{dataVal}}" tabindex="{{fieldTabindex}}" ng-class="{\'angucomplete-input-not-empty\': notEmpty, \'required\': required}" ng-model="searchStr" ng-disabled="disableInput" type="{{inputType}}" placeholder="{{placeholder}}" maxlength="{{maxlength}}" ng-focus="onFocusHandler()" class="ignore-focusout-validation preventdefault {{inputClass}} autocomplete angucomplete-input" ng-focus="resetHideResults()" ng-blur="hideResults($event)" autocapitalize="off" autocorrect="off" autocomplete="off" ng-change="inputChangeHandler(searchStr)"/>' +
41            '  <div scrolly id="{{id}}_dropdown" class="angucomplete-dropdown panel panel-default" ng-show="showDropdown">' +
42            '    <div class="angucomplete-searching" ng-show="searching" ng-bind="textSearching"></div>' +
43            '    <div class="angucomplete-searching" ng-show="!searching && (!results || results.length == 0)" ng-bind-html="textNoResults"></div>' +
44            '    <div class="angucomplete-row" ng-repeat="result in results | limitTo: resLimit" ng-click="selectResult(result)" ng-mouseenter="hoverRow($index)" ng-class="{\'angucomplete-selected-row\': $index == currentIndex}">' +
45            // '      <div ng-if="imageField" class="angucomplete-image-holder">' +
46            // '        <img ng-if="result.image && result.image != \'\'" ng-src="{{result.image}}" class="angucomplete-image"/>' +
47            // '        <div ng-if="!result.image && result.image != \'\'" class="angucomplete-image-default"></div>' +
48            // '      </div>' +
49            '      <div class="angucomplete-title" ng-if="matchClass" ng-bind-html="result.originalObject.matchedtext || result.originalObject.text"></div>' +
50            // '      <div class="angucomplete-title" ng-if="!matchClass">{{ result.title }}</div>' +
51            // '      <div ng-if="matchClass && result.description && result.description != \'\'" class="angucomplete-description" ng-bind-html="result.description"></div>' +
52            // '      <div ng-if="!matchClass && result.description && result.description != \'\'" class="angucomplete-description">{{result.description}}</div>' +
53            '    </div>' +
54            '  </div>' +
55            '</div>'
56        );
57
58        function link(scope, elem, attrs, ctrl) {
59            scope.resLimit = parseInt(scope.displayNumber) ? parseInt(scope.displayNumber) : 50;
60            scope.required = elem.hasClass('required');
61            var inputField = elem.find('input');
62            var minlength = MIN_LENGTH;
63            var searchTimer = null;
64            var hideTimer;
65            var requiredClassName = REQUIRED_CLASS;
66            var responseFormatter;
67            var validState = null;
68            var httpCanceller = null;
69            var httpCallInProgress = false;
70            var dd = elem[0].querySelector('.angucomplete-dropdown');
71            var isScrollOn = false;
72            var mousedownOn = null;
73            var unbindInitialValue;
74            var displaySearching;
75            var displayNoResults;
76            if (scope.initValue) {
77                $.each(scope.localData, function (i, v) {
78                    if (v.text == scope.initValue) {
79                        scope.dataVal = v.path;
80                        scope.searchStr = v.text;
81                        scope.selectedObject = v;
82                    } else {
83                        if (v.value == scope.initValue) {
84                            scope.dataVal = v.path;
85                            scope.searchStr = v.text;
86                            scope.selectedObject = v;
87                        }
88                    }
89                })
90            }
91            elem.on('mousedown', function (event) {
92                if (event.target.id) {
93                    mousedownOn = event.target.id;
94                    if (mousedownOn === scope.id + '_dropdown') {
95                        document.body.addEventListener('click', clickoutHandlerForDropdown);
96                    }
97                }
98                else {
99                    mousedownOn = event.target.className;
100                }
101            });
102
vendor: 17,895 bytes, lines 103-538
103            scope.currentIndex = scope.focusFirst ? 0 : null;
104            scope.searching = false;
105            unbindInitialValue = scope.$watch('initialValue', function (newval) {
106                if (newval) {
107                    // remove scope listener
108                    unbindInitialValue();
109                    // change input
110                    handleInputChange(newval, true);
111                }
112            });
113            scope.$watch('fieldRequired', function (newval, oldval) {
114                if (newval !== oldval) {
115                    if (!newval) {
116                        ctrl[scope.inputName].$setValidity(requiredClassName, true);
117                    }
118                    else if (!validState || scope.currentIndex === -1) {
119                        handleRequired(false);
120                    }
121                    else {
122                        handleRequired(true);
123                    }
124                }
125            });
126
127            scope.$on('angucomplete-alt:clearInput', function (event, elementId) {
128                if (!elementId || elementId === scope.id) {
129                    scope.searchStr = null;
130                    callOrAssign();
131                    handleRequired(false);
132                    clearResults();
133                }
134            });
135
136            scope.$on('angucomplete-alt:changeInput', function (event, elementId, newval) {
137                if (!!elementId && elementId === scope.id) {
138                    handleInputChange(newval);
139                }
140            });
141
142            function handleInputChange(newval, initial) {
143                if (newval) {
144                    if (typeof newval === 'object') {
145                        scope.searchStr = extractTitle(newval);
146                        callOrAssign({ originalObject: newval });
147                    } else if (typeof newval === 'string' && newval.length > 0) {
148                        scope.searchStr = newval;
149                    } else {
150                        if (console && console.error) {
151                            console.error('Tried to set ' + (!!initial ? 'initial' : '') + ' value of angucomplete to', newval, 'which is an invalid value');
152                        }
153                    }
154
155                    handleRequired(true);
156                }
157            }
158
159            // #194 dropdown list not consistent in collapsing (bug).
160            function clickoutHandlerForDropdown(event) {
161                mousedownOn = null;
162                scope.hideResults(event);
163                document.body.removeEventListener('click', clickoutHandlerForDropdown);
164            }
165
166            // for IE8 quirkiness about event.which
167            function ie8EventNormalizer(event) {
168                return event.which ? event.which : event.keyCode;
169            }
170
171            function callOrAssign(value) {
172                if (typeof scope.selectedObject === 'function') {
173                    scope.selectedObject(value, scope.selectedObjectData);
174                }
175                else {
176                    scope.selectedObject = value;
177                }
178
179                if (value) {
180                    handleRequired(true);
181                }
182                else {
183                    handleRequired(false);
184                }
185            }
186
187            function callFunctionOrIdentity(fn) {
188                return function (data) {
189                    return scope[fn] ? scope[fn](data) : data;
190                };
191            }
192
193            function setInputString(str) {
194                callOrAssign({ originalObject: str });
195
196                if (scope.clearSelected) {
197                    scope.searchStr = null;
198                }
199                clearResults();
200            }
201
202            function extractTitle(data) {
203                // split title fields and run extractValue for each and join with ' '
204                return scope.titleField.split(',')
205                    .map(function (field) {
206                        return extractValue(data, field);
207                    })
208                    .join(' ');
209            }
210
211            function extractValue(obj, key) {
212                var keys, result;
213                if (key) {
214                    keys = key.split('.');
215                    result = obj;
216                    for (var i = 0; i < keys.length; i++) {
217                        result = result[keys[i]];
218                    }
219                }
220                else {
221                    result = obj;
222                }
223                return result;
224            }
225
226            function findMatchString(target, str) {
227                var result, matches, re;
228                // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
229                // Escape user input to be treated as a literal string within a regular expression
230                re = new RegExp(str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i');
231                if (!target) { return; }
232                if (!target.match || !target.replace) { target = target.toString(); }
233                matches = target.match(re);
234                if (matches) {
235                    result = target.replace(re,
236                        '<span class="' + scope.matchClass + '">' + matches[0] + '</span>');
237                }
238                else {
239                    result = target;
240                }
241                return $sce.trustAsHtml(result);
242            }
243
244            function handleRequired(valid) {
245                scope.notEmpty = valid;
246                validState = scope.searchStr;
247                if (scope.fieldRequired && ctrl && scope.inputName) {
248                    ctrl[scope.inputName].$setValidity(requiredClassName, valid);
249                }
250            }
251
252            function keyupHandler(event) {
253                var which = ie8EventNormalizer(event);
254                if (which === KEY_LF || which === KEY_RT) {
255                    // do nothing
256                    return;
257                }
258
259                if (which === KEY_UP || which === KEY_EN) {
260                    event.preventDefault();
261                }
262                else if (which === KEY_DW) {
263                    if (!scope.searchStr) {
264                        scope.showDropdown = true;
265                        showAll();
266                    }
267
268                    if (!scope.showDropdown && scope.searchStr && scope.searchStr.length >= minlength) {
269                        initResults();
270                        scope.searching = true;
271                        searchTimerComplete(scope.searchStr);
272                    }
273                }
274                else if (which === KEY_ES) {
275                    clearResults();
276                    scope.$apply(function () {
277                        inputField.val(scope.searchStr);
278                    });
279                }
280                else {
281                    if (minlength === 0 && !scope.searchStr) {
282                        return;
283                    }
284
285                    if (!scope.searchStr || scope.searchStr === '') {
286                        scope.showDropdown = false;
287                    } else if (scope.searchStr.length >= minlength) {
288                        initResults();
289
290                        if (searchTimer) {
291                            $timeout.cancel(searchTimer);
292                        }
293
294                        scope.searching = true;
295
296                        searchTimer = $timeout(function () {
297                            searchTimerComplete(scope.searchStr);
298                        }, scope.pause);
299                    }
300
301                    if (validState && validState !== scope.searchStr && !scope.clearSelected) {
302                        scope.$apply(function () {
303                            callOrAssign();
304                        });
305                    }
306                }
307            }
308
309            function handleOverrideSuggestions(event) {
310                if (scope.overrideSuggestions &&
311                    !(scope.selectedObject && scope.selectedObject.originalObject === scope.searchStr)) {
312                    if (event) {
313                        event.preventDefault();
314                        event.stopPropagation();
315                    }
316
317                    // cancel search timer
318                    $timeout.cancel(searchTimer);
319                    // cancel http request
320                    cancelHttpRequest();
321                    //Check if we have a match on the first search result to keep it or clear
322                    if ((scope.results[0] ? scope.results[0].title : '') != scope.searchStr)
323                        scope.searchStr = '';
324                    setInputString(scope.searchStr);
325                }
326            }
327
328            function dropdownRowOffsetHeight(row) {
329                var css = getComputedStyle(row);
330                return row.offsetHeight +
331                    parseInt(css.marginTop, 10) + parseInt(css.marginBottom, 10);
332            }
333
334            function dropdownHeight() {
335                return dd.getBoundingClientRect().top +
336                    parseInt(getComputedStyle(dd).maxHeight, 10);
337            }
338
339            function dropdownRow() {
340                return elem[0].querySelectorAll('.angucomplete-row')[scope.currentIndex];
341            }
342
343            function dropdownRowTop() {
344                return dropdownRow().getBoundingClientRect().top -
345                    (dd.getBoundingClientRect().top +
346                        parseInt(getComputedStyle(dd).paddingTop, 10));
347            }
348
349            function dropdownScrollTopTo(offset) {
350                dd.scrollTop = dd.scrollTop + offset;
351            }
352
353            function updateInputField() {
354                var current = scope.results[scope.currentIndex];
355                if (scope.matchClass) {
356                    inputField.val(extractTitle(current.originalObject));
357                }
358                else {
359                    inputField.val(current.title);
360                }
361            }
362
363            function keydownHandler(event) {
364                event.stopPropagation();
365                var which = ie8EventNormalizer(event);
366                var row = null;
367                var rowTop = null;
368
369                if (which === KEY_EN && scope.results) {
370                    if (scope.currentIndex >= 0 && scope.currentIndex < scope.results.length) {
371                        event.preventDefault();
372                        event.stopPropagation();
373                        scope.selectResult(scope.results[scope.currentIndex]);
374                    } else {
375                        handleOverrideSuggestions(event);
376                        clearResults();
377                    }
378                    scope.$apply();
379                } else if (which === KEY_DW && scope.results) {
380                    event.preventDefault();
381                    if ((scope.currentIndex + 1) < scope.results.length && scope.showDropdown) {
382                        scope.$apply(function () {
383                            scope.currentIndex++;
384                            //Add more items if it is the last
385                            if (scope.currentIndex == scope.resLimit - 1)
386                                $timeout(function () {
387                                    scope.resLimit += parseInt(scope.displayNumber) ? parseInt(scope.displayNumber) : 10;
388                                }, 1500);
389                            updateInputField();
390                        });
391
392                        if (isScrollOn) {
393                            row = dropdownRow();
394                            if (dropdownHeight() < row.getBoundingClientRect().bottom) {
395                                dropdownScrollTopTo(dropdownRowOffsetHeight(row));
396                            }
397                        }
398                    }
399                } else if (which === KEY_UP && scope.results) {
400                    event.preventDefault();
401                    if (scope.currentIndex >= 1) {
402                        scope.$apply(function () {
403                            scope.currentIndex--;
404                            updateInputField();
405                        });
406
407                        if (isScrollOn) {
408                            rowTop = dropdownRowTop();
409                            if (rowTop < 0) {
410                                dropdownScrollTopTo(rowTop - 1);
411                            }
412                        }
413                    }
414                    else if (scope.currentIndex === 0) {
415                        scope.$apply(function () {
416                            scope.currentIndex = -1;
417                            inputField.val(scope.searchStr);
418                        });
419                    }
420                } else if (which === KEY_TAB) {
421                    if (scope.results && scope.results.length > 0 && scope.showDropdown) {
422                        if (scope.currentIndex === -1 && scope.overrideSuggestions) {
423                            // intentionally not sending event so that it does not
424                            // prevent default tab behavior
425                            handleOverrideSuggestions();
426                        }
427                        else {
428                            if (scope.currentIndex === -1) {
429                                scope.currentIndex = 0;
430                            }
431                            scope.selectResult(scope.results[scope.currentIndex]);
432                            scope.$digest();
433                        }
434                    }
435                    else {
436                        // no results
437                        // intentionally not sending event so that it does not
438                        // prevent default tab behavior
439                        if (scope.searchStr && scope.searchStr.length > 0) {
440                            handleOverrideSuggestions();
441                        }
442                    }
443                } else if (which === KEY_ES) {
444                    // This is very specific to IE10/11 #272
445                    // without this, IE clears the input text
446                    event.preventDefault();
447                }
448            }
449
450            function httpSuccessCallbackGen(str) {
451                return function (responseData, status, headers, config) {
452                    // normalize return obejct from promise
453                    if (!status && !headers && !config && responseData.data) {
454                        responseData = responseData.data;
455                    }
456                    scope.searching = false;
457                    processResults(
458                        extractValue(responseFormatter(responseData), scope.remoteUrlDataField),
459                        str);
460                };
461            }
462
463            function httpErrorCallback(errorRes, status, headers, config) {
464                scope.searching = httpCallInProgress;
465
466                // normalize return obejct from promise
467                if (!status && !headers && !config) {
468                    status = errorRes.status;
469                }
470
471                // cancelled/aborted
472                if (status === 0 || status === -1) { return; }
473                if (scope.remoteUrlErrorCallback) {
474                    scope.remoteUrlErrorCallback(errorRes, status, headers, config);
475                }
476                else {
477                    if (console && console.error) {
478                        console.error('http error');
479                    }
480                }
481            }
482
483            function cancelHttpRequest() {
484                if (httpCanceller) {
485                    httpCanceller.resolve();
486                }
487            }
488
489            function getRemoteResults(str) {
490                var params = {},
491                    url = scope.remoteUrl + encodeURIComponent(str);
492                if (scope.remoteUrlRequestFormatter) {
493                    params = { params: scope.remoteUrlRequestFormatter(str) };
494                    url = scope.remoteUrl;
495                }
496                if (!!scope.remoteUrlRequestWithCredentials) {
497                    params.withCredentials = true;
498                }
499                cancelHttpRequest();
500                httpCanceller = $q.defer();
501                params.timeout = httpCanceller.promise;
502                httpCallInProgress = true;
503                $http.get(url, params)
504                    .success(httpSuccessCallbackGen(str))
505                    .error(httpErrorCallback)
506                    .finally(function () { httpCallInProgress = false; });
507            }
508
509            function getRemoteResultsWithCustomHandler(str) {
510                cancelHttpRequest();
511
512                httpCanceller = $q.defer();
513
514                scope.remoteApiHandler(str, httpCanceller.promise)
515                    .then(httpSuccessCallbackGen(str))
516                    .catch(httpErrorCallback);
517
518                /* IE8 compatible
519                scope.remoteApiHandler(str, httpCanceller.promise)
520                  ['then'](httpSuccessCallbackGen(str))
521                  ['catch'](httpErrorCallback);
522                */
523            }
524
525            function clearResults() {
526                scope.showDropdown = false;
527                scope.results = [];
528                if (dd) {
529                    dd.scrollTop = 0;
530                }
531                if (!scope.dataVal || !scope.selectedObject) {
532                    scope.searchStr = "";
533                    scope.dataVal = "";
534                }
535            }
536
537            function initResults() {
538                scope.showDropdown = displaySearching;
539                scope.currentIndex = scope.focusFirst ? 0 : -1;
540                scope.results = [];
541            }
542
543            function getLocalResults(str) {
544                var i, match, s, value,
545                    searchFields = scope.searchFields.split(','),
546                    matches = [];
547                if (typeof scope.parseInput() !== 'undefined') {
548                    str = scope.parseInput()(str);
549                }
550                for (i = 0; i < scope.localData.length; i++) {
551                    match = false;
552
553                    for (s = 0; s < searchFields.length; s++) {
554                        value = extractValue(scope.localData[i], searchFields[s]) || '';
555                        match = match || (value.toString().toLowerCase().indexOf(str.toString().toLowerCase()) >= 0);
556                    }
557
558                    if (match) {
559                        matches[matches.length] = scope.localData[i];
560                    }
561                }
562                return matches;
563            }
564
565            function checkExactMatch(result, obj, str) {
566                if (!str) { return false; }
567                for (var key in obj) {
568                    if (obj[key].toLowerCase() === str.toLowerCase()) {
569                        scope.selectResult(result);
570                        return true;
571                    }
572                }
573                return false;
574            }
575
576            function searchTimerComplete(str) {
577                // Begin the search
578                if (!str || str.length < minlength) {
579                    return;
580                }
581                if (scope.localData) {
582                    scope.$apply(function () {
583                        var matches;
584                        if (typeof scope.localSearch() !== 'undefined') {
585                            matches = scope.localSearch()(str, scope.localData);
586                        } else {
587                            matches = getLocalResults(str);
588                        }
589                        scope.searching = false;
590                        processResults(matches, str);
591                    });
592                }
593                else if (scope.remoteApiHandler) {
594                    getRemoteResultsWithCustomHandler(str);
595                } else {
596                    getRemoteResults(str);
597                }
598            }
599
600            function processResults(responseData, str) {
601                var i, description, image, text, formattedText, formattedDesc;
602
603                if (responseData && responseData.length > 0) {
604                    scope.results = [];
605
606                    for (i = 0; i < responseData.length; i++) {
607                        responseData[i].initialValue ? (responseData[i].value = responseData[i].initialValue) : (responseData[i].initialValue = responseData[i].value);
608                        responseData[i].title ? (responseData[i].title = responseData[i].text) : (responseData[i].title = responseData[i].text);
609                        if (scope.titleField && scope.titleField !== '') {
610                            text = formattedText = extractTitle(responseData[i]);
611                        }
612
613                        description = '';
614                        if (scope.descriptionField) {
615                            description = formattedDesc = extractValue(responseData[i], scope.descriptionField);
616                        }
617
618                        image = '';
619                        if (scope.imageField) {
620                            image = extractValue(responseData[i], scope.imageField);
621                        }
622
623                        if (scope.matchClass) {
624                            formattedText = findMatchString(text, str);
625                            //formattedDesc = findMatchString(description, str);
626                        }
627                        responseData[i].matchedtext = formattedText;
628                        scope.results[scope.results.length] = {
629                            title: responseData[i].title,
630                            description: formattedDesc,
631                            originalObject: responseData[i],
632                            value: responseData[i].initialValue
633                        };
634                    }
635
636                } else {
637                    scope.results = [];
638                }
639
640                if (scope.autoMatch && scope.results.length === 1 &&
641                    checkExactMatch(scope.results[0],
642                        { title: text, desc: description || '' }, scope.searchStr)) {
643                    scope.showDropdown = false;
644                } else if (scope.results.length === 0 && !displayNoResults) {
645                    scope.showDropdown = false;
646                } else {
647                    scope.showDropdown = true;
648                    //In case of searching .... wait and don't crash
649                    if (!scope.results) {
650                        scope.results = { 'length': 0 };
651                    }
652                    //Calculate height of dropdown
653                    var getHeight = setInterval(function () {
654                        if ((scope.results.length == 0 ? 1 : scope.results.length) < scope.displayNumber && $('#' + scope.id + "_dropdown").children().last(
654) != null) {
655                            $('#' + scope.id + '_dropdown').css('height', ($('#' + scope.id + "_dropdown").children().last().outerHeight() * parseInt((scope.results.length == 0 ? 1 : scope.results.length))) + 'px');
656                            window.clearInterval(getHeight);
657                        } else {
658                            $('#' + scope.id + '_dropdown').css('height', ($('#' + scope.id + "_dropdown").children().last().outerHeight() * parseInt(scope.displayNumber) - 20) + 'px');
659                            window.clearInterval(getHeight);
660                        }
661                    }, 50);
662
663                }
664            }
665
666            function showAll() {
667                if (scope.localData) {
668                    scope.searching = false;
669                    processResults(scope.localData, '');
670                }
671                else if (scope.remoteApiHandler) {
672                    scope.searching = true;
673                    getRemoteResultsWithCustomHandler('');
674                }
675                else {
676                    scope.searching = true;
677                    getRemoteResults('');
678                }
679            }
680
681            scope.onFocusHandler = function () {
682                scope.resLimit = parseInt(scope.displayNumber) ? parseInt(scope.displayNumber) : 50;
683                if (scope.focusIn) {
684                    scope.focusIn();
685                    scope.showDropdown = false;
686                    //Option to display dropdown only for when you start typing
687                    if (scope.disableDropdownOnClick != 'True')
688                        showAll();
689                }
690
691                if (minlength === 0 && (!scope.searchStr || scope.searchStr.length === 0)) {
692                    scope.currentIndex = scope.focusFirst ? 0 : scope.currentIndex;
693                    scope.showDropdown = true;
694                    showAll();
695                }
696            };
697
698            scope.hideResults = function () {
699                if (mousedownOn &&
700                    (mousedownOn === scope.matchClass ||
701                        mousedownOn === scope.id + '_dropdown' ||
702                        mousedownOn.indexOf('angucomplete') >= 0)) {
703                    mousedownOn = null;
704                }
705                else {
706                    clearResults();
707                    hideTimer = $timeout(function () {
708                        scope.$apply(function () {
709                            if (scope.searchStr && scope.searchStr.length > 0) {
710                                inputField.val(scope.searchStr);
711                            }
712                        });
713                    }, BLUR_TIMEOUT);
714                    cancelHttpRequest();
715
716                    if (scope.focusOut) {
717                        scope.focusOut();
718                    }
719
720                    scope.overrideSuggestions = true;
721                    if (scope.overrideSuggestions) {
722                        if (scope.searchStr && scope.searchStr.length > 0 && scope.currentIndex === -1) {
723                            handleOverrideSuggestions();
724                        }
725                    }
726                }
727            };
728
729            scope.resetHideResults = function () {
730                if (hideTimer) {
731                    $timeout.cancel(hideTimer);
732                }
733            };
734
735            scope.hoverRow = function (index) {
736                scope.currentIndex = index;
737            };
738
739            scope.selectResult = function (result) {
740                if (result.value == scope.ngModel && scope.searchStr == result.title)
741                    return;
742                scope.updateField({ field: attrs.afField, val: result.value });
743                // Restore original values
744                // if (scope.matchClass) {
745                //   result.title = extractTitle(result.originalObject);
746                //   result.description = extractValue(result.originalObject, scope.descriptionField);
747                // }
748                scope.showDropdown = false;
749                if (scope.clearSelected) {
750                    scope.searchStr = null;
751                }
752                else {
753                    scope.dataVal = result.originalObject.path;
754                    scope.searchStr = result.title;
755                }
756                callOrAssign(result);
757                clearResults();
758            };
759
760            scope.inputChangeHandler = function (str) {
761                if (!str.length) {
762                    scope.dataVal = "";
763                    scope.updateField({ field: attrs.afField, val: "" });
764                }
765                if (str.length < minlength) {
766                    cancelHttpRequest();
767                    clearResults();
768                }
769                else if (str.length === 0 && minlength === 0) {
770                    showAll();
771                }
772
773                if (scope.inputChanged) {
774                    str = scope.inputChanged(str);
775                }
776                return str;
777            };
778
779            // check required
780            if (scope.fieldRequiredClass && scope.fieldRequiredClass !== '') {
781                requiredClassName = scope.fieldRequiredClass;
782            }
783
784            // check min length
785            if (scope.minlength && scope.minlength !== '') {
786                minlength = parseInt(scope.minlength, 10);
787            }
788
789            // check pause time
790            if (!scope.pause) {
791                scope.pause = PAUSE;
792            }
793
794            // check clearSelected
795            if (!scope.clearSelected) {
796                scope.clearSelected = false;
797            }
798
799            // check override suggestions
800            if (!scope.overrideSuggestions) {
801                scope.overrideSuggestions = false;
802            }
803
804            // check required field
805            if (scope.fieldRequired && ctrl) {
806                // check initial value, if given, set validitity to true
807                if (scope.initialValue) {
808                    handleRequired(true);
809                }
810                else {
811                    handleRequired(false);
812                }
813            }
814
815            scope.inputType = attrs.type ? attrs.type : 'text';
816
817            // set strings for "Searching..." and "No results"
818            scope.textSearching = attrs.textSearching ? attrs.textSearching : TEXT_SEARCHING;
819            scope.textNoResults = attrs.textNoResults ? $sce.trustAsHtml(attrs.textNoResults) : TEXT_NORESULTS;
820            displaySearching = scope.textSearching === 'false' ? false : true;
821            displayNoResults = scope.textNoResults === 'false' ? false : true;
822
823            // set max length (default to maxlength deault from html
824            scope.maxlength = attrs.maxlength ? attrs.maxlength : MAX_LENGTH;
825
826            // register events
827            inputField.on('keydown', keydownHandler);
828            inputField.on('keyup', keyupHandler);
829
830            // set response formatter
831            responseFormatter = callFunctionOrIdentity('remoteUrlResponseFormatter');
832
833            // set isScrollOn
834            $timeout(function () {
835                var css = getComputedStyle(dd);
836                isScrollOn = css.maxHeight && css.overflowY === 'auto';
837            });
838
839            scope.$watch('ngModel', function (newVal, oldVal) {
840                if (newVal != oldVal) {
841                    var result = _.find(scope.localData, function (result, index) { return result.value === newVal });
842                    if (!result) {
843                        return;
844                    }
845                    var selectableResult = {
846                        originalObject: result,
847                        value: result.value,
848                        title: result.text
849                    }
850                    scope.selectResult(selectableResult);
851                }
852            });
853        }
854
855        return {
856            restrict: 'EA',
857            require: '^?form',
858            scope: {
859                // selectedObject: '=',
860                selectedObjectData: '=',
861                disableInput: '=',
862                initialValue: '=',
863                initValue: '=',
864                disabled: '=',
865                displayNumber: '=?',
866                disableDropdownOnClick: '=?',
867                localData: '=',
868                localSearch: '&',
869                remoteUrlRequestFormatter: '=',
870                remoteUrlRequestWithCredentials: '@',
871                remoteUrlResponseFormatter: '=',
872                remoteUrlErrorCallback: '=',
873                remoteApiHandler: '=',
874                id: '@',
875                type: '@',
876                placeholder: '@',
877                textSearching: '@',
878                textNoResults: '@',
879                remoteUrl: '@',
880                remoteUrlDataField: '@',
881                titleField: '@',
882                descriptionField: '@',
883                imageField: '@',
884                inputClass: '@',
885                pause: '@',
886                searchFields: '@',
887                minlength: '@',
888                matchClass: '@',
889                clearSelected: '@',
890                overrideSuggestions: '@',
891                fieldRequired: '=',
892                fieldRequiredClass: '@',
893                inputChanged: '=',
894                autoMatch: '@',
895                focusOut: '&',
896                focusIn: '&',
897                fieldTabindex: '@',
898                inputName: '@',
899                focusFirst: '@',
900                parseInput: '&',
901                updateField: '&',
902                ngModel: '='
903            },
904            templateUrl: function (element, attrs) {
905                return attrs.templateUrl || TEMPLATE_URL;
906            },
907            compile: function (tElement) {
908                var startSym = $interpolate.startSymbol();
909                var endSym = $interpolate.endSymbol();
910                if (!(startSym === '{{' && endSym === '}}')) {
911                    var interpolatedHtml = tElement.html()
912                        .replace(/\{\{/g, startSym)
913                        .replace(/\}\}/g, endSym);
914                    tElement.html(interpolatedHtml);
915                }
916                return link;
917            }
918        };
919    }]);
920})(window.dnnsfAngular15 || window.angular);

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.