足跡を残しておく。
HTMLの構造が違う
https://getbootstrap.com/docs/4.0/components/forms/#server-side
invalid-feedback
などとりあえず形が違う。
config/initializers/simple_form_boosstrap.rb
を編集する。自分のところでは下記のようになった。error_class
の名前を is-invalid
にしたり、 エラー時のspanのクラスをinvalid-feedback
にしたり。
horizontal_formがデフォルトになっていたり、:full_error
になっているのはこちらの都合なので、適宜直していただければ。
# Use this setup block to configure all options available in SimpleForm.
# @see https://suin.io/546
SimpleForm.setup do |config|
config.error_notification_class = 'alert alert-danger'
config.button_class = 'btn btn-default'
config.boolean_label_class = nil
config.wrappers :vertical_form, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.use :placeholder
b.optional :maxlength
b.optional :minlength
b.optional :pattern
b.optional :min_max
b.optional :readonly
b.use :label, class: 'control-label'
b.use :input, class: 'form-control'
b.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
config.wrappers :vertical_file_input, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.use :placeholder
b.optional :maxlength
b.optional :minlength
b.optional :readonly
b.use :label, class: 'control-label'
b.use :input
b.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
config.wrappers :vertical_boolean, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.optional :readonly
b.wrapper tag: 'div', class: 'checkbox' do |ba|
ba.use :label_input
end
b.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.optional :readonly
b.use :label, class: 'control-label'
b.use :input
b.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
config.wrappers :horizontal_form, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.use :placeholder
b.optional :maxlength
b.optional :minlength
b.optional :pattern
b.optional :min_max
b.optional :readonly
b.use :label, class: 'col-sm-3 control-label'
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
ba.use :input, class: 'form-control'
ba.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
end
config.wrappers :horizontal_file_input, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.use :placeholder
b.optional :maxlength
b.optional :minlength
b.optional :readonly
b.use :label, class: 'col-sm-3 control-label'
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
ba.use :input
ba.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
end
config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.optional :readonly
b.wrapper tag: 'div', class: 'col-sm-offset-3 col-sm-9' do |wr|
wr.wrapper tag: 'div', class: 'checkbox' do |ba|
ba.use :label_input
end
wr.use :error, wrap_with: { tag: 'span', class: 'help-block' }
wr.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
end
config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.optional :readonly
b.use :label, class: 'col-sm-3 control-label'
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
ba.use :input
ba.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
end
config.wrappers :inline_form, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.use :placeholder
b.optional :maxlength
b.optional :minlength
b.optional :pattern
b.optional :min_max
b.optional :readonly
b.use :label, class: 'sr-only'
b.use :input, class: 'form-control'
b.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
config.wrappers :multi_select, tag: 'div', class: 'form-group row', error_class: 'is-invalid' do |b|
b.use :html5
b.optional :readonly
b.use :label, class: 'control-label col-sm-3'
b.wrapper tag: 'div', class: 'form-inline col-sm-9' do |ba|
ba.use :input, class: 'form-control'
ba.use :full_error, wrap_with: { tag: 'span', class: 'invalid-feedback' }
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
end
# Wrappers for forms and inputs using the Bootstrap toolkit.
# Check the Bootstrap docs (http://getbootstrap.com)
# to learn about the different styles for forms and inputs,
# buttons and other elements.
config.default_wrapper = :horizontal_form
config.wrapper_mappings = {
check_boxes: :horizontal_radio_and_checkboxes,
radio_buttons: :horizontal_radio_and_checkboxes,
file: :horizontal_file_input,
boolean: :horizontal_boolean,
datetime: :multi_select,
date: :multi_select,
time: :multi_select
}
end
バリデーションが飾られない
上記をやるだけでは画面にフィードバックも出ないし、色分けもされない。
とりあえず、formに was-validated
を付けると表示されるようにはなるので、下記のようなヘルパーを書いた。多分SimpleFormがすぐに追随すると思う(これは無駄な努力感)。
module ApplicationHelper
def simple_form_ex_for(record, options = {}, &block)
classes = ['form-horizontal']
if record.is_a?(Array)
classes.push('was-validated') if record.last.try(:errors).present?
else
classes.push('was-validated') if record.try(:errors).present?
end
simple_form_for(record, html: {class: classes.join(' ')}, &block)
end
end
invalidなのにグリーンの枠
form-control:valid
は、ブラウザ側のバリデーションのセレクタだが、これが悪さしてしまう様子。よくわからなくて、下記のようなscssを書いて逃げた。
/* for bootstrap4 validation */
form.was-validated {
.is-invalid {
.form-control {
border-color: #dc3545;
}
}
}
おしまいに
やりたいこと出来たのだけど、教材の内容で使おうとしていたのでこれはオーバースペック。おとなしくBootstrap3にすることにした。