Shopware storefront实现带AJAX查询的商品选择输入框咨询
Shopware Storefront 自定义商品搜索选择框实现方案
后台的sw-entity-single-select/sw-entity-multi-id-select是Admin端专属组件,Storefront没有内置对应封装,可按以下方向实现需求:
1. 页面模板编写(Twig)
在你需要插入输入框的页面位置添加对应DOM结构,示例代码:
{# 输入框容器 #} <div class="custom-product-search"> <input type="text" id="customProductSearchInput" placeholder="输入商品关键词搜索" class="form-control"> {# 下拉结果容器,默认隐藏 #} <div id="productSearchResult" class="custom-product-search-result d-none mt-1 border rounded shadow-sm"></div> {# 也可单独加隐藏域存ID,避免用户直接修改输入框内容 #} <input type="hidden" name="selectedProductId" id="selectedProductId"> </div>
2. 后端API接口开发
需要先开发一个Storefront可访问的接口,用于接收关键词返回匹配商品数据:
- 首先在自定义插件的
src/Controller/Storefront目录下新建控制器,示例代码:
<?php declare(strict_types=1); namespace YourPluginNamespace\Controller\Storefront; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Shopware\Storefront\Controller\StorefrontController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; /** * @Route(defaults={"_routeScope"={"storefront"}}) */ class CustomProductSearchController extends StorefrontController { /** * @Route("/custom-product-search", name="frontend.custom.product.search", methods={"GET"}, defaults={"XmlHttpRequest"=true}) */ public function search(Request $request, SalesChannelContext $context): JsonResponse { $keyword = $request->query->get('keyword', ''); if (empty($keyword)) { return new JsonResponse([]); } $criteria = new Criteria(); // 按商品名称模糊匹配,可按需扩展SKU、商品编号等字段匹配 $criteria->addFilter(new ContainsFilter('product.name', $keyword)); $criteria->setLimit(10); // 最多返回10条匹配结果 $products = $this->container->get('product.repository')->search($criteria, $context->getContext())->getEntities(); $result = []; foreach ($products as $product) { $result[] = [ 'id' => $product->getId(), 'name' => $product->getName(), // 可按需加价格、缩略图等字段用于下拉展示 ]; } return new JsonResponse($result); } }
注意替换代码中的YourPluginNamespace为你自定义插件的实际命名空间
- 在插件的
src/Resources/config/routes.xml中注册路由,或配置注解扫描自动加载路由。
3. 前端交互逻辑实现
在Storefront的JS文件中添加输入监听、请求、结果渲染逻辑,示例代码:
// 防抖函数,避免输入过程频繁发送请求 function debounce(func, wait = 300) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } const searchInput = document.getElementById('customProductSearchInput'); const resultContainer = document.getElementById('productSearchResult'); const selectedIdInput = document.getElementById('selectedProductId'); // 监听输入事件 searchInput.addEventListener('input', debounce(async (e) => { const keyword = e.target.value.trim(); if (keyword.length < 2) { // 输入至少2个字符才触发搜索 resultContainer.classList.add('d-none'); resultContainer.innerHTML = ''; return; } // 发起AJAX请求 const response = await fetch(`/custom-product-search?keyword=${encodeURIComponent(keyword)}`, { headers: { 'X-Requested-With': 'XMLHttpRequest' } }); const products = await response.json(); if (products.length === 0) { resultContainer.innerHTML = '<div class="p-2 text-muted">未找到匹配商品</div>'; resultContainer.classList.remove('d-none'); return; } // 渲染结果列表 let html = ''; products.forEach(product => { html += `<div class="p-2 border-bottom product-search-item cursor-pointer" data-id="${product.id}" data-name="${product.name}"> ${product.name} </div>`; }); resultContainer.innerHTML = html; resultContainer.classList.remove('d-none'); // 绑定选中事件 document.querySelectorAll('.product-search-item').forEach(item => { item.addEventListener('click', () => { const productId = item.dataset.id; const productName = item.dataset.name; // 若需要输入框显示商品名就赋值productName,要显示ID则赋值productId searchInput.value = productId; selectedIdInput.value = productId; // 收起结果列表 resultContainer.classList.add('d-none'); }); }); })); // 点击页面其他位置自动收起结果列表 document.addEventListener('click', (e) => { if (!e.target.closest('.custom-product-search')) { resultContainer.classList.add('d-none'); } });
可选优化
- 如需支持多选,可调整逻辑将选中的ID用逗号拼接存入输入框/隐藏域,同时扩展已选中项的删除功能
- 可扩展搜索匹配规则,支持SKU、商品参数等多字段匹配
- 可添加加载状态,搜索过程中显示加载提示
内容的提问来源于stack exchange,提问作者CCCCC
相关产品推荐
相关产品推荐

