最近做了一個項目,其中需要從大量數據中篩選出需要的相應數據,因為數據量龐大,且變化,因此不能一次性渲染至前端頁面,所以只能通過輸入關鍵字,后台獲取關鍵字搜索匹配返回數據給前端的方法,然后在網上大量尋找,始終找不到能完美融合項目的插件,於是萌發了自己寫一個的想法,晚輩學疏才淺,望指教!
下面開始進入正題
前端部分
本想自己設計樣式,但審美受限,感覺與整體項目風格不符,於是直接采用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)
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))
效果如下:
單選



多選


注:如需引用,請注意HTML格式!!!
