Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add custom product field on quick edit option on the product listing of a woocommerce site

How can I add custom product field/s on quick edit screen on the product listing of a woocommerce store?

like image 991
Jplus2 Avatar asked Dec 03 '14 01:12

Jplus2


1 Answers

I am not really sure if this is the best way to do it, but it works great for me

Basically my general goal is to add custom fields for a product, I managed to do it (Adding custom fields to the single product pages) with the help of these useful tuts.

http://www.remicorson.com/mastering-woocommerce-products-custom-fields/ http://www.remicorson.com/woocommerce-custom-fields-for-variations/

I recommend checking those links first before proceeding.

Now, what I wanted to do is to add those custom fields to the quick add option on the product listing.

That's where the resource get scarce.

Basically this is how I did it.

  1. Add your custom field (the html forms) to the quick edit options. I hooked into the 'woocommerce_product_quick_edit_end' action to accomplish this. This hook is found on woocommerce->includes->admin->views->html-quick-edit-product.php on line 195

  2. Save your custom field. I hooked into the 'woocommerce_product_quick_edit_save' action to accomplish this. This hook is found on woocommerce->includes->admin->class-wc-admin-post-types.php inside the 'quick_edit_save' function on line 929

The previous 2 steps does the trick, it does persist the values, however after updating the custom field via the quick edit option, the data is persisted on the backend, but is not populated to the custom field on the UI. That's why we need the 3rd step.

  1. Add the custom field meta data inside the product listing column, then use js to extract the metadata out then populate it to the custom field

I hooked into the 'manage_product_posts_custom_column' action to add a custom HTML tags (div or whatever) to hold my custom field metadata

Then I used javascript to extract the data out from the meta data and populate it into the custom fields

Step 3 is just a copy of how WooCommerce does this process.

For referrence, take a look at function 'render_product_columns' of woocommerce->includes->admin->class-wc-admin-post-types.php

Also take a look at quick-edit.js located at woocommerce->assets->js->admin

Example Code: Note that the code below is used for illustration and guide purposes, my actual code is quite long and complex.

Step 1:

add_action( 'woocommerce_product_quick_edit_end', function(){

    /*
    Notes:
    Take a look at the name of the text field, '_custom_field_demo', that is the name of the custom field, basically its just a post meta
    The value of the text field is blank, it is intentional
    */

    ?>
    <div class="custom_field_demo">
        <label class="alignleft">
            <div class="title"><?php _e('Custom Field Demo', 'woocommerce' ); ?></div>
            <input type="text" name="_custom_field_demo" class="text" placeholder="<?php _e( 'Custom Field Demo', 'woocommerce' ); ?>" value="">
        </label>
    </div>
    <?php

} );

Step 2:

add_action('woocommerce_product_quick_edit_save', function($product){

/*
Notes:
$_REQUEST['_custom_field_demo'] -> the custom field we added above
Only save custom fields on quick edit option on appropriate product types (simple, etc..)
Custom fields are just post meta
*/

if ( $product->is_type('simple') || $product->is_type('external') ) {

    $post_id = $product->id;

    if ( isset( $_REQUEST['_custom_field_demo'] ) ) {

        $customFieldDemo = trim(esc_attr( $_REQUEST['_custom_field_demo'] ));

        // Do sanitation and Validation here

        update_post_meta( $post_id, '_custom_field_demo', wc_clean( $customFieldDemo ) );
    }

}

}, 10, 1);

Step 3:

add_action( 'manage_product_posts_custom_column', function($column,$post_id){

/*
Notes:
The 99 is just my OCD in action, I just want to make sure this callback gets executed after WooCommerce's
*/

switch ( $column ) {
    case 'name' :

        ?>
        <div class="hidden custom_field_demo_inline" id="custom_field_demo_inline_<?php echo $post_id; ?>">
            <div id="_custom_field_demo"><?php echo get_post_meta($post_id,'_custom_field_demo',true); ?></div>
        </div>
        <?php

        break;

    default :
        break;
}

}, 99, 2);

The JS part

jQuery(function(){
jQuery('#the-list').on('click', '.editinline', function(){

    /**
     * Extract metadata and put it as the value for the custom field form
     */
    inlineEditPost.revert();

    var post_id = jQuery(this).closest('tr').attr('id');

    post_id = post_id.replace("post-", "");

    var $cfd_inline_data = jQuery('#custom_field_demo_inline_' + post_id),
        $wc_inline_data = jQuery('#woocommerce_inline_' + post_id );

    jQuery('input[name="_custom_field_demo"]', '.inline-edit-row').val($cfd_inline_data.find("#_custom_field_demo").text());


    /**
     * Only show custom field for appropriate types of products (simple)
     */
    var product_type = $wc_inline_data.find('.product_type').text();

    if (product_type=='simple' || product_type=='external') {
        jQuery('.custom_field_demo', '.inline-edit-row').show();
    } else {
        jQuery('.custom_field_demo', '.inline-edit-row').hide();
    }

});
});

Make sure to enqueue the script

Hope this helps anyone, again, I am not sure if this is the best way to do it, but upon examining WooCommerce source, it seems WooCommerce doesn't provide a convenient hook to accomplish this task with ease (at least not yet)

If you have a better approach than this please share.

like image 126
Jplus2 Avatar answered Nov 24 '22 00:11

Jplus2