activeadmin_dynamic_fields 0.5.0 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '019f2b81ed1552f13f57b73141860957f4869b10de1f018a289aa8724cc23ec1'
4
- data.tar.gz: 4ed1bb60f5b1ddef1a3d870296d8548faa18cc36db5adadb8271f0c655c769f6
3
+ metadata.gz: 1a0aa1741561ea938be8cfdfb7d75df0b85ba24dcdf303639ac3824ffc6ddd4f
4
+ data.tar.gz: 208287487042b2ef3de93b20f9a733383e470e44473c40b398b3600ec18f11bc
5
5
  SHA512:
6
- metadata.gz: b07cc4e73b801ef79ee52b52a6c82117d7e966a2f1eadb0e415e00c608456c02f2c14694c2fc41037ad381c9c0c3bfbf1c0ed96c0c6d13bd0ce3335c38dc1e11
7
- data.tar.gz: c0aa33df12ef6ed16927a49bb9b93d0fcffeffc6f20b661f11edb350544f12e550f90fd5fa5870a43154c0097995bbb02f2f80f24e1ff821eddc2d0fa60e613d
6
+ metadata.gz: 6817a8dccfb3691bf61cfe2f8a30d0dd51fb45b40becc20fab9b36fe9b8c573e9f78f68dc12e6c8a0e91c34d2416d773f5f3a1d62359b32e2888e68b2d19113a
7
+ data.tar.gz: 0f15dcb8b29b7cbf73ba0e6932b6a0dd42a91ca883357ea0024da13b5b65867c2cf22bcae0458967ec37f70a7667607c0cb65be8aa43b17319b83595c2ee8cbd
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
- # ActiveAdmin Dynamic Fields [![Gem Version](https://badge.fury.io/rb/activeadmin_dynamic_fields.svg)](https://badge.fury.io/rb/activeadmin_dynamic_fields) [![CircleCI](https://circleci.com/gh/blocknotes/activeadmin_dynamic_fields.svg?style=svg)](https://circleci.com/gh/blocknotes/activeadmin_dynamic_fields)
1
+ # ActiveAdmin Dynamic Fields
2
+ [![gem version](https://badge.fury.io/rb/activeadmin_dynamic_fields.svg)](https://badge.fury.io/rb/activeadmin_dynamic_fields) [![gem downloads](https://badgen.net/rubygems/dt/activeadmin_dynamic_fields)](https://rubygems.org/gems/activeadmin_dynamic_fields) [![linters](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/linters.yml/badge.svg)](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/linters.yml) [![specs](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/specs.yml/badge.svg)](https://github.com/blocknotes/activeadmin_dynamic_fields/actions/workflows/specs.yml)
2
3
 
3
4
  An Active Admin plugin to add dynamic behaviors to some fields.
4
5
 
5
6
  Features:
7
+
6
8
  - set conditional checks on fields
7
9
  - trigger actions on target elements
8
10
  - inline field editing
@@ -10,19 +12,39 @@ Features:
10
12
 
11
13
  The easiest way to show how this plugin works is looking the examples [below](#examples).
12
14
 
15
+ Please :star: if you like it.
16
+
13
17
  ## Install
14
- - Add to your Gemfile: `gem 'activeadmin_dynamic_fields'`
15
- - Execute bundle
16
- - Add at the end of your ActiveAdmin javascripts (_app/assets/javascripts/active_admin.js_):
18
+
19
+ First, add the gem to your ActiveAdmin project: `gem 'activeadmin_dynamic_fields'` (and execute `bundle`)
20
+
21
+ If you installed Active Admin **without Webpacker** support:
22
+ - add at the end of your ActiveAdmin javascripts (_app/assets/javascripts/active_admin.js_):
17
23
 
18
24
  ```js
19
25
  //= require activeadmin/dynamic_fields
20
26
  ```
21
27
 
28
+ Otherwise **with Webpacker**:
29
+
30
+ - Execute in your project root:
31
+
32
+ ```sh
33
+ yarn add blocknotes/activeadmin_dynamic_fields
34
+ ```
35
+
36
+ - Add to your *app/javascript/packs/active_admin.js*:
37
+
38
+ ```js
39
+ require('activeadmin_dynamic_fields')
40
+ ```
41
+
22
42
  ## Options
43
+
23
44
  Options are passed to fields using *input_html* parameter as *data* attributes.
24
45
 
25
46
  Conditions:
47
+
26
48
  - **data-if**: check a condition, values:
27
49
  + **checked**: check if a checkbox is checked (ex. `"data-if": "checked"`)
28
50
  + **not_checked**: check if a checkbox is not checked
@@ -36,6 +58,7 @@ Conditions:
36
58
  - **data-function**: check the return value of a custom function (ex. `"data-function": "my_check"`)
37
59
 
38
60
  Actions:
61
+
39
62
  - **data-then**: action to trigger (alias **data-action**), values:
40
63
  + **hide**: hides elements (ex. `"data-then": "hide", "data-target": ".errors"`)
41
64
  + **slide**: hides elements (using sliding)
@@ -49,6 +72,7 @@ Actions:
49
72
  - **data-args**: arguments passed to the callback function
50
73
 
51
74
  Targets:
75
+
52
76
  - **data-target**: target css selector (from parent fieldset, look for the closest match)
53
77
  - **data-gtarget**: target css selector globally
54
78
 
@@ -57,6 +81,7 @@ A check condition or a custom check function are required. A trigger action is r
57
81
  ## Examples
58
82
 
59
83
  ### Dynamic fields examples
84
+
60
85
  - A checkbox that hides other fields if is checked (ex. model *Article*):
61
86
 
62
87
  ```rb
@@ -128,6 +153,7 @@ function on_change_category(el) {
128
153
  ```
129
154
 
130
155
  ### Inline editing examples
156
+
131
157
  - Prepare a custom member action to save data, an *update* helper function is available (third parameter is optional, allow to filter using strong parameters):
132
158
 
133
159
  ```rb
@@ -165,6 +191,7 @@ end
165
191
  ```
166
192
 
167
193
  ### Dialog example
194
+
168
195
  Example with 2 models: *Author* and *Article*
169
196
 
170
197
  Prepare the content dialog - in Active Admin Author config:
@@ -208,13 +235,16 @@ end
208
235
  The link url is loaded via AJAX before opening the dialog.
209
236
 
210
237
  ## Do you like it? Star it!
211
- If you use this component just star it. A developer is more motivated to improve a project when there is some interest.
212
238
 
213
- 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.
239
+ If you use this component just star it. A developer is more motivated to improve a project when there is some interest. My other [Active Admin components](https://github.com/blocknotes?utf8=✓&tab=repositories&q=activeadmin&type=source).
240
+
241
+ Or consider offering me a coffee, it's a small thing but it is greatly appreciated: [about me](https://www.blocknot.es/about-me).
214
242
 
215
243
  ## Contributors
244
+
216
245
  - [Mattia Roccoberton](http://blocknot.es): author
217
246
  - The good guys that opened issues and pull requests from time to time
218
247
 
219
248
  ## License
249
+
220
250
  The gem is available as open-source under the terms of the [MIT](LICENSE.txt).
data/Rakefile CHANGED
@@ -1,3 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
3
+ require 'bundler/gem_tasks'
4
+
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ # t.ruby_opts = %w[-w]
10
+ t.rspec_opts = ['--color', '--format documentation']
11
+ end
12
+
13
+ task default: :spec
14
+ rescue LoadError
15
+ puts '! LoadError: no RSpec available'
16
+ end
@@ -1,6 +1,7 @@
1
1
  (function () {
2
2
  'use strict'
3
3
 
4
+ // noinspection JSUnusedGlobalSymbols
4
5
  const ACTIONS = {
5
6
  addClass: (el, name) => el.addClass(name),
6
7
  addStyle: (el, extra_style) => {
@@ -11,7 +12,8 @@
11
12
  }
12
13
  },
13
14
  callback: (el, name) => {
14
- if (window[name]) window[name](el.data('args'))
15
+ const cb_function = window.hasOwnProperty(name) ? window[name] : null
16
+ if (typeof cb_function === 'function') cb_function(el.data('args'))
15
17
  else {
16
18
  el.attr('data-df-errors', 'callback function not found')
17
19
  console.warn(`activeadmin_dynamic_fields callback function not found: ${name}`)
@@ -21,13 +23,14 @@
21
23
  hide: el => el.hide(),
22
24
  setText: (el, text) => el.text(text),
23
25
  setValue: (el, value) => {
24
- if (el.attr('type') == 'checkbox') el.prop('checked', value == '1')
26
+ if (el.attr('type') === 'checkbox') el.prop('checked', value === '1')
25
27
  else el.val(value)
26
28
  el.trigger('change')
27
29
  },
28
30
  slide: el => el.slideUp()
29
31
  }
30
32
 
33
+ // noinspection EqualityComparisonWithCoercionJS, JSUnusedGlobalSymbols
31
34
  const CONDITIONS = {
32
35
  blank: el => el.val().length === 0 || !el.val().trim(),
33
36
  changed: _el => true,
@@ -88,12 +91,21 @@
88
91
  }
89
92
 
90
93
  evaluateCondition() {
91
- let value = CONDITIONS[this.el.data('if')?.trim()]
94
+ let data_if = this.el.data('if')
95
+ let value = data_if ? CONDITIONS[data_if.trim()] : null
92
96
  if (value) return { condition: value }
93
- if (value = this.el.data('eq')) return { condition: CONDITIONS['eq'], condition_arg: value }
94
- if (value = this.el.data('not')) return { condition: CONDITIONS['not'], condition_arg: value }
95
- if (value = this.el.data('match')) return { condition: CONDITIONS['match'], condition_arg: new RegExp(value) }
96
- if (value = this.el.data('mismatch')) return { condition: CONDITIONS['mismatch'], condition_arg: new RegExp(value) }
97
+
98
+ value = this.el.data('eq')
99
+ if (value) return { condition: CONDITIONS['eq'], condition_arg: value }
100
+
101
+ value = this.el.data('not')
102
+ if (value) return { condition: CONDITIONS['not'], condition_arg: value }
103
+
104
+ value = this.el.data('match')
105
+ if (value) return { condition: CONDITIONS['match'], condition_arg: new RegExp(value) }
106
+
107
+ value = this.el.data('mismatch')
108
+ if (value) return { condition: CONDITIONS['mismatch'], condition_arg: new RegExp(value) }
97
109
 
98
110
  this.custom_function = this.el.data('function')
99
111
  if (this.custom_function) {
@@ -112,32 +124,30 @@
112
124
  // closest find for has many associations
113
125
  if (this.el.data('target')) this.target = this.el.closest('fieldset').find(this.el.data('target'))
114
126
  else if (this.el.data('gtarget')) this.target = $(this.el.data('gtarget'))
115
- if (action_name == 'callback') this.target = this.el
127
+ if (action_name === 'callback') this.target = this.el
116
128
  }
117
129
 
118
130
  isValid() {
119
131
  if (!this.condition) return false
120
- if (!this.action && !this.custom_function) return false
121
-
122
- return true
132
+ return (this.action || this.custom_function)
123
133
  }
124
134
 
125
135
  setup() {
126
136
  if (!this.isValid()) return
127
- if (this.el.data('if') != 'changed') this.apply()
137
+ if (this.el.data('if') !== 'changed') this.apply()
128
138
  this.el.on('change', () => this.apply())
129
139
  }
130
140
  }
131
141
 
132
- // Inline update - must be called binded on the editing element
142
+ // Inline update - must be called bound on the editing element
133
143
  function dfUpdateField() {
134
- if ($(this).data('loading') != '1') {
144
+ if ($(this).data('loading') !== '1') {
135
145
  $(this).data('loading', '1');
136
146
  let _this = $(this);
137
147
  let type = $(this).data('field-type');
138
148
  let new_value;
139
- if (type == 'boolean') new_value = !$(this).data('field-value');
140
- else if (type == 'select') new_value = $(this).val();
149
+ if (type === 'boolean') new_value = !$(this).data('field-value');
150
+ else if (type === 'select') new_value = $(this).val();
141
151
  else new_value = $(this).text();
142
152
  let data = {};
143
153
  data[$(this).data('field')] = new_value;
@@ -146,16 +156,16 @@
146
156
  data: { data: data },
147
157
  method: 'POST',
148
158
  url: $(this).data('save-url'),
149
- complete: function (req, status) {
159
+ complete: function (_req, _status) {
150
160
  $(this).data('loading', '0');
151
161
  },
152
- success: function (data, status, req) {
153
- if (data.status == 'error') {
162
+ success: function (data, _status, _req) {
163
+ if (data.status === 'error') {
154
164
  if ($(this).data('show-errors')) {
155
165
  let result = '';
156
166
  let message = data.message;
157
167
  for (let key in message) {
158
- if (typeof (message[key]) === 'object') {
168
+ if (message.hasOwnProperty(key) && typeof (message[key]) === 'object') {
159
169
  if (result) result += ' - ';
160
170
  result += key + ': ' + message[key].join('; ');
161
171
  }
@@ -181,8 +191,7 @@
181
191
  }
182
192
  }
183
193
 
184
- // Init
185
- $(document).ready(function () {
194
+ function dfInit() {
186
195
  // Setup dynamic fields
187
196
  const selectors = '.active_admin .input [data-if], .active_admin .input [data-eq], .active_admin .input [data-not], .active_admin .input [data-match], .active_admin .input [data-mismatch], .active_admin .input [data-function]'
188
197
  $(selectors).each(function () {
@@ -205,20 +214,23 @@
205
214
  $('.active_admin [data-df-dialog]').on('click', function (event) {
206
215
  event.preventDefault()
207
216
  $(this).blur()
208
- if ($('#df-dialog').data('loading') != '1') {
209
- $('#df-dialog').data('loading', '1')
210
- if ($('#df-dialog').length == 0) $('body').append('<div id="df-dialog"></div>')
217
+ const df_dialog = $('#df-dialog')
218
+
219
+ if (df_dialog.data('loading') !== '1') {
220
+ df_dialog.data('loading', '1')
221
+ if (df_dialog.length === 0) $('body').append('<div id="df-dialog"></div>')
211
222
  let title = $(this).attr('title')
212
223
  $.ajax({
213
224
  url: $(this).attr('href'),
214
- complete: function (req, status) {
225
+ complete: function (_req, _status) {
215
226
  $('#df-dialog').data('loading', '0')
216
227
  },
217
- success: function (data, status, req) {
218
- if (title) $('#df-dialog').attr('title', title)
219
- $('#df-dialog').html(data)
220
- $('#df-dialog').dialog({ modal: true })
221
- },
228
+ success: function (data, _status, _req) {
229
+ const dialog = $('#df-dialog')
230
+ if (title) dialog.attr('title', title)
231
+ dialog.html(data)
232
+ dialog.dialog({ modal: true })
233
+ }
222
234
  })
223
235
  }
224
236
  })
@@ -231,11 +243,14 @@
231
243
  $(this).data('field-value', $(this).text())
232
244
  let fnUpdate = $.proxy(dfUpdateField, $(this))
233
245
  $(this).on('blur', function () {
234
- if ($(this).data('field-value') != $(this).text()) fnUpdate()
246
+ if ($(this).data('field-value') !== $(this).text()) fnUpdate()
235
247
  })
236
248
  })
237
249
  $('[data-field][data-field-type="select"][data-save-url]').each(function () {
238
250
  $(this).on('change', $.proxy(dfUpdateField, $(this)))
239
251
  })
240
- })
252
+ }
253
+
254
+ $(document).ready(dfInit)
255
+ $(document).on('turbolinks:load', dfInit)
241
256
  })()
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveAdmin
4
4
  module DynamicFields
5
- VERSION = '0.5.0'
5
+ VERSION = '0.6.4'
6
6
  end
7
7
  end
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.5.0
4
+ version: 0.6.4
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-10-04 00:00:00.000000000 Z
11
+ date: 2022-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeadmin
@@ -25,131 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activestorage
28
+ name: appraisal
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 6.0.3.2
33
+ version: '2.4'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
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: rubocop
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: 0.90.0
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: 0.90.0
125
- - !ruby/object:Gem::Dependency
126
- name: selenium-webdriver
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: 3.142.7
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: 3.142.7
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
40
+ version: '2.4'
153
41
  description: An Active Admin plugin to add dynamic behaviors to fields
154
42
  email: mat@blocknot.es
155
43
  executables: []
@@ -167,7 +55,10 @@ files:
167
55
  homepage: https://github.com/blocknotes/activeadmin_dynamic_fields
168
56
  licenses:
169
57
  - MIT
170
- metadata: {}
58
+ metadata:
59
+ homepage_uri: https://github.com/blocknotes/activeadmin_dynamic_fields
60
+ source_code_uri: https://github.com/blocknotes/activeadmin_dynamic_fields
61
+ rubygems_mfa_required: 'true'
171
62
  post_install_message:
172
63
  rdoc_options: []
173
64
  require_paths:
@@ -183,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
74
  - !ruby/object:Gem::Version
184
75
  version: '0'
185
76
  requirements: []
186
- rubygems_version: 3.0.3
77
+ rubygems_version: 3.1.6
187
78
  signing_key:
188
79
  specification_version: 4
189
80
  summary: Dynamic fields for ActiveAdmin