activeadmin_dynamic_fields 0.1.5 → 0.2.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
  SHA1:
3
- metadata.gz: 42ac2b763d8f98e2e55cf81e3ec76aecf16cec7e
4
- data.tar.gz: 9a7c58695fbb59281f948ce192bfeb0aefe79e2e
3
+ metadata.gz: d599f816a20b2b7068d3b7d72e7ada1002c848bf
4
+ data.tar.gz: 296760d26145ceddb5e535296c1fa8a234e9781d
5
5
  SHA512:
6
- metadata.gz: 613eeec1ba5f472a7309a0b1463bd06ced96044def8845005f6fc3fad7c44cc40efbbece500af140251ab03ad6001b21f1d40b3205b4bb70167ca819156dfbc0
7
- data.tar.gz: f60670bc64107e1c7d57f19f9792c5dd2485d5d910f22ec970c5f572d7d2703e18c626457bbefc1ab03ff530d1c4549d42e3d2230ee89df92ef520a09c106671
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 of dynamic fields
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
- ## Example to open a dialog
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
- if( $('#df-dialog').length == 0 ) $('body').append( '<div id="df-dialog"></div>' );
118
- var title = $(this).attr( 'title' );
119
- $.ajax({
120
- url: $(this).attr( 'href' )
121
- }).done( function( result ) {
122
- if( title ) $('#df-dialog').attr( 'title', title );
123
- $('#df-dialog').html( result );
124
- $('#df-dialog').dialog({ modal: true });
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
- $('.active_admin [data-df-icon]').each( function() {
128
- $(this).append( ' &raquo;' ); // ' &bullet;'
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
@@ -1,5 +1,5 @@
1
1
  module ActiveAdmin
2
2
  module DynamicFields
3
- VERSION = '0.1.5'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  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.1.5
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-23 00:00:00.000000000 Z
11
+ date: 2017-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeadmin