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

如何在PrestaShop模块中通过<select>筛选并刷新HTML表格?

问题:PrestaShop模块中实现下拉框筛选表格数据

开发基于Smarty模板的PrestaShop模块时,需要实现下拉选择框(<select>)值改变时,筛选HTML表格数据并刷新表格。已通过JavaScript获取到下拉框选中值,但不清楚如何实现筛选功能,相关代码如下:

下拉框代码

<tr>
   <select name="valueType" id="select">
     <option value="all" selected="selected" disabled>Select type of document</option>
     <option value="0">Invoice 1</option>
     <option value="1">Invoice 2</option>
     <option value="3">Invoice 3</option>
   </select>
   <a type="button" class="btn" href="{$link->getModuleLink('invoice', 'myinvoices', array(), true)|escape:'html':'UTF-8'}">Voir tout</a>
</tr>

表格代码

<tbody>
   {if isset($invoices) && $invoices}
   {foreach from=$invoices item=invoice}
   <tr>
       <td><a class="dl" href="{$invoice.link}" title="{l s='Download the invoice number' mod='aechistoryinvoice'} {$invoice.invoice_number}"><i class="icon-file-pdf-o left"></i> {l s='Download' mod='aechistoryinvoice'}</a></td>
       <td class="align-center">{$invoice.invoice_number}</td>
       <td class="align-center">{$invoice.invoice_date}</td>
       <td class="align-right"><strong>{$invoice.total_amount_tax_excl}</strong></td>
       <td class="align-right">{$invoice.total_amount_tax_incl}</td>
       <td class="align-right">{$invoice.type_document}</td>
    </tr>
    {/foreach}  
    {else}     
    <tr>
      <td colspan="5">{l s='No data yet' mod='invoice'}</td>
    </tr>
  {/if}
</tbody>

当前JS代码

<script type="text/javascript"> 
   document.getElementById("select").addEventListener("change", function(e) {
      console.log(e.target.value);
   })
</script>

解决方案

提供两种实现方式,根据数据量和需求选择:

方式一:前端纯JS本地筛选(适合数据量小的场景)

无需请求后端,直接在前端对已加载的表格行进行显示/隐藏操作:

  1. 修改表格行模板,添加data-type属性存储单据类型:
<tr data-type="{$invoice.type_document}">
  1. 更新JavaScript事件逻辑:
<script type="text/javascript"> 
   const selectElement = document.getElementById("select");
   const tableRows = document.querySelectorAll("tbody tr[data-type]");

   selectElement.addEventListener("change", function(e) {
      const selectedType = e.target.value;

      tableRows.forEach(row => {
         // 选中"all"时显示所有行,否则只显示匹配类型的行
         if (selectedType === "all" || row.dataset.type === selectedType) {
            row.style.display = "";
         } else {
            row.style.display = "none";
         }
      });

      // 处理无数据提示:检查可见行数量,为空则显示提示
      const visibleRows = Array.from(tableRows).filter(row => row.style.display !== "none");
      const emptyRow = document.querySelector("tbody tr td[colspan='5']");
      if (emptyRow) {
         emptyRow.parentElement.style.display = visibleRows.length === 0 ? "" : "none";
      }
   });
</script>

方式二:后端AJAX异步刷新(适合数据量大或需实时取数的场景)

通过AJAX请求后端接口,获取筛选后的表格内容并替换:

1. 后端控制器修改

在模块的myinvoices控制器中添加筛选逻辑,接收type参数并返回渲染后的表格内容:

// 路径:/modules/invoice/controllers/front/myinvoices.php
public function initContent()
{
    parent::initContent();

    $type = Tools::getValue('type', 'all');
    $invoices = [];

    // 替换为你的实际数据查询逻辑
    if ($type === 'all') {
        $invoices = $this->getAllInvoices();
    } else {
        $invoices = $this->getInvoicesByType($type);
    }

    // AJAX请求直接返回表格内容
    if (Tools::isSubmit('ajax')) {
        $this->context->smarty->assign('invoices', $invoices);
        die($this->context->smarty->fetch(_PS_MODULE_DIR_ . 'invoice/views/templates/front/invoice_table_body.tpl'));
    }

    // 非AJAX请求正常渲染页面
    $this->context->smarty->assign('invoices', $invoices);
    $this->setTemplate('module:invoice/views/templates/front/myinvoices.tpl');
}

// 示例查询方法,替换为你的实际逻辑
private function getAllInvoices()
{
    return Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'invoice` WHERE id_customer = '.(int)$this->context->customer->id);
}

private function getInvoicesByType($type)
{
    return Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'invoice` WHERE id_customer = '.(int)$this->context->customer->id.' AND type_document = '.(int)$type);
}

2. 拆分表格模板

将表格tbody部分单独拆为invoice_table_body.tpl,方便AJAX渲染:

{if isset($invoices) && $invoices}
{foreach from=$invoices item=invoice}
<tr>
    <td><a class="dl" href="{$invoice.link}" title="{l s='Download the invoice number' mod='aechistoryinvoice'} {$invoice.invoice_number}"><i class="icon-file-pdf-o left"></i> {l s='Download' mod='aechistoryinvoice'}</a></td>
    <td class="align-center">{$invoice.invoice_number}</td>
    <td class="align-center">{$invoice.invoice_date}</td>
    <td class="align-right"><strong>{$invoice.total_amount_tax_excl}</strong></td>
    <td class="align-right">{$invoice.total_amount_tax_incl}</td>
    <td class="align-right">{$invoice.type_document}</td>
</tr>
{/foreach}  
{else}     
<tr>
  <td colspan="5">{l s='No data yet' mod='invoice'}</td>
</tr>
{/if}

原页面模板中引入该子模板:

<tbody id="invoice-table-body">
    {include file='module:invoice/views/templates/front/invoice_table_body.tpl'}
</tbody>

3. 更新AJAX请求的JS代码

<script type="text/javascript"> 
   const selectElement = document.getElementById("select");
   const tableBody = document.getElementById("invoice-table-body");
   const moduleLink = "{$link->getModuleLink('invoice', 'myinvoices', array(), true)|escape:'html':'UTF-8'}";

   selectElement.addEventListener("change", function(e) {
      const selectedType = e.target.value;

      fetch(`${moduleLink}&ajax=1&type=${selectedType}`)
         .then(response => response.text())
         .then(html => {
            tableBody.innerHTML = html;
         })
         .catch(error => {
            console.error('筛选失败:', error);
         });
   });
</script>

内容的提问来源于stack exchange,提问作者JeremT8

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 04:33:37