Support

Account

Home Forums Backend Issues (wp-admin) Custom fields on woocommerce product variations

Solved

Custom fields on woocommerce product variations

  • I am using ACF on my sites and it is a great plugin but I ran into an issue. While creating a new product in woocommerce there is an option to set up the product variations. I want to add some custom fields to the variations box, which will be different for each variation and then show them on the front-end. I have attached an image which will give a better idea of what i am trying to say. I want to add some fields on that box. Is it possible to achieve?

    I can add custom meta boxes below the product data box but that will result in being constant for individual variations and different for products. I want the fields to be different for individual variations. Thanks in advance for any help!

    Regards

  • Hi @scorcher

    This is unfortunately out of scope for the ACF plugin. You will need to read up on the woo-commerce documentation to learn if and how you can extend the custom fields for a variation.

    Thanks
    E

  • Uh, alright. By the way thank you for taking out the time for developing and maintaining such an awesome plugin.

    Thanks again

  • Any News here?
    I have the same Problem and cant find a solution, i just need the custom fields in the backend.
    If i set a new group with the rule show an Product-Type = Variation i dont get the field.

  • I was able to add ACF fields to woocommerce product variations using only a couple of actions and a filter.

    // Render fields at the bottom of variations - does not account for field group order or placement.
    add_action( 'woocommerce_product_after_variable_attributes', function( $loop, $variation_data, $variation ) {
        global $abcdefgh_i; // Custom global variable to monitor index
        $abcdefgh_i = $loop;
        // Add filter to update field name
        add_filter( 'acf/prepare_field', 'acf_prepare_field_update_field_name' );
        
        // Loop through all field groups
        $acf_field_groups = acf_get_field_groups();
        foreach( $acf_field_groups as $acf_field_group ) {
            foreach( $acf_field_group['location'] as $group_locations ) {
                foreach( $group_locations as $rule ) {
                    // See if field Group has at least one post_type = Variations rule - does not validate other rules
                    if( $rule['param'] == 'post_type' && $rule['operator'] == '==' && $rule['value'] == 'product_variation' ) {
                        // Render field Group
                        acf_render_fields( $variation->ID, acf_get_fields( $acf_field_group ) );
                        break 2;
                    }
                }
            }
        }
        
        // Remove filter
        remove_filter( 'acf/prepare_field', 'acf_prepare_field_update_field_name' );
    }, 10, 3 );
    
    // Filter function to update field names
    function  acf_prepare_field_update_field_name( $field ) {
        global $abcdefgh_i;
        $field['name'] = preg_replace( '/^acf\[/', "acf[$abcdefgh_i][", $field['name'] );
        return $field;
    }
        
    // Save variation data
    add_action( 'woocommerce_save_product_variation', function( $variation_id, $i = -1 ) {
        // Update all fields for the current variation
        if ( ! empty( $_POST['acf'] ) && is_array( $_POST['acf'] ) && array_key_exists( $i, $_POST['acf'] ) && is_array( ( $fields = $_POST['acf'][ $i ] ) ) ) {
            foreach ( $fields as $key => $val ) {
                update_field( $key, $val, $variation_id );
            }
        }
    }, 10, 2 );

    Adding this code as is to your theme’s functions.php file should enable this functionality for all product variation field groups. The only drawback is that it doesn’t check for more complex rules, and the order and position of field groups are not taken into consideration.

  • @shaun Thanks for sharing your code. This helped a lot – but I am facing the issue with a repeater field. I believe this is not supported with your solution. Do you have a solution for repeater fields as well?

    I know that the value of repeater fields are stored like this pattern in the postmeta database:

    repeaterfieldname_0_fieldname

    Now, when I save my repeater field I get this form in the $_POST[‘acf’] variable. I believe I can not make a connecttion to this structure (repeaterfieldname_0_fieldname), can I? My repeater field is named “product_options”, and the fields are named “component”, “text”, “price”.

    array(2) {
    	 ["field_5aa23edb20eb5"]=> array(2) {
    	  ["5aa24c5eafcd0"]=> array(3) {
    	  	 ["field_5aa23f0020eb6"]=> string(3) "abc"
    	  	 ["field_5aa23f0920eb7"]=> string(4) "abc2"
    	  	 ["field_5aa23f1420eb8"]=> string(2) "12"
    	  } 
    	  ["acfcloneindex"]=> array(3) {
    	  	["field_5aa23f0020eb6"]=> string(0) ""
    	  	["field_5aa23f0920eb7"]=> string(0) ""
    	  	["field_5aa23f1420eb8"]=> string(0) ""
    	  }
    	}
    }

    So basically field_5aa23f0020eb6 is “component” etc. Maybe @elliot has an idea?

    Edit:

    It does work like this, but maybe there is another, more convenient, solution?

    
    foreach ( $fields as $key => $val ) {
    	if (is_array($val)) {
    		foreach ($val as $k => $v) {
    			foreach ($v as $fKey => $fValue) {
    				if ($fKey !== 'acfcloneindex') {
    					$i = add_row($k, $fValue, $variation_id);		
    				}       				
    			}							
    		}
    	} else {
    		update_field( $key, $val, $variation_id );
    	}				
    }
    
  • WooCommerce Product Variations are *all* saved via a single POST request.

    To differentiate between product variation fields, WooCommerce names each field field_name[variation_id] so that it is accessible as $_POST['field_name'][$variation_id].

    ACF field data is located in $_POST['acf'][...] and can only have one of each field.

    ACF’s acf()->input->save_post( $post_id ) method uses $_POST['acf'] data, so it cannot contain fields for another variation.

    We need to allow duplicate ACF fields to exist within a single <form> without having them overwrite each other’s value within $_POST['acf'].

    We can achieve this by renaming the field name prefix acf[...] to acf_varation[variation_id][...] and then set $_POST['acf'] to $_POST['acf_varation'][$variation_id] when saving.

    
    $GLOBALS['wc_loop_variation_id'] = null;
    
    function is_field_group_for_variation($field_group, $variation_data, $variation_post) {
    	return (preg_match( '/Variation/i', $field_group['title'] ) == true);
    }
    
    add_action( 'woocommerce_product_after_variable_attributes', function( $loop_index, $variation_data, $variation_post ) {
    		$GLOBALS['wc_loop_variation_id'] = $variation_post->ID;
    
    		foreach ( acf_get_field_groups() as $field_group ) {
    			if ( is_field_group_for_variation( $field_group, $variation_data, $variation_post ) ) {
    				acf_render_fields( $variation_post->ID, acf_get_fields( $field_group ) );
    			}
    		}
    
    		$GLOBALS['wc_loop_variation_id'] = null;
    	}, 10, 3 );
    
    add_action( 'woocommerce_save_product_variation', function( $variation_id, $loop_index ) {
    		if ( !isset( $_POST['acf_variation'][$variation_id] ) ) {
    			return;
    		}
    
    		$_POST['acf'] = $_POST['acf_variation'][$variation_id];
    
    		acf()->input->save_post( $variation_id );
    	}, 10, 2 );
    
    add_filter( 'acf/prepare_field', function ( $field ) {
    		if ( !$GLOBALS['wc_loop_variation_id'] ) {
    			return $field;
    		}
    
    		$field['name'] = preg_replace( '/^acf\[/', 'acf_variation[' . $GLOBALS['wc_loop_variation_id'] . '][', $field['name'] );
    
    		return $field;
    	}, 10, 1);
    
  • When I use these filter scripts, they allow the repeater fields to display in the variations, but I am having a problem getting them to save. Is there something I am doing wrong? I copied Shaun’s and rchipka’s scripts.

  • I don’t see “Product Variations” as a post type, in ACF rules.
    Using latest ACF and latest WC.
    Am I missing something??
    @elliot ?

  • Hello @J_M you need to add this to your functions.php to be able to see the option on the dropdown.

    //add ACF rule
    add_filter('acf/location/rule_values/post_type', 'acf_location_rule_values_Post');
    function acf_location_rule_values_Post( $choices ) {
    	$choices['product_variation'] = 'Product Variation';
        //print_r($choices);
        return $choices;
    }
  • @dynostudios I am having this exact same issue. Did you ever resolve it?

    Thanks
    John

  • @shaun I can add my fields and save them but I cant see them on the front of my website? Are they displayed in the same way as a normal ACF field?

  • Greate work,

    I have to add this after render field to get work with relation field:

    
    <script>
    (function($) {
    	acf.do_action('append', $('#post'));
    })(jQuery);
    </script>
  • Thank you! This solution worked great to get my acf custom fields into a product variation, with one exception – one of my fields is a datepicker field. The datepicker script won’t trigger on the field in the product variation, and manually entering a date doesn’t save the data. What am I missing? Thanks.

  • John, and those struggling to piece together the different parts of this solution together, Here is how to display it on the ‘single-product.php’ page.

    Add the following, or similar, function to ‘functions.php’.

    /*----------------------------------------------*/
    /* Displays ACF fields 'Frame Type' and 'Lens Type' 
    /* Displays on SINGLE PRODUCT page and QUICK VIEW via archive
    /* DEPENDENCIES: ACF Custom Fields
    /* $variations are outputted by "variation.php"
    /*----------------------------------------------*/
    function frame_style_lens_colour ( $variations ) {
    	$variations['frame_type'] = get_field('frame_type', $variations[ 'variation_id' ]);
    	$variations['lens_type'] = get_field('lens_type', $variations[ 'variation_id' ]);
    	
    	return $variations;
    }
    add_filter ( 'woocommerce_available_variation', 'frame_style_lens_colour ', 10, 1 );

    THEN copy ‘variation.php’ to your theme or child theme.
    Add the following to the file, or similar, and save it:

    <p><strong>Lens Style:</strong> {{{ data.variation.lens_type }}} Polarized Lens </p>
    <p><strong>Frame Style:</strong> {{{ data.variation.frame_type }}} </p>

    Now your variation specific ACF fields will appear on the front end of the website.

  • hi, first of all, thank you so much for all this great info.

    I have the fields loading in the backend, but when I insert your code into my functions.php file I get a notice on the frontend saying the product is out of stock. I tried changing the get_field values to match my custom fields but to no avail.

    Any help would be greatly appreciated.

    My fields are:
    Planter Name (planter_name)
    Planter Full Story (planter_full_story)
    Planter Image (planter_image)

  • Hey people, thanks for all this great work… It’s almost working for me too.
    I try to add an extra product-attribute value (color range) to each variation (fabric in several colors) to filter them by colour-groups vi the “Product filters”-plugin.

    The code described by Shaun + allows to display and select the attribute checkboxes in each variation. When I click “save changes” it keeps them at first, but if I update the product-page I lose the values.

    Seems the script by rchipka from March 17, 2018 doesn’t save the single values properly in my case. I also added it in the functions.php of my child-theme. Is this correct? Can anyone please help finding how to save the values properly? Thanks!

  • Hello! I am very interested in this…

    I tried it but it didn’t work. What steps must be taken to make it work?

    I have inserted in the function

    //add ACF rule
    add_filter('acf/location/rule_values/post_type', 'acf_location_rule_values_Post');
    function acf_location_rule_values_Post( $choices ) {
        $choices['product_variation'] = 'Product Variation';
        //print_r($choices);
        return $choices;
    }

    With that I can add fields from ACF but then in the product variation I don’t see them to be able to fill in. And then it’s the display of them in the frontend.

    Can you help me?

    Thank you.

  • And the other question is…. Can I show them in any section of the web? The idea is to show this content at the end of the page and not within the default price.

Viewing 20 posts - 1 through 20 (of 20 total)

The topic ‘Custom fields on woocommerce product variations’ is closed to new replies.