Home Forums General Issues Add Choices to Select Menu Reply To: Add Choices to Select Menu

  • Although this is from 2017, thanks John for the idea!

    It might be helpful to others, that the existence of a custom option for the checkbox field is accessible from the field variable.

    In class-acf-field-checkbox.php within function update_value() you will find

    // save_other_choice
    if( $field['save_custom'] ) {

    Since the select field does not have an option for custom values, you have to check for the text field ‘other, as described by John.

    I had trouble accessing the value of this field when working with the acf/update_value filter, since I can only check for either the select field or the custom text field. get_field() will pull the field value from database, the value that was just posted is within the array and I was not sure how to control wich field will be processed first.

    acf/save_post is the filter that allows access to all posted values.

    However, the $_POST variable delivers just the field keys (like field_1e6543821dge2) and their posted values. So I have to know wich field is the select field and wich is the custom text field. At this point, it would be extremely helpful to have the $field[‘save_custom’] value set, like it is for the checkboxes.

    My workaround, which unfortunately needs to check for the exact field keys is as follows. Biggest diadvantage is that whenever I change the fields in WordPress backend, I need to change the code. If someone had an idea how to make this approach more generic, help would be appreciated. I put the code inside a plugin, so setting up an option page would be reasonable to assign custom fields to select fields.

    However, I hope that we will see the select fields featuering custom values, soon!

    Please note that the following code is used within a WooCommerce site, so please check your post_type!

    function my_custom_select_field( $post_id ) {
        $new_custom_values = array();
        $repeater_key   = 'field_1e6543821dge2'; // in my case, select field is inside a repeater field
        $select_key     = 'field_1e72471e52424';
        $custom_key     = 'field_1e82477957985';
        // not a product, not our business
        if( 'product' != get_post_type( $post_id ) ) return;
        // not generic yet... check for specific field or leave 
        if ( !( $_POST['acf'][$repeater_key] && is_array($_POST['acf'][$repeater_key]) ) ) return;
        // STEP 1:
        // if cusotm values are submitted, just move them to our select field
        $repeater_field = $_POST['acf'][$repeater_key];
        // check if we have a custom value
        foreach ( $repeater_field as $row => $repeaters) {
            if ( ( ( $repeaters[$select_key] === 'custom' ) ) && ( !empty( $repeaters[$custom_key] ) ) ) {
                // assign custom value to our actual select field
                $repeater_field[$row][$select_key] = $repeaters[$custom_key];
                // gather new custom values to update select field
                $new_custom_values[] = $repeaters[$custom_key];
                // clear the custom field, no need to keep it
                $repeater_field[$row][$custom_key] = '';
        // save modified values to actual POST, please note that no return value is neccessary since this
        // filters the $_POST wich will be processed afterwards
        $_POST['acf'][$repeater_key] = $repeater_field;
        // STEP 2:
        // lets go update the select field to have our new custom options available
        // if there are no custom values, leave it
        if ( empty($new_custom_values ) ) return;
        // otherwise, we need our raw select field from db
        $field = acf_get_field( $select_key, true );
        // bail early if no ID (JSON only)
        if( !$field['ID'] ) return;
        // loop through custom values
        foreach ( $new_custom_values as $v ) {
            // ignore if already eixsts
            if( isset($field['choices'][ $v ]) ) continue;
            // unslash (fixes serialize single quote issue)
            $v = wp_unslash($v);
            // sanitize (remove tags)
            $v = sanitize_text_field($v);
            // append
            $field['choices'][ $v ] = $v;
        // save
        acf_update_field( $field );
    add_filter('acf/save_post', 'my_custom_select_field', 5, 1); // priority < 10 = filter before db update