單文本框可以下拉進行多選JS特效
因需求單個文本框可以選擇多個人,是以做了一個可以進行多選的效果,希望可以幫到有同需求的夥伴。
效果展示:
文本框可以進行多選,然後可以根據輸入關鍵詞進行搜尋
前端頁面引用和部分代碼
<link rel="stylesheet" type="text/css" href="css/tree.css" target="_blank" rel="external nofollow" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/comboTreePlugin.js"></script>
<script type="text/javascript" src="js/appraiser.js"></script>
// 評價人框
<td><div class='text-container align-right' style='width:90px;'>評價人 : </div></td>
<input type='text' id='apprcount' class='apprcount' style=' border:none;width:65px;background-color:transparent;color:#666' readonly></td>");
// 評價人用來存值的隐藏域
<td><input type='text' style='display: none;' id='appraiser' value='{data["ddesc"]}' class='appraiser' name='fdata__appraiser'></td>"
tree.css
.wrapper {
width: 1024px;
margin: 50px auto 0 auto;
}
.wrapper > div {
overflow visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.select-tree-wrap {
min-height: 24px;
border: 1px solid #e4e4ea;
background-color: white;
}
.input-keyword-wrap {
min-height: 24px;
position: relative;
}
.input-keyword-wrap .handle-arrow {
position: absolute;
right: 10px;
top: 10px;
}
.input-keyword-wrap .select-menu-input {
font-size: 12px;
height: 100%;
overflow: hidden;
min-height: 24px;
cursor: pointer;
background-color: white;
}
.input-keyword-wrap .input-tips {
font-size: 14px;
line-height: 24px;
padding-left: 10px;
color: #d6d6d6;
}
.input-keyword-wrap .single-keyword {
border: 0px !important;
}
.input-keyword-wrap .input-keyword-item {
width: auto;
margin: 2px 8px 2px 5px;
border: 1px solid #e4e4ea;
color: #666;
border-radius: 3px;
display: block;
float: left;
}
.input-keyword-wrap .input-keyword-item span:nth-child(1) {
line-height: 22px;
display: block;
float: left;
width: auto;
height: 24px;
float: left;
margin-left: 2px;
margin-right: 0px;
border: 0 none;
padding-right: 5px;
color: #666;
}
.input-keyword-wrap .input-keyword-item i {
width: 20px;
height: 20px;
display: block;
padding: 0;
margin: 1px 0px 1px 0px;
float: left;
text-align: center;
font-style: normal;
text-indent: 0px;
cursor: pointer;
}
.drop-down-wrap {
display: none;
position: absolute;
background-color: white;
}
.drop-down-wrap .noresults {
display: none;
padding: 10px 0;
font-size: 12px;
color: #ccc;
text-align: center;
}
/* .drop-down-wrap .handle-left-icons {
text-align: center;
display: inline-block;
width: 20px;
}*/
.drop-down-wrap .title-group-name {
display: inline-block;
}
.drop-down-wrap .handle-checkbox {
text-align: center;
width: 30px;
display: inline-block;
}
.drop-down-wrap .keyword-search {
padding: 6px 10px 6px 10px;
width: 100%;
border-top: 1px solid #ccc;
box-sizing: border-box;
position: relative;
}
.drop-down-wrap .keyword-search input {
width: 150px;
outline: 0;
padding: 0 30px 0 10px;
height: 20px;
border: 1px solid #ccc;
box-sizing: border-box;
border-radius: 5px;
}
.drop-down-wrap .keyword-search .search-icons {
width: 20px;
height: 20px;
display: inline-block;
position: absolute;
right: 15px;
top: 16px;
color: #ccc;
}
.drop-down-wrap .select-tree-list {
padding: 0;
margin: 0;
max-height: 400px;
height: 170px;
overflow-x: hidden; // 橫向滾動條隐藏
/*overflow-x: scroll; // 橫向滾動條顯示*/
}
.drop-down-wrap .select-tree-list li {
list-style-type: none;
cursor: pointer;
}
.drop-down-wrap .title-container {
line-height: 24px;
padding: 0 20px
}
.drop-down-wrap .title-container:hover {
background: #f2f2f2;
color: #0079fe;
}
.drop-down-wrap .select-tree-list li .tree-sub-body ul {
padding: 0;
}
.drop-down-wrap .select-tree-list li .tree-sub-body ul li {
line-height: 0px;
}
.drop-down-wrap .select-tree-list li .tree-sub-body ul li .title-container {
padding-left: 0px
}
.drop-down-wrap .select-tree-list li .tree-sub-body ul li .tree-sub-body ul li .title-container {
padding-left: 0px;
}
.actived_li {
color: #666;
}
comboTreePlugin.js
(function ($, window, document, undefined) {
let comboTreePlugin = 'comboTree',
//定義一個存儲資料的數組,用于下面重複選擇判斷,删除标簽,
defaults = {
source: [],
isMultiple: false,
cascadeSelect: false,
selected: [],
selectedlength: 3
},
tempstructerarray = [];
let ComboTree = function (element, options) {
this.options = $.extend({}, defaults, options);
this.element = element;
this.ulcontainer = null;
this.oliIdArray = [];
this.copysource = [];
this.roleSelect = null;
this.copydom = null;
this.comboxinput = null;
this.comboxinputcontainer = null;
this.comboxulcontainer = null;
this.selectul = null;
this.myplaceholder = null;
this.noresults = null;
this.init();
};
ComboTree.prototype.init = function () {
$.extend(true, this.copysource, this.options.source);
this.initstruct();
this.initdom();
this.ulcontainer = $(this.element).find('div[_id=comboxulcontainer]');
this.comboxinput = $(this.element).find('input[_id=comboxinput]');
this.roleSelect = $(this.element).find('div[_id=role_select]');
this.comboxinputcontainer = $(this.element).find('div[_id=comboxinputcontainer]');
this.comboxulcontainer = $(this.element).find('div[_id=comboxulcontainer]')
this.copydom = this.selectul.clone();
this.myplaceholder = $(this.element).find('span[_id=myplaceholder]');
this.noresults = $(this.element).find('.noresults');
this.initevent();
for (var i = 0; i < this.options.selected.length; i++) {
console.log(this.options.selected[i]);
$("[data-id='" + this.options.selected[i] + "']").trigger("click");
}
};
ComboTree.prototype.initstruct = function () {
for (let i = 0; i < this.copysource.length; i++) {
this.copysource[i]['class'] = 'first'
}
};
ComboTree.prototype.initevent = function () {
let _this = this;
//點選輸入框時候
$(this.element).on('click', function (event) {
event = event || window.event;
let closet = $(event.target).closest('.input-keyword-wrap'),icon = null;
if (($(event.target).hasClass('imitationSelect') || $(event.target).hasClass('fa')) && closet.length > 0) {
$(_this.element).find('.drop-down-wrap').toggle();
if (!icon) {
icon = $(_this.element).find('.input-keyword-wrap>i');
}
if (icon.hasClass("fa-caret-down")) {
icon.removeClass("fa-caret-down").addClass("fa-caret-up"); //點選input選擇适合,小圖示動态切換
} else {
icon.removeClass("fa-caret-up").addClass("fa-caret-down"); //點選input選擇适合,小圖示動态切換
}
}
let target = $(event.target).hasClass('title-container') ? $(event.target) : $(event.target)
.parent().hasClass('title-container') ? $(event.target).parent() : null;
if (target) {
// 如果已選擇的大于設定的數目,并且目前是選擇動作 則不執行
if ((_this.oliIdArray.length >= _this.options.selectedlength) && !target.hasClass('actived_li') && _this.options.isMultiple) {
console.log('最大可選條目已設定');
return false;
}
if (target.attr('role') !== 'parent') {
event.target = target;
let oliId = target.attr("data-id");
if (target.hasClass('actived_li')) {
_this.uncheckrow(oliId);
} else {
if (!_this.options.isMultiple) { //如果是單選,則已選條目大于零,并且所點選的不是 激活狀态的,不執行
if (_this.oliIdArray.length > 0) {
for (let j = 0; j < _this.oliIdArray.length; j++) {
_this.uncheckrow(_this.oliIdArray[j]);
}
}
}
_this.checkrow(target, oliId, false); //第三個參數表示點選的是否是checkbox
}
if (!_this.options.isMultiple) {
_this.hideul();
}
}
}
if ($(event.target).attr('type') === 'checkbox') {
if ((_this.oliIdArray.length >= _this.options.selectedlength) && $(event.target).prop(
'checked')) {
console.log('超出最大條目');
return false;
}
let _target = $(event.target).closest('.title-container');
if (_target.hasClass('actived_li')) {
_this.uncheckrow($(event.target).attr('data-id'));
} else {
_this.checkrow(_target, $(event.target).attr('data-id'), true);
}
}
//點選x關閉事件處理
if ($(event.target).attr('class') === 'close') {
_this.uncheckrow($(event.target).attr('data-id'));
}
let containerparent = $(event.target).attr('role') === 'parent' ? $(event.target) : $(event
.target).parent().attr('role') === 'parent' ? $(event.target).parent() : null;
if (!containerparent) {
target = $(event.target).attr('tag') === 'closeitem' ?
$(event.target) : $(event.target).parent().attr('tag') === 'closeitem' ?
$(event.target).parent() : null;
}
if( $(event.target).attr('tag') === 'search' || $(event.target).parent().attr('tag') === 'search' ){
_this.comboxinput.val('');
_this.comboxinput.trigger('keyup');
}
if (target || containerparent) {
let _parent = null;
if (containerparent) {
_parent = containerparent
} else {
_parent = target.closest('.title-container');
}
_parent.next().toggle();
target = target.find('i');
if (target.hasClass('fa-caret-down')) {
target.removeClass('fa-caret-down').addClass('fa-caret-right');
} else {
target.removeClass('fa-caret-right').addClass('fa-caret-down');
}
}
if (event.stopPropagation) {
event.stopPropagation(); // 針對 Mozilla 和 Opera
} else if (window.event) {
window.event.cancelBubble = true; // 針對 IE
}
});
this.comboxinput.on('keyup', function (event) {
event = event || window.event;
_this.selectul.find('.hide').removeClass('hide');
// 判斷搜尋框裡是否有内容,如果有則添加删除按鈕
if (event.currentTarget.value != "") {
$(this).siblings('span').find('i').removeClass('fa-search').addClass('fa-close');
} else {
$(this).siblings('span').find('i').removeClass('fa-close').addClass('fa-search');
}
let lis = _this.selectul.find('li'),
targetli = null,
_tempattr = null;
lis.each(function (index, item) {
$(item).attr('matched', '');
});
let val = $(event.target).val();
function getChildren(parent) {
let lichild = parent.children('li');
if (lichild.length) {
for (let i = 0, _p = lichild, len = _p.length; i < len; i++) {
targetli = _p.eq(i), _tempattr = targetli.attr('data-name');
if (_tempattr.indexOf(val) >= 0 && _tempattr !== ' ' && _tempattr !== '') {
targetli.attr('matched', 'matched');
}
let subulcontainer = targetli.find('>.tree-sub-body');
if (subulcontainer.length > 0) {
let _tempul = subulcontainer.find('>ul');
getChildren(_tempul);
}
}
}
}
getChildren(_this.selectul);
if (val.trim() !== '') {
let lis1 = _this.selectul.find('li');
lis1.each(function (index, item) {
let _item = $(item);
let matched = _item.find('li[matched="matched"]');
if (_item.length === 0) {
return true; //相當于continue
}
if (matched.length === 0) {
if (_item.attr('matched') === 'matched') { //如果目前元素比對,則保留目前的删除它後面的所有元素
let _matcheditem = _item.find('>div.tree-sub-body');
_matcheditem.each(function (index, item) {
$(item).addClass('hide');
});
} else {
_item.addClass('hide');
}
}
});
let children = _this.comboxulcontainer.find('li[matched=matched]');
if (children.length === 0) {
_this.selectul.hide();
_this.noresults.show();
} else {
_this.noresults.hide();
_this.selectul.show();
}
} else {
_this.selectul.show();
_this.selectul.find('.hide').removeClass('hide');
_this.noresults.hide();
}
});
//點選任意地方隐藏下拉
$(document).click(function (event) {
_this.hideul();
});
// 點選請選擇人員隐藏下拉下拉
$(this.element).find('span[_id=myplaceholder]').on('click', function (event) {
_this.toggleul();
});
};
ComboTree.prototype.initdom = function () {
$(this.element).append(
'<div class="input-keyword-wrap">' +
'<div _id="role_select" class="select-menu-input imitationSelect role_select">'+
'<span _id="myplaceholder" class="input-tips">請選擇人員</span>'+
'</div>' +
'<i class="fa fa-caret-down handle-arrow"></i>' +
'</div>' +
'<div class="drop-down-wrap">' +
'<div _id="comboxinputcontainer" class="comboxinputcontainer keyword-search">' +
'<input _id="comboxinput" placeholder="輸入關鍵詞搜尋" type="text">' +
'<span tag="search" class="search-icons"><i class="fa fa-search"></i></span>' +
'</div>' +
'<div _id="comboxulcontainer">' +
'<div _id="noresault" class="noresults">無搜尋結果</div>'+
'<ul class="select-tree-list" _id="selectUl"></ul>' +
'</div>' +
'</div>');
this.selectul = $(this.element).find('ul[_id=selectUl]');
this.createitem(this.copysource, this.selectul);
};
ComboTree.prototype.createitem = function (SampleJSONData, container) {
for (let j = 0; j < SampleJSONData.length; j++) {
var oliName = SampleJSONData[j].title;
var oliId = SampleJSONData[j].id;
// li容器
let item = $('<li data-name="' + oliName + '" data-id="' + oliId + '"></li>'),
divitem = $('<div data-name="' + oliName + '" data-id="' + oliId +'" class="title-container"></div>');
spanitem = $('<span tag="closeitem" class="handle-left-icons"></span>');
divitem.append(spanitem);
//如果是第一層,給他設定一個屬性叫firstclass
if (SampleJSONData[j]['class'] === 'first') {
divitem.attr('role', 'parent');
}
if (SampleJSONData[j]['subs']) {
spanitem.append('<i class="fa fa-caret-down"></i>');
divitem.append(spanitem);
divitem.attr('role', 'parent');
}
//放入checkbox ,這段業務表示如果是第一層,并且在配置中寫了,第一層允許選擇才加入checkbox
if (this.options.isMultiple) {
if (SampleJSONData[j]['class'] === 'first') {
if (this.options.isFirstClassSelectable) {
appendcheckbox(divitem, oliId);
}
} else {
if (!SampleJSONData[j]['subs']) {
appendcheckbox(divitem, oliId);
}
}
}
// 放入名稱
divitem.append('<span class="title-group-name">' + oliName + '</span>');
item.append(divitem);
container.append(item);
if (SampleJSONData[j]['subs']) {
let titlediv = $('<div class="tree-sub-body"></div>');
item.append(titlediv);
let subul = $('<ul></ul>');
titlediv.append(subul);
this.createitem(SampleJSONData[j]['subs'], subul);
}
}
};
ComboTree.prototype.checkrow = function (target, oliId, ischeckbox) {
let _this = this;
target.addClass("actived_li"); //點選目前的添加 actived_li這個類;
// 判斷目前元素前面是否有checkbox,如果有就選中
let inputcheckbox = target.find('input');
if (inputcheckbox.length > 0 && !ischeckbox) {
inputcheckbox.prop('checked', !inputcheckbox.prop('checked'));
}
_this.oliIdArray.push(oliId);
_this.roleSelect.attr("data-id", _this.oliIdArray); //把目前點選的oliId指派到顯示的input的oliId裡面
if (_this.oliIdArray.length > 0) {
_this.myplaceholder.hide();
}
// 新增人員後将評價人id更新頁面的評價人隐藏域
$("#appraiser").val(_this.oliIdArray);
var jslength = 0;
for (var appr in _this.oliIdArray) {
jslength++;
}
// 更新選擇人員數量
$("#apprcount").val('已選' + jslength + '人');
//向input裡面存放的内容,是一個span
let item = $("<span data-id='" + oliId + "' class='input-keyword-item'></span>"),
namespan = $("<span>" + target.attr('data-name') + "</span>"),
checkicon = $("<i class='close' data-id='" + oliId + "' >x</i>");
item.append(namespan);
if (this.options.isMultiple) {
item.append(checkicon);
} else {
item.addClass('single-keyword')
}
_this.roleSelect.append(item);
};
ComboTree.prototype.uncheckrow = function (oliId) {
let _this = this, icon = null;
let id = null;
for (let i = 0; i < _this.oliIdArray.length; i++) {
if (_this.oliIdArray[i] === oliId) { //表示數組裡面有這個元素
id = i; //元素位置
_this.oliIdArray.splice(i, 1);
//把目前點選的oliId指派到顯示的input的oliId裡面
_this.roleSelect.attr("data-id", _this.oliIdArray);
// console.log('删除目前的序号' + oliId + ';' + '剩下數組' + _this.oliIdArray)
}
}
$(_this.element).find('.title-container').each(function (index, item) {
if ($(item).attr('data-id') === oliId) {
$(item).removeClass('actived_li');
let $checkbox = $(item).find('input');
$checkbox.prop('checked', false);
}
});
if (!icon) {
icon = $(_this.element).find('.input-keyword-wrap>i');
icon.removeClass("fa-caret-up").addClass("fa-caret-down"); //點選input選擇适合,小圖示動态切換
}
_this.roleSelect.find('>span').each(function (index, item) {
if ($(item).attr('data-id') === oliId) {
item.remove();
// 删除人員後将評價人id更新頁面的評價人隐藏域
$("#appraiser").val(_this.oliIdArray);
var jslength = 0;
for (var appr in _this.oliIdArray) {
jslength++;
}
// 更新選擇人員數量
if (jslength != 0) {
$("#apprcount").val('已選' + jslength + '人');
}
else {
$("#apprcount").val('');
}
}
});
if (_this.oliIdArray.length === 0) {
_this.myplaceholder.show();
}
};
ComboTree.prototype.hideul = function () {
// event=event||window.event;
$(this.element).find('.input-keyword-wrap .fa').removeClass("fa-caret-up").addClass("fa-caret-down"); //當點隐藏ul彈窗時候,把小圖示恢複原狀
$(this.element).find('.drop-down-wrap').hide(); //當點選空白處,隐藏ul彈窗
};
ComboTree.prototype.toggleul = function () {
// event=event||window.event;
$(this.element).find('.input-keyword-wrap .fa').toggleClass("fa-caret-up").toggleClass("fa-caret-down");
$(this.element).find('.drop-down-wrap').toggle();
};
/**
* 清空搜尋輸入框裡面的内容
*/
ComboTree.prototype.clearSearchValue = function() {
};
ComboTree.prototype.datas = function () {
let arr = [];
$(this.element).find('.input-keyword-item').each(function (index, item) {
arr.push({
id:$(item).attr('data-id'),
val:$(item).find('span').html()
});
});
return arr;
};
function appendcheckbox(divitem, oliId) {
let $checkboxspan = $('<span class="handle-checkbox"></span>'),
$checkbox = $('<input data-id="' + oliId + '" type="checkbox">');
$checkboxspan.append($checkbox);
divitem.append($checkboxspan);
}
$.fn[comboTreePlugin] = function (options) {
var ctArr = [];
this.each(function () {
if (!$.data(this, 'plugin_' + comboTreePlugin)) {
$.data(this, 'plugin_' + comboTreePlugin, new ComboTree(this, options));
ctArr.push($(this).data()['plugin_' + comboTreePlugin]);
}
});
if (this.length === 1)
return ctArr[0];
else
return ctArr;
};
})(jQuery, window, document);
appraiser.js
$(function () {
var SampleJSONData = [];
for (var i in datacustom) {
SampleJSONData.push({
id: datacustom[i].id,
title: datacustom[i].title,
subs :[]
});
}
let bbb = $('#justAnInputBox').comboTree({
source: SampleJSONData,
isMultiple: true,
isFirstClassSelectable: true, //第一級是否可選
cascadeSelect: true,
selected: ($("#appraiser").val() || '').split(','),
selectedlength: 100 //最多可選
});
console.log($("#appraiser").val());
// bbb.datas(); //擷取資料
});