全选反选穿梭框

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.css" rel="stylesheet">
    <style type="text/css">
    .transferBox {
        height: 100%;
        border: 1px solid #beb8b8;
        border-radius: 6px;
    }

    .shuttleBtn {
        height: 100%;
    }

    .transferBtn .btn {
        display: block;
    }

    .transferBtn .btn:first-child {
        margin-bottom: 20px;
    }

    .transferBtn .btnList {
        position: absolute;
        width: 80%;
        top: 50%;
        margin-top: -40px;
    }

    .transferBox .search {
        width: 100%;
    }

    .transferBtn .btn-default {
        background: #ccc;
        cursor: no-drop;
    }
    </style>
</head>

<body>
    <div id="transferContainer" class="row" style="height: 700px;width: 950px;"></div>
   
    
</body>

</html>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap-table/1.12.1/locale/bootstrap-table-zh-CN.min.js"></script>
<script src="Transfer.js"></script>

<!-- 中间点击按钮图标没显示出来没关系  是因为引入的cdn问题  正常下载引入bootstrap.css的话没问题的 -->
<!-- 此处演示的数据源为一个 用falg去区分在哪个里面 -->
<script type="text/javascript">
var data = [{

        "importUnitId": "950258484706803712",
        "importUnitName": "分数对比2016",
        "flag": false,

    },
    {
        "importUnitId": "949202813861232640",
        "importUnitName": "对比1",
        "flag": false,
    },
    {
        "importUnitId": "948380218236600320",
        "importUnitName": "测试2",
        "flag": false,
    },
    {
        "importUnitId": "946590730653007872",
        "importUnitName": "对比4",
        "flag": false,
    },
    {
        "importUnitId": "946590730653007889",
        "importUnitName": "对比954",
        "flag": true,
    },
    {
        "importUnitId": "946590730653008647",
        "importUnitName": "对比88",
        "flag": true,
    }
]


$('#transferContainer').transfer({
    titles: ['待选对比档案', '已选对比档案'],
    search: true,
    uniqueId: "importUnitId",//唯一id
    dataSource: data,
    maxSelect: 6,
    diffKey: 'flag',
    unselectColumns: [{
            field: 'flag',
            checkbox: true
        },
        {
            field: 'importUnitName',
            title: '档案名称'
        }
    ]
});

$('#btn').click(function(){
   var data= $('#transferContainer').transfer('getData', 'selectData', 'importUnitId');
   console.log(data)
})

$('#refresh').click(function(){
     $('#transferContainer').transfer('refresh',data)
})

</script>


Transfer.js


(function ($, window, document) {
    var transfer = function (el, options) {
        this.option = options;
        this.$el = $(el);
        this.selectData=[];
        this.unselectData=[];
        this.init();
    };
    transfer.DEFAULTS = {
        titles:['待选列表','已选列表'],
        search: true,///是否显示搜索查询
        showRefresh: false,//
        clickToSelect: true,
        pagination: false,//是否支持分页
        autoHeight:false,
        url:'',
        type:"get",
        queryParams:{},
        contentType: 'application/json',
        paginationDetail:false,
        maxSelect:undefined,
        uniqueId: "",//每行的id
        dataSource:[],//默认数据源为同一个  内部会通过diffKey去区分是待选框的  还是已选框的数据,如果selectdataSource存在  则或解析为待选数据框里的数据
        selectdataSource:undefined,
        diffKey:'flag',
        selectColumns:[],
        unselectColumns:[]

    };
    transfer.prototype = {
        init: function () {
            this.initoption();
            this.initContainer();
            this.initBothTable();
            if(this.option.url){
                this.initServer();
            }else{
                this.classifyData();
            }

            this.initEvent();
        },
        /*
        * 渲染穿梭框页面结构*/
        initContainer: function () {
            var _this=this;
          var  containerHtml=['<div class="col-sm-5 transferBox">',
            '<h3 class="unselectTitle" style="margin: 0;padding: 5px 0 10px 0;">'+this.unselectTitle+'<span style="margin-left: 5px;">(<span id="checkedNum1"></span><span id="unselectTotalNum"></span>)</span></h3>',
            '<table id="transferUnselectTable"></table>',
            '</div>',
            '<div class="col-sm-2 transferBtn" style="height: 100%">',
            '<div class="btnList">',
            '<span class="btn btn-default  forwardBtn" ><i class="glyphicon glyphicon-forward"></i></span>',
            '<span class="btn btn-default  backwardBtn" ><i class="glyphicon glyphicon-backward"></i></span>',
            '</div>',
            '</div>',
            '<div class="col-sm-5 transferBox">',
            '<h3 class="selectTitle" style="margin: 0;padding: 5px 0 10px 0;">'+this.selectTitle+'<span style="margin-left: 5px;">(<span id="checkedNum2"></span><span id="selectTotalNum"></span>)</span></h3>',
            '<table id="transferSelectTable"></table>',
            '</div>'].join('');
            this.$el.html(containerHtml);
            this.$unselectTable=this.$el.find('#transferUnselectTable');//待选表格
            this.$unselectTotalNum=this.$el.find('#unselectTotalNum');//存放待选表格内总的数量
            this.$checkedNum1=this.$el.find('#checkedNum1');//存放待选表格中已勾选的数量
            this.$forwardBtn=this.$el.find('.forwardBtn');//向待选表格内添加的按钮

            this.$selectTable=this.$el.find('#transferSelectTable');//已选表格
            this.$selectTotalNum=this.$el.find('#selectTotalNum');//存放已选表格内总的数量
            this.$checkedNum2=this.$el.find('#checkedNum2');//存放已选表格中已勾选的数量
            this.$backwardBtn=this.$el.find('.backwardBtn');//向待选表格内添加的按钮
            this.option.height=this.$el.outerHeight()-this.$el.find('h3.unselectTitle').outerHeight()-8;
        },
        /*
        * 参数处理*/
        initoption:function(){
            /*
            * 两边标题参数处理*/
            if(typeof this.option.titles=='string'|| (this.option.titles instanceof Array&&this.option.titles.length==1)){
                this.selectTitle=this.unselectTitle=this.option.titles+'';
            }else if(this.option.titles instanceof Array&&this.option.titles.length>1){
                this.unselectTitle=this.option.titles[0];
                this.selectTitle=this.option.titles[1];
            }
             /*
            * 两个table渲染内容若一样,给任意一个columns即可*/
            if(this.option.selectColumns instanceof Array&&this.option.unselectColumns instanceof Array&&(!this.option.selectColumns.length&&this.option.unselectColumns.length)){
                this.option.selectColumns= $.extend(true,[],this.option.unselectColumns);
            }else if(this.option.selectColumns instanceof Array&&this.option.unselectColumns instanceof Array&&(this.option.selectColumns.length&&!this.option.unselectColumns.length)){
                this.option.unselectColumns=$.extend(true,[],this.option.selectColumns);
            }else if(!this.option.selectColumns instanceof Array||!this.option.unselectColumns instanceof Array){
                console.error('参数selectColumnsunselectColumns必须为数组');
                return false;
            }
            /*
            * 两边table两边渲染选中的field不能一样,此处强制替换了,参数中可不写field*/
            this.option.selectColumns[0].field=this.option.diffKey+'s';
            this.option.unselectColumns[0].field=this.option.diffKey;
         },
        /*
        * 从数据中挑出已选列表和待选列表的数据*/
         classifyData:function(){
             /*
              *数据源如果为同一个则通过diffKey去区分
               *  */
             if(!this.option.dataSource){console.error('dataSource参数为必填项,请检查');return false;}
               if(this.option.selectdataSource){
                 this.selectData=this.option.selectdataSource;
                 this.unselectData=this.option.dataSource;
             }else{
                 for(var i=0;i<this.option.dataSource.length;i++){
                     if(this.option.dataSource[i][this.option.diffKey]){
                         this.selectData.push(JSON.parse(JSON.stringify(this.option.dataSource[i])));
                     }else{
                         this.unselectData.push(JSON.parse(JSON.stringify(this.option.dataSource[i])));
                     }
                 }
             }
            this.refreshTable();
            this.showTotalNum();
        },
        /*
        * 当数据发生变化重新渲染表格*/
        refreshTable:function(){
            this.$unselectTable.bootstrapTable("load",this.unselectData);
            this.$selectTable.bootstrapTable("load",this.selectData);
        },
        /*
        * 当表格数据总量发生变化,相应改变其总数*/
        showTotalNum:function(){
            this.$unselectTotalNum.html(this.unselectData.length+'');
            this.$selectTotalNum.html(this.selectData.length+'');
        },
        /*
        * 初始化表格,开始是没有数据加入*/
        initBothTable:function(){
            var _this=this;
            this.$unselectBootstrapTable=this.$unselectTable.bootstrapTable({
                search: _this.option.search,
                showRefresh: _this.option.showRefresh,
                showToggle: false,
                showColumns: false,
                paginationDetail:_this.option.paginationDetail,
                clickToSelect: _this.option.clickToSelect,
                pagination: _this.option.pagination,
                sidePagination: 'client',
                autoHeight:false,
                height:_this.option.height,
                data:[],
                sortName: "createTime",
                sortOrder: "desc",
                uniqueId: _this.option.uniqueId,
                columns:_this.option.unselectColumns
            });
            this.$selectBootstrapTable=this.$selectTable.bootstrapTable({
                search: _this.option.search,
                showRefresh: _this.option.showRefresh,
                showToggle: false,
                paginationDetail:_this.option.paginationDetail,
                showColumns: false,
                clickToSelect: _this.option.clickToSelect,
                pagination: _this.option.pagination,
                autoHeight:false,
                height:_this.option.height,
                data:[],
                sortName: "createTime",
                sortOrder: "desc",
                uniqueId: _this.option.uniqueId,
                columns:_this.option.selectColumns
            });
            this.$selectBootstrapTable.on('check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table', function (e, rows) {
                var num=_this.$selectTable.find('tr input[name="btSelectItem"]:checked').length;
                if(num){
                    _this.$backwardBtn.removeClass('btn-default').addClass('btn-info');
                    _this.$checkedNum2.html(num+'/');
                }else{
                    _this.$backwardBtn.removeClass('btn-info').addClass('btn-default');
                    _this.$checkedNum2.html('');
                }
            });
            this.$unselectBootstrapTable.on('check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table', function (e, rows) {
                var num=_this.$unselectTable.find('tr input[name="btSelectItem"]:checked').length;
                if(num){
                    _this.$forwardBtn.removeClass('btn-default').addClass('btn-info');
                    _this.$checkedNum1.html(num+'/');
                }else{
                    _this.$forwardBtn.removeClass('btn-info').addClass('btn-default');
                    _this.$checkedNum1.html('');
                }
            });
        },
        /*
        * 请求数据*/
        initServer:function(){
            var _this=this;
            if(this.option.url){
                    $.ajax({
                        url: _this.option.url,
                        type: _this.option.type,
                        contentType: _this.option.contentType, //对应后台的@RequestBody
                        data:_this.option.queryParams||null,
                        data: _this.option.contentType==='application/json' && _this.option.type === 'post' ?
                            JSON.stringify(_this.option.queryParams) : _this.option.queryParams,
                        success: function (res) {
                            if(res.success){
                                _this.option.dataSource=res.data;
                                _this.selectData=[];
                                _this.unselectData=[];
                                _this.classifyData();
                            }
                        },
                        error: function (result) {

                        }
                    });

            }
        },
        /*
        * 初始化点击事件*/
        initEvent:function(){
            var _this=this;
            this.$forwardBtn.click(function(){
                _this.transferData($(this),1);
            });
            this.$backwardBtn.click(function(){
                _this.transferData($(this),0);
            });
        },
        /*
        * 获取选中行的id*/
        getSelect:function($tr){
            return  $.map($tr,function(ele,index){
                if($(ele).find('input[name="btSelectItem"]').is(':checked')){
                    return $(ele).attr("data-uniqueid");
                }
            });
        },
        /*
        * 两边数据穿梭逻辑
        * @params type:穿梭方向*/
        transferData:function($dom,type){
            var _this=this;
            if(!$dom.hasClass('btn-info')){
                return false;
            }
            if(type){
                var selectList=this.getSelect(this.$unselectTable.find('tbody tr'));
                if((this.option.maxSelect-0)&&typeof (this.option.maxSelect-0)=="number"){
                    var currenNum=selectList.length+this.selectData.length;
                    if(currenNum>this.option.maxSelect){
                        alert(this.selectTitle+'最多只能存在'+this.option.maxSelect+'个,您选的太多了!');
                        return false;
                    }
                }
                for(var i=0;i<this.unselectData.length;i++){
                    if(selectList.indexOf(this.unselectData[i][this.option.uniqueId])>=0){
                        this.unselectData[i][this.option.selectColumns[0].field]=false;
                        this.selectData.push(this.unselectData[i]);
                        this.unselectData.splice(i,1);
                        i--;
                    }
                }
               this.refreshTable();
                this.$forwardBtn.removeClass('btn-info').addClass('btn-default');
                this.$checkedNum1.html('');
            }else{
                var selectList=this.getSelect(this.$selectTable.find('tbody tr'));
                for(var i=0;i<this.selectData.length;i++){
                    if(selectList.indexOf(this.selectData[i][this.option.uniqueId])>=0){
                        this.selectData[i][this.option.unselectColumns[0].field]=false;
                        this.unselectData.push(this.selectData[i]);
                        this.selectData.splice(i,1);
                        i--;
                    }
                }
                this.refreshTable();
               this.$backwardBtn.removeClass('btn-info').addClass('btn-default');
                this.$checkedNum2.html('');
            }
            this.showTotalNum();
        },
        /*
        * 暴露到外面的实例的方法,可返回两个表格内的数据集合
        * @params type: 必填 unselectData待选列表数据,selectData已选列表数据
        * @params arr: 非必填 若不存在直接返回源数据集合,若配置字段名则返回所需的字段集合*/
        getData:function(type,arr){
            if(!type){console.error('请填写想要返回的数据名称unselectDataselectData');return false;}
            if(arr&&typeof arr=='string'){
               return $.map(this[type],function(item,index){
                   return item[arr];
                });
            }else if(arr&&arr instanceof Array && arr.length>0){
                return $.map(this[type],function(item,index){
                    var obj={};
                    for(var i=0;i<arr.length;i++){
                        obj[arr[i]]=item[arr[i]];
                    }
                    return obj;
                });
            }else{
                return this[type];
            }
        },
         /*
        * 销毁实例*/
        destroy :function () {
            this.$el.html('');
        },
        /*
        * 刷新表格  只当数据源为一个时有效*/
        refresh:function(data){
            if(this.option.url) {
                this.initServer();
            }else{
                this.option.dataSource=JSON.parse(JSON.stringify(data));
                this.selectData=[];
                this.unselectData=[];
                this.classifyData();
            }
        }
     }
    var allowedMethods = ['refresh','destroy','getData'];
    $.fn.transfer = function (option) {   //jQuery注册插件
        var e = this, value,
            args = Array.prototype.slice.call(arguments, 1);
        e.each(function () {
            var $this = $(this),
                data = $this.data('transfer'),
                options = $.extend({}, transfer.DEFAULTS, $this.data(),
                    typeof option === 'object' && option);
            if (typeof option === 'string') {
                if ($.inArray(option, allowedMethods) < 0) {
                    throw new Error("Unknown method: " + option);
                }
                if (!data) {
                    return;
                }
                value = data[option].apply(data, args);

                if (option === 'destroy') {
                    $this.removeData('transfer');
                }
            }
            if (!data) {
                $this.data('transfer', (data = new transfer(this, options)));
            }
        });
        return typeof value === 'undefined' ? this : value;
    };
    $.fn.transfer.Constructor = transfer;
    $.fn.transfer.defaults = transfer.DEFAULTS;
    $.fn.transfer.methods = allowedMethods;
})(jQuery, window, document);















猜你喜欢

转载自blog.csdn.net/weixin_42603150/article/details/80925960