activeadmin_dynamic_fields 0.2.8 → 0.3.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 +4 -4
- data/README.md +27 -31
- data/app/assets/javascripts/activeadmin/dynamic_fields.js +185 -195
- data/lib/activeadmin/dynamic_fields/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1af148e7cd9d7704c902e17fdb022acbb1c0c2012bf423f9be6e4ae92cdb6f5f
|
4
|
+
data.tar.gz: ad108b3ae42ba846251dcab61487e68809e4cfaf21e453039a7ad3cb0cb22bd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c76b4cb42b90bf7c88c4cafbbab1bb40f8fa61efbaa8acef0cb3230c6dd2f3eea3b0bf88413431c2a275538ef7c1f37aa0463a2445f0e2a61eae17b189955b5
|
7
|
+
data.tar.gz: d09b1cfe869567e5634236a31385608800375be5cef690b5ee1c420d2cba8a5018f642c5bec0d2996078338a8bdfa0499c02d839e264b9704fb5581e5659d44d
|
data/README.md
CHANGED
@@ -1,27 +1,26 @@
|
|
1
|
-
# ActiveAdmin Dynamic Fields [](https://badge.fury.io/rb/activeadmin_dynamic_fields)
|
1
|
+
# ActiveAdmin Dynamic Fields [](https://badge.fury.io/rb/activeadmin_dynamic_fields) [](https://circleci.com/gh/blocknotes/activeadmin_dynamic_fields)
|
2
2
|
|
3
|
-
An Active Admin plugin to add dynamic behaviors to fields.
|
3
|
+
An Active Admin plugin to add dynamic behaviors to some fields.
|
4
4
|
|
5
5
|
Features:
|
6
|
-
|
7
6
|
- set conditional checks on fields
|
8
|
-
- trigger
|
7
|
+
- trigger actions on target elements
|
9
8
|
- inline field editing
|
10
9
|
- create links to load some content in a dialog
|
11
10
|
|
12
11
|
The easiest way to show how this plugin works is looking the examples [below](#examples).
|
13
12
|
|
14
13
|
## Install
|
15
|
-
|
16
14
|
- Add to your Gemfile: `gem 'activeadmin_dynamic_fields'`
|
17
15
|
- Execute bundle
|
18
16
|
- Add at the end of your ActiveAdmin javascripts (_app/assets/javascripts/active_admin.js_):
|
19
|
-
`//= require activeadmin/dynamic_fields`
|
20
17
|
|
21
|
-
|
18
|
+
```js
|
19
|
+
//= require activeadmin/dynamic_fields
|
20
|
+
```
|
22
21
|
|
22
|
+
## Options
|
23
23
|
Options are passed to fields using *input_html* parameter as *data* attributes:
|
24
|
-
|
25
24
|
- **data-if**: check a condition, values:
|
26
25
|
+ **checked**: check if a checkbox is checked
|
27
26
|
+ **not_checked**: check if a checkbox is not checked
|
@@ -32,7 +31,7 @@ Options are passed to fields using *input_html* parameter as *data* attributes:
|
|
32
31
|
- **data-not**: check if a field hasn't a specific value
|
33
32
|
- **data-target**: target css selector (from parent fieldset, look for the closest match)
|
34
33
|
- **data-gtarget**: target css selector globally
|
35
|
-
- **data-
|
34
|
+
- **data-then**: the action to trigger (alias **data-action**), values:
|
36
35
|
+ **hide**: hides elements
|
37
36
|
+ **slide**: hides elements (using sliding)
|
38
37
|
+ **fade**: hides elements (using fading)
|
@@ -42,16 +41,17 @@ Options are passed to fields using *input_html* parameter as *data* attributes:
|
|
42
41
|
- **data-function**: check the return value of a custom function
|
43
42
|
- **data-arg**: argument passed to the custom set function (as array of strings)
|
44
43
|
|
44
|
+
A check condition or a custom check function are required. A trigger action is required too, unless you are using a custom function (in that case it is optional).
|
45
|
+
|
45
46
|
## Examples
|
46
47
|
|
47
48
|
### Dynamic fields examples
|
48
|
-
|
49
49
|
- A checkbox that hides other fields if is checked (ex. model *Article*):
|
50
50
|
|
51
51
|
```rb
|
52
52
|
form do |f|
|
53
53
|
f.inputs 'Article' do
|
54
|
-
f.input :published, input_html: { data: { if: 'checked',
|
54
|
+
f.input :published, input_html: { data: { if: 'checked', then: 'hide', target: '.grp1' } }
|
55
55
|
f.input :online_date, wrapper_html: { class: 'grp1' }
|
56
56
|
f.input :draft_notes, wrapper_html: { class: 'grp1' }
|
57
57
|
end
|
@@ -61,31 +61,31 @@ end
|
|
61
61
|
|
62
62
|
- Add 3 classes (*first*, *second*, *third*) if a checkbox is not checked:
|
63
63
|
|
64
|
-
`f.input :published, input_html: { data: { if: 'not_checked',
|
64
|
+
`f.input :published, input_html: { data: { if: 'not_checked', then: 'addClass first second third', target: '.grp1' } }`
|
65
65
|
|
66
66
|
- Set another field value if a string field is blank:
|
67
67
|
|
68
|
-
`f.input :title, input_html: { data: { if: 'blank',
|
68
|
+
`f.input :title, input_html: { data: { if: 'blank', then: 'setValue 10', target: '#article_position' } }`
|
69
69
|
|
70
70
|
- Use a custom function for conditional check (*title_not_empty()* must be available on global scope) (with alternative syntax for data attributes):
|
71
71
|
|
72
|
-
`f.input :title, input_html: { 'data-function': 'title_empty', 'data-
|
72
|
+
`f.input :title, input_html: { 'data-function': 'title_empty', 'data-then': 'slide', 'data-target': '#article_description_input' }`
|
73
73
|
|
74
74
|
```js
|
75
|
-
function title_empty(
|
76
|
-
return (
|
75
|
+
function title_empty(el) {
|
76
|
+
return ($('#article_title').val().trim() === '');
|
77
77
|
}
|
78
78
|
```
|
79
79
|
|
80
80
|
- Call a callback function as action:
|
81
81
|
|
82
|
-
`f.input :published, input_html: { data: { if: 'checked',
|
82
|
+
`f.input :published, input_html: { data: { if: 'checked', then: 'callback set_title', args: '["Unpublished !"]' } }`
|
83
83
|
|
84
84
|
```js
|
85
|
-
function set_title(
|
86
|
-
if(
|
87
|
-
$('#article_title').val(
|
88
|
-
$('#article_title').trigger(
|
85
|
+
function set_title(args) {
|
86
|
+
if($('#article_title').val().trim() === '') {
|
87
|
+
$('#article_title').val(args[0]);
|
88
|
+
$('#article_title').trigger('change');
|
89
89
|
}
|
90
90
|
}
|
91
91
|
```
|
@@ -95,15 +95,14 @@ function set_title( args ) {
|
|
95
95
|
`f2.input :category, as: :select, collection: [ [ 'Cat 1', 'cat1' ], [ 'Cat 2', 'cat2' ], [ 'Cat 3', 'cat3' ] ], input_html: { 'data-function': 'on_change_category' }`
|
96
96
|
|
97
97
|
```js
|
98
|
-
function on_change_category(
|
99
|
-
var target = el.closest(
|
100
|
-
target.prop(
|
101
|
-
target.trigger(
|
98
|
+
function on_change_category(el) {
|
99
|
+
var target = el.closest('fieldset').find('.pub');
|
100
|
+
target.prop('checked', (el.val() == 'cat2');
|
101
|
+
target.trigger('change');
|
102
102
|
}
|
103
103
|
```
|
104
104
|
|
105
105
|
### Inline editing examples
|
106
|
-
|
107
106
|
- Prepare a custom member action to save data, an *update* helper function is available (third parameter is optional, allow to filter using strong parameters):
|
108
107
|
|
109
108
|
```rb
|
@@ -141,7 +140,6 @@ end
|
|
141
140
|
```
|
142
141
|
|
143
142
|
### Dialog example
|
144
|
-
|
145
143
|
Example with 2 models: *Author* and *Article*
|
146
144
|
|
147
145
|
Prepare the content dialog - in Active Admin Author config:
|
@@ -185,15 +183,13 @@ end
|
|
185
183
|
The link url is loaded via AJAX before opening the dialog.
|
186
184
|
|
187
185
|
## Do you like it? Star it!
|
188
|
-
|
189
186
|
If you use this component just star it. A developer is more motivated to improve a project when there is some interest.
|
190
187
|
|
191
188
|
Take a look at [other ActiveAdmin components](https://github.com/blocknotes?utf8=✓&tab=repositories&q=activeadmin&type=source) that I made if you are curious.
|
192
189
|
|
193
190
|
## Contributors
|
194
|
-
|
195
191
|
- [Mattia Roccoberton](http://blocknot.es): author
|
192
|
+
- The good guys that opened issues and pull requests from time to time
|
196
193
|
|
197
194
|
## License
|
198
|
-
|
199
|
-
[MIT](LICENSE.txt)
|
195
|
+
The gem is available as open-source under the terms of the [MIT](LICENSE.txt).
|
@@ -1,209 +1,199 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
return el.val().length !== 0 && el.val().trim();
|
18
|
-
}
|
19
|
-
else if(args.if == 'changed') {
|
20
|
-
return on_change;
|
21
|
-
}
|
22
|
-
else if(args.eq) {
|
23
|
-
return el.val() == args.eq;
|
24
|
-
}
|
25
|
-
else if(args.not) {
|
26
|
-
return el.val() != args.not;
|
27
|
-
}
|
28
|
-
return undefined;
|
29
|
-
}
|
30
|
-
|
31
|
-
// Prepare a field
|
32
|
-
function dfSetupField(el) {
|
33
|
-
var action = el.data('action');
|
34
|
-
var target, args = {};
|
35
|
-
args.if = el.data('if');
|
36
|
-
args.eq = el.data('eq');
|
37
|
-
args.not = el.data('not');
|
38
|
-
args.fn = el.data('function');
|
39
|
-
if(el.data('target')) target = el.closest('fieldset').find(el.data('target')); // closest find for has many associations
|
40
|
-
else if(el.data('gtarget')) target = $(el.data('gtarget'));
|
41
|
-
if(action == 'hide') {
|
42
|
-
if(dfEvalCondition(el, args, false)) target.hide();
|
43
|
-
else target.show();
|
44
|
-
el.on('change', function(event) {
|
45
|
-
if(dfEvalCondition($(this), args, true)) target.hide();
|
46
|
-
else target.show();
|
47
|
-
});
|
48
|
-
}
|
49
|
-
else if(action == 'slide') {
|
50
|
-
if(dfEvalCondition(el, args, false)) target.slideDown();
|
51
|
-
else target.slideUp();
|
52
|
-
el.on('change', function(event) {
|
53
|
-
if(dfEvalCondition($(this), args, true)) target.slideDown();
|
54
|
-
else target.slideUp();
|
55
|
-
});
|
1
|
+
(function () {
|
2
|
+
'use strict'
|
3
|
+
|
4
|
+
const ACTIONS = {
|
5
|
+
addClass: (el, name) => el.addClass(name),
|
6
|
+
callback: (el, name) => {
|
7
|
+
if (window[name]) window[name](el.data('args'))
|
8
|
+
else {
|
9
|
+
el.attr('data-df-errors', 'callback function not found')
|
10
|
+
console.warn(`activeadmin_dynamic_fields callback function not found: ${name}`)
|
11
|
+
}
|
12
|
+
},
|
13
|
+
fade: el => el.fadeOut(),
|
14
|
+
hide: el => el.hide(),
|
15
|
+
setValue: (el, value) => dfSetValue(el, value),
|
16
|
+
slide: el => el.slideUp()
|
56
17
|
}
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
18
|
+
|
19
|
+
const CONDITIONS = {
|
20
|
+
blank: el => el.val().length === 0 || !el.val().trim(),
|
21
|
+
changed: _el => true,
|
22
|
+
checked: el => el.is(':checked'),
|
23
|
+
eq: (el, value) => el.val() == value,
|
24
|
+
not: (el, value) => el.val() != value,
|
25
|
+
not_blank: el => el.val().trim(),
|
26
|
+
not_checked: el => !el.is(':checked')
|
64
27
|
}
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
el.
|
69
|
-
|
70
|
-
|
28
|
+
|
29
|
+
const REVERSE_ACTIONS = {
|
30
|
+
addClass: (el, name) => el.removeClass(name),
|
31
|
+
fade: el => el.fadeIn(),
|
32
|
+
hide: el => el.show(),
|
33
|
+
slide: el => el.slideDown()
|
71
34
|
}
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
35
|
+
|
36
|
+
function dfEvalCondition(el) {
|
37
|
+
let condition = CONDITIONS[el.data('if')]
|
38
|
+
let condition_arg
|
39
|
+
|
40
|
+
if(!condition && el.data('eq')) {
|
41
|
+
condition = CONDITIONS['eq']
|
42
|
+
condition_arg = el.data('eq')
|
79
43
|
}
|
80
|
-
|
44
|
+
if(!condition && el.data('not')) {
|
45
|
+
condition = CONDITIONS['not']
|
46
|
+
condition_arg = el.data('not')
|
47
|
+
}
|
48
|
+
if(!condition && el.data('function')) {
|
49
|
+
condition = window[el.data('function')]
|
50
|
+
if(!condition) {
|
51
|
+
el.attr('data-df-errors', 'custom function not found')
|
52
|
+
console.warn(`activeadmin_dynamic_fields custom function not found: ${el.data('function')}`)
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
return [condition, condition_arg]
|
81
57
|
}
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
58
|
+
|
59
|
+
function dfInitField(el) {
|
60
|
+
const [condition, condition_arg] = dfEvalCondition(el)
|
61
|
+
const action_name = (el.data('then') || el.data('action') || '').substr(0, 8)
|
62
|
+
const action = ACTIONS[action_name]
|
63
|
+
const arg = (el.data('then') || el.data('action') || '').substr(9)
|
64
|
+
const reverse_action = REVERSE_ACTIONS[action_name]
|
65
|
+
if (typeof condition === 'undefined') return
|
66
|
+
if (typeof action === 'undefined' && !el.data('function')) return
|
67
|
+
|
68
|
+
// closest find for has many associations
|
69
|
+
let target
|
70
|
+
if (el.data('target')) target = el.closest('fieldset').find(el.data('target'))
|
71
|
+
else if (el.data('gtarget')) target = $(el.data('gtarget'))
|
72
|
+
if (action_name == 'callback') target = el
|
73
|
+
|
74
|
+
if (condition(el, condition_arg) && el.data('if') != 'changed') action(target, arg)
|
75
|
+
else if (reverse_action) reverse_action(target, arg)
|
76
|
+
|
77
|
+
el.on('change', () => {
|
78
|
+
if (condition(el, condition_arg)) action(target, arg)
|
79
|
+
else if (reverse_action) reverse_action(target, arg)
|
80
|
+
})
|
90
81
|
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
82
|
+
|
83
|
+
// Set the value of an element
|
84
|
+
function dfSetValue(el, val) {
|
85
|
+
if (el.attr('type') == 'checkbox') el.prop('checked', val == '1')
|
86
|
+
else el.val(val)
|
87
|
+
el.trigger('change')
|
96
88
|
}
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
if($(this).data('show-errors')) {
|
129
|
-
var result = '';
|
130
|
-
var message = data.message;
|
131
|
-
for(var key in message) {
|
132
|
-
if(typeof(message[key]) === 'object') {
|
133
|
-
if(result) result += ' - ';
|
134
|
-
result += key + ': ' + message[key].join('; ');
|
89
|
+
|
90
|
+
// Inline update - must be called binded on the editing element
|
91
|
+
function dfUpdateField() {
|
92
|
+
if ($(this).data('loading') != '1') {
|
93
|
+
$(this).data('loading', '1');
|
94
|
+
let _this = $(this);
|
95
|
+
let type = $(this).data('field-type');
|
96
|
+
let new_value;
|
97
|
+
if (type == 'boolean') new_value = !$(this).data('field-value');
|
98
|
+
else if (type == 'select') new_value = $(this).val();
|
99
|
+
else new_value = $(this).text();
|
100
|
+
let data = {};
|
101
|
+
data[$(this).data('field')] = new_value;
|
102
|
+
$.ajax({
|
103
|
+
context: _this,
|
104
|
+
data: { data: data },
|
105
|
+
method: 'POST',
|
106
|
+
url: $(this).data('save-url'),
|
107
|
+
complete: function (req, status) {
|
108
|
+
$(this).data('loading', '0');
|
109
|
+
},
|
110
|
+
success: function (data, status, req) {
|
111
|
+
if (data.status == 'error') {
|
112
|
+
if ($(this).data('show-errors')) {
|
113
|
+
let result = '';
|
114
|
+
let message = data.message;
|
115
|
+
for (let key in message) {
|
116
|
+
if (typeof (message[key]) === 'object') {
|
117
|
+
if (result) result += ' - ';
|
118
|
+
result += key + ': ' + message[key].join('; ');
|
119
|
+
}
|
135
120
|
}
|
121
|
+
if (result) alert(result);
|
136
122
|
}
|
137
|
-
if(result) alert(result);
|
138
123
|
}
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
124
|
+
else {
|
125
|
+
$(this).data('field-value', new_value);
|
126
|
+
if ($(this).data('content')) {
|
127
|
+
let old_text = $(this).text();
|
128
|
+
let old_class = $(this).attr('class');
|
129
|
+
let content = $($(this).data('content'));
|
130
|
+
$(this).text(content.text());
|
131
|
+
$(this).attr('class', content.attr('class'));
|
132
|
+
content.text(old_text);
|
133
|
+
content.attr('class', old_class);
|
134
|
+
$(this).data('content', content);
|
135
|
+
}
|
151
136
|
}
|
152
137
|
}
|
153
|
-
}
|
154
|
-
});
|
155
|
-
}
|
156
|
-
}
|
157
|
-
|
158
|
-
// Init
|
159
|
-
$(document).ready(function() {
|
160
|
-
// Setup dynamic fields
|
161
|
-
$('.active_admin .input [data-if], .active_admin .input [data-function], .active_admin .input [data-eq], .active_admin .input [data-not]').each(function() {
|
162
|
-
dfSetupField($(this));
|
163
|
-
});
|
164
|
-
// Setup dynamic fields for has many associations
|
165
|
-
$('.active_admin .has_many_container').on('has_many_add:after', function(e, fieldset, container) {
|
166
|
-
$('.active_admin .input [data-if], .active_admin .input [data-function], .active_admin .input [data-eq], .active_admin .input [data-not]').each(function() {
|
167
|
-
dfSetupField($(this));
|
168
|
-
});
|
169
|
-
});
|
170
|
-
// Set dialog icon link
|
171
|
-
$('.active_admin [data-df-icon]').each(function() {
|
172
|
-
$(this).append(' »'); // ' •'
|
173
|
-
});
|
174
|
-
// Open content in dialog
|
175
|
-
$('.active_admin [data-df-dialog]').on('click', function(event) {
|
176
|
-
event.preventDefault();
|
177
|
-
$(this).blur();
|
178
|
-
if($('#df-dialog').data('loading') != '1') {
|
179
|
-
$('#df-dialog').data('loading', '1');
|
180
|
-
if($('#df-dialog').length == 0) $('body').append('<div id="df-dialog"></div>');
|
181
|
-
var title = $(this).attr('title');
|
182
|
-
$.ajax({
|
183
|
-
url: $(this).attr('href'),
|
184
|
-
complete: function(req, status) {
|
185
|
-
$('#df-dialog').data('loading', '0');
|
186
|
-
},
|
187
|
-
success: function(data, status, req) {
|
188
|
-
if(title) $('#df-dialog').attr('title', title);
|
189
|
-
$('#df-dialog').html(data);
|
190
|
-
$('#df-dialog').dialog({ modal: true });
|
191
|
-
},
|
192
138
|
});
|
193
139
|
}
|
194
|
-
}
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
$(
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
})
|
140
|
+
}
|
141
|
+
|
142
|
+
// Init
|
143
|
+
$(document).ready(function () {
|
144
|
+
// Setup dynamic fields
|
145
|
+
const selectors = '.active_admin .input [data-if], .active_admin .input [data-eq], .active_admin .input [data-not], .active_admin .input [data-function]'
|
146
|
+
$(selectors).each(function () {
|
147
|
+
dfInitField($(this))
|
148
|
+
})
|
149
|
+
|
150
|
+
// Setup dynamic fields for associations
|
151
|
+
$('.active_admin .has_many_container').on('has_many_add:after', () => {
|
152
|
+
$(selectors).each(function () {
|
153
|
+
dfInitField($(this))
|
154
|
+
})
|
155
|
+
})
|
156
|
+
|
157
|
+
// Set dialog icon link
|
158
|
+
$('.active_admin [data-df-icon]').each(function () {
|
159
|
+
$(this).append(' »')
|
160
|
+
})
|
161
|
+
|
162
|
+
// Open content in dialog
|
163
|
+
$('.active_admin [data-df-dialog]').on('click', function (event) {
|
164
|
+
event.preventDefault()
|
165
|
+
$(this).blur()
|
166
|
+
if ($('#df-dialog').data('loading') != '1') {
|
167
|
+
$('#df-dialog').data('loading', '1')
|
168
|
+
if ($('#df-dialog').length == 0) $('body').append('<div id="df-dialog"></div>')
|
169
|
+
let title = $(this).attr('title')
|
170
|
+
$.ajax({
|
171
|
+
url: $(this).attr('href'),
|
172
|
+
complete: function (req, status) {
|
173
|
+
$('#df-dialog').data('loading', '0')
|
174
|
+
},
|
175
|
+
success: function (data, status, req) {
|
176
|
+
if (title) $('#df-dialog').attr('title', title)
|
177
|
+
$('#df-dialog').html(data)
|
178
|
+
$('#df-dialog').dialog({ modal: true })
|
179
|
+
},
|
180
|
+
})
|
181
|
+
}
|
182
|
+
})
|
183
|
+
|
184
|
+
// Inline editing
|
185
|
+
$('[data-field][data-field-type="boolean"][data-save-url]').each(function () {
|
186
|
+
$(this).on('click', $.proxy(dfUpdateField, $(this)))
|
187
|
+
})
|
188
|
+
$('[data-field][data-field-type="string"][data-save-url]').each(function () {
|
189
|
+
$(this).data('field-value', $(this).text())
|
190
|
+
let fnUpdate = $.proxy(dfUpdateField, $(this))
|
191
|
+
$(this).on('blur', function () {
|
192
|
+
if ($(this).data('field-value') != $(this).text()) fnUpdate()
|
193
|
+
})
|
194
|
+
})
|
195
|
+
$('[data-field][data-field-type="select"][data-save-url]').each(function () {
|
196
|
+
$(this).on('change', $.proxy(dfUpdateField, $(this)))
|
197
|
+
})
|
198
|
+
})
|
199
|
+
})()
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeadmin_dynamic_fields
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Roccoberton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activeadmin
|
@@ -109,33 +109,33 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 4.0.1
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: rubocop
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 0.90.0
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 0.90.0
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: selenium-webdriver
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
131
|
+
version: 3.142.7
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
138
|
+
version: 3.142.7
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: sqlite3
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|