选择对话框(Dailog)是我们项目开发过程中最常的一种JS前端UI界面,比如选择文件、图片、人员组织树等等,为了达到最佳的效果和项目统一,我们都会精心设计各种通用对话框,下面就是我在考勤管理系统开发中使用的一种对话框。
人员、部门、职位选择对话框,先上效果图:
这是我在开发考勤系统时使用的选择对话框代码。
HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>天时考勤系统</title>
<meta name="description" content="天时考勤" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<link rel="shortcut icon" href="views/images/favicon.png" type="image/png" />
<link rel="stylesheet" href="//www.daytime.cc/.../styles/daytime-all-min.css?v=20200712" type="text/css" />
<base href="http://www.daytime.cc/" root="/" html5="false">
</head>
<body ng-app="app" id="win10" ng-controller="AppCtrl" ng-class="{'childwindow':ischildwindow == true, 'page-signin':$state.includes('auth')}"><div class="h-full w-full layui-row noselect layui-form dlg-pagination-box" lay-filter="dlgForm">
<div class="layui-col-xs12 h-full dailog-container">
<div class="dailog-layout w-full h-full">
<div class="dailog-layout-left h-full layui-inline">
<div class="layui-row" style="height:40px;line-height:35px;margin-top:2px;text-align:right;">
<div class="layui-col-xs12">选择范围:</div>
</div>
<div class="layui-dailog-data"><div class="layui-scroll-auto"><div class="scroll-item-list">
<div class="dailog-category-item" ng-repeat="cat in dlgSideCates">
<div class="item-icon"><i class="iconfont {{cat.iconfont}}"></i></div>
<div class="item-title">{{cat.name}}</div>
</div>
</div></div></div>
</div>
<div class="dailog-layout-right h-full layui-inline">
<div class="layui-dailog-head">
<div class="layui-row" style="height:40px;">
<div class="layui-col-search">
<input type="text" name="path" id="dailog_depttree" style="border-radius: 2px 0px 0px 2px;" ng-model="openinfo.path" autocomplete="off" class="layui-input">
</div>
<div class="layui-col-buttons">
<div class="layui-btn-group">
<button type="button" style="border-left-width: 0px;" class="layui-btn layui-btn-sm"><i class="iconfont icon-xiangzuo"></i></button>
<button type="button" class="layui-btn layui-btn-sm"><i class="iconfont icon-fanhui"></i></button>
<button type="button" class="layui-btn layui-btn-sm"><i class="iconfont icon-viewer-head"></i></button>
<button type="button" class="layui-btn layui-btn-sm"><i class="iconfont icon-viewer-grid"></i></button>
</div>
<div class="input-group" style="width:175px;float:right;">
<input type="text" name="keyword" ng-model="openinfo.keyword" autocomplete="off" class="layui-input">
<span class="layui-btn input-group-addon p-h-sm"><i class="iconfont icon-chaxun i-18"></i></span>
</div>
</div>
</div>
</div>
<div class="layui-dailog-body" id="dailog_selector-items">
<div class="list-container grid-list" ng-append="flexempty">
<!-- department/position/user list -->
<div ng-repeat="item in lists.list" ng-class="{'select':inArray($index,lists.select)}" class="list-item grid-item item-drag-select" title="{{item.cntitle}}">
<div class="item-icon">
<i ng-if="item.type=='dept'" class="iconfont icon-viewer-orgchart"></i>
<i ng-if="item.type=='posi'" class="iconfont icon-rencaifuwu"></i>
<div ng-if="item.type=='user'" class="thumb thumb-full"><img ng-src="{{item.photo}}"/></div>
</div>
<div class="title-type-name">
<span class="title">{{item.name}}</span>
</div>
</div>
</div>
</div>
<div class="layui-dailog-foot">
<div class="dailog-pagination pos-abt"></div>
<div class="layui-row" style="height:40px;">
<div class="layui-col-title">已选择:</div>
<div class="layui-col-input">
<input type="text" id="sellist" name="sellist" ng-model="openinfo.sellist" autocomplete="off" class="layui-input">
</div>
<div class="layui-col-button">
<button ng-click="dlgSave()" class="layx-button-item layui-btn layui-btn-primary" title="确定">确定</button>
</div>
</div>
<div class="layui-row" style="height:40px;">
<div class="layui-col-title">选择类型:</div>
<div class="layui-col-input selectUp">
<div ng-class="{'layui-col-xs12':openinfo.opentype!='user', 'layui-col-xs6 layui-col-xs60':openinfo.opentype=='user'||openinfo.opentype=='posi'}">
<select name="opentype" ng-change="selectOpenType()" ng-model="openinfo.opentype">
<option value="">全部类型</option>
<option value="dept">部门</option>
<option value="posi">职位</option>
<option value="user">人员</option>
</select>
</div>
<div class="layui-col-xs6" ng-show="openinfo.opentype=='user'||openinfo.opentype=='posi'" style="width:calc(50% - 5px);margin-left:10px;">
<select name="postseries" ng-model="openinfo.postseries">
<option value="">全部职系</option>
<option value="dept">领导层</option>
<optgroup label="技术类">
<option value="posi">技术层</option>
<option value="posi0">技工</option>
</optgroup>
<optgroup label="操作类">
<option value="posi2">机台工</option>
<option value="posi3">保全工</option>
</optgroup>
<option value="user">普通员工</option>
</select>
</div>
</div>
<div class="layui-col-button">
<button ng-click="dlgCancel()" class="layx-button-item layui-btn" title="取消">取消</button>
</div>
</div>
<div class="layui-row m-t-xs">
<div class="layui-col-xs2" style="margin-left:120px;">
<input type="checkbox" name="position[desktop]" lay-skin="primary" value="1" title="显示全部子部门">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
这是JS代码
(function ($) {
$.fn.extend({
"dailog":function (options, scope) {
// 目标样式, 这里是上面的className
var $that = $(this);
var win_h = 550,win_w = 830;
var $dailog = $('.dailog-btn-open', $that);
var $winscope;
// 定义控制器
app.controller(options.winid+'Ctrl', ['$scope', '$timeout', function($scope, $timeout) {
var deptlist;
$scope.openinfo = {
'opentype': 'dept'
};
$scope.lists = {
'list':[],
'select':[]
};
$scope.inArray = function(value, list){
if($.inArray(value, list) > -1){
return true;
}else{
return false;
}
}
$scope.dlgSideCates = [
{'name':'最近选择', 'id':'recent', 'iconfont':'icon-time'},
{'name':'最新入职', 'id':'join', 'iconfont':'icon-renyuantongxunlu'},
{'name':'本部门', 'id':'dept', 'iconfont':'icon-viewer-orgchart'},
{'name':'本公司', 'id':'company', 'iconfont':'icon-yuyan'},
//{'title':'集团', 'id':'group', 'iconfont':'icon-jigou'},
{'name':'部门负责人', 'id':'deptleader', 'iconfont':'icon-position'},
{'name':'分管领导', 'id':'bizleader', 'iconfont':'icon-wode'},
{'name':'公司领导', 'id':'coleader', 'iconfont':'icon-HRrenshirenshiguanli'},
{'name':'集团领导', 'id':'groupleader', 'iconfont':'icon-rencaifuwu'}
];
$scope.selectOpenType = function(){
if(!$scope.openinfo.opentype){
$scope.openinfo.opentype = 'dept';
$("select[name='opentype']").val('dept');
}
if($scope.openinfo.opentype!='user' && $scope.openinfo.opentype!='posi'){
$scope.openinfo.postseries = '';
$("select[name='postseries']").val('');
}
layui.use(['form'], function () {
var form = layui.form;
form.render(null, 'dlgForm');
});
};
var get_users = function(node){
if(typeof node === 'undefined'){
loadDepartment(function(deptlist){
$scope.lists.list = [];
for(var i=0; i<deptlist.length; i++){
if(!deptlist[i].pid){
var data = {'name': deptlist[i].name,'type':'dept'};
$scope.lists.list.push(data);
}
}
for(var i=0; i<20; i++){
var data = {'name': '职位'+i,'type':'posi'};
$scope.lists.list.push(data);
}
for(var i=0; i<100; i++){
var data = {'name': '员工'+i,'photo':'./medias/image/system/vatar_2.jpg','type':'user'};
$scope.lists.list.push(data);
}
});
}else{
$scope.lists.list = [];
if(typeof node.children !== 'undefined'){
$.each(node.children, function(k, v){
var data = {'name': v.name, 'type':'dept'};
$scope.lists.list.push(data);
});
}
for(var i=0; i<10; i++){
var data = {'name': '职位'+i,'type':'posi'};
$scope.lists.list.push(data);
}
for(var i=0; i<50; i++){
var data = {'name': '员工'+i,'photo':'./medias/image/system/vatar_2.jpg','type':'user'};
$scope.lists.list.push(data);
}
$scope.$apply();
}
}
var select_item = function(callback){
var $selector = $('#dailog_selector-items');
$selector.selectable({
//=================属性
//appendTo : "body", //指定选择过程中将辅助元素追加到何处。默认值 "body"
autoRefresh : true, //决定是否在每次选择动作时,都重新计算每个选择元素的坐标和大小。如果你有很多个选择项的话,建议设置成false并通过方法手动刷新。默认值 true
cancel : "textarea,button,select,option,.set-icon-size-slider,.layui-table-header,.slide-body,.list-type-header,.main-title,.column-drag,.tools", //防止在与选择器相匹配的元素上发生选择动作。默认值 "input,textarea,button,select,option"
delay : 100, //以毫秒为单位,设置延迟多久才激活选择动作。此参数可防止误点击。默认值 0
disabled : false, //如果选择true则该selectable实例将不能使用。默认值 false
distance : 10, //决定至少要在元素上面拖动多少像素后,才正式触发选择的动作。默认值 0
filter : ".item-drag-select", //设置哪些子元素才可以被选择。默认值 "*"
tolerance : "touch", //可选值:"touch", "fit",分别代表完全和部署覆盖元素即触发选择动作。默认值 "touch"
//=================事件
selected :function(e, ui) { //当选定某一个元素后触发此事件。
$(ui.selected).removeClass('ui-selectee');
$(ui.selected).removeClass('ui-selected');
},
selecting :function(e, ui) { //当选择某一个元素中时触发此事件。
$(ui.selecting).addClass('select');
},
unselected :function(event, ui) { //当取消选定某一个元素后触发此事件。
$(ui.selected).removeClass('ui-selectee');
$(ui.selected).removeClass('ui-selected');
},
unselecting :function(event, ui) { //当取消选定某一个元素中触发此事件。
$(ui.unselecting).removeClass('select');
}
});
$selector.on('click', '.item-drag-select', function(){
$('.item-drag-select.select', $selector).removeClass('select');
$(this).addClass('select');
return false;
}).on('dblclick', '.item-drag-select', function(){
//$('.item-drag-select.select', $selector).removeClass('select');
//$(this).addClass('select');
layx.destroy(options.winid);
return false;
}).on('click', function(){
$('.item-drag-select.select', $selector).removeClass('select');
});;
};
$scope.initWinDailog = function(){
var $dlg = $('#layx-'+options.winid);
$(".layui-scroll-auto").panel({iWheelStep:32});
layui.use(['form', 'treeSelect', 'laypage'], function () {
var form = layui.form;
var treeSelect= layui.treeSelect;
var pager = layui.laypage;
form.render(null, 'dlgForm');
loadDepartment(function(deptlist){
var depts = angular.copy(deptlist);
var cates = angular.copy($scope.dlgSideCates);
for(var i=0; i<cates.length; i++){
depts.push(cates[i]);
}
treeSelect.render({
elem: '#dailog_depttree',
data: depts,
click: function(d){
//console.log(d);
get_users(d.current);
},
success:function(e){
//console.log(e);
}
});
get_users();
});
var pageid = 'page_' + guid();
var timer;
$('.dailog-pagination', $dlg).attr('id', pageid).on('mouseenter', function(){
clearTimeout(timer);
$(this).fadeTo(300, 1, 'swing');
}).on('mouseleave', function(){
var $that = $(this);
timer = setTimeout(function(){
$that.fadeTo(1000, 0.3, 'swing');
},500);
});
// 检查最后删除的字符
$('#sellist').keydown(function(e){
// e.target.selectionStart === e.target.textLength 在开始位置
console.log(e.target.selectionStart, e.target.selectionEnd);
console.log(e.target.value[e.target.selectionStart - 1]);
});
var pageoption = {
elem: pageid,
count: 3000 //数据总数,从服务端得到
,limit: 50
,page: 1
,limits:[50,100,150,200,300,500,1000]
,layout: ['page', 'limit', 'count']
};
pager.render(pageoption);
});
select_item();
};
}]);
var create_dailog = function(){
var url = 'http://www.daytime.cc/.../views/dailog.html';
$.get(url, function(html){
var winoption = {
id:options.winid,
title:"选择",
width:win_w,
height:win_h,
minWidth:win_w,
minHeight:win_h,
shadable: true,
minMenu:false,
maxMenu:false,
position: 'center',
icon:'<i class="iconfont icon-dakaiwenjian"></i>',
content:'<div class="w-full h-full">'+html+'</div>'
};
var winform = layer.open(winoption);
});
};
}
});
})(jQuery);