不确定这是合适的地方分享我的方式混合三个,但我没有博客或git帐户,问题花了我2天的时间来解决,所以也许有一个挂在那里。我想分享我的解决方案。
1。 simple_form
simple_form还没有支持bootstrap 3,但有人已经解决了这个问题。您可以在以下链接中找到它:
SimpleForm default input class
https://github.com/plataformatec/simple_form/issues/316
#simple_form_bootstrap.rb in the initializers
inputs = %w[
CollectionSelectInput
DateTimeInput
FileInput
GroupedCollectionSelectInput
NumericInput
PasswordInput
RangeInput
StringInput
TextInput
]
inputs.each do |input_type|
superclass = "SimpleForm::Inputs::#{input_type}".constantize
new_class = Class.new(superclass) do
def input_html_classes
super.push('form-control')
end
end
Object.const_set(input_type, new_class)
end
# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
config.boolean_style = :nested
config.wrappers :bootstrap3, tag: 'div', class: 'form-group', error_class: 'has-error',
defaults: { input_html: { class: 'default_class' } } do |b|
b.use :html5
b.use :min_max
b.use :maxlength
b.use :placeholder
b.optional :pattern
b.optional :readonly
b.use :label_input
b.use :hint, wrap_with: { tag: 'span', class: 'help-block' }
b.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' }
end
config.wrappers :bootstrap3_horizontal, tag: 'div', class: 'form-group', error_class: 'has-error',
defaults: { input_html: { class: 'default-class '}, wrapper_html: { class: "col-lg-10 col-md-10"} } do |b|
b.use :html5
b.use :min_max
b.use :maxlength
b.use :placeholder
b.optional :pattern
b.optional :readonly
b.use :label
b.wrapper :right_column, tag: :div do |component|
component.use :input
end
b.use :hint, wrap_with: { tag: 'span', class: 'help-block' }
b.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' }
end
config.wrappers :group, tag: 'div', class: "form-group", error_class: 'has-error',
defaults: { input_html: { class: 'default-class '} } do |b|
b.use :html5
b.use :min_max
b.use :maxlength
b.use :placeholder
b.optional :pattern
b.optional :readonly
b.use :label
b.use :input, wrap_with: { class: "input-group" }
b.use :hint, wrap_with: { tag: 'span', class: 'help-block' }
b.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' }
end
config.default_wrapper = :bootstrap3
end
2。图
请记住,html代码的bootstrap3结构与bootstrap2不同。 基本上,形式句子是:
=simple_form_for(resource,
wrapper: :bootstrap3_horizontal, //I'm using bootstrap3_horizontal layout. you can find it in the initializer.
defaults: {right_column_html: {class: "col-lg-4 col-md-4"},
label_html: {class: "col-lg-3 col-md-3"} }
第3。客户端验证
我安装了2个宝石进行验证 - client_side_validations - client_side_validations-simple_form
请注意,这两颗宝石不再维护。但是,我的应用程序太过分了,无法改为另一种方法。
如果您仍想继续,请将资产复制到应用程序:
rails g client_side_validations:copy_assets
打开rails.validations.simple_form.js,将其更改为流动:
(function() {
ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = {
add: function(element, settings, message) {
return this.wrappers[settings.wrapper].add.call(this, element, settings, message);
},
remove: function(element, settings) {
return this.wrappers[settings.wrapper].remove.call(this, element, settings);
},
wrappers: {
//default wrapper is not changed.
"default": {
add: function(element, settings, message) {
var errorElement, wrapper;
errorElement = element.parent().find("" + settings.error_tag + "." + settings.error_class);
wrapper = element.closest(settings.wrapper_tag);
if (!(errorElement[0] != null)) {
errorElement = $("<" + settings.error_tag + "/>", {
"class": settings.error_class,
text: message
});
wrapper.append(errorElement);
}
wrapper.addClass(settings.wrapper_error_class);
return errorElement.text(message);
},
remove: function(element, settings) {
var errorElement, wrapper;
wrapper = element.closest("" + settings.wrapper_tag + "." + settings.wrapper_error_class);
wrapper.removeClass(settings.wrapper_error_class);
errorElement = wrapper.find("" + settings.error_tag + "." + settings.error_class);
return errorElement.remove();
}
},
// I'm using horizontal form layout, so the wrapper is bootstrap3_horizontal, which is in the initializer and view form.
bootstrap3_horizontal: { // changed
add: function(element, settings, message) {
var errorElement, errorSpan, wrapper_class_element, wrapper_tag_element;
errorSpan = settings.error_tag+"[class=\'"+settings.error_class+"\']"; //changed
errorElement = element.parent().find(errorSpan); //changed
if (!(errorElement[0] != null)) {
wrapper_tag_element = element.closest(settings.wrapper_tag);
errorElement = $("<" + settings.error_tag + "/>", {
"class": settings.error_class,
text: message
});
wrapper_tag_element.append(errorElement);
}
wrapper_class_element = element.closest("." + settings.wrapper_class);
wrapper_class_element.addClass(settings.wrapper_error_class);
return errorElement.text(message);
},
remove: function(element, settings) {
var errorElement, errorSpan, wrapper_class_element, wrapper_tag_element;
wrapper_class_element = element.closest("." + settings.wrapper_class + "." + settings.wrapper_error_class);
wrapper_tag_element = element.closest(settings.wrapper_tag);
wrapper_class_element.removeClass(settings.wrapper_error_class);
errorSpan = settings.error_tag+"[class=\'"+settings.error_class+"\']"; //changed
errorElement = wrapper_tag_element.find(errorSpan); //changed
return errorElement.remove();
}
}
}
};
}).call(this);