Search code examples
phpjquerywoocommercemetadataproduct-variations

Hide empty variation cutom fields displayed in WooCommerce


I'm using Add variation setting fields to specific variable products in Woocommerce answer code, to show variation custom fields in WooCommerce, and It's working fine.

Now I would like to hide displayed variation custom fields data when empty. I tried to add this jQuery code:

/* Hide empty custom fields for all variations */
function variation_custom_field_js() {
    
    foreach(  custom_fields_settings_all() as $field_key => $values ) {
            ?>
            <script>
            jQuery(function($){
                
                var CustomField = "<?php Print($field_key); ?>";
                //console.log(CustomField);

                $('.shop_attributes .<?php Print($field_key); ?>_class').hide();
    
                $('form.cart').on('show_variation', function(event, data) {

                    if ( data.<?php Print($field_key); ?> == '0' ) {

                        $('.shop_attributes .<?php Print($field_key); ?>_class').hide();
                    } else {

                        $('.shop_attributes .<?php Print($field_key); ?>_class').show();
                    }
                }).on('hide_variation', function(){

                    $('.shop_attributes .<?php Print($field_key); ?>_class').hide();
                });
            });
            </script>
            <?php
    }
}
add_action( 'woocommerce_after_variations_form', 'variation_custom_field_js' );

I can see the script on the frontend, but it doesn't work.


Solution

  • As you don't provide the code that display the custom fields values on selected variations, is not possible to test anything…

    Try the following replacement code (not really tested):

    /* Hide empty custom fields for all variations */
    add_action( 'woocommerce_after_variations_form', 'variation_custom_field_js' );
    function variation_custom_field_js() {
        $field_keys = array_keys( custom_fields_settings_all() );
        ?>
        <script>
        jQuery( function($){
            <?php foreach( $field_keys as $field_key ) { ?>
            $('.shop_attributes .<?php echo $field_key; ?>_class').hide();
            <?php } ?>
    
            $('form.cart').on('show_variation', function(event, data) {
                <?php foreach( $field_keys as $field_key ) { ?>
                console.log(data.<?php echo $field_key; ?>); // To be removed (testing)
                if ( data.<?php echo $field_key; ?> !== undefined ) {
                    $('.shop_attributes .<?php echo $field_key; ?>_class').show();
                } else {
                    $('.shop_attributes .<?php echo $field_key; ?>_class').hide();
                }
                <?php } ?>
            }).on('hide_variation', function(){
                <?php foreach( $field_keys as $field_key ) { ?>
                $('.shop_attributes .<?php echo $field_key; ?>_class').hide();
                <?php } ?>
            });
        });
        </script>
        <?php
    }
    

    It should work.


    Here is a complete working example that will display any non-empty custom field, based on the selected variation:

    // Fields settings
    function custom_fields_settings() {
        return array(
            'my_custom_field1' => array(
                'label'       => __('Text field Name 1', 'woocommerce'),
                'placeholder' => __('Text field placeholder 1', 'woocommerce'),
                'description' => __('Text field description 1', 'woocommerce'),
                'display'     => __('Name 1', 'woocommerce'),
            ),
            'my_custom_field2' => array(
                'label'       => __('Text field Name 2', 'woocommerce'),
                'placeholder' => __('Text field placeholder 2', 'woocommerce'),
                'description' => __('Text field description 2', 'woocommerce'),
                'display'     => __('Name 2', 'woocommerce'),
            ),
            'my_custom_field3' => array(
                'label'       => __('Text field Name 3', 'woocommerce'),
                'placeholder' => __('Text field placeholder 3', 'woocommerce'),
                'description' => __('Text field description 3', 'woocommerce'),
                'display'     => __('Name 3', 'woocommerce'),
            ),
        );
    }
    
    
    // Add custom field(s) to product variations from specific variable products
    add_action( 'woocommerce_product_after_variable_attributes', 'add_variation_setting_fields', 10, 3 );
    function add_variation_setting_fields( $loop, $variation_data, $variation ) {
        $targeted_ids = array(); // Targeted variable product Ids
    
        if ( $targeted_ids && ! in_array( $variation->post_parent, $targeted_ids ) ) return;
    
        foreach(  custom_fields_settings() as $field_key => $values ) {
            $args = array(
                'id'            => $field_key.'['.$loop.']',
                'wrapper_class' => 'form-row',
                'desc_tip'      => true,
                'value'         => get_post_meta($variation->ID, $field_key, true)
            );
            woocommerce_wp_text_input( array_merge( $args, $values) );
        }
    }
    
    // Save the custom field from product variations
    add_action('woocommerce_admin_process_variation_object', 'save_variation_setting_fields', 10, 2 );
    function save_variation_setting_fields($variation, $i) {
        foreach(  custom_fields_settings() as $field_key => $values ) {
            if ( isset($_POST[$field_key][$i]) ) {
                $variation->update_meta_data($field_key, sanitize_text_field($_POST[$field_key][$i]));
            }
        }
    }
    
    // Add variations custom fields to the variable product form data
    add_action( 'woocommerce_available_variation', 'add_variations_custom_fields_to_variable_product_form', 10, 3 );
    function add_variations_custom_fields_to_variable_product_form( $data, $product, $variation ) {
        $targeted_ids = array(); // Targeted variable product Ids
    
        if ( $targeted_ids && ! in_array( $product->get_id(), $targeted_ids ) ) return $data;
    
        foreach(  custom_fields_settings() as $field_key => $values ) {
            if ( $value = $variation->get_meta($field_key)) {
                $data[$field_key] = $value;
            }
        }
        return  $data;
    }
    
    // Output dynamically the HTML structure (where the custom fields will be displayed)
    add_action( 'woocommerce_single_variation', 'display_variation_custom_fields' );
    function display_variation_custom_fields() {
        $html = '<div class="woocommerce-variation-cfs">';
        foreach( custom_fields_settings() as $field_key => $values ) {
            $html .= sprintf('<div class="%s" style="%s"><strong>%s:</strong> <span></span></div>',
            $field_key, 'display:none;', $values['display'] );
        }
        echo $html . '</div>';
    }
    
    // Show/hide custom fields, display the values based on the selected custom field
    add_action( 'woocommerce_after_variations_form', 'variation_custom_fields_js' );
    function variation_custom_fields_js() {
        $field_keys = array_keys( custom_fields_settings() );
        ?>
        <script>
        jQuery( function($){
            $('form.cart').on('show_variation', function(event, data) {
                <?php foreach( $field_keys as $field_key ) { ?>
                const <?php echo $field_key; ?> = data.<?php echo $field_key; ?>;
                console.log(<?php echo $field_key; ?>); // To be removed (testing)
                if ( <?php echo $field_key; ?> !== undefined ) {
                    $('.woocommerce-variation-cfs .<?php echo $field_key; ?> span').html(<?php echo $field_key; ?>);
                    $('.woocommerce-variation-cfs .<?php echo $field_key; ?>').show();
                } else {
                    $('.woocommerce-variation-cfs .<?php echo $field_key; ?>').hide();
                    $('.woocommerce-variation-cfs .<?php echo $field_key; ?> span').html('');
                }
                <?php } ?>
            }).on('hide_variation', function(){
                <?php foreach( $field_keys as $field_key ) { ?>
                $('.woocommerce-variation-cfs .<?php echo $field_key; ?>').hide();
                $('.woocommerce-variation-cfs .<?php echo $field_key; ?> span').html('');
                <?php } ?>
            });
        });
        </script>
        <?php
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and work.

    Related: Add variation setting fields to specific variable products in Woocommerce