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

Ruby on Rails如何实现文本框与下拉选项结合的输入组件?

Hey there! Let's figure out how to swap those static select dropdowns for flexible input components that let users either type custom values or pick from predefined options—exactly like a datalist, perfect for your vehicle filters (price, year, km). Here are a few practical approaches tailored for your Rails app:


1. Native HTML5 <datalist> (Zero Dependencies, Quick Win)

This is the simplest option since it’s built directly into browsers, no extra libraries needed. Users can type freely or select from your predefined options, just like you want.

Rails View Example

Replace your select_tag inputs with text_field_tag paired with a <datalist>:

<%= form_tag(filter_vehicles_path, method: 'get') do %>
  <!-- Price Filters -->
  <span>Preço</span>
  <%= text_field_tag :price_start, params[:price_start], list: 'price-options', placeholder: "--de--" %>
  <datalist id="price-options">
    <% ["250 EUR", "500 EUR", "1000 EUR", ..., "200 000 EUR"].each do |price| %>
      <option value="<%= price %>"><%= price %></option>
    <% end %>
  </datalist>
  <%= text_field_tag :price_ending, params[:price_ending], list: 'price-options', placeholder: "--até--" %>

  <!-- Year Filters -->
  <span>Ano</span>
  <%= text_field_tag :year_start, params[:year_start], list: 'year-options', placeholder: "--de--" %>
  <datalist id="year-options">
    <% ["1990", "1980", "1970", ..., "1900"].each do |year| %>
      <option value="<%= year %>"><%= year %></option>
    <% end %>
  </datalist>
  <%= text_field_tag :year_ending, params[:year_ending], list: 'year-options', placeholder: "--até--" %>

  <!-- KM Filters -->
  <span>Quilómetros</span>
  <%= text_field_tag :kms_start, params[:kms_start], list: 'kms-options', placeholder: "--de--" %>
  <datalist id="kms-options">
    <% ["5 000 km", "10 000 km", ..., "500 000 km"].each do |km| %>
      <option value="<%= km %>"><%= km %></option>
    <% end %>
  </datalist>
  <%= text_field_tag :kms_end, params[:kms_end], list: 'kms-options', placeholder: "--até--" %>

  <%= submit_tag "Pesquisar" %>
<% end %>

Key Notes

  • Pros: No extra code to install, lightweight, works on all modern browsers.
  • Cons: Limited styling control (browser default styles vary), no advanced features like search.
  • Parameter Cleaning: Since users might type values with units (like "1500 EUR"), you’ll need to strip non-numeric characters before passing to your named_scope:
    # In your VehiclesController#filter action
    price_start = params[:price_start]&.gsub(/\D/, '').to_i # Removes EUR, spaces, etc.
    price_ending = params[:price_ending]&.gsub(/\D/, '').to_i
    year_start = params[:year_start]&.gsub(/\D/, '').to_i
    kms_start = params[:kms_start]&.gsub(/\D/, '').to_i
    
    @vehicles = Vehicle.price_start(price_start).price_ending(price_ending)...
    

2. Frontend UI Libraries (Better Styling & Interaction)

If you want consistent cross-browser styling, searchable options, and more control, use a library like Select2 or Chosen. Both support custom user input while keeping predefined dropdown options.

Select2 Example

  1. Install via Yarn:
    yarn add select2
    
  2. Import in your JS/CSS:
    // app/javascript/packs/application.js
    import 'select2';
    import 'select2/dist/css/select2.css';
    
    document.addEventListener('DOMContentLoaded', () => {
      $('.select2-filter').select2({
        placeholder: function() {
          $(this).data('placeholder');
        },
        allowClear: true,
        tags: true // Lets users type custom values
      });
    });
    
  3. Update your Rails view:
    <span>Preço</span>
    <%= select_tag :price_start, options_for_select(["250 EUR", ..., "200 000 EUR"], params[:price_start]),
      prompt: "--de--",
      class: "select2-filter",
      data: { placeholder: "--de--" } %>
    <%= select_tag :price_ending, options_for_select(["250 EUR", ..., "200 000 EUR"], params[:price_ending]),
      prompt: "--até--",
      class: "select2-filter",
      data: { placeholder: "--até--" } %>
    

Chosen Example

Similar to Select2, but with a simpler API:

  1. Install via Yarn:
    yarn add chosen-js
    
  2. Import and initialize:
    // app/javascript/packs/application.js
    import 'chosen-js';
    import 'chosen-js/chosen.css';
    
    document.addEventListener('DOMContentLoaded', () => {
      $('.chosen-filter').chosen({
        allow_single_deselect: true,
        enable_search_threshold: 10, // Shows search box when there are many options
        search_contains: true
      });
    });
    
  3. View code:
    <%= select_tag :price_start, options_for_select(["250 EUR", ...], params[:price_start]),
      prompt: "--de--",
      class: "chosen-filter" %>
    

3. Rails-Specific Gems (Seamless Integration)

If you prefer using Rails form helpers with minimal setup, pair Simple Form with the libraries above. For example:

<%= simple_form_for :filter, url: filter_vehicles_path, method: :get do |f| %>
  <%= f.input :price_start, as: :select, 
    collection: ["250 EUR", ..., "200 000 EUR"],
    include_blank: "--de--",
    input_html: { class: "select2-filter", data: { tags: true } } %>
<% end %>

Final Tips for Your named_scope

Make sure your scopes handle empty values gracefully to avoid invalid SQL:

# In your Vehicle model
scope :price_start, ->(price) { where('price >= ?', price) if price.present? }
scope :price_ending, ->(price) { where('price <= ?', price) if price.present? }
scope :year_start, ->(year) { where('year >= ?', year) if year.present? }
scope :kms_start, ->(kms) { where('kms >= ?', kms) if kms.present? }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:09:10