activeadmin_dynamic_fields 0.3.0 → 0.4.0

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: 1af148e7cd9d7704c902e17fdb022acbb1c0c2012bf423f9be6e4ae92cdb6f5f
4
- data.tar.gz: ad108b3ae42ba846251dcab61487e68809e4cfaf21e453039a7ad3cb0cb22bd8
3
+ metadata.gz: bf72bdd2f498f04dd656b044b1b711cd1e4962ad98d9190807ac9b4bfa423ba0
4
+ data.tar.gz: 036c3c43e6b00ed99b900f21216b824b00dccbf3a3d871cdfa331080f30eceb3
5
5
  SHA512:
6
- metadata.gz: 0c76b4cb42b90bf7c88c4cafbbab1bb40f8fa61efbaa8acef0cb3230c6dd2f3eea3b0bf88413431c2a275538ef7c1f37aa0463a2445f0e2a61eae17b189955b5
7
- data.tar.gz: d09b1cfe869567e5634236a31385608800375be5cef690b5ee1c420d2cba8a5018f642c5bec0d2996078338a8bdfa0499c02d839e264b9704fb5581e5659d44d
6
+ metadata.gz: 94007fc44295a8e251f011ef78884c31a03904e53d264bc9b5aa716645c268a0c3a7343f75b0831f790a36b14f1dcdb03ea6a87fb8e819accb36b871c5617f14
7
+ data.tar.gz: bc6beec26ce12eb2f40c70cc8b9fd12f3cdd416ecf735380fd77343d395e7e7b3f2665cfc2fed8a8339651dcbc12db1eaaae3ce7c6019b5cf6bdf133c4390e31
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017 Mattia Roccoberton
1
+ Copyright (c) 2017-2020 Mattia Roccoberton
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
data/README.md CHANGED
@@ -20,7 +20,9 @@ The easiest way to show how this plugin works is looking the examples [below](#e
20
20
  ```
21
21
 
22
22
  ## Options
23
- Options are passed to fields using *input_html* parameter as *data* attributes:
23
+ Options are passed to fields using *input_html* parameter as *data* attributes.
24
+
25
+ Conditions:
24
26
  - **data-if**: check a condition, values:
25
27
  + **checked**: check if a checkbox is checked
26
28
  + **not_checked**: check if a checkbox is not checked
@@ -29,17 +31,22 @@ Options are passed to fields using *input_html* parameter as *data* attributes:
29
31
  + **changed**: check if the value of an input is changed (dirty)
30
32
  - **data-eq**: check if a field has a specific value
31
33
  - **data-not**: check if a field hasn't a specific value
32
- - **data-target**: target css selector (from parent fieldset, look for the closest match)
33
- - **data-gtarget**: target css selector globally
34
- - **data-then**: the action to trigger (alias **data-action**), values:
34
+ - **data-function**: check the return value of a custom function
35
+
36
+ Actions:
37
+ - **data-then**: action to trigger (alias **data-action**), values:
35
38
  + **hide**: hides elements
36
39
  + **slide**: hides elements (using sliding)
37
40
  + **fade**: hides elements (using fading)
38
41
  + **addClass**: adds classes
39
42
  + **setValue**: set a value
40
- + **callback**: call a function
41
- - **data-function**: check the return value of a custom function
42
- - **data-arg**: argument passed to the custom set function (as array of strings)
43
+ + **callback**: call a function (with arguments: **data-args**)
44
+ - **data-else**: action to trigger when the condition check is not true
45
+ - **data-args**: arguments passed to the callback function
46
+
47
+ Targets:
48
+ - **data-target**: target css selector (from parent fieldset, look for the closest match)
49
+ - **data-gtarget**: target css selector globally
43
50
 
44
51
  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
52
 
@@ -59,17 +66,25 @@ form do |f|
59
66
  end
60
67
  ```
61
68
 
62
- - Add 3 classes (*first*, *second*, *third*) if a checkbox is not checked:
69
+ - Add 3 classes (*first*, *second*, *third*) if a checkbox is not checked, else add "forth" class:
63
70
 
64
- `f.input :published, input_html: { data: { if: 'not_checked', then: 'addClass first second third', target: '.grp1' } }`
71
+ ```rb
72
+ data = { if: 'not_checked', then: 'addClass first second third', target: '.grp1', else: 'addClass forth' }
73
+ f.input :published, input_html: { data: data }
74
+ ```
65
75
 
66
76
  - Set another field value if a string field is blank:
67
77
 
68
- `f.input :title, input_html: { data: { if: 'blank', then: 'setValue 10', target: '#article_position' } }`
78
+ ```rb
79
+ f.input :title, input_html: { data: { if: 'blank', then: 'setValue 10', target: '#article_position' } }
80
+ ```
69
81
 
70
82
  - Use a custom function for conditional check (*title_not_empty()* must be available on global scope) (with alternative syntax for data attributes):
71
83
 
72
- `f.input :title, input_html: { 'data-function': 'title_empty', 'data-then': 'slide', 'data-target': '#article_description_input' }`
84
+ ```rb
85
+ attrs = { 'data-function': 'title_empty', 'data-then': 'slide', 'data-target': '#article_description_input' }
86
+ f.input :title, input_html: attrs
87
+ ```
73
88
 
74
89
  ```js
75
90
  function title_empty(el) {
@@ -79,7 +94,10 @@ function title_empty(el) {
79
94
 
80
95
  - Call a callback function as action:
81
96
 
82
- `f.input :published, input_html: { data: { if: 'checked', then: 'callback set_title', args: '["Unpublished !"]' } }`
97
+ ```rb
98
+ data = { if: 'checked', then: 'callback set_title', args: '["Unpublished !"]' }
99
+ f.input :published, input_html: { data: data }
100
+ ```
83
101
 
84
102
  ```js
85
103
  function set_title(args) {
@@ -92,7 +110,10 @@ function set_title(args) {
92
110
 
93
111
  - Custom function without action:
94
112
 
95
- `f2.input :category, as: :select, collection: [ [ 'Cat 1', 'cat1' ], [ 'Cat 2', 'cat2' ], [ 'Cat 3', 'cat3' ] ], input_html: { 'data-function': 'on_change_category' }`
113
+ ```rb
114
+ collection = [['Cat 1', 'cat1'], ['Cat 2', 'cat2'], ['Cat 3', 'cat3']]
115
+ f2.input :category, as: :select, collection: collection, input_html: { 'data-function': 'on_change_category' }
116
+ ```
96
117
 
97
118
  ```js
98
119
  function on_change_category(el) {
data/Rakefile CHANGED
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/gem_tasks'
3
+ require "bundler/gem_tasks"
@@ -12,7 +12,11 @@
12
12
  },
13
13
  fade: el => el.fadeOut(),
14
14
  hide: el => el.hide(),
15
- setValue: (el, value) => dfSetValue(el, value),
15
+ setValue: (el, value) => {
16
+ if (el.attr('type') == 'checkbox') el.prop('checked', value == '1')
17
+ else el.val(value)
18
+ el.trigger('change')
19
+ },
16
20
  slide: el => el.slideUp()
17
21
  }
18
22
 
@@ -33,58 +37,65 @@
33
37
  slide: el => el.slideDown()
34
38
  }
35
39
 
36
- function dfEvalCondition(el) {
37
- let condition = CONDITIONS[el.data('if')]
38
- let condition_arg
40
+ class Field {
41
+ constructor(el) {
42
+ const action = el.data('then') || el.data('action') || ''
43
+ const action_name = action.split(' ', 1)[0]
44
+ const else_action = el.data('else') || ''
45
+ const else_action_name = else_action.split(' ', 1)[0]
46
+
47
+ this.el = el
48
+ this.action = ACTIONS[action_name]
49
+ this.action_arg = action.substring(action.indexOf(' ') + 1)
50
+ this.reverse_action = REVERSE_ACTIONS[action_name]
51
+ this.else_action = ACTIONS[else_action_name]
52
+ this.else_action_arg = else_action.substring(else_action.indexOf(' ') + 1)
53
+ this.else_reverse_action = REVERSE_ACTIONS[else_action_name]
54
+ this.condition = CONDITIONS[el.data('if')]
55
+ if (!this.condition && el.data('eq')) {
56
+ [this.condition, this.condition_arg] = [CONDITIONS['eq'], el.data('eq')]
57
+ }
58
+ if (!this.condition && el.data('not')) {
59
+ [this.condition, this.condition_arg] = [CONDITIONS['not'], el.data('not')]
60
+ }
61
+ this.custom_function = el.data('function')
62
+ if (!this.condition && this.custom_function) {
63
+ this.condition = window[this.custom_function]
64
+ if (!this.condition) {
65
+ el.attr('data-df-errors', 'custom function not found')
66
+ console.warn(`activeadmin_dynamic_fields custom function not found: ${this.custom_function}`)
67
+ }
68
+ }
39
69
 
40
- if(!condition && el.data('eq')) {
41
- condition = CONDITIONS['eq']
42
- condition_arg = el.data('eq')
43
- }
44
- if(!condition && el.data('not')) {
45
- condition = CONDITIONS['not']
46
- condition_arg = el.data('not')
70
+ // closest find for has many associations
71
+ if (el.data('target')) this.target = el.closest('fieldset').find(el.data('target'))
72
+ else if (el.data('gtarget')) this.target = $(el.data('gtarget'))
73
+ if (action_name == 'callback') this.target = el
47
74
  }
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')}`)
75
+
76
+ apply(el) {
77
+ if (this.condition(el, this.condition_arg)) {
78
+ if (this.else_reverse_action) this.else_reverse_action(this.target, this.else_action_arg)
79
+ this.action(this.target, this.action_arg)
80
+ }
81
+ else {
82
+ if (this.reverse_action) this.reverse_action(this.target, this.action_arg)
83
+ if (this.else_action) this.else_action(this.target, this.else_action_arg)
53
84
  }
54
85
  }
55
86
 
56
- return [condition, condition_arg]
57
- }
87
+ is_valid() {
88
+ if (!this.condition) return false
89
+ if (!this.action && !this.custom_function) return false
58
90
 
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
- })
81
- }
91
+ return true
92
+ }
82
93
 
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')
94
+ setup() {
95
+ if (!this.is_valid()) return
96
+ if (this.el.data('if') != 'changed') this.apply(this.el)
97
+ this.el.on('change', () => this.apply(this.el))
98
+ }
88
99
  }
89
100
 
90
101
  // Inline update - must be called binded on the editing element
@@ -144,14 +155,14 @@
144
155
  // Setup dynamic fields
145
156
  const selectors = '.active_admin .input [data-if], .active_admin .input [data-eq], .active_admin .input [data-not], .active_admin .input [data-function]'
146
157
  $(selectors).each(function () {
147
- dfInitField($(this))
158
+ new Field($(this)).setup()
148
159
  })
149
160
 
150
161
  // Setup dynamic fields for associations
151
162
  $('.active_admin .has_many_container').on('has_many_add:after', () => {
152
163
  $(selectors).each(function () {
153
- dfInitField($(this))
154
- })
164
+ new Field($(this)).setup()
165
+ })
155
166
  })
156
167
 
157
168
  // Set dialog icon link
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveAdmin
4
4
  module DynamicFields
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
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.3.0
4
+ version: 0.4.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-09-17 00:00:00.000000000 Z
11
+ date: 2020-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeadmin