justinfrench-formtastic 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.textile +9 -3
- data/generators/formtastic_stylesheets/templates/formtastic.css +17 -2
- data/lib/formtastic.rb +184 -39
- data/spec/formtastic_spec.rb +430 -142
- metadata +11 -15
data/README.textile
CHANGED
|
@@ -227,6 +227,7 @@ Customize the HTML attributes for the @<li>@ wrapper around every input with the
|
|
|
227
227
|
h2. The Available Inputs
|
|
228
228
|
|
|
229
229
|
* :select (a select menu) - default for ActiveRecord associations (belongs_to, has_many, has_and_belongs_to_many)
|
|
230
|
+
* :check_boxes (a set of check_box inputs) - alternative to :select has_many and has_and_belongs_to_many associations
|
|
230
231
|
* :radio (a set of radio inputs) - alternative to :select for ActiveRecord belongs_to associations
|
|
231
232
|
* :time_zone (a select input) - default for :string column types with 'time_zone' in the method name
|
|
232
233
|
* :password (a password input) - default for :string column types with 'password' in the method name
|
|
@@ -238,6 +239,9 @@ h2. The Available Inputs
|
|
|
238
239
|
* :string (a text field) - default for :string column types
|
|
239
240
|
* :numeric (a text field, like string) - default for :integer, :float and :decimal column types
|
|
240
241
|
* :file (a file field) - default for paperclip or attachment_fu attributes
|
|
242
|
+
* :country (a select menu of country names) - default for :string columns named "country", requires a country_select plugin to be installed
|
|
243
|
+
* :hidden (a hidden field) - creates a hidden field (added for compatibility)
|
|
244
|
+
|
|
241
245
|
|
|
242
246
|
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.
|
|
243
247
|
|
|
@@ -284,6 +288,9 @@ If you wish, put something like this in config/initializers/formtastic_config.rb
|
|
|
284
288
|
# the input, in the following order: hints, input and errors. You can
|
|
285
289
|
# customize it doing just as below:
|
|
286
290
|
Formtastic::SemanticFormBuilder.inline_order = [:hints, :input, :errors]
|
|
291
|
+
|
|
292
|
+
# Set the default "priority countries" to suit your user base when using :as => :country
|
|
293
|
+
Formtastic::SemanticFormBuilder.priority_countries = ["Australia", "New Zealand"]
|
|
287
294
|
</pre>
|
|
288
295
|
|
|
289
296
|
|
|
@@ -313,6 +320,7 @@ h2. Dependencies
|
|
|
313
320
|
There are none, but...
|
|
314
321
|
|
|
315
322
|
* 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)
|
|
323
|
+
* 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)
|
|
316
324
|
* rspec, rspec_hpricot_matchers and rcov gems (plus any of their own dependencies) are required for the test suite
|
|
317
325
|
|
|
318
326
|
|
|
@@ -342,10 +350,8 @@ A proof-of-concept (very much a work-in-progress) stylesheet is provided which y
|
|
|
342
350
|
|
|
343
351
|
h2. Contributors
|
|
344
352
|
|
|
345
|
-
Formtastic wouldn't be as awesome as it is today if it weren't for the wonderful contributions of these fine, fine coders.
|
|
353
|
+
Formtastic is maintained by "Justin French":http://justinfrench.com and "José Valim":http://github.com/josevalim, but it wouldn't be as awesome as it is today if it weren't for the wonderful contributions of these fine, fine coders.
|
|
346
354
|
|
|
347
|
-
* "Justin French":http://justinfrench.com
|
|
348
|
-
* "José Valim":http://github.com/josevalim
|
|
349
355
|
* "Jeff Smick":http://github.com/sprsquish
|
|
350
356
|
* "Tien Dung":http://github.com/tiendung
|
|
351
357
|
* "Mark Mansour":http://stateofflux.com
|
|
@@ -59,7 +59,7 @@ form.formtastic fieldset ol li li label { line-height:100%; padding-top:0; }
|
|
|
59
59
|
form.formtastic fieldset ol li li label input { line-height:100%; vertical-align:middle; margin-top:-0.1em;}
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
/* NESTED FIELDSETS AND LEGENDS (radio and date/time inputs use nested fieldsets)
|
|
62
|
+
/* NESTED FIELDSETS AND LEGENDS (radio, check boxes and date/time inputs use nested fieldsets)
|
|
63
63
|
--------------------------------------------------------------------------------------------------*/
|
|
64
64
|
form.formtastic fieldset ol li fieldset { position:relative; }
|
|
65
65
|
form.formtastic fieldset ol li fieldset legend { position:absolute; width:25%; padding-top:0.1em; }
|
|
@@ -91,7 +91,12 @@ form.formtastic fieldset ol li.numeric input { width:74%; }
|
|
|
91
91
|
form.formtastic fieldset ol li.text textarea { width:74%; }
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
/*
|
|
94
|
+
/* HIDDEN OVERRIDES
|
|
95
|
+
--------------------------------------------------------------------------------------------------*/
|
|
96
|
+
form.formtastic fieldset ol li.hidden { display:none; }
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
/* BOOLEAN OVERRIDES
|
|
95
100
|
--------------------------------------------------------------------------------------------------*/
|
|
96
101
|
form.formtastic fieldset ol li.boolean label { padding-left:25%; width:auto; }
|
|
97
102
|
form.formtastic fieldset ol li.boolean label input { margin:0 0.5em 0 0.2em; }
|
|
@@ -106,6 +111,16 @@ form.formtastic fieldset ol li.radio fieldset ol li label { float:none; width:10
|
|
|
106
111
|
form.formtastic fieldset ol li.radio fieldset ol li label input { margin-right:0.2em; }
|
|
107
112
|
|
|
108
113
|
|
|
114
|
+
/* CHECK BOXES (COLLECTION) OVERRIDES
|
|
115
|
+
--------------------------------------------------------------------------------------------------*/
|
|
116
|
+
form.formtastic fieldset ol li.check_boxes { }
|
|
117
|
+
form.formtastic fieldset ol li.check_boxes fieldset ol { margin-bottom:-0.6em; }
|
|
118
|
+
form.formtastic fieldset ol li.check_boxes fieldset ol li { margin:0.1em 0 0.5em 0; }
|
|
119
|
+
form.formtastic fieldset ol li.check_boxes fieldset ol li label { float:none; width:100%; }
|
|
120
|
+
form.formtastic fieldset ol li.check_boxes fieldset ol li label input { margin-right:0.2em; }
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
109
124
|
/* DATE & TIME OVERRIDES
|
|
110
125
|
--------------------------------------------------------------------------------------------------*/
|
|
111
126
|
form.formtastic fieldset ol li.date fieldset ol li,
|
data/lib/formtastic.rb
CHANGED
|
@@ -18,13 +18,13 @@ module Formtastic #:nodoc:
|
|
|
18
18
|
@@collection_label_methods = %w[to_label display_name full_name name title username login value to_s]
|
|
19
19
|
@@inline_order = [ :input, :hints, :errors ]
|
|
20
20
|
@@file_methods = [ :file?, :public_filename ]
|
|
21
|
+
@@priority_countries = ["Australia", "Canada", "United Kingdom", "United States"]
|
|
21
22
|
|
|
22
23
|
cattr_accessor :default_text_field_size, :all_fields_required_by_default, :required_string,
|
|
23
24
|
:optional_string, :inline_errors, :label_str_method, :collection_label_methods,
|
|
24
|
-
:inline_order, :file_methods
|
|
25
|
+
:inline_order, :file_methods, :priority_countries
|
|
25
26
|
|
|
26
27
|
# Keeps simple mappings in a hash
|
|
27
|
-
#
|
|
28
28
|
INPUT_MAPPINGS = {
|
|
29
29
|
:string => :text_field,
|
|
30
30
|
:password => :password_field,
|
|
@@ -42,7 +42,7 @@ module Formtastic #:nodoc:
|
|
|
42
42
|
# Options:
|
|
43
43
|
#
|
|
44
44
|
# * :as - override the input type (eg force a :string to render as a :password field)
|
|
45
|
-
# * :label - use something other than the method name as the label
|
|
45
|
+
# * :label - use something other than the method name as the label text, when false no label is printed
|
|
46
46
|
# * :required - specify if the column is required (true) or not (false)
|
|
47
47
|
# * :hint - provide some text to hint or help the user provide the correct information for a field
|
|
48
48
|
# * :input_html - provide options that will be passed down to the generated input
|
|
@@ -55,8 +55,9 @@ module Formtastic #:nodoc:
|
|
|
55
55
|
# columns all map to a single numeric_input, for example).
|
|
56
56
|
#
|
|
57
57
|
# * :select (a select menu for associations) - default to association names
|
|
58
|
+
# * :check_boxes (a set of check_box inputs for associations) - alternative to :select has_many and has_and_belongs_to_many associations
|
|
59
|
+
# * :radio (a set of radio inputs for associations) - alternative to :select belongs_to associations
|
|
58
60
|
# * :time_zone (a select menu with time zones)
|
|
59
|
-
# * :radio (a set of radio inputs for associations) - default to association names
|
|
60
61
|
# * :password (a password input) - default for :string column types with 'password' in the method name
|
|
61
62
|
# * :text (a textarea) - default for :text column types
|
|
62
63
|
# * :date (a date select) - default for :date column types
|
|
@@ -65,6 +66,8 @@ module Formtastic #:nodoc:
|
|
|
65
66
|
# * :boolean (a checkbox) - default for :boolean column types (you can also have booleans as :select and :radio)
|
|
66
67
|
# * :string (a text field) - default for :string column types
|
|
67
68
|
# * :numeric (a text field, like string) - default for :integer, :float and :decimal column types
|
|
69
|
+
# * :country (a select menu of country names) - requires a country_select plugin to be installed
|
|
70
|
+
# * :hidden (a hidden field) - creates a hidden field (added for compatibility)
|
|
68
71
|
#
|
|
69
72
|
# Example:
|
|
70
73
|
#
|
|
@@ -308,18 +311,39 @@ module Formtastic #:nodoc:
|
|
|
308
311
|
fields_for(record_or_name_or_array, *args, &block)
|
|
309
312
|
end
|
|
310
313
|
|
|
311
|
-
# Generates the label for the input.
|
|
312
|
-
# label method
|
|
313
|
-
#
|
|
314
|
+
# Generates the label for the input. It also accepts the same arguments as
|
|
315
|
+
# Rails label method. It has three options that are not supported by Rails
|
|
316
|
+
# label method:
|
|
317
|
+
#
|
|
318
|
+
# * :required - Appends an abbr tag if :required is true
|
|
319
|
+
# * :label - An alternative form to give the label content. Whenever label
|
|
320
|
+
# is false, a blank string is returned.
|
|
321
|
+
# * :as_span - When true returns a span tag with class label instead of a label element
|
|
322
|
+
#
|
|
323
|
+
# == Examples
|
|
324
|
+
#
|
|
325
|
+
# f.label :title # like in rails, except that it searches the label on I18n API too
|
|
314
326
|
#
|
|
315
|
-
# :
|
|
316
|
-
#
|
|
327
|
+
# f.label :title, "Your post title"
|
|
328
|
+
# f.label :title, :label => "Your post title" # Added for formtastic API
|
|
317
329
|
#
|
|
318
|
-
|
|
330
|
+
# f.label :title, :required => true # Returns <label>Title<abbr title="required">*</abbr></label>
|
|
331
|
+
#
|
|
332
|
+
def label(method, options_or_text=nil, options=nil)
|
|
333
|
+
if options_or_text.is_a?(Hash)
|
|
334
|
+
return if options_or_text[:label] == false
|
|
335
|
+
|
|
336
|
+
options = options_or_text
|
|
337
|
+
text = options.delete(:label)
|
|
338
|
+
else
|
|
339
|
+
text = options_or_text
|
|
340
|
+
options ||= {}
|
|
341
|
+
end
|
|
342
|
+
|
|
319
343
|
text ||= humanized_attribute_name(method)
|
|
320
344
|
text << required_or_optional_string(options.delete(:required))
|
|
321
345
|
|
|
322
|
-
if as_span
|
|
346
|
+
if options.delete(:as_span)
|
|
323
347
|
options[:class] ||= 'label'
|
|
324
348
|
template.content_tag(:span, text, options)
|
|
325
349
|
else
|
|
@@ -327,6 +351,25 @@ module Formtastic #:nodoc:
|
|
|
327
351
|
end
|
|
328
352
|
end
|
|
329
353
|
|
|
354
|
+
# Generates error messages for the given method. Errors can be shown as list
|
|
355
|
+
# or as sentence. If :none is set, no error is shown.
|
|
356
|
+
#
|
|
357
|
+
# This method is also aliased as errors_on, so you can call on your custom
|
|
358
|
+
# inputs as well:
|
|
359
|
+
#
|
|
360
|
+
# semantic_form_for :post do |f|
|
|
361
|
+
# f.text_field(:body)
|
|
362
|
+
# f.errors_on(:body)
|
|
363
|
+
# end
|
|
364
|
+
#
|
|
365
|
+
def inline_errors_for(method, options=nil) #:nodoc:
|
|
366
|
+
return nil unless @object && @object.respond_to?(:errors) && [:sentence, :list].include?(@@inline_errors)
|
|
367
|
+
|
|
368
|
+
errors = @object.errors.on(method.to_s)
|
|
369
|
+
send("error_#{@@inline_errors}", Array(errors)) unless errors.blank?
|
|
370
|
+
end
|
|
371
|
+
alias :errors_on :inline_errors_for
|
|
372
|
+
|
|
330
373
|
protected
|
|
331
374
|
|
|
332
375
|
# Deals with :for option when it's supplied to inputs methods. Additional
|
|
@@ -410,10 +453,18 @@ module Formtastic #:nodoc:
|
|
|
410
453
|
html_options = options.delete(:input_html) || {}
|
|
411
454
|
html_options = default_string_options(method).merge(html_options) if STRING_MAPPINGS.include?(type)
|
|
412
455
|
|
|
413
|
-
self.label(method, options.
|
|
456
|
+
self.label(method, options.slice(:label, :required)) +
|
|
414
457
|
self.send(INPUT_MAPPINGS[type], method, html_options)
|
|
415
458
|
end
|
|
416
459
|
|
|
460
|
+
# Outputs a hidden field inside the wrapper, which should be hidden with CSS.
|
|
461
|
+
# Additionals options can be given and will be sent straight to hidden input
|
|
462
|
+
# element.
|
|
463
|
+
#
|
|
464
|
+
def hidden_input(method, options)
|
|
465
|
+
self.hidden_field(method, set_options(options))
|
|
466
|
+
end
|
|
467
|
+
|
|
417
468
|
# Outputs a label and a select box containing options from the parent
|
|
418
469
|
# (belongs_to, has_many, has_and_belongs_to_many) association. If an association
|
|
419
470
|
# is has_many or has_and_belongs_to_many the select box will be set as multi-select
|
|
@@ -503,7 +554,7 @@ module Formtastic #:nodoc:
|
|
|
503
554
|
end
|
|
504
555
|
|
|
505
556
|
input_name = generate_association_input_name(method)
|
|
506
|
-
self.label(input_name, options.
|
|
557
|
+
self.label(input_name, options.slice(:label, :required)) +
|
|
507
558
|
self.select(input_name, collection, set_options(options), html_options)
|
|
508
559
|
end
|
|
509
560
|
alias :boolean_select_input :select_input
|
|
@@ -518,7 +569,7 @@ module Formtastic #:nodoc:
|
|
|
518
569
|
def time_zone_input(method, options)
|
|
519
570
|
html_options = options.delete(:input_html) || {}
|
|
520
571
|
|
|
521
|
-
self.label(method, options.
|
|
572
|
+
self.label(method, options.slice(:label, :required)) +
|
|
522
573
|
self.time_zone_select(method, options.delete(:priority_zones), set_options(options), html_options)
|
|
523
574
|
end
|
|
524
575
|
|
|
@@ -547,7 +598,7 @@ module Formtastic #:nodoc:
|
|
|
547
598
|
# You can customize the options available in the set by passing in a collection (Array) of
|
|
548
599
|
# ActiveRecord objects through the :collection option. If not provided, the choices are found
|
|
549
600
|
# by inferring the parent's class name from the method name and simply calling find(:all) on
|
|
550
|
-
# it (
|
|
601
|
+
# it (Author.find(:all) in the example above).
|
|
551
602
|
#
|
|
552
603
|
# Examples:
|
|
553
604
|
#
|
|
@@ -665,6 +716,7 @@ module Formtastic #:nodoc:
|
|
|
665
716
|
time_inputs << [:second] if options[:include_seconds]
|
|
666
717
|
|
|
667
718
|
list_items_capture = ""
|
|
719
|
+
hidden_fields_capture = ""
|
|
668
720
|
|
|
669
721
|
# Gets the datetime object. It can be a Fixnum, Date or Time, or nil.
|
|
670
722
|
datetime = @object ? @object.send(method) : nil
|
|
@@ -673,26 +725,135 @@ module Formtastic #:nodoc:
|
|
|
673
725
|
(inputs + time_inputs).each do |input|
|
|
674
726
|
html_id = generate_html_id(method, "#{position[input]}i")
|
|
675
727
|
field_name = "#{method}(#{position[input]}i)"
|
|
676
|
-
|
|
677
|
-
list_items_capture << if options["discard_#{input}".intern]
|
|
728
|
+
if options["discard_#{input}".intern]
|
|
678
729
|
break if time_inputs.include?(input)
|
|
679
|
-
|
|
730
|
+
|
|
680
731
|
hidden_value = datetime.respond_to?(input) ? datetime.send(input) : datetime
|
|
681
|
-
template.hidden_field_tag("#{@object_name}[#{field_name}]", (hidden_value || 1), :id => html_id)
|
|
732
|
+
hidden_fields_capture << template.hidden_field_tag("#{@object_name}[#{field_name}]", (hidden_value || 1), :id => html_id)
|
|
682
733
|
else
|
|
683
734
|
opts = set_options(options).merge(:prefix => @object_name, :field_name => field_name)
|
|
684
735
|
item_label_text = I18n.t(input.to_s, :default => input.to_s.humanize, :scope => [:datetime, :prompts])
|
|
685
736
|
|
|
686
|
-
template.content_tag(:li,
|
|
737
|
+
list_items_capture << template.content_tag(:li,
|
|
687
738
|
template.content_tag(:label, item_label_text, :for => html_id) +
|
|
688
739
|
template.send("select_#{input}".intern, datetime, opts, html_options.merge(:id => html_id))
|
|
689
740
|
)
|
|
690
741
|
end
|
|
691
742
|
end
|
|
692
743
|
|
|
693
|
-
field_set_and_list_wrapping_for_method(method, options, list_items_capture)
|
|
744
|
+
hidden_fields_capture + field_set_and_list_wrapping_for_method(method, options, list_items_capture)
|
|
694
745
|
end
|
|
695
746
|
|
|
747
|
+
|
|
748
|
+
# Outputs a fieldset containing a legend for the label text, and an ordered list (ol) of list
|
|
749
|
+
# items, one for each possible choice in the belongs_to association. Each li contains a
|
|
750
|
+
# label and a check_box input.
|
|
751
|
+
#
|
|
752
|
+
# This is an alternative for has many and has and belongs to many associations.
|
|
753
|
+
#
|
|
754
|
+
# Example:
|
|
755
|
+
#
|
|
756
|
+
# f.input :author, :as => :check_boxes
|
|
757
|
+
#
|
|
758
|
+
# Output:
|
|
759
|
+
#
|
|
760
|
+
# <fieldset>
|
|
761
|
+
# <legend><span>Authors</span></legend>
|
|
762
|
+
# <ol>
|
|
763
|
+
# <li>
|
|
764
|
+
# <input type="hidden" name="book[author_id][1]" value="">
|
|
765
|
+
# <label for="book_author_id_1"><input id="book_author_id_1" name="book[author_id][1]" type="checkbox" value="1" /> Justin French</label>
|
|
766
|
+
# </li>
|
|
767
|
+
# <li>
|
|
768
|
+
# <input type="hidden" name="book[author_id][2]" value="">
|
|
769
|
+
# <label for="book_author_id_2"><input id="book_author_id_2" name="book[owner_id][2]" type="checkbox" value="2" /> Kate French</label>
|
|
770
|
+
# </li>
|
|
771
|
+
# </ol>
|
|
772
|
+
# </fieldset>
|
|
773
|
+
#
|
|
774
|
+
# Notice that the value of the checkbox is the same as the id and the hidden
|
|
775
|
+
# field has empty value. You can override the hidden field value using the
|
|
776
|
+
# unchecked_value option.
|
|
777
|
+
#
|
|
778
|
+
# You can customize the options available in the set by passing in a collection (Array) of
|
|
779
|
+
# ActiveRecord objects through the :collection option. If not provided, the choices are found
|
|
780
|
+
# by inferring the parent's class name from the method name and simply calling find(:all) on
|
|
781
|
+
# it (Author.find(:all) in the example above).
|
|
782
|
+
#
|
|
783
|
+
# Examples:
|
|
784
|
+
#
|
|
785
|
+
# f.input :author, :as => :check_boxes, :collection => @authors
|
|
786
|
+
# f.input :author, :as => :check_boxes, :collection => Author.find(:all)
|
|
787
|
+
# f.input :author, :as => :check_boxes, :collection => [@justin, @kate]
|
|
788
|
+
#
|
|
789
|
+
# You can also customize the text label inside each option tag, by naming the correct method
|
|
790
|
+
# (:full_name, :display_name, :account_number, etc) to call on each object in the collection
|
|
791
|
+
# by passing in the :label_method option. By default the :label_method is whichever element of
|
|
792
|
+
# Formtastic::SemanticFormBuilder.collection_label_methods is found first.
|
|
793
|
+
#
|
|
794
|
+
# Examples:
|
|
795
|
+
#
|
|
796
|
+
# f.input :author, :as => :check_boxes, :label_method => :full_name
|
|
797
|
+
# f.input :author, :as => :check_boxes, :label_method => :display_name
|
|
798
|
+
# f.input :author, :as => :check_boxes, :label_method => :to_s
|
|
799
|
+
# f.input :author, :as => :check_boxes, :label_method => :label
|
|
800
|
+
#
|
|
801
|
+
# You can set :value_as_class => true if you want that LI wrappers contains
|
|
802
|
+
# a class with the wrapped checkbox input value.
|
|
803
|
+
#
|
|
804
|
+
def check_boxes_input(method, options)
|
|
805
|
+
collection = find_collection_for_column(method, options)
|
|
806
|
+
html_options = options.delete(:input_html) || {}
|
|
807
|
+
|
|
808
|
+
input_name = generate_association_input_name(method)
|
|
809
|
+
value_as_class = options.delete(:value_as_class)
|
|
810
|
+
unchecked_value = options.delete(:unchecked_value) || ''
|
|
811
|
+
html_options = { :name => "#{@object_name}[#{input_name}][]" }.merge(html_options)
|
|
812
|
+
|
|
813
|
+
list_item_content = collection.map do |c|
|
|
814
|
+
label = c.is_a?(Array) ? c.first : c
|
|
815
|
+
value = c.is_a?(Array) ? c.last : c
|
|
816
|
+
|
|
817
|
+
html_options.merge!(:id => generate_html_id(input_name, value.to_s.downcase))
|
|
818
|
+
|
|
819
|
+
li_content = template.content_tag(:label,
|
|
820
|
+
"#{self.check_box(input_name, html_options, value, unchecked_value)} #{label}",
|
|
821
|
+
:for => html_options[:id]
|
|
822
|
+
)
|
|
823
|
+
|
|
824
|
+
li_options = value_as_class ? { :class => value.to_s.downcase } : {}
|
|
825
|
+
template.content_tag(:li, li_content, li_options)
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
field_set_and_list_wrapping_for_method(method, options, list_item_content)
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
# Outputs a country select input, wrapping around a regular country_select helper.
|
|
833
|
+
# Rails doesn't come with a country_select helper by default any more, so you'll need to install
|
|
834
|
+
# the "official" plugin, or, if you wish, any other country_select plugin that behaves in the
|
|
835
|
+
# same way.
|
|
836
|
+
#
|
|
837
|
+
# The Rails plugin iso-3166-country-select plugin can be found "here":http://github.com/rails/iso-3166-country-select.
|
|
838
|
+
#
|
|
839
|
+
# By default, Formtastic includes a handfull of english-speaking countries as "priority counties",
|
|
840
|
+
# which you can change to suit your market and user base (see README for more info on config).
|
|
841
|
+
#
|
|
842
|
+
# Examples:
|
|
843
|
+
# f.input :location, :as => :country # use Formtastic::SemanticFormBuilder.priority_countries array for the priority countries
|
|
844
|
+
# f.input :location, :as => :country, :priority_countries => /Australia/ # set your own
|
|
845
|
+
#
|
|
846
|
+
def country_input(method, options)
|
|
847
|
+
raise "To use the :country input, please install a country_select plugin, like this one: http://github.com/rails/iso-3166-country-select" unless self.respond_to?(:country_select)
|
|
848
|
+
|
|
849
|
+
html_options = options.delete(:input_html) || {}
|
|
850
|
+
priority_countries = options.delete(:priority_countries) || @@priority_countries
|
|
851
|
+
|
|
852
|
+
self.label(method, options.slice(:label, :required)) +
|
|
853
|
+
self.country_select(method, priority_countries, set_options(options), html_options)
|
|
854
|
+
end
|
|
855
|
+
|
|
856
|
+
|
|
696
857
|
# Outputs a label containing a checkbox and the label text. The label defaults
|
|
697
858
|
# to the column name (method name) and can be altered with the :label option.
|
|
698
859
|
# :checked_value and :unchecked_value options are also available.
|
|
@@ -724,23 +885,6 @@ module Formtastic #:nodoc:
|
|
|
724
885
|
end
|
|
725
886
|
end
|
|
726
887
|
|
|
727
|
-
# Generates error messages for the given method. Errors can be shown as list
|
|
728
|
-
# or as sentence. If :none is set, no error is shown.
|
|
729
|
-
#
|
|
730
|
-
def inline_errors_for(method, options) #:nodoc:
|
|
731
|
-
return nil unless @object && @object.respond_to?(:errors) && [:sentence, :list].include?(@@inline_errors)
|
|
732
|
-
|
|
733
|
-
# Ruby 1.9: Strings are not Enumerable, ie no String#to_a
|
|
734
|
-
errors = @object.errors.on(method.to_s)
|
|
735
|
-
unless errors.respond_to?(:to_a)
|
|
736
|
-
errors = [errors]
|
|
737
|
-
else
|
|
738
|
-
errors = errors.to_a
|
|
739
|
-
end
|
|
740
|
-
|
|
741
|
-
send("error_#{@@inline_errors}", errors) unless errors.empty?
|
|
742
|
-
end
|
|
743
|
-
|
|
744
888
|
# Generates hints for the given method using the text supplied in :hint.
|
|
745
889
|
#
|
|
746
890
|
def inline_hints_for(method, options) #:nodoc:
|
|
@@ -816,7 +960,7 @@ module Formtastic #:nodoc:
|
|
|
816
960
|
#
|
|
817
961
|
def field_set_and_list_wrapping_for_method(method, options, contents)
|
|
818
962
|
template.content_tag(:fieldset,
|
|
819
|
-
%{<legend>#{self.label(method, options.
|
|
963
|
+
%{<legend>#{self.label(method, options.slice(:label, :required).merge!(:as_span => true))}</legend>} +
|
|
820
964
|
template.content_tag(:ol, contents)
|
|
821
965
|
)
|
|
822
966
|
end
|
|
@@ -841,6 +985,7 @@ module Formtastic #:nodoc:
|
|
|
841
985
|
return :datetime if column.type == :timestamp
|
|
842
986
|
return :numeric if [:integer, :float, :decimal].include?(column.type)
|
|
843
987
|
return :password if column.type == :string && method.to_s =~ /password/
|
|
988
|
+
return :country if column.type == :string && method.to_s =~ /country/
|
|
844
989
|
|
|
845
990
|
# otherwise assume the input name will be the same as the column type (eg string_input)
|
|
846
991
|
return column.type
|
data/spec/formtastic_spec.rb
CHANGED
|
@@ -234,6 +234,10 @@ describe 'Formtastic' do
|
|
|
234
234
|
@new_post.stub!(:body)
|
|
235
235
|
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
|
|
236
236
|
end
|
|
237
|
+
|
|
238
|
+
after do
|
|
239
|
+
Formtastic::SemanticFormHelper.builder = Formtastic::SemanticFormBuilder
|
|
240
|
+
end
|
|
237
241
|
|
|
238
242
|
it "can be overridden" do
|
|
239
243
|
|
|
@@ -293,15 +297,92 @@ describe 'Formtastic' do
|
|
|
293
297
|
end
|
|
294
298
|
end
|
|
295
299
|
|
|
296
|
-
it 'should
|
|
300
|
+
it 'should be printed as span' do
|
|
297
301
|
semantic_form_for(@new_post) do |builder|
|
|
298
|
-
builder.label(:login, nil, :required => true).should have_tag('label abbr')
|
|
302
|
+
builder.label(:login, nil, { :required => true, :as_span => true }).should have_tag('span.label abbr')
|
|
299
303
|
end
|
|
300
304
|
end
|
|
301
305
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
306
|
+
describe 'when required is given' do
|
|
307
|
+
it 'should append a required note' do
|
|
308
|
+
semantic_form_for(@new_post) do |builder|
|
|
309
|
+
builder.label(:login, nil, :required => true).should have_tag('label abbr')
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it 'should allow require option to be given as second argument' do
|
|
314
|
+
semantic_form_for(@new_post) do |builder|
|
|
315
|
+
builder.label(:login, :required => true).should have_tag('label abbr')
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
describe 'when label is given' do
|
|
321
|
+
it 'should allow the text to be given as label option' do
|
|
322
|
+
semantic_form_for(@new_post) do |builder|
|
|
323
|
+
builder.label(:login, :required => true, :label => 'My label').should have_tag('label', :with => /My label/)
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
it 'should return nil if label is false' do
|
|
328
|
+
semantic_form_for(@new_post) do |builder|
|
|
329
|
+
builder.label(:login, :label => false).should be_nil
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
describe '#errors_on' do
|
|
336
|
+
before(:each) do
|
|
337
|
+
@title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
|
|
338
|
+
@errors = mock('errors')
|
|
339
|
+
@errors.stub!(:on).with('title').and_return(@title_errors)
|
|
340
|
+
@errors.stub!(:on).with('body').and_return(nil)
|
|
341
|
+
@new_post.stub!(:errors).and_return(@errors)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
describe 'and the errors will be displayed as a sentence' do
|
|
345
|
+
it 'should render a paragraph with the errors joined into a sentence' do
|
|
346
|
+
Formtastic::SemanticFormBuilder.inline_errors = :sentence
|
|
347
|
+
semantic_form_for(@new_post) do |builder|
|
|
348
|
+
builder.errors_on(:title).should have_tag('p.inline-errors', @title_errors.to_sentence)
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
describe 'and the errors will be displayed as a list' do
|
|
354
|
+
it 'should render an unordered list with the class errors' do
|
|
355
|
+
Formtastic::SemanticFormBuilder.inline_errors = :list
|
|
356
|
+
semantic_form_for(@new_post) do |builder|
|
|
357
|
+
builder.errors_on(:title).should have_tag('ul.errors')
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
it 'should include a list element for each of the errors within the unordered list' do
|
|
362
|
+
Formtastic::SemanticFormBuilder.inline_errors = :list
|
|
363
|
+
semantic_form_for(@new_post) do |builder|
|
|
364
|
+
@title_errors.each do |error|
|
|
365
|
+
builder.errors_on(:title).should have_tag('ul.errors li', error)
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
describe 'but the errors will not be shown' do
|
|
372
|
+
it 'should return nil' do
|
|
373
|
+
Formtastic::SemanticFormBuilder.inline_errors = :none
|
|
374
|
+
semantic_form_for(@new_post) do |builder|
|
|
375
|
+
builder.errors_on(:title).should be_nil
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
describe 'and no error is found on the method' do
|
|
381
|
+
it 'should return nil' do
|
|
382
|
+
Formtastic::SemanticFormBuilder.inline_errors = :sentence
|
|
383
|
+
semantic_form_for(@new_post) do |builder|
|
|
384
|
+
builder.errors_on(:body).should be_nil
|
|
385
|
+
end
|
|
305
386
|
end
|
|
306
387
|
end
|
|
307
388
|
end
|
|
@@ -558,6 +639,10 @@ describe 'Formtastic' do
|
|
|
558
639
|
default_input_type(:float).should == :numeric
|
|
559
640
|
default_input_type(:decimal).should == :numeric
|
|
560
641
|
end
|
|
642
|
+
|
|
643
|
+
it 'should default to :country for :string columns named country' do
|
|
644
|
+
default_input_type(:string, :country).should == :country
|
|
645
|
+
end
|
|
561
646
|
|
|
562
647
|
describe 'defaulting to file column' do
|
|
563
648
|
Formtastic::SemanticFormBuilder.file_methods.each do |method|
|
|
@@ -581,7 +666,7 @@ describe 'Formtastic' do
|
|
|
581
666
|
end
|
|
582
667
|
|
|
583
668
|
it 'should call the corresponding input method' do
|
|
584
|
-
[:select, :time_zone, :radio, :date, :datetime, :time, :boolean].each do |input_style|
|
|
669
|
+
[:select, :time_zone, :radio, :date, :datetime, :time, :boolean, :check_boxes, :hidden].each do |input_style|
|
|
585
670
|
@new_post.stub!(:generic_column_name)
|
|
586
671
|
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
|
|
587
672
|
semantic_form_for(@new_post) do |builder|
|
|
@@ -721,7 +806,6 @@ describe 'Formtastic' do
|
|
|
721
806
|
end
|
|
722
807
|
|
|
723
808
|
describe 'when there are errors on the object for this method' do
|
|
724
|
-
|
|
725
809
|
before do
|
|
726
810
|
@title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
|
|
727
811
|
@errors = mock('errors')
|
|
@@ -743,65 +827,24 @@ describe 'Formtastic' do
|
|
|
743
827
|
output_buffer.should_not have_tag('div.fieldWithErrors')
|
|
744
828
|
end
|
|
745
829
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
semantic_form_for(@new_post) do |builder|
|
|
751
|
-
concat(builder.input(:title))
|
|
752
|
-
end
|
|
753
|
-
end
|
|
754
|
-
|
|
755
|
-
it 'should render a paragraph with the errors joined into a sentence' do
|
|
756
|
-
output_buffer.should have_tag('form li.error p.inline-errors', @title_errors.to_sentence)
|
|
757
|
-
end
|
|
758
|
-
|
|
759
|
-
end
|
|
760
|
-
|
|
761
|
-
describe 'and the errors will be displayed as a list' do
|
|
762
|
-
|
|
763
|
-
before do
|
|
764
|
-
Formtastic::SemanticFormBuilder.inline_errors = :list
|
|
765
|
-
semantic_form_for(@new_post) do |builder|
|
|
766
|
-
concat(builder.input(:title))
|
|
767
|
-
end
|
|
768
|
-
end
|
|
769
|
-
|
|
770
|
-
it 'should render an unordered list with the class errors' do
|
|
771
|
-
output_buffer.should have_tag('form li.error ul.errors')
|
|
772
|
-
end
|
|
773
|
-
|
|
774
|
-
it 'should include a list element for each of the errors within the unordered list' do
|
|
775
|
-
@title_errors.each do |error|
|
|
776
|
-
output_buffer.should have_tag('form li.error ul.errors li', error)
|
|
777
|
-
end
|
|
830
|
+
it 'should render a paragraph for the errors' do
|
|
831
|
+
Formtastic::SemanticFormBuilder.inline_errors = :sentence
|
|
832
|
+
semantic_form_for(@new_post) do |builder|
|
|
833
|
+
concat(builder.input(:title))
|
|
778
834
|
end
|
|
779
|
-
|
|
835
|
+
output_buffer.should have_tag('form li.error p.inline-errors')
|
|
780
836
|
end
|
|
781
837
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
semantic_form_for(@new_post) do |builder|
|
|
787
|
-
concat(builder.input(:title))
|
|
788
|
-
end
|
|
789
|
-
end
|
|
790
|
-
|
|
791
|
-
it 'should not display an error sentence' do
|
|
792
|
-
output_buffer.should_not have_tag('form li.error p.inline-errors')
|
|
793
|
-
end
|
|
794
|
-
|
|
795
|
-
it 'should not display an error list' do
|
|
796
|
-
output_buffer.should_not have_tag('form li.error ul.errors')
|
|
838
|
+
it 'should not display an error list' do
|
|
839
|
+
Formtastic::SemanticFormBuilder.inline_errors = :list
|
|
840
|
+
semantic_form_for(@new_post) do |builder|
|
|
841
|
+
concat(builder.input(:title))
|
|
797
842
|
end
|
|
798
|
-
|
|
843
|
+
output_buffer.should have_tag('form li.error ul.errors')
|
|
799
844
|
end
|
|
800
|
-
|
|
801
845
|
end
|
|
802
846
|
|
|
803
847
|
describe 'when there are no errors on the object for this method' do
|
|
804
|
-
|
|
805
848
|
before do
|
|
806
849
|
semantic_form_for(@new_post) do |builder|
|
|
807
850
|
concat(builder.input(:title))
|
|
@@ -819,11 +862,9 @@ describe 'Formtastic' do
|
|
|
819
862
|
it 'should not display an error list' do
|
|
820
863
|
output_buffer.should_not have_tag('form li.error ul.errors')
|
|
821
864
|
end
|
|
822
|
-
|
|
823
865
|
end
|
|
824
866
|
|
|
825
867
|
describe 'when no object is provided' do
|
|
826
|
-
|
|
827
868
|
before do
|
|
828
869
|
semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
|
829
870
|
concat(builder.input(:title))
|
|
@@ -841,7 +882,6 @@ describe 'Formtastic' do
|
|
|
841
882
|
it 'should not display an error list' do
|
|
842
883
|
output_buffer.should_not have_tag('form li.error ul.errors')
|
|
843
884
|
end
|
|
844
|
-
|
|
845
885
|
end
|
|
846
886
|
end
|
|
847
887
|
|
|
@@ -1008,30 +1048,65 @@ describe 'Formtastic' do
|
|
|
1008
1048
|
|
|
1009
1049
|
end
|
|
1010
1050
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1051
|
+
describe 'when no object is given' do
|
|
1052
|
+
before(:each) do
|
|
1053
|
+
semantic_form_for(:project, :url => 'http://test.host/') do |builder|
|
|
1054
|
+
concat(builder.input(:title, :as => type))
|
|
1055
|
+
end
|
|
1014
1056
|
end
|
|
1015
1057
|
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1058
|
+
it 'should generate input' do
|
|
1059
|
+
if template_method.to_s =~ /_field$/ # password_field
|
|
1060
|
+
output_buffer.should have_tag("form li input")
|
|
1061
|
+
output_buffer.should have_tag("form li input#project_title")
|
|
1062
|
+
output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
|
|
1063
|
+
output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
|
|
1064
|
+
else
|
|
1065
|
+
output_buffer.should have_tag("form li #{input_type}")
|
|
1066
|
+
output_buffer.should have_tag("form li #{input_type}#project_title")
|
|
1067
|
+
output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
|
|
1068
|
+
end
|
|
1069
|
+
end
|
|
1019
1070
|
|
|
1020
|
-
|
|
1021
|
-
output_buffer.should have_tag(
|
|
1022
|
-
output_buffer.should have_tag(
|
|
1023
|
-
output_buffer.should have_tag(
|
|
1024
|
-
output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
|
|
1025
|
-
else
|
|
1026
|
-
output_buffer.should have_tag("form li #{input_type}")
|
|
1027
|
-
output_buffer.should have_tag("form li #{input_type}#project_title")
|
|
1028
|
-
output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
|
|
1071
|
+
it 'should generate labels' do
|
|
1072
|
+
output_buffer.should have_tag('form li label')
|
|
1073
|
+
output_buffer.should have_tag('form li label[@for="project_title"')
|
|
1074
|
+
output_buffer.should have_tag('form li label', /Title/)
|
|
1029
1075
|
end
|
|
1030
1076
|
end
|
|
1031
1077
|
|
|
1032
1078
|
end
|
|
1033
1079
|
end
|
|
1034
1080
|
|
|
1081
|
+
describe ":as => :hidden" do
|
|
1082
|
+
before do
|
|
1083
|
+
@new_post.stub!(:hidden)
|
|
1084
|
+
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
|
|
1085
|
+
|
|
1086
|
+
semantic_form_for(@new_post) do |builder|
|
|
1087
|
+
concat(builder.input(:hidden, :as => :hidden))
|
|
1088
|
+
end
|
|
1089
|
+
end
|
|
1090
|
+
|
|
1091
|
+
it "should have a hidden class on the wrapper" do
|
|
1092
|
+
output_buffer.should have_tag('form li.hidden')
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
it 'should have a post_hidden_input id on the wrapper' do
|
|
1096
|
+
output_buffer.should have_tag('form li#post_hidden_input')
|
|
1097
|
+
end
|
|
1098
|
+
|
|
1099
|
+
it 'should not generate a label for the input' do
|
|
1100
|
+
output_buffer.should_not have_tag('form li label')
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
it "should generate a input field" do
|
|
1104
|
+
output_buffer.should have_tag("form li input#post_hidden")
|
|
1105
|
+
output_buffer.should have_tag("form li input[@type=\"hidden\"]")
|
|
1106
|
+
output_buffer.should have_tag("form li input[@name=\"post[hidden]\"]")
|
|
1107
|
+
end
|
|
1108
|
+
end
|
|
1109
|
+
|
|
1035
1110
|
describe ":as => :time_zone" do
|
|
1036
1111
|
before do
|
|
1037
1112
|
@new_post.stub!(:time_zone)
|
|
@@ -1069,27 +1144,110 @@ describe 'Formtastic' do
|
|
|
1069
1144
|
output_buffer.should have_tag("form li select.myclass")
|
|
1070
1145
|
end
|
|
1071
1146
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1147
|
+
describe 'when no object is given' do
|
|
1148
|
+
before(:each) do
|
|
1149
|
+
semantic_form_for(:project, :url => 'http://test.host/') do |builder|
|
|
1150
|
+
concat(builder.input(:time_zone, :as => :time_zone))
|
|
1151
|
+
end
|
|
1075
1152
|
end
|
|
1076
1153
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1154
|
+
it 'should generate labels' do
|
|
1155
|
+
output_buffer.should have_tag('form li label')
|
|
1156
|
+
output_buffer.should have_tag('form li label[@for="project_time_zone"')
|
|
1157
|
+
output_buffer.should have_tag('form li label', /Time zone/)
|
|
1158
|
+
end
|
|
1080
1159
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1160
|
+
it 'should generate select inputs' do
|
|
1161
|
+
output_buffer.should have_tag("form li select")
|
|
1162
|
+
output_buffer.should have_tag("form li select#project_time_zone")
|
|
1163
|
+
output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
|
|
1164
|
+
end
|
|
1084
1165
|
end
|
|
1085
1166
|
end
|
|
1167
|
+
|
|
1168
|
+
describe ":as => :country" do
|
|
1169
|
+
|
|
1170
|
+
before do
|
|
1171
|
+
@new_post.stub!(:country)
|
|
1172
|
+
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1175
|
+
describe "when country_select is not available as a helper from a plugin" do
|
|
1176
|
+
|
|
1177
|
+
it "should raise an error, sugesting the author installs a plugin" do
|
|
1178
|
+
lambda {
|
|
1179
|
+
semantic_form_for(@new_post) do |builder|
|
|
1180
|
+
concat(builder.input(:country, :as => :country))
|
|
1181
|
+
end
|
|
1182
|
+
}.should raise_error
|
|
1183
|
+
end
|
|
1184
|
+
|
|
1185
|
+
end
|
|
1186
|
+
|
|
1187
|
+
describe "when country_select is available as a helper (from a plugin)" do
|
|
1188
|
+
|
|
1189
|
+
before do
|
|
1190
|
+
semantic_form_for(@new_post) do |builder|
|
|
1191
|
+
builder.stub!(:country_select).and_return("<select><option>...</option></select>")
|
|
1192
|
+
concat(builder.input(:country, :as => :country))
|
|
1193
|
+
end
|
|
1194
|
+
end
|
|
1195
|
+
|
|
1196
|
+
it "should have a time_zone class on the wrapper" do
|
|
1197
|
+
output_buffer.should have_tag('form li.country')
|
|
1198
|
+
end
|
|
1199
|
+
|
|
1200
|
+
it 'should have a post_title_input id on the wrapper' do
|
|
1201
|
+
output_buffer.should have_tag('form li#post_country_input')
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1204
|
+
it 'should generate a label for the input' do
|
|
1205
|
+
output_buffer.should have_tag('form li label')
|
|
1206
|
+
output_buffer.should have_tag('form li label[@for="post_country"')
|
|
1207
|
+
output_buffer.should have_tag('form li label', /Country/)
|
|
1208
|
+
end
|
|
1086
1209
|
|
|
1210
|
+
it "should generate a select" do
|
|
1211
|
+
output_buffer.should have_tag("form li select")
|
|
1212
|
+
end
|
|
1213
|
+
|
|
1214
|
+
end
|
|
1215
|
+
|
|
1216
|
+
describe ":priority_countries option" do
|
|
1217
|
+
|
|
1218
|
+
it "should be passed down to the country_select helper when provided" do
|
|
1219
|
+
priority_countries = ["Foo", "Bah"]
|
|
1220
|
+
semantic_form_for(@new_post) do |builder|
|
|
1221
|
+
builder.stub!(:country_select).and_return("<select><option>...</option></select>")
|
|
1222
|
+
builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
|
|
1223
|
+
|
|
1224
|
+
concat(builder.input(:country, :as => :country, :priority_countries => priority_countries))
|
|
1225
|
+
end
|
|
1226
|
+
end
|
|
1227
|
+
|
|
1228
|
+
it "should default to the @@priority_countries config when absent" do
|
|
1229
|
+
priority_countries = Formtastic::SemanticFormBuilder.priority_countries
|
|
1230
|
+
priority_countries.should_not be_empty
|
|
1231
|
+
priority_countries.should_not be_nil
|
|
1232
|
+
|
|
1233
|
+
semantic_form_for(@new_post) do |builder|
|
|
1234
|
+
builder.stub!(:country_select).and_return("<select><option>...</option></select>")
|
|
1235
|
+
builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
|
|
1236
|
+
|
|
1237
|
+
concat(builder.input(:country, :as => :country))
|
|
1238
|
+
end
|
|
1239
|
+
end
|
|
1240
|
+
|
|
1241
|
+
end
|
|
1242
|
+
|
|
1243
|
+
end
|
|
1244
|
+
|
|
1087
1245
|
describe ':as => :radio' do
|
|
1088
1246
|
|
|
1089
1247
|
before do
|
|
1090
1248
|
@new_post.stub!(:author).and_return(@bob)
|
|
1091
1249
|
@new_post.stub!(:author_id).and_return(@bob.id)
|
|
1092
|
-
|
|
1250
|
+
Post.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :klass => Author, :macro => :belongs_to) }
|
|
1093
1251
|
end
|
|
1094
1252
|
|
|
1095
1253
|
describe 'for belongs_to association' do
|
|
@@ -1103,7 +1261,7 @@ describe 'Formtastic' do
|
|
|
1103
1261
|
output_buffer.should have_tag('form li.radio')
|
|
1104
1262
|
end
|
|
1105
1263
|
|
|
1106
|
-
it 'should have a
|
|
1264
|
+
it 'should have a post_author_input id on the wrapper' do
|
|
1107
1265
|
output_buffer.should have_tag('form li#post_author_input')
|
|
1108
1266
|
end
|
|
1109
1267
|
|
|
@@ -1118,7 +1276,7 @@ describe 'Formtastic' do
|
|
|
1118
1276
|
output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
|
|
1119
1277
|
end
|
|
1120
1278
|
|
|
1121
|
-
it 'should have one option with a "
|
|
1279
|
+
it 'should have one option with a "checked" attribute' do
|
|
1122
1280
|
output_buffer.should have_tag('form li input[@checked]', :count => 1)
|
|
1123
1281
|
end
|
|
1124
1282
|
|
|
@@ -1126,10 +1284,8 @@ describe 'Formtastic' do
|
|
|
1126
1284
|
|
|
1127
1285
|
it 'should contain a label for the radio input with a nested input and label text' do
|
|
1128
1286
|
Author.find(:all).each do |author|
|
|
1129
|
-
output_buffer.should have_tag('form li fieldset ol li label')
|
|
1130
1287
|
output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
|
|
1131
1288
|
output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
|
|
1132
|
-
output_buffer.should have_tag("form li fieldset ol li label input")
|
|
1133
1289
|
end
|
|
1134
1290
|
end
|
|
1135
1291
|
|
|
@@ -1161,29 +1317,39 @@ describe 'Formtastic' do
|
|
|
1161
1317
|
end
|
|
1162
1318
|
end
|
|
1163
1319
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1320
|
+
describe 'and no object is given' do
|
|
1321
|
+
before(:each) do
|
|
1322
|
+
output_buffer.replace ''
|
|
1323
|
+
semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
|
1324
|
+
concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
|
|
1325
|
+
end
|
|
1326
|
+
end
|
|
1166
1327
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1328
|
+
it 'should generate a fieldset with legend' do
|
|
1329
|
+
output_buffer.should have_tag('form li fieldset legend', /Author/)
|
|
1169
1330
|
end
|
|
1170
1331
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1332
|
+
it 'shold generate an li tag for each item in the collection' do
|
|
1333
|
+
output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
|
|
1334
|
+
end
|
|
1173
1335
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1336
|
+
it 'should generate labels for each item' do
|
|
1337
|
+
Author.find(:all).each do |author|
|
|
1338
|
+
output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
|
|
1339
|
+
output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
|
|
1340
|
+
end
|
|
1341
|
+
end
|
|
1177
1342
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1343
|
+
it 'should generate inputs for each item' do
|
|
1344
|
+
Author.find(:all).each do |author|
|
|
1345
|
+
output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
|
|
1346
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
|
|
1347
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
|
|
1348
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
|
|
1349
|
+
end
|
|
1182
1350
|
end
|
|
1183
1351
|
end
|
|
1184
|
-
|
|
1185
1352
|
end
|
|
1186
|
-
|
|
1187
1353
|
end
|
|
1188
1354
|
|
|
1189
1355
|
describe ':as => :select' do
|
|
@@ -1341,19 +1507,126 @@ describe 'Formtastic' do
|
|
|
1341
1507
|
end
|
|
1342
1508
|
end
|
|
1343
1509
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1510
|
+
describe 'when no object is given' do
|
|
1511
|
+
before(:each) do
|
|
1512
|
+
semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
|
1513
|
+
concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
|
|
1514
|
+
end
|
|
1347
1515
|
end
|
|
1348
1516
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1517
|
+
it 'should generate label' do
|
|
1518
|
+
output_buffer.should have_tag('form li label', /Author/)
|
|
1519
|
+
output_buffer.should have_tag("form li label[@for='project_author']")
|
|
1520
|
+
end
|
|
1351
1521
|
|
|
1352
|
-
|
|
1353
|
-
|
|
1522
|
+
it 'should generate select inputs' do
|
|
1523
|
+
output_buffer.should have_tag('form li select#project_author')
|
|
1524
|
+
output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
|
|
1525
|
+
end
|
|
1354
1526
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1527
|
+
it 'should generate an option to each item' do
|
|
1528
|
+
Author.find(:all).each do |author|
|
|
1529
|
+
output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
|
|
1530
|
+
end
|
|
1531
|
+
end
|
|
1532
|
+
end
|
|
1533
|
+
end
|
|
1534
|
+
|
|
1535
|
+
describe ':as => :check_boxes' do
|
|
1536
|
+
|
|
1537
|
+
describe 'for a has_many association' do
|
|
1538
|
+
before do
|
|
1539
|
+
semantic_form_for(@fred) do |builder|
|
|
1540
|
+
concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true))
|
|
1541
|
+
end
|
|
1542
|
+
end
|
|
1543
|
+
|
|
1544
|
+
it 'should have a check_boxes class on the wrapper' do
|
|
1545
|
+
output_buffer.should have_tag('form li.check_boxes')
|
|
1546
|
+
end
|
|
1547
|
+
|
|
1548
|
+
it 'should have a author_posts_input id on the wrapper' do
|
|
1549
|
+
output_buffer.should have_tag('form li#author_posts_input')
|
|
1550
|
+
end
|
|
1551
|
+
|
|
1552
|
+
it 'should generate a fieldset and legend containing label text for the input' do
|
|
1553
|
+
output_buffer.should have_tag('form li fieldset')
|
|
1554
|
+
output_buffer.should have_tag('form li fieldset legend')
|
|
1555
|
+
output_buffer.should have_tag('form li fieldset legend', /Posts/)
|
|
1556
|
+
end
|
|
1557
|
+
|
|
1558
|
+
it 'should generate an ordered list with a list item for each choice' do
|
|
1559
|
+
output_buffer.should have_tag('form li fieldset ol')
|
|
1560
|
+
output_buffer.should have_tag('form li fieldset ol li', :count => Post.find(:all).size)
|
|
1561
|
+
end
|
|
1562
|
+
|
|
1563
|
+
it 'should have one option with a "checked" attribute' do
|
|
1564
|
+
output_buffer.should have_tag('form li input[@checked]', :count => 1)
|
|
1565
|
+
end
|
|
1566
|
+
|
|
1567
|
+
it 'should generate hidden inputs with default value blank' do
|
|
1568
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => Post.find(:all).size)
|
|
1569
|
+
end
|
|
1570
|
+
|
|
1571
|
+
describe "each choice" do
|
|
1572
|
+
|
|
1573
|
+
it 'should contain a label for the radio input with a nested input and label text' do
|
|
1574
|
+
Post.find(:all).each do |post|
|
|
1575
|
+
output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
|
|
1576
|
+
output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
|
|
1577
|
+
end
|
|
1578
|
+
end
|
|
1579
|
+
|
|
1580
|
+
it 'should use values as li.class when value_as_class is true' do
|
|
1581
|
+
Post.find(:all).each do |post|
|
|
1582
|
+
output_buffer.should have_tag("form li fieldset ol li.#{post.id} label")
|
|
1583
|
+
end
|
|
1584
|
+
end
|
|
1585
|
+
|
|
1586
|
+
it 'should have a checkbox input for each post' do
|
|
1587
|
+
Post.find(:all).each do |post|
|
|
1588
|
+
output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
|
|
1589
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
|
|
1590
|
+
end
|
|
1591
|
+
end
|
|
1592
|
+
|
|
1593
|
+
it "should mark input as checked if it's the the existing choice" do
|
|
1594
|
+
Post.find(:all).include?(@fred.posts.first).should be_true
|
|
1595
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
|
|
1596
|
+
end
|
|
1597
|
+
end
|
|
1598
|
+
|
|
1599
|
+
describe 'and no object is given' do
|
|
1600
|
+
before(:each) do
|
|
1601
|
+
output_buffer.replace ''
|
|
1602
|
+
semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
|
1603
|
+
concat(builder.input(:author_id, :as => :check_boxes, :collection => Author.find(:all)))
|
|
1604
|
+
end
|
|
1605
|
+
end
|
|
1606
|
+
|
|
1607
|
+
it 'should generate a fieldset with legend' do
|
|
1608
|
+
output_buffer.should have_tag('form li fieldset legend', /Author/)
|
|
1609
|
+
end
|
|
1610
|
+
|
|
1611
|
+
it 'shold generate an li tag for each item in the collection' do
|
|
1612
|
+
output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
|
|
1613
|
+
end
|
|
1614
|
+
|
|
1615
|
+
it 'should generate labels for each item' do
|
|
1616
|
+
Author.find(:all).each do |author|
|
|
1617
|
+
output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
|
|
1618
|
+
output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
|
|
1619
|
+
end
|
|
1620
|
+
end
|
|
1621
|
+
|
|
1622
|
+
it 'should generate inputs for each item' do
|
|
1623
|
+
Author.find(:all).each do |author|
|
|
1624
|
+
output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
|
|
1625
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
|
|
1626
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
|
|
1627
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
|
|
1628
|
+
end
|
|
1629
|
+
end
|
|
1357
1630
|
end
|
|
1358
1631
|
end
|
|
1359
1632
|
end
|
|
@@ -1366,7 +1639,7 @@ describe 'Formtastic' do
|
|
|
1366
1639
|
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
|
|
1367
1640
|
end
|
|
1368
1641
|
|
|
1369
|
-
{ :select => :option, :radio => :input }.each do |type, countable|
|
|
1642
|
+
{ :select => :option, :radio => :input, :check_boxes => :'input[@type="checkbox"]' }.each do |type, countable|
|
|
1370
1643
|
|
|
1371
1644
|
describe ":as => #{type.inspect}" do
|
|
1372
1645
|
describe 'when the :collection option is not provided' do
|
|
@@ -1421,9 +1694,9 @@ describe 'Formtastic' do
|
|
|
1421
1694
|
concat(builder.input(:category_name, :as => type, :collection => @categories))
|
|
1422
1695
|
end
|
|
1423
1696
|
|
|
1424
|
-
@categories.each do |
|
|
1425
|
-
output_buffer.should have_tag("form li.#{type}", /#{
|
|
1426
|
-
output_buffer.should have_tag("form li.#{type} #{countable}[@value
|
|
1697
|
+
@categories.each do |value|
|
|
1698
|
+
output_buffer.should have_tag("form li.#{type}", /#{value}/)
|
|
1699
|
+
output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
|
|
1427
1700
|
end
|
|
1428
1701
|
end
|
|
1429
1702
|
|
|
@@ -1456,7 +1729,7 @@ describe 'Formtastic' do
|
|
|
1456
1729
|
|
|
1457
1730
|
@categories.each do |label, value|
|
|
1458
1731
|
output_buffer.should have_tag("form li.#{type}", /#{label}/)
|
|
1459
|
-
output_buffer.should have_tag("form li.#{type} #{countable}[@value
|
|
1732
|
+
output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
|
|
1460
1733
|
end
|
|
1461
1734
|
end
|
|
1462
1735
|
end
|
|
@@ -1469,12 +1742,13 @@ describe 'Formtastic' do
|
|
|
1469
1742
|
|
|
1470
1743
|
it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
|
|
1471
1744
|
semantic_form_for(@new_post) do |builder|
|
|
1472
|
-
concat(builder.input(:category_name, :as =>
|
|
1745
|
+
concat(builder.input(:category_name, :as => type, :collection => @categories))
|
|
1473
1746
|
end
|
|
1474
1747
|
|
|
1475
|
-
@categories.each do |
|
|
1476
|
-
|
|
1477
|
-
output_buffer.should have_tag(
|
|
1748
|
+
@categories.each do |text, value|
|
|
1749
|
+
label = type == :select ? :option : :label
|
|
1750
|
+
output_buffer.should have_tag("form li.#{type} #{label}", /#{text}/i)
|
|
1751
|
+
output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
|
|
1478
1752
|
end
|
|
1479
1753
|
end
|
|
1480
1754
|
end
|
|
@@ -1487,12 +1761,13 @@ describe 'Formtastic' do
|
|
|
1487
1761
|
|
|
1488
1762
|
it "should use the symbol as the label text and value for each #{countable}" do
|
|
1489
1763
|
semantic_form_for(@new_post) do |builder|
|
|
1490
|
-
concat(builder.input(:category_name, :as =>
|
|
1764
|
+
concat(builder.input(:category_name, :as => type, :collection => @categories))
|
|
1491
1765
|
end
|
|
1492
1766
|
|
|
1493
1767
|
@categories.each do |value|
|
|
1494
|
-
|
|
1495
|
-
output_buffer.should have_tag(
|
|
1768
|
+
label = type == :select ? :option : :label
|
|
1769
|
+
output_buffer.should have_tag("form li.#{type} #{label}", /#{value}/i)
|
|
1770
|
+
output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
|
|
1496
1771
|
end
|
|
1497
1772
|
end
|
|
1498
1773
|
end
|
|
@@ -1549,8 +1824,15 @@ describe 'Formtastic' do
|
|
|
1549
1824
|
end
|
|
1550
1825
|
|
|
1551
1826
|
end
|
|
1827
|
+
end
|
|
1828
|
+
end
|
|
1829
|
+
|
|
1830
|
+
describe 'for boolean attributes' do
|
|
1552
1831
|
|
|
1553
|
-
|
|
1832
|
+
{ :select => :option, :radio => :input }.each do |type, countable|
|
|
1833
|
+
checked_or_selected = { :select => :selected, :radio => :checked }[type]
|
|
1834
|
+
|
|
1835
|
+
describe ":as => #{type.inspect}" do
|
|
1554
1836
|
|
|
1555
1837
|
before do
|
|
1556
1838
|
@new_post.stub!(:allow_comments)
|
|
@@ -1598,8 +1880,6 @@ describe 'Formtastic' do
|
|
|
1598
1880
|
end
|
|
1599
1881
|
end
|
|
1600
1882
|
|
|
1601
|
-
checked_or_selected = { :select => :selected, :radio => :checked }[type]
|
|
1602
|
-
|
|
1603
1883
|
describe 'when the value is nil' do
|
|
1604
1884
|
before do
|
|
1605
1885
|
@new_post.stub!(:allow_comments).and_return(nil)
|
|
@@ -1667,7 +1947,6 @@ describe 'Formtastic' do
|
|
|
1667
1947
|
end
|
|
1668
1948
|
end
|
|
1669
1949
|
|
|
1670
|
-
|
|
1671
1950
|
end
|
|
1672
1951
|
end
|
|
1673
1952
|
end
|
|
@@ -1775,7 +2054,7 @@ describe 'Formtastic' do
|
|
|
1775
2054
|
concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
|
|
1776
2055
|
end
|
|
1777
2056
|
|
|
1778
|
-
output_buffer.should have_tag("form li
|
|
2057
|
+
output_buffer.should have_tag("form li input[@type='hidden'][@value='1']")
|
|
1779
2058
|
end
|
|
1780
2059
|
|
|
1781
2060
|
it 'should use default attribute value when it is not nil' do
|
|
@@ -1784,7 +2063,7 @@ describe 'Formtastic' do
|
|
|
1784
2063
|
concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
|
|
1785
2064
|
end
|
|
1786
2065
|
|
|
1787
|
-
output_buffer.should have_tag("form li
|
|
2066
|
+
output_buffer.should have_tag("form li input[@type='hidden'][@value='27']")
|
|
1788
2067
|
end
|
|
1789
2068
|
end
|
|
1790
2069
|
|
|
@@ -1857,16 +2136,25 @@ describe 'Formtastic' do
|
|
|
1857
2136
|
end
|
|
1858
2137
|
end
|
|
1859
2138
|
|
|
1860
|
-
|
|
1861
|
-
|
|
2139
|
+
describe 'when no object is given' do
|
|
2140
|
+
before(:each) do
|
|
2141
|
+
output_buffer.replace ''
|
|
2142
|
+
semantic_form_for(:project, :url => 'http://test.host') do |@builder|
|
|
2143
|
+
concat(@builder.input(:publish_at, :as => :datetime))
|
|
2144
|
+
end
|
|
2145
|
+
end
|
|
1862
2146
|
|
|
1863
|
-
|
|
1864
|
-
|
|
2147
|
+
it 'should have fieldset with legend' do
|
|
2148
|
+
output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
|
|
1865
2149
|
end
|
|
1866
2150
|
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2151
|
+
it 'should have labels for each input' do
|
|
2152
|
+
output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
|
|
2153
|
+
end
|
|
2154
|
+
|
|
2155
|
+
it 'should have selects for each inputs' do
|
|
2156
|
+
output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
|
|
2157
|
+
end
|
|
1870
2158
|
end
|
|
1871
2159
|
end
|
|
1872
2160
|
|
|
@@ -1903,8 +2191,9 @@ describe 'Formtastic' do
|
|
|
1903
2191
|
output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
|
|
1904
2192
|
end
|
|
1905
2193
|
|
|
1906
|
-
it 'should have
|
|
1907
|
-
output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
|
|
2194
|
+
it 'should have two selects for hour and minute' do
|
|
2195
|
+
#output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
|
|
2196
|
+
output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
|
|
1908
2197
|
end
|
|
1909
2198
|
end
|
|
1910
2199
|
|
|
@@ -1983,7 +2272,6 @@ describe 'Formtastic' do
|
|
|
1983
2272
|
end
|
|
1984
2273
|
end
|
|
1985
2274
|
|
|
1986
|
-
|
|
1987
2275
|
describe '#inputs' do
|
|
1988
2276
|
|
|
1989
2277
|
describe 'with a block' do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: justinfrench-formtastic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin French
|
|
@@ -9,7 +9,7 @@ autorequire: formtastic
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-
|
|
12
|
+
date: 2009-05-21 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|
|
@@ -25,24 +25,19 @@ files:
|
|
|
25
25
|
- MIT-LICENSE
|
|
26
26
|
- README.textile
|
|
27
27
|
- Rakefile
|
|
28
|
-
- rails/init.rb
|
|
29
|
-
- lib/formtastic.rb
|
|
30
|
-
- lib/justin_french
|
|
31
|
-
- lib/justin_french/formtastic.rb
|
|
32
|
-
- lib/locale
|
|
33
|
-
- lib/locale/en.yml
|
|
34
|
-
- generators/formtastic_stylesheets
|
|
35
28
|
- generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb
|
|
36
|
-
- generators/formtastic_stylesheets/templates
|
|
37
29
|
- generators/formtastic_stylesheets/templates/formtastic.css
|
|
38
30
|
- generators/formtastic_stylesheets/templates/formtastic_changes.css
|
|
31
|
+
- lib/formtastic.rb
|
|
32
|
+
- lib/justin_french/formtastic.rb
|
|
33
|
+
- lib/locale/en.yml
|
|
34
|
+
- rails/init.rb
|
|
39
35
|
- spec/formtastic_spec.rb
|
|
40
36
|
- spec/test_helper.rb
|
|
41
|
-
has_rdoc:
|
|
37
|
+
has_rdoc: false
|
|
42
38
|
homepage: http://github.com/justinfrench/formtastic/tree/master
|
|
43
39
|
post_install_message:
|
|
44
40
|
rdoc_options:
|
|
45
|
-
- --inline-source
|
|
46
41
|
- --charset=UTF-8
|
|
47
42
|
require_paths:
|
|
48
43
|
- lib
|
|
@@ -63,7 +58,8 @@ requirements: []
|
|
|
63
58
|
rubyforge_project:
|
|
64
59
|
rubygems_version: 1.2.0
|
|
65
60
|
signing_key:
|
|
66
|
-
specification_version:
|
|
61
|
+
specification_version: 3
|
|
67
62
|
summary: A Rails form builder plugin/gem with semantically rich and accessible markup
|
|
68
|
-
test_files:
|
|
69
|
-
|
|
63
|
+
test_files:
|
|
64
|
+
- spec/formtastic_spec.rb
|
|
65
|
+
- spec/test_helper.rb
|