activeadmin_select_many 0.2.8 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3a289f4b6418d0af92538f32caed2af60a8149d6
4
- data.tar.gz: 37deed25511b1de438cae523b52a0f4c627d2d4e
2
+ SHA256:
3
+ metadata.gz: 125c98dc457c8e510aa9e35d0c03c9d86341a42c6395cbd5da501f32a0782ab3
4
+ data.tar.gz: aa9ab407d84de81df360209eba4c868da7232805fe6606d19d2e3b3c74d00279
5
5
  SHA512:
6
- metadata.gz: a7774b3c4765e20abf7a18379a86f7faf0482c771fac313320bacb555e4a69c440c765da602c1ead8d93952e68a2acfc98d4ec0d626c22cc53f851f55d2242c9
7
- data.tar.gz: f7c76a2763f1a7977ea28e17eafbf1f7dde25a784f715d399f2f7b550f370573dd54161de5326e6e0c21ecd11660e6197f06cf3a90b79080ec4406583e42fc22
6
+ metadata.gz: f40eda600327c6a7262548e7052ae0662c65b88a40cdd21d4138d7b2ce9e4df37e9884384d23dc34e34236f778e876e2a7d48f575d11af8d361598189e7b3ffa
7
+ data.tar.gz: 5e0d0b7b131174658ad5dfde9c235dedb5ddfb09c703efed47ea4141b4b0ac06fec1f3591c4ab6b790167f1793570f70a5d2b3a557b7196bed4bb993f4ed9035
data/README.md CHANGED
@@ -1,20 +1,22 @@
1
1
  # ActiveAdmin Select Many [![Gem Version](https://badge.fury.io/rb/activeadmin_select_many.svg)](https://badge.fury.io/rb/activeadmin_select_many)
2
2
 
3
- An Active Admin plugin which improves one-to-many / many-to-many / many-to-one associations selection using 2 new inputs: **select_many** and **select_one** (jQuery required)
3
+ An Active Admin plugin which improves one-to-many / many-to-many / many-to-one associations selection using 2 new inputs: **select_many** and **select_one** (jQuery required).
4
4
 
5
5
  Features for *select_many*:
6
- - search box
7
- - available items on the left, selected items on the right
8
- - local/remote collections
9
- - double click to add/remove items
10
- - sortable (with up/down buttons)
6
+ - search box;
7
+ - available items on the left, selected items on the right;
8
+ - local/remote collections;
9
+ - double click to add/remove items;
10
+ - sortable (with up/down buttons);
11
+ - key bindings to improve accessibility.
11
12
 
12
13
  Features for *select_one*:
13
- - search box
14
- - selected items on the right
15
- - remote collections
16
- - counter of items found
17
- - can be used as filter
14
+ - search box;
15
+ - selected items on the right;
16
+ - remote collections;
17
+ - counter of items found;
18
+ - can be used as filter;
19
+ - key bindings to improve accessibility.
18
20
 
19
21
  ![screenshot](screenshot.png)
20
22
 
@@ -36,6 +38,7 @@ Features for *select_one*:
36
38
  - **collection**: local collection
37
39
  - **counter_limit**: if results count is greater than or equal to this limit a '+' is shown
38
40
  - **filter_form**: for *select_one* only, allow to use it as filter
41
+ - **include_blank**: for *select_one* only, default true, allow to include a blank value on top
39
42
  - **member_label**: key to use as text for select options
40
43
  - **placeholder**: placeholder string for search box
41
44
  - **remote_collection**: JSON path
@@ -44,7 +47,7 @@ Features for *select_one*:
44
47
  - **size**: number of rows of both the selects (default: 4)
45
48
  - **sortable**: set to true to enable sortable buttons (default: not set)
46
49
 
47
- ## Example with select_many
50
+ ## Examples with select_many
48
51
 
49
52
  Add to ActiveAdmin model config, in *form* block.
50
53
 
@@ -82,7 +85,7 @@ ActiveAdmin.register Tag do
82
85
  end
83
86
  ```
84
87
 
85
- ## Example with select_one
88
+ ## Examples with select_one
86
89
 
87
90
  In a form:
88
91
 
@@ -92,6 +95,10 @@ As filter:
92
95
 
93
96
  `filter :article_id_eq, as: :select_one, filter_form: true, placeholder: 'Search...', search_param: 'title_contains', member_label: 'title', remote_collection: '/admin/articles.json'`
94
97
 
98
+ ## Notes
99
+
100
+ - To use this plugins with ActiveAdmin 1.x please use the version 0.3.4
101
+
95
102
  ## Do you like it? Star it!
96
103
 
97
104
  If you use this component just star it. A developer is more motivated to improve a project when there is some interest.
@@ -1,15 +1,15 @@
1
- function smActivate( target ) {
2
- if( target.tagName.toLowerCase() == 'option' ) {
3
- var parent = $(this).closest( '.select_many' );
1
+ function smActivate(target) {
2
+ if(target.tagName.toLowerCase() == 'option') {
3
+ var parent = $(this).closest('.select_many');
4
4
  var opt = $(target);
5
- var dst = parent.find( $(this).data( 'select' ) == 'src' ? '[data-select="dst"]' : '[data-select="src"]' );
6
- dst.append( $('<option>', { value: opt.val(), text: opt.text() }) );
5
+ var dst = parent.find($(this).data('select') == 'src' ? '[data-select="dst"]' : '[data-select="src"]');
6
+ dst.append($('<option>', { value: opt.val(), text: opt.text() }));
7
7
  opt.remove();
8
- smUpdateValues( parent );
8
+ smUpdateValues(parent);
9
9
  }
10
10
  }
11
11
 
12
- function smDebounce( func, wait, immediate ) {
12
+ function smDebounce(func, wait, immediate) {
13
13
  var timeout;
14
14
  return function() {
15
15
  var context = this, args = arguments;
@@ -24,120 +24,199 @@ function smDebounce( func, wait, immediate ) {
24
24
  };
25
25
  };
26
26
 
27
- function smUpdateValues( parent ) {
28
- var cnt = 0, values = parent.find( '.values' );
27
+ function smUpdateValues(parent) {
28
+ var cnt = 0, values = parent.find('.values');
29
29
  values.empty();
30
- parent.find( '[data-select="dst"] option' ).each( function() {
31
- values.append( $('<input>', { type: 'hidden', name: values.data( 'name' ), value: $(this).val() }) );
30
+ parent.find('[data-select="dst"] option').each(function() {
31
+ values.append($('<input>', { type: 'hidden', name: values.data('name'), value: $(this).val() }));
32
32
  cnt++;
33
33
  });
34
- if( cnt == 0 ) values.append( $('<input>', { type: 'hidden', name: values.data( 'name' ) }) );
35
- parent.find( '.selected span' ).text( ' [' + cnt + ']' );
34
+ if(cnt == 0) values.append($('<input>', { type: 'hidden', name: values.data('name') }));
35
+ parent.find('.selected span').text(' [' + cnt + ']');
36
+ parent.find('.available span').text(' [' + parent.find('[data-select="src"] option').length + ']');
36
37
  }
37
38
 
38
- $(document).ready( function() {
39
- $('.select_many.input select').on( 'dblclick', function( event ) {
40
- $.proxy( smActivate, $(this) )( event.target );
39
+ $(document).ready(function() {
40
+ $('.select_many.input select').on('dblclick', function(event) {
41
+ $.proxy(smActivate, $(this))(event.target);
41
42
  });
42
43
 
43
- var onLocalSelect = smDebounce( function() {
44
+ // --- select_many ----------------------------------------------------------
45
+ var onLocalSelect = smDebounce(function() {
44
46
  var cnt = 0, search = $(this).val().toLowerCase();
45
- $(this).closest( '.select_many' ).find( '[data-select="src"] option' ).each( function() {
46
- var found = $(this).text().toLowerCase().indexOf( search ) >= 0;
47
- $(this).toggle( found );
48
- if( found ) cnt++;
47
+ $(this).closest('.select_many').find('[data-select="src"] option').each(function() {
48
+ var found = $(this).text().toLowerCase().indexOf(search) >= 0;
49
+ $(this).toggle(found);
50
+ if(found) cnt++;
49
51
  });
50
- $(this).parent().find( '.available span' ).text( ' [' + cnt + ']' );
51
- }, 250 );
52
- var onRemoteSelect = smDebounce( function() {
52
+ $(this).parent().find('.available span').text(' [' + cnt + ']');
53
+ }, 250);
54
+
55
+ var onRemoteSelect = smDebounce(function(event) {
53
56
  var search = $(this).val().trim();
54
- if( search != '' && $(this).data( 'searching' ) != '1' ) {
55
- $(this).data( 'searching', '1' );
57
+ if($(this).data('searching') != '1' && search && $(this).data('last-search') != search) {
58
+ $(this).data('searching', '1');
59
+ $(this).data('last-search', search);
56
60
  var _this = $(this);
57
61
  var data = {}
58
62
  var text_key = $(this).data('text');
59
63
  var value_key = $(this).data('value');
60
- var counter_limit = $(this).data('counter-limit') ? Number( $(this).data('counter-limit') ) : 0;
64
+ var counter_limit = $(this).data('counter-limit') ? Number($(this).data('counter-limit')) : 0;
61
65
  data['q['+$(this).data('search')+']'] = search;
62
66
  $.ajax({
63
67
  context: _this,
64
68
  data: data,
65
- url: $(this).data( 'remote-collection' ),
66
- complete: function( req, status ) {
67
- $(this).data( 'searching', '' );
69
+ url: $(this).data('remote-collection'),
70
+ complete: function(req, status) {
71
+ $(this).data('searching', '');
68
72
  },
69
- success: function( data, status, req ) {
70
- var select = $(this).closest( '.select_many' ).find( '[data-select="src"]' );
73
+ success: function(data, status, req) {
74
+ var select = $(this).closest('.select_many').find('[data-select="src"]');
71
75
  select.empty();
72
- data.forEach( function( item ) {
73
- select.append( $('<option>', { value: item[value_key], text: item[text_key] }) );
76
+ data.forEach(function(item) {
77
+ select.append($('<option>', { value: item[value_key], text: item[text_key] }));
74
78
  });
75
- $(this).parent().find( '.available span' ).text( ' [' + ( ( counter_limit > 0 && data.length >= counter_limit ) ? ( counter_limit + '+' ) : data.length ) + ']' );
79
+ $(this).parent().find('.available span').text(' [' + ((counter_limit > 0 && data.length >= counter_limit) ? (counter_limit + '+') : data.length) + ']');
76
80
  },
77
81
  });
78
82
  }
79
- }, 400 );
83
+ }, 400);
80
84
 
81
- $('.select_many.input .search-select').each( function() {
85
+ $('.select_many.input .search-select').each(function() {
82
86
  var parent = $(this).parent();
83
- parent.find( '.available' ).append( '<span> [' + parent.find( '[data-select="src"] option' ).length + ']</span>' );
84
- parent.find( '.selected' ).append( '<span> [' + parent.find( '[data-select="dst"] option' ).length + ']</span>' );
85
- $(this).on( 'keyup', $(this).data( 'remote-collection' ) ? onRemoteSelect : onLocalSelect );
87
+ parent.find('.available').append('<span> [' + parent.find('[data-select="src"] option').length + ']</span>');
88
+ parent.find('.selected').append('<span> [' + parent.find('[data-select="dst"] option').length + ']</span>');
89
+ $(this).on('keydown', function(event) {
90
+ if(event.which == 13 || event.which == 40) { // enter or arrow down
91
+ event.preventDefault();
92
+ $(this).closest('.select_many').find('[data-select="src"]').focus();
93
+ }
94
+ else $.proxy($(this).data('remote-collection') ? onRemoteSelect : onLocalSelect, $(this))(event);
95
+ });
96
+
97
+ // --- key bindings -------------------------------------------------------
98
+ parent.find('[data-select="src"]').on('keydown', function(event) {
99
+ if(event.which == 13) { // enter
100
+ event.preventDefault();
101
+ var opts = $(this).find(':selected');
102
+ if(opts.length > 0) {
103
+ var next = $(opts[0]).next();
104
+ $.proxy(smActivate, $(this))(opts[0]);
105
+ if(next.length > 0) $(this).val(next.val());
106
+ }
107
+ }
108
+ else if(event.which == 9 || event.which == 39) { // tab or right arrow
109
+ event.preventDefault();
110
+ parent.find('[data-select="dst"]').focus();
111
+ }
112
+ else if(event.which == 38) { // up arrow
113
+ if($(this).find('option')[0] == $(this).find(':selected')[0]) {
114
+ event.preventDefault();
115
+ parent.find('.search-select').focus();
116
+ }
117
+ }
118
+ });
119
+ parent.find('[data-select="dst"]').on('keydown', function(event) {
120
+ if(event.which == 13) { // enter
121
+ event.preventDefault();
122
+ var opts = $(this).find(':selected');
123
+ if(opts.length > 0) {
124
+ var next = $(opts[0]).next();
125
+ $.proxy(smActivate, $(this))(opts[0]);
126
+ if(next.length > 0) $(this).val(next.val());
127
+ }
128
+ }
129
+ else if(event.which == 37) { // left arrow
130
+ event.preventDefault();
131
+ parent.find('[data-select="src"]').focus();
132
+ }
133
+ });
86
134
  });
87
- $('.select_many .add').on( 'click', function() {
135
+
136
+ // --- buttons --------------------------------------------------------------
137
+ $('.select_many .add').on('click', function() {
88
138
  var select = $(this).parent().prev();
89
- var current = select.find( 'option:selected' )[0];
90
- if( current ) $.proxy( smActivate, select )( current );
139
+ var current = select.find('option:selected')[0];
140
+ if(current) $.proxy(smActivate, select)(current);
91
141
  });
92
- $('.select_many .remove').on( 'click', function() {
142
+ $('.select_many .remove').on('click', function() {
93
143
  var select = $(this).parent().next();
94
- var current = select.find( 'option:selected' )[0];
95
- if( current ) $.proxy( smActivate, select )( current );
144
+ var current = select.find('option:selected')[0];
145
+ if(current) $.proxy(smActivate, select)(current);
96
146
  });
97
- $('.select_many [sortable] .move_up').on( 'click', function() {
147
+ $('.select_many [sortable] .move_up').on('click', function() {
98
148
  var select = $(this).parent().next();
99
- var current = select.find( 'option:selected' )[0];
100
- if( current ) {
101
- $(current).prev().before( current );
102
- smUpdateValues( $(this).closest( '.select_many' ) );
149
+ var current = select.find('option:selected')[0];
150
+ if(current) {
151
+ $(current).prev().before(current);
152
+ smUpdateValues($(this).closest('.select_many'));
103
153
  }
104
154
  });
105
- $('.select_many [sortable] .move_down').on( 'click', function() {
155
+ $('.select_many [sortable] .move_down').on('click', function() {
106
156
  var select = $(this).parent().next();
107
- var current = select.find( 'option:selected' )[0];
108
- if( current ) {
109
- $(current).next().after( current );
110
- smUpdateValues( $(this).closest( '.select_many' ) );
157
+ var current = select.find('option:selected')[0];
158
+ if(current) {
159
+ $(current).next().after(current);
160
+ smUpdateValues($(this).closest('.select_many'));
111
161
  }
112
162
  });
113
163
 
114
- var onRemoteSelectOne = smDebounce( function( event ) {
115
- var select = $(this).next();
116
- if( select.data( 'searching' ) != '1' ) {
117
- select.data( 'searching', '1' );
164
+ // --- select one -----------------------------------------------------------
165
+ var onRemoteSelectOne = smDebounce(function(event) {
166
+ var search = $(this).val().trim();
167
+ var select = $(this).closest('.select_one').find('[data-select="src"]');;
168
+ if(select.data('searching') != '1' && search && select.data('last-search') != search) {
169
+ select.data('searching', '1');
170
+ select.data('last-search', search);
118
171
  var data = {}
119
172
  var search_key = $(this).data('search') ? $(this).data('search') : 'name_contains';
120
173
  var value_key = $(this).data('value') ? $(this).data('value') : 'id';
121
174
  var text_key = $(this).data('text') ? $(this).data('text') : 'name';
122
- var counter_limit = $(this).data('counter-limit') ? Number( $(this).data('counter-limit') ) : 0;
123
- data['q['+search_key+']'] = $(this).val();
175
+ var counter_limit = $(this).data('counter-limit') ? Number($(this).data('counter-limit')) : 0;
176
+ data['q['+search_key+']'] = search;
124
177
  $.ajax({
125
178
  context: select,
126
179
  data: data,
127
- url: $(this).data( 'remote-collection' ),
128
- complete: function( req, status ) {
129
- $(this).data( 'searching', '' );
180
+ url: $(this).data('remote-collection'),
181
+ complete: function(req, status) {
182
+ $(this).data('searching', '');
130
183
  },
131
- success: function( data, status, req ) {
132
- var sel = $(this);
184
+ success: function(data, status, req) {
185
+ var first = false, sel = $(this);
133
186
  sel.empty();
134
- data.forEach( function( item ) {
135
- sel.append( $('<option>', { value: item[value_key], text: item[text_key] }) );
187
+ if(sel.data('include-blank')) sel.append($('<option>', { value: '', text: '' }));
188
+ data.forEach(function(item) {
189
+ sel.append($('<option>', { value: item[value_key], text: item[text_key] }));
190
+ if(!first) first = item[value_key];
136
191
  });
137
- sel.parent().find( '.status' ).text( '[' + ( ( counter_limit > 0 && data.length >= counter_limit ) ? ( counter_limit + '+' ) : data.length ) + ']' );
192
+ sel.parent().find('.status').text('[' + ((counter_limit > 0 && data.length >= counter_limit) ? (counter_limit + '+') : data.length) + ']');
193
+ if(first) sel.val(first);
138
194
  },
139
195
  });
140
196
  }
141
- }, 500 );
142
- $('.select-one-inputs > .search-select').on( 'keyup', onRemoteSelectOne );
197
+ }, 500);
198
+
199
+ $('.select-one-inputs').each(function() {
200
+ $(this).find('.search-select').on('keydown', function(event) {
201
+ if(event.which == 38) { // up arrow
202
+ event.preventDefault();
203
+ var select = $(this).closest('.select-one-inputs').find('[data-select="src"]');
204
+ var prev = select.find(':selected').prev();
205
+ if(prev.length) select.val(prev.val());
206
+ }
207
+ else if(event.which == 40) { // down arrow
208
+ event.preventDefault();
209
+ var select = $(this).closest('.select-one-inputs').find('[data-select="src"]');
210
+ var next = select.find(':selected').next();
211
+ if(next.length) select.val(next.val());
212
+ }
213
+ else $.proxy(onRemoteSelectOne, $(this))(event);
214
+ });
215
+ $(this).find('[data-select="src"]').on('keydown', function(event) {
216
+ if(event.which == 37) { // left arrow
217
+ event.preventDefault();
218
+ $(this).closest('.select-one-inputs').find('.search-select').focus();
219
+ }
220
+ });
221
+ });
143
222
  });
@@ -1,5 +1,5 @@
1
1
  module ActiveAdmin
2
2
  module SelectMany
3
- VERSION = '0.2.8'
3
+ VERSION = '0.4.0'
4
4
  end
5
5
  end
@@ -1,18 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Formtastic
2
4
  module Inputs
3
5
  class SelectManyInput < SelectInput
4
6
  def to_html
5
- options[:'data-remote-collection'] = options.delete( :remote_collection )
7
+ options[:'data-remote-collection'] = options.delete(:remote_collection)
6
8
  opts = { class: 'select-many-inputs' }
7
- opts[:sortable] = options.delete( :sortable ) if options[:sortable]
9
+ opts[:sortable] = options.delete(:sortable) if options[:sortable]
8
10
  input_wrapping do
9
11
  label_html <<
10
- template.content_tag( :div, opts ) do
12
+ template.content_tag(:div, opts) do
11
13
  hidden_input <<
12
14
  search_box_html <<
13
- template.content_tag( :span, '', class: 'empty' ) <<
14
- template.content_tag( :span, template.t( 'inputs.select_many.available' ), class: 'available' ) <<
15
- template.content_tag( :span, template.t( 'inputs.select_many.selected' ), class: 'selected' ) <<
15
+ template.content_tag(:span, '', class: 'empty') <<
16
+ template.content_tag(:span, ::I18n.t('inputs.select_many.available'), class: 'available') <<
17
+ template.content_tag(:span, ::I18n.t('inputs.select_many.selected'), class: 'selected') <<
16
18
  select_src_html <<
17
19
  buttons_html <<
18
20
  select_dst_html
@@ -21,48 +23,72 @@ module Formtastic
21
23
  end
22
24
 
23
25
  def hidden_input
24
- template.content_tag( :div, class: 'values', 'data-name': input_html_options[:name] ) do
25
- values = object.send( input_name )
26
- values = [values] if values.is_a? Fixnum
26
+ template.content_tag(:div, class: 'values', 'data-name': input_html_options[:name]) do
27
+ values = object.send(input_name)
28
+ values = [values] if values.is_a? Integer
27
29
  values.each do |value|
28
- template.concat template.hidden_field_tag( input_html_options[:name], value, {id: nil} )
30
+ template.concat template.hidden_field_tag(input_html_options[:name], value, {id: nil})
29
31
  end if values
30
32
  end
31
33
  end
32
34
 
33
35
  def buttons_html
34
- template.content_tag( :div, class: 'buttons' ) do
35
- template.link_to( '&rarr;'.html_safe, 'Javascript:void(0)', class: 'add' ) +
36
- template.link_to( '&larr;'.html_safe, 'Javascript:void(0)', class: 'remove' ) +
37
- template.link_to( '&uarr;'.html_safe, 'Javascript:void(0)', class: 'move_up' ) +
38
- template.link_to( '&darr;'.html_safe, 'Javascript:void(0)', class: 'move_down' )
36
+ template.content_tag(:div, class: 'buttons') do
37
+ template.link_to('&rarr;'.html_safe, 'Javascript:void(0)', class: 'add') +
38
+ template.link_to('&larr;'.html_safe, 'Javascript:void(0)', class: 'remove') +
39
+ template.link_to('&uarr;'.html_safe, 'Javascript:void(0)', class: 'move_up') +
40
+ template.link_to('&darr;'.html_safe, 'Javascript:void(0)', class: 'move_down')
39
41
  end
40
42
  end
41
43
 
42
44
  def search_box_html
43
- @opts ||= {id: nil, class: 'search-select', placeholder: options.delete( :placeholder ), 'data-remote-collection': options[:'data-remote-collection'], 'data-search': options[:search_param] ? options[:search_param] : 'name_contains', 'data-text': options[:member_label] ? options[:member_label] : ( options[:text_key] ? options[:text_key] : 'name' ), 'data-value': options[:value_key] ? options[:value_key] : 'id', 'data-counter-limit': options[:counter_limit].to_i}
44
- template.text_field_tag( nil, '', @opts )
45
+ opts = {
46
+ id: nil,
47
+ class: 'search-select',
48
+ placeholder: options.delete(:placeholder),
49
+ 'data-counter-limit': options[:counter_limit].to_i,
50
+ 'data-remote-collection': options[:'data-remote-collection'],
51
+ 'data-search': options[:search_param] ? options[:search_param] : 'name_contains',
52
+ 'data-text': options[:member_label] ? options[:member_label] : (options[:text_key] ? options[:text_key] : 'name'),
53
+ 'data-value': options[:value_key] ? options[:value_key] : 'id',
54
+ }
55
+ template.text_field_tag(nil, '', opts)
45
56
  end
46
57
 
47
58
  def select_src_html
48
- coll = if options[:'data-remote-collection']
49
- []
50
- else
51
- # TODO: add option unique ?
52
- selected = object.send( input_name )
53
- selected = [selected] if selected.is_a? Fixnum
54
- selected ? collection.select { |option| !selected.include?( option[1] ) } : collection
55
- end
56
- opts = input_options.merge( name: nil, id: nil, multiple: true, 'data-select': 'src', size: options[:size] ? options[:size] : 4 )
57
- template.select_tag nil, template.options_for_select( coll ), opts
59
+ coll =
60
+ if options[:'data-remote-collection']
61
+ []
62
+ else
63
+ # TODO: add option unique ?
64
+ selected = object.send(input_name)
65
+ selected = [selected] if selected.is_a? Integer
66
+ selected ? collection.select { |option| !selected.include?(option[1]) } : collection
67
+ end
68
+ opts = {
69
+ id: nil,
70
+ include_blank: false,
71
+ multiple: true,
72
+ name: nil,
73
+ size: options[:size] || 4,
74
+ 'data-select': 'src'
75
+ }
76
+ template.select_tag nil, template.options_for_select(coll), input_options.merge(opts)
58
77
  end
59
78
 
60
79
  def select_dst_html
61
- selected = options[:selected] ? options[:selected] : object.send( input_name )
62
- selected = [selected] if selected.is_a? Fixnum
63
- coll = selected ? collection.select { |option| selected.include?( option[1] ) } : collection
64
- opts = input_options.merge( name: nil, id: nil, multiple: true, 'data-select': 'dst', size: options[:size] ? options[:size] : 4 )
65
- template.select_tag nil, template.options_for_select( coll ), opts
80
+ selected = options[:selected] || object.send(input_name)
81
+ selected = [selected] if selected.is_a? Integer
82
+ coll = selected ? collection.select { |option| selected.include?(option[1]) } : []
83
+ opts = {
84
+ id: nil,
85
+ include_blank: false,
86
+ multiple: true,
87
+ name: nil,
88
+ size: options[:size] || 4,
89
+ 'data-select': 'dst'
90
+ }
91
+ template.select_tag nil, template.options_for_select(coll), input_options.merge(opts)
66
92
  end
67
93
  end
68
94
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Formtastic
2
4
  module Inputs
3
5
  class SelectOneInput < SelectInput
4
- def input_options
5
- super.merge include_blank: false
6
- end
6
+ # def input_options
7
+ # super.merge include_blank: false
8
+ # end
7
9
 
8
10
  def input_wrapping(&block)
9
11
  template.content_tag(options[:filter_form] ? :div : :li,
@@ -16,30 +18,35 @@ module Formtastic
16
18
  opts = { class: 'select-one-inputs' }
17
19
  input_wrapping do
18
20
  label_html <<
19
- template.content_tag( :div, opts ) do
21
+ template.content_tag(:div, opts) do
20
22
  search_box <<
21
23
  select_html <<
22
- template.content_tag( :span, '', class: 'status' )
24
+ template.content_tag(:span, '', class: 'status')
23
25
  end
24
26
  end
25
27
  end
26
28
 
27
29
  def search_box
28
30
  # TODO: remove text_key in next major version
29
- @opts ||= {id: nil, class: 'search-select', placeholder: options[:placeholder], 'data-remote-collection': options[:remote_collection], 'data-search': options[:search_param] ? options[:search_param] : 'name_contains', 'data-text': options[:member_label] ? options[:member_label] : ( options[:text_key] ? options[:text_key] : 'name' ), 'data-value': options[:value_key] ? options[:value_key] : 'id', 'data-msg': options[:msg_items], 'data-counter-limit': options[:counter_limit].to_i}
30
- template.text_field_tag( nil, '', @opts )
31
+ opts = {
32
+ id: nil,
33
+ class: 'search-select',
34
+ placeholder: options[:placeholder],
35
+ 'data-counter-limit': options[:counter_limit].to_i,
36
+ 'data-msg': options[:msg_items],
37
+ 'data-remote-collection': options[:remote_collection],
38
+ 'data-search': options[:search_param] || 'name_contains',
39
+ 'data-text': options[:member_label] || options[:text_key] || 'name',
40
+ 'data-value': options[:value_key] || 'id'
41
+ }
42
+ template.text_field_tag(nil, '', opts)
31
43
  end
32
44
 
33
45
  def select_html
34
- selected = options[:selected] ? options[:selected] : object.send( input_name )
35
- sel = ''
36
- collection.each do |item|
37
- if item[1] == selected
38
- sel = template.options_for_select( [item], selected ) if item[1] == selected
39
- break
40
- end
41
- end
42
- builder.select(input_name, sel, input_options, input_html_options.merge( 'data-select': 'src' ) )
46
+ selected = options[:selected] || object.send(input_name)
47
+ opts = input_html_options.merge('data-select': 'src')
48
+ opts['data-include-blank'] = '1' if input_options[:include_blank]
49
+ template.select_tag input_name, template.options_for_select(collection, selected), input_options.merge(opts)
43
50
  end
44
51
  end
45
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeadmin_select_many
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattia Roccoberton
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-14 00:00:00.000000000 Z
11
+ date: 2020-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeadmin
@@ -16,14 +16,140 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activestorage
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 6.0.3.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 6.0.3.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: capybara
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.33.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.33.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.13.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.13.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: puma
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 4.3.5
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 4.3.5
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec_junit_formatter
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.4.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.4.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 4.0.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 4.0.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: selenium-webdriver
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 3.142.7
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 3.142.7
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.19.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.19.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 1.4.2
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 1.4.2
27
153
  description: An Active Admin plugin which improves one-to-many and many-to-many associations
28
154
  selection (jQuery required)
29
155
  email: mat@blocknot.es
@@ -31,12 +157,9 @@ executables: []
31
157
  extensions: []
32
158
  extra_rdoc_files: []
33
159
  files:
34
- - ".gitignore"
35
- - Gemfile
36
160
  - LICENSE.txt
37
161
  - README.md
38
162
  - Rakefile
39
- - activeadmin_select_many.gemspec
40
163
  - app/assets/javascripts/activeadmin/select_many.js
41
164
  - app/assets/stylesheets/activeadmin/_select_many.sass
42
165
  - config/locales/en.yml
@@ -46,12 +169,11 @@ files:
46
169
  - lib/activeadmin_select_many.rb
47
170
  - lib/formtastic/inputs/select_many_input.rb
48
171
  - lib/formtastic/inputs/select_one_input.rb
49
- - screenshot.png
50
172
  homepage: https://github.com/blocknotes/activeadmin_select_many
51
173
  licenses:
52
174
  - MIT
53
175
  metadata: {}
54
- post_install_message:
176
+ post_install_message:
55
177
  rdoc_options: []
56
178
  require_paths:
57
179
  - lib
@@ -66,9 +188,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
188
  - !ruby/object:Gem::Version
67
189
  version: '0'
68
190
  requirements: []
69
- rubyforge_project:
70
- rubygems_version: 2.6.13
71
- signing_key:
191
+ rubygems_version: 3.0.3
192
+ signing_key:
72
193
  specification_version: 4
73
194
  summary: SelectMany plugin for ActiveAdmin
74
195
  test_files: []
data/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- _misc/
2
-
3
- *.orig
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
4
-
@@ -1,19 +0,0 @@
1
- lib = File.expand_path('../lib', __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'activeadmin/select_many/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'activeadmin_select_many'
7
- spec.version = ActiveAdmin::SelectMany::VERSION
8
- spec.summary = 'SelectMany plugin for ActiveAdmin'
9
- spec.description = 'An Active Admin plugin which improves one-to-many and many-to-many associations selection (jQuery required)'
10
- spec.license = 'MIT'
11
- spec.authors = ['Mattia Roccoberton']
12
- spec.email = 'mat@blocknot.es'
13
- spec.homepage = 'https://github.com/blocknotes/activeadmin_select_many'
14
-
15
- spec.files = `git ls-files -z`.split("\x0")
16
- spec.require_paths = ['lib']
17
-
18
- spec.add_runtime_dependency 'activeadmin', '~> 1.0'
19
- end
Binary file