skip to Main Content

I need help adding custom image fields to my Product Variations, same as the default field but with a different name and value or custom meta so I can differentiate default and custom image.


I tried with this plugin

Additional Variation Images Gallery for WooCommerce

but it’s ruined my frontend functionality. I just want this on my backend (see attached image)

enter image description here


I also tried

or some custom code changes as per my knowledge but it’s not working out for me.

2

Answers


  1. By looking at WC source code, I was able to get this working by following php code:

    add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
    add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
    
    function variation_settings_fields( $loop, $variation_data, $variation ) {
        $my_custom_image_field = $variation_data['my_custom_image_field'][0] ?? null;
        ?>
        <p class="form-row form-row-first upload_my_custom_field">
            <a
                href="#"
                class="upload_my_custom_field_button tips <?php echo $my_custom_image_field ? 'remove' : ''; ?>"
                data-tip="<?php echo $my_custom_image_field ? esc_attr__( 'Remove this image', 'woocommerce' ) : esc_attr__( 'Upload an image', 'woocommerce' ); ?>"
                rel="<?php echo esc_attr( $variation->ID ); ?>">
                <img src="<?php echo $my_custom_image_field ? esc_url( wp_get_attachment_thumb_url( $my_custom_image_field ) ) : esc_url( wc_placeholder_img_src() ); ?>" />
                <input
                    type="hidden"
                    name="upload_my_custom_image_field[<?php echo esc_attr( $loop ); ?>]"
                    class="upload_my_custom_image_field" value="<?php echo esc_attr( $my_custom_image_field ); ?>" />
            </a>
        </p>
        <?php
    }
    
    function save_variation_settings_fields( $variation_id, $loop ) {
        if (isset( $_POST['upload_my_custom_image_field'][ $loop ] )) {
            $value = wc_clean( wp_unslash( $_POST['upload_my_custom_image_field'][ $loop ] ) );
            update_post_meta( $variation_id, 'my_custom_image_field', esc_attr( $value ));
        }
    }
    

    And following js code:

    (function($) {
        var settings = {
            setting_variation_image: null,
            setting_variation_image_id: null
        }
        function add_my_custom_field(event) {
            var $button = $( this ),
                post_id = $button.attr( 'rel' ),
                $parent = $button.closest( '.upload_my_custom_field' );
    
            settings.setting_variation_image    = $parent;
            settings.setting_variation_image_id = post_id;
    
            event.preventDefault();
    
            if ( $button.is( '.remove' ) ) {
    
                $( '.upload_my_custom_image_field', settings.setting_variation_image ).val( '' ).trigger( 'change' );
                settings.setting_variation_image.find( 'img' ).eq( 0 )
                    .attr( 'src', woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src );
                settings.setting_variation_image.find( '.upload_my_custom_field_button' ).removeClass( 'remove' );
    
            } else {
    
                // If the media frame already exists, reopen it.
                if ( settings.variable_image_frame ) {
                    settings.variable_image_frame.uploader.uploader
                        .param( 'post_id', settings.setting_variation_image_id );
                    settings.variable_image_frame.open();
                    return;
                } else {
                    wp.media.model.settings.post.id = settings.setting_variation_image_id;
                }
    
                // Create the media frame.
                settings.variable_image_frame = wp.media.frames.variable_image = wp.media({
                    // Set the title of the modal.
                    title: woocommerce_admin_meta_boxes_variations.i18n_choose_image,
                    button: {
                        text: woocommerce_admin_meta_boxes_variations.i18n_set_image
                    },
                    states: [
                        new wp.media.controller.Library({
                            title: woocommerce_admin_meta_boxes_variations.i18n_choose_image,
                            filterable: 'all'
                        })
                    ]
                });
    
                // When an image is selected, run a callback.
                settings.variable_image_frame.on( 'select', function () {
    
                    var attachment = settings.variable_image_frame.state()
                        .get( 'selection' ).first().toJSON(),
                        url = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
    
                    $( '.upload_my_custom_image_field', settings.setting_variation_image ).val( attachment.id )
                        .trigger( 'change' );
                    settings.setting_variation_image.find( '.upload_my_custom_field_button' ).addClass( 'remove' );
                    settings.setting_variation_image.find( 'img' ).eq( 0 ).attr( 'src', url );
    
                    wp.media.model.settings.post.id = settings.wp_media_post_id;
                });
    
                // Finally, open the modal.
                settings.variable_image_frame.open();
            }
        }
    
        $(document).on('click', '.upload_my_custom_field', add_my_custom_field);
    })(jQuery)
    
    Login or Signup to reply.
  2. In regards to the JS part in atlantehs’ answer, i think the click event is meant to be added to the button itself. I’ve replaced $(document).on('click', '.upload_my_custom_field', add_my_custom_field); with $(document).on('click', '.upload_my_custom_field_button', add_my_custom_field); and the removal of the image is working as intended, because it wasn’t working for me before the change.

    This is what i’ve used, all written in functions.php of the child theme:

    //Product Variations Upload Custom Image Field
    
    add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
    add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
    
    function variation_settings_fields( $loop, $variation_data, $variation ) {
        $my_custom_image_field = $variation_data['my_custom_image_field'][0] ?? null;
        ?>
        <p class="form-row form-row-first upload_my_custom_field">
            <a
                href="#"
                class="upload_my_custom_field_button tips <?php echo $my_custom_image_field ? 'remove' : ''; ?>"
                data-tip="<?php echo $my_custom_image_field ? esc_attr__( 'Remove this image', 'woocommerce' ) : esc_attr__( 'Upload an image', 'woocommerce' ); ?>"
                rel="<?php echo esc_attr( $variation->ID ); ?>">
                <img src="<?php echo $my_custom_image_field ? esc_url( wp_get_attachment_thumb_url( $my_custom_image_field ) ) : esc_url( wc_placeholder_img_src() ); ?>" />
                <input
                    type="hidden"
                    name="upload_my_custom_image_field[<?php echo esc_attr( $loop ); ?>]"
                    class="upload_my_custom_image_field" value="<?php echo esc_attr( $my_custom_image_field ); ?>" />
            </a>
        </p>
        <?php
    }
    
    function save_variation_settings_fields( $variation_id, $loop ) {
        if (isset( $_POST['upload_my_custom_image_field'][ $loop ] )) {
            $value = wc_clean( wp_unslash( $_POST['upload_my_custom_image_field'][ $loop ] ) );
            update_post_meta( $variation_id, 'my_custom_image_field', esc_attr( $value ));
        }
    }
    
    function product_variation_img_script() {
    $screen = get_current_screen();
        if ($screen->post_type === 'product') :
            ?>
            <style>
                .upload_my_custom_field_button:focus {
                    outline: none !important;
                    box-shadow: none !important;
                }
            </style>
            <script>
               (function($) {
            var settings = {
                setting_variation_image: null,
                setting_variation_image_id: null
            }
            function add_my_custom_field(event) {
                var $button = $( this ),
                    post_id = $button.attr( 'rel' ),
                    $parent = $button.closest( '.upload_my_custom_field' );
    
                settings.setting_variation_image    = $parent;
                settings.setting_variation_image_id = post_id;
    
                event.preventDefault();
                
                if ( $button.hasClass('remove')) {
                    console.log("remove");
                    $( '.upload_my_custom_image_field', settings.setting_variation_image ).val( '' ).trigger( 'change' );
                    settings.setting_variation_image.find( 'img' ).eq( 0 )
                        .attr( 'src', woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src );
                    settings.setting_variation_image.find( '.upload_my_custom_field_button' ).removeClass( 'remove' );
    
                } else {
                    
                    // If the media frame already exists, reopen it.
                    if ( settings.variable_image_frame ) {
                        settings.variable_image_frame.uploader.uploader
                            .param( 'post_id', settings.setting_variation_image_id );
                        settings.variable_image_frame.open();
                        return;
                    } else {
                        wp.media.model.settings.post.id = settings.setting_variation_image_id;
                    }
    
                    // Create the media frame.
                    settings.variable_image_frame = wp.media.frames.variable_image = wp.media({
                        // Set the title of the modal.
                        title: woocommerce_admin_meta_boxes_variations.i18n_choose_image,
                        button: {
                            text: woocommerce_admin_meta_boxes_variations.i18n_set_image
                        },
                        states: [
                            new wp.media.controller.Library({
                                title: woocommerce_admin_meta_boxes_variations.i18n_choose_image,
                                filterable: 'all'
                            })
                        ]
                    });
    
                    // When an image is selected, run a callback.
                    settings.variable_image_frame.on( 'select', function () {
    
                        var attachment = settings.variable_image_frame.state()
                            .get( 'selection' ).first().toJSON(),
                            url = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
    
                        $( '.upload_my_custom_image_field', settings.setting_variation_image ).val( attachment.id )
                            .trigger( 'change' );
                        settings.setting_variation_image.find( '.upload_my_custom_field_button' ).addClass( 'remove' );
                        settings.setting_variation_image.find( 'img' ).eq( 0 ).attr( 'src', url );
    
                        wp.media.model.settings.post.id = settings.wp_media_post_id;
                    });
    
                    // Finally, open the modal.
                    settings.variable_image_frame.open();
                }
            }
    
            $(document).on('click', '.upload_my_custom_field_button', add_my_custom_field);
            })(jQuery)
            </script>
    <?php
        endif;
    }
    add_action('admin_footer', 'product_variation_img_script');
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search