2012-03-26 6 views
9

Utilizzo Formtastic da un po 'di tempo, ed è ottimo per velocizzare l'implementazione dei moduli. Tuttavia, ho un caso speciale in cui ho bisogno di un po 'più di personalizzazione in ciò che viene visualizzato nel mio modulo. Nello specifico, il campo è un modulo di caricamento file per caricare immagini e sul modulo di modifica, voglio mostrare una miniatura della versione corrente dell'immagine che è stata caricata.Esiste un approccio migliore per questo input Formtastic personalizzato in Rails?

Desired Form Output

Ho questo lavoro, ma è necessario che io uso markup HTML personalizzato, il che significa che ogni volta che Formtastic cambia il formato di output, ho bisogno di aggiornare il mio corrispondente HTML. Ecco quello che ho in questo momento:

<%= 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 %> 

Idealmente, sarebbe bello fare qualcosa di più come il seguente, dove input_html si presume essere il codice HTML generato per l'ingresso, suggerimento, ecc .:

<%= 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 %> 

Esiste già qualcosa del genere? O c'è un'altra opzione simile che renderà la mia vita più facile?

risposta

20

Bene, l'ho risolto io stesso, naturalmente. Come sempre accade quando pubblico qui. : P

Per chiunque volesse fare qualcosa di simile, ho creato un tipo di input personalizzato derivato dall'input del file di 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 

Ora posso solo creare un ingresso di questo tipo, nel modo seguente:

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

Facoltativamente, il tag :image può accettare uno dei seguenti:

  • un Proc, che passa param dell'oggetto form,
  • a Simbolo, che è un nome di metodo sull'oggetto,
  • qualsiasi altra cosa, che viene convertita in una stringa e si presume che rappresenti l'URL.

Inoltre, posso utilizzare l'opzione :image_html per specificare le classi HTML, id, ecc

+4

Yup, sembra buono. Ho molti input personalizzati che fanno cose del genere, o visualizzo il valore come String in un input disabilitato. –

+3

Sono nuovo alla modifica/aggiunta al codice sorgente. Dove hai inserito la classe AttachmentInput? Hai messo un corso nella cartella lib delle tue rotaie?L'hai messo nella cartella degli input? Se nella cartella degli input come gestisci le diverse versioni? Cosa succederebbe se Justin avesse aggiornato il codice base? – ebbflowgo

+0

@ebbflowgo, ho incollato il codice sopra in 'app/inputs/attachment_input.rb' e funziona. – ShadSterling

7

In fondo i documenti Formtastic a https://github.com/justinfrench/formtastic#modified--custom-inputs:

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

non è sufficiente per una soluzione completa , ma dopo aver fatto il tifo per la fonte formtante dell'ispirazione, sono riuscito a trovare ciò che sta funzionando bene per me.

in app/ingressi/label_input.rb:

class LabelInput 
    include Formtastic::Inputs::Base 

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

capita di essere utilizzando ActiveAdmin, nel modulo a pagina:

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