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

Shopify联系表单添加商品选择下拉框遇显示问题求助

Shopify联系表单自定义商品下拉组件解决方案

问题1:仅显示50个商品的解决

Shopify 默认限制集合产品返回数量为50,使用 paginate 标签可遍历所有产品:

{% paginate collections.all.products by 100 %}
  {% for product in collections.all.products %}
    <!-- 产品渲染逻辑 -->
  {% endfor %}
{% endpaginate %}

注:by 100 表示每页加载100个,可根据总商品数调整,最大支持每页200个

问题2:自定义下拉显示商品图片、标题、价格 + 选中预览

原生 <select> 无法在选项中显示图片,需用HTML+CSS+JS实现自定义下拉组件,同时添加选中预览区域:

完整代码实现

<label for="customProductDropdown">Products</label>
<!-- 自定义下拉容器 -->
<div class="custom-product-dropdown">
  <!-- 下拉触发按钮 -->
  <div class="dropdown-trigger" tabindex="0">
    <span class="selected-text">Choose your product</span>
    <svg class="dropdown-arrow" viewBox="0 0 24 24" width="16" height="16">
      <path d="M7 10l5 5 5-5z"/>
    </svg>
  </div>
  <!-- 下拉选项列表 -->
  <div class="dropdown-options">
    <div class="dropdown-option" data-value="Others - No product-related concerns">
      <span>Others - No product-related concerns</span>
    </div>
    {% paginate collections.all.products by 100 %}
      {% for product in collections.all.products %}
        {% assign featured_img = product.featured_image | img_url: 'small' %}
        <div class="dropdown-option" data-value="{{ product.title }}" data-price="{{ product.price | money }}" data-image="{{ featured_img }}">
          <img src="{{ featured_img }}" alt="{{ product.title }}">
          <div class="product-info">
            <span class="product-title">{{ product.title }}</span>
            <span class="product-price">{{ product.price | money }}</span>
          </div>
        </div>
      {% endfor %}
    {% endpaginate %}
  </div>
</div>
<!-- 选中商品预览区域 -->
<div class="selected-product-preview" style="display: none;">
  <h4>Selected Product:</h4>
  <div class="preview-content">
    <img src="" alt="" class="preview-image">
    <div class="preview-info">
      <span class="preview-title"></span>
      <span class="preview-price"></span>
    </div>
  </div>
</div>
<!-- 隐藏的表单字段,用于提交选中值 -->
<input type="hidden" name="contact[Product]" id="ContactFormProductNameField" required>

<style>
.custom-product-dropdown {
  position: relative;
  margin: 1rem 0;
  width: 100%;
  max-width: 400px;
}
.dropdown-trigger {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.8rem 1rem;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  background: white;
}
.dropdown-trigger:focus {
  outline: 2px solid #007cba;
}
.dropdown-arrow {
  transition: transform 0.2s;
}
.dropdown-arrow.open {
  transform: rotate(180deg);
}
.dropdown-options {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid #ddd;
  border-radius: 4px;
  background: white;
  display: none;
  z-index: 100;
}
.dropdown-options.open {
  display: block;
}
.dropdown-option {
  display: flex;
  align-items: center;
  padding: 0.8rem 1rem;
  cursor: pointer;
  border-bottom: 1px solid #f0f0f0;
}
.dropdown-option:last-child {
  border-bottom: none;
}
.dropdown-option:hover {
  background: #f8f9fa;
}
.dropdown-option img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  margin-right: 1rem;
}
.product-info {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.product-price {
  font-size: 0.9rem;
  color: #555;
}
.selected-product-preview {
  margin-top: 1rem;
  padding: 1rem;
  border: 1px solid #eee;
  border-radius: 4px;
}
.preview-content {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.preview-image {
  width: 60px;
  height: 60px;
  object-fit: cover;
}
.preview-info {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
</style>

<script>
const dropdownTrigger = document.querySelector('.dropdown-trigger');
const dropdownOptions = document.querySelector('.dropdown-options');
const dropdownArrow = document.querySelector('.dropdown-arrow');
const selectedText = document.querySelector('.selected-text');
const hiddenInput = document.getElementById('ContactFormProductNameField');
const previewArea = document.querySelector('.selected-product-preview');
const previewImage = document.querySelector('.preview-image');
const previewTitle = document.querySelector('.preview-title');
const previewPrice = document.querySelector('.preview-price');

// 切换下拉展开/收起
dropdownTrigger.addEventListener('click', () => {
  dropdownOptions.classList.toggle('open');
  dropdownArrow.classList.toggle('open');
});

// 点击选项选择商品
document.querySelectorAll('.dropdown-option').forEach(option => {
  option.addEventListener('click', () => {
    const value = option.dataset.value;
    const price = option.dataset.price;
    const image = option.dataset.image;
    
    // 更新触发按钮文本
    selectedText.textContent = value;
    // 更新隐藏字段值
    hiddenInput.value = value;
    // 关闭下拉
    dropdownOptions.classList.remove('open');
    dropdownArrow.classList.remove('open');
    
    // 更新预览区域
    if (value !== 'Others - No product-related concerns') {
      previewArea.style.display = 'block';
      previewImage.src = image;
      previewImage.alt = value;
      previewTitle.textContent = value;
      previewPrice.textContent = price;
    } else {
      previewArea.style.display = 'none';
    }
  });
});

// 点击外部关闭下拉
document.addEventListener('click', (e) => {
  if (!dropdownTrigger.contains(e.target) && !dropdownOptions.contains(e.target)) {
    dropdownOptions.classList.remove('open');
    dropdownArrow.classList.remove('open');
  }
});
</script>

代码说明

  1. 商品数量限制解决:通过 paginate 标签批量加载产品,突破50个的默认限制
  2. 自定义下拉组件:用div模拟下拉结构,支持显示商品图片、标题、价格,交互更友好
  3. 选中预览功能:选中商品后自动展示在下拉框下方,提升用户体验
  4. 表单兼容性:保留隐藏的原生输入字段,确保选中值能正常提交到Shopify后台

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:01:18