织梦自定义表单搜索如何实现?

99ANYc3cd6
预计阅读时长 33 分钟
位置: 首页 织梦建站 正文

下面我将为你提供一个详细、完整的步骤指南,分为两种主要方法:

织梦 自定义表单搜索
(图片来源网络,侵删)
  1. 使用织梦的“高级搜索”功能(推荐,更规范)
  2. 直接在自定义表单模板中编写搜索(更灵活,但需要手动处理分页等)

准备工作:以一个“留言反馈”表单为例

假设你已经创建了一个名为 dede_addonfeedback 的自定义表单(在后台“核心” -> “自定义表单”中创建),它包含以下字段:

  • id (主键,自增)
  • uname (姓名, textinput)
  • company (公司, textinput)
  • tel (电话, textinput)
  • email (邮箱, textinput)
  • msg (留言内容, textarea)
  • dtime (提交时间, datetime)

我们的目标是实现一个搜索框,可以根据unamecompanymsg这三个字段进行关键词搜索。


使用织梦的“高级搜索”功能(推荐)

这种方法的好处是能直接利用织梦内置的搜索框架,自动处理分页、高亮、搜索结果页模板等,非常规范。

步骤 1:在自定义表单列表页添加搜索框

打开你的自定义表单列表页模板文件,通常是 plus/list.php 或者你自定义的模板文件(templets/plus/your_form_list.htm),为了清晰,我们创建一个独立的模板文件 templets/plus/feedback_search.htm

织梦 自定义表单搜索
(图片来源网络,侵删)

feedback_search.htm 中,添加搜索表单:

<form name="search" action="/plus/search.php" method="get">
    <!-- 隐藏字段,指定搜索模型为我们的自定义表单 -->
    <input type="hidden" name="kwtype" value="0" />
    <input type="hidden" name="searchtype" value="custom" />
    <input type="hidden" name="typeid" value="1" /> <!-- typeid可以任意设置,但必须有 -->
    <!-- 关键词输入框 -->
    <input type="text" name="q" placeholder="请输入姓名、公司或留言内容..." />
    <!-- 搜索按钮 -->
    <button type="submit">搜索</button>
</form>

代码解释:

  • action="/plus/search.php":织梦的搜索程序入口。
  • name="searchtype" value="custom"这是关键,告诉织梦这是一个“自定义”搜索,而不是搜索文章或产品。
  • name="q":这是用户输入的关键词,织梦会自动获取这个值。

步骤 2:修改 plus/search.php 文件

这是实现自定义搜索的核心,我们需要修改 search.php,让它能识别并查询我们的自定义表单。

  1. 打开 /plus/search.php 文件。
  2. 找到处理搜索类型的关键代码段。 大约在文件的第 60-80 行,你会看到 switch($searchtype) 语句。
  3. switch 语句中添加 case 'custom': 分支。

switch($searchtype) 中添加如下代码:

织梦 自定义表单搜索
(图片来源网络,侵删)
// 在 switch($searchtype) 语句块内添加
case 'custom':
    // 1. 获取关键词并处理
    $keyword = trim($q);
    if (empty($keyword)) {
        ShowMsg('请输入搜索关键词!', '-1');
        exit();
    }
    // 2. 设置搜索的表前缀和字段
    // 注意:这里需要根据你的实际表名和要搜索的字段进行修改
    $tablepre = $dsql->GetTablePrefix(); // 获取表前缀,如 'dede_'
    $query = "SELECT * FROM `{$tablepre}addonfeedback` WHERE "; // 替换为你的自定义表名
    // 3. 构建搜索条件
    // 使用 CONCAT 函数将多个字段拼接成一个字符串进行搜索,实现多字段模糊匹配
    $search_fields = array('uname', 'company', 'msg'); // 定义要搜索的字段
    $like_conditions = array();
    foreach ($search_fields as $field) {
        $like_conditions[] = "`$field` LIKE '%$keyword%'";
    }
    $query .= implode(' OR ', $like_conditions);
    // 4. 执行查询并获取结果
    $dsql->SetQuery($query);
    $dsql->Execute('fb');
    $items = array();
    while ($row = $dsql->GetArray('fb')) {
        $items[] = $row;
    }
    // 5. 设置模板变量,并显示搜索结果页
    $tempfile = $cfg_basedir.$cfg_templets_dir."/plus/search_result.htm";
    $GLOBALS['totalresult'] = count($items); // 总结果数
    $GLOBALS 'searchpage'] = ''; // 分页变量,这里我们先不处理分页
    // 将结果数组传递给模板
    $GLOBALS['arr'] = $items;
    // 引入并解析搜索结果模板
    include($tempfile);
    exit();
    break;

代码解释:

  • $tablepre:自动获取数据库表前缀,避免硬编码。
  • {$tablepre}addonfeedback:替换成你的自定义表名。
  • $search_fields:定义一个数组,包含所有需要搜索的字段名。
  • LIKE '%$keyword%':标准的SQL模糊查询语法。
  • implode(' OR ', $like_conditions):将多个字段的条件用 OR 连接起来,实现“任意字段匹配”。
  • $GLOBALS['arr'] = $items;:将查询到的结果数组存入全局变量,供模板调用。
  • $tempfile = ...:指定搜索结果要使用的模板文件。

步骤 3:创建搜索结果页模板

templets/plus/ 目录下创建一个名为 search_result.htm 的文件,这个文件用来展示搜索结果。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">搜索结果</title>
</head>
<body>
    <h1>搜索结果</h1>
    <!-- 显示搜索关键词和结果数量 -->
    <p>搜索关键词:<strong>{dede:global.q/}</strong>,共找到 <strong>{dede:global.totalresult/}</strong> 条结果。</p>
    <!-- 循环输出搜索结果 -->
    {dede:global name='arr' function='print_r'/} 
    <!-- 上面的这行代码是用来调试的,它会直接打印出 $arr 数组的内容,你可以先加上它,看看数据结构,然后替换成下面的循环代码。 -->
    <!-- 正确的循环输出方式 -->
    <table border="1" width="100%">
        <tr>
            <th>姓名</th>
            <th>公司</th>
            <th>电话</th>
            <th>留言内容</th>
            <th>提交时间</th>
        </tr>
        {dede:global name='arr'}
        <tr>
            <td>[field:uname/]</td>
            <td>[field:company/]</td>
            <td>[field:tel/]</td>
            <td>[field:msg function='cn_substr(@me, 50)'/]</td> <!-- 截取留言内容前50个字符 -->
            <td>[field:dtime function='MyDate("Y-m-d H:i:s", @me)'/]</td>
        </tr>
        {/dede:global}
    </table>
    <!-- 注意:上面的 {dede:global name='arr'} ... {/dede:global} 是一个自定义标签循环,需要你修改 /include/taglib/global.lib.php 文件来支持。
    更简单直接的方法是直接用PHP循环,但这不符合织梦模板规范。 -->
    <!-- 为了简单起见,我们直接在模板里写PHP代码(不推荐,但快速实现) -->
    <?php
    if (is_array($GLOBALS['arr'])) {
        foreach ($GLOBALS['arr'] as $field) {
            echo "<tr>";
            echo "<td>".$field['uname']."</td>";
            echo "<td>".$field['company']."</td>";
            echo "<td>".$field['tel']."</td>";
            echo "<td>".cn_substr($field['msg'], 50)."</td>";
            echo "<td>".MyDate('Y-m-d H:i:s', $field['dtime'])."</td>";
            echo "</tr>";
        }
    }
    ?>
</body>
</html>

注意: 直接在模板中写PHP代码 (<?php ... ?>) 是一种快速实现的方式,但会破坏模板的封装性,更规范的方法是扩展织梦标签,但对于快速实现,这是可行的。


直接在自定义表单模板中编写搜索

这种方法更直接,不需要修改 search.php,但所有逻辑(分页、排序等)都需要自己处理。

步骤 1:修改列表页模板(如 templets/plus/feedback_list.htm

在列表页的头部添加搜索表单。

<form name="myform" action="{dede:global.cfg_cmspath/}/plus/feedback_list.php" method="get">
    <input type="hidden" name="tid" value="{dede:global.tid/}" /> <!-- 保持当前表单ID -->
    <input type="text" name="keyword" placeholder="输入关键词搜索..." value="{dede:global.keyword/}" />
    <button type="submit">搜索</button>
</form>
<hr>
<!-- 原有的列表内容 -->
{dede:list pagesize='10'}
    <h3>[field:uname/] - [field:company/]</h3>
    <p>[field:msg/]</p>
    <p>时间:[field:dtime function="MyDate('Y-m-d H:i:s', @me)"/]</p>
    <hr>
{/dede:list}
{dede:pagelist listsize='5'/}

步骤 2:修改列表处理程序(plus/list.php

打开 /plus/list.php 文件,找到获取 tid 的地方,在其后添加获取 keyword 的逻辑,并修改SQL查询语句。

  1. 获取关键词变量:$tid = isset($tid) && is_numeric($tid) ? $tid : 0; 这类代码附近,添加:

    $keyword = isset($keyword) ? trim($keyword) : '';
  2. 修改SQL查询语句: 找到类似 $cquery = "SELECT * FROM{$tablepre}addonfeedbackWHERE arcrank > -1 ORDER BY id DESC"; 的代码。 修改为:

    // 基础查询
    $cquery = "SELECT * FROM `{$tablepre}addonfeedback` WHERE 1=1";
    // 如果有关键词,则添加搜索条件
    if (!empty($keyword)) {
        $cquery .= " AND (`uname` LIKE '%$keyword%' OR `company` LIKE '%$keyword%' OR `msg` LIKE '%$keyword%')";
    }
    // 添加排序
    $cquery .= " ORDER BY id DESC";
  3. 传递关键词到模板:include($tempfile); 之前,添加:

    $GLOBALS['keyword'] = $keyword;

步骤 3:处理分页

{dede:pagelist/} 标签需要总记录数才能正常工作,我们需要手动计算总记录数。

在修改SQL查询的地方,添加一个计算总数的查询:

// ... 在修改 $cquery 之后 ...
// 计算总记录数
$count_query = "SELECT COUNT(*) AS total FROM `{$tablepre}addonfeedback` WHERE 1=1";
if (!empty($keyword)) {
    $count_query .= " AND (`uname` LIKE '%$keyword%' OR `company` LIKE '%$keyword%' OR `msg` LIKE '%$keyword%')";
}
$row = $dsql->GetOne($count_query);
$GLOBALS['TotalResult'] = $row['total'];
// 设置分页
$pagesize = 10;
$TotalPage = ceil($GLOBALS['TotalResult'] / $pagesize);
if ($pagenow > $TotalPage) $pagenow = $TotalPage;
$limitstart = ($pagenow - 1) * $pagesize;
// 将 limit 添加到主查询
$cquery .= " LIMIT $limitstart, $pagesize";
// ... 后续执行查询 ...

总结与对比

特性 方法一 (高级搜索) 方法二 (直接修改)
实现难度 中等,需要修改核心文件 search.php 中等,需要修改 list.php 和模板
规范性 ,符合织梦架构,代码复用性好 ,逻辑耦合在列表页,不易复用
分页处理 自动,由织梦搜索框架完成 手动,需要自己计算总数和分页
结果页 独立模板 (search_result.htm),清晰 与列表页共用一个模板 (list.htm)
推荐度 强烈推荐,特别是对于需要复杂搜索和独立结果页的场景 适用于简单、独立的列表页内搜索,快速实现

对于大多数项目,方法一是更优的选择,因为它更规范、更易于维护,并且能更好地利用织梦自身的功能,虽然修改核心文件听起来有些“危险”,但只要操作前备份好文件,就是完全可行的。

-- 展开阅读全文 --
头像
Verilog与C语言的核心差异与应用场景对比?
« 上一篇 03-03
织梦内容也改独立标题
下一篇 » 03-03

相关文章

取消
微信二维码
支付宝二维码

目录[+]