如何在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本地筛选(适合数据量小的场景)
无需请求后端,直接在前端对已加载的表格行进行显示/隐藏操作:
- 修改表格行模板,添加
data-type属性存储单据类型:
<tr data-type="{$invoice.type_document}">
- 更新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
相关产品推荐
相关产品推荐

