2012-03-26 34 views
9

Tôi đã sử dụng Formtastic một thời gian, và nó thật tuyệt vời để đẩy nhanh quá trình triển khai biểu mẫu. Tuy nhiên, tôi có một trường hợp đặc biệt mà tôi cần thêm một số tùy chỉnh trong những gì được hiển thị trong biểu mẫu của tôi. Cụ thể, trường là biểu mẫu tải lên tệp để tải lên hình ảnh và trên biểu mẫu chỉnh sửa, tôi muốn hiển thị hình thu nhỏ của phiên bản hiện tại của hình ảnh đã được tải lên.Có cách nào tốt hơn cho đầu vào Formtastic tùy chỉnh này trong Rails không?

Desired Form Output

Tôi đã có làm việc này, nhưng nó đòi hỏi mà tôi sử dụng đánh dấu HTML tùy chỉnh, có nghĩa là bất cứ lúc nào Formtastic thay đổi định dạng đầu ra, tôi cần phải cập nhật phù hợp với HTML của tôi. Đây là những gì tôi đã có ngay bây giờ:

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

Lý tưởng nhất, nó sẽ được tốt đẹp để làm một cái gì đó nhiều hơn như sau, nơi input_html được giả định là HTML được tạo ra cho các đầu vào, gợi ý, v.v .:

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

Có điều gì như thế này đã tồn tại không? Hoặc là có một lựa chọn tương tự mà sẽ làm cho cuộc sống của tôi dễ dàng hơn?

Trả lời

20

Vâng, tôi tự giải quyết điều này. Như thường lệ xảy ra khi tôi đăng ở đây. : P

Đối với bất kỳ ai muốn làm điều gì đó tương tự, tôi đã tạo loại đầu vào tùy chỉnh bắt nguồn từ đầu vào tệp của 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 

Bây giờ tôi chỉ có thể tạo ra một đầu vào của loại này theo cách sau:

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

Tùy chọn, thẻ :image có thể chấp nhận một trong số:

  • một Proc, mà đi thông số đối tượng của biểu mẫu,
  • một Biểu tượng, là tên phương thức trên đối tượng,
  • bất kỳ thứ gì khác, được chuyển đổi thành chuỗi và được giả định đại diện cho URL.

Ngoài ra, tôi có thể sử dụng tùy chọn :image_html để xác định các lớp học HTML, id, vv

+4

Yup, có vẻ tốt. Tôi có rất nhiều đầu vào tùy chỉnh thực hiện các công cụ như thế này hoặc hiển thị giá trị dưới dạng Chuỗi trong đầu vào bị tắt. –

+3

Tôi mới chỉnh sửa/thêm vào mã nguồn. Bạn đã đặt lớp AttachmentInput ở đâu? Bạn đã đặt một lớp học trong thư mục lib thư của bạn?Bạn đã đặt nó vào thư mục đầu vào chưa? Nếu trong thư mục đầu vào, bạn quản lý các phiên bản khác nhau như thế nào? Điều gì sẽ xảy ra nếu Justin cập nhật mã cơ sở? – ebbflowgo

+0

@ebbflowgo, tôi đã dán mã ở trên vào 'app/input/attachment_input.rb' và nó hoạt động. – ShadSterling

7

Ở dưới cùng của các tài liệu Formtastic tại https://github.com/justinfrench/formtastic#modified--custom-inputs:

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

Không đủ cho một giải pháp đầy đủ , nhưng sau khi root thông qua các nguồn formtastic cho cảm hứng đã có thể đến với những điều sau đây là làm việc tốt cho tôi.

trong app/đầu vào/label_input.rb:

class LabelInput 
    include Formtastic::Inputs::Base 

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

xảy ra để được sử dụng ActiveAdmin, trong biểu mẫu của trang:

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 
Các vấn đề liên quan