Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updating formtastic

  • Loading branch information...
commit fe93d8ab072c136f9b536051ba886b40756b12cb 1 parent be0f497
@jgdavey authored
View
174 vendor/plugins/formtastic/README.textile
@@ -42,34 +42,34 @@ I also wrote the accompanying HTML output I expected, favoring something very si
h2. It's better than _SomeOtherFormBuilder_ because...
-* it can handle @belongs_to@ associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model
-* it can handle @has_many@ and @has_and_belongs_to_many@ associations (like Post has_many :tags), rendering a multi-select with choices from the child models
-* it's Rails 2.3-ready (including nested forms)
+* it can handle @belongs_to@ associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
+* it can handle @has_many@ and @has_and_belongs_to_many@ associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
+* it's Rails 2.3-ready (including nested forms).
* it has internationalization (I18n)!
-* it's _really_ quick to get started with a basic form in place (4 lines), then go back to add in more detail if you need it
-* there's heaps of elements, id and class attributes for you to hook in your CSS and JS
-* it handles real world stuff like inline hints, inline error messages & help text
-* it doesn't hijack or change any of the standard Rails form inputs, so you can still use them as expected (even mix and match)
-* it's got absolutely awesome spec coverage
-* there's a bunch of people using and working on it (it's not just one developer building half a solution)
+* it's _really_ quick to get started with a basic form in place (4 lines), then go back to add in more detail if you need it.
+* there's heaps of elements, id and class attributes for you to hook in your CSS and JS.
+* it handles real world stuff like inline hints, inline error messages & help text.
+* it doesn't hijack or change any of the standard Rails form inputs, so you can still use them as expected (even mix and match).
+* it's got absolutely awesome spec coverage.
+* there's a bunch of people using and working on it (it's not just one developer building half a solution).
h2. Why?
-* web apps = lots of forms
-* forms are so friggin' boring to code
-* semantically rich & accessible forms really are possible
-* the "V" is way behind the "M" and "C" in Rails' MVC – it's the ugly sibling
-* best practices and common patterns have to start somewhere
-* i need a challenge
+* web apps = lots of forms.
+* forms are so friggin' boring to code.
+* semantically rich & accessible forms really are possible.
+* the "V" is way behind the "M" and "C" in Rails' MVC – it's the ugly sibling.
+* best practices and common patterns have to start somewhere.
+* i need a challenge.
h2. Opinions
-* it should be easier to do things the right way than the wrong way
-* sometimes _more mark-up_ is better
-* elements and attribute hooks are _gold_ for stylesheet authors
-* make the common things we do easy, yet still ensure uncommon things are still possible
+* it should be easier to do things the right way than the wrong way.
+* sometimes _more mark-up_ is better.
+* elements and attribute hooks are _gold_ for stylesheet authors.
+* make the common things we do easy, yet still ensure uncommon things are still possible.
h2. Documentation
@@ -79,13 +79,13 @@ RDoc documentation _should_ be automatically generated after each commit and mad
h2. Installation
-The gem is hosted on gemcutter, so if you haven't already, add it as a gem source:
+The gem is hosted on gemcutter, so *if you haven't already*, add it as a gem source:
<pre>
sudo gem sources -a http://gemcutter.org/
</pre>
-Then install the Formtastic gem:q
+Then install the Formtastic gem:
<pre>
sudo gem install formtastic
@@ -93,11 +93,11 @@ Then install the Formtastic gem:q
Optionally, run @./script/generate formtastic@ to copy the following files into your app:
-* config/initializers/formtastic.rb (a commented out Formtastic config initializer)
-* public/stylesheets/formtastic.css
-* public/stylesheets/formtastic_changes.css
+* @config/initializers/formtastic.rb@ - a commented out Formtastic config initializer
+* @public/stylesheets/formtastic.css@
+* @public/stylesheets/formtastic_changes.css@
-A proof-of-concept stylesheet is provided which you can include in your layout. Customization is best achieved by overriding these styles in an additional stylesheet so that the Formtastic styles can be updated without clobbering your changes. If you want to use these stylesheets, add both to your layout:
+A proof-of-concept stylesheet is provided which you can include in your layout. Customization is best achieved by overriding these styles in an additional stylesheet so that the Formtastic styles can be updated without clobbering your changes. If you want to use these stylesheets, add both to your layout:
<pre>
<%= stylesheet_link_tag "formtastic" %>
@@ -109,7 +109,7 @@ h2. Usage
Forms are really boring to code... you want to get onto the good stuff as fast as possible.
-This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord belongs_to association), followed by a submit button:
+This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord @belongs_to@-association), followed by a submit button:
<pre>
<% semantic_form_for @user do |form| %>
@@ -127,7 +127,7 @@ If you want to specify the order of the fields, skip some of the fields or even
<% end %>
</pre>
-If you want control over the input type Formtastic uses for each field, you can expand the @inputs@ and @buttons@ blocks. This specifies the :section input should be a set of radio buttons (rather than the default select box), and that the :created_at field should be a string (rather than the default datetime selects):
+If you want control over the input type Formtastic uses for each field, you can expand the @inputs@ and @buttons@ blocks. This specifies the @:section@ input should be a set of radio buttons (rather than the default select box), and that the @:created_at@ field should be a string (rather than the default datetime selects):
<pre>
<% semantic_form_for @post do |form| %>
@@ -165,14 +165,13 @@ If you want to customize the label text, or render some hint text below the fiel
<% end %>
</pre>
-
Nested forms (Rails 2.3) are also supported. You can do it in the Rails way:
<pre>
<% semantic_form_for @post do |form| %>
<%= form.inputs :title, :body, :created_at %>
<% form.semantic_fields_for :author do |author| %>
- <%= author.inputs :first_name, :last_name, :name => 'Author' %>
+ <%= author.inputs :first_name, :last_name, :name => "Author" %>
<% end %>
<%= form.buttons %>
<% end %>
@@ -188,7 +187,7 @@ Or the Formtastic way with the @:for@ option:
<% end %>
</pre>
-When working in has many association, you can even supply "%i" in your fieldset name that it will be properly interpolated with the child index. For example:
+When working in has many association, you can even supply @"%i"@ in your fieldset name that it will be properly interpolated with the child index. For example:
<pre>
<% semantic_form_for @post do |form| %>
@@ -199,7 +198,7 @@ When working in has many association, you can even supply "%i" in your fieldset
</pre>
-Customize HTML attributes for any input using the @:input_html@ option. Typically his is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like "autogrow":http://plugins.jquery.com/project/autogrow textareas:
+Customize HTML attributes for any input using the @:input_html@ option. Typically his is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like "autogrow":http://plugins.jquery.com/project/autogrow textareas:
<pre>
<% semantic_form_for @post do |form| %>
@@ -221,8 +220,8 @@ The same can be done for buttons with the @:button_html@ option:
<% end %>
</pre>
-Customize the HTML attributes for the @<li>@ wrapper around every input with the @:wrapper_html@ option hash. There's one special key in the hash (:class), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like "required string error")
-
+Customize the HTML attributes for the @<li>@ wrapper around every input with the @:wrapper_html@ option hash. There's one special key in the hash (@:class@), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like @"required string error"@)
+
<pre>
<% semantic_form_for @post do |form| %>
<%= form.input :title, :wrapper_html => { :class => "important" } %>
@@ -233,36 +232,33 @@ Customize the HTML attributes for the @<li>@ wrapper around every input with the
</pre>
-
h2. The Available Inputs
-* :select (a select menu) - default for ActiveRecord associations (belongs_to, has_many, has_and_belongs_to_many)
-* :check_boxes (a set of check_box inputs) - alternative to :select has_many and has_and_belongs_to_many associations
-* :radio (a set of radio inputs) - alternative to :select for ActiveRecord belongs_to associations
-* :time_zone (a select input) - default for :string column types with 'time_zone' in the method name
-* :password (a password input) - default for :string column types with 'password' in the method name
-* :text (a textarea) - default for :text column types
-* :date (a date select) - default for :date column types
-* :datetime (a date and time select) - default for :datetime and :timestamp column types
-* :time (a time select) - default for :time column types
-* :boolean (a checkbox) - default for :boolean column types
-* :string (a text field) - default for :string column types
-* :numeric (a text field, like string) - default for :integer, :float and :decimal column types
-* :file (a file field) - default for paperclip or attachment_fu attributes
-* :country (a select menu of country names) - default for :string columns named "country", requires a country_select plugin to be installed
-* :hidden (a hidden field) - creates a hidden field (added for compatibility)
-
-
-The documentation is pretty good for each of these (what it does, what the output is, what the options are, etc) so go check it out.
+The Formtastic input types:
+
+* @:select@ - a select menu. Default for ActiveRecord associations: @belongs_to@, @has_many@, and @has_and_belongs_to_many@.
+* @:check_boxes@ - a set of check_box inputs. Alternative to @:select@ for ActiveRecord-associations: @has_many@, and @has_and_belongs_to_many@.
+* @:radio@ - a set of radio inputs. Alternative to @:select@ for ActiveRecord-associations: @belongs_to@.
+* @:time_zone@ - a select input. Default for column types: @:string@ with name matching @"time_zone"@.
+* @:password@ - a password input. Default for column types: @:string@ with name matching @"password"@.
+* @:text@ - a textarea. Default for column types: @:text@.
+* @:date@ - a date select. Default for column types: @:date@.
+* @:datetime@ - a date and time select. Default for column types: @:datetime@ and @:timestamp@.
+* @:time@ - a time select. Default for column types: @:time@.
+* @:boolean@ - a checkbox. Default for column types: @:boolean@.
+* @:string@ - a text field. Default for column types: @:string@.
+* @:numeric@ - a text field (just like string). Default for column types: @:integer@, @:float@, and @:decimal@.
+* @:file@ - a file field. Default for file-attachment attributes matching: "paperclip":http://github.com/thoughtbot/paperclip or "attachment_fu":http://github.com/technoweenie/attachment_fu.
+* @:country@ - a select menu of country names. Default for column types: :string with name @"country"@ - requires a *country_select* plugin to be installed.
+* @:hidden@ - a hidden field. Creates a hidden field (added for compatibility).
+
+The documentation is pretty good for each of these (what it does, what the output is, what the options are, etc.) so go check it out.
h2. Internationalization (I18n)
-Formtastic got some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling @object.human_name and @object.human_attribute_name(attr) respectively. There are a few words specific to Formtastic that can be translated. See lib/locale/en.yml for more information.
-
+h3. Basic Localization
-h3. Label/Hint-localization
-
-Formtastic supports localized *labels* and *hints* using the I18n API for more advanced usage. Your forms can now be DRYer and more flexible than ever, and still fully localized. This is how:
+Formtastic got some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling @@object.human_name@ and @@object.human_attribute_name(attr)@ respectively. There are a few words specific to Formtastic that can be translated. See @lib/locale/en.yml@ for more information.
Basic localization (labels only, with ActiveRecord):
@@ -274,17 +270,19 @@ Basic localization (labels only, with ActiveRecord):
<% end %>
</pre>
-*Note:* This is perfectly fine if you just want your labels to be translated using *ActiveRecord I18n attribute translations*, and you don't use input hints. But what if you do? And what if you don't want same labels in all forms?
+*Note:* This is perfectly fine if you just want your labels/attributes and/or models to be translated using *ActiveRecord I18n attribute translations*, and you don't use input hints and legends. But what if you do? And what if you don't want same labels in all forms?
+
+h3. Enhanced Localization (Formtastic I18n API)
-Enhanced localization (labels + hints + titles/legends, with Formtastic):
+Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the I18n API for more advanced usage. Your forms can now be DRYer and more flexible than ever, and still fully localized. This is how:
-1. Enable I18n lookups by default (@config/initializers/formtastic.rb@):
+*1. Enable I18n lookups by default (@config/initializers/formtastic.rb@):*
<pre>
Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
</pre>
-2. Add some cool label-translations/variants (@config/locale/en.yml@):
+*2. Add some cool label-translations/variants (@config/locale/en.yml@):*
<pre>
en:
@@ -301,24 +299,30 @@ Enhanced localization (labels + hints + titles/legends, with Formtastic):
post:
title: "Choose a good title for you post."
body: "Write something inspiring here."
+ actions:
+ create: "Create my {{model}}"
+ update: "Save changes"
+ dummie: "Launch!"
</pre>
*Note:* We are using English here still, but you get the point.
-3. ...and now you'll get:
+*3. ...and now you'll get:*
<pre>
- <% semantic_form_for @post do |form| %>
+ <% semantic_form_for Post.new do |form| %>
<% inputs do %>
<%= form.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for you post."
<%= form.input :body %> # => :label => "Write something...", :hint => "Write something inspiring here."
<%= form.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
<% end %>
- ...
+ <% buttons do %>
+ <%= form.commit_button %> # => "Create my {{model}}"
+ <% end %>
<% end %>
</pre>
-4. Localized titles (a.k.a. legends):
+*4. Localized titles (a.k.a. legends):*
_Note: Slightly different because Formtastic can't guess how you group fields in a form._
@@ -331,7 +335,7 @@ _Note: Slightly different because Formtastic can't guess how you group fields in
<% end %>
</pre>
-5. Override I18n settings:
+*5. Override I18n settings:*
<pre>
<% semantic_form_for @post do |form| %>
@@ -340,7 +344,9 @@ _Note: Slightly different because Formtastic can't guess how you group fields in
<%= form.input :body, :hint => false %> # => :label => "Write something..."
<%= form.input :section, :label => 'Some section' %> # => :label => 'Some section'
<% end %>
- # ...
+ <% buttons do %>
+ <%= form.commit_button :dummie %> # => "Launch!"
+ <% end %>
<% end %>
</pre>
@@ -359,23 +365,25 @@ If I18n-lookups is disabled, i.e.:
<%= form.input :body, :label => true %> # => :label => "Write something..."
<%= form.input :section, :label => true %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
<% end %>
- # ...
+ % buttons do %>
+ <%= form.commit_button true %> # => "Save changes" (if we are in edit that is...)
+ <% end %>
<% end %>
</pre>
-6. Advanced I18n lookups
+*6. Advanced I18n lookups*
For more flexible forms; Formtastic find translations using a bottom-up approach taking the following variables in account:
* @MODEL@, e.g. "post"
* @ACTION@, e.g. "edit"
-* @ATTRIBUTE@, e.g. "title"
+* @KEY/ATTRIBUTE@, e.g. "title", :my_custom_key, ...
...in the following order:
-1. @formtastic.{titles,labels,hints}.MODEL.ACTION.ATTRIBUTE@ # By model and action
-2. @formtastic.{titles,labels,hints}.MODEL.ATTRIBUTE@ # By model
-3. @formtastic.{titles,labels,hints}.ATTRIBUTE@ # Global default
+1. @formtastic.{titles,labels,hints,actions}.MODEL.ACTION.ATTRIBUTE@ - by model and action
+2. @formtastic.{titles,labels,hints,actions}.MODEL.ATTRIBUTE@ - by model
+3. @formtastic.{titles,labels,hints,actions}.ATTRIBUTE@ - global default
...which means that you can define translations like this:
@@ -395,41 +403,41 @@ For more flexible forms; Formtastic find translations using a bottom-up approach
body: "Edit body"
</pre>
-*Note:* For @title@: ATTRIBUTE is a KEY chosen by you, e.g. in step 4 example above: @:post_details@.
+Values for @labels@/@hints@/@actions@ are can take values: @String@ (explicit value), @Symbol@ (i18n-lookup-key relative to the current "type", e.g. actions:), @true@ (force I18n lookup), @false@ (force no I18n lookup). Titles (legends) can only take: @String@ and @Symbol@ - true/false have no meaning.
h2. ValidationReflection plugin
-If you have the "ValidationReflection":http://github.com/redinger/validation_reflection plugin installed, you won't have to specify the :required option (it checks the validations on the model instead).
+If you have the "ValidationReflection":http://github.com/redinger/validation_reflection plugin installed, you won't have to specify the @:required@ option (it checks the validations on the model instead).
h2. Configuration
-Run @./script/generate formtastic@ to copy a commented out config file into @config/initializers/formtastic.rb@. You can "view the configuration file on GitHub":http://github.com/justinfrench/formtastic/blob/master/generators/formtastic/templates/formtastic.rb
+Run @./script/generate formtastic@ to copy a commented out config file into @config/initializers/formtastic.rb@. You can "view the configuration file on GitHub":http://github.com/justinfrench/formtastic/blob/master/generators/formtastic/templates/formtastic.rb
h2. Status
-Formtastic has been in active development for about a year. We've just recently jumped to an 0.9 version number, signalling that we consider this a 1.0 release candidate, and that the API won't change significantly for the 1.x series.
+Formtastic has been in active development for about a year. We've just recently jumped to an 0.9 version number, signaling that we consider this a 1.0 release candidate, and that the API won't change significantly for the 1.x series.
h2. Dependencies
There are none, but...
-* if you have the "ValidationReflection":http://github.com/redinger/validation_reflection plugin is installed, you won't have to specify the :required option (it checks the validations on the model instead)
-* if you want to use the :country input, you'll need to install the "iso-3166-country-select plugin":http://github.com/rails/iso-3166-country-select (or any other country_select plugin with the same API)
-* rspec, rspec_hpricot_matchers and rcov gems (plus any of their own dependencies) are required for the test suite
+* if you have the "ValidationReflection":http://github.com/redinger/validation_reflection plugin is installed, you won't have to specify the :required option (it checks the validations on the model instead).
+* if you want to use the @:country@ input, you'll need to install the "iso-3166-country-select plugin":http://github.com/rails/iso-3166-country-select (or any other country_select plugin with the same API).
+* "rspec":http://github.com/dchelimsky/rspec/, "rspec_hpricot_matchers":http://rubyforge.org/projects/rspec-hpricot/ and "rcov":http://github.com/relevance/rcov gems (plus any of their own dependencies) are required for the test suite.
h2. Compatibility
-I'm only testing Formtastic with the latest Rails 2.2.x stable release, and it should be fine under Rails 2.3 as well (including nested forms). Patches are welcome to allow backwards compatibility, but I don't have the energy!
+I'm only testing Formtastic with the latest Rails 2.2.x stable release, and it should be fine under Rails 2.3 as well (including nested forms). Patches are welcome to allow backwards compatibility, but I don't have the energy!
h2. Got TextMate?
-Well...there's a TextMate-bundle in town, dedicated to make usage of Formtastic in the TextMate editor even more of a breeze:
+Well...there's a TextMate-bundle in town, dedicated to make usage of Formtastic in the "TextMate":http://macromates.com/ editor even more of a breeze:
"Formtastic.tmbundle":http://github.com/grimen/formtastic_tmbundle
@@ -463,7 +471,7 @@ Please join the "Formtastic Google Group":http://groups.google.com.au/group/form
h2. Project Info
-Formtastic is hosted on Github: http://github.com/justinfrench/formtastic/, where your contributions, forkings, comments and feedback are greatly welcomed.
+Formtastic is hosted on Github: "http://github.com/justinfrench/formtastic":http://github.com/justinfrench/formtastic, where your contributions, forkings, comments and feedback are greatly welcomed.
Copyright (c) 2007-2008 Justin French, released under the MIT license.
View
103 vendor/plugins/formtastic/lib/formtastic.rb
@@ -283,30 +283,55 @@ def buttons(*args, &block)
#
# The value of the button text can be overridden:
#
- # <%= form.commit_button "Go" %> => <input name="commit" type="submit" value="Go" />
+ # <%= form.commit_button "Go" %> => <input name="commit" type="submit" value="Go" class="{create|update|submit}" />
+ # <%= form.commit_button :label => "Go" %> => <input name="commit" type="submit" value="Go" class="{create|update|submit}" />
#
# And you can pass html atributes down to the input, with or without the button text:
#
- # <%= form.commit_button "Go" %> => <input name="commit" type="submit" value="Go" />
- # <%= form.commit_button :class => "pretty" %> => <input name="commit" type="submit" value="Save Post" class="pretty" />
+ # <%= form.commit_button "Go" %> => <input name="commit" type="submit" value="Go" class="{create|update|submit}" />
+ # <%= form.commit_button :class => "pretty" %> => <input name="commit" type="submit" value="Save Post" class="pretty {create|update|submit}" />
#
# You can use the actual <button/> html tag instead the default <input type="submit"/>:
#
- # <%= form.commit_button "Save", :use_button_html => true %> => <button name="commit" type="submit">Go</button>
+ # <%= form.commit_button "Save", :use_button_html => true %> #=> <button name="commit" type="submit">Go</button>
#
def commit_button(*args)
- value = args.first.is_a?(String) ? args.shift : save_or_create_button_text
- options = args.shift || {}
+ options = args.extract_options!
+ text = options.delete(:label) || args.shift
+
+ if @object
+ key = @object.new_record? ? :create : :update
+ object_name = @object.class.human_name
+
+ if key == :update
+ # Note: Fallback on :save-key (deprecated), :update makes more sense in the REST-world.
+ fallback_text = ::I18n.t(:save, :model => object_name, :default => "Save {{model}}", :scope => [:formtastic])
+ ::ActiveSupport::Deprecation.warn "Formtastic I18n: Key 'formtastic.save' is now deprecated in favor 'formtastic.update'."
+ end
+ else
+ key = :submit
+ object_name = @object_name.to_s.send(@@label_str_method)
+ end
+ fallback_text ||= "#{key.to_s.humanize} {{model}}"
+
+ text = (self.localized_string(key, text, :action, :model => object_name) ||
+ ::I18n.t(key, :model => object_name, :default => fallback_text, :scope => [:formtastic])) unless text.is_a?(::String)
+
button_html = options.delete(:button_html) || {}
- button_or_input_tag = begin
- if options.delete(:use_button_tag)
+ button_html.merge!(:class => [button_html[:class], key].compact.join(' '))
+ element_class = ['commit', options.delete(:class)].compact.join(' ') # TODO: Add class reflecting on form action.
+
+ button_content = begin
+ as = options.delete(:as)
+ if as && as.to_sym == :button || options.delete(:use_button_tag)
button_html.merge!(:type => 'submit', :name => 'commit')
- template.content_tag(:button, value, button_html)
+ template.content_tag(:button, text, button_html)
else
- self.submit(value, button_html)
+ self.submit(text, button_html)
end
end
- template.content_tag(:li, button_or_input_tag, :class => "commit")
+
+ template.content_tag(:li, button_content, :class => "commit")
end
# A thin wrapper around #fields_for to set :builder => Formtastic::SemanticFormBuilder
@@ -364,10 +389,12 @@ def label(method, options_or_text=nil, options=nil)
text = options_or_text
options ||= {}
end
-
- text = localized_attribute_string(method, text, :label) || humanized_attribute_name(method)
+ text = localized_string(method, text, :label) || humanized_attribute_name(method)
text += required_or_optional_string(options.delete(:required))
-
+
+ # special case for boolean (checkbox) labels, which have a nested input
+ text = (options.delete(:label_prefix_for_nested_input) || "") + text
+
input_name = options.delete(:input_name) || method
if options.delete(:as_span)
options[:class] ||= 'label'
@@ -433,22 +460,6 @@ def set_options(options)
:as, :hint, :input_html, :label_html, :value_as_class)
end
- # Create a default button text. If the form is working with a object, it
- # defaults to "Create {{model}}" or "Save {{model}}" depending if we are working
- # with a new_record or not.
- #
- # When not working with models, it defaults to "Submit object".
- #
- def save_or_create_button_text(prefix='Submit') #:nodoc:
- if @object
- prefix = @object.new_record? ? 'Create' : 'Save'
- object_name = @object.class.human_name
- else
- object_name = @object_name.to_s.send(@@label_str_method)
- end
- I18n.t(prefix.downcase, :model => object_name, :default => "#{prefix} {{model}}", :scope => [:formtastic])
- end
-
# Determins if the attribute (eg :title) should be considered required or not.
#
# * if the :required option was provided in the options hash, the true/false value will be
@@ -937,8 +948,12 @@ def boolean_input(method, options)
input = self.check_box(method, set_options(options).merge(html_options),
options.delete(:checked_value) || '1', options.delete(:unchecked_value) || '0')
-
- self.label(method, input << self.label(method, options_for_label(options)), options_for_label(options))
+ options = options_for_label(options)
+
+ # the label() method will insert this nested input into the label at the last minute
+ options[:label_prefix_for_nested_input] = input
+
+ self.label(method, options)
end
# Generates an input for the given method using the type supplied with :as.
@@ -961,7 +976,7 @@ def inline_input_for(method, options)
# Generates hints for the given method using the text supplied in :hint.
#
def inline_hints_for(method, options) #:nodoc:
- options[:hint] = localized_attribute_string(method, options[:hint], :hint)
+ options[:hint] = localized_string(method, options[:hint], :hint)
return if options[:hint].blank?
template.content_tag(:p, options[:hint], :class => 'inline-hints')
end
@@ -1013,7 +1028,7 @@ def required_or_optional_string(required) #:nodoc:
#
def field_set_and_list_wrapping(html_options, contents='', &block) #:nodoc:
html_options[:name] ||= html_options.delete(:title)
- html_options[:name] = localized_attribute_string(html_options[:name], html_options[:name], :title) if html_options[:name].is_a?(Symbol)
+ html_options[:name] = localized_string(html_options[:name], html_options[:name], :title) if html_options[:name].is_a?(Symbol)
legend = html_options.delete(:name).to_s
legend %= parent_child_index(html_options[:parent]) if html_options[:parent]
@@ -1244,16 +1259,18 @@ def humanized_attribute_name(method)
#
# NOTE: Generic, but only used for form input labels/hints.
#
- def localized_attribute_string(attr_name, attr_value, i18n_key)
- if attr_value.is_a?(String)
- attr_value
+ def localized_string(key, value, type, options = {})
+ key = value if value.is_a?(::Symbol)
+
+ if value.is_a?(::String)
+ value
else
- use_i18n = attr_value.nil? ? @@i18n_lookups_by_default : (attr_value != false)
-
+ use_i18n = value.nil? ? @@i18n_lookups_by_default : (value != false)
+
if use_i18n
- model_name = @object.class.name.underscore
+ model_name = (@object ? @object.class.name : @object_name.to_s.send(@@label_str_method)).underscore
action_name = template.params[:action].to_s rescue ''
- attribute_name = attr_name.to_s
+ attribute_name = key.to_s
defaults = I18N_SCOPES.collect do |i18n_scope|
i18n_path = i18n_scope.dup
@@ -1265,8 +1282,8 @@ def localized_attribute_string(attr_name, attr_value, i18n_key)
end
defaults << ''
- i18n_value = ::I18n.t(defaults.shift, :default => defaults,
- :scope => "formtastic.#{i18n_key.to_s.pluralize}")
+ i18n_value = ::I18n.t(defaults.shift, options.merge(:default => defaults,
+ :scope => :"formtastic.#{type.to_s.pluralize}"))
i18n_value.blank? ? nil : i18n_value
end
end
View
297 vendor/plugins/formtastic/spec/commit_button_spec.rb
@@ -63,7 +63,7 @@
end
describe 'when the first option is a hash' do
-
+
before do
@new_post.stub!(:new_record?).and_return(false)
semantic_form_for(@new_post) do |builder|
@@ -77,112 +77,225 @@
end
- describe 'when used on an existing record' do
-
- it 'should render an input with a value attribute of "Save Post"' do
- @new_post.stub!(:new_record?).and_return(false)
- semantic_form_for(@new_post) do |builder|
- concat(builder.commit_button)
- end
- output_buffer.should have_tag('li.commit input[@value="Save Post"]')
+ describe 'label' do
+ before do
+ ::Post.stub!(:human_name).and_return('Post')
end
- describe 'when the locale sets the label text' do
- before do
- I18n.backend.store_translations 'en', :formtastic => {:save => 'Save Changes To {{model}}' }
- @new_post.stub!(:new_record?).and_return(false)
- semantic_form_for(@new_post) do |builder|
- concat(builder.commit_button)
+ # No object
+ describe 'when used without object' do
+ describe 'when explicit label is provided' do
+ it 'should render an input with the explicitly specified label' do
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
+ concat(builder.commit_button("Click!"))
+ end
+ output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="submit"]')
end
end
- after do
- I18n.backend.store_translations 'en', :formtastic => {:save => nil}
- end
+ describe 'when no explicit label is provided' do
+ describe 'when no I18n-localized label is provided' do
+ before do
+ ::I18n.backend.store_translations :en, :formtastic => {:submit => 'Submit {{model}}'}
+ end
+
+ after do
+ ::I18n.backend.store_translations :en, :formtastic => {:submit => nil}
+ end
+
+ it 'should render an input with default I18n-localized label (fallback)' do
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag('li.commit input[@value="Submit Post"][@class~="submit"]')
+ end
+ end
- it 'should allow translation of the labels' do
- output_buffer.should have_tag('li.commit input[@value="Save Changes To Post"]')
+ describe 'when I18n-localized label is provided' do
+ before do
+ ::I18n.backend.store_translations :en,
+ :formtastic => {
+ :actions => {
+ :submit => 'Custom Submit',
+ :post => {
+ :submit => 'Custom Submit {{model}}'
+ }
+ }
+ }
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
+ end
+
+ it 'should render an input with localized label (I18n)' do
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Submit Post"][@class~="submit"]})
+ end
+
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
+ ::I18n.backend.store_translations :en,
+ :formtastic => {
+ :actions => {
+ :post => {
+ :submit => nil
+ }
+ }
+ }
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Submit"][@class~="submit"]})
+ end
+
+ end
end
end
- describe 'when the label text is set for a locale with different word order from the default' do
+ # New record
+ describe 'when used on a new record' do
before do
- I18n.locale = 'ja'
- I18n.backend.store_translations 'ja', :formtastic => {:save => 'Save {{model}}'}
- @new_post.stub!(:new_record?).and_return(false)
- ::Post.stub!(:human_name).and_return('Post')
- semantic_form_for(@new_post) do |builder|
- concat(builder.commit_button)
- end
+ @new_post.stub!(:new_record?).and_return(true)
end
- after do
- I18n.backend.store_translations 'ja', :formtastic => {:save => nil}
- I18n.locale = 'en'
+ describe 'when explicit label is provided' do
+ it 'should render an input with the explicitly specified label' do
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button("Click!"))
+ end
+ output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="create"]')
+ end
end
- it 'should allow the translated label to have a different word order' do
- output_buffer.should have_tag('li.commit input[@value="Save Post"]')
- end
- end
- end
+ describe 'when no explicit label is provided' do
+ describe 'when no I18n-localized label is provided' do
+ before do
+ ::I18n.backend.store_translations :en, :formtastic => {:create => 'Create {{model}}'}
+ end
+
+ after do
+ ::I18n.backend.store_translations :en, :formtastic => {:create => nil}
+ end
+
+ it 'should render an input with default I18n-localized label (fallback)' do
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag('li.commit input[@value="Create Post"][@class~="create"]')
+ end
+ end
- describe 'when used on a new record' do
+ describe 'when I18n-localized label is provided' do
+ before do
+ ::I18n.backend.store_translations :en,
+ :formtastic => {
+ :actions => {
+ :create => 'Custom Create',
+ :post => {
+ :create => 'Custom Create {{model}}'
+ }
+ }
+ }
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
+ end
+
+ it 'should render an input with localized label (I18n)' do
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Create Post"][@class~="create"]})
+ end
+
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
+ ::I18n.backend.store_translations :en,
+ :formtastic => {
+ :actions => {
+ :post => {
+ :create => nil
+ }
+ }
+ }
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Create"][@class~="create"]})
+ end
- it 'should render an input with a value attribute of "Create Post"' do
- @new_post.stub!(:new_record?).and_return(true)
- semantic_form_for(@new_post) do |builder|
- concat(builder.commit_button)
+ end
end
- output_buffer.should have_tag('li.commit input[@value="Create Post"]')
end
- describe 'when the locale sets the label text' do
+ # Existing record
+ describe 'when used on an existing record' do
before do
- I18n.backend.store_translations 'en', :formtastic => {:create => 'Make {{model}}' }
- semantic_form_for(@new_post) do |builder|
- concat(builder.commit_button)
- end
- end
-
- after do
- I18n.backend.store_translations 'en', :formtastic => {:create => nil}
+ @new_post.stub!(:new_record?).and_return(false)
end
- it 'should allow translation of the labels' do
- output_buffer.should have_tag('li.commit input[@value="Make Post"]')
- end
- end
-
- end
-
- describe 'when used without object' do
-
- it 'should render an input with a value attribute of "Submit"' do
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
- concat(builder.commit_button)
+ describe 'when explicit label is provided' do
+ it 'should render an input with the explicitly specified label' do
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button("Click!"))
+ end
+ output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="update"]')
+ end
end
- output_buffer.should have_tag('li.commit input[@value="Submit Project"]')
- end
-
- describe 'when the locale sets the label text' do
- before do
- I18n.backend.store_translations 'en', :formtastic => { :submit => 'Send {{model}}' }
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
- concat(builder.commit_button)
+ describe 'when no explicit label is provided' do
+ describe 'when no I18n-localized label is provided' do
+ before do
+ ::I18n.backend.store_translations :en, :formtastic => {:update => 'Save {{model}}'}
+ end
+
+ after do
+ ::I18n.backend.store_translations :en, :formtastic => {:update => nil}
+ end
+
+ it 'should render an input with default I18n-localized label (fallback)' do
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag('li.commit input[@value="Save Post"][@class~="update"]')
+ end
end
- end
- after do
- I18n.backend.store_translations 'en', :formtastic => {:submit => nil}
- end
+ describe 'when I18n-localized label is provided' do
+ before do
+ ::I18n.backend.store_translations :en,
+ :formtastic => {
+ :actions => {
+ :update => 'Custom Save',
+ :post => {
+ :update => 'Custom Save {{model}}'
+ }
+ }
+ }
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
+ end
+
+ it 'should render an input with localized label (I18n)' do
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Save Post"][@class~="update"]})
+ end
+
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
+ ::I18n.backend.store_translations :en,
+ :formtastic => {
+ :actions => {
+ :post => {
+ :update => nil
+ }
+ }
+ }
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button)
+ end
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Save"][@class~="update"]})
+ end
- it 'should allow translation of the labels' do
- output_buffer.should have_tag('li.commit input[@value="Send Project"]')
+ end
end
end
-
end
describe 'when given the option "use_button_tag"' do
@@ -223,5 +336,31 @@
end
-end
+ describe 'when using :as option for html tag choice' do
+
+ context ":as => :button" do
+ before do
+ @new_post.stub!(:new_record?).and_return(false)
+ @button_text = "Click to Save"
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.commit_button(@button_text, :as => :button, :button_html => {:class => "pretty"}))
+ end
+ end
+
+ it "should render a button tag rather than input[type=submit]" do
+ output_buffer.should have_tag('li button[@type="submit"]')
+ output_buffer.should_not have_tag('li input[@type="submit"]')
+ end
+ it "should deal with the button_html options hash" do
+ output_buffer.should have_tag('li button.pretty', /#{@button_text}/)
+ end
+
+ it "should have name=\"commit\" by default" do
+ output_buffer.should have_tag('li button[@name"commit"]')
+ end
+
+ end
+ end
+
+end
View
2  vendor/plugins/formtastic/spec/input_spec.rb
@@ -2115,7 +2115,7 @@ def should_be_required(options)
end
it 'should generate a label containing the input' do
- output_buffer.should have_tag('form li label')
+ output_buffer.should have_tag('form li label', :count => 1)
output_buffer.should have_tag('form li label[@for="post_allow_comments"]')
output_buffer.should have_tag('form li label', /Allow comments/)
output_buffer.should have_tag('form li label input[@type="checkbox"]')
View
2  vendor/plugins/formtastic/spec/spec.opts
@@ -0,0 +1,2 @@
+--color
+--format=progress
View
4 vendor/plugins/formtastic/spec/test_helper.rb
@@ -156,6 +156,4 @@ def protect_against_forgery?
end
-
-
-
+::ActiveSupport::Deprecation.silenced = true
Please sign in to comment.
Something went wrong with that request. Please try again.