dependent-select 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dependent-select.gemspec
4
+ gemspec
@@ -0,0 +1,36 @@
1
+ # Dependent Select #
2
+
3
+ dependent-select is a Formtastic 1.2 compatible extension which provides a `select` where the available options depend on the current value of another field. When the parent field's value is changed, the options of the `dependent_select` are updated via an AJAX request. Much of the functionality is implemented in a [jQuery plugin](https://github.com/topsail/dependent-select/blob/master/lib/assets/javascripts/dependent-select.js) which could be used independenly of Formtastic.
4
+
5
+ ## Simple Example ##
6
+
7
+ <%= semantic_form_for @user do |f| %>
8
+ <%= f.inputs do %>
9
+ <%= f.input :department, :as => :select, :collection => Department.find(:all) %>
10
+ <%= f.input :division, :as => :dependent_select, :parent_method => :department, :collection => (@user.department ? @user.department.divisions : []) %>
11
+ <% end %>
12
+ <% end %>
13
+
14
+ In this example each `Department` has many `Divisions`. Whenever the department field changes value, the division field is updated to contain only the `Divisions` of the selected `Department`.
15
+
16
+ ## URL template ##
17
+
18
+ The URL used to request the updated option values is controlled by a simple template option, `url_template`, which defaults to:
19
+
20
+ /${plural_parent_resource_name}/${value}/${plural_resource_name}.json
21
+
22
+ In the above example, assuming the selected department ID is 47, this would translate to `/departments/47/divisions.json`
23
+
24
+ The default URL template can also be overridden globally:
25
+
26
+ DependentSelect.default_url_template = '/${plural_resource_name}.json?${parent_resource_name}=${value}'
27
+
28
+ ## Option template ##
29
+
30
+ The server must return JSON records. The new `option` tags are then generated via the `option_template`, which defaults to:
31
+
32
+ <option value="${id}">${name}</option>
33
+
34
+ If the returned objects do not have an `id` and `name` attribute, `option_template` must be overridden.
35
+
36
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dependent_select/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "dependent-select"
7
+ s.version = Dependent::Select::VERSION
8
+ s.authors = ["Mark Roghelia"]
9
+ s.email = ["mroghelia@topsailtech.com"]
10
+ s.summary = %q{Helper and Formtastic support for a select box whose value depends on another field.}
11
+ #s.rubyforge_project = "dependent-select"
12
+ s.files = `git ls-files`.split("\n")
13
+ #s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ #s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.require_paths = ["lib"]
16
+ s.add_dependency "formtastic"
17
+ end
@@ -0,0 +1,56 @@
1
+ (function($){
2
+
3
+ /*
4
+ * Sets up a select that refreshes its options whenever another
5
+ * field changes value.
6
+ *
7
+ * parentId - the ID of the observed field
8
+ *
9
+ * urlTemplate - the URL used to request the new data from the
10
+ * server. The value of the parent field will be
11
+ * substituted for ${value} in the template
12
+ *
13
+ */
14
+ $.fn.dependentSelect = function(parentId, urlTemplate, options) {
15
+
16
+ options = $.extend({
17
+ optionTemplate: '<option value="${id}">${name}</option>',
18
+ blankOptionHtml: '<option value=""></option>'
19
+ }, options || {});
20
+
21
+ var select = this;
22
+
23
+ $('#' + parentId).bind('change', function(event) {
24
+
25
+ select.empty().append(options.blankOptionHtml); // clear out the current options
26
+
27
+ var url = urlTemplate.replace('${value}', event.target.value);
28
+
29
+ $.getJSON(url, function(resources) {
30
+
31
+ var nodes = [ ];
32
+
33
+ if (options.includeBlank) {
34
+ nodes.push(options.blankOptionHtml);
35
+ }
36
+
37
+ for (var i = resources.length-1; i >= 0; i--) {
38
+
39
+ var optionNode = options.optionTemplate;
40
+
41
+ // substitute resource property values in optionTemplate
42
+ for (attr in resources[i]) {
43
+ optionNode = optionNode.replace('${' + attr + '}', resources[i][attr]);
44
+ }
45
+
46
+ nodes.push(optionNode);
47
+ }
48
+
49
+ select.empty().append(nodes.join(''));
50
+ });
51
+ });
52
+
53
+ return this;
54
+ };
55
+
56
+ })(jQuery);
@@ -0,0 +1 @@
1
+ require 'dependent_select'
@@ -0,0 +1,10 @@
1
+ require "formtastic"
2
+ require "dependent_select/version"
3
+ require 'dependent_select/semantic_form_builder'
4
+ require "dependent_select/engine"
5
+
6
+ module DependentSelect
7
+ mattr_accessor :default_url_template
8
+ end
9
+
10
+ DependentSelect.default_url_template = '/${plural_parent_resource_name}/${value}/${plural_resource_name}.json'
@@ -0,0 +1,6 @@
1
+ module DependentSelect
2
+
3
+ class Engine < ::Rails::Engine
4
+ end
5
+
6
+ end
@@ -0,0 +1,55 @@
1
+ module Formtastic
2
+ class SemanticFormBuilder
3
+
4
+ # Options:
5
+ # parent_id - The DOM ID of the parent field to observe
6
+ # url_template - The jQuery-compatible template used to generate the URL
7
+ # parent_method - If provided, parent_id and url_template can be created automatically
8
+ # option_template - The jQuery-compatible template used to generate the select options
9
+ def dependent_select_input(method, options)
10
+
11
+ html = select_input(method, options)
12
+
13
+ options = {}.merge(options)
14
+
15
+ html_options = options.delete(:input_html) || {}
16
+ input_name = generate_association_input_name(method)
17
+ html_options[:id] ||= generate_html_id(input_name, "")
18
+
19
+ if options[:parent_method]
20
+
21
+ parent_input_name = generate_association_input_name(options[:parent_method])
22
+ options[:parent_id] ||= generate_html_id(parent_input_name, "")
23
+
24
+ child_reflection = reflection_for(method)
25
+ parent_reflection = reflection_for(options[:parent_method])
26
+
27
+ if child_reflection && parent_reflection && parent_reflection.macro == :belongs_to
28
+ options[:url_template] ||= DependentSelect.default_url_template
29
+ .gsub('${resource_name}', child_reflection.class_name.underscore)
30
+ .gsub('${plural_resource_name}', child_reflection.class_name.underscore.pluralize)
31
+ .gsub('${parent_resource_name}', parent_reflection.class_name.underscore)
32
+ .gsub('${plural_parent_resource_name}', parent_reflection.class_name.underscore.pluralize)
33
+ .gsub('${parent_parameter}', parent_reflection.foreign_key.to_s)
34
+ end
35
+
36
+ end
37
+
38
+ unless options[:parent_id].blank? || options[:url_template].blank?
39
+
40
+ # convert to camelcase keys, which is the convention in Javascript
41
+ js_options = options.inject({}) do |hash, pair|
42
+ hash[pair[0].to_s.camelize(:lower)] = pair[1]
43
+ hash
44
+ end
45
+
46
+ html += "<script>$(document).ready(function() { $('##{html_options[:id]}').dependentSelect('#{options[:parent_id]}', '#{options[:url_template]}', #{js_options.to_json}) });</script>".html_safe
47
+
48
+ end
49
+
50
+ return html
51
+
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ module Dependent
2
+ module Select
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dependent-select
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Roghelia
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-06 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: formtastic
16
+ requirement: &71770510 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *71770510
25
+ description:
26
+ email:
27
+ - mroghelia@topsailtech.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - Gemfile
33
+ - README.md
34
+ - Rakefile
35
+ - dependent-select.gemspec
36
+ - lib/assets/javascripts/dependent-select.js
37
+ - lib/dependent-select.rb
38
+ - lib/dependent_select.rb
39
+ - lib/dependent_select/engine.rb
40
+ - lib/dependent_select/semantic_form_builder.rb
41
+ - lib/dependent_select/version.rb
42
+ homepage:
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.6
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Helper and Formtastic support for a select box whose value depends on another
66
+ field.
67
+ test_files: []