CMB2 icon indicating copy to clipboard operation
CMB2 copied to clipboard

Repeatable: fields with default values on save get extra default value saved (options page)

Open slaFFik opened this issue 7 years ago • 3 comments

Expected Behavior:

On save, there should be no extra "default" value added to user selection inside the repeatable field (which has a default value).

Actual Behavior:

That's a tricky one to explain. We have a repeatable text field. When it's rendered - we have a hidden row with default text that is cloned when a user clicks a Add Row button. On save that default hidden via CSS value is saved and displayed on front-end. So user saw 1 text field by default, clicked Add row - saw the 2nd one, edited values in both. He has now 2 visible repeatable text fields. On save - the user sees 3 repeatable text fields, with 3rd one holding the default field value.

Steps to reproduce (I have confirmed I can reproduce this issue on the develop branch):

See code below

CMB2 Field Registration Code:

add_action( 'cmb2_admin_init', 'yourprefix_register_theme_options_metabox' );
function yourprefix_register_theme_options_metabox() {

	/**
	 * Registers options page menu item and form.
	 */
	$cmb = new_cmb2_box( array(
		'id'           => 'yourprefix_theme_options_page',
		'title'        => esc_html__( 'Theme Options', 'cmb2' ),
		'object_types' => array( 'options-page' ),
		'option_key'      => 'yourprefix_theme_options', // The option key and admin menu page slug.
		'icon_url'        => 'dashicons-palmtree', // Menu icon. Only applicable if 'parent_slug' is left empty.
	) );

	$cmb->add_field( array(
		                 'name'       => 'Test Text',
		                 'desc'       => 'field description (optional)',
		                 'default'    => 'text',
		                 'id'         => 'wiki_test_text',
		                 'type'       => 'text',
		                 'repeatable' => true,
	                 ) );
}

slaFFik avatar Jan 14 '19 21:01 slaFFik

Seems broken because of 420cca9f4cecb00c51dfb2a279745b004da18360 Works on posts/pages inside groups. Doesn't work on separate options pages.

slaFFik avatar Jan 14 '19 21:01 slaFFik

I'm currently struggling with this issue.

It seems to be because the field ready to be added in the repeatable set is simply set to display: none. But the value of fields hidden like this are submitted to the server - so each time the form is submitted, the first option in a repeatable select is added onto the array.

I'm trying to patch this (override the saved options) with the cmb2_override_option_save_ filter, but it's tricky to tell if the final value in the submitted array is redundant or not.

I imagine the fix is to not only set the ready-to-be-added field row to display: none, but for its input / select to be set to disabled too (and enabled when it's shown).

gyrus avatar Apr 29 '20 09:04 gyrus

This is my current jQuery hack, which seems to work for admin options pages:

$( 'body' ).on( 'submit', 'form.cmb-form', function() {

	// Init
	var el = $( this );

	// Options page?
	if ( el.parent().hasClass( 'cmb2-options-page' ) ) {

		// Find hidden rows in repeatable groups
		el.find( '.cmb-row.hidden' ).each( function() {

			// Disable selects
			$( this ).find( 'select' ).prop( 'disabled', true );

		});

	}

});

gyrus avatar Apr 29 '20 10:04 gyrus