-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Adding custom input components
You may find yourself wanting to add a custom component to the normally generated set of tags that simple_form creates for each input.
In my case I wanted to show a preview of an uploaded file below the file input. This would show when editing a record with an existing file, or when an error has occured with another part of the form when adding a new record but where a file has been uploaded against that record successfully. See: carrierwave allows you to keep the file in a temporary cache in case of form validation problems on other fields.
First, create a subclass of SimpleForm::Inputs::FileInput
under app/inputs
:
# app/inputs/image_preview_input.rb
class ImagePreviewInput < SimpleForm::Inputs::FileInput
def input(wrapper_options = nil)
# :preview_version is a custom attribute from :input_html hash, so you can pick custom sizes
version = input_html_options.delete(:preview_version)
out = ActiveSupport::SafeBuffer.new # the output buffer we're going to build
# check if there's an uploaded file (eg: edit mode or form not saved)
if object.send("#{attribute_name}?")
# append preview image to output
out << template.image_tag(object.send(attribute_name).tap {|o| break o.send(version) if version}.send('url'))
end
# allow multiple submissions without losing the tmp version
out << @builder.hidden_field("#{attribute_name}_cache").html_safe
# append file input. it will work accordingly with your simple_form wrappers
out << @builder.file_field(attribute_name, input_html_options)
end
end
Optionally, if you want to add a CSS class to all instances of the custom input, you should add input_html_classes.push 'class-name'
.
Then, use it in your form:
<%= simple_form_for @some_model do |f| %>
<!-- we specify the new custom input, and we'll use the 'thumb' version of the carrierwave upload -->
<%= f.input :image, :as => :image_preview, :input_html => {:preview_version => :thumb} %>
<% end %>
If you need a better upload input specifically, you might want to check out the fancy uploads gem.
Your first step is to modify the simple_form initialiser setting config.components to call your custom component:
config.components = [ :placeholder, :label, :hint, :input, :preview, :error ]
You'll find a commented out version of this config option at the top of the file in /config/initializers/simple_form.rb
.
As you can see I've added a component called preview that will show after the input. In my example I've also split out the label and input components (normally label_input) because it suited my form design better.
The next step is to require a file that we're going to store in your /lib
folder that will deal with displaying your custom component. Put it right at the end of the same file /config/initializers/simple_form.rb
.
SimpleForm.setup do |config|
config.components = [ :placeholder, :label, :hint, :input, :preview, :error ]
end
require 'simple_form/preview_component.rb'
Ok now simply make a folder in your /lib
folder called simple_form and make a new file in there called preview_component.rb. Here is the contents of my preview_component.rb file:
module SimpleForm
module Components
module Preview
def preview
if input_type == :file
template.image_tag(object.send("#{attribute_name}_url"), :class => 'file_preview') if object.send("#{attribute_name}?")
end
end
end
end
module Inputs
class Base
include SimpleForm::Components::Preview
end
end
end
In this file we're essentially opening SimpleForm::Inputs::Base
and including SimpleForm::Components::Preview
. This module contains a method preview that first checks if the input we're dealing with is a file input, and if so, adds the preview image.
You have access to template
which allows you to use view helpers, object
which is the overall record object, and attribute_name
which is the name of the attribute currently being dealt with. There are more variables and objects at your disposal, see: https://github.com/plataformatec/simple_form/blob/master/lib/simple_form/inputs/base.rb#L29
Many thanks to Carlos Antonio da Silva who provided me with most of this information to get me started.
This page was created by the OSS community and might be outdated or incomplete. Feel free to improve or update this content according to the latest versions of SimpleForm and Rails to help the next developer who visits this wiki after you.
Keep in mind to maintain the guides as simple as possible and to avoid additional dependencies that might be specific to your application or workflow (such as Haml, RSpec, Guard and similars).