You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mSearch2组件mFilter联动筛选适配:品牌与车型独立匹配

MODX mSearch2/mFilter品牌与车型联动筛选适配方案

问题背景

基于MODX的mSearch2组件搭建了mFilter联动筛选器,现有脚本仅支持车型名称包含品牌关键词的场景(比如车型名是「Ford Galaxy」对应品牌Ford),选品牌后车型选择框才能正常显示生效。但产品数据库体量庞大,无法批量修改车型名称为「品牌+车型」格式,需要实现基于产品实际关联关系的条件判断,验证指定品牌是否对应特定车型。

现有实现脚本

var modelFilter = {
    // 选择器配置
    options: {
        marka: '#mse2_tv\\|marka',
        model: '#mse2_tv\\|model',
    },
    // 初始化函数
    initialize: function() {
        $this = this;
        // 获取所需元素并保存为对象属性
        this.marka = $(this.options['marka']);
        this.model = $(this.options['model']);

        // 从地址栏参数中查找已选品牌
        var params = mSearch2.Hash.get();
        // 无选中品牌时禁用车型选择
        if (params['marka'] == undefined) {
            $this.disableModel();
        }
        // 有选中品牌时启用车型选择
        else {
            $this.enableModel();
        }

        // 绑定品牌选择变更事件
        this.marka.find('select').on('change', function() {
            // 选中品牌时,重置车型为默认选项并启用
            if ($(this).val() != '') {
                $this.model.find('option:first').attr('selected', true);
                $this.enableModel();
            }
            // 未选中品牌时禁用车型选择
            else {
                $this.disableModel();
            }
        })
    },

    // 禁用车型选择函数
    disableModel: function() {
        // 清空并禁用所有非空值选项
        $this.model.find('option[value!=""]').attr('selected', false).attr('disabled', true);
        // 隐藏车型选择框
        $this.model.hide();
    },

   // 启用车型选择函数(原逻辑:基于文本匹配)
    enableModel: function() {
        // 获取品牌名称(去除括号和末尾空格)
        var marka = this.marka.find(':selected').text().replace(/\(.*?\)$/, '').replace(/\s+$/, '');
        var re = new RegExp('^' + marka);
        // 遍历所有车型选项,根据文本匹配启用/禁用
        $this.model.find('option').each(function() {
            var $this = $(this);
            // 不匹配且非空值则禁用隐藏
            if (!$this.text().match(re) && $this.prop('value') != '') {
                $this.attr('disabled', true);
                $this.hide();
            }
            // 匹配则启用显示
            else {
                $this.attr('disabled', false);
                $this.show();
            }
        });
        // 显示车型选择框
        $this.model.show();
    },

}

// 文档加载完成后初始化脚本
$(document).ready(function() {
    // 页面存在筛选器时执行
    if ($('#mse2_mfilter').length > 0) {
        modelFilter.initialize();
    }
});

解决方案

核心思路:放弃文本正则匹配,改用品牌-车型关联映射表来判断对应关系,步骤如下:

1. 预构建品牌-车型映射表

先在页面中生成品牌与对应车型的映射关系,建议通过MODX后台snippet提前生成并渲染到页面,避免前端遍历大量数据影响性能。

后台生成映射表(MODX Snippet示例)

创建名为getBrandModelMap的snippet,代码如下:

<?php
$map = [];
// 替换为你的产品资源父ID或其他筛选条件
$products = $modx->getCollection('modResource', ['parent' => 123]);
foreach ($products as $product) {
    $brand = $product->getTVValue('marka'); // 替换为你的品牌TV字段名
    $model = $product->getTVValue('model'); // 替换为你的车型TV字段名
    if (!empty($brand) && !empty($model)) {
        if (!isset($map[$brand])) {
            $map[$brand] = [];
        }
        // 车型去重
        if (!in_array($model, $map[$brand])) {
            $map[$brand][] = $model;
        }
    }
}
// 输出为前端可直接使用的JSON变量
echo '<script>const brandModelMap = ' . json_encode($map) . ';</script>';
?>

在页面头部或筛选器区域之前调用该snippet:[[getBrandModelMap]]

2. 修改enableModel函数逻辑

替换原有的文本匹配逻辑,改用映射表判断车型归属:

// 修改后的启用车型选择函数
enableModel: function() {
    // 获取当前选中品牌的value(确保与映射表的key一致)
    var selectedBrand = this.marka.find(':selected').val();
    // 从映射表中获取该品牌对应的车型列表,无匹配则为空数组
    var validModels = brandModelMap[selectedBrand] || [];

    // 遍历所有车型选项
    $this.model.find('option').each(function() {
        var $option = $(this);
        var modelText = $option.text();
        var modelValue = $option.val();

        // 默认选项(空值)或车型在当前品牌列表中,则启用显示
        if (modelValue === '' || validModels.includes(modelText) || validModels.includes(modelValue)) {
            $option.attr('disabled', false);
            $option.show();
        } else {
            // 不属于当前品牌的车型,禁用隐藏
            $option.attr('disabled', true);
            $option.hide();
        }
    });
    // 显示车型选择框
    $this.model.show();
},

3. 优化初始化时的地址栏参数处理

确保地址栏中的品牌参数能正确关联映射表,修改初始化逻辑:

// 修改initialize中的地址栏参数判断部分
var params = mSearch2.Hash.get();
if (params['marka'] == undefined) {
    $this.disableModel();
} else {
    // 先设置品牌选择框的选中值,再启用车型筛选
    $this.marka.find('select').val(params['marka']);
    $this.enableModel();
}

注意事项

  • 确保品牌选择框的value与映射表的key完全一致,避免匹配失败
  • 如果车型的value和text不一致,可根据实际情况调整validModels.includes的判断对象
  • 产品数据量大时,建议后台缓存映射表,避免每次页面加载都遍历所有产品

内容的提问来源于stack exchange,提问作者Дмитрий Авакьян

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:24:32