Repeatable: fields with default values on save get extra default value saved (options page)
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,
) );
}
Seems broken because of 420cca9f4cecb00c51dfb2a279745b004da18360 Works on posts/pages inside groups. Doesn't work on separate options pages.
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).
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 );
});
}
});