多个无关联字段联动筛选解决方案

2020-03-27 12:04:13 +08:00
 KevinRed

原文排版更清晰哦 => 多个无关联字段联动筛选解决方案

原文排版更清晰哦 => 多个无关联字段联动筛选解决方案

原文排版更清晰哦 => 多个无关联字段联动筛选解决方案


开发中可能遇多个字段的联动筛选问题,与省市区这样的有关联联动不同,这些字段没有关联

这样谁先谁后选择就会对联动产生影响,上级字段变动下级相应的也需要做联动

此处提出解决方案,请大家指点,实现效果可以点击此处 无关联字段联动筛选示例

主要思想是:

1.分层级展示所有字段,每一字段都可以作为该层级的筛选条件

2.当某层级字段 A 确定后隐藏其余字段和该层级以下的 A 字段

3.当某层级字段 A 清空后,将该层级以及以下选择内容清空,展示出可选字段

4.当某层级字段 A 变动后,将该层级以下选择内容清空,展示出可选字段

5.字段筛选仅联动未选择字段

可以使用一个栈,字段确定后入栈,如果有字段变动将该字段之后的全部出栈,清空对应选择数据

接下来是实现代码,以无关联字段联动筛选示例实现为例

前端代码

涉及到的分页列表可以看 基于 ThinkPHP 和 Layui 的分页列表实现

//html

<form class="layui-form" action="">

    <for start="1" end="6">
        <div class="layui-form-item layui-row">
            <div class=" layui-col-md2 layui-col-sm2 layui-col-xs2" id="div-sex{$i}">
                <label class="layui-form-label" id="label-sex{$i}">性别{$i}</label>
                <div class="layui-input-block">
                    <select lay-filter="sex{$i}" name="sex{$i}" id="sex{$i}"></select>
                </div>
            </div>

            <div class="layui-col-md2 layui-col-sm2 layui-col-xs2" id="div-birth{$i}">
                <label class="layui-form-label" id="label-birth{$i}">生日{$i}</label>
                <div class="layui-input-block">
                    <select lay-filter="birth{$i}" name="birth{$i}" id="birth{$i}"></select>
                </div>
            </div>

            <div class=" layui-col-md2 layui-col-sm2 layui-col-xs2" id="div-place{$i}">
                <label class="layui-form-label" id="label-place{$i}">住址{$i}</label>
                <div class="layui-input-block">
                    <select lay-filter="place{$i}" name="place{$i}" id="place{$i}"></select>
                </div>
            </div>

            <div class="layui-col-md2 layui-col-sm2 layui-col-xs2" id="div-look{$i}">
                <label class="layui-form-label" id="label-look{$i}">长相{$i}</label>
                <div class="layui-input-block">
                    <select lay-filter="look{$i}" name="look{$i}" id="look{$i}"></select>
                </div>
            </div>

            <div class="layui-col-md2 layui-col-sm2 layui-col-xs2" id="div-income{$i}">
                <label class="layui-form-label" id="label-income{$i}">收入{$i}</label>
                <div class="layui-input-block">
                    <select lay-filter="income{$i}" name="income{$i}" id="income{$i}"></select>
                </div>
            </div>


            <div class="layui-col-md2 layui-col-sm2 layui-col-xs2" >

            </div>

        </div>
    </for>


    <div class="layui-form-item layui-row">
        <div class="layui-col-md10 layui-col-sm10 layui-col-xs10" id="div-say">
            <label class="layui-form-label">宣言</label>
            <div class="layui-input-block">
                <input sex="text" name="say" placeholder="请输入关键字" autocomplete="off" class="layui-input" id="say">
            </div>
        </div>
    </div>


</form>

//js

var form, infos;
var level = [];
var keys = ['place', 'sex', 'birth', 'income', 'look'];
var book = {'place' : '', 'sex' : '', 'birth' : '', 'income' : '', 'look' : ''};
var map = {'place' : '住址', 'sex' : '性別', 'birth' : '生日', 'income' : '收入', 'look' : '长相'};

$(function () {
    layui.use('form', function () {
        form = layui.form;
        
        //注册选择框监听事件
        for (var num = 1; num <= 5; num++) {
            for(var name of keys){
                select(name, num);
            }
        }
    });


    //注册 input 框监听事件
    $('#say').on('input', function (data) {
        infos = $('#say').val().split(";");
        getData();
    });
    
    //获取筛选结果
    getData();
});


/__
 * 选择框监听
 * 
 * @param name 变动字段的名称
 * @param num  变动字段的层级
 */
function select(name, num) {
    var select = "select(" + name + num + ")";
    form.on(select, function (data) {
        var select = "#" + name + num;
        var val = $(select).val();

        //某字段选择
        if(val !== ''){
        
            //字段变动
            if(book[name] !== ''){
            
                //出栈
                var empty = level.pop();
                book[empty] = '';
                while (empty !== name) {
                    var empty = level.pop();
                    book[empty] = '';
                }

                //入栈
                book[name] = val;
                level.push(name);

                //还原字段
                for (var i = num + 1; i <= 5; i ++) {
                    for (var key of keys) {
                        var div = "#div-" + key + i;
                        if (book[key] === '') {
                            $(div).css("display", "block");
                            var label = "#label-" + key + i;
                            $(label).html(map[key] + i);

                            var div = "#div-" + key + i;
                            $(div).removeClass("layui-col-md10 layui-col-sm10 layui-col-xs10");
                            $(div).addClass("layui-col-md2 layui-col-sm2 layui-col-xs2");
                        }
                    }
                }
                
            //字段首选
            } else{
            
                //入栈
                book[name] = val;
                level.push(name);
                
                
                //隐藏字段
                for(var key of keys){
                    var div = "#div-" + key + num;
                    if (book[key] === '') {
                        $(div).css("display", "none");
                    }
                }
                var label = "#label-" + name + num;
                $(label).html(map[name]);
                var div = "#div-" + name + num;
                $(div).removeClass("layui-col-md2 layui-col-sm2 layui-col-xs2");
                $(div).addClass("layui-col-md10 layui-col-sm10 layui-col-xs10");

                for (var i = num + 1; i <= 5; i++) {
                    var s = "#div-" + name + i;
                    $(s).css("display", "none");
                }
            }

        //某字段清空
        }else{
            //出栈
            var empty = level.pop();
            book[empty] = '';
            while (empty !== name) {
                var empty = level.pop();
                book[empty] = '';
            }
            
            //还原字段
            for (var i = num; i <= 5; i ++) {
                for (var key of keys) {
                    var div = "#div-" + key + i;
                    if (book[key] === '') {
                        $(div).css("display", "block");
                        var label = "#label-" + key + i;
                        $(label).html(map[key] + i);
                        var div = "#div-" + key + i;
                        $(div).removeClass("layui-col-md10 layui-col-sm10 layui-col-xs10");
                        $(div).addClass("layui-col-md2 layui-col-sm2 layui-col-xs2");
                    }
                }
            }
        }

        getData();
    });
}


/__
 * 获取变动字段
 *
 */
function getData() {

    if (book['sex'] === '') {
        getClass('sex');
    }

    if (book['place'] === '') {
        getClass('place');
    }

    if (book['birth'] === '') {
        getClass('birth');
    }

    if (book['income'] === '') {
        getClass('income');
    }

    if (book['look'] === '') {
        getClass('look');
    }

   
    getList(1, 50);        
}

/__
 * 筛选分类
 *
 * @param name
 */
function getClass(name) {
    $.ajax({
        type: "post",
        url: "----/getClass",
        data: {
            "class": name,
            "sex": book['sex'],
            "place":  book['place'],
            "income":  book['income'],
            "look":  book['look'],
            "birth":  book['birth'],
            "says": infos
        },
        dataType: 'json',
        success: function (msg) {
            var data = msg.data;
            var len = data.length;
            var html = "<option value=\'\'></option>";
            for (var i = 0; i < len; i++) {
                html += "<option value=\'" + data[i] + "\' >" + data[i] + "</option>";
            }

            for (var i = level.length + 1; i <= 6; i++) {
                var s = "#" + name + i;
                $(s).html(html);
            }
            
            //layui 表单需要刷新
            form.render('select');

        }
    })
};

后端代码

//Controller 层

public function getClass(){

    $sex = $_POST['sex'];
    $birth = $_POST['birth'];
    $income = $_POST['income'];
    $look = $_POST['look'];
    $place = $_POST['place'];
    $says = $_POST['says'];

    $where = array();
    if (!empty($sex)) {
        $where['sex'] = $sex;
    }

    if (!empty($birth)) {
        $where['birth'] = $birth;
    }

    if (!empty($income)) {
        $where['income'] = $income;
    }

    if (!empty($look)) {
        $where['look'] = $look;
    }

    if (!empty($place)) {
        $where['place'] = $place;
    }

    foreach($says As $say){
        if (!empty($say)) {
            $where['say'][] = array('like', '%' . $say . '%');
        }
    }
    if(!empty($where['say'])){
        $where['say'][] = 'and';
    }


    $data = D('filter')->getClass($where, $_POST['class']);
    ajaxReturn(1, "成功", $data);
}

//Model 层

public function getClass($where, $class){

    $field = array("distinct " . $class);    

    $list = $this
            ->field($field)
            ->where($where)
            ->order($class)
            ->select();
    
    $data = array();
    foreach ($list As $item) {
        $data[] = $item[$class];
    }
    return $data;
}
784 次点击
所在节点    程序员
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/656732

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX