record_collection 0.3.2

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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +217 -0
  7. data/Rakefile +16 -0
  8. data/app/assets/images/record_collection/.keep +0 -0
  9. data/app/assets/javascripts/record_collection/application.js.coffee +1 -0
  10. data/app/assets/javascripts/record_collection/multi_select.js.coffee +66 -0
  11. data/app/assets/javascripts/record_collection/optionals.js.coffee +101 -0
  12. data/app/assets/stylesheets/record_collection/application.css +15 -0
  13. data/app/assets/stylesheets/record_collection/multi_select.css.sass +20 -0
  14. data/app/assets/stylesheets/record_collection/optionals.css.sass +48 -0
  15. data/app/controllers/record_collection/application_controller.rb +4 -0
  16. data/app/helpers/record_collection/application_helper.rb +4 -0
  17. data/app/views/layouts/record_collection/application.html.erb +14 -0
  18. data/lib/record_collection.rb +12 -0
  19. data/lib/record_collection/base.rb +98 -0
  20. data/lib/record_collection/engine.rb +5 -0
  21. data/lib/record_collection/name.rb +7 -0
  22. data/lib/record_collection/rails/form_options_helper.rb +48 -0
  23. data/lib/record_collection/rails/routes.rb +21 -0
  24. data/lib/record_collection/version.rb +3 -0
  25. data/record_collection.gemspec +43 -0
  26. data/spec/dummy/README.rdoc +28 -0
  27. data/spec/dummy/Rakefile +6 -0
  28. data/spec/dummy/app/assets/images/.keep +0 -0
  29. data/spec/dummy/app/assets/javascripts/application.js.coffee +10 -0
  30. data/spec/dummy/app/assets/stylesheets/application.css.sass +4 -0
  31. data/spec/dummy/app/assets/stylesheets/components/_forms.css.sass +0 -0
  32. data/spec/dummy/app/assets/stylesheets/components/_structure.css.sass +0 -0
  33. data/spec/dummy/app/assets/stylesheets/scaffolds.scss +69 -0
  34. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  35. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  36. data/spec/dummy/app/controllers/employees_controller.rb +75 -0
  37. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  38. data/spec/dummy/app/mailers/.keep +0 -0
  39. data/spec/dummy/app/models/.keep +0 -0
  40. data/spec/dummy/app/models/concerns/.keep +0 -0
  41. data/spec/dummy/app/models/employee.rb +2 -0
  42. data/spec/dummy/app/models/employee/collection.rb +6 -0
  43. data/spec/dummy/app/models/project.rb +2 -0
  44. data/spec/dummy/app/views/application/_form_errors.html.slim +8 -0
  45. data/spec/dummy/app/views/employees/_form.html.erb +25 -0
  46. data/spec/dummy/app/views/employees/batch_actions.html.slim +13 -0
  47. data/spec/dummy/app/views/employees/edit.html.erb +6 -0
  48. data/spec/dummy/app/views/employees/index.html.slim +25 -0
  49. data/spec/dummy/app/views/employees/new.html.erb +5 -0
  50. data/spec/dummy/app/views/employees/show.html.erb +14 -0
  51. data/spec/dummy/app/views/layouts/application.html.slim +10 -0
  52. data/spec/dummy/bin/bundle +3 -0
  53. data/spec/dummy/bin/rails +4 -0
  54. data/spec/dummy/bin/rake +4 -0
  55. data/spec/dummy/bin/setup +29 -0
  56. data/spec/dummy/config.ru +4 -0
  57. data/spec/dummy/config/application.rb +26 -0
  58. data/spec/dummy/config/boot.rb +5 -0
  59. data/spec/dummy/config/database.yml +25 -0
  60. data/spec/dummy/config/environment.rb +5 -0
  61. data/spec/dummy/config/environments/development.rb +41 -0
  62. data/spec/dummy/config/environments/production.rb +79 -0
  63. data/spec/dummy/config/environments/test.rb +42 -0
  64. data/spec/dummy/config/initializers/assets.rb +11 -0
  65. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  66. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  67. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  68. data/spec/dummy/config/initializers/inflections.rb +16 -0
  69. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  70. data/spec/dummy/config/initializers/session_store.rb +3 -0
  71. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  72. data/spec/dummy/config/locales/en.yml +23 -0
  73. data/spec/dummy/config/locales/models.en.yml +5 -0
  74. data/spec/dummy/config/routes.rb +3 -0
  75. data/spec/dummy/config/secrets.yml +22 -0
  76. data/spec/dummy/db/migrate/20150203124634_create_employees.rb +10 -0
  77. data/spec/dummy/db/migrate/20150204103712_add_vegan_to_employees.rb +5 -0
  78. data/spec/dummy/db/migrate/20150204103925_add_admin_to_employees.rb +5 -0
  79. data/spec/dummy/db/migrate/20150204125014_create_projects.rb +11 -0
  80. data/spec/dummy/db/schema.rb +33 -0
  81. data/spec/dummy/lib/assets/.keep +0 -0
  82. data/spec/dummy/log/.keep +0 -0
  83. data/spec/dummy/public/404.html +67 -0
  84. data/spec/dummy/public/422.html +67 -0
  85. data/spec/dummy/public/500.html +66 -0
  86. data/spec/dummy/public/favicon.ico +0 -0
  87. data/spec/features/multi_select_spec.rb +23 -0
  88. data/spec/fixtures/collections.rb +0 -0
  89. data/spec/record_selection/base_spec.rb +113 -0
  90. data/spec/spec_helper.rb +26 -0
  91. data/spec/validations_spec.rb +19 -0
  92. metadata +482 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 57c83b9fc9b46bcfed66a78f8966f8a71a48cee6
4
+ data.tar.gz: 0c28f323778b1c26db44f619ebe7814cdc435263
5
+ SHA512:
6
+ metadata.gz: 0833cd40aa97cf4c08af7be2feff96543b776eb024bb2ccd287b8b081fd3d492eb919e5b97ae7b29669fdced058c1191b49b1eb2f4b97f8da3e4b9b6c9160441
7
+ data.tar.gz: 9e7768139cba271ec1d58fb48c8e166609547708ee341d41a599d3de05751dfcfd15ae7aa87edc8961b92f17419d744126e55cb0a9ad9ebec11dcf17b9ae6c2c
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ /.yardoc
2
+ /Gemfile.lock
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.bundle
10
+ *.so
11
+ *.o
12
+ *.a
13
+ mkmf.log
14
+ /temt
15
+ .bundle/
16
+ log/*.log
17
+ pkg/
18
+ spec/dummy/db/*.sqlite3
19
+ spec/dummy/db/*.sqlite3-journal
20
+ spec/dummy/log/*.log
21
+ spec/dummy/tmp/
22
+ spec/dummy/spec/
23
+ spec/dummy/.sass-cache
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in record_collection.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Benjamin ter Kuile
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,217 @@
1
+ # RecordCollection
2
+ [<img src="https://secure.travis-ci.org/bterkuile/record_collection.png?branch=master" alt="Build Status" />](http://travis-ci.org/bterkuile/record_collection)
3
+
4
+ record\_collection is a gem that adds functionality to rails to work
5
+ with collections. This consists of a few components:
6
+
7
+ * Collection objects containing some active record models and acting on
8
+ that collection.
9
+ * the multi\_select helpers for selecting records from the index page
10
+ * the optionals helpers for managing attributes on the collection of
11
+ records you may or may not want to edit in the collection form
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'record_collection'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install record_collection
28
+
29
+ ## Adding routes
30
+ Add two collection routes to the normal resources definition.
31
+ This call behaves exactly as the normal resources :... call,
32
+ but adds:
33
+ ```ruby
34
+ collection do
35
+ get :batch_actions
36
+ post :process_batch
37
+ end
38
+ ```
39
+ So the route definition in `config/routes.rb` defined as:
40
+ ```ruby
41
+ batch_resources :employees, except: [:new]
42
+ ```
43
+ is exactly the same as:
44
+ ```ruby
45
+ resources :employees, except: [:new] do
46
+ collection do
47
+ get :batch_actions
48
+ post :process_batch
49
+ end
50
+ end
51
+ ```
52
+
53
+ ## Defining the collection
54
+ A good practice is to define your collection as a subclass of your
55
+ resource class. So an employees collection should be defined like:
56
+ `app/models/employee.rb`:
57
+ ```ruby
58
+ class Employee < ActiveRecord::Base
59
+ # attribute :admin, type: Boolean (defined by database)
60
+ validates :name, presence: true
61
+
62
+ end
63
+ ```
64
+ `app/models/employee/collection.rb`:
65
+ ```ruby
66
+ class Employee::Collection < RecordCollection::Base
67
+ attribute :name
68
+ validates :section, format: {with: /\A\w{3}\Z/, if: 'section.present?' }
69
+ attribute :admin, type: Boolean
70
+ attribute :vegan, type: Boolean
71
+ end
72
+ ```
73
+ See the [active_attr](https://github.com/cgriego/active_attr) gem for
74
+ attribute definitions.
75
+
76
+ ## Defining your controllers
77
+ If you already used the specification `batch_resources :employees` in
78
+ your [config/routes.rb](spec/dummy/config/routes.rb) file you can add
79
+ the actions in your controller typically looking like:
80
+ ```ruby
81
+ class EmployeesController < ApplicationController
82
+ # your standard actions here
83
+
84
+ # GET /employees/batch_actions?ids[]=1&ids[]=3&...
85
+ def batch_actions
86
+ @employees = Employee.find(Array.wrap(params[:ids]))
87
+ @collection = Employee::Collection.new(@employees)
88
+ redirect_to employees_path, alert: 'No employees selected' if @collection.empty?
89
+ end
90
+
91
+ # POST /employees/process_batch
92
+ def process_batch
93
+ @employees = Employee.find(Array.wrap(params[:ids]))
94
+ @collection = Employee::Collection.new(@employees, params[:collection])
95
+ if @collection.save
96
+ redirect_to employees_path, notice: 'Collection is updated'
97
+ else
98
+ render 'batch_actions'
99
+ end
100
+ end
101
+ end
102
+ ```
103
+ For more advanced use of the collection the pattern above can of course
104
+ be different eg: different collection objects for the same active record
105
+ model types.
106
+
107
+ ## Creating your views
108
+ The
109
+ [app/views/employess/batch_actions.html.slim](spec/dummy/app/views/employees/batch_actions.html.slim) view is a tricky one.
110
+ Since we are working on a collection of record, and want to edit those
111
+ attributes we just want a normal form for editing the attributes,
112
+ treating the collection as the record itself. The problem however is
113
+ that some attributes can be in a mixed state, say two employees, one
114
+ having `admin => true`, the other one `admin => false`. If I only want
115
+ to update the section they are both in, I want to leave the admin
116
+ attribute allone. To accomplish this, this gem provides the `optional`
117
+ helpers. These helpers make it easy to manage a form of attributes where
118
+ you can determine which attributes you want to manage for this
119
+ particular collection of records. This gem also support [simple_form](https://github.com/plataformatec/simple_form)
120
+ gem where you can replace `f.input :attribute, ...etc` with
121
+ `f.optional_input :attribute, ...etc`. Our current example works with
122
+ the standard [form_helpers](http://guides.rubyonrails.org/form_helpers.html)<br>
123
+ ### currently supported helpers:
124
+ * `optional_boolean`
125
+ * `optional_text_field`
126
+ * `optional_input` ([simple_form](https://github.com/plataformatec/simple_form))
127
+
128
+ The form you create typically looks like:
129
+ ```slim
130
+ h1 Edit multiple employees
131
+ = form_for @collection, url: [:process_batch, @collection.record_class] do |f|
132
+ = f.collection_ids
133
+ .form-inputs= f.optional_text_field :section
134
+ .form-inputs= f.optional_boolean :admin
135
+ .form-inputs= f.optional_boolean :vegan
136
+ .form-actions= f.submit
137
+ .page-actions
138
+ = link_to 'Back', employees_path
139
+ ```
140
+
141
+ That is the view part. Be sure to read the optionals section for a
142
+ better understanding of how the optional fields work.
143
+
144
+ ## Selecting records from the index using checkboxes (multi_select)
145
+ The idea behind working with collections is that you end up as a `GET` request at:
146
+ `+controller+/batch_actions?ids[]=2&ids[]=3` etc. How you achieve this
147
+ is totally up to yourself, but this gem provides you with a nice
148
+ standard way of selecting records from the index page. To filter records
149
+ to a specific subset the [ransack](https://github.com/activerecord-hackery/ransack)
150
+ gem also provides a nice way to add filtering to the index page. To add
151
+ checkbox selecting to your page this gem assumes the following
152
+ structure using the [Slim lang](http://slim-lang.com/):
153
+ ```slim
154
+ table.with-selection
155
+ thead
156
+ tr
157
+ th Name
158
+ th Section
159
+ tbody
160
+ - @employees.each do |employee|
161
+ tr data-record=employee.attributes.to_json
162
+ ```
163
+ Note that each row needs a json version of the record at least
164
+ containing its id.<br>
165
+ Implement the multiselect dependencies in your manifest files, typically
166
+ being `app/assets/javascripts/application.js`:
167
+ ```javascript
168
+ //= require record_collection/multi_select
169
+ ```
170
+ And for the styling provided by this gem ([app/assets/stylesheets/application.css](spec/dummy/app/assets/stylesheets/application.css.sass)):
171
+ ```css
172
+ /*
173
+ *= require record_collection/multi_select
174
+ */
175
+ ```
176
+ The styling uses the [font-awesome-rails](http://fortawesome.github.io/Font-Awesome/) gem, so this gem should be
177
+ present in your `Gemfile`:
178
+ ```ruby
179
+ gem 'font-awesome-rails'
180
+ ```
181
+ Of course you are welcome to create your own awesome styling and send it
182
+ to me so I can add it as a theme :smile:.
183
+
184
+ ## Optionals
185
+ Optionals is the name for the feature in this gem that activates
186
+ collection attributes to be sumitted in the form or not. Since for a
187
+ mixed collection on an attribute you might not want to edit, but another
188
+ attribute you do want to edit you add the optionals functionality to
189
+ your manifests. This is similar to the `multi_select` feature:
190
+ ```javascript
191
+ //= require record_collection/optionals
192
+ ```
193
+ And for the styling provided by this gem ([app/assets/stylesheets/application.css](spec/dummy/app/assets/stylesheets/application.css.sass)):
194
+ ```css
195
+ /*
196
+ *= require record_collection/optionals
197
+ */
198
+ ```
199
+
200
+ **TODO: more explanation about optionals**
201
+
202
+ ## Special thanks
203
+
204
+ Special thanks for this project goes to:<br>
205
+ <a href="http://companytools.nl/" target="_blank"><img src="http://companytools.nl/assets/logo2-f5f9a19c745e753a4d52b5c0a1a7c6d7.png" alt="Companytools"></a>
206
+ &nbsp;&nbsp;
207
+ <a href="http://fourstack.nl" target="_blank"><img src="http://fourstack.nl/logo1.png" alt="FourStack"></a>
208
+ &nbsp;&nbsp;
209
+ <a href="http://www.kpn.com" target="_blank"><img src="http://www.kpn.com/ss/Satellite/yavUnLl8hN7yMh6Gh2IPWqYD60HbUkXsNK4iD8PcUpR0bnBXyZZtwQUuCgSUG72CJE/MungoBlobs/kpn_logo.png"></a>
210
+
211
+ ## Contributing
212
+
213
+ 1. Fork it ( https://github.com/bterkuile/record_collection/fork )
214
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
215
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
216
+ 4. Push to the branch (`git push origin my-new-feature`)
217
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+ require "bundler/gem_tasks"
7
+
8
+ require 'rspec/core'
9
+ require 'rspec/core/rake_task'
10
+
11
+ desc "Run all specs in spec directory (excluding plugin specs)"
12
+ #RSpec::Core::RakeTask.new(spec: 'app:db:test:prepare')
13
+ RSpec::Core::RakeTask.new(:spec)
14
+
15
+ task default: :spec
16
+
File without changes
@@ -0,0 +1 @@
1
+ #= require_tree .
@@ -0,0 +1,66 @@
1
+ class MultiSelect
2
+ setup: (table) ->
3
+ return unless table and table.length
4
+ table.data 'multi_select', @
5
+ @set 'table', table
6
+
7
+ @set 'resource', table.data('resource')
8
+ # Add an extra th to all header rows
9
+ table.find('thead tr').each -> $(this).prepend("<th></th>")
10
+
11
+ # Create a toggle for selecting an deselecting all records
12
+ # and add it to the last header row
13
+ #toggle_all = $("<input type='checkbox'></input>").addClass('selection-toggle-all').click ->
14
+ #checked = $(this).is(':checked')
15
+ #table.find('td.selection input').prop 'checked', checked
16
+ toggle_all = $("<span></span>").addClass('selection-toggle-all unchecked').click ->
17
+ if $(this).hasClass('checked')
18
+ table.find('td.selection .checker').removeClass('checked').addClass('unchecked')
19
+ $(this).removeClass('checked').addClass('unchecked')
20
+ else
21
+ table.find('td.selection .checker').removeClass('unchecked').addClass('checked')
22
+ $(this).removeClass('unchecked').addClass('checked')
23
+ table.find('thead tr:last th:first').append toggle_all
24
+
25
+ # Create a toggle/checkbox for all records and add it to the row
26
+ #record_toggle = $("<input type='checkbox'></input>")
27
+ record_toggle = $("<span></span>").addClass('checker unchecked').click ->
28
+ if $(this).hasClass('checked')
29
+ $(this).removeClass('checked').addClass('unchecked')
30
+ else
31
+ $(this).removeClass('unchecked').addClass('checked')
32
+ record_td = $('<td></td>').addClass('selection').append(record_toggle)
33
+ table.find('tbody tr').prepend record_td
34
+
35
+ @setup_selection_actions()
36
+
37
+ toggle_all.click() if table.data('preselected')
38
+
39
+ # Find all buttons in the table footer and attach the action given their action data attribute
40
+ setup_selection_actions: ->
41
+ selector = this
42
+ @table.find('tfoot button').click ->
43
+ $.post Routes["actions_#{selector.get('resource')}_path"](),
44
+ ids: selector.selected_ids().toArray()
45
+ selection_action: $(this).data('action')
46
+
47
+ # use set and get as a good reactive pattern
48
+ # implement the raw version, can become more complex int the future
49
+ set: (path, value) -> @[path] = value
50
+ get: (path) -> @[path]
51
+
52
+ #selected_records: -> @table.find("td.selection input:checked").map( -> $(this).parents('tr').data('record') )
53
+ selected_records: -> @table.find("td.selection .checked").map( -> $(this).parents('tr').data('record') )
54
+ selected_ids: -> @selected_records().map( -> this.id ).toArray()
55
+ root = @
56
+ root.MultiSelect = new MultiSelect()
57
+ $.fn.multi_select = ->
58
+ if @.hasClass('with-selection') or @.prop('tagName') is 'TABLE'
59
+ select = new MultiSelect()
60
+ root.MultiSelect = select
61
+ select.setup @
62
+ else
63
+ @.find('table.with-selection').each (i, el)->
64
+ select = new MultiSelect()
65
+ root.MultiSelect = select
66
+ select.setup $(el)
@@ -0,0 +1,101 @@
1
+ class Optionals
2
+ setup: (target)->
3
+ @setup_inputs(target)
4
+
5
+ setup_inputs: (target)->
6
+ target.find('.optional-attribute-container').each (i, el)=>
7
+ container = $(el)
8
+ if container.hasClass('optional-boolean')
9
+ @optionalBoolean container
10
+ else
11
+ @prependActivator(container)
12
+
13
+ # Replace the <input type="checkbox"> for a <input type="hidden" # value="0|1"> fields
14
+ # managed by the javascript
15
+ optionalBoolean: (container)->
16
+ check_box = container.find('input')
17
+ initially_checked = check_box.is(':checked')
18
+ field_name = check_box.attr('name')
19
+
20
+ label_text = container.find('label').text()
21
+
22
+ value_field = $('<input>').attr('type', 'hidden').val(0)
23
+ # Set name based on activated state
24
+ if container.hasClass('active')
25
+ value_field.attr 'name', field_name
26
+ else
27
+ value_field.attr 'name', "disabled_#{field_name}"
28
+
29
+ # Clear the container and initialize to inactive
30
+ container.html('')
31
+
32
+ label = $('<span></span>').addClass('optional-boolean-label').text label_text
33
+
34
+ activator_toggle = $('<span></span>').addClass('optional-boolean-activator-toggle').click ->
35
+ container.toggleClass('active').toggleClass('inactive')
36
+ if container.hasClass('active')
37
+ value_field.attr 'name', value_field.attr('name').replace(/^disabled_/, '')
38
+ else
39
+ value_field.attr 'name', "disabled_#{value_field.attr('name')}"
40
+
41
+ value_toggle = $('<span></span>').addClass('optional-boolean-toggle').click ->
42
+ return if container.hasClass('inactive')
43
+ if $(@).hasClass('active')
44
+ value_field.val(0)
45
+ $(@).removeClass('active').addClass('inactive')
46
+ else
47
+ value_field.val(1)
48
+ $(@).addClass('active').removeClass('inactive')
49
+
50
+ if initially_checked
51
+ value_toggle.addClass('active')
52
+ value_field.val(1)
53
+ else
54
+ value_toggle.addClass('inactive')
55
+
56
+ container.append activator_toggle
57
+ container.append label
58
+ container.append value_toggle
59
+ container.append value_field
60
+
61
+ prependActivator: (container)->
62
+ value_field = container.find('select,input')
63
+ # INITIAL STATE IS DISABLED, Activation by triggering click if needed
64
+ value_field.attr 'name', "disabled_#{value_field.attr('name')}"
65
+
66
+ label_text = container.find('label').text()
67
+
68
+ # Activator container
69
+ activator_container = $('<div></div>').addClass('optional-input-activator-container inactive')
70
+ activator_container.addClass container.data('attribute')
71
+ activator_container.addClass('error') if container.hasClass('error')
72
+ activator_toggle = $('<span></span>').addClass('optional-input-activator-toggle').click ->
73
+ activator_container.toggleClass('active').toggleClass('inactive')
74
+ #label.toggleClass('inactive')
75
+ if activator_container.hasClass('active')
76
+ value_field.attr 'name', value_field.attr('name').replace(/^disabled_/, '')
77
+ #value_toggle.show()
78
+ container.removeClass('inactive')
79
+ else
80
+ value_field.attr 'name', "disabled_#{value_field.attr('name')}"
81
+ #value_toggle.hide()
82
+ container.addClass('inactive')
83
+ activator_label = $('<span></span>').addClass('optional-input-activator-label').text label_text
84
+ activator_container.append activator_toggle
85
+ activator_container.append activator_label
86
+
87
+ container.before(activator_container)
88
+
89
+ container.find('label').remove()
90
+
91
+ activator_toggle.click() if container.hasClass('active')
92
+
93
+ root = @
94
+ root.Optionals = new Optionals()
95
+ $.fn.optionals = (action_or_options = {})->
96
+ if typeof action_or_options is 'string'
97
+ #nothing
98
+ else
99
+ optionals = new Optionals(action_or_options)
100
+ optionals.setup(@)
101
+ root.Optionals = optionals