splendeo-dependent_select 0.5.3 → 0.6.0

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.
@@ -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.