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

如何在PHP中实现分类、品牌与产品的左右分栏Algolia自动补全

实现Algolia自动补全左右分栏布局

我正在开发一个PHP项目,集成Algolia自动补全功能以提供分类、品牌和产品的建议,希望自动补全界面分为左右两栏:左侧展示分类和品牌,右侧展示产品建议,效果类似下图:

自动补全分栏效果

当前代码

以下是初始化Algolia并设置自动补全的JavaScript代码:

<script type="text/javascript">
const ALGOLIA_APP_ID = 'my app id';
const ALGOLIA_API_KEY = 'my key';
const ALGOLIA_INDEX_NAME_1 = 'shop_PRODUCTS';
const ALGOLIA_INDEX_NAME_2 = 'shop_CATEGORY';
const ALGOLIA_INDEX_NAME_3 = 'shop_BRANDS';
const ALGOLIA_PRODUCT_URL = '<?php echo base_url('product'); ?>/';
const ALGOLIA_CATEGORY_URL = '<?php echo base_url('category'); ?>/';
const ALGOLIA_BRAND_URL = '<?php echo base_url('products/brand'); ?>/';
const ALGOLIA_IMAGE_PREFIX = '<?php echo CDN_LINK; ?>/cpanel/assets/uploads/product/';

// Initialize Algolia client
const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_API_KEY);
const index1 = client.initIndex(ALGOLIA_INDEX_NAME_1);
const index2 = client.initIndex(ALGOLIA_INDEX_NAME_2);
const index3 = client.initIndex(ALGOLIA_INDEX_NAME_3);

autocomplete('#search-input', {}, [
  {
    source: autocomplete.sources.hits(index1, { hitsPerPage: 5 }),
    displayKey: 'prd_name',
    templates: {
        header: '<div class="suggestion-header"><h3 class="gcom__typeahead-results-heading"><span class="gcom__typeahead-results-heading-label">Suggestions</span></h3></div>',
      suggestion: function(suggestion) {
          return '<a class="atagproduct" href="'+ ALGOLIA_PRODUCT_URL + suggestion.prd_slug + '"><div class="suggestion-item">' +
            '<img class="suggestion-image" src="'+ ALGOLIA_IMAGE_PREFIX + suggestion.prd_image + '" />' +
            '<div class="sugges-text-column">' +
           '<span class="suggestion-name">' + suggestion._highlightResult.prd_name.value + '</span>' +
           '<span class="suggestion-description">' + suggestion._highlightResult.prd_description.value + '</span>' +
           '</div>' +
           '</div></a>';
      }
    }
  },
  {
    source: autocomplete.sources.hits(index2, { hitsPerPage: 5 }),
    displayKey: 'cat_title',
    templates: {
      header: '<div class="suggestion-header"><h3 class="gcom__typeahead-results-heading"><span class="gcom__typeahead-results-heading-label">Category</span></h3></div>',
      suggestion: function(suggestion) {
            return '<a class="atagproduct" href="'+ ALGOLIA_CATEGORY_URL + suggestion.cat_slug + '"><div class="suggestion-item">' +
           '<span class="suggestion-name">' + suggestion._highlightResult.cat_title.value + '</span>' +
           '</div></a>';
      }
    }
  },
  {
    source: autocomplete.sources.hits(index3, { hitsPerPage: 5 }),
    displayKey: 'brd_title',
    templates: {
      header: '<div class="suggestion-header"><h3 class="gcom__typeahead-results-heading"><span class="gcom__typeahead-results-heading-label">Brands</span></h3></div>',
      suggestion: function(suggestion) {
            return '<a class="atagproduct" href="'+ ALGOLIA_BRAND_URL + suggestion.brd_slug + '"><div class="suggestion-item">' +
           '<span class="suggestion-name">' + suggestion._highlightResult.brd_title.value + '</span>' +
           '</div></a>';
      }
    }
  }
]);
</script>

需求布局

  • 分类和品牌显示在左侧
  • 产品建议显示在右侧

修改方案

要实现左右分栏布局,需要自定义Algolia Autocomplete的容器结构,并通过CSS控制布局,同时指定不同数据源的渲染位置。

1. 修改JavaScript代码

调整autocomplete的配置,添加自定义容器模板,并为每个数据源指定对应的渲染区域:

<script type="text/javascript">
const ALGOLIA_APP_ID = 'my app id';
const ALGOLIA_API_KEY = 'my key';
const ALGOLIA_INDEX_NAME_1 = 'shop_PRODUCTS';
const ALGOLIA_INDEX_NAME_2 = 'shop_CATEGORY';
const ALGOLIA_INDEX_NAME_3 = 'shop_BRANDS';
const ALGOLIA_PRODUCT_URL = '<?php echo base_url('product'); ?>/';
const ALGOLIA_CATEGORY_URL = '<?php echo base_url('category'); ?>/';
const ALGOLIA_BRAND_URL = '<?php echo base_url('products/brand'); ?>/';
const ALGOLIA_IMAGE_PREFIX = '<?php echo CDN_LINK; ?>/cpanel/assets/uploads/product/';

// Initialize Algolia client
const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_API_KEY);
const indexProducts = client.initIndex(ALGOLIA_INDEX_NAME_1);
const indexCategories = client.initIndex(ALGOLIA_INDEX_NAME_2);
const indexBrands = client.initIndex(ALGOLIA_INDEX_NAME_3);

autocomplete('#search-input', {
  // 自定义下拉框整体容器
  templates: {
    container: () => `
      <div class="autocomplete-container">
        <div class="autocomplete-left">
          <div class="left-section" id="category-section"></div>
          <div class="left-section" id="brand-section"></div>
        </div>
        <div class="autocomplete-right" id="product-section"></div>
      </div>
    `
  }
}, [
  // 产品数据源(渲染到右侧)
  {
    source: autocomplete.sources.hits(indexProducts, { hitsPerPage: 5 }),
    displayKey: 'prd_name',
    templates: {
      header: '<div class="suggestion-header"><h3 class="gcom__typeahead-results-heading"><span class="gcom__typeahead-results-heading-label">Suggestions</span></h3></div>',
      suggestion: (suggestion) => `
        <a class="atagproduct" href="${ALGOLIA_PRODUCT_URL}${suggestion.prd_slug}">
          <div class="suggestion-item">
            <img class="suggestion-image" src="${ALGOLIA_IMAGE_PREFIX}${suggestion.prd_image}" />
            <div class="sugges-text-column">
              <span class="suggestion-name">${suggestion._highlightResult.prd_name.value}</span>
              <span class="suggestion-description">${suggestion._highlightResult.prd_description.value}</span>
            </div>
          </div>
        </a>
      `,
      // 指定产品结果插入到右侧区域
      container: () => document.getElementById('product-section')
    }
  },
  // 分类数据源(渲染到左侧)
  {
    source: autocomplete.sources.hits(indexCategories, { hitsPerPage: 5 }),
    displayKey: 'cat_title',
    templates: {
      header: '<div class="suggestion-header"><h3 class="gcom__typeahead-results-heading"><span class="gcom__typeahead-results-heading-label">Category</span></h3></div>',
      suggestion: (suggestion) => `
        <a class="atagproduct" href="${ALGOLIA_CATEGORY_URL}${suggestion.cat_slug}">
          <div class="suggestion-item">
            <span class="suggestion-name">${suggestion._highlightResult.cat_title.value}</span>
          </div>
        </a>
      `,
      // 指定分类结果插入到左侧分类区域
      container: () => document.getElementById('category-section')
    }
  },
  // 品牌数据源(渲染到左侧)
  {
    source: autocomplete.sources.hits(indexBrands, { hitsPerPage: 5 }),
    displayKey: 'brd_title',
    templates: {
      header: '<div class="suggestion-header"><h3 class="gcom__typeahead-results-heading"><span class="gcom__typeahead-results-heading-label">Brands</span></h3></div>',
      suggestion: (suggestion) => `
        <a class="atagproduct" href="${ALGOLIA_BRAND_URL}${suggestion.brd_slug}">
          <div class="suggestion-item">
            <span class="suggestion-name">${suggestion._highlightResult.brd_title.value}</span>
          </div>
        </a>
      `,
      // 指定品牌结果插入到左侧品牌区域
      container: () => document.getElementById('brand-section')
    }
  }
]);
</script>

2. 添加CSS样式

通过Flexbox实现左右分栏布局,调整各区域的样式:

/* 自动补全容器 */
.autocomplete-container {
  display: flex;
  min-width: 700px;
  background: #fff;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

/* 左侧栏 */
.autocomplete-left {
  flex: 1;
  padding: 12px;
  border-right: 1px solid #f0f0f0;
}

/* 右侧栏 */
.autocomplete-right {
  flex: 2;
  padding: 12px;
}

/* 左侧区域间距 */
.left-section {
  margin-bottom: 16px;
}

/* 建议项样式 */
.suggestion-item {
  display: flex;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid #f5f5f5;
  cursor: pointer;
}

.suggestion-item:hover {
  background-color: #fafafa;
}

/* 产品图片样式 */
.suggestion-image {
  width: 48px;
  height: 48px;
  object-fit: cover;
  border-radius: 4px;
  margin-right: 10px;
}

/* 建议标题样式 */
.suggestion-header {
  margin-bottom: 8px;
}

.gcom__typeahead-results-heading {
  font-size: 14px;
  font-weight: 600;
  color: #666;
  margin: 0;
}

/* 建议文本样式 */
.suggestion-name {
  display: block;
  font-size: 14px;
  color: #333;
}

.suggestion-description {
  display: block;
  font-size: 12px;
  color: #999;
  margin-top: 4px;
}

关键说明

  • 自定义容器模板:通过templates.container创建左右分栏的DOM结构,为分类、品牌、产品分别预留独立的渲染节点。
  • 指定数据源容器:每个数据源的templates.container函数返回对应的DOM元素,确保不同类型的搜索结果渲染到正确的区域。
  • Flexbox布局:使用Flexbox实现左右分栏,通过flex属性调整左右栏的宽度比例,同时添加样式优化交互体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:23:09