【20】网站搭建:搜索提醒功能

一、前言   

  其实每一个input输入框都会自动保存用户的搜索记录,然后表现出来。而我的想法是可以在输入的同时自动查询数据库,然后将结果显示在页面中,所以明显查询数据库的搜索提醒对于用户来说要高效的多。将两者的效果对比一下:

二、开发步骤

1.关闭输入框的记录显示

  因为每一个input输入框都会默认将本地搜索记录进行展示,如果不将其关闭,将会影响数据库的查询输出。关闭记录显示也很简单,只需要将input框的autocomplete属性设置位off。

<input type="text" name="q" class="form-control" autocomplete="off" placeholder="搜点啥?" id="key">

2.返回Json格式的数据

  后面会使用Ajax请求该方法,将返回出去的Json数据,动态加载在输入框下面。

@csrf_exempt
def findWords(request):    
    """    
    查询数据库的文章标题    
    :param request:    
    :return:    
    """    
    key = request.POST.get('key', '')       
    list = Post.objects.filter(Q(display=0) | Q(display__isnull=True), title__icontains=key)[:5]    
    search_list = []    
    for post in list:    
        data = {    
            'id': post.id,    
            'title': post.title    
        }    
        search_list.append(data)    
    # 错误In order to allow non-dict objects to be serialized    
    return JsonResponse(search_list, safe=False)

  此处需要注意两点,第一点:需要给方法加上@csrf_exempt装饰器,用来关闭csrf的令牌功能,否则将可能出现CSRF token missing or incorrect的错误。第二点:返回的JsonResponse中,还需要令safe参数为False,否则也可能出现In order to allow non-dict objects to be serialized的错误。

3.编写Ajax代码

  构造好返回的Json数据后,接下来就是编写Ajax部分的代码,用来请求上面的方法。在这之前还需要定义一个div,用来存放加载的标签,如:

<div class="blog-search" style="display: none;" id="blog-search">    
    <ul id="titles">    
    </ul>    
</div>

  下面是Ajax代码,最关键的是用来了keyup事件,用来检测键盘是否有弹起的行为,也就是说一旦有键盘按下,就会执行下面的post请求,目标地址是上面的方法。

$(function(){    
       
    // 按键弹起,自动加载相关标题    
    $("#key").keyup(function(){    
        // 获取搜索关键词    
        var key = $("#key").val();    
        // alert(key);    
        if(key == ""){    
            $("#blog-search").hide();    
        }else{    
            //3. 请求数据。    
            $.post("{% url 'blog:findWords' %}",{key:key} ,function(data , status){    
                //alert(data);    
                $("#blog-search").show();    
                $("#titles").empty();    
                $(data).each(function(index , c) {    
                    if(c.title.length > 20){    
                        title = c.title.substring(0, 15);    
                        $("#titles").append("<li>" + title + "...</li>")    
                    }else{    
                        title = c.title    
                        $("#titles").append("<li>" + title + "</li>")    
                    }    
                });    
            }, "json");    
        }    
    });
});

4.动态设置存放数据的div宽度

// 使得输入框与提醒框宽度一致    
var inWidth = $("#key").outerWidth();    
$("#blog-search").outerWidth(inWidth);

5.点击标题自动提交数据

// 自动提交,查找    
// 动态绑定事件    
$("#titles").on("click","li", function(){    
    var word = $(this).text();    
    if(word.includes("...")){    
        word = word.substring(0, word.length -3);    
    }    
    $("#key").val(word);       
});

  原文出处:https://jzfblog.com/detail/140,文章的更新编辑以此链接为准。欢迎关注源站文章!

posted @ 2019-05-18 13:48  代码打碟手  阅读(270)  评论(0编辑  收藏  举报