基于mui.popover的自定义底部弹出框-支持多选和搜索筛选的弹出列表组件改造以及mui.prompt添加自定义内容

在开发过程中总能遇到一些似曾相识有新鲜的玩意儿,此次要介绍的内容是在开发移动app过程中基于mui的popover进行改造的一个支持多选操作和列表检索筛选的底部弹出列表组件,以及如何往mui的prompt弹出输入式对话框中添加自定义的 input或textarea 内容,js操作,话不多说,先看看最终效果吧:

    

具体代码如下(代码量比较多喜欢的话请耐心看完):

html:

<!doctype html>
<html>

    <head>
        <meta charset="utf-8">
        <title></title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <link href="../css/mui.min.css" rel="stylesheet" />
        <link href="../css/custom.popover.css" rel="stylesheet" />
    </head>

    <body>
        <header class="mui-bar mui-bar-nav" style="background: #ffffff; box-shadow: none;">
            <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
            <h1 class="mui-title">基于mui.popover的底部弹出列表组件和mui.prompt</h1>
        </header>
        <div class="mui-content">
            <a href="#favorites" class="mui-btn mui-btn-outlined" style="margin: 30px 23%;">mui.custom.popover.multiple</a>
            <a href="#share" class="mui-btn mui-btn-outlined" style="margin: 0 25%;">mui.custom.popover.search</a>
            <div id="resBox" style="font-size: 15px; color: green; padding: 10px;"></div>
        </div>
    </body>
    <script src="../js/mui.min.js"></script>
</html>
View Code

javascript:

var customPopverData = [
    {'id': 'id1', 'name': '超时1', 'size': 12},
    {'id': 'id2', 'name': '阿斯蒂芬2', 'size': 13},
    {'id': 'id3', 'name': '传输3', 'size': 8},
    {'id': 'id5', 'name': '反恐精英5', 'size': 3},
    {'id': 'id6', 'name': '重试6', 'size': 1},
    {'id': 'id7', 'name': '草食动物7', 'size': 0},
    {'id': 'id8', 'name': '不听8', 'size': 2},
    {'id': 'id9', 'name': '参赛队伍9', 'size': 6},
];
var shareData = [
    {guid: '1', userName: 'u1'},
    {guid: '2', userName: '测试2'},
    {guid: '3', userName: '参数3'},
    {guid: '4', userName: '超时4'},
    {guid: '5', userName: '重试5'},
    {guid: '6', userName: '反恐精英6'},
    {guid: '7', userName: '传输7'},
    {guid: '8', userName: '厂商8'},
    {guid: '9', userName: '超时9'},
];

(function(doc) {
    /*********** 第一个按钮 可多选 功能 start ************/
    var favoriteDiv = doc.createElement('div');
    favoriteDiv.setAttribute('id', 'favorites');
    favoriteDiv.setAttribute('class', 'mui-popover mui-popover-action custom-popover favorites');
    favoriteDiv.innerHTML = '<ul class="mui-table-view table-view-top">\
                                <li class="mui-table-view-cell center">\
                                    <a href="#favorites" class="mui-icon mui-icon-closeempty"></a>\
                                    <span class="title">选择项</span>\
                                </li>\
                                <li class="mui-table-view-cell">\
                                    <a id="createF" href="#favorites" style="color: #0091FF;">+ 新建项</a>\
                                </li>\
                            </ul>\
                            <ul class="mui-table-view table-view-middle">\
                                <li class="mui-scroll-wrapper">\
                                    <div class="mui-scroll"><ul class="mui-table-view"></ul></div>\
                                </li>\
                            </ul>';
    // 此组件中间列表区域原结构是 <ul class="mui-table-view table-view-middle"></ul> 在安卓机中会出现无法滚动的现象
    // 为解决无法滚动 特添加 mui-scroll-wrapper  mui-scroll 结构 并使用mui('.mui-scroll-wrapper').scroll() 进行初始化
    doc.body.appendChild(favoriteDiv);
    mui('.mui-scroll-wrapper').scroll({
        bounce: true,
        indicators: true,
        deceleration: 0.0006
    });
    
    var promptExt = '<textarea class="favorite-tips" rows="3" \
                        style="font-size: 14px; width: 100%; padding: 5px; margin: 10px 0 -10px 0; border-radius: 0;" \
                        placeholder="请输入收藏夹说明"></textarea>'
    
    // 初始化组件列表
    initPopover();
    
    // 新建按钮点击事件监听
    doc.getElementById('createF').addEventListener('tap', function() {
        mui.prompt('新建项', '请输入名称', ' ', ['取消', '确认'], function(e) {
            // e.index为propmpt的按钮数组 ['取消', '确认'] 的索引值 e.index==0:取消按钮  e.index==1:确认按钮
            if (e.index == 1) {
                // 关于trim方法可参考博客   js去空 去除空格
                var name = trim(doc.querySelector('.mui-popup-input input').value);
                var tips = trim(doc.querySelector('.mui-popup-input textarea.favorite-tips').value);
                if (!name || name.length < 2 || name.length > 10) {
                    mui.toast('名称 2~10 个字符');
                    doc.querySelector('.mui-popup-input input').value = !name ? '' : name;
                    return false;
                }
                if (tips > 200) {
                    mui.toast('收藏夹说明200个字符内');
                    return false;
                }
                
                // 这里可以执行自己的ajax请求进行数据保存操作
                // 执行ajax后 重新渲染初始化mui.popover底部弹出组件
                initPopover();
                
                mui.showLoading() // 自定义 mui loading 可参考博客 
            }
        },'div')
        // 一定要在执行mui.prompt方法后在执行一下方法  往prompt中添加自定义的 input或textarea 内容
        var popupInput = doc.querySelector('.mui-popup').querySelector('.mui-popup-input')
        popupInput.innerHTML = popupInput.innerHTML + promptExt
    }, false);
    
    // popover列表组件关闭按钮监听
    doc.querySelector('.mui-icon.mui-icon-closeempty').addEventListener('tap', function() {
        // dosomething
    }, false);
    
    // 初始化或更新popover列表组件内容
    function initPopover() {
        var html = '';
        // alert('init favorite popup -> init popup -> ')
        // 获取当前情况下的收藏夹列表进行初始化操作
        for (var i in customPopverData) {
            var checked = customPopverData[i].include ? 'checked' : ''; 
            html += '<li class="mui-table-view-cell">\
                <div class="mui-input-row mui-checkbox">\
                  <label>\
                      <div class="title">' + customPopverData[i].name + '</div>\
                      <div class="tips"><span class="num">' + customPopverData[i].size + '</span>个内容</div>\
                  </label>\
                  <input name="favoriteCategory" value="' + customPopverData[i].id + '" \
                  type="checkbox" ' + checked + '>\
                </div>\
            </li>';
        }
        // type="checkbox" ' + checked + ' onchange="favoriteChange(this)">\
        html += '';
        // html += '<li class="mui-table-view-cell" style="height: 60px;"></li>'
        doc.querySelector('.mui-table-view.table-view-middle .mui-table-view').innerHTML = html;
        listnerFavoriteChange();
    }
    
    // 监听组件中的复选框状态 
    function listnerFavoriteChange() {
        var checkboxs = doc.querySelectorAll('input[name="favoriteCategory"]');
        // alert('len -> ' + checkboxs.length)
        mui.each(checkboxs, function(index, ele) {
            ele.addEventListener('change', function() {
                var html = '<div>功 能:mui.custom.popover.search</div>';
                var vals = [], texts = [], nums = [];
                mui.each(checkboxs, function(index, item){
                    if (item.checked) {
                        vals.push(item.value);
                        texts.push(item.parentNode.querySelector('.title').innerText);
                        nums.push(item.parentNode.querySelector('span.num').innerText);
                    }
                });
                html += '<div>已选择:\
                            <div> nums:' + nums.join(",") + '</div>\
                            <div> names:' + texts.join(",") + '</div>\
                            <div> values:' + vals.join(",") + '</div>\
                        </div>';
                document.querySelector("#resBox").innerHTML=html;
            }, false);
        })
    }
    /*********** 第一个按钮 可多选 功能 end ************/


    /*************  单选 可搜索功能 start *****************/
    var inputVal = '', shareDataAll = []; shareDiv = doc.createElement('div');
    shareDiv.setAttribute('id', 'share');
    shareDiv.setAttribute('class', 'mui-popover mui-popover-action custom-popover search share');
    shareDiv.innerHTML = '<ul class="mui-table-view table-view-top">\
                                <li class="mui-table-view-cell center">\
                                    <a href="#share" class="mui-icon mui-icon-closeempty"></a>\
                                    <span class="title">选择项分享人</span>\
                                </li>\
                                <li class="mui-table-view-cell">\
                                    <div class="mui-input-row">\
                                        <span class="mui-icon mui-icon-search"></span>\
                                        <input id="searchInput" type="text" class="mui-input-clear" \
                                        style="font-size: 15px;" autocomplete="off" placeholder="请输入">\
                                    </div>\
                                </li>\
                            </ul>\
                            <ul class="mui-table-view table-view-middle">\
                                <li class="mui-scroll-wrapper">\
                                    <div class="mui-scroll"><ul class="mui-table-view"></ul></div>\
                                </li>\
                            </ul>';
    // 此组件中间列表区域原结构是 <ul class="mui-table-view table-view-middle"></ul> 在安卓机中会出现无法滚动的现象
    // 为解决无法滚动 特添加 mui-scroll-wrapper  mui-scroll 结构 并使用mui('.mui-scroll-wrapper').scroll() 进行初始化
    doc.body.appendChild(shareDiv);
    mui('.mui-scroll-wrapper').scroll({
        bounce: true,
        indicators: true,
        deceleration: 0.0006
    });
    
    initSharePopover();
    
    // 初始化或更新popover列表组件内容
    function initSharePopover() {
        shareDataAll = shareData;
        renderListHtml();
    }
    
    function renderListHtml() {
        var shareHtml = '';
        // alert('init favorite popup -> init popup -> ')
        // 获取当前情况下的收藏夹列表进行初始化操作
        for (var i in shareData) {
            shareHtml += '<li class="mui-table-view-cell">\
                  <a class="share-item" href="#share" id="' + shareData[i].guid + '" \
                  name="' + shareData[i].userName + '">' + shareData[i].userName + '</a>\
            </li>';
        }
        // type="checkbox" ' + checked + ' onchange="favoriteChange(this)">\
        shareHtml += '';
        // html += '<li class="mui-table-view-cell" style="height: 60px;"></li>'
        doc.querySelector('.share .mui-table-view.table-view-middle .mui-table-view').innerHTML = shareHtml;
        listnerShareChoose();
    }
    
    function listnerShareChoose() {
        mui.each(document.querySelectorAll('.share .table-view-middle .share-item'), function(i, ele) {
            ele.addEventListener('tap', function() {
                var html = '<div>功 能:mui.custom.popover.search</div>';
                var val = ele.getAttribute('id');
                var name = ele.getAttribute('name');
                html += '<div>已选择:<div> text:' + name + '</div><div> value:' + val + '</div></div>';
                document.querySelector("#resBox").innerHTML=html;
            }, false);
        });
        
        document.querySelector('.share .table-view-top .mui-input-row input').addEventListener('keydown',  function(event) {
            var e = event || window.event || arguments.callee.caller.arguments[0];
            if (e.keyCode === 13) {
                if (this.value) {
                    inputVal = this.value;
                    shareData = shareDataAll.filter(shareItemFilter);
                } else {
                    shareData = shareDataAll;
                }
                renderListHtml();
            }
        });
    }
    
    function shareItemFilter(item) {
        return item.userName.includes(inputVal);
    }
    /*************  单选 可搜索功能 end *****************/
}(document));
View Code

css:

.mui-popover.custom-popover {
    position: fixed;
}
.mui-popover.custom-popover,
.mui-popover.custom-popover * {
    font-size: 16px;
}
.mui-popover.custom-popover .mui-scroll-wrapper {
    margin-top: 0;
}
.mui-popover.mui-popover-action.custom-popover .mui-table-view {
    margin: 0;
    text-align: left;
    border-radius: 0;
}
.mui-popover.custom-popover .mui-table-view.table-view-middle {
    height: 200px;
}
.mui-popover.custom-popover .mui-table-view:after {
    height: 1px;
}
.mui-popover.custom-popover .mui-table-view.table-view-middle:after {
    height: 0;
}
.mui-popover.custom-popover .mui-table-view.table-view-bottom.fixed-btn-box {
    background: #035495;
    border-radius: 6px;
    position: fixed;
    z-index: 999;
    color: white;
    bottom: 6px;
    width: 90%;
    left: 5%;
}
.mui-popover.custom-popover .mui-table-view.table-view-bottom.fixed-btn-box:after {
    height: 0;
}
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell {
    padding: 11px 25px;
}
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell.center {
    text-align: center;
}
.mui-popover.custom-popover .mui-table-view.table-view-top .mui-table-view-cell {
    padding: 11px 20px;
}
.mui-popover.custom-popover .mui-table-view.table-view-bottom.fixed-btn-box .mui-table-view-cell {
    padding: 0;
    border-radius: 5px;
}
.mui-popover .mui-table-view.table-view-top li.mui-table-view-cell a.mui-icon-closeempty {
    top: 18px;
    left: 20px;
    padding: 0;
    color: #999999;
    display: inline;
    font-size: 30px;
    font-weight: bold;
    position: absolute;
    border-bottom: none;
}
.mui-popover .mui-table-view.table-view-top li.mui-table-view-cell span.title {
    color: #3a3a3a;
    font-weight: 600;
}
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell:last-child:after {
    height: 0;
}
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-checkbox label,
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-radio label {
    text-align: left;
    padding: 0 30px 0 0;
}
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-checkbox label>.title,
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-radio label>.title {
    line-height: 25px;
    font-weight: 600;
    color: #000000;
    height: 25px;
}
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-checkbox label>.tips>span.num,
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-radio label>.tips>span.num,
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-checkbox label>.tips,
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-radio label>.tips {
    line-height: 20px;
    font-size: 12px;
    color: #999999;
    height: 20px;
}
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-checkbox input[type=checkbox],
.mui-popover.custom-popover .mui-table-view .mui-table-view-cell .mui-input-row.mui-radio input[type=radio] {
    top: 5;
    right: 0;
}
.mui-popover.custom-popover .mui-table-view.table-view-bottom.fixed-btn-box .mui-table-view-cell .btn {
    margin: 0;
    height: 50px;
    line-height: 50px;
    border-radius: 5px;
}
a.research-laws-info-operation-frame2-font.collect-btn {
    width: 100%;
    height: 100%;
    margin: 9px 0;
    line-height: 1;
}
a.research-laws-info-operation-frame2-font.collect-btn>span.mui-icon {
    top: -1px;
    font-size: 18px;
    position: relative;
    margin-right: 10px;
}
/*****************   有搜索功能的popover样式start   ********************/
.mui-popover.mui-popover-action.custom-popover .mui-table-view .mui-input-row .mui-input-clear~.mui-icon-clear {
    top: 7px;
}
.mui-popover.mui-popover-action.custom-popover .mui-table-view .mui-input-row .mui-icon-search{
    position: absolute;
    font-size: 20px;
    left: 8px;
    top: 7px;
}
.mui-popover.mui-popover-action.custom-popover .mui-table-view .mui-input-row input {
    margin: 0;
    height: 36px;
    color: #999999;
    padding: 0 30px;
    font-size: 15px;
    line-height: 36px;
}
.mui-popover.mui-popover-action.custom-popover.search .mui-table-view.table-view-middle .mui-table-view li {
    text-align: center;
}
.mui-popover.mui-popover-action.custom-popover.search .mui-table-view.table-view-middle .mui-table-view li a{
    color: #999999;
}
/*****************   有搜索功能的popover样式end   ********************/
View Code

每天进步一点点,点滴记录,积少成多。

以此做个记录,

如有不足之处还望多多留言指教!

posted @ 2021-06-23 15:52  金刀3691  阅读(665)  评论(0编辑  收藏  举报