最近作了一個項目,其中須要從大量數據中篩選出須要的相應數據,由於數據量龐大,且變化,所以不能一次性渲染至前端頁面,因此只能經過輸入關鍵字,後臺獲取關鍵字搜索匹配返回數據給前端的方法,而後在網上大量尋找,始終找不到能完美融合項目的插件,因而萌發了本身寫一個的想法,晚輩學疏才淺,望指教!javascript
下面開始進入正題css
前端部分html
本想本身設計樣式,但審美受限,感受與總體項目風格不符,因而直接採用layui模塊的樣式前端
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <link rel="stylesheet" href={% static 'layui-v2.4.3/layui/css/layui.css' %}> <style> .select_a { color: #009688; padding: 2px; margin: 2px; border: #009688 1px dashed; } </style> <body> {% csrf_token %} <div class=" layui-col-md4"> <label class="layui-form-label">單選搜索</label> <div class="layui-input-block" name="single_select"> <div class="layui-form-select" style="width: 200px"> <div class="layui-select-title"> <input type="text" class="layui-input" placeholder="請輸入單位名稱" name="select_input" autocomplete="off" id=""> <i class="layui-edge"></i> </div> <dl name="select_show" class="layui-anim layui-anim-upbit"> <dd lay-value="" class="layui-select-tips" style="text-align: center"> <i class="layui-icon layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i> </dd> </dl> </div> </div> </div> <div class=" layui-col-md4"> <label class="layui-form-label">多選搜索</label> <div class="layui-input-block" name="multiple_select"> <div class="layui-form-select"> <div class="layui-select-title"> <div style="display: inline-block;position: absolute;left:4px;height: 38px;line-height: 38px"> </div> <input type="text" class="layui-input" placeholder="請輸入單位名稱" name="select_input" autocomplete="off" id=""> <i class="layui-edge"></i> </div> <dl name="select_show" class="layui-anim layui-anim-upbit"> <dd lay-value="" class="layui-select-tips" style="text-align: center"> <i class="layui-icon layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i> </dd> </dl> </div> </div> </div> </body> <script type="text/javascript" src={% static 'jquery-3.3.1.min.js' %}></script> <script type="text/javascript" src={% static 'layui-v2.4.3/layui/layui.js' %}></script> <script> layui.use(['layer', 'element', 'form'], function () { var element = layui.element; var layer = layui.layer; var form = layui.form; //select自適應 function select_adaption(select_input) { var div_width = select_input.prev().outerWidth(true) select_input.css('padding-left', (parseInt(div_width) + 6) + 'px') select_input.val('') } //select模糊搜索 function vagueselect(obj, type) { var select_input = obj.find('[name="select_input"]') var select_show = obj.find('[name="select_show"]') function getdataList() { var parms = new Object(); parms["keyword"] = select_input.val(); parms["csrfmiddlewaretoken"] = $("[name = 'csrfmiddlewaretoken']").val() $.ajax({ cache: true, type: "POST", url: '/test/', data: parms, async: false, success: function (data) { var json = $.parseJSON(data); var html if (type == 'multiple') { select_input.prev().children().each(function () { for (var i = 0; i < json.data_list.length; i++) { if (json.data_list[i].ID == $(this).attr('belong_id')) { //刪除已選選項 json.data_list.splice(i, 1) } } }) } if (json.data_list.length > 0) { //將得到的數據填充到下拉的數據框裏 select_show.children().first().hide().nextAll().remove() for (var i = 0; i < json.data_list.length; i++) { html = '<dd lay-value="' + json.data_list[i].ID + '" class="">' + json.data_list[i].Name + '</dd>'; select_show.append(html) } } else { if (parms["keyword"].length > 0) { //若是爲搜索到匹配項顯示 select_show.children().first().hide().nextAll().remove() html = '<dd lay-value="無" class="layui-select-tips">無該匹配項</dd>'; select_show.append(html) } else { //若是未輸入關鍵字復原樣式 select_show.children().first().show().nextAll().remove() } } }, error: function (request) { layer.msg("Connection error", {icon: 2}); } }); } //輸入框聚焦事件 select_input.focus(function () { obj.find('.layui-form-select').addClass('layui-form-selected') getdataList() }) //輸入框失去焦點事件 select_input.blur(function () { var input_dom = this $(document).on('click', function (event) { var dom = select_show[0] if (event.target !== input_dom && event.target !== dom) { obj.find('.layui-form-select').removeClass('layui-form-selected') } }) }) //當案件鬆開時 select_input.keyup(function () { getdataList() }) if (type == 'single') { obj.delegate('dd', 'click', function () { if ($(this).index() > 0) { $(this).siblings().removeClass('layui-this') $(this).addClass('layui-this') select_input.val($(this).text()) select_input.attr('id', $(this).attr('lay-value')) obj.find('.layui-form-select').removeClass('layui-form-selected') } }); } else if (type == 'multiple') { //爲選擇項綁定點擊事件 obj.delegate('dd', 'click', function () { if ($(this).index() > 0 && $(this).text() !== '無該匹配項') { $(this).siblings().removeClass('layui-this') $(this).addClass('layui-this') var temp = '<a class="select_a" belong_id="' + $(this).attr('lay-value') + '" ><i class="layui-icon" style="cursor: pointer;" name="select_del">ဆ</i>' + $(this).text() + '</a>' console.log(temp) select_input.prev().append(temp) console.log(select_input.prev()) select_adaption(select_input) obj.find('.layui-form-select').removeClass('layui-form-selected') obj.parent().parent().next().find('input').attr('disabled', false) obj.parent().parent().next().find('select').attr('disabled', false) form.render() } }); } } //刪除選項統一接口 $('body').delegate('[name="select_del"]', 'click', function () { var select_input = $(this).parent().parent().next() if ($(this).parent().siblings().length == 0) { $(this).parents(':eq(5)').nextAll().find('input').attr('disabled', true) $(this).parents(':eq(6)').next().find('input').attr('disabled', true) $(this).parents(':eq(6)').next().find('select').attr('disabled', true) form.render() } $(this).parent().remove() select_adaption(select_input) }); vagueselect($('[name="single_select"]'), 'single') vagueselect($('[name="multiple_select"]'), 'multiple') }); </script> </html>
後臺部分使用python編寫(django)java
def test(request): data_list = [] return_dict = {'code': 0, 'data_list': data_list} res_dict = request.POST.dict() keyword = res_dict['keyword'] if keyword: company_obj = models.S_Company.objects.all().filter(C_Astatus=2).exclude( C_Status__in=[-1, 0]).filter( Q(C_Name__icontains=keyword) | Q(C_SName__icontains=keyword) ).values('C_ID', 'C_Name').order_by("C_Name") for index, company in enumerate(company_obj): data_list.append({}) data_list[index]['ID'] = company['C_ID'] data_list[index]['Name'] = company['C_Name'] return_dict['data_list'] = data_list return HttpResponse(json.dumps(return_dict))
效果以下:python
單選jquery
多選ajax
注:如需引用,請注意HTML格式!!! django