Есть ли лучший подход для этого пользовательского Formtastic ввода в Rails?
Я использую Formtastic уже некоторое время, и это отлично подходит для ускорения реализации форм. Однако у меня есть особый случай, когда мне нужна дополнительная настройка в том, что отображается в моей форме. В частности, поле представляет собой форму загрузки файла для загрузки изображений, а в форме редактирования я хочу показать миниатюру текущей версии загруженного изображения.
у меня это работает, но для этого требуется, чтобы я использовал Пользовательский 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 ответов
Ну, я решил это сам, конечно. Как всегда, когда я пишу здесь. : 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, который передает объект формы param,
- символ, который имя метода на объекте,
- что-нибудь еще, которое преобразуется в строку и предполагается представлять URL.
кроме того, я могу использовать :image_html
опция для указания классов HTML, идентификаторов и т. д.
в нижней части Formtastic docs в https://github.com/justinfrench/formtastic#modified--custom-inputs:
Create a file in app/inputs with a filename ending in _input.rb
недостаточно для полного решения, но после укоренения через formtastic источник для вдохновения смог придумать следующее, которое хорошо работает для меня.
в приложении / входы / 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