Как можно окружить несколько входов из формы тегом div? - PullRequest
2 голосов
/ 24 мая 2011

В настоящее время я работаю над приложением rails, которое имеет общий шаблон для полей во многих формах и во многих полях одинаковой формы.Это шаблон:

<%= simple_form_for(@evaluation) do |f| %>
  <%= f.error_notification %>

  <div class="toggle">

    <div class="toggle_selector">
      <%= f.input :was_answered, :as => :radio, :collection => [:yes, :no, '?'] %>
    </div>

    <div class="toggle_content">
      <%= f.input :name %>
      <%= f.input :answer %>
      <%= f.input :score %>
    </div>

  </div>

  <div class="actions">
    <%= f.button :submit %>
  </div>
<% end %>

Существует основной тег div, который окружает два других элемента div.Div toggle_content делается видимым или нет, с использованием javascript, на основе значения из входных данных в div toggle_selector.

Я попытался извлечь пару помощников, которые бы принимали входные данные в качестве параметров и выводили желаемый вывод:

def toggling_field_for form, selector, &block                            
  content_tag :div, :class => 'toggle' do                                
    %{#{toggle_selector form, selector}                                  
      #{toggle_content &block if block_given?}                           
    }.html_safe                                                          
  end                                                                    
end                                                                      

private                                                                  

def toggle_selector form, selector                                       
    content_tag :div, :class => 'toggle_selector' do                     
      form.input selector, :as => :radio, :collection => [:yes, :no, '?']
    end                                                                  
end                                                                      

def toggle_content                                                       
  content_tag :div, :class => 'toggle_content' do                        
    yield if block_given?                                                
  end                                                                    
end            

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

Кто-нибудь может дать подсказку о лучшем решении для их рефакторинга, чтобы иметь возможность принимать более одного ввода в элементе toggle_content div?

Отредактировано: проблема решена с помощью вспомогательного метода capture вместо простого yield.Код получился так у помощника:

def toggling_field_for form, selector, &block
  content_tag :div, :class => 'toggle' do
    %{#{toggle_selector form, selector}
      #{toggle_content &block}
    }.html_safe
  end
end

private

def toggle_content &block
  content_tag :div, capture(&block), :class => 'toggle_content'
end

И вызывался так на каждой форме:

    <%= toggling_field_for f, :was_answered, do %>
        <%= f.input :name %>
        <%= f.input :answer %>
        <%= f.input :score %>
    <% end %>

Спасибо, мошь!

1 Ответ

1 голос
/ 24 мая 2011

С Rails 3 ваш код должен работать с небольшой модификацией: попробуйте изменить

def toggle_content                                                       
  content_tag :div, :class => 'toggle_content' do                        
    yield if block_given?                                                
  end                                                                    
end

на

def toggle_content(&block)
  content_tag :div, :class => 'toggle_content' do                        
    capture(&block) if block_given?
  end                                                                    
end

Я не уверен, но вы, вероятно, можете удалить block_given?пункт в этом случае.

...