$widget 控件的封装 多选按钮和filter 的实现 两栏显示框

实现代码 html 结构布局部分:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        div, input {
            padding: 0;
            margin: 0
        }

        ul, li {
            list-style: none;
            margin: 0;
            padding: 0;
        }

        .displayNone {
            display: none;
        }

        .again, .group {
            height: 32px;
            padding: 0 4px;
            margin: 2px;
            background-color: #c3c3c3;
            border: 1px solid #333;
            border-radius: 5px;
            box-shadow: none;
            outline: none;
            cursor: pointer;
        }

        .again:hover, .group:hover {
            background-color: #c3f1f8;
        }

        /*多项 选择和删除 弹出框 样式布局*/
        .jd_widget_box * {
            margin: 0;
            padding: 0;
            font-size: 12px;
            font-family: "Microsoft YaHei", 微软雅黑, "Microsoft JhengHei", 华文细黑, STHeiti, MingLiu;
            color: #464c5b;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            -webkit-text-size-adjust: none;
        }

        .jd_widget_box .jd_pop_box {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            left: 0;
            z-index: 999;
        }

        /*弹出框背景色*/
        .jd_widget_box .jd_pop_bg {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            left: 0;
            background-color: #767779;
            opacity: .7;
            filter: alpha(opacity=70);
            z-index: 990;
        }

        .jd_widget_box .result_input {
            box-sizing: border-box;
            height: 32px;
            line-height: 32px;
            padding: 0 4px;
            vertical-align: middle;
            border: 1px solid #333;
            border-radius: 3px;
            box-shadow: none;
            outline: none;
        }

        .jd_widget_box .result_box {
            box-sizing: border-box;
            display: inline-block;
            vertical-align: middle;
        }

        .jd_widget_box .btn_add {
            box-sizing: border-box;
            width: 32px;
            height: 32px;
            margin: 0 2px;
            vertical-align: middle;
            background-color: #fff;
            border: 1px solid #333;
            border-radius: 3px;
            box-shadow: none;
            outline: none;
            cursor: pointer;
        }

        .jd_widget_box .btn_add:hover {
            background-color: #c3f1f8;
        }

        .jd_widget_box .jd_show_box {
            width: 690px;
            height: 400px;
            position: absolute;
            left: 50%;
            top: 50%;
            margin-left: -345px;
            margin-top: -200px;
            background-color: #f7f7f7;
            opacity: 1;
            border: 1px solid #ddd;
            border-radius: 3px;
            z-index: 999;
        }

        .jd_widget_box .jd_top_bar {
            box-sizing: border-box;
            width: 100%;
            height: 38px;
            line-height: 38px;
            padding: 0 10px;
            font-size: 14px;
            font-weight: 600;
            border-bottom: 1px solid #e4e9ed;
        }

        .jd_widget_box .btn_submit {
            float: right;
            height: 24px;
            padding: 0 18px;
            color: #fff;
            background-color: #4b71c2;
            border: 1px solid #2e5abd;
            border-radius: 3px;
            box-shadow: none;
            outline: none;
            cursor: pointer;
        }

        .jd_widget_box .btn_close {
            float: right;
            width: 16px;
            height: 16px;
            margin: 11px auto;
            background: url("css/widgeticon/closeTab.png") left center no-repeat;
            background-size: cover;
            cursor: pointer;
        }

        .jd_widget_box .filter_box {
            box-sizing: border-box;
            width: 100%;
            padding: 20px 30px 15px 20px;
        }

        .jd_widget_box .filter_input {
            box-sizing: border-box;
            width: 325px;
            height: 24px;
            padding: 0 8px;
            border: 1px solid #8fb7e6;
            border-radius: 3px;
        }

        .jd_widget_box .btn_tools {
            display: inline-block;
            width: 345px;
            padding-left: 30px;
            box-sizing: border-box
        }

        /*全选,全不选按钮*/
        .jd_widget_box .btn_selected_all, .jd_widget_box .btn_unselected_all {
            line-height: 20px;
            padding: 0;
            background-color: transparent;
            border: none;
            border-radius: 3px;
            box-shadow: none;
            outline: none;
        }

        /*全选图标*/
        .jd_widget_box .btn_selected_all .icon_select_all {
            float: left;
            width: 20px;
            height: 20px;
            margin-right: 6px;
            background: url("css/widgeticon/select_icon_show.png") left center no-repeat;
            cursor: pointer;
        }

        /*全不选图标*/
        .jd_widget_box .icon_unselect_all {
            float: left;
            width: 20px;
            height: 20px;
            margin-right: 6px;
            background: url("css/widgeticon/delete_icon_show.png") left center no-repeat;
            cursor: pointer;
        }

        .jd_widget_box .icon_select_all:hover {
            background: url("css/widgeticon/select_icon_hover.png") left center no-repeat;
        }

        .jd_widget_box .icon_select_all:active {
            background: url("css/widgeticon/select_icon_active.png") left center no-repeat;
        }

        .jd_widget_box .icon_unselect_all:hover {
            background: url("css/widgeticon/delete_icon_hover.png") left center no-repeat;
        }

        .jd_widget_box .icon_unselect_all:active {
            background: url("css/widgeticon/delete_icon_active.png") left center no-repeat;
        }

        /*显示共选择则数量*/
        .jd_widget_box .count_text {
            display: inline-block;
            width: 120px;
            padding-right: 8px;
            margin-left: 40px;
            text-align: right;
        }

        /*筛选 和 已选 列表项*/
        .jd_widget_box .box_items {
            box-sizing: border-box;
            width: 688px;
            padding: 12px 0;
        }

        .jd_widget_box .filter_list, .jd_widget_box .selected_list {
            display: inline-block;
            width: 335px;
            height: 248px;
            overflow: auto
        }

        .jd_widget_box .filter_list li, .jd_widget_box .selected_list li {
            box-sizing: border-box;
            padding: 0 0 0 30px;
            line-height: 28px;
            border-bottom: none;
        }

        .jd_widget_box .filter_list {
            margin-right: 10px;
        }

        .jd_widget_box .filter_list li:hover, .jd_widget_box .selected_list li:hover {
            background-color: #f3f3f3;
            cursor: pointer;
        }

        /*筛选条件列表的添加图标*/
        .jd_widget_box .filter_list li .icon_select_list {
            float: left;
            width: 20px;
            height: 20px;
            padding: 4px 0;
            margin-right: 6px;
            vertical-align: text-bottom;
        }

        .jd_widget_box .filter_list li:hover .icon_select_list {
            background: url("css/widgeticon/select_icon_show.png") left center no-repeat;
        }

        .jd_widget_box .filter_list li:hover .icon_select_list:hover {
            background: url("css/widgeticon/select_icon_hover.png") left center no-repeat;
        }

        .jd_widget_box .filter_list li:hover .icon_select_list:active {
            background: url("css/widgeticon/select_icon_active.png") left center no-repeat;
        }

        /*已选列表的删除图标*/
        .jd_widget_box .selected_list li .icon_unselect_list {
            float: left;
            width: 20px;
            height: 20px;
            padding: 4px 0;
            margin-right: 6px;
            vertical-align: text-bottom;
        }

        /*已选列表的删除图标*/
        .jd_widget_box .selected_list li:hover .icon_unselect_list {
            background: url("css/widgeticon/delete_icon_show.png") left center no-repeat;
        }

        .jd_widget_box .selected_list li:hover .icon_unselect_list:hover {
            background: url("css/widgeticon/delete_icon_hover.png") left center no-repeat;
        }

        .jd_widget_box .selected_list li:hover .icon_unselect_list:active {
            background: url("css/widgeticon/delete_icon_active.png") left center no-repeat;
        }

        /*显示已选中的按钮组*/
        .jd_widget_box .item_card {
            display: inline-block;
            box-sizing: border-box;
            height: 32px;
            line-height: 32px;
            padding: 0 35px;
            margin: 0 2px;
            position: relative;
            text-align: center;
            background: #fff;
            border: 1px solid #666666;
            border-radius: 3px;
            outline: none;
            cursor: pointer;
        }

        .jd_widget_box .item_card:hover {
            background-color: #eff4f9;
            border: 1px solid #8fb7e6;
        }

        .jd_widget_box .item_card:hover .btn_small_del {
            display: inline-block;
            width: 10px;
            height: 10px;
            position: absolute;
            right: 5px;
            top: 5px;
            font-size: 18px;
            font-weight: 500;
            cursor: pointer;
            background: url('css/widgeticon/close-small.png') center center no-repeat;
        }
    </style>
</head>
<body>
<div id="maincontainer">
</div>
<input class="again" type="button" value="Again" οnclick="doCreate()"/>
<script src="js/jquery-1.11.3.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="js/a-widget.js"></script>
<script>
    var xx;
    //    显示的是id 卡片组
    function doCreate() {
        $('#maincontainer').multiSelect({
            id: "t",
            items: [
                {id: 'k001', name: '这是文本一'},
                {id: 'k002', name: '这是文本二', selected: true},
                {id: 'k003', name: '这是文本三'},
                {id: 'k004', name: '这是文本四'},
                {id: 'k005', name: '这是文本五'},
                {id: 'k006', name: '这是文本6', selected: true},
                {id: 'k007', name: '这是文本7'},
                {id: 'k008', name: '这是文本8'},
                {id: 'k009', name: '这是文本9'},
                {id: 'k0010', name: '这是文本10'},
                {id: 'k0011', name: '这是文本11'},
                {id: 'k0012', name: '这是文本12'},
                {id: 'k0013', name: '这是文本13'},
                {id: 'k0014', name: '这是文本14'}
            ], selecteds: [
                'k003'
            ], excludes: [
                'k003', 'k004', 'k005'
            ], maxShowCount: 2,
            style: 1,
            showType: 0,
            maxShowFormat: "我选了{0}个共{1}", complete: function (event, data) {
                $.each(data, function (i, val) {
                })
            }, deleted: function (event, data) {
                alert("删除的ID:  " + data.id + ":" + "    删除的name:  " + data.name);
            }
        });
    }
    $(function () {
//        显示文本
        xx = $('#maincontainer').multiSelect({
            items: [
                {id: 'k001', name: '这是文本一'},
                {id: 'k002', name: '这是文本二', selected: true},
                {id: 'k003', name: '这是文本三'},
                {id: 'k004', name: '这1文本四'},
                {id: 'k005', name: '这1文本五'}
            ], selecteds: [
                'k003'
            ], maxShowCount: 4, complete: function (event, data) {
                $.each(data, function (i, val) {
                    alert(val.id + ":" + val.name);
                })
            }, del: function (event, data) {
                $.each(data, function (i, val) {
                    alert("删除的ID:  " + val.id + ":" + "    删除的name:  " + val.name);
                })
            }
        });
    });
</script>

</body>
</html>

 

实现的 js 方法封装部分:

/**
 * Created by ZhangML on 2019/3/5.
 */
(function ($) {
    //它带有两个参数:一个是要创建的插件名称,一个是包含支持插件的函数的对象文字。
    $.widget("hzjd.multiSelect", {
        //    默认参数
        options: {
            componentId: 'K' + parseInt(Math.random() * 100000000, 10),
            items: [], //所有选项, 格式 [{"id":"0","name":"xx","selected":false},...]
            excludes: [], //排除数组. 格式  ['id0','id1','id2',...]
            selecteds: [],//已选中数组. 格式  ['id0','id1','id2',...]
            style: 0, //0:表示下拉框, 1:表示文本框
            showType: 1, //显示文本方式, 0:表示显示id,1:表示显示文本
            maxShowCount: 0, //选中的文本框中最大显示个数, 0:表示全部 当style为0时有效
            maxShowFormat: "已选择{0}项,共{1}项", //超过最大显示个数的显示格式
            itemCountFormat: "共:{0}项", //显示全部项目数显示格式
            filterCountFormat: "符合条件:{0}项", //显示符合查询条件项目数显示格式
            selectedCountFormat: "已选:{0}项", //已选项目数显示格式
            title: '选择条件',//窗口标题
            completed: null,
            deleted: null,
            filtered: null
        },
        _tempItems: [],
        _tempMap: null,
        _init: function () {
            //    创建控件,控件生命周期内会运行多次
            this._initComponent();
            this._initItems();
            this._show();
            this._showText();
        },
        _create: function () {
            //    初始化,控件生命周期内只运行一次
            //alert("create");
            var self = this;
            $(self.element).append('<div id="' + this.options.componentId + '" class="jd_widget_box"/>');
        },
        _initComponent: function () {
            var self = this;
            var component = $('#' + this.options.componentId);
            var cmpHtml = "";
            if (this.options.style == 0) {
                cmpHtml += '<input class="result_input" type="text"/>';
            } else {
                cmpHtml += '<div class="result_box"></div>';
            }
            cmpHtml += '<input type="button" class="btn_add" value="+"/>';
            cmpHtml += '<div class="jd_pop_box" style="display:none;">'
            + '<div class="jd_pop_bg"></div>'
            + '<div class="jd_show_box">'
            + '<div class="jd_top_bar">' + self.options.title + '<a class="btn_close"></a></div>'
            + '<div class="filter_box"><input class="filter_input" type="text"/><button class="btn_submit">确定</button></div>'
            + '<div class="btn_tools"><a class="btn_selected_all"><b class="icon_select_all"></b>全选</a><span class="item_count count_text"></span></div>'
            + '<div class="btn_tools"><a class="btn_unselected_all"><b class="icon_unselect_all"></b>全不选</a><span class="selected_count count_text"></span></div>'
            + '<div class="box_items">'
            + '<ul class="filter_list"></ul><ul class="selected_list"></ul>'
            + '</div></div></div>';
            component.html(cmpHtml);
            this._bindBtnAdd();
            this._bindSelectAll();
            this._bindUnselectAll();
            this._bindSubmit();
            this._bindClose();
            this._bindFilterInput();
        },
        selected: function () {
            var selectedAry = [];
            var allItems = this._tempItems;
            if (allItems != undefined && allItems != null) {
                for (var i = 0; i < allItems.length; i++) {
                    var item = allItems[i];
                    if (item.selected) {
                        selectedAry.push(item);
                    }
                }
            }
            return selectedAry;
        },
        removeSelected: function (id) {
            var item = this._tempMap.get(id);
            if (item != undefined && item != null) {
                item.selected = false;
                this.options.items = this._tempItems;
                this._trigger('deleted', null, item);
            }
        },
        items: function () {
            return this.options.items;
        },
        _initTempItems: function () {
            //初始化临时选项数组
            var self = this;
            this._tempItems = [];
            var items = this.options.items;
            var selecteds = this.options.selecteds;
            var excludes = this.options.excludes;

            this._tempMap = new Map(); //id为key, item为value
            var exMap = new Map(); //id为key, id为value
            for (var i = 0; i < excludes.length; i++) {
                exMap.set(excludes[i], excludes[i]);
            }
            if (items != undefined && items != null) {
                //遍历全部项目,添加Option 如果项目已选中,则隐藏
                for (var i = 0; i < items.length; i++) {
                    var exItem = exMap.get(items[i].id);
                    if (exItem != undefined && exItem != null) {
                        continue;
                    }
                    var item = {};
                    item["id"] = items[i].id;
                    item["name"] = items[i].name;
                    item["selected"] = items[i].selected;
                    item["index"] = i; //选项加上序号
                    this._tempItems.push(item);
                    this._tempMap.set(item.id, item);
                }
            }
            if (selecteds != undefined && selecteds != null) {
                $.each(selecteds, function (index, id) {  //遍历二维数组
                    var idItem = self._tempMap.get(id);
                    if (idItem != undefined && selecteds != null) {
                        idItem.selected = true;
                    }
                });
            }
        },
        //渲染列表页面
        _initItems: function () {
            this._initTempItems();
            var leftHtml = "";
            var rightHtml = "";
            if (this._tempItems != undefined && this._tempItems != null) {
                //遍历全部项目,添加Option
                $.each(this._tempItems, function (index, item) {  //遍历二维数组
                    leftHtml += "<li class='" + "item_" + index + "' itemId='" + item.id + "' itemIndex='" + index + "' itemName='" + item.name + "'>"
                    + item.name + "<b class='icon_select_list'></b></li>";
                    rightHtml += "<li class='" + " selected_" + index + "' itemId='" + item.id + "' itemIndex='" + index + "' itemName='" + item.name + "'>"
                    + item.name + "<b class='icon_unselect_list'></b></li>";
                });
            }
            $('#' + this.options.componentId + ' .filter_list').html(leftHtml);
            $('#' + this.options.componentId + ' .selected_list').html(rightHtml);
            this._bindItemClick();
            this._bindSelectedClick();
        },
        _refresh: function (isFilter) {
            var scount = 0;
            var ncount = 0;
            var self = this;
            if (this._tempItems != undefined && this._tempItems != null) {
                //遍历全部项目,添加Option 如果项目已选中,则隐藏
                $.each(this._tempItems, function (index, item) {  //遍历二维数组
                    //显示或隐藏
                    if (item.hidden || item.selected) {
                        $('#' + self.options.componentId + ' .filter_list .item_' + index).addClass("displayNone");
                    } else {
                        ncount++;
                        $('#' + self.options.componentId + ' .filter_list .item_' + index).removeClass("displayNone");
                    }
                    if (item.selected) {
                        scount++;
                        $('#' + self.options.componentId + ' .selected_list .selected_' + index).removeClass("displayNone");
                    } else {
                        $('#' + self.options.componentId + ' .selected_list .selected_' + index).addClass("displayNone");
                    }
                });
            }
            var selectedCountText = this.options.selectedCountFormat.replace('{0}', scount);
            var itemCountText = this.options.itemCountFormat.replace('{0}', ncount);
            if (isFilter) {
                itemCountText = this.options.filterCountFormat.replace('{0}', ncount);
            }
            $('#' + this.options.componentId + ' .item_count').html(itemCountText);
            $('#' + this.options.componentId + ' .selected_count').html(selectedCountText);
        },
        _show: function () {
            $('#' + this.options.componentId + ' .filter_input').val(""); //过滤条件清空
            //显示内容
            this._initTempItems();
            this._refresh();
        },
        _filter: function (text) {
            //根据项目显示相应内容
            //项目添加过滤属性 hidden: true 表示因过滤不显示
            if (this._tempItems != undefined && this._tempItems != null) {
                //遍历全部项目,添加Option 如果项目已选中,则隐藏
                $.each(this._tempItems, function (index, item) {  //遍历二维数组
                    if (item.name.indexOf(text) >= 0) {
                        item["hidden"] = false;
                    } else {
                        item["hidden"] = true;
                    }
                });
                text != "" ? this._refresh(true) : this._refresh(false);
                this._trigger('filtered', null, text);
            }
        },
        _bindFilterInput: function () {
            //选中点击事件
            var self = this;
            $('#' + this.options.componentId + ' .filter_input').on('input', function () {
                self._filter($(this).val());
            });
        },
        _bindItemClick: function () {
            //选中点击事件
            var self = this;
            $('#' + this.options.componentId + ' .icon_select_list').on('click', function () {
                var index = $(this).parent('li').attr("itemIndex");
                var item = self._tempItems[index];
                item["selected"] = true;
                self._refresh();
            });
        },
        _bindSelectedClick: function () {
            //取消点击事件
            var self = this;
            $('#' + this.options.componentId + ' .icon_unselect_list').on('click', function () {
                var index = $(this).parent('li').attr("itemIndex");
                var item = self._tempItems[index];
                item["selected"] = false;
                self._refresh();
            });
        },
        _selectAll: function () {
            $.each(this._tempItems, function (index, item) {  //遍历二维数组
                if (item.hidden != true) {
                    item.selected = true;
                }
            });
            this._refresh();
        },
        _unselectAll: function () {
            $.each(this._tempItems, function (index, item) {  //遍历二维数组
                if (item.selected == true) {
                    item.selected = false;
                }
            });
            this._refresh();
        },
        _bindSelectAll: function () {
            //全选点击事件
            var self = this;
            $('#' + this.options.componentId + ' .icon_select_all').on('click', function () {
                self._selectAll();
            });
        },
        _bindBtnAdd: function () {
            //添加点击事件
            var self = this;
            $('#' + this.options.componentId + ' .btn_add').on('click', function () {
                $('#' + self.options.componentId + ' .jd_pop_box').css({'display': 'block'});
            });
        },
        _bindUnselectAll: function () {
            //全不选点击事件
            var self = this;
            $('#' + this.options.componentId + ' .icon_unselect_all').on('click', function () {
                self._unselectAll();
            });
        },
        _bindSubmit: function () {
            //确定点击事件
            var self = this;
            $('#' + this.options.componentId + ' .btn_submit').on('click', function () {
                $('#' + self.options.componentId + ' .jd_pop_box').css({'display': 'none'});
                self.options.items = self._tempItems;
                self._trigger('completed', null, self.selected());
            });
        },
        _bindClose: function () {
            //取消点击事件
            var self = this;
            $('#' + this.options.componentId + ' .btn_close').on('click', function () {
                self._show();
                $('#' + self.options.componentId + ' .jd_pop_box').css({'display': 'none'});
            });
        }
        ,
        _setOptions: function (options) {
            var key;
            for (key in options) {
                this._setOption(key, options[key]);
            }
            return this;
        }
        ,
        _setOption: function (key, value) {
            //    设置参数
            if (key === "items") {
                this.options[key] = value;
                return;
            }
            //    In jQuery UI 1.9及以后用法
            this._super(key, value);
            //    In jQuery UI 1.8及以前用法
            //  $.Widget.prototype._setOption.apply(this, arguments);
        }
        ,
        _showText: function () {
            var selectedItems = this.selected();
            if (this.options.style == 0) {
                var val = "";
                if (this.options.maxShowCount != 0 && selectedItems.length > this.options.maxShowCount) {
                    var totalCount = this._tempItems.length;
                    val = this.options.maxShowFormat.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());
                } else {
                    for (var i = 0; i < selectedItems.length; i++) {
                        var text = selectedItems[i].name;
                        if (this.options.showType == 0) {
                            text = selectedItems[i].id;
                        }
                        if (i == 0) {
                            val = text;
                        } else {
                            val += "," + text;
                        }
                    }
                }
                $('#' + this.options.componentId + ' .result_input').val(val);
            } else {
                var valHtml = "";
                for (var i = 0; i < selectedItems.length; i++) {
                    var text = selectedItems[i].name;
                    if (this.options.showType == 0) {
                        text = selectedItems[i].id;
                    }
                    valHtml += '<div class="item_card" itemId="' + selectedItems[i].id + '">'
                    + text + '<b class="btn_small_del" title="点击删除"></b></div>';
                }
                $('#' + this.options.componentId + ' .result_box').html(valHtml);
                this._bindBtnDelete();
            }
        },
        _bindBtnDelete: function () {
            var self = this;
            $('#' + this.options.componentId + ' .btn_small_del').on('click', function () {
                var itemId = $(this).parent('.item_card').attr("itemId");
                self.removeSelected(itemId);
            });
        },
        _trigger: function (type, event, data) {
            if (type == 'completed') {
                this._showText();
            }
            else if (type == 'deleted') {
                this._show();
                this._showText();
            }
            var callback = this.options[type];
            if (callback != undefined && callback != null) {
                callback(event, data);
            }
        },
        destroy: function () {
            //    释放控件
            $(this.element).html("");
            //    In jQuery UI 1.8及以前用法
            $.Widget.prototype.destroy.call(this);
            //    In jQuery UI 1.9及以后
        }
    });
})(jQuery);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值