Использование двух отдельных полей для одного и того же параметра в обработчике формы Rails?

Я новичок в Rails и исправляю сайт Rails 2. У меня есть форма, которая позволяет пользователю добавлять информацию для начального местоположения (: начало) ЛИБО с вводом ИЛИ с выпадающим полем. Тем не менее, я обнаружил, что когда я включаю оба варианта, только раскрывающийся список (который идет последним) представляет данные, в то время как ввод игнорируется. Как правильно включить оба варианта?

МОЙ ВЗГЛЯД

    <% form_for @newsavedmap, :html=>{:id=>'createaMap'} do |f| %>
    <%= f.error_messages %>
    <p>Enter a street address, city, and state:
    <%= f.text_field :start, {:id=>"startinput", :size=>50}%></p>
    <p>Or, select a location from the list:
    <%= f.select :start, options_for_select(@itinerary.locations), {:include_blank => true }, {:id=>"startdrop"} %>      

    <input type="submit" id="savethismap" value="Save Map">
    <% end %>

1 ответ

Решение

Одним из способов достижения этого является использование виртуальных атрибутов. Поскольку оба поля соответствуют одному и тому же атрибуту, вам придется выбрать, какое из них использовать.

# app/models/newsavedmap.rb
class Newsavedmap < ActiveRecord::Base
  ...
  attr_accessible :start_text, :start_select
  ...

  def start_text=(value)
    @start_text = value if value
    prepare_start
  end

  def start_select=(value)
    @start_select = value if value
    prepare_start
  end

  # start_text will fall back to self.start if @start_text is not set
  def start_text
    @start_text || self.start
  end

  # start_select will fall back to self.start if @start_select is not set
  def start_select
    @start_select || self.start
  end

private 
  def prepare_start
    # Pick one of the following or use however you see fit.
    self.start = start_text if start_text
    self.start = start_select if start_select
  end
end

Тогда ваша форма должна использовать виртуальные атрибуты:

<%= f.text_field :start_text, {:id=>"startinput", :size=>50}%></p>
<p>Or, select a location from the list:
<%= f.select :start_select, options_for_select(@itinerary.locations), {:include_blank => true }, {:id=>"startdrop"} %>

Другие варианты:

  1. Используйте text_field в качестве основного и обновите его значение выбранной опцией, если пользователь выбирает опцию.
  2. Добавьте скрытое поле в форму и используйте JavaScript, чтобы обновить значение скрытого поля при обновлении текста text_field или выбрать изменения параметров
Другие вопросы по тегам