版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41355260/article/details/82663136
需求分析:
1、功能独立,即一个页面可以有多个功能相同的输入框
2、功能需求多样,存在最大数目、数据形式的区别
3、完成输入后,与后台的数据交互问题(传id)
4、点击删除键或者删除按钮都能移除目标
思路:
1.页面结构:在一个div中,包含已经选择的元素、input输入框、hidden-info(后台用,隐藏)、select下拉框(隐藏/显示,JS控制)四部分。页面中至多有一个select下拉框。
<div class="ui-autocomplete">
<div class="autocomplete-box">
<input type="text" class="autocomplete autocomplete-by-name mul-autocomplete" data-num="4" />
<input class="hidden-info hide hidden" type="text" value="" />
</div>
</div>
2.input获得焦点,值有变化,未超过最大数量,且始终保证值不为空时,请求数据源 。
3.选中后,检查选中的值是否在已经选过的列表中(ids为所有tags组成的数组,使用ids.indexOf(hiddenID)==-1判断),若在,给出提示;否则,变成非字符串的dom节点,填充在div中,确切的说,是插入在input输入框的前面($(新节点).innerBefore(目标节点)),隐藏select下拉框。切记,永远读取页面已有的内容,而不是临时添加新内容。
扫描二维码关注公众号,回复:
4095933 查看本文章
JavaScript代码:
//添加onpropertychange事件是为了兼容ie
//做事件代理,使得动态添加的dom节点也能实现绑定的功能
//autocomplete-by-name 只显示名称
//mul-autocomplete 可填写多个元素
$(".autocomplete").on('input onpropertychange', function () {
var $this = $(this),
val = $this.val();
//去掉页面其他的下拉选项框
if ($('.select-box').length > 0) {
$('.select-box').remove();
}
//输入不为空且少于允许的输入数目
if (val.length > 0 && maxnum($this, $this.data('num'))) {
$.ajax({
url: "/tool/getpy/",
type: 'get',
datatype: 'json',
data: {
py: $this.val()
},
success: function (data) {
//添加下拉框节点
$this.parent().append('<ul class="select-box u-menu u-menu-max"></ul>');
//调整下拉框样式
$('.select-box').css('width', $this.closest('.ui-autocomplete').width())
var $selectBox = $this.siblings('.select-box');
//每一次input变化下拉框都会初始化(清空)
$selectBox.html('');
//遍历所有下拉框选项
$.map(data, function (item) {
var $this = $(this);
if ($this.length > 0) {
$selectBox.show();
//判断autocomplete的类型
if ($('.autocomplete').hasClass('autocomplete-by-name')) {
$selectBox.append(('<li class="ui-menu-item" id=' + item.unid + '>' + item.name + '</li>'));
} else {
$selectBox.append(('<li class="ui-menu-item" id=' + item.unid + '>' + item.name + '(' + item.sex + '/' + item.dw + ')' + '</li>'));
}
}
});;
}
});
}
}).on('keydown', function (e) {//键盘控制
if (e.keyCode == 8 && $(this).val().length == 0) {
//移除目标,方法一:删除键
var ids = [];
$(this).prev().remove();
$(this).closest('.ui-autocomplete').find('.autocomplete-tags').each(function () {
var $this = $(this),
hiddenID = $this.attr('id');
ids.push(hiddenID);
console.log(ids);
});
// console.log(ids);
$(this).closest('.ui-autocomplete').find('.hidden-info').val(ids);
}
});
//移除目标,方法二:点击'x'
$('.autocomplete-box').on('click', '.remove', function () {
var $this = $(this),
ids = [];
$this.parent().siblings('.autocomplete-tags').each(function () {
var $this = $(this),
hiddenID = $this.attr('id');
ids.push(hiddenID);
//console.log(ids);
});
$this.closest('.ui-autocomplete').find('.hidden-info').val(ids);
$this.parent().remove();
});
//当下拉框选项被选中
$('body').on('click', '.select-box .ui-menu-item', function () {
var $this = $(this),
$selectBox = $('.select-box'),
$autoInput = $this.parent().siblings('.autocomplete'),
current = $this.text(),
hiddenID = $this.attr('id'),
ids = [];
//input清空
$autoInput.val('');
$this.closest('.ui-autocomplete').find('.autocomplete-tags').each(function () {
var $this = $(this),
current = $this.text(),
hiddenID = $this.attr('id');
ids.push(hiddenID);
});
//根据hiddenID判断是否已经被添加过,若有,提示已选择,否则再将选择的数据变成label元素添加到div中
if (ids.indexOf(hiddenID) == -1) {
$('<label class="autocomplete-tags" id="' + hiddenID + '">' + current + '<a class="remove">x</a></label>').insertBefore($autoInput);
ids.push(hiddenID);
$this.closest('.ui-autocomplete').find('.hidden-info').val(ids);
} else {
alert(current+'已在列表中!');
}
$selectBox.hide();
return false;
});
//控制选项数目
function maxnum(ele, num) {
var ids = ele.closest('.ui-autocomplete').find('.autocomplete-tags');
if (num && ids.length >= num) {//设置了最大数量限制且超过
alert('最多选择' + num + '个选项');
$('.autocomplete').val('');
return false;
} else {
return true;
}
}
注意:
1、移除元素放在与该元素有关操作的最后一步操作
2、insertBefore()