2012-03-26 14 views
9

Używam Formtastic już od jakiegoś czasu i świetnie nadaje się do przyspieszenia wdrażania formularzy. Jednak mam specjalny przypadek, w którym potrzebuję więcej personalizacji w tym, co jest wyświetlane w moim formularzu. W szczególności pole to formularz przesyłania plików do przesyłania zdjęć, a na formularzu edycji chcę pokazać miniaturę aktualnej wersji obrazu, który został przesłany.Czy istnieje lepsze podejście do tego niestandardowego wejścia Formtastic w Railsach?

Desired Form Output

mam tej pracy, ale to wymaga, że ​​mogę używać niestandardowych znaczników HTML, co oznacza, że ​​za każdym razem Formtastic zmienia format wyjściowy, muszę zaktualizować pasujący HTML. Oto co mam teraz:

<%= form.inputs do %> 
    <% if form.object.new_record? -%> 
     <%= form.input :image, :required => true, :hint => 'Maximum size of 3MB. JPG, GIF, PNG.' %> 
    <% else -%> 
     <li class="file input required" id="profile_image_input"> 
      <label class="label" for="profile_image">Image</label> 
      <%= image_tag form.object.image.url(:thumb), :class => 'attachment' %> 
      <%= form.file_field :image %> 
      <p class="inline-hints">Maximum size of 3MB. JPG, GIF, PNG.</p> 
     </li> 
    <% end -%> 
<% end %> 

Idealnie byłoby miło zrobić coś więcej jak poniżej, gdzie input_html zakłada być wygenerowany HTML do wejścia, podpowiedzi itp .:

<%= form.inputs do %> 
    <%= form.input :image, :required => true, :hint => 'Maximum size of 3MB. JPG, GIF, PNG.' do |input_html| %> 
     <%= image_tag form.object.image.url(:thumb), :class => 'attachment' unless form.object.new_record? %> 
     <%= input_html %> 
    <% end %> 
<% end %> 

Czy coś takiego już istnieje? A może jest inna podobna opcja, która ułatwi mi życie?

Odpowiedz

20

Oczywiście sam to rozwiązałem. Jak zwykle, kiedy zamieszczam tutaj. : P

Dla każdego, kto chciałby zrobić coś podobnego, stworzyłem niestandardowy typ wejścia wyprowadzony z pliku wejściowego Formtastic.

class AttachmentInput < Formtastic::Inputs::FileInput 
    def image_html_options 
    {:class => 'attachment'}.merge(options[:image_html] || {}) 
    end 

    def to_html 
    input_wrapping do 
     label_html << 
     image_html << 
     builder.file_field(method, input_html_options) 
    end 
    end 

protected 

    def image_html 
    return "".html_safe if builder.object.new_record? 

    url = case options[:image] 
    when Symbol 
     builder.object.send(options[:image]) 
    when Proc 
     options[:image].call(builder.object) 
    else 
     options[:image].to_s 
    end 

    builder.template.image_tag(url, image_html_options).html_safe 
    end 
end 

Teraz mogę tylko tworzyć wejście tego typu w następujący sposób:

<%= form.input :image, :as => :attachment, 
         :required => true, 
         :hint => 'Maximum size of 3MB. JPG, GIF, PNG.', 
         :image => proc { |o| o.image.url(:thumb) } %> 

Opcjonalnie tag :image może przyjąć jedną z:

  • Proc, który przechodzi obiekt obiektu param,
  • a Symbol, który jest nazwą metody na obiekcie,
  • cokolwiek innego, które jest konwertowane na ciąg znaków i zakłada się, że reprezentuje adres URL.

Dodatkowo mogę wykorzystać opcję :image_html do określania klas HTML, identyfikatory itp

+4

Tak, wygląda dobrze. Mam wiele niestandardowych danych wejściowych, które robią takie rzeczy, lub wyświetlają wartość jako ciąg w zablokowanym wejściu. –

+3

Jestem nowy w edycji/dodawaniu do kodu źródłowego. Gdzie umieściłeś klasę AttachmentInput? Czy umieściłeś klasę w swoim folderze rails?Czy umieściłeś go w folderze wejściowym? Jeśli w folderze wejściowym w jaki sposób zarządzasz różnymi wersjami? Co by się stało, gdyby Justin zaktualizował bazę kodów? – ebbflowgo

+0

@ebbflowgo, Wkleiłem powyższy kod do 'app/inputs/attachment_input.rb' i to działa. – ShadSterling

7

Na dole Formtastic docs na https://github.com/justinfrench/formtastic#modified--custom-inputs:

Create a file in app/inputs with a filename ending in _input.rb 

nie wystarcza na pełne rozwiązanie , ale po zakorzenieniu się przez źródło inspiracji dla formtastic udało mi się wymyślić następujące rozwiązania, które działają dobrze dla mnie.

w app/wejść/label_input.rb:

class LabelInput 
    include Formtastic::Inputs::Base 

    def to_html 
     input_wrapping do 
      label_html << 
      "#{@object.send(method)}" 
     end 
    end 
    end 

zdarzyć się przy użyciu ActiveAdmin w formularzu na stronie:

form do |f| 
    f.inputs do 
    f.input :project 
    f.input :date_consumed 
    f.input :total_consumed 
    f.input :computed_waste, :as => :label 
    f.actions 
    end 
end 
Powiązane problemy