Currently we're able to make Select fields into Chosen fields via 'chosen' => true, but if we want to allow multiple items to be selected via Chosen's native functionality (Or the less intuitive, basic HTML interface) that isn't currently possible.
I did some hacky regex in the meantime to enable it within my extension, but the data does not save:
add_filter( 'edd_after_setting_output, function( $html, $args ) {
if ( $args['chosen'] === true ) {
if ( $args['section'] == 'my-settings-section' ) {
$html = preg_replace( '/(<select.*?[^>])*/i', '$1multiple="true" ', $html, 1 );
}
}
return $html;
}, 10, 2 );
Screenshot (Before Saving):

I'm now realizing that I could have just as easily made a custom Callback function rather than writing that regex, but the saving issue would have still persisted. edd_get_option( 'my-field-id' ) always returns 1 value in this case.
I've been poking around and I believe it is the sanitization filters that are to blame. However, I can't seem to modify the data properly. Even throwing a die() in there doesn't seem to stop execution:
add_filter( 'edd_settings_sanitize_select', function( $value, $key ) {
die( $value );
}, 10, 2 );
Ideally, having another option for Select fields to set 'multiple' => true to enable this functionality would be best. I'm thinking this could be a pretty big addition for a lot of Extensions.
@d4mation We actually do already support allowing the multiple option.
Example:
echo EDD()->html->select( array( 'chosen' => true, 'multiple' => true ) );
Oh wait, you mean in the select option callback in the settings API, yes?
Yep! I am talking about the Settings API. Looking around there isn't any support for it there, and when I hacked it in there it wouldn't save the data properly. I figure this has to do with edd_settings_sanitize() and/or its filters, but I can't seem to pin it down.
Thanks! We can get support added for that.
I figured this out for a project and made it a Custom Field Type.
Went ahead and added that functionality to the Select Field Type in PR #5683.
There are some flaws in the PR.
First is on default settings, and the other is that it's blanking out all my other EDD Settings. I'll get this fixe dup in an issue branch keeping the commit history in tact.
This is ready for some testing, this is the code I used to register a bunch of select fields for testing:
/**
* Add settings section
*
* @since 1.0
* @param array $sections The existing extensions sections
* @return array The modified extensions settings
*/
function edd_ck_test_add_settings_section( $sections ) {
$sections['ck-testing'] = __( 'Test Settings', 'edd-optimize-checkout' );
return $sections;
}
add_filter( 'edd_settings_sections_extensions', 'edd_ck_test_add_settings_section' );
/**
* Add extension settings
*
* @since 1.0
* @param array $settings The existing plugin settings
* @return array The modified plugin settings
*/
function edd_ck_test_add_settings( $settings ) {
$my_settings = array(
array(
'id' => 'edd_ck_test_settings',
'name' => __( 'Test Settings', 'edd-optimize-checkout' ),
'desc' => __( 'Configure the settings for EDD Optimize Checkout', 'edd-optimize-checkout' ),
'type' => 'header',
),
array(
'id' => 'edd_ck_test_select_multiple',
'name' => __( 'Test Select (Multiple)', 'edd-optimize-checkout' ),
'desc' => __( 'Testing a select with multiples', 'edd-optimize-checkout' ),
'type' => 'select',
'multiple' => true,
'options' => array( 'option-1' => 'Option 1', 'option-2' => 'Option 2', 'option-3' => 'Option 3', 'option-4' => 'Option 4' ),
),
array(
'id' => 'edd_ck_test_select_multiple_chosen',
'name' => __( 'Test Select (Multiple w/ chosen)', 'edd-optimize-checkout' ),
'desc' => __( 'Testing a select with multiples', 'edd-optimize-checkout' ),
'type' => 'select',
'multiple' => true,
'chosen' => true,
'placeholder' => 'Test',
'options' => array( 'option-1' => 'Option 1', 'option-2' => 'Option 2', 'option-3' => 'Option 3', 'option-4' => 'Option 4' ),
),
array(
'id' => 'edd_ck_test_select',
'name' => __( 'Test Select', 'edd-optimize-checkout' ),
'desc' => __( 'Testing a select', 'edd-optimize-checkout' ),
'type' => 'select',
'options' => array( 'option-1' => 'Option 1', 'option-2' => 'Option 2', 'option-3' => 'Option 3', 'option-4' => 'Option 4' ),
),
array(
'id' => 'edd_ck_test_select_chosen',
'name' => __( 'Test Select (w/ chosen)', 'edd-optimize-checkout' ),
'desc' => __( 'Testing a select', 'edd-optimize-checkout' ),
'type' => 'select',
'chosen' => true,
'options' => array( 'option-1' => 'Option 1', 'option-2' => 'Option 2', 'option-3' => 'Option 3', 'option-4' => 'Option 4' ),
),
);
if ( version_compare( EDD_VERSION, 2.5, '>=' ) ) {
$my_settings = array( 'ck-testing' => $my_settings );
}
return array_merge( $settings, $my_settings );
}
add_filter( 'edd_settings_extensions', 'edd_ck_test_add_settings' );
@easydigitaldownloads/core-devs See above.
There is a minor issue with your fix. My (admittedly heavy-handed) code that you removed allowed the User to fully clear out a previously saved value from a Multiple Select. As it is now, if an option is ever selected, that Select can never be emptied again.
I feel that the ability for a Select Field to be "reset" is an important feature. It may not be a horribly common use case, but for example a Select Field may have a "Default" functionality if it is left blank that could not be reverted to if it is incapable of being cleared.
I left a comment on the Commit itself, but I wanted to add more detail here in the Issue.

https://github.com/easydigitaldownloads/easy-digital-downloads/pull/5837/files/4e543170ef155932c3a74093036e4bb7bd0e4af0..72b2595050be5dcfcbe6b0d3b2fd45530a3a0021#diff-0fc4cfad82ef0e4a14720904d33c326c
Yep see what you mean. I'll work something up to fix it.
Ok I think I have this fixed up. It's a little more intense than originally expected, as the saving of settings will now only run sanitization on the current settings section if it's defined.
As a side affect, this REALLY speeds up saving settings, since it's only itterating over the settings that are currently being saved.
Just tested your change and I was able to set a value on a Multi-Select, save the changes, clear out the values and have them be successfully saved as cleared :+1:
Nice bonus with the Settings saving more quickly too!
This is working great for me!