Advanced Custom Fields: Table Field - Version 1.2.5

Version Description

  • Adds danish translation, thanks to Jeppe Skovsgaard
Download this release

Release Info

Developer Jonua
Plugin Icon 128x128 Advanced Custom Fields: Table Field
Version 1.2.5
Comparing to
See all releases

Version 1.2.5

acf-table-v4.php ADDED
@@ -0,0 +1,302 @@
1
+ <?php
2
+
3
+ class acf_table_add_on extends acf_field
4
+ {
5
+ // vars
6
+ var $settings, // will hold info such as dir / path
7
+ $defaults; // will hold default field options
8
+
9
+ /*
10
+ * __construct
11
+ *
12
+ * Set name / label needed for actions / filters
13
+ *
14
+ * @since 3.6
15
+ * @date 23/01/13
16
+ */
17
+
18
+ function __construct()
19
+ {
20
+ // language
21
+ load_textdomain( 'acf-table', dirname(__FILE__) . '/lang/acf-table-' . get_locale() . '.mo' );
22
+
23
+ $this->name = 'table';
24
+ $this->label = __( 'Table','acf-table' );
25
+ $this->category = __( 'Layout', 'acf' ); // Basic, Content, Choice, etc
26
+ $this->defaults = array(
27
+ 'use_header' => 0,
28
+ // add default here to merge into your field.
29
+ // This makes life easy when creating the field options as you don't need to use any if( isset('') ) logic. eg:
30
+ //'preview_size' => 'thumbnail'
31
+ );
32
+
33
+ // do not delete!
34
+ parent::__construct();
35
+
36
+ // settings
37
+ $this->settings = array(
38
+ 'dir_url' => plugins_url( '', __FILE__ ) . '/',
39
+ 'version' => '1.2.5',
40
+ );
41
+
42
+ // PREVENTS SAVING INVALID TABLE FIELD JSON DATA {
43
+
44
+ add_filter( 'update_post_metadata', function( $x, $object_id, $meta_key, $meta_value, $prev_value ) {
45
+
46
+ // detecting ACF table json
47
+ if (
48
+ is_string( $meta_value ) and
49
+ strpos( $meta_value, '"acftf":{' ) !== false
50
+ ) {
51
+
52
+ // is new value a valid json string
53
+ json_decode( $meta_value );
54
+
55
+ if ( json_last_error() !== JSON_ERROR_NONE ) {
56
+
57
+ // canceling meta value uptdate
58
+ error_log( 'The plugin advanced-custom-fields-table-field prevented a third party update_post_meta( ' . $object_id . ', "' . $meta_key . '", $value ); action that would save a broken JSON string.' . "\n" . 'For details see https://codex.wordpress.org/Function_Reference/update_post_meta#Character_Escaping.' );
59
+ return true;
60
+ }
61
+ }
62
+
63
+ }, 10, 5 );
64
+
65
+ // }
66
+
67
+ }
68
+
69
+ /*
70
+ * create_field()
71
+ *
72
+ * Create the HTML interface for your field
73
+ *
74
+ * @param $field - an array holding all the field's data
75
+ *
76
+ * @type action
77
+ * @since 3.6
78
+ * @date 23/01/13
79
+ */
80
+
81
+ function create_field( $field )
82
+ {
83
+
84
+ $data_field['use_header'] = $field['use_header'];
85
+
86
+ $e = '';
87
+
88
+ $e .= '<div class="acf-table-root">';
89
+
90
+ // OPTION HEADER {
91
+
92
+ if ( $data_field['use_header'] === 0 ) {
93
+
94
+ $e .= '<div class="acf-table-optionbox">';
95
+ $e .= '<label>' . __( 'use table header', 'acf-table' ) . ' </label>';
96
+ $e .= '<select class="acf-table-optionbox-field acf-table-fc-opt-use-header" name="acf-table-opt-use-header">';
97
+ $e .= '<option value="0">' . __( 'No', 'acf-table' ) . '</option>';
98
+ $e .= '<option value="1">' . __( 'Yes', 'acf-table' ) . '</option>';
99
+ $e .= '</select>';
100
+ $e .= '</div>';
101
+ }
102
+
103
+ // }
104
+
105
+ $e .= '<div class="acf-input-wrap">';
106
+ $e .= '<input type="hidden" data-field-options="' . urlencode( wp_json_encode( $data_field ) ) . '" id="' . $field['id'] . '" class="' . $field['class'] . '" name="' . $field['name'] . '" value="' . urlencode( $field['value'] ) . '"/>';
107
+ $e .= '</div>';
108
+
109
+ $e .= '</div>';
110
+
111
+ echo $e;
112
+
113
+ }
114
+
115
+ /*
116
+ * input_admin_enqueue_scripts()
117
+ *
118
+ * This action is called in the admin_enqueue_scripts action on the edit screen where your field is created.
119
+ * Use this action to add css + javascript to assist your create_field() action.
120
+ *
121
+ * $info http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts
122
+ * @type action
123
+ * @since 3.6
124
+ * @date 23/01/13
125
+ */
126
+
127
+ function input_admin_enqueue_scripts()
128
+ {
129
+ // Note: This function can be removed if not used
130
+
131
+ // register acf scripts
132
+ wp_register_script('acf-input-table', $this->settings['dir_url'] . 'js/input-v4.js', array('acf-input'), $this->settings['version'] );
133
+ wp_register_style('acf-input-table', $this->settings['dir_url'] . 'css/input.css', array('acf-input'), $this->settings['version'] );
134
+
135
+ // scripts
136
+ wp_enqueue_script(array(
137
+ 'acf-input-table',
138
+ ));
139
+
140
+ // styles
141
+ wp_enqueue_style(array(
142
+ 'acf-input-table',
143
+ ));
144
+ }
145
+
146
+ /*
147
+ * create_options()
148
+ *
149
+ * Create extra options for your field. This is rendered when editing a field.
150
+ * The value of $field['name'] can be used (like bellow) to save extra data to the $field
151
+ *
152
+ * @type action
153
+ * @since 3.6
154
+ * @date 23/01/13
155
+ *
156
+ * @param $field - an array holding all the field's data
157
+ */
158
+
159
+ function create_options($field)
160
+ {
161
+ // defaults?
162
+ /*
163
+ $field = array_merge($this->defaults, $field);
164
+ */
165
+
166
+ // key is needed in the field names to correctly save the data
167
+ $key = $field['name'];
168
+
169
+ // Create Field Options HTML
170
+
171
+ // USER HEADER
172
+
173
+ echo '<tr class="field_option field_option_' . $this->name . '">';
174
+ echo '<td class="label">';
175
+ echo '<label>' . __( "Table Header", 'acf-table' ) . '</label>';
176
+ //echo '<p class="description">' . __( "", 'acf' ) . '</p>';
177
+ echo '</td>';
178
+ echo '<td>';
179
+
180
+ do_action('acf/create_field', array(
181
+ 'type' => 'radio',
182
+ 'name' => 'fields[' . $key . '][use_header]',
183
+ 'value' => $field['use_header'],
184
+ 'choices' => array(
185
+ 0 => __( "Optional", 'acf-table' ),
186
+ 1 => __( "Yes", 'acf-table' ),
187
+ 2 => __( "No", 'acf-table' ),
188
+ ),
189
+ 'layout' => 'horizontal',
190
+ ));
191
+
192
+ echo '</td>';
193
+ echo '</tr>';
194
+
195
+ }
196
+
197
+ /*
198
+ * format_value()
199
+ *
200
+ * This filter is appied to the $value after it is loaded from the db and before it is passed to the create_field action
201
+ *
202
+ * @type filter
203
+ * @since 3.6
204
+ * @date 23/01/13
205
+ *
206
+ * @param $value - the value which was loaded from the database
207
+ * @param $post_id - the $post_id from which the value was loaded
208
+ * @param $field - the field array holding all the field options
209
+ *
210
+ * @return $value - the modified value
211
+ */
212
+
213
+ function format_value_for_api( $value, $post_id, $field )
214
+ {
215
+ $a = json_decode( $value, true );
216
+
217
+ $value = false;
218
+
219
+ // IF BODY DATA
220
+
221
+ if (
222
+ null !== $a['b'] &&
223
+ count( $a['b'] ) > 0
224
+ ) {
225
+
226
+ // IF HEADER DATA
227
+
228
+ if ( $a['p']['o']['uh'] === 1 ) {
229
+
230
+ $value['header'] = $a['h'];
231
+ }
232
+ else {
233
+
234
+ $value['header'] = false;
235
+ }
236
+
237
+ // BODY
238
+
239
+ $value['body'] = $a['b'];
240
+
241
+ // IF SINGLE EMPTY CELL, THEN DO NOT RETURN TABLE DATA
242
+
243
+ if (
244
+ count( $a['b'] ) === 1
245
+ AND count( $a['b'][0] ) === 1
246
+ AND trim( $a['b'][0][0]['c'] ) === ''
247
+ ) {
248
+
249
+ $value = false;
250
+ }
251
+ }
252
+
253
+ return $value;
254
+ }
255
+
256
+ /*
257
+ * update_value()
258
+ *
259
+ * This filter is appied to the $value before it is updated in the db
260
+ *
261
+ * @type filter
262
+ * @since 3.6
263
+ * @date 23/01/13
264
+ *
265
+ * @param $value - the value which will be saved in the database
266
+ * @param $post_id - the $post_id of which the value will be saved
267
+ * @param $field - the field array holding all the field options
268
+ *
269
+ * @return $value - the modified value
270
+ */
271
+
272
+ function update_value($value, $post_id, $field)
273
+ {
274
+ if ( is_string( $value ) ) {
275
+
276
+ $value = urldecode( str_replace( '%5C', '%5C%5C', $value ) );
277
+ }
278
+
279
+ if ( is_array( $value ) ) {
280
+
281
+ $data = get_post_meta( $post_id, $field['name'], true );
282
+ $data = json_decode( $data, true );
283
+
284
+ if ( isset( $value['header'] ) ) {
285
+
286
+ $data['h'] = $value['header'];
287
+ }
288
+
289
+ if ( isset( $value['body'] ) ) {
290
+
291
+ $data['b'] = $value['body'];
292
+ }
293
+
294
+ $value = wp_slash( json_encode( $data ) );
295
+ }
296
+
297
+ return $value;
298
+ }
299
+ }
300
+
301
+ // create field
302
+ new acf_table_add_on();
acf-table-v5.php ADDED
@@ -0,0 +1,599 @@
1
+ <?php
2
+
3
+ class acf_field_table extends acf_field {
4
+
5
+ /*
6
+ * __construct
7
+ *
8
+ * This function will setup the field type data
9
+ *
10
+ * @type function
11
+ * @date 29/12/2014
12
+ * @since 5.0.0
13
+ *
14
+ * @param n/a
15
+ * @return n/a
16
+ */
17
+
18
+ function __construct() {
19
+
20
+ /*
21
+ * settings (array) Array of settings
22
+ */
23
+ $this->settings = array(
24
+ 'version' => '1.2.5',
25
+ 'dir_url' => plugins_url( '', __FILE__ ) . '/',
26
+ );
27
+
28
+ /*
29
+ * name (string) Single word, no spaces. Underscores allowed
30
+ */
31
+
32
+ $this->name = 'table';
33
+
34
+ /*
35
+ * label (string) Multiple words, can include spaces, visible when selecting a field type
36
+ */
37
+
38
+ $this->label = __('Table', 'acf-table');
39
+
40
+ /*
41
+ * category (string) basic | content | choice | relational | jquery | layout | CUSTOM GROUP NAME
42
+ */
43
+
44
+ $this->category = 'layout';
45
+
46
+ /*
47
+ * defaults (array) Array of default settings which are merged into the field object. These are used later in settings
48
+ */
49
+
50
+ $this->defaults = array(
51
+ //'font_size' => 14,
52
+ );
53
+
54
+ /*
55
+ * l10n (array) Array of strings that are used in JavaScript. This allows JS strings to be translated in PHP and loaded via:
56
+ * var message = acf._e('table', 'error');
57
+ */
58
+
59
+ $this->l10n = array(
60
+ 'error' => __('Error! Please enter a higher value', 'acf-table'),
61
+ );
62
+
63
+ // do not delete!
64
+ parent::__construct();
65
+
66
+ // PREVENTS SAVING INVALID TABLE FIELD JSON DATA {
67
+
68
+ add_filter( 'update_post_metadata', function( $x, $object_id, $meta_key, $meta_value, $prev_value ) {
69
+
70
+ // detecting ACF table json
71
+ if (
72
+ is_string( $meta_value ) and
73
+ strpos( $meta_value, '"acftf":{' ) !== false
74
+ ) {
75
+
76
+ // is new value a valid json string
77
+ json_decode( $meta_value );
78
+
79
+ if ( json_last_error() !== JSON_ERROR_NONE ) {
80
+
81
+ // canceling meta value uptdate
82
+ error_log( 'The plugin advanced-custom-fields-table-field prevented a third party update_post_meta( ' . $object_id . ', "' . $meta_key . '", $value ); action that would save a broken JSON string.' . "\n" . 'For details see https://codex.wordpress.org/Function_Reference/update_post_meta#Character_Escaping.' );
83
+ return true;
84
+ }
85
+ }
86
+
87
+ }, 10, 5 );
88
+
89
+ // }
90
+
91
+ }
92
+
93
+ /*
94
+ * render_field_settings()
95
+ *
96
+ * Create extra settings for your field. These are visible when editing a field
97
+ *
98
+ * @type action
99
+ * @since 3.6
100
+ * @date 23/01/13
101
+ *
102
+ * @param $field (array) the $field being edited
103
+ * @return n/a
104
+ */
105
+
106
+ function render_field_settings( $field ) {
107
+
108
+ /*
109
+ * acf_render_field_setting
110
+ *
111
+ * This function will create a setting for your field. Simply pass the $field parameter and an array of field settings.
112
+ * The array of settings does not require a `value` or `prefix`; These settings are found from the $field array.
113
+ *
114
+ * More than one setting can be added by copy/paste the above code.
115
+ * Please note that you must also have a matching $defaults value for the field name (font_size)
116
+ */
117
+
118
+ acf_render_field_setting( $field, array(
119
+ 'label' => __('Table Header','acf-table'),
120
+ 'instructions' => __('Presetting the usage of table header','acf-table'),
121
+ 'type' => 'radio',
122
+ 'name' => 'use_header',
123
+ 'choices' => array(
124
+ 0 => __( "Optional", 'acf-table' ),
125
+ 1 => __( "Yes", 'acf-table' ),
126
+ 2 => __( "No", 'acf-table' ),
127
+ ),
128
+ 'layout' => 'horizontal',
129
+ ));
130
+
131
+ }
132
+
133
+ /*
134
+ * render_field()
135
+ *
136
+ * Create the HTML interface for your field
137
+ *
138
+ * @param $field (array) the $field being rendered
139
+ *
140
+ * @type action
141
+ * @since 3.6
142
+ * @date 23/01/13
143
+ *
144
+ * @param $field (array) the $field being edited
145
+ * @return n/a
146
+ */
147
+
148
+ function render_field( $field ) {
149
+
150
+ /*
151
+ * Review the data of $field.
152
+ * This will show what data is available
153
+ */
154
+
155
+ //echo '<pre>';
156
+ // print_r( $field );
157
+ //echo '</pre>';
158
+
159
+ /*
160
+ * Create a simple text input using the 'font_size' setting.
161
+ */
162
+ /*
163
+ ?>
164
+ <input type="text" name="<?php echo esc_attr($field['name']) ?>" value="<?php echo esc_attr($field['value']) ?>" style="font-size:<?php echo $field['font_size'] ?>px;" />
165
+ <?php
166
+ */
167
+
168
+ $data_field['use_header'] = $field['use_header'];
169
+
170
+ $e = '';
171
+
172
+ $e .= '<div class="acf-table-root">';
173
+
174
+ // OPTION HEADER {
175
+
176
+ if ( $data_field['use_header'] === 0 ) {
177
+
178
+ $e .= '<div class="acf-table-optionbox">';
179
+ $e .= '<label>' . __( 'use table header', 'acf-table' ) . ' </label>';
180
+ $e .= '<select class="acf-table-optionbox-field acf-table-fc-opt-use-header" name="acf-table-opt-use-header">';
181
+ $e .= '<option value="0">' . __( 'No', 'acf-table' ) . '</option>';
182
+ $e .= '<option value="1">' . __( 'Yes', 'acf-table' ) . '</option>';
183
+ $e .= '</select>';
184
+ $e .= '</div>';
185
+ }
186
+
187
+ // }
188
+
189
+ $e .= '<div class="acf-input-wrap">';
190
+ $e .= '<input type="hidden" data-field-options="' . urlencode( wp_json_encode( $data_field ) ) . '" id="' . esc_attr( $field['id'] ) . '" class="' . esc_attr( $field['type'] ) . '" name="' . esc_attr( $field['name'] ) . '" value="' . urlencode( $field['value'] ) . '"/>';
191
+ $e .= '</div>';
192
+
193
+ $e .= '</div>';
194
+
195
+ echo $e;
196
+
197
+ }
198
+
199
+ /*
200
+ * input_admin_enqueue_scripts()
201
+ *
202
+ * This action is called in the admin_enqueue_scripts action on the edit screen where your field is created.
203
+ * Use this action to add CSS + JavaScript to assist your render_field() action.
204
+ *
205
+ * @type action (admin_enqueue_scripts)
206
+ * @since 3.6
207
+ * @date 23/01/13
208
+ *
209
+ * @param n/a
210
+ * @return n/a
211
+ */
212
+
213
+ function input_admin_enqueue_scripts() {
214
+
215
+ // register & include JS
216
+ wp_register_script( 'acf-input-table', $this->settings['dir_url'] . 'js/input-v5.js', array('acf-input'), $this->settings['version'] );
217
+ wp_enqueue_script('acf-input-table');
218
+
219
+ // register & include CSS
220
+ wp_register_style( 'acf-input-table', $this->settings['dir_url'] . 'css/input.css', array('acf-input'), $this->settings['version'] );
221
+ wp_enqueue_style('acf-input-table');
222
+
223
+ }
224
+
225
+ /*
226
+ * input_admin_head()
227
+ *
228
+ * This action is called in the admin_head action on the edit screen where your field is created.
229
+ * Use this action to add CSS and JavaScript to assist your render_field() action.
230
+ *
231
+ * @type action (admin_head)
232
+ * @since 3.6
233
+ * @date 23/01/13
234
+ *
235
+ * @param n/a
236
+ * @return n/a
237
+ */
238
+
239
+ /*
240
+
241
+ function input_admin_head() {
242
+
243
+ }
244
+
245
+ */
246
+
247
+ /*
248
+ * input_form_data()
249
+ *
250
+ * This function is called once on the 'input' page between the head and footer
251
+ * There are 2 situations where ACF did not load during the 'acf/input_admin_enqueue_scripts' and
252
+ * 'acf/input_admin_head' actions because ACF did not know it was going to be used. These situations are
253
+ * seen on comments / user edit forms on the front end. This function will always be called, and includes
254
+ * $args that related to the current screen such as $args['post_id']
255
+ *
256
+ * @type function
257
+ * @date 6/03/2014
258
+ * @since 5.0.0
259
+ *
260
+ * @param $args (array)
261
+ * @return n/a
262
+ */
263
+
264
+ /*
265
+
266
+ function input_form_data( $args ) {
267
+
268
+ }
269
+
270
+ */
271
+
272
+ /*
273
+ * input_admin_footer()
274
+ *
275
+ * This action is called in the admin_footer action on the edit screen where your field is created.
276
+ * Use this action to add CSS and JavaScript to assist your render_field() action.
277
+ *
278
+ * @type action (admin_footer)
279
+ * @since 3.6
280
+ * @date 23/01/13
281
+ *
282
+ * @param n/a
283
+ * @return n/a
284
+ */
285
+
286
+ /*
287
+
288
+ function input_admin_footer() {
289
+
290
+ }
291
+
292
+ */
293
+
294
+ /*
295
+ * field_group_admin_enqueue_scripts()
296
+ *
297
+ * This action is called in the admin_enqueue_scripts action on the edit screen where your field is edited.
298
+ * Use this action to add CSS + JavaScript to assist your render_field_options() action.
299
+ *
300
+ * @type action (admin_enqueue_scripts)
301
+ * @since 3.6
302
+ * @date 23/01/13
303
+ *
304
+ * @param n/a
305
+ * @return n/a
306
+ */
307
+
308
+ /*
309
+
310
+ function field_group_admin_enqueue_scripts() {
311
+
312
+ }
313
+
314
+ */
315
+
316
+ /*
317
+ * field_group_admin_head()
318
+ *
319
+ * This action is called in the admin_head action on the edit screen where your field is edited.
320
+ * Use this action to add CSS and JavaScript to assist your render_field_options() action.
321
+ *
322
+ * @type action (admin_head)
323
+ * @since 3.6
324
+ * @date 23/01/13
325
+ *
326
+ * @param n/a
327
+ * @return n/a
328
+ */
329
+
330
+ /*
331
+
332
+ function field_group_admin_head() {
333
+
334
+ }
335
+
336
+ */
337
+
338
+ /*
339
+ * load_value()
340
+ *
341
+ * This filter is applied to the $value after it is loaded from the db
342
+ *
343
+ * @type filter
344
+ * @since 3.6
345
+ * @date 23/01/13
346
+ *
347
+ * @param $value (mixed) the value found in the database
348
+ * @param $post_id (mixed) the $post_id from which the value was loaded
349
+ * @param $field (array) the field array holding all the field options
350
+ * @return $value
351
+ */
352
+
353
+ /*
354
+
355
+ function load_value( $value, $post_id, $field ) {
356
+
357
+ return $value;
358
+
359
+ }
360
+
361
+ */
362
+
363
+ /*
364
+ * update_value()
365
+ *
366
+ * This filter is applied to the $value before it is saved in the db
367
+ *
368
+ * @type filter
369
+ * @since 3.6
370
+ * @date 23/01/13
371
+ *
372
+ * @param $value (mixed) the value found in the database
373
+ * @param $post_id (mixed) the $post_id from which the value was loaded
374
+ * @param $field (array) the field array holding all the field options
375
+ * @return $value
376
+ */
377
+
378
+ function update_value( $value, $post_id, $field ) {
379
+
380
+ if ( is_string( $value ) ) {
381
+
382
+ $value = urldecode( str_replace( '%5C', '%5C%5C', $value ) );
383
+ }
384
+
385
+ if ( is_array( $value ) ) {
386
+
387
+ $data = get_post_meta( $post_id, $field['name'], true );
388
+ $data = json_decode( $data, true );
389
+
390
+ if ( isset( $value['header'] ) ) {
391
+
392
+ $data['h'] = $value['header'];
393
+ }
394
+
395
+ if ( isset( $value['body'] ) ) {
396
+
397
+ $data['b'] = $value['body'];
398
+ }
399
+
400
+ $value = wp_slash( json_encode( $data ) );
401
+ }
402
+
403
+ return $value;
404
+ }
405
+
406
+ /*
407
+ * format_value()
408
+ *
409
+ * This filter is appied to the $value after it is loaded from the db and before it is returned to the template
410
+ *
411
+ * @type filter
412
+ * @since 3.6
413
+ * @date 23/01/13
414
+ *
415
+ * @param $value (mixed) the value which was loaded from the database
416
+ * @param $post_id (mixed) the $post_id from which the value was loaded
417
+ * @param $field (array) the field array holding all the field options
418
+ *
419
+ * @return $value (mixed) the modified value
420
+ */
421
+
422
+ function format_value( $value, $post_id, $field ) {
423
+
424
+ $a = json_decode( $value, true );
425
+
426
+ $value = false;
427
+
428
+ // IF BODY DATA
429
+
430
+ if (
431
+ null !== $a['b'] &&
432
+ count( $a['b'] ) > 0
433
+ ) {
434
+
435
+ // IF HEADER DATA
436
+
437
+ if ( $a['p']['o']['uh'] === 1 ) {
438
+
439
+ $value['header'] = $a['h'];
440
+ }
441
+ else {
442
+
443
+ $value['header'] = false;
444
+ }
445
+
446
+ // BODY
447
+
448
+ $value['body'] = $a['b'];
449
+
450
+ // IF SINGLE EMPTY CELL, THEN DO NOT RETURN TABLE DATA
451
+
452
+ if (
453
+ count( $a['b'] ) === 1
454
+ AND count( $a['b'][0] ) === 1
455
+ AND trim( $a['b'][0][0]['c'] ) === ''
456
+ ) {
457
+
458
+ $value = false;
459
+ }
460
+ }
461
+
462
+ return $value;
463
+ }
464
+
465
+ /*
466
+ * validate_value()
467
+ *
468
+ * This filter is used to perform validation on the value prior to saving.
469
+ * All values are validated regardless of the field's required setting. This allows you to validate and return
470
+ * messages to the user if the value is not correct
471
+ *
472
+ * @type filter
473
+ * @date 11/02/2014
474
+ * @since 5.0.0
475
+ *
476
+ * @param $valid (boolean) validation status based on the value and the field's required setting
477
+ * @param $value (mixed) the $_POST value
478
+ * @param $field (array) the field array holding all the field options
479
+ * @param $input (string) the corresponding input name for $_POST value
480
+ * @return $valid
481
+ */
482
+
483
+ /*
484
+
485
+ function validate_value( $valid, $value, $field, $input ){
486
+
487
+ // Basic usage
488
+ if( $value < $field['custom_minimum_setting'] )
489
+ {
490
+ $valid = false;
491
+ }
492
+
493
+ // Advanced usage
494
+ if( $value < $field['custom_minimum_setting'] )
495
+ {
496
+ $valid = __('The value is too little!','acf-table'),
497
+ }
498
+
499
+ // return
500
+ return $valid;
501
+
502
+ }
503
+
504
+ */
505
+
506
+ /*
507
+ * delete_value()
508
+ *
509
+ * This action is fired after a value has been deleted from the db.
510
+ * Please note that saving a blank value is treated as an update, not a delete
511
+ *
512
+ * @type action
513
+ * @date 6/03/2014
514
+ * @since 5.0.0
515
+ *
516
+ * @param $post_id (mixed) the $post_id from which the value was deleted
517
+ * @param $key (string) the $meta_key which the value was deleted
518
+ * @return n/a
519
+ */
520
+
521
+ /*
522
+
523
+ function delete_value( $post_id, $key ) {
524
+
525
+ }
526
+
527
+ */
528
+
529
+ /*
530
+ * load_field()
531
+ *
532
+ * This filter is applied to the $field after it is loaded from the database
533
+ *
534
+ * @type filter
535
+ * @date 23/01/2013
536
+ * @since 3.6.0
537
+ *
538
+ * @param $field (array) the field array holding all the field options
539
+ * @return $field
540
+ */
541
+
542
+ /*
543
+
544
+ function load_field( $field ) {
545
+
546
+ return $field;
547
+
548
+ }
549
+
550
+ */
551
+
552
+ /*
553
+ * update_field()
554
+ *
555
+ * This filter is applied to the $field before it is saved to the database
556
+ *
557
+ * @type filter
558
+ * @date 23/01/2013
559
+ * @since 3.6.0
560
+ *
561
+ * @param $field (array) the field array holding all the field options
562
+ * @return $field
563
+ */
564
+
565
+ /*
566
+
567
+ function update_field( $field ) {
568
+
569
+ return $field;
570
+
571
+ }
572
+
573
+ */
574
+
575
+ /*
576
+ * delete_field()
577
+ *
578
+ * This action is fired after a field is deleted from the database
579
+ *
580
+ * @type action
581
+ * @date 11/02/2014
582
+ * @since 5.0.0
583
+ *
584
+ * @param $field (array) the field array holding all the field options
585
+ * @return n/a
586
+ */
587
+
588
+ /*
589
+
590
+ function delete_field( $field ) {
591
+
592
+ }
593
+
594
+ */
595
+
596
+ }
597
+
598
+ // create field
599
+ new acf_field_table();
acf-table.php ADDED
@@ -0,0 +1,40 @@
1
+ <?php
2
+ /*
3
+ Plugin Name: Advanced Custom Fields: Table Field
4
+ Plugin URI: http://www.johannheyne.de/
5
+ Description: This free Add-on adds a table field type for the Advanced Custom Fields plugin
6
+ Version: 1.2.5
7
+ Author: Johann Heyne
8
+ Author URI: http://www.johannheyne.de/
9
+ License: GPLv2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
+ Text Domain: acf-table
12
+ Domain Path: /lang/
13
+ */
14
+
15
+ // 1. set text domain
16
+ // Reference: https://codex.wordpress.org/Function_Reference/load_plugin_textdomain
17
+ function acf_table_load_plugin_textdomain( $version ) {
18
+
19
+ load_plugin_textdomain( 'acf-table', false, dirname( plugin_basename(__FILE__) ) . '/lang/' );
20
+ }
21
+
22
+ add_action('plugins_loaded', 'acf_table_load_plugin_textdomain');
23
+
24
+
25
+ // 2. Include field type for ACF5
26
+ // $version = 5 and can be ignored until ACF6 exists
27
+ function include_field_types_table( $version ) {
28
+
29
+ include_once('acf-table-v5.php');
30
+ }
31
+
32
+ add_action('acf/include_field_types', 'include_field_types_table');
33
+
34
+ // 3. Include field type for ACF4
35
+ function register_fields_table() {
36
+
37
+ include_once('acf-table-v4.php');
38
+ }
39
+
40
+ add_action('acf/register_fields', 'register_fields_table');
css/input.css ADDED
@@ -0,0 +1,322 @@
1
+ .acf-table-wrap {
2
+ padding: 11px 26px 11px 11px;
3
+ }
4
+
5
+ .acf-table-wrap,
6
+ .acf-table-wrap *,
7
+ .acf-table-wrap *:before,
8
+ .acf-table-wrap *:after {
9
+ -moz-box-sizing: border-box;
10
+ -webkit-box-sizing: border-box;
11
+ -ms-box-sizing: border-box;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ /* TABLE { */
16
+
17
+ .acf-table-table {
18
+ display: table;
19
+ border-collapse: collapse;
20
+ width: 100%;
21
+ }
22
+
23
+ .acf-table-body-row {
24
+ width: 100%;
25
+ }
26
+
27
+ .acf-table-table * {
28
+ background-clip: padding-box; /* fix FireFox and IE background color painting over the borders */
29
+ }
30
+
31
+ /* TOP { */
32
+
33
+ .acf-table-top-row {
34
+ position: relative;
35
+ display: table-row;
36
+ }
37
+ .acf-table-top-left {
38
+ position: relative;
39
+ display: table-cell;
40
+ width: 1px;
41
+ padding: 4px 8px 4px 16px;
42
+ min-height: 27px;
43
+ }
44
+ .acf-table-top-cell {
45
+ position: relative;
46
+ display: table-cell;
47
+ padding: 4px 8px;
48
+ border: 1px solid #e1e1e1;
49
+ background-color: #eee;
50
+ cursor: move;
51
+ min-width: 68px;
52
+ }
53
+ .acf-table-top-right {
54
+ position: relative;
55
+ display: table-cell;
56
+ width: 26px;
57
+ }
58
+ .acf-table-top-cont {
59
+ margin: 0;
60
+ padding: 0;
61
+ font-size: inherit;
62
+ line-height: inherit;
63
+ text-align: center;
64
+ color: #aaa;
65
+ }
66
+
67
+ /* TOP } */
68
+
69
+ /* HEADER { */
70
+
71
+ .acf-table-header-row {
72
+ position: relative;
73
+ display: table-row;
74
+ }
75
+ .acf-table-header-left {
76
+ position: relative;
77
+ display: table-cell;
78
+ }
79
+ .acf-table-header-cell {
80
+ position: relative;
81
+ display: table-cell;
82
+ padding: 4px 8px;
83
+ border: 1px solid #e1e1e1;
84
+ background-color: #f9f9f9;
85
+ height: 28px;
86
+ }
87
+ .acf-table-header-right {
88
+ position: relative;
89
+ display: table-cell;
90
+ width: 26px;
91
+ }
92
+ .acf-table-header-cont {
93
+ margin: 0;
94
+ padding: 0;
95
+ font-size: inherit;
96
+ line-height: inherit;
97
+ font-weight: bold;
98
+ }
99
+
100
+ /* HEADER } */
101
+
102
+ /* BODY { */
103
+
104
+ .acf-table-body-row {
105
+ position: relative;
106
+ display: table-row;
107
+ }
108
+ .acf-table-body-left {
109
+ position: relative;
110
+ display: table-cell;
111
+ border: 1px solid #e1e1e1;
112
+ padding: 4px 8px 4px 16px;
113
+ background-color: #eee;
114
+ height: 27px;
115
+ cursor: move;
116
+ text-align: right;
117
+ color: #aaa;
118
+ }
119
+ .acf-table-body-cell {
120
+ position: relative;
121
+ display: table-cell;
122
+ border: 1px solid #e1e1e1;
123
+ padding: 4px 8px;
124
+ background-color: white;
125
+
126
+ }
127
+ .acf-table-body-right {
128
+ position: relative;
129
+ display: table-cell;
130
+ border-bottom: 1px solid transparent;
131
+ }
132
+ .acf-table-body-cont {
133
+ margin: 0;
134
+ padding: 0;
135
+ font-size: inherit;
136
+ line-height: inherit;
137
+
138
+ /* FOLD CELLS { *off/
139
+
140
+ max-height: 18px;
141
+ overflow: hidden;
142
+
143
+ /* FOLD CELLS } */
144
+ }
145
+
146
+ /* BODY } */
147
+
148
+ /* BOTTOM { */
149
+
150
+ .acf-table-bottom-row {
151
+ position: relative;
152
+ display: table-row;
153
+ }
154
+ .acf-table-bottom-left {
155
+ position: relative;
156
+ display: table-cell;
157
+ height: 24px;
158
+ }
159
+ .acf-table-bottom-cell {
160
+ position: relative;
161
+ display: table-cell;
162
+ }
163
+ .acf-table-bottom-right {
164
+ position: relative;
165
+ display: table-cell;
166
+ }
167
+
168
+ /* BOTTOM } */
169
+
170
+ /* HIDES { */
171
+
172
+ /* .acf-table-hide-header { */
173
+
174
+ .acf-table-hide-header .acf-table-header-row,
175
+ .acf-table-hide-header .acf-table-header-row * {
176
+ height: 0 !important;
177
+ font-size: 0 !important;
178
+ line-height: 0 !important;
179
+ padding: 0 !important;
180
+ border: 0 !important;
181
+ display: block;
182
+ }
183
+ .acf-table-hide-header .acf-table-top-row > * {
184
+ border-bottom: none;
185
+ }
186
+
187
+ /* .acf-table-hide-header } */
188
+
189
+ /* .acf-table-hide-left { */
190
+
191
+ .acf-table.acf-table-hide-left > * > *:first-child {
192
+ font-size: 0 !important;
193
+ line-height: 0 !important;
194
+ width: 16px !important;
195
+ padding: 0 !important;
196
+ //border: 0 !important;
197
+ background: none !important;
198
+ border-left: none;
199
+ }
200
+
201
+ /* .acf-table-hide-left } */
202
+
203
+ /* .acf-table-hide-top { */
204
+
205
+ .acf-table.acf-table-hide-top .acf-table-top-left,
206
+ .acf-table.acf-table-hide-top .acf-table-top-cell,
207
+ .acf-table.acf-table-hide-top .acf-table-top-right {
208
+ height: 0 !important;
209
+ font-size: 0 !important;
210
+ line-height: 0 !important;
211
+ height: 16px !important;
212
+ //padding: 0 !important;
213
+ //border: 0 !important;
214
+ background: none !important;
215
+ border-top: none;
216
+ }
217
+
218
+ /* .acf-table-hide-top } */
219
+
220
+ /* HIDE } */
221
+
222
+ /* TABLE } */
223
+
224
+ /* BUTTONS { */
225
+
226
+ .acf-table-add-col {
227
+ box-sizing: content-box;
228
+ position: absolute !important;
229
+ top: -9px;
230
+ right: -10px;
231
+ z-index: 1;
232
+ }
233
+ .acf-table-add-row {
234
+ box-sizing: content-box;
235
+ position: absolute !important;
236
+ bottom: -9px;
237
+ left: -10px;
238
+ z-index: 1;
239
+ }
240
+ .acf-table-remove-col {
241
+ box-sizing: content-box;
242
+ position: absolute !important;
243
+ top: 4px;
244
+ left: 50%;
245
+ margin-left: -10px;
246
+ }
247
+ .acf-table-remove-row {
248
+ box-sizing: content-box;
249
+ position: absolute !important;
250
+ left: 6px;
251
+ top: 3px;
252
+ }
253
+
254
+ /* BUTTONS } */
255
+
256
+ /* CELL EDITOR { */
257
+
258
+ .acf-table-cell-editor {
259
+ position: absolute;
260
+ border: 3px solid #2ea2cc;
261
+ top: -67px;
262
+ left: 0;
263
+ z-index: 2;
264
+ font-size: 0;
265
+ line-height: 0;
266
+ }
267
+ .acf-table-cell-editor:before {
268
+ content: "";
269
+ display: block;
270
+ position: absolute;
271
+ left: 3px;
272
+ bottom: -17px;
273
+ width 0;
274
+ height: 0;
275
+ border: 7px solid transparent;
276
+ border-top: 7px solid #2ea2cc;
277
+ }
278
+ .acf-table-cell-editor:after {
279
+ content: "";
280
+ display: block;
281
+ position: absolute;
282
+ left: 4px;
283
+ bottom: -12px;
284
+ width 0;
285
+ height: 0;
286
+ border: 6px solid transparent;
287
+ border-top: 6px solid #e5f8ff;
288
+ }
289
+ .acf-table-cell-editor-textarea {
290
+ border: none !important;
291
+ padding: 3px 7px !important;
292
+ background-color: #e5f8ff;
293
+ font-size: 13px;
294
+ line-height: 1.4;
295
+ min-width: 180px;
296
+ min-height: 61px !important;
297
+
298
+ /* fix profile.php ACF v4 */
299
+ width: auto !important;
300
+ margin-bottom: 0 !important;
301
+ }
302
+
303
+ /* CELL EDITOR } */
304
+
305
+ /* OPTIONBOX { */
306
+
307
+ .acf-table-optionbox {
308
+ padding-bottom: 8px;
309
+ margin-bottom: 8px;
310
+ }
311
+ .acf-flexible-content .acf-table-optionbox {
312
+ border-bottom: 1px solid #e1e1e1;
313
+ padding-bottom: 10px;
314
+ margin-bottom: 10px;
315
+ }
316
+
317
+ .acf-table-optionbox-field {
318
+ width: auto !important;
319
+ }
320
+
321
+
322
+ /* OPTIONBOX } */
js/input-v4.js ADDED
@@ -0,0 +1,1183 @@
1
+ jQuery.noConflict();
2
+ jQuery( document ).ready(function( $ ){
3
+
4
+ function ACFTableField() {
5
+
6
+ var t = this;
7
+
8
+ t.version = '1.2.5';
9
+
10
+ t.param = {};
11
+
12
+ // DIFFERENT IN ACF VERSION 4 and 5 {
13
+
14
+ t.param.classes = {
15
+
16
+ btn_remove_row: 'acf-button-remove acf-table-remove-row',
17
+ btn_add_row: 'acf-button-add acf-table-add-row',
18
+ btn_add_col: 'acf-button-add acf-table-add-col',
19
+ btn_remove_col: 'acf-button-remove acf-table-remove-col',
20
+ admin_page_profile: 'profile-php',
21
+ admin_page_user_edit: 'user-edit-php',
22
+ };
23
+
24
+ t.param.htmlbuttons = {
25
+
26
+ add_row: '<a href="#" class="' + t.param.classes.btn_add_row + '"></a>',
27
+ remove_row: '<a href="#" class="' + t.param.classes.btn_remove_row + '"></a>',
28
+ add_col: '<a href="#" class="' + t.param.classes.btn_add_col + '"></a>',
29
+ remove_col: '<a href="#" class="' + t.param.classes.btn_remove_col + '"></a>',
30
+ };
31
+
32
+ // }
33
+
34
+ t.param.htmltable = {
35
+
36
+ body_row: '<div class="acf-table-body-row">' +
37
+ '<div class="acf-table-body-left">' +
38
+ t.param.htmlbuttons.add_row +
39
+ '<div class="acf-table-body-cont"><!--ph--></div>' +
40
+ '</div>' +
41
+ '<div class="acf-table-body-right">' +
42
+ t.param.htmlbuttons.remove_row +
43
+ '</div>' +
44
+ '</div>',
45
+
46
+ top_cell: '<div class="acf-table-top-cell" data-colparam="">' +
47
+ t.param.htmlbuttons.add_col +
48
+ '<div class="acf-table-top-cont"><!--ph--></div>' +
49
+ '</div>',
50
+
51
+ header_cell: '<div class="acf-table-header-cell">' +
52
+ '<div class="acf-table-header-cont"><!--ph--></div>' +
53
+ '</div>',
54
+
55
+ body_cell: '<div class="acf-table-body-cell">' +
56
+ '<div class="acf-table-body-cont"><!--ph--></div>' +
57
+ '</div>',
58
+
59
+ bottom_cell: '<div class="acf-table-bottom-cell">' +
60
+ t.param.htmlbuttons.remove_col +
61
+ '</div>',
62
+
63
+ table: '<div class="acf-table-wrap">' +
64
+ '<div class="acf-table-table">' + // acf-table-hide-header acf-table-hide-left acf-table-hide-top
65
+ '<div class="acf-table-top-row">' +
66
+ '<div class="acf-table-top-left">' +
67
+ t.param.htmlbuttons.add_col +
68
+ '</div>' +
69
+ '<div class="acf-table-top-right"></div>' +
70
+ '</div>' +
71
+ '<div class="acf-table-header-row acf-table-header-hide-off">' +
72
+ '<div class="acf-table-header-left">' +
73
+ t.param.htmlbuttons.add_row +
74
+ '</div>' +
75
+ '<div class="acf-table-header-right"></div>' +
76
+ '</div>' +
77
+ '<div class="acf-table-bottom-row">' +
78
+ '<div class="acf-table-bottom-left"></div>' +
79
+ '<div class="acf-table-bottom-right"></div>' +
80
+ '</div>' +
81
+ '</div>' +
82
+
83
+ '</div>',
84
+ };
85
+
86
+ t.param.htmleditor = '<div class="acf-table-cell-editor">' +
87
+ '<textarea name="acf-table-cell-editor-textarea" class="acf-table-cell-editor-textarea"></textarea>' +
88
+ '</div>';
89
+
90
+ t.obj = {
91
+ body: $( 'body' ),
92
+ };
93
+
94
+ t.var = {
95
+ ajax: false,
96
+ };
97
+
98
+ t.state = {
99
+ 'current_cell_obj': false,
100
+ 'cell_editor_cell': false
101
+ };
102
+
103
+ t.init = function() {
104
+
105
+ t.init_workflow();
106
+ };
107
+
108
+ t.init_workflow = function() {
109
+
110
+ t.each_table();
111
+ t.table_add_col_event();
112
+ t.table_remove_col();
113
+ t.table_add_row_event();
114
+ t.table_remove_row();
115
+ t.cell_editor();
116
+ t.cell_editor_tab_navigation();
117
+ t.prevent_cell_links();
118
+ t.sortable_row();
119
+ t.sortable_col();
120
+ t.ui_event_use_header();
121
+ t.ui_event_new_flex_field();
122
+ t.ui_event_change_location_rule();
123
+ t.ui_event_ajax();
124
+ };
125
+
126
+ t.ui_event_ajax = function() {
127
+
128
+ $( document ).ajaxComplete( function( event ) {
129
+
130
+ t.each_table();
131
+ });
132
+ }
133
+
134
+ t.ui_event_change_location_rule = function() {
135
+
136
+ t.obj.body.on( 'change', '[name="post_category[]"], [name="post_format"], [name="page_template"], [name="parent_id"], [name="role"], [name^="tax_input"]', function() {
137
+
138
+ var interval = setInterval( function() {
139
+
140
+ var table_fields = $( '.field_type-table' );
141
+
142
+ if ( table_fields.length > 0 ) {
143
+
144
+ t.each_table();
145
+
146
+ clearInterval( interval );
147
+ }
148
+
149
+ }, 100 );
150
+
151
+ } );
152
+
153
+ };
154
+
155
+ t.each_table = function( ) {
156
+
157
+ $( '.field_type-table .acf-table-root' ).not( '.acf-table-rendered' ).each( function() {
158
+
159
+ var p = {};
160
+ p.obj_root = $( this ),
161
+ table = p.obj_root.find( '.acf-table-wrap' );
162
+
163
+ if ( table.length > 0 ) {
164
+
165
+ return;
166
+ }
167
+
168
+ p.obj_root.addClass( 'acf-table-rendered' );
169
+
170
+ t.data_get( p );
171
+
172
+ t.data_default( p );
173
+
174
+ t.field_options_get( p );
175
+
176
+ t.table_render( p );
177
+
178
+ t.misc_render( p );
179
+
180
+ if ( typeof p.data.b[ 1 ] === 'undefined' && typeof p.data.b[ 0 ][ 1 ] === 'undefined' && p.data.b[ 0 ][ 0 ].c === '' ) {
181
+
182
+ p.obj_root.find( '.acf-table-remove-col' ).hide(),
183
+ p.obj_root.find( '.acf-table-remove-row' ).hide();
184
+ }
185
+
186
+ } );
187
+ };
188
+
189
+ t.field_options_get = function( p ) {
190
+
191
+ try {
192
+
193
+ p.field_options = $.parseJSON( decodeURIComponent( p.obj_root.find( '[data-field-options]' ).data( 'field-options' ) ) );
194
+ }
195
+ catch (e) {
196
+
197
+ p.field_options = {
198
+ use_header: 2
199
+ };
200
+
201
+ console.log( 'The tablefield options value is not a valid JSON string:', decodeURIComponent( p.obj_root.find( '[data-field-options]' ).data( 'field-options' ) ) );
202
+ console.log( 'The parsing error:', e );
203
+ }
204
+
205
+ };
206
+
207
+ t.ui_event_use_header = function() {
208
+
209
+ // HEADER: SELECT FIELD ACTIONS {
210
+
211
+ t.obj.body.on( 'change', '.acf-table-fc-opt-use-header', function() {
212
+
213
+ var that = $( this ),
214
+ p = {};
215
+
216
+ p.obj_root = that.parents( '.acf-table-root' );
217
+ p.obj_table = p.obj_root.find( '.acf-table-table' );
218
+
219
+ t.data_get( p );
220
+
221
+ t.data_default( p );
222
+
223
+ if ( that.val() === '1' ) {
224
+
225
+ p.obj_table.removeClass( 'acf-table-hide-header' );
226
+
227
+ p.data.p.o.uh = 1;
228
+ t.update_table_data_field( p );
229
+ }
230
+ else {
231
+
232
+ p.obj_table.addClass( 'acf-table-hide-header' );
233
+
234
+ p.data.p.o.uh = 0;
235
+ t.update_table_data_field( p );
236
+ }
237
+
238
+ } );
239
+
240
+ // }
241
+ };
242
+
243
+ t.ui_event_new_flex_field = function() {
244
+
245
+ t.obj.body.on( 'click', '.acf-fc-popup', function() {
246
+
247
+ // SORTABLE {
248
+
249
+ $( '.acf-table-table' )
250
+ .sortable('destroy')
251
+ .unbind();
252
+
253
+ window.setTimeout( function() {
254
+
255
+ t.sortable_row();
256
+
257
+ }, 300 );
258
+
259
+ // }
260
+
261
+ } );
262
+ };
263
+
264
+ t.data_get = function( p ) {
265
+
266
+ // DATA FROM FIELD {
267
+
268
+ var val = p.obj_root.find( 'input.table' ).val();
269
+
270
+ p.data = false;
271
+
272
+ if ( val !== '' ) {
273
+
274
+ try {
275
+
276
+ p.data = $.parseJSON( decodeURIComponent( val.replace(/\+/g, '%20') ) );
277
+ }
278
+ catch (e) {
279
+
280
+ p.data = false;
281
+
282
+ console.log( 'The tablefield value is not a valid JSON string:', decodeURIComponent( val.replace(/\+/g, '%20') ) );
283
+ console.log( 'The parsing error:', e );
284
+ }
285
+ }
286
+
287
+ return p.data;
288
+
289
+ // }
290
+
291
+ };
292
+
293
+ t.data_default = function( p ) {
294
+
295
+ // DEFINE DEFAULT DATA {
296
+
297
+ p.data_defaults = {
298
+
299
+ acftf: {
300
+ v: t.version,
301
+ },
302
+
303
+ p: {
304
+ o: {
305
+ uh: 0,
306
+ },
307
+ },
308
+
309
+ // from data-colparam
310
+
311
+ c: [
312
+ {
313
+ c: '',
314
+ },
315
+ ],
316
+
317
+ // header
318
+
319
+ h: [
320
+ {
321
+ c: '',
322
+ },
323
+ ],
324
+
325
+ // body
326
+
327
+ b: [
328
+ [
329
+ {
330
+ c: '',
331
+ },
332
+ ],
333
+ ],
334
+ };
335
+
336
+ // }
337
+
338
+ // MERGE DEFAULT DATA {
339
+
340
+ if ( p.data ) {
341
+
342
+ if ( typeof p.data.b === 'array' ) {
343
+
344
+ $.extend( true, p.data, p.data_defaults );
345
+ }
346
+ }
347
+ else {
348
+
349
+ p.data = p.data_defaults;
350
+ }
351
+
352
+ // }
353
+
354
+ };
355
+
356
+ t.table_render = function( p ) {
357
+
358
+ // TABLE HTML MAIN {
359
+
360
+ p.obj_root.find( '.acf-table-wrap' ).remove();
361
+ p.obj_root.append( t.param.htmltable.table );
362
+
363
+ // }
364
+
365
+ // TABLE GET OBJECTS {
366
+
367
+ p.obj_table = p.obj_root.find( '.acf-table-table' );
368
+ p.obj_top_row = p.obj_root.find( '.acf-table-top-row' ),
369
+ p.obj_top_insert = p.obj_top_row.find( '.acf-table-top-right' ),
370
+ p.obj_header_row = p.obj_root.find( '.acf-table-header-row' ),
371
+ p.obj_header_insert = p.obj_header_row.find( '.acf-table-header-right' ),
372
+ p.obj_bottom_row = p.obj_root.find( '.acf-table-bottom-row' ),
373
+ p.obj_bottom_insert = p.obj_bottom_row.find( '.acf-table-bottom-right' );
374
+
375
+ // }
376
+
377
+ // TOP CELLS {
378
+
379
+ if ( p.data.c ) {
380
+
381
+ for ( i in p.data.c ) {
382
+
383
+ p.obj_top_insert.before( t.param.htmltable.top_cell );
384
+ }
385
+ }
386
+
387
+ t.table_top_labels( p );
388
+
389
+ // }
390
+
391
+ // HEADER CELLS {
392
+
393
+ if ( p.data.h ) {
394
+
395
+ for ( i in p.data.h ) {
396
+
397
+ p.obj_header_insert.before( t.param.htmltable.header_cell.replace( '<!--ph-->', p.data.h[ i ].c.replace( /xxx&quot/g, '"' ) ) );
398
+ }
399
+ }
400
+
401
+ // }
402
+
403
+ // BODY ROWS {
404
+
405
+ if ( p.data.b ) {
406
+
407
+ for ( i in p.data.b ) {
408
+
409
+ p.obj_bottom_row.before( t.param.htmltable.body_row.replace( '<!--ph-->', parseInt(i) + 1 ) );
410
+ }
411
+ }
412
+
413
+ // }
414
+
415
+ // BODY ROWS CELLS {
416
+
417
+ var body_rows = p.obj_root.find( '.acf-table-body-row'),
418
+ row_i = 0;
419
+
420
+ if ( body_rows ) {
421
+
422
+ body_rows.each( function() {
423
+
424
+ var body_row = $( this ),
425
+ row_insert = body_row.find( '.acf-table-body-right' );
426
+
427
+ for( i in p.data.b[ row_i ] ) {
428
+
429
+ row_insert.before( t.param.htmltable.body_cell.replace( '<!--ph-->', p.data.b[ row_i ][ i ].c.replace( /xxx&quot/g, '"' ) ) );
430
+ }
431
+
432
+ row_i = row_i + 1
433
+ } );
434
+ }
435
+
436
+ // }
437
+
438
+ // TABLE BOTTOM {
439
+
440
+ if ( p.data.c ) {
441
+
442
+ for ( i in p.data.c ) {
443
+
444
+ p.obj_bottom_insert.before( t.param.htmltable.bottom_cell );
445
+ }
446
+ }
447
+
448
+ // }
449
+
450
+ };
451
+
452
+ t.misc_render = function( p ) {
453
+
454
+ // VARS {
455
+
456
+ var v = {};
457
+
458
+ v.obj_use_header = p.obj_root.find( '.acf-table-fc-opt-use-header' );
459
+
460
+ // }
461
+
462
+ // HEADER {
463
+
464
+ // HEADER: FIELD OPTIONS, THAT AFFECTS DATA {
465
+
466
+ // HEADER IS NOT ALLOWED
467
+
468
+ if ( p.field_options.use_header === 2 ) {
469
+
470
+ p.obj_table.addClass( 'acf-table-hide-header' );
471
+
472
+ p.data.p.o.uh = 0;
473
+ t.update_table_data_field( p );
474
+ }
475
+
476
+ // HEADER IS REQUIRED
477
+
478
+ if ( p.field_options.use_header === 1 ) {
479
+
480
+ p.data.p.o.uh = 1;
481
+ t.update_table_data_field( p );
482
+ }
483
+
484
+ // }
485
+
486
+ // HEADER: SET CHECKBOX STATUS {
487
+
488
+ if ( p.data.p.o.uh === 1 ) {
489
+
490
+ v.obj_use_header.val( '1' );
491
+ }
492
+
493
+ if ( p.data.p.o.uh === 0 ) {
494
+
495
+ v.obj_use_header.val( '0' );
496
+ }
497
+
498
+ // }
499
+
500
+ // HEADER: SET HEADER VISIBILITY {
501
+
502
+ if ( p.data.p.o.uh === 1 ) {
503
+
504
+ p.obj_table.removeClass( 'acf-table-hide-header' );
505
+
506
+ }
507
+
508
+ if ( p.data.p.o.uh === 0 ) {
509
+
510
+ p.obj_table.addClass( 'acf-table-hide-header' );
511
+ }
512
+
513
+ // }
514
+
515
+ // }
516
+ };
517
+
518
+ t.table_add_col_event = function() {
519
+
520
+ t.obj.body.on( 'click', '.acf-table-add-col', function( e ) {
521
+
522
+ e.preventDefault();
523
+
524
+ var that = $( this ),
525
+ p = {};
526
+
527
+ p.obj_col = that.parent();
528
+
529
+ t.table_add_col( p );
530
+
531
+ } );
532
+ };
533
+
534
+ t.table_add_col = function( p ) {
535
+
536
+ // requires
537
+ // p.obj_col
538
+
539
+ var that_index = p.obj_col.index();
540
+
541
+ p.obj_root = p.obj_col.parents( '.acf-table-root' );
542
+ p.obj_table = p.obj_root.find( '.acf-table-table' );
543
+
544
+ $( p.obj_table.find( '.acf-table-top-row' ).children()[ that_index ] ).after( t.param.htmltable.top_cell.replace( '<!--ph-->', '' ) );
545
+
546
+ $( p.obj_table.find( '.acf-table-header-row' ).children()[ that_index ] ).after( t.param.htmltable.header_cell.replace( '<!--ph-->', '' ) );
547
+
548
+ p.obj_table.find( '.acf-table-body-row' ).each( function() {
549
+