如何在Ajax中使用实现自动完成插件? [英] How to use materialize autocomplete plugin with ajax?

查看:82
本文介绍了如何在Ajax中使用实现自动完成插件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 materializecss自动完成插件与我的ajax调用一起使用根据输入字段上的内容动态加载数据.

I am trying to make work together the materializecss autocomplete plugin with my ajax call in order to dynamically load data according to what is typed on the input field.

我的ajax请求在一个keydown事件中被调用.所有获取的数据都会自动推送到键/值对象数组中.

My ajax request is called inside a keydown event. All data fetched are automatically pushed into a key/value object array.

然后,我将自动完成功能放在ajax的成功函数中,并且键"data"的值是之前建立的对象数组.

Then, i put the autocomplete function in the ajax's success function and the value of the key "data" is the object array built right before.

看来我是个好方法,但是当我在浏览器中进行测试时,每次我键入内容时,建议下拉菜单都会按预期显示结果,但不是每次按键后都更新提示,而是另一个下拉列表与上一个等等...

It's seems i am on the good way but when i am testing in the browser, each time i type something, the suggestion dropdown shows up as expected with results, but rather than be renewed after each keydown, another dropdown list overlap the previous one and so one...

这就是我的问题:如何避免下拉建议列表重叠,而是在每次按下键时使它重新显示?

So this is my problem : How to do to avoid the dropdown suggestion list to overlap and rather make it renew each time i press a key ?

感谢您的帮助.

var dat = {};
	$('input').on('keydown',function(e){
		var d = {

         "query": {
                         "prefix": {
                            "body": e.target.value
                         }
                     }

        }; 
	
		 $.ajax({
        url:'https://xxxxxxxxxxxxxxx.eu-west-1.es.amazonaws.com/xxxxxxxxxxxxx',
        type:'POST',
        contentType : "application/json",
        crossDomain : true,
        data:JSON.stringify(d),
        dataType:'JSON',
        async:true,
        success: function(da){
			
			var c = da.hits.hits.length;
			for(var i = 0; i < c; i++){
				dat[da.hits.hits[i]._source.body] = null;
			}
			
		  $("input").autocomplete({
	 data : dat
	 
		
        },
        error: function(jqXHR, errorStatus, errorThrown){
          console.log(jqXHR);
          console.log(errorStatus);
          console.log(errorThrown);
        }

       }) 
		

推荐答案

以@ friek108的出色答案为基础,让我们添加以下功能.

Building on top of @friek108's excellent answer, let's add the following features.

  • 在其外部单击时关闭自动完成小部件.
  • 允许使用箭头键滚动结果并使用Enter键进行选择.
  • 仅在输入预定义的最小字符数之后,才进行AJAX调用.
  • 阻止某些键触发AJAX调用.

这采用了超时& @ friek108的答案中的ajax呼叫取消功能.您可能要先检查一下.

This adopts the timeout & ajax call cancelling features from @friek108's answer. You might want to check it first.

ajaxAutoComplete({inputId:'autocomplete-input',ajaxUrl:'/search/my-auto-complete-results'})

function ajaxAutoComplete(options)
{

    var defaults = {
        inputId:null,
        ajaxUrl:false,    
        data: {},
        minLength: 3
    };

    options = $.extend(defaults, options);
    var $input = $("#" + options.inputId);


    if (options.ajaxUrl){


        var $autocomplete = $('<ul id="ac" class="autocomplete-content dropdown-content"'
            + 'style="position:absolute"></ul>'),
        $inputDiv = $input.closest('.input-field'),
        request,
        runningRequest = false,
        timeout,
        liSelected;

        if ($inputDiv.length) {
            $inputDiv.append($autocomplete); // Set ul in body
        } else {
            $input.after($autocomplete);
        }

        var highlight = function (string, match) {
            var matchStart = string.toLowerCase().indexOf("" + match.toLowerCase() + ""),
            matchEnd = matchStart + match.length - 1,
            beforeMatch = string.slice(0, matchStart),
            matchText = string.slice(matchStart, matchEnd + 1),
            afterMatch = string.slice(matchEnd + 1);
            string = "<span>" + beforeMatch + "<span class='highlight'>" + 
            matchText + "</span>" + afterMatch + "</span>";
            return string;

        };

        $autocomplete.on('click', 'li', function () {
            $input.val($(this).text().trim());
            $autocomplete.empty();
        });

        $input.on('keyup', function (e) {

            if (timeout) { // comment to remove timeout
                clearTimeout(timeout);
            }

            if (runningRequest) {
                request.abort();
            }

            if (e.which === 13) { // select element with enter key
                liSelected[0].click();
                return;
            }

            // scroll ul with arrow keys
            if (e.which === 40) {   // down arrow
                if (liSelected) {
                    liSelected.removeClass('selected');
                    next = liSelected.next();
                    if (next.length > 0) {
                        liSelected = next.addClass('selected');
                    } else {
                        liSelected = $autocomplete.find('li').eq(0).addClass('selected');
                    }
                } else {
                    liSelected = $autocomplete.find('li').eq(0).addClass('selected');
                }
                return; // stop new AJAX call
            } else if (e.which === 38) { // up arrow
                if (liSelected) {
                    liSelected.removeClass('selected');
                    next = liSelected.prev();
                    if (next.length > 0) {
                        liSelected = next.addClass('selected');
                    } else {
                        liSelected = $autocomplete.find('li').last().addClass('selected');
                    }
                } else {
                    liSelected = $autocomplete.find('li').last().addClass('selected');
                }
                return;
            } 

            // escape these keys
            if (e.which === 9 ||        // tab
                e.which === 16 ||       // shift
                e.which === 17 ||       // ctrl
                e.which === 18 ||       // alt
                e.which === 20 ||       // caps lock
                e.which === 35 ||       // end
                e.which === 36 ||       // home
                e.which === 37 ||       // left arrow
                e.which === 39) {       // right arrow
                return;
            } else if (e.which === 27) { // Esc. Close ul
                $autocomplete.empty();
                return;
            }

            var val = $input.val().toLowerCase();
            $autocomplete.empty();

            if (val.length > options.minLength) {

                timeout = setTimeout(function () { // comment this line to remove timeout
                    runningRequest = true;

                    request = $.ajax({
                        type: 'GET',
                        url: options.ajaxUrl + val,
                        success: function (data) {
                            if (!$.isEmptyObject(data)) { // (or other) check for empty result
                                var appendList = '';
                                for (var key in data) {
                                    if (data.hasOwnProperty(key)) {
                                        var li = '';
                                        if (!!data[key]) { // if image exists as in official docs
                                            li += '<li><img src="' + data[key] + '" class="left">';
                                            li += "<span>" + highlight(key, val) + "</span></li>";
                                        } else {
                                            li += '<li><span>' + highlight(key, val) + '</span></li>';
                                        }
                                        appendList += li;
                                    }
                                }
                                $autocomplete.append(appendList);
                            }else{
                                $autocomplete.append($('<li>No matches</li>'));
                            }
                        },
                        complete: function () {
                            runningRequest = false;
                        }
                    });
                }, 250);        // comment this line to remove timeout
            }
        });

        $(document).click(function () { // close ul if clicked outside
            if (!$(event.target).closest($autocomplete).length) {
                $autocomplete.empty();
            }
        });
    }
}

我没有将结果一个接一个地附加到自动完成小部件中,而是将所有这些结果与一个长字符串附加在一起,以加快处理速度. (正确阅读jQuery .append()方法的精彩分析此处).

Instead of appending results to the autocomplete widget one by one, I've appended all of them together with one single, long string to make the process faster. (Read a wonderful analysis of jQuery .append() method here).

这篇关于如何在Ajax中使用实现自动完成插件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆