activeadmin_dynamic_fields 0.1.5 → 0.2.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
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d599f816a20b2b7068d3b7d72e7ada1002c848bf
|
4
|
+
data.tar.gz: 296760d26145ceddb5e535296c1fa8a234e9781d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28779caf4f980c64bffc0cc88e006f0d3ec9b6b1666e53f306a57e9e035c386f7c4f30d55994ee38e610bd337b6922a2470662f5c341b3ca2f77acfbf322b021
|
7
|
+
data.tar.gz: e078d3ab6b1ddc26c1af8c899c4aa2a903803b59e3f2f56a331e071437fb98265efd8386653fe16f140015e2ce8070f2a7d1b65b6313167ec855d73da3b3b722
|
data/README.md
CHANGED
@@ -6,6 +6,7 @@ Features:
|
|
6
6
|
|
7
7
|
- set conditional checks on fields
|
8
8
|
- trigger some actions on other fields
|
9
|
+
- inline field editing
|
9
10
|
- create links to load some content in a dialog
|
10
11
|
|
11
12
|
The easiest way to show how this plugin works is looking the examples [below](#examples-of-dynamic-fields).
|
@@ -39,7 +40,9 @@ Options are passed to fields using *input_html* parameter as *data* attributes:
|
|
39
40
|
- **data-function**: check the return value of a custom function
|
40
41
|
- **data-arg**: argument passed to the custom set function (as array of strings)
|
41
42
|
|
42
|
-
## Examples
|
43
|
+
## Examples
|
44
|
+
|
45
|
+
### Dynamic fields examples
|
43
46
|
|
44
47
|
- A checkbox that hides other fields if false (ex. model *Article*):
|
45
48
|
|
@@ -97,7 +100,45 @@ function on_change_category( el ) {
|
|
97
100
|
}
|
98
101
|
```
|
99
102
|
|
100
|
-
|
103
|
+
### Inline editing example
|
104
|
+
|
105
|
+
- Prepare a custom member action to save data, an *update* helper function is available (third parameter is optional, allow to filter using strong parameters):
|
106
|
+
|
107
|
+
```rb
|
108
|
+
member_action :save, method: [:post] do
|
109
|
+
render ActiveAdmin::DynamicFields::update( resource, params )
|
110
|
+
# render ActiveAdmin::DynamicFields::update( resource, params, [:published] )
|
111
|
+
# render ActiveAdmin::DynamicFields::update( resource, params, Article::permit_params )
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
- In *index* config:
|
116
|
+
|
117
|
+
```rb
|
118
|
+
# Edit a string:
|
119
|
+
column :title do |row|
|
120
|
+
div row.title, ActiveAdmin::DynamicFields::edit_string( :title, save_admin_article_path( row.id ) )
|
121
|
+
end
|
122
|
+
# Edit a boolean:
|
123
|
+
column :published do |row|
|
124
|
+
status_tag row.published, ActiveAdmin::DynamicFields::edit_boolean( :published, save_admin_article_path( row.id ), row.published )
|
125
|
+
end
|
126
|
+
# Edit a select ([''] allow to have a blank value):
|
127
|
+
column :author do |row|
|
128
|
+
select ActiveAdmin::DynamicFields::edit_select( :author_id, save_admin_article_path( row.id ) ) do
|
129
|
+
options_for_select( [''] + Author.pluck( :name, :id ), row.author_id )
|
130
|
+
end
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
- In *show* config (less useful):
|
135
|
+
```rb
|
136
|
+
row :title do |row|
|
137
|
+
div row.title, ActiveAdmin::DynamicFields::edit_string( :title, save_admin_article_path( row.id ) )
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
### Dialog example
|
101
142
|
|
102
143
|
Example with 2 models: *Author* and *Article*
|
103
144
|
|
@@ -99,6 +99,61 @@ function dfSetValue( el, val ) {
|
|
99
99
|
el.trigger( 'change' );
|
100
100
|
}
|
101
101
|
|
102
|
+
// Inline update - must be called binded on the editing element
|
103
|
+
function dfUpdateField() {
|
104
|
+
if( $(this).data( 'loading' ) != '1' ) {
|
105
|
+
$(this).data( 'loading', '1' );
|
106
|
+
var _this = $(this);
|
107
|
+
var type = $(this).data( 'field-type' );
|
108
|
+
var new_value;
|
109
|
+
if( type == 'boolean' ) new_value = !$(this).data( 'field-value' );
|
110
|
+
else if( type == 'select' ) new_value = $(this).val();
|
111
|
+
else new_value = $(this).text();
|
112
|
+
var data = {};
|
113
|
+
data[$(this).data('field')] = new_value;
|
114
|
+
$.ajax({
|
115
|
+
context: _this,
|
116
|
+
data: { data: data },
|
117
|
+
method: 'POST',
|
118
|
+
url: $(this).data( 'save-url' ),
|
119
|
+
complete: function( req, status ) {
|
120
|
+
$(this).data( 'loading', '0' );
|
121
|
+
},
|
122
|
+
success: function( data, status, req ) {
|
123
|
+
if( data.status == 'error' ) {
|
124
|
+
if( $(this).data( 'show-errors' ) ) {
|
125
|
+
var result = '';
|
126
|
+
var message = data.message;
|
127
|
+
for( var key in message ) {
|
128
|
+
if( typeof( message[key] ) === 'object' ) {
|
129
|
+
if( result ) result += ' - ';
|
130
|
+
result += key + ': ' + message[key].join( '; ' );
|
131
|
+
}
|
132
|
+
}
|
133
|
+
if( result ) alert( result );
|
134
|
+
}
|
135
|
+
}
|
136
|
+
else {
|
137
|
+
$(this).data( 'field-value', new_value );
|
138
|
+
if( $(this).data('content') ) {
|
139
|
+
var old_text = $(this).text();
|
140
|
+
var old_class = $(this).attr( 'class' );
|
141
|
+
var content = $($(this).data('content'));
|
142
|
+
$(this).text( content.text() );
|
143
|
+
$(this).attr( 'class', content.attr( 'class' ) );
|
144
|
+
content.text( old_text );
|
145
|
+
content.attr( 'class', old_class );
|
146
|
+
$(this).data( 'content', content );
|
147
|
+
}
|
148
|
+
}
|
149
|
+
},
|
150
|
+
// error: function( req, status, error ) {
|
151
|
+
// // if( $(this).data( 'show-errors' ) && req.responseJSON.message ) { }
|
152
|
+
// },
|
153
|
+
});
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
102
157
|
// Init
|
103
158
|
$(document).ready( function() {
|
104
159
|
// Setup dynamic fields
|
@@ -111,20 +166,43 @@ $(document).ready( function() {
|
|
111
166
|
dfSetupField( $(this) );
|
112
167
|
});
|
113
168
|
});
|
169
|
+
// Set dialog icon link
|
170
|
+
$('.active_admin [data-df-icon]').each( function() {
|
171
|
+
$(this).append( ' »' ); // ' •'
|
172
|
+
});
|
114
173
|
// Open content in dialog
|
115
174
|
$('.active_admin [data-df-dialog]').on( 'click', function( event ) {
|
116
175
|
event.preventDefault();
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
176
|
+
$(this).blur();
|
177
|
+
if( $('#df-dialog').data( 'loading' ) != '1' ) {
|
178
|
+
$('#df-dialog').data( 'loading', '1' );
|
179
|
+
if( $('#df-dialog').length == 0 ) $('body').append( '<div id="df-dialog"></div>' );
|
180
|
+
var title = $(this).attr( 'title' );
|
181
|
+
$.ajax({
|
182
|
+
url: $(this).attr( 'href' ),
|
183
|
+
complete: function( req, status ) {
|
184
|
+
$('#df-dialog').data( 'loading', '0' );
|
185
|
+
},
|
186
|
+
success: function( data, status, req ) {
|
187
|
+
if( title ) $('#df-dialog').attr( 'title', title );
|
188
|
+
$('#df-dialog').html( data );
|
189
|
+
$('#df-dialog').dialog({ modal: true });
|
190
|
+
},
|
191
|
+
});
|
192
|
+
}
|
193
|
+
});
|
194
|
+
// Inline editing
|
195
|
+
$('[data-field][data-field-type="boolean"][data-save-url]').each( function() {
|
196
|
+
$(this).on( 'click', $.proxy( dfUpdateField, $(this) ) );
|
197
|
+
});
|
198
|
+
$('[data-field][data-field-type="string"][data-save-url]' ).each( function() {
|
199
|
+
$(this).data( 'field-value', $(this).text() );
|
200
|
+
var fnUpdate = $.proxy( dfUpdateField, $(this) );
|
201
|
+
$(this).on( 'blur', function() {
|
202
|
+
if( $(this).data( 'field-value' ) != $(this).text() ) fnUpdate();
|
125
203
|
});
|
126
204
|
});
|
127
|
-
$('
|
128
|
-
$(this).
|
205
|
+
$('[data-field][data-field-type="select"][data-save-url]').each( function() {
|
206
|
+
$(this).on( 'change', $.proxy( dfUpdateField, $(this) ) );
|
129
207
|
});
|
130
208
|
});
|
@@ -5,5 +5,32 @@ module ActiveAdmin
|
|
5
5
|
class Engine < ::Rails::Engine
|
6
6
|
engine_name 'activeadmin_dynamic_fields'
|
7
7
|
end
|
8
|
+
|
9
|
+
def self.edit_boolean( field, url, value )
|
10
|
+
{ 'data-field': field, 'data-field-type': 'boolean', 'data-field-value': value, 'data-content': "<span class=\"status_tag changed\">#{value ? 'no' : 'yes'}</span>", 'data-save-url': url, 'data-show-errors': '1' }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.edit_select( field, url )
|
14
|
+
{ 'data-field': field, 'data-field-type': 'select', 'data-save-url': url, 'data-show-errors': '1' }
|
15
|
+
# 'data-field': 'author_id', 'data-field-type': 'select', 'data-save-url': save_admin_article_path( row.id ), 'data-show-errors': '1' do
|
16
|
+
# ( [''] + Author.pluck( :name, :id ) ).map{ |opt| option opt[0], value: opt[1], selected: row.author_id == opt[1] }.join
|
17
|
+
# end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.edit_string( field, url )
|
21
|
+
{ contenteditable: true, 'data-field': field, 'data-field-type': 'string', 'data-save-url': url, 'data-show-errors': '1' }
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.update( resource, params, permit_params = nil )
|
25
|
+
if params[:data]
|
26
|
+
if resource.update( permit_params ? params[:data].permit( permit_params ) : params[:data].permit! )
|
27
|
+
{ json: { status: 'ok' } }
|
28
|
+
else
|
29
|
+
{ json: { status: 'error', message: resource.errors } }
|
30
|
+
end
|
31
|
+
else
|
32
|
+
{ json: { status: 'error', message: 'No data' }, status: 400 }
|
33
|
+
end
|
34
|
+
end
|
8
35
|
end
|
9
36
|
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.
|
4
|
+
version: 0.2.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: 2017-09-
|
11
|
+
date: 2017-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activeadmin
|