Support

Account

Home Forums General Issues Add Choices to Select Menu

Solving

Add Choices to Select Menu

  • I have a form that collects a users name, email and company. I setup a Field Group and added a Select Field to that group. I then added choices for the select menu (e.g. nameone : Name One, nametwo : Name Two etc.). Next I set the Location rules to “show this field group if”, “User Form is equal to Add/Edit”. All good so far. Within the form on the front-end a user fills out their name, email and then chooses a company name from a select menu populated by getting

    $companies = get_field_object('field_5901048ea19ff')

    and doing a foreach loop over

    $companies['choices']

    When the form is submitted I create a user and assign the company to the user by using

    update_field('company', $company, 'user_' . $user_id)"

    What I would love to do, is if a user doesn’t see their company in the select menu they can fill out an “other” text field with their company name. When processing the form I would love to be able to add this new company name to the default Choices for Company (e.g. namethree : Name Three) in the field Group so that the next person from that company to fill out the form can just choose their company name from the select menu. I’ve tried using:

    update_field('field_5901048ea19ff', array("namethree"))

    but that only seems to be applicable for posts/users/cpt with an ID. I would like to update the default values themselves for that field/field group. Something like set_field_object(). Is this possible?

  • This functionality has recently been added to the checkbox field, it was originally only part of the radio field. I imagine that eventually it will find it’s way into the select field as well.

    In the mean time, a work-a-round

    Create your select field that has a choice of “Other”
    Create a text field with conditional logic to show if “Other” is selected for the choice.

    That’s the easy bit.

    For the saving of the new value as a choice I would recommend looking at the code that does this for the checkbox field

    
    // FROM advanced-custom-fields-pro/fields/checkbox.php LINE 368 
    
    // save_other_choice
    if( $field['save_custom'] ) {
      
      // get raw $field (may have been changed via repeater field)
      // if field is local, it won't have an ID
      $selector = $field['ID'] ? $field['ID'] : $field['key'];
      $field = acf_get_field( $selector, true );
      
      
      // bail early if no ID (JSON only)
      if( !$field['ID'] ) return $value;
      
      
      // loop
      foreach( $value as $v ) {
        
        // ignore if already eixsts
        if( isset($field['choices'][ $v ]) ) continue;
        
        
        // unslash (fixes serialize single quote issue)
        $v = wp_unslash($v);
        
        
        // append
        $field['choices'][ $v ] = $v;
        
      }
      
      
      // save
      acf_update_field( $field );
      
    }    
    

    basically, you need to get the current field, update the choices with your addition and then call acf_update_field().

  • 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 acessible 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 are cusotm values 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
    
  • 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
    
Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.