I need to add a class to the input/textarea/etc when the form is rendered and that field has an error.
<input type="text" class="custom-error-class" />
Is there an easy way to append to SimpleForm's list of CSS classes, but only when the field's corresponding object is an error?
I was having the same problem. My solution for this:
I created a new class StringInput (which overrides the original one) and copied the implementation out of the rdoc. I patched that code to check if there are errors on the field itself, if so I add a class invalid.
Because I wanted to use the wrapper options I added a error_class attribute into my initializer.
The full code:
app/inputs/string_input.rb
class StringInput < SimpleForm::Inputs::StringInput
def input(wrapper_options = nil)
unless string?
input_html_classes.unshift("string")
input_html_options[:type] ||= input_type if html5?
end
input_html_classes << wrapper_options[:error_class] if has_errors?
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
@builder.text_field(attribute_name, merged_input_options)
end
end
config/initializers/simple_form.rb
SimpleForm.setup do |config|
config.error_notification_class = 'alert alert-danger'
config.button_class = 'waves-effect waves-light btn'
config.wrappers tag: :div, class: :input, error_class: :"error-field" do |b|
# Form extensions
b.use :html5
b.optional :pattern
b.use :maxlength
b.use :placeholder
b.use :readonly
# Form components
b.use :label
b.use :input, class: 'validate', error_class: 'invalid'
b.use :hint, wrap_with: { tag: :span, class: :hint }
b.use :error, wrap_with: { tag: :span, class: :error }
end
end
This adds a defined error class onto all of your string inputs.
simple_form adds field_with_errors
class to the wrapper element. You can use this to make your input look different:
.field_with_errors input { ... }
It is easier now with simple_form 3.5.0.
Redefine existing input (i.e. StringInput
) by creating a new class with the same name (docs). Then override input_html_classes
method:
# app/inputs/string_input.rb
class StringInput < SimpleForm::Inputs::StringInput
def input_html_classes
has_errors? ? super.push('custom-error-class') : super
end
end
You can do so using error_html
option:
<%= f.input :attr, error_html: { class: 'custom-error-class' } %>
Thanks @vince-v,
Using your information I came up with this work in progress for applying the error class to all types of inputs, including labels if they're configured with an error_class.
# lib/inputs/base.rb
module SimpleForm
module Inputs
class Base
def merge_wrapper_options(options, wrapper_options)
working_wrapper_options = wrapper_options.dup
if working_wrapper_options
if working_wrapper_options[:error_class] && has_errors?
working_wrapper_options[:class] =
[working_wrapper_options[:class]] + \
[working_wrapper_options[:error_class]]
end
working_wrapper_options.delete(:error_class)
working_wrapper_options.merge(options) do |key, oldval, newval|
case key.to_s
when "class"
Array(oldval) + Array(newval)
when "data", "aria"
oldval.merge(newval)
else
newval
end
end
else
options.dup
end
end
end
end
end
# config/initializers/simple_form.rb
require 'inputs/base.rb
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With