Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update widget snippet with working group fields #66

Open
rubengc opened this issue May 12, 2017 · 10 comments
Open

Update widget snippet with working group fields #66

rubengc opened this issue May 12, 2017 · 10 comments

Comments

@rubengc
Copy link

rubengc commented May 12, 2017

I am trying to make group fields work at widgets area

First I added a new loop to add group fields correctly:

        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'] );
                }

                $field['default_cb'] = array( $this, 'default_cb' );

                $field_id = $cmb2->add_field( $field );

                // Support for group fields
                if( $field['type'] == 'group' ) {
                    foreach( $field['fields'] as $group_field ) {
                        $cmb2->add_group_field( $field_id, $group_field );
                    }
                }
            }

            return $cmb2;
        }

And the js event to make repeatables working:

(function( window, document, $, cmb ) {
    $( document ).on('widget-updated widget-added', function( event, widget ) {
        var $metabox = $(widget).find('.cmb2-wrap > .cmb2-metabox');
        
        $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);
    });
})( window, document, jQuery, window.CMB2 );

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!

@rubengc
Copy link
Author

rubengc commented May 12, 2017

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

@rubengc
Copy link
Author

rubengc commented May 12, 2017

is possible that default_cb is not called on repeatable groups because it returns false instead of null?

@rubengc
Copy link
Author

rubengc commented May 12, 2017

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

@rubengc
Copy link
Author

rubengc commented May 15, 2017

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;
        }

@rubengc
Copy link
Author

rubengc commented May 15, 2017

Finally I got it working, I need to add a filter to cmb2_override_meta_value to retrieve correctly group field value

@jazzsequence
Copy link
Collaborator

@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?

@rubengc
Copy link
Author

rubengc commented May 16, 2017

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

@jazzsequence
Copy link
Collaborator

jazzsequence commented May 16, 2017

👍
This is really an issue in CMB2, then, rather than the snippet library, but I will leave it open here for context.

@av-nexter
Copy link

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 );

@rubengc
Copy link
Author

rubengc commented Aug 1, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants