splendeo-dependent_select 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,6 +6,8 @@ depending on other fields"
6
6
 
7
7
  Demo application can be found in http://github.com/splendeo/dependent_select
8
8
 
9
+ Mailing list on http://groups.google.com/group/dependent_select/
10
+
9
11
  ==Quick example: Store with country and province
10
12
 
11
13
  On your layout:
@@ -18,9 +20,9 @@ On your new/edit views:
18
20
  Country:<br/>
19
21
  <% f.collection_select :country_id, @countries, :id, :name, :include_blanks => true %> <br />
20
22
  Province:<br/>
21
- <% f.collection_select :province_id, @provinces, :id, :name, :country_id, :include_blanks => true %> <br />
23
+ <% f.dependent_collection_select :province_id, @provinces, :id, :name, :country_id, :include_blanks => true %> <br />
22
24
  City:<br/>
23
- <% f.collection_select :city_id, @cities, :id, :name, :province_id, :include_blanks => true %> <br />
25
+ <% f.dependent_collection_select :city_id, @cities, :id, :name, :province_id, :include_blanks => true %> <br />
24
26
  <% end %>
25
27
 
26
28
  In order for this to work properly, the Store model must have methods for +country_id+ and +store_id+.
@@ -1,6 +1,8 @@
1
1
  # Various helpers available for use in your view
2
2
  module DependentSelect::FormHelpers
3
3
 
4
+ @used_array_names = {}
5
+
4
6
  # Similar to collection_select form helper, but adds a "filter_method" parameter
5
7
  # the generated code includes a javascript observer that modifies the select
6
8
  # using the value of a form method.
@@ -29,7 +31,7 @@ module DependentSelect::FormHelpers
29
31
  # +html_options+:: (Optional)The same html options as +collection_select+.
30
32
  # They are appended to the html +select+ as attributes.
31
33
  # == Options
32
- # In addition to all options for +collection_select+, two new options are available
34
+ # In addition to all options for +collection_select+, several new options are available
33
35
  #
34
36
  # === :collapse_spaces
35
37
  # By default, blank spaces are collapsed on browsers when printing the select option texts
@@ -44,6 +46,34 @@ module DependentSelect::FormHelpers
44
46
  #
45
47
  # option_text.replace(/ /g, "\240"); // "\240" is the octal representation of charcode 160 (nbsp)
46
48
  #
49
+ # On the following example, a sale occurs on a store that belongs to a company. The store model
50
+ # has a method called +name_for_selects+ that prints a two-column text - the first column has
51
+ # the company name on it, while the second has the store address. They are separated by a '|'
52
+ # character, and padded with spaces when necesary (company name has 10 chars or less)
53
+ #
54
+ # class Store < ActiveRecord::Model
55
+ # belongs_to :company
56
+ # has_many :sales
57
+ # validates_presence_of :address
58
+ #
59
+ # def name_for_selects
60
+ # "#{company.name.ljust(10)} | #{address}"
61
+ # end
62
+ # end
63
+ #
64
+ # Now on the edit/new sale view, we will need to use the :collapse_spaces option like this:
65
+ #
66
+ # <%= dependent_collection_select(:sale, :store_id, @stores, :id, :name_for_selects, :company_id,
67
+ # {:collapse_spaces => true}, {:class => 'monospaced'})
68
+ # %>
69
+ #
70
+ # It is recommended that you use this function in conjunction with a monospaced css style. The following
71
+ # rule should be available, for example on application.css:
72
+ #
73
+ # .monospaced {
74
+ # font-family: monospaced;
75
+ # }
76
+ #
47
77
  # === :filter_field
48
78
  # The javascript employed for updating the dependent select needs a field for getting
49
79
  # the "filter value". The default behaviour is calculating this field name by using the
@@ -65,17 +95,48 @@ module DependentSelect::FormHelpers
65
95
  # Notice that the chain 'sale_' is still appended to the field name. It is possible to override this
66
96
  # by using the +:complete_filter_field+ option istead of this one.
67
97
  #
98
+ # The most common use of this property will be for dealing with multiple relationships between the same
99
+ # models. See the complex example below for details.
100
+ #
68
101
  # === :complete_filter_field
69
102
  # Works the same way as :filter_field, except that it uses its value directly, instead
70
103
  # of appending the :object_name at all. For example:
71
104
  #
72
- # <%= dependent_collection_select (:sale, :province_id, @provinces, :id, :name,
105
+ # <%= dependent_collection_select(:sale, :province_id, @provinces, :id, :name,
73
106
  # :country_id, {:complete_filter_field => :the_province})
74
107
  # %>
75
108
  #
76
109
  # This will make the javascript to look for a field called +'the_province'+ on the
77
110
  # page, and use its value for filtering.
78
111
  #
112
+ # === :array_name
113
+ # dependent_select generates a javascript array with all the options available to the dependent select.
114
+ # By default, the name of that variable is automatically generated using the following formula:
115
+ #
116
+ # js_array_name = "ds_#{object_name}_#{method}_array"
117
+ #
118
+ # This can be overriden by using the js_array_name option (its value will be used instead of the previous)
119
+ #
120
+ # This is useful because, by default, dependant_select forms will keep track of generated arrays, and *will not*
121
+ # generate the same array twice. This is very useful for situations in which lots of dependent_selects have
122
+ # to be generated, with the same data. For example, a flight has a destination and origin city:
123
+ #
124
+ # <%= dependent_collection_select( :flight, :origin_city_id, @cities, :id, :name, :province_id,
125
+ # { :filter_field => :origin_province_id, js_array_name => 'cities_array' }
126
+ # %>
127
+ #
128
+ # <%= dependent_collection_select( :flight, :destination_city_id, @cities, :id, :name, :province_id,
129
+ # { :filter_field => :destination_province_id, js_array_name => 'cities_array' }
130
+ # %>
131
+ #
132
+ # This example will generate the first javascript array and call it cities_array. Then the second
133
+ # call to +dependent_select+ is done, the form will already know that the javascript for this script
134
+ # is generated, so it will not generate an array.
135
+ #
136
+ # The +:array_name+ option can also be used in the opposite way: to force the generation of an array.
137
+ # This should happen very rarely - two dependent selects generate the same object name and method but are not
138
+ # supposed to use the same list of values.
139
+ #
79
140
  # == Examples
80
141
  #
81
142
  # === Example 1: A store on a City
@@ -182,25 +243,28 @@ module DependentSelect::FormHelpers
182
243
  # </p><p>
183
244
  # Import Province:
184
245
  # <%= dependent_collection_select :store, :import_province_id, @provinces, :id, :name,
185
- # :country_id, :filter_field => :import_country_id
246
+ # :country_id, :filter_field => :import_country_id, :array_name => 'provinces_array'
186
247
  # %>
187
248
  # </p><p>
188
249
  # Import City:
189
250
  # <%= dependent_collection_select :store, :import_city_id, @cities, :id, :name,
190
- # :province_id, :filter_field => :import_province_id %>
251
+ # :province_id, :filter_field => :import_province_id, :array_name => 'cities_array'
252
+ # %>
191
253
  # </p><p>
192
254
  # Export Country:
193
255
  # <%= collection_collection_select :store, :export_country_id, @countries, :id, :name %>
194
256
  # </p><p>
195
257
  # Export Province:
196
258
  # <%= dependent_collection_select :store, :export_province_id, @provinces, :id, :name,
197
- # :country_id, :filter_field => :export_country_id
259
+ # :country_id, :filter_field => :export_country_id, :array_name => 'provinces_array'
198
260
  # %>
199
261
  # </p><p>
200
262
  # Export City:
201
263
  # <%= dependent_select :store, :export_city_id, @cities, :id, :name,
202
- # :province_id, :filter_field => :export_province_id %>
264
+ # :province_id, :filter_field => :export_province_id, :array_name => 'cities_array'
265
+ # %>
203
266
  # </p>
267
+ # Notice the use of +:array_name+. This is optional, but greatly reduces the amount of js code generated
204
268
  #
205
269
  def dependent_collection_select(object_name, method, collection, value_method,
206
270
  text_method, filter_method, options = {}, html_options = {}
@@ -285,7 +349,7 @@ module DependentSelect::FormHelpers
285
349
  # extracts any options passed into calendar date select, appropriating them to either the Javascript call or the html tag.
286
350
  def dependent_select_process_options(options)
287
351
  options, extra_options = DependentSelect.default_options.merge(options), {}
288
- for key in [:collapse_spaces, :filter_field, :complete_filter_field]
352
+ for key in [:collapse_spaces, :filter_field, :complete_filter_field, :array_name]
289
353
  extra_options[key] = options.delete(key) if options.has_key?(key)
290
354
  end
291
355
 
@@ -304,8 +368,14 @@ module DependentSelect::FormHelpers
304
368
  filter_method, options, extra_options)
305
369
 
306
370
  # the js variable that will hold the array with option values, texts and filters
307
- js_array_name = "ds_#{object_name}_#{method}_array"
308
-
371
+ js_array_name = extra_options[:array_name] || "ds_#{object_name}_#{method}_array"
372
+
373
+ js_array_code = ""
374
+
375
+ if(@used_array_names[js_array_name].nil?)
376
+ js_array_code += "#{js_array_name} = #{choices_with_filter.to_json};\n"
377
+ end
378
+
309
379
  dependent_id = dependent_select_calculate_id(object_name, method)
310
380
  observed_id = dependent_select_calculate_observed_field_id(object_name, filter_method, extra_options)
311
381
  initial_value = dependent_select_initial_value(object, method)
@@ -316,7 +386,7 @@ module DependentSelect::FormHelpers
316
386
  "function(e) { update_dependent_select( '#{dependent_id}', '#{observed_id}', #{js_array_name}, " +
317
387
  "'#{initial_value}', #{include_blank}, #{collapse_spaces}, false); }"
318
388
 
319
- javascript_tag( "#{js_array_name} = #{choices_with_filter.to_json};\n" +
389
+ javascript_tag(js_array_code +
320
390
  "$('#{observed_id}').observe ('change', #{js_callback});\n" +
321
391
  "$('#{observed_id}').observe ('DependentSelectFormBuilder:change', #{js_callback}); \n" +
322
392
  "update_dependent_select( '#{dependent_id}', '#{observed_id}', #{js_array_name}, " +
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splendeo-dependent_select
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Enrique Garcia Cota (egarcia)
@@ -31,7 +31,6 @@ files:
31
31
  - README.rdoc
32
32
  has_rdoc: true
33
33
  homepage: http://github.com/splendeo/dependent_select
34
- licenses:
35
34
  post_install_message:
36
35
  rdoc_options:
37
36
  - --charset=UTF-8
@@ -52,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
51
  requirements: []
53
52
 
54
53
  rubyforge_project:
55
- rubygems_version: 1.3.5
54
+ rubygems_version: 1.2.0
56
55
  signing_key:
57
56
  specification_version: 2
58
57
  summary: generates a select with some js code that updates if if another field is modified.