Open rubengc opened 7 years ago
After investigate it, I do not need add any extra check for group fields at widget class
The value is stored correctly, but for some reason is not loaded correctly
is possible that default_cb is not called on repeatable groups because it returns false instead of null?
I try to override how CMB2 is getting group values because is trying to retrieve a wrong options index
I dumped the contents of $args in cmb2_override_meta_value and It has type => post instead of options-page (and metabox has correctly configured show_on argument)
I need to investigate It a bit more
I got some progress about this
I am able to get group field elements values, but for some reason it only return the first element
public function cmb2( $saving = false ) {
// Create a new box in the class
$cmb2 = new CMB2( array(
'id' => $this->option_name .'_box', // Option name is taken from the WP_Widget class.
'hookup' => false,
'show_on' => array(
'key' => 'options-page', // Tells CMB2 to handle this as an option
'value' => array( $this->option_name )
),
), $this->option_name );
foreach ( $this->fields as $field ) {
if ( ! $saving ) {
$field['id'] = $this->get_field_name( $field['id'] );
}
if( $field['type'] == 'group' ) {
// Update group fields default_cb
foreach( $field['fields'] as $group_field_index => $group_field ) {
$group_field['default_cb'] = array( $this, 'default_cb' );
$field['fields'][$group_field_index] = $group_field;
}
}
$field['default_cb'] = array( $this, 'default_cb' );
$cmb2->add_field( $field );
}
return $cmb2;
}
public function default_cb( $field_args, $field ) {
if( $field->group ) {
if( isset( $this->_instance[ $field->group->args( 'id_key' ) ] ) ) {
$data = $this->_instance[ $field->group->args( 'id_key' ) ];
return is_array( $data ) && isset( $data[ $field->group->index ][ $field->args( 'id_key' ) ] )
? $data[ $field->group->index ][ $field->args( 'id_key' ) ]
: null;
} else {
return null;
}
}
return isset( $this->_instance[ $field->args( 'id_key' ) ] )
? $this->_instance[ $field->args( 'id_key' ) ]
: null;
}
Finally I got it working, I need to add a filter to cmb2_override_meta_value
to retrieve correctly group field value
@rubengc would you be willing to submit a PR on the widget snippet so we can see what worked and potentially add that code to the snippet library?
The problem (that i hackily solved) is CMB2 do not call default_cb on group field but default_cb is called in fields inside a group
If CMB2 adds this check to group fields probably my solution will not be needle
👍 This is really an issue in CMB2, then, rather than the snippet library, but I will leave it open here for context.
public function form( $instance ) {
add_filter( 'cmb2_override_meta_value', array( $this, 'cmb2_override_meta_value' ), 11, 4 );
// If there are no settings, set up defaults
$this->_instance = wp_parse_args( (array) $instance, self::$defaults );
$cmb2 = $this->cmb2();
$cmb2->object_id( $this->option_name );
CMB2_hookup::enqueue_cmb_css();
CMB2_hookup::enqueue_cmb_js();
$cmb2->show_form();
remove_filter( 'cmb2_override_meta_value', array( $this, 'cmb2_override_meta_value' ) );
}
public function cmb2_override_meta_value( $value, $object_id, $args, $field ) {
if ( $field->group || 'group' === $field->type() ) {
if ( isset( $field->args['id_key'] ) ) {
$id_key = $field->args['id_key'];
if ( isset( $this->_instance[$id_key] ) ) {
$value = $this->_instance[$id_key];
}
}
}
return $value;
}
public function cmb2( $saving = false ) {
// Create a new box in the class
$cmb2 = new CMB2( array(
'id' => $this->option_name .'_box', // Option name is taken from the WP_Widget class.
'hookup' => false,
'show_on' => array(
'key' => 'options-page', // Tells CMB2 to handle this as an option
'value' => array( $this->option_name )
),
), $this->option_name );
foreach ( $this->fields as $field ) {
if ( ! $saving ) {
$field['id'] = $this->get_field_name( $field['id'] );
}
if( $field['type'] == 'group' ) {
// Update group fields default_cb
foreach( $field['fields'] as $group_field_index => $group_field ) {
$group_field['default_cb'] = array( $this, 'default_cb' );
$field['fields'][$group_field_index] = $group_field;
}
}
$field['default_cb'] = array( $this, 'default_cb' );
$cmb2->add_field( $field );
}
return $cmb2;
}
public function default_cb( $field_args, $field ) {
if( $field->group ) {
if( isset( $this->_instance[ $field->group->args( 'id_key' ) ] ) ) {
$data = $this->_instance[ $field->group->args( 'id_key' ) ];
return is_array( $data ) && isset( $data[ $field->group->index ][ $field->args( 'id_key' ) ] )
? $data[ $field->group->index ][ $field->args( 'id_key' ) ]
: null;
} else {
return null;
}
}
return isset( $this->_instance[ $field->args( 'id_key' ) ] )
? $this->_instance[ $field->args( 'id_key' ) ]
: null;
}
(function( window, document, $ ) {
$( document ).on('widget-updated widget-added', function( event, widget ) {
var $metabox = $(widget).find('.cmb2-wrap > .cmb2-metabox'),
cmb = window.CMB2;
$metabox
.on('click', '.cmb-add-group-row', cmb.addGroupRow)
.on('click', '.cmb-add-row-button', cmb.addAjaxRow)
.on('click', '.cmb-remove-group-row', cmb.removeGroupRow)
.on('click', '.cmb-remove-row-button', cmb.removeAjaxRow)
.on( 'click', '.cmbhandle, .cmbhandle + .cmbhandle-title', cmb.toggleHandle );
});
})( window, document, jQuery );
Note: ColorPicker fields gets destroyed after field save on widgets area a way to fix it:
// Auto Call plugin is class is color-picker
jQuery( document ).ready( function( $ ) {
$( '.color-picker' ).wpColorPicker();
// Initialize on widgets area
$(document).on('widget-updated widget-added', function(e, widget) {
widget.find( '.color-picker, .cmb2-colorpicker' ).wpColorPicker();
});
} );
An explanation on this can be found here
I am trying to make group fields work at widgets area
First I added a new loop to add group fields correctly:
And the js event to make repeatables working:
But I miss something, because i got a duplicated group fields in each group, and also save functionallity is not working
Can someone help me to get it working?
Thanks in advance!