下面我将为你提供一个详细、完整的实现方案,包含从数据库修改到模板制作的全部步骤,这个方案基于织梦最经典的 {dede:arclist} 标签和AJAX技术,兼容性较好,易于理解。

(图片来源网络,侵删)
实现原理
- 数据准备:在数据库中,分类信息需要有一个主分类(如“房产”)和一个子分类(如“租房”、“二手房”),筛选通常基于这些分类字段。
- 前端交互:
- 用户选择“一级分类”(如“房产”)后,通过AJAX请求向服务器发送请求。
- 服务器根据选择的一级分类ID,查询出所有对应的二级分类(如“租房”、“二手房”)。
- 服务器将查询结果(通常是JSON格式)返回给前端。
- 前端JavaScript接收到数据后,动态生成二级分类的
<option>选项并更新到页面上。
- 筛选执行:
- 用户选择好一、二级分类后,点击“筛选”按钮或直接选择分类时,再次通过AJAX请求将所有筛选条件(如分类ID、价格范围、面积等)发送到服务器。
- 后端PHP程序接收到这些条件后,动态构建SQL查询语句。
- 执行查询,获取符合条件的数据列表。
- 将结果返回给前端,JavaScript负责将结果列表渲染到页面上,实现无刷新更新。
详细实现步骤
第一步:数据库与模型准备
-
确保模型正确:
- 进入后台
[核心] -> [内容模型管理],确保你的分类信息模型已经正确创建。 - 检查模型中的字段,特别是分类相关的字段,通常织梦会自动生成
typeid(主分类ID) 和ttid(子分类ID,也叫小分类ID),如果需要筛选其他条件(如价格、面积),请确保这些字段也已添加到模型中。
- 进入后台
-
添加自定义字段(可选):
- 如果需要根据价格、面积等字段进行筛选,需要先添加自定义字段,添加一个名为
price的数字类型字段。
- 如果需要根据价格、面积等字段进行筛选,需要先添加自定义字段,添加一个名为
第二步:修改列表页模板 (list_*.htm)
这是实现联动筛选的核心部分,我们以 /templets/default/list_1.htm 为例进行修改。
-
引入jQuery库: 在模板的
<head>标签内,确保引入了jQuery库,如果模板没有,可以手动添加:
(图片来源网络,侵删)<script src="https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js"></script>
-
编写筛选表单HTML: 在列表页的合适位置(通常是列表上方)添加筛选表单,这里我们假设根据
typeid(主分类) 和ttid(子分类) 进行筛选。<!-- 筛选表单开始 --> <div class="filter-form"> <form id="filterForm" action=""> <!-- 一级分类 --> <select name="typeid" id="typeid"> <option value="0">请选择主分类</option> {dede:channel type='son' typeid='0'} <option value='[field:id/]'>[field:typename/]</option> {/dede:channel} </select> <!-- 二级分类 (初始为空,由JS动态填充) --> <select name="ttid" id="ttid" disabled> <option value="0">请先选择主分类</option> </select> <!-- 其他筛选条件示例,如价格范围 --> <select name="price_range"> <option value="">价格不限</option> <option value="0-1000">1000以下</option> <option value="1000-3000">1000-3000</option> <option value="3000-5000">3000-5000</option> <option value="5000-">5000以上</option> </select> <!-- 筛选按钮 --> <button type="button" id="filterBtn">筛选</button> </form> </div> <!-- 筛选表单结束 --> <!-- 列表内容容器 --> <div id="list-container"> {dede:arclist titlelen='50' row='10'} <li> <a href="[field:arcurl/]">[field:title/]</a> <p>[field:pubdate function="MyDate('Y-m-d',@me)"/]</p> </li> {/dede:arclist} </div>
第三步:编写JavaScript实现联动和AJAX筛选
在模板的底部,</body> 标签之前,添加以下JavaScript代码。
<script type="text/javascript">
$(function(){
// 1. 一级分类联动二级分类
$('#typeid').change(function(){
var typeid = $(this).val();
var $ttidSelect = $('#ttid');
// 清空二级分类下拉框,并禁用
$ttidSelect.empty().append('<option value="0">加载中...</option>').prop('disabled', true);
if(typeid == 0){
$ttidSelect.empty().append('<option value="0">请先选择主分类</option>').prop('disabled', true);
return;
}
// 发送AJAX请求获取二级分类
$.ajax({
url: "{dede:global.cfg_cmspath/}/plus/list_ajax.php", // 这是织梦自带的AJAX处理文件
type: "GET",
data: {typeid: typeid, action: 'getsonclass'},
dataType: "json",
success: function(data) {
$ttidSelect.empty().append('<option value="0">请选择子分类</option>');
if(data && data.length > 0){
$.each(data, function(i, item){
$ttidSelect.append('<option value="' + item.id + '">' + item.typename + '</option>');
});
$ttidSelect.prop('disabled', false); // 启用二级分类
} else {
$ttidSelect.append('<option value="0">该分类下无子分类</option>');
}
},
error: function() {
$ttidSelect.empty().append('<option value="0">加载失败</option>');
}
});
});
// 2. 执行筛选功能
$('#filterBtn').click(function(){
performFilter();
});
// 监听二级分类变化,也可以自动筛选
$('#ttid').change(function(){
performFilter();
});
// 筛选函数
function performFilter() {
// 获取所有筛选条件
var formData = $('#filterForm').serialize(); // 序列化表单数据,非常方便
// 显示加载提示
$('#list-container').html('<p>正在加载...</p>');
// 发送AJAX请求进行筛选
$.ajax({
url: "{dede:global.cfg_cmspath/}/plus/list_ajax.php",
type: "POST",
data: formData + '&action=getfilterlist', // 添加一个自定义的action标识
dataType: "html", // 返回的是HTML片段
success: function(data) {
// 用返回的新HTML替换列表容器内容
$('#list-container').html(data);
},
error: function() {
$('#list-container').html('<p>筛选失败,请稍后重试。</p>');
}
});
}
});
</script>
第四步:创建并修改AJAX处理文件 (list_ajax.php)
织梦在 /plus/ 目录下自带了一个 list_ajax.php 文件,我们可以直接修改它来满足我们的需求。
-
找到并打开
/plus/list_ajax.php文件。 -
修改文件内容: 在文件末尾,
<?php } ?>之前,添加我们自己的处理逻辑。<?php // ... 文件顶部原有的代码,请勿修改 ... // 在文件末尾添加以下代码 /** * 处理联动筛选请求 */ if ($dopost == '') { // 默认行为,不做处理 } // 获取二级分类 else if ($dopost == 'getsonclass' && isset($typeid)) { $typeid = intval($typeid); $dsql->SetQuery("SELECT id, typename FROM `#@__arctype` WHERE reid = $typeid ORDER BY sortrank ASC"); $dsql->Execute('t'); $sonclasses = array(); while ($row = $dsql->GetArray('t')) { $sonclasses[] = $row; } // 返回JSON格式数据 header('Content-Type: application/json'); echo json_encode($sonclasses); exit(); } // 获取筛选后的列表 else if ($dopost == 'getfilterlist') { // 1. 接收筛选参数 $typeid = isset($typeid) && is_numeric($typeid) ? $typeid : 0; $ttid = isset($ttid) && is_numeric($ttid) ? $ttid : 0; $price_range = isset($price_range) ? $price_range : ''; // 2. 构建基础查询 $addquery = " WHERE arc.arcrank > -1 "; // 只审核通过的 // 3. 根据条件动态添加SQL if ($typeid > 0) { $addquery .= " AND arc.typeid = '$typeid' "; } if ($ttid > 0) { // 注意:如果你的数据表中子分类字段名是ttid,则用下面的 $addquery .= " AND arc.ttid = '$ttid' "; // 如果你的数据表中子分类字段名是typeid2,则用下面的 // $addquery .= " AND arc.typeid2 = '$ttid' "; } if (!empty($price_range)) { list($min_price, $max_price) = explode('-', $price_range); if ($max_price == '') { $addquery .= " AND arc.price >= $min_price "; } else { $addquery .= " AND arc.price BETWEEN $min_price AND $max_price "; } } // ... 可以继续添加其他筛选条件的逻辑 ... // 4. 调用系统列表函数,生成HTML // 这里直接调用arclist标签,可以复用模板逻辑,最简单的方式 // 但注意,这种方式可能会把整个页面的HTML都返回回来,所以需要在前端做处理 // 更好的方式是手动构建SQL并查询,然后循环输出列表项的HTML // 为了简单演示,我们这里采用手动构建SQL并输出的方式 $sql = "SELECT arc.*,tp.typename as typename,tp.corank,tp.isdefault,tp.defaultname,tp.namerule,tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath FROM `#@__archives` arc LEFT JOIN `#@__arctype` tp ON arc.typeid=tp.id $addquery ORDER BY arc.sortrank DESC, arc.id DESC"; $dsql->SetQuery($sql); $dsql->Execute('t'); $artlist = ''; while ($row = $dsql->GetArray('t')) { // 这里构建列表项的HTML,样式可以根据你的模板调整 $arcurl = GetFileUrl($row['id'],$row['typeid'],$row['senddate'],$row['title'],$row['ismake'],$row['arcrank'],$row['namerule'],$row['typedir'],$row money); $artlist .= '<li>'; $artlist .= '<a href="'.$arcurl.'">'.$row['title'].'</a>'; $artlist .= '<p>发布时间:'.date('Y-m-d', $row['senddate']).'</p>'; // 如果有价格字段 if(isset($row['price'])){ $artlist .= '<p>价格:'. $row['price'] .'元</p>'; } $artlist .= '</li>'; } // 如果没有结果 if(empty($artlist)){ $artlist = '<p>没有找到符合条件的信息。</p>'; } // 直接返回HTML片段 echo $artlist; exit(); } ?>
总结与注意事项
- 字段名匹配:在
list_ajax.php中,arc.ttid这个字段名必须和你数据库中dede_archives表存储子分类的字段名一致,如果不是ttid,请务必修改。 - 安全性:代码中对
typeid等参数使用了intval()进行了基本处理,防止SQL注入,但在生产环境中,建议使用$dsql->SelectSql()等更安全的方法来构建查询。 - 性能:AJAX请求会频繁查询数据库,确保你的数据库索引建立得合理(特别是在
typeid,ttid,arcrank等字段上),以保证查询效率。 - 分页问题:上述方案没有实现AJAX分页,要实现AJAX分页,需要修改分页标签的生成逻辑,并让分页按钮也触发AJAX请求,这是一个更复杂的话题,但原理类似。
- 织梦版本:此方案基于织梦5.7等经典版本,在高版本(如织梦DedeBIZ)中,部分API或文件结构可能略有不同,需要做相应调整。
通过以上四个步骤,你就可以在织梦分类信息频道中实现一个功能完善的联动筛选了,这个方案兼顾了功能性和易用性,是中小型网站实现该需求的常用方法。
