Procházet zdrojové kódy

Feature: stag-suggest

Vijayakrishnan před 3 roky
rodič
revize
a911f1e9c8
1 změnil soubory, kde provedl 180 přidání a 0 odebrání
  1. 180 0
      public/js/stag-suggest.js

+ 180 - 0
public/js/stag-suggest.js

@@ -0,0 +1,180 @@
+(function () {
+    window.initStagSuggest = function () {
+
+        let suggestionsOuter = null;
+
+        const debounce = (func, wait) => {
+            let timeout;
+            return function executedFunction(...args) {
+                const later = () => {
+                    clearTimeout(timeout);
+                    func(...args);
+                };
+                clearTimeout(timeout);
+                timeout = setTimeout(later, wait);
+            };
+        };
+
+        var lastTerm = '';
+        var returnedFunction = debounce(function (elem) {
+            let term = elem.val();
+            if (!!term && lastTerm !== term) {
+                let ep = $(elem).attr('stag-suggest-ep');
+                $.get(ep + '?term=' + $.trim(term), function (_data) {
+
+                    /*
+                    expected return format:
+                    {
+                        success: true,
+                        data: [
+                            {
+                                x: ...,
+                                y: ...,
+                                text: ...    // "text" key is "mandatory"
+                            },
+                            {
+                                x: ...,
+                                y: ...,
+                                text: ...    // "text" key is "mandatory"
+                            },
+                            ...
+                        ]
+                    }
+                     */
+
+                    suggestionsOuter.empty();
+                    if(!hasResponseError(_data) && _data.data && _data.data.length) {
+                        for (let i = 0; i < _data.data.length; i++) {
+                            let item = $('<a native href="#" class="d-block suggest-item stag-suggest text-nowrap"/>');
+                            for(let x in _data.data[i]) {
+                                if(_data.data[i].hasOwnProperty(x) && x !== 'text') {
+                                    item.attr('data-' + x, _data.data[i][x]);
+                                }
+                            }
+                            item.data('suggest-data', _data.data[i]);
+                            item.html(_data.data[i].text);
+                            suggestionsOuter.append(item);
+                        }
+                    }
+                    else {
+                        suggestionsOuter.html('<span class="d-block no-suggest-items">No matches!</span>');
+                    }
+
+                    suggestionsOuter.removeClass('d-none');
+                }, 'json');
+                lastTerm = term;
+            } else {
+                suggestionsOuter.addClass('d-none');
+            }
+        }, 250);
+
+        function handleKeydown(elem, e) {
+            let term = $.trim(elem.val());
+            let activeItem = suggestionsOuter.find('.suggest-item.active');
+            switch (e.which) {
+                case 27:
+                    suggestionsOuter.addClass('d-none');
+                    return false;
+                case 38:
+                    if (activeItem.prev().length) {
+                        activeItem.prev()
+                            .addClass('active')
+                            .siblings().removeClass('active');
+                        activeItem = suggestionsOuter.find('.suggest-item.active');
+                        if (activeItem.length) {
+                            activeItem[0].scrollIntoView();
+                        }
+                    }
+                    return false;
+                case 40:
+                    if (activeItem.next().length) {
+                        activeItem.next()
+                            .addClass('active')
+                            .siblings().removeClass('active');
+                        activeItem = suggestionsOuter.find('.suggest-item.active');
+                        if (activeItem.length) {
+                            activeItem[0].scrollIntoView();
+                        }
+                    }
+                    return false;
+                case 13:
+                    if (activeItem.length) {
+                        activeItem.first().click();
+                    }
+                    return false;
+                default:
+                    if (!!term) {
+                        suggestionsOuter
+                            .html('<span class="d-block no-suggest-items">Searching...</span>')
+                            .removeClass('d-none');
+                        returnedFunction(elem);
+                    } else {
+                        suggestionsOuter.addClass('d-none');
+                    }
+                    break;
+            }
+        }
+
+        function handleKeypress(elem, e) {
+            var term = $.trim(elem.val());
+            if (!!term) {
+                suggestionsOuter
+                    .html('<span class="d-block no-suggest-items">Searching...</span>')
+                    .removeClass('d-none');
+                returnedFunction(elem);
+            } else {
+                suggestionsOuter.addClass('d-none');
+            }
+        }
+
+        $('[stag-suggest]:not([stag-suggest-initialized])').each(function () {
+            let elem = $(this);
+            elem.next('.stag-suggestions-container').remove();
+            $('<div class="stag-suggestions-container position-relative">' +
+                '<div class="suggestions-outer stag-suggestions position-absolute d-none"></div>' +
+                '</div>').insertAfter(elem);
+
+            elem
+                .off('keydown.stag-suggest')
+                .on('keydown.stag-suggest', function (e) {
+                    suggestionsOuter = $(this).next('.stag-suggestions-container').find('>.suggestions-outer');
+                    return handleKeydown($(this), e);
+                })
+                .off('keypress.stag-suggest')
+                .on('keypress.stag-suggest', function (e) {
+                    suggestionsOuter = $(this).next('.stag-suggestions-container').find('>.suggestions-outer');
+                    return handleKeypress($(this), e);
+                });
+
+            $(this).attr('stag-suggest-initialized', 1);
+        });
+
+        // on auto-suggest selection
+        $(document).off('click', '.suggest-item.stag-suggest');
+        $(document).on('click', '.suggest-item.stag-suggest', function () {
+
+            $('.suggestions-outer.stag-suggestions').addClass('d-none');
+
+            let data = $(this).data('suggest-data'),
+                label = $.trim($(this).text());
+
+            // set value
+            let input = $(this).closest('.position-relative').prev('[stag-suggest]');
+            input.val(label);
+            input.data('suggest-data', data);
+            for(let x in data) {
+                if(data.hasOwnProperty(x)) {
+                    input.attr('data-' + x, data[x]);
+                }
+            }
+            input.trigger('input');
+            input.trigger('change');
+
+            input.trigger('stag-suggest-selected', [input, data]);
+
+            return false;
+        });
+
+    }
+    addMCInitializer('stag-suggest', window.initStagSuggest);
+})();