Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ If your form is not backed by a model, use the `bootstrap_form_tag`. Usage of th
<% end %>
```

### bootstrap_form_with

If you are using Rails >= 5.1 just use the `bootstrap_form_with` helper. Here's an example:

```erb
<%= bootstrap_form_with(model: @user) do |f| %>
<%= f.email_field :email %>
<% end %>
```

## Form Helpers

This gem wraps the following Rails form helpers:
Expand Down
24 changes: 24 additions & 0 deletions lib/bootstrap_form/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,29 @@ def temporarily_disable_field_error_proc
ensure
ActionView::Base.field_error_proc = original_proc
end

if ::Rails::VERSION::STRING >= '5.1'
def bootstrap_form_with(options = {}, &block)
options.reverse_merge!({builder: BootstrapForm::FormBuilder})

options[:html] ||= {}
options[:html][:role] ||= 'form'

layout = case options[:layout]
when :inline
"form-inline"
when :horizontal
"form-horizontal"
end

if layout
options[:html][:class] = [options[:html][:class], layout].compact.join(" ")
end

temporarily_disable_field_error_proc do
form_with(options, &block)
end
end
end
end
end
139 changes: 139 additions & 0 deletions test/bootstrap_form_with_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
require 'test_helper'

if ::Rails::VERSION::STRING >= '5.1'
class BootstrapFormWithTest < ActionView::TestCase
include BootstrapForm::Helper

def setup
setup_test_fixture
end

test "default-style forms" do
expected = %{<form accept-charset="UTF-8" action="/users" data-remote="true" method="post" role="form"><input name="utf8" type="hidden" value="&#x2713;" /></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user) { |f| nil }
end

test "inline-style forms" do
expected = %{<form accept-charset="UTF-8" action="/users" class="form-inline" data-remote="true" method="post" role="form"><input name="utf8" type="hidden" value="&#x2713;" /></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, layout: :inline) { |f| nil }
end

test "horizontal-style forms" do
expected = %{<form role="form" class="form-horizontal" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group"><label class="control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" type="email" value="steve@example.com" name="user[email]" /></div></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, layout: :horizontal) { |f| f.email_field :email }
end

test "existing styles aren't clobbered when specifying a form style" do
expected = %{<form role="form" class="my-style form-horizontal" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group"><label class="control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" type="email" value="steve@example.com" name="user[email]" /></div></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, layout: :horizontal, html: { class: "my-style" }) { |f| f.email_field :email }
end

test "given role attribute should not be covered by default role attribute" do
expected = %{<form role="not-a-form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, html: { role: 'not-a-form'}) {|f| nil}
end

test "errors display correctly and inline_errors are turned off by default when label_errors is true" do
@user.email = nil
@user.valid?

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group has-error"><label class="control-label required" for="user_email">Email can&#39;t be blank, is too short (minimum is 5 characters)</label><input class="form-control" type="text" name="user[email]" /></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, label_errors: true) { |f| f.text_field :email }
end

test "errors display correctly and inline_errors can also be on when label_errors is true" do
@user.email = nil
@user.valid?

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group has-error"><label class="control-label required" for="user_email">Email can&#39;t be blank, is too short (minimum is 5 characters)</label><input class="form-control" type="text" name="user[email]" /><span class="help-block">can&#39;t be blank, is too short (minimum is 5 characters)</span></div></form>ost\" role=\"form\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /></div><div class=\"form-group has-error\"><label class=\"control-label required\" for=\"user_email\">Email can&#39;t be blank, is too short (minimum is 5 characters)</label><input class=\"form-control\" id=\"user_email\" name=\"user[email]\" type=\"text\" /><span class=\"help-block\">can&#39;t be blank, is too short (minimum is 5 characters)</span></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, label_errors: true, inline_errors: true) { |f| f.text_field :email }
end

test "label error messages use humanized attribute names" do
I18n.backend.store_translations(:en, {activerecord: {attributes: {user: {email: 'Your e-mail address'}}}})

@user.email = nil
@user.valid?

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group has-error"><label class="control-label required" for="user_email">Your e-mail address can&#39;t be blank, is too short (minimum is 5 characters)</label><input class="form-control" type="text" name="user[email]" /><span class="help-block">can&#39;t be blank, is too short (minimum is 5 characters)</span></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, label_errors: true, inline_errors: true) { |f| f.text_field :email }

I18n.backend.store_translations(:en, {activerecord: {attributes: {user: {email: nil}}}})
end

test "alert_message contains the error summary when inline_errors are turned off" do
@user.email = nil
@user.valid?

output = bootstrap_form_with(model: @user, inline_errors: false) do |f|
f.alert_message('Please fix the following errors:')
end

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="alert alert-danger"><p>Please fix the following errors:</p><ul class="rails-bootstrap-forms-error-summary"><li>Email can&#39;t be blank</li><li>Email is too short (minimum is 5 characters)</li><li>Terms must be accepted</li></ul></div></form>}
assert_equivalent_xml expected, output
end

test "alert_message allows the error_summary to be turned off" do
@user.email = nil
@user.valid?

output = bootstrap_form_with(model: @user, inline_errors: false) do |f|
f.alert_message('Please fix the following errors:', error_summary: false)
end

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="alert alert-danger"><p>Please fix the following errors:</p></div></form>}
assert_equivalent_xml expected, output
end

test "alert_message allows the error_summary to be turned on with inline_errors also turned on" do
@user.email = nil
@user.valid?

output = bootstrap_form_with(model: @user, inline_errors: true) do |f|
f.alert_message('Please fix the following errors:', error_summary: true)
end

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="alert alert-danger"><p>Please fix the following errors:</p><ul class="rails-bootstrap-forms-error-summary"><li>Email can&#39;t be blank</li><li>Email is too short (minimum is 5 characters)</li><li>Terms must be accepted</li></ul></div></form>}
assert_equivalent_xml expected, output
end

test "custom label width for horizontal forms" do
expected = %{<form role="form" class="form-horizontal" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group"><label class="control-label col-sm-1 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" type="email" value="steve@example.com" name="user[email]" /></div></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, layout: :horizontal) { |f| f.email_field :email, label_col: 'col-sm-1' }
end

test "offset for form group without label respects label width for horizontal forms" do
expected = %{<form role="form" class="form-horizontal" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group"><div class="col-md-10 col-md-offset-2"><input type="submit" name="commit" value="Create User" class="btn btn-default" data-disable-with="Create User" /></div></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, layout: :horizontal, label_col: 'col-md-2', control_col: 'col-md-10') { |f| f.form_group { f.submit } }
end

test "custom input width for horizontal forms" do
expected = %{<form role="form" class="form-horizontal" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group"><label class="control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-5"><input class="form-control" type="email" value="steve@example.com" name="user[email]" /></div></div></form>}
assert_equivalent_xml expected, bootstrap_form_with(model: @user, layout: :horizontal) { |f| f.email_field :email, control_col: 'col-sm-5' }
end

test "the field contains the error and is not wrapped in div.field_with_errors when bootstrap_form_with is used" do
@user.email = nil
@user.valid?

output = bootstrap_form_with(model: @user) do |f|
f.text_field(:email, help: 'This is required')
end

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group has-error"><label class="control-label required" for="user_email">Email</label><input class="form-control" type="text" name="user[email]" /><span class="help-block">can&#39;t be blank, is too short (minimum is 5 characters)</span></div></form>}
assert_equivalent_xml expected, output
end

test "help is preserved when inline_errors: false is passed to bootstrap_form_with" do
@user.email = nil
@user.valid?

output = bootstrap_form_with(model: @user, inline_errors: false) do |f|
f.text_field(:email, help: 'This is required')
end

expected = %{<form role="form" action="/users" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><div class="form-group has-error"><label class="control-label required" for="user_email">Email</label><input class="form-control" type="text" name="user[email]" /><span class="help-block">This is required</span></div></form>}
assert_equivalent_xml expected, output
end
end
end