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

如何以HTMX风格通过下拉菜单筛选FastAPI生成的表格?

方案一:前端本地直接筛选(无需后端改动)

适合数据量不大的场景,页面加载完成后直接在浏览器内完成筛选,无需请求后端。

步骤1:给表格行添加标识属性

修改gpio.html,为每个表格行添加data-gpio属性,用来标记该行对应的GPIO值:

{% for gpio in gpios %}
    <tr data-gpio="{{ gpio.gpio }}">
    <td class="border">
        {{ gpio.gpio }}
    </td>
    <td class="border">
        {{ gpio.name }}
    </td>
    <td class="border">
        {{ gpio.type }}
    </td>
    <td class="border">
        {{ gpio.state }}
    </td>
    <td class="border">
        {{ gpio.changed }}
    </td>
    </tr>
{% endfor %}

步骤2:修改下拉菜单,添加筛选逻辑

替换原下拉菜单代码,添加JavaScript处理点击事件来筛选表格行:

<div class="dropdown">
    <button class="btn btn-primary dropdown-toggle p-2"
            type="button" id="gpioDropdown"
            data-bs-toggle="dropdown" aria-expanded="false">
        Select GPIO
    </button>
    <ul class="dropdown-menu" aria-labelledby="gpioDropdown">
        <!-- 增加"显示全部"选项 -->
        <li><a class="dropdown-item" data-gpio="all">显示全部</a></li>
        {% for gpio in gpios %}
          <li><a class="dropdown-item" data-gpio="{{ gpio.gpio }}">{{ gpio.gpio }}</a></li>
        {% endfor %}
    </ul>
</div>

<script>
// 给所有下拉选项绑定点击事件
document.querySelectorAll('.dropdown-item').forEach(item => {
    item.addEventListener('click', function() {
        const selectedGpio = this.getAttribute('data-gpio');
        const tableRows = document.querySelectorAll('#gpios tr');
        
        tableRows.forEach(row => {
            if (selectedGpio === 'all' || row.getAttribute('data-gpio') === selectedGpio) {
                row.style.display = ''; // 显示匹配行
            } else {
                row.style.display = 'none'; // 隐藏不匹配行
            }
        });
        
        // 更新下拉按钮的显示文本
        document.getElementById('gpioDropdown').textContent = this.textContent;
    });
});
</script>

方案二:HTMX风格后端筛选(推荐,符合无刷新理念)

如果数据量大或需要获取最新数据,通过HTMX请求后端接口,获取筛选后的表格内容替换原有tbody。

步骤1:修改FastAPI端点,添加筛选参数

假设你的后端基础端点如下,新增筛选逻辑和专用的表格内容接口:

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")

# 模拟GPIO数据,实际可从数据库读取
gpios_data = [
    {"gpio": "GPIO1", "name": "LED", "type": "output", "state": "on", "changed": "2024-05-20"},
    {"gpio": "GPIO2", "name": "Button", "type": "input", "state": "off", "changed": "2024-05-20"},
]

@app.get("/")
async def root(request: Request, gpio: str = None):
    filtered_gpios = gpios_data
    if gpio and gpio != "all":
        filtered_gpios = [g for g in gpios_data if g["gpio"] == gpio]
    return templates.TemplateResponse("index.html", {"request": request, "gpios": filtered_gpios})

# 仅返回表格tbody内容的接口,提升HTMX请求效率
@app.get("/gpio-table")
async def gpio_table(request: Request, gpio: str = None):
    filtered_gpios = gpios_data
    if gpio and gpio != "all":
        filtered_gpios = [g for g in gpios_data if g["gpio"] == gpio]
    return templates.TemplateResponse("components/gpio.html", {"request": request, "gpios": filtered_gpios})

步骤2:修改前端下拉菜单,添加HTMX属性

将HTMX属性绑定到每个下拉选项,实现无刷新更新表格:

<div class="dropdown">
    <button class="btn btn-primary dropdown-toggle p-2"
            type="button" id="gpioDropdown"
            data-bs-toggle="dropdown" aria-expanded="false">
        Select GPIO
    </button>
    <ul class="dropdown-menu" aria-labelledby="gpioDropdown">
        <li>
            <a class="dropdown-item" 
               hx-get="/gpio-table?gpio=all"
               hx-target="#gpios"
               hx-swap="innerHTML">
                显示全部
            </a>
        </li>
        {% for gpio in gpios %}
          <li>
              <a class="dropdown-item" 
                 hx-get="/gpio-table?gpio={{ gpio.gpio }}"
                 hx-target="#gpios"
                 hx-swap="innerHTML">
                  {{ gpio.gpio }}
              </a>
          </li>
        {% endfor %}
    </ul>
</div>

原代码问题说明

你之前的代码存在几个关键问题:

  • HTMX属性错误绑定到了下拉按钮而非选项上,点击按钮无法触发筛选逻辑
  • hx-select="value"是无效配置,此属性用于从响应中提取特定内容,你场景下不需要
  • hx-target="#test"指向的目标元素不存在,应改为表格tbody的#gpios
  • 用<form>包裹下拉菜单无必要,HTMX可直接发送请求,无需表单提交

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:22:47