Есть ли лучший подход для этого пользовательского ввода Formtastic в Rails? - PullRequest
9 голосов
/ 26 марта 2012

Я уже некоторое время использую Formtastic, и он отлично подходит для ускорения реализации форм.Тем не менее, у меня есть особый случай, когда мне нужно больше настроек, что отображается в моей форме.В частности, поле представляет собой форму загрузки файла для загрузки изображений, а в форме редактирования я хочу показать эскиз текущей версии загруженного изображения.

Desired Form Output

У меня это работает, но требуется, чтобы я использовал пользовательскую разметку HTML, а это означает, что каждый раз, когда Formtastic меняет формат вывода, мне нужно обновить свой соответствующий HTML.Вот что я получил прямо сейчас:

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

В идеале было бы неплохо сделать что-то похожее на следующее, где предполагается, что input_html - это сгенерированный HTML для ввода, подсказки и т. Д..:

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

Что-нибудь подобное уже существует?Или есть другой подобный вариант, который облегчит мою жизнь?

Ответы [ 2 ]

20 голосов
/ 26 марта 2012

Ну, я решил это сам, конечно. Как всегда, когда я пишу здесь. : P

Для тех, кто хочет сделать что-то подобное, я создал собственный тип ввода, полученный из файла ввода 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

Теперь я могу просто создать вход этого типа следующим образом:

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

При желании тег :image может принимать одно из:

  • Proc, который передает параметр объекта формы,
  • Символ, который является именем метода на объекте,
  • все остальное, которое преобразуется в строку и считается URL-адресом.

Кроме того, я могу использовать опцию :image_html для указания классов HTML, идентификаторов и т. Д.

7 голосов
/ 29 октября 2013

В нижней части документа Formtastic на https://github.com/justinfrench/formtastic#modified--custom-inputs:

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

Недостаточно для полного решения, но после рутирования через форму-источник для вдохновения смог придумать следующее, что хорошо работает для меня.

в приложении / input / label_input.rb:

class LabelInput
  include Formtastic::Inputs::Base

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

случайно использует ActiveAdmin, в форме на странице:

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
...