Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

"semantic_errors" helper #60

Merged
merged 2 commits into from

4 participants

@nzaillian

formtastic-bootstrap doesn't seem to contain a bootstrap-friendly "semantic_errors" helper. I needed one so I added it. Renders errors in a bootstrap "alert-error" div. Added specs as well. Here's a screencap (disregard the bit of custom styling for my particular application): http://imgur.com/Xgn9ruz. Merge if you see fit.

.gitignore
@@ -10,3 +10,7 @@ doc
# bundler
.bundle
+
+.idea
+
+log
@sodabrew Collaborator

What are these files?

RubyMine config XML files are kept in ".idea", my respec config writes to a file in "log". You're right, though, should not have committed: probably only relevant for a minority of contributors.

@sodabrew Collaborator

Thanks! Would you mind doing a git commit --amend and pushing a new edition without these?

OK, amended that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@sodabrew
Collaborator

Looks good! Just want to make sure that the gitignores are generally useful.

lib/formtastic-bootstrap/helpers.rb
((6 lines not shown))
autoload :FieldsetWrapper, 'formtastic-bootstrap/helpers/fieldset_wrapper'
- # autoload :FileColumnDetection, 'formtastic/helpers/file_column_detection'
@sodabrew Collaborator

Another question - what's the purpose of removing these commented-out lines?

It just seemed odd to have them there if of no effect, but can put them back if you'd rather that.

@sodabrew Collaborator

I prefer to keep the changes to just the minimum required to implement your functionality. Would you amend the commit here to only change the ErrorsHelper line?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@sodabrew
Collaborator

Hi! @nzaillian pinging to see if you've had time to update your branch? I'm looking forward to merging this PR soon!

@nzaillian

Hey, sorry this all fell by the wayside lately. I found myself needing this helper today again, though and wishing it were in the gem. Let me know if you need any more changes (I'll jump on it sooner this time)

@sodabrew sodabrew merged commit b8a2a4e into from
@djwonk

This commit causes the specs to halt (not just fail).

bundle exec rake spec

formtastic-bootstrap/lib/formtastic-bootstrap/form_builder.rb:34:in `<class:FormBuilder>': uninitialized constant FormtasticBootstrap::Helpers::ErrorsHelper (NameError)
  from /Users/david/src/formtastic-bootstrap/lib/formtastic-bootstrap/form_builder.rb:3:in `<module:FormtasticBootstrap>'
  from /Users/david/src/formtastic-bootstrap/lib/formtastic-bootstrap/form_builder.rb:1:in `<top (required)>'
  from /Users/david/src/formtastic-bootstrap/lib/formtastic-bootstrap.rb:4:in `<top (required)>'

I'll look into it right now

My pull request is here: #64

@nzaillian nzaillian referenced this pull request
Closed

fix for load error #65

@owocki

i'm not sure if it's because i'm a rails noob or not, but im getting a syntax error here

/Library/Ruby/Gems/1.8/gems/formtastic-bootstrap-2.1.1/lib/formtastic-bootstrap/form_builder.rb:34: /Library/Ruby/Gems/1.8/gems/formtastic-bootstrap-2.1.1/lib/formtastic-bootstrap/helpers/errors_helper.rb:63: syntax error, unexpected ':' (SyntaxError)
          template.content_tag(:ul, {class: "error-list"}) do
                                           ^
/Library/Ruby/Gems/1.8/gems/formtastic-bootstrap-2.1.1/lib/formtastic-bootstrap/helpers/errors_helper.rb:63: syntax error, unexpected '}', expecting kEND
          template.content_tag(:ul, {class: "error-list"}) do
                                                         ^
/Library/Ruby/Gems/1.8/gems/formtastic-bootstrap-2.1.1/lib/formtastic-bootstrap/helpers/errors_helper.rb:70: syntax error, unexpected kEND, expecting $end
    from /Library/Ruby/Gems/1.8/gems/formtastic-bootstrap-2.1.1/lib/formtastic-bootstrap.rb:4:in `require'
    from /Library/Ruby/Gems/1.8/gems/formtastic-bootstrap-2.1.1/lib/formtastic-bootstrap.rb:4
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.5/lib/bundler/runtime.rb:68:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.5/lib/bundler/runtime.rb:68:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.5/lib/bundler/runtime.rb:66:in `each'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.5/lib/bundler/runtime.rb:66:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.5/lib/bundler/runtime.rb:55:in `each'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.5/lib/bundler/runtime.rb:55:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.5/lib/bundler.rb:119:in `require'
    from /Users/kevinowocki/Sites/slowordown/config/application.rb:7
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.13/lib/rails/commands.rb:53:in `require'
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.13/lib/rails/commands.rb:53
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.13/lib/rails/commands.rb:50:in `tap'
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.13/lib/rails/commands.rb:50
    from script/rails:6:in `require'
    from script/rails:6

Rails 3.2.13

Collaborator

This is Ruby 1.9 syntax. Pushing a fix right now so that it will run on Ruby 1.8.

Collaborator

Fixed in version 2.1.3, just posted to Rubygems.

you'z a boss. thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 17, 2013
  1. @nzaillian
Commits on Apr 4, 2013
  1. @nzaillian
This page is out of date. Refresh to see the latest.
View
2  README.md
@@ -54,7 +54,7 @@ made to generate the HTML expected by Bootstrap while still generating the rich
<%= f.input :title, :hint => "This is the title!" %>
<% end %>
<%= f.actions do %>
- <%= f.submit %>
+ <%= f.action :submit %>
<% end %>
<% end %>
View
1  lib/formtastic-bootstrap/form_builder.rb
@@ -31,6 +31,7 @@ def self.default_hint_class=(hint_class)
include FormtasticBootstrap::Helpers::InputHelper # Revisit
include FormtasticBootstrap::Helpers::InputsHelper
+ include FormtasticBootstrap::Helpers::ErrorsHelper
include FormtasticBootstrap::Helpers::ActionHelper
include FormtasticBootstrap::Helpers::ActionsHelper
# include Formtastic::Helpers::ErrorsHelper
View
70 lib/formtastic-bootstrap/helpers/errors_helper.rb
@@ -0,0 +1,70 @@
+module FormtasticBootstrap
+ module Helpers
+ module ErrorsHelper
+ include Formtastic::Helpers::FileColumnDetection
+ include Formtastic::Helpers::Reflection
+ include Formtastic::LocalizedString
+
+ INLINE_ERROR_TYPES = [:sentence, :list, :first]
+
+ # Generates a bootstrap error alert element containing
+ # an unordered list of error messages on the base object and optionally for a given
+ # set of named attribute. This is idea for rendering a block of error messages at the top of
+ # the form for hidden/special/virtual attributes (the Paperclip Rails plugin does this), or
+ # errors on the base model.
+ #
+ # A hash can be used as the last set of arguments to pass HTML attributes to the `<ul>`
+ # wrapper.
+ #
+ # @example A list of errors on the base model
+ # <%= semantic_form_for ... %>
+ # <%= f.semantic_errors %>
+ # ...
+ # <% end %>
+ #
+ # @example A list of errors on the base and named attributes
+ # <%= semantic_form_for ... %>
+ # <%= f.semantic_errors :something_special %>
+ # ...
+ # <% end %>
+ #
+ # @example A list of errors on the base model, with custom HTML attributes
+ # <%= semantic_form_for ... %>
+ # <%= f.semantic_errors :class => "awesome" %>
+ # ...
+ # <% end %>
+ #
+ # @example A list of errors on the base model and named attributes, with custom HTML attributes
+ # <%= semantic_form_for ... %>
+ # <%= f.semantic_errors :something_special, :something_else, :class => "awesome", :onclick => "Awesome();" %>
+ # ...
+ # <% end %>
+ def semantic_errors(*args)
+ html_options = args.extract_options!
+ args = args - [:base]
+ full_errors = args.inject([]) do |array, method|
+ attribute = localized_string(method, method.to_sym, :label) || humanized_attribute_name(method)
+ errors = Array(@object.errors[method.to_sym]).to_sentence
+ errors.present? ? array << [attribute, errors].join(" ") : array ||= []
+ end
+ full_errors << @object.errors[:base]
+ full_errors.flatten!
+ full_errors.compact!
+ return nil if full_errors.blank?
+
+ if html_options[:class].blank?
+ html_options[:class] = "alert alert-error"
+ else
+ html_options[:class] = "alert alert-error " + html_options[:class]
+ end
+
+ template.content_tag(:div, html_options) do
+ template.content_tag(:button, "&times;".html_safe, :class => "close", "data-dismiss" => "alert") +
+ template.content_tag(:ul, {class: "error-list"}) do
+ Formtastic::Util.html_safe(full_errors.map { |error| template.content_tag(:li, Formtastic::Util.html_safe(error)) }.join)
+ end
+ end
+ end
+ end
+ end
+end
View
112 spec/helpers/semantic_errors_helper_spec.rb
@@ -0,0 +1,112 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe 'FormtasticBootstrap::FormBuilder#semantic_errors' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ @title_errors = ['must not be blank', 'must be awesome']
+ @base_errors = ['base error message', 'nasty error']
+ @base_error = 'one base error'
+ @errors = mock('errors')
+ @new_post.stub!(:errors).and_return(@errors)
+ end
+
+ describe 'when there is only one error on base' do
+ before do
+ @errors.stub!(:[]).with(errors_matcher(:base)).and_return(@base_error)
+ end
+
+ it 'should render an alert with an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors.should have_tag('.alert.alert-error ul.error-list li', @base_error)
+ end
+ end
+ end
+
+ describe 'when there is more than one error on base' do
+ before do
+ @errors.stub!(:[]).with(errors_matcher(:base)).and_return(@base_errors)
+ end
+
+ it 'should render an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors.should have_tag('.alert.alert-error ul.error-list')
+ @base_errors.each do |error|
+ builder.semantic_errors.should have_tag('.alert.alert-error ul.error-list li', error)
+ end
+ end
+ end
+ end
+
+ describe 'when there are errors on title' do
+ before do
+ @errors.stub!(:[]).with(errors_matcher(:title)).and_return(@title_errors)
+ @errors.stub!(:[]).with(errors_matcher(:base)).and_return([])
+ end
+
+ it 'should render an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ title_name = builder.send(:localized_string, :title, :title, :label) || builder.send(:humanized_attribute_name, :title)
+ builder.semantic_errors(:title).should have_tag('.alert.alert-error ul.error-list li', title_name << " " << @title_errors.to_sentence)
+ end
+ end
+ end
+
+ describe 'when there are errors on title and base' do
+ before do
+ @errors.stub!(:[]).with(errors_matcher(:title)).and_return(@title_errors)
+ @errors.stub!(:[]).with(errors_matcher(:base)).and_return(@base_error)
+ end
+
+ it 'should render an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ title_name = builder.send(:localized_string, :title, :title, :label) || builder.send(:humanized_attribute_name, :title)
+ builder.semantic_errors(:title).should have_tag('.alert.alert-error ul.error-list li', title_name << " " << @title_errors.to_sentence)
+ builder.semantic_errors(:title).should have_tag('.alert.alert-error ul.error-list li', @base_error)
+ end
+ end
+ end
+
+ describe 'when there are no errors' do
+ before do
+ @errors.stub!(:[]).with(errors_matcher(:title)).and_return(nil)
+ @errors.stub!(:[]).with(errors_matcher(:base)).and_return(nil)
+ end
+
+ it 'should return nil' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors(:title).should be_nil
+ end
+ end
+ end
+
+ describe 'when there is one error on base and options with class is passed' do
+ before do
+ @errors.stub!(:[]).with(errors_matcher(:base)).and_return(@base_error)
+ end
+
+ it 'should render an unordered list with given class' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors(:class => "awesome").should have_tag('.alert.alert-error.awesome ul.error-list li', @base_error)
+ end
+ end
+ end
+
+ describe 'when :base is passed in as an argument' do
+ before do
+ @errors.stub!(:[]).with(errors_matcher(:base)).and_return(@base_error)
+ end
+
+ it 'should ignore :base and only render base errors once' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors(:base).should have_tag('ul li', :count => 1)
+ builder.semantic_errors(:base).should_not have_tag('ul li', "Base #{@base_error}")
+ end
+ end
+ end
+
+end
View
4 vendor/assets/stylesheets/formtastic-bootstrap.css
@@ -1,3 +1,7 @@
.hidden {
display: none;
}
+
+.alert.alert-error .error-list {
+ margin: 0px;
+}
Something went wrong with that request. Please try again.