Add a product note field in single product pages in Woocommerce

10,106

Solution 1

To make it work as you want try the following code where your product note will be displayed in the product page below the product meta. In my code, I have added a hidden field in the add to cart form, and some jQuery code will add the content of the textarea field into the hidden field on the fly. This way the product note can be saved afterwards in the cart item as custom data.

Now this answer will not handle saving the data in the order and display it after checkout, as this is not explicit and too broad for this question.

// Add a custom product note below product meta in single product pages
add_action('woocommerce_single_product_summary', 'custom_product_note', 100 );
function custom_product_note() {

    echo '<br><div>';

    woocommerce_form_field('customer_note', array(
        'type' => 'textarea',
        'class' => array( 'my-field-class form-row-wide') ,
        'label' => __('Product note') ,
        'placeholder' => __('Add your note here, please…') ,
        'required' => false,
    ) , '');

    echo '</div>';

    //
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('#customer_note').on( 'input blur', function() {
            $('#product_note').val($(this).val());
        });
     });
    </script>

    <?php
}

// Custom hidden field in add to cart form
add_action( 'woocommerce_before_add_to_cart_button', 'hidden_field_before_add_to_cart_button', 5 );
function hidden_field_before_add_to_cart_button(){
    echo '<input type="hidden" name="product_note" id="product_note" value="">';
}

// Add customer note to cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_product_note_to_cart_item_data', 20, 2 );
function add_product_note_to_cart_item_data( $cart_item_data, $product_id ){
    if( isset($_POST['product_note']) && ! empty($_POST['product_note']) ){
        $product_note = sanitize_textarea_field( $_POST['product_note'] );
        $cart_item_data['product_note'] = $product_note;
    }
    return $cart_item_data;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

enter image description here


If you want to display this field after add to cart button, you will use this shorter code:

// Add a custom product note after add to cart button in single product pages
add_action('woocommerce_after_add_to_cart_button', 'custom_product_note', 10 );
function custom_product_note() {

    echo '<br><div>';

    woocommerce_form_field('product_note', array(
        'type' => 'textarea',
        'class' => array( 'my-field-class form-row-wide') ,
        'label' => __('Product note') ,
        'placeholder' => __('Add your note here, please…') ,
        'required' => false,
    ) , '');

    echo '</div>';
}

// Add customer note to cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_product_note_to_cart_item_data', 20, 2 );
function add_product_note_to_cart_item_data( $cart_item_data, $product_id ){
    if( isset($_POST['product_note']) && ! empty($_POST['product_note']) ){
        $product_note = sanitize_textarea_field( $_POST['product_note'] );
        $cart_item_data['product_note'] = $product_note;
    }
    return $cart_item_data;
}

enter image description here

Code goes in function.php file of your active child theme (or active theme). Tested and works.


This custom cart item data is accessible this way:

foreach( WC()->cart->get_cart() as $cart_item ){
    if( isset($cart_item['product_note']) )
       echo $cart_item['product_note'];
}

Solution 2

Below is complete flow how to add custom filed at product page and that value will be save, display at order detail and email as well.

  // Display custom field on single product page
    function d_extra_product_field(){
        $value = isset( $_POST['extra_product_field'] ) ? sanitize_text_field( $_POST['extra_product_field'] ) : '';
        printf( '<label>%s</label><input name="extra_product_field" value="%s" />', __( 'Enter your custom text' ), esc_attr( $value ) );
    }
    add_action( 'woocommerce_before_add_to_cart_button', 'd_extra_product_field', 9 );

    // validate when add to cart
    function d_extra_field_validation($passed, $product_id, $qty){

        if( isset( $_POST['extra_product_field'] ) && sanitize_text_field( $_POST['extra_product_field'] ) == '' ){
            $product = wc_get_product( $product_id );
            wc_add_notice( sprintf( __( '%s cannot be added to the cart until you enter some text.' ), $product->get_title() ), 'error' );
            return false;
        }

        return $passed;

    }
    add_filter( 'woocommerce_add_to_cart_validation', 'd_extra_field_validation', 10, 3 );

     // add custom field data in to cart
    function d_add_cart_item_data( $cart_item, $product_id ){

        if( isset( $_POST['extra_product_field'] ) ) {
            $cart_item['extra_product_field'] = sanitize_text_field( $_POST['extra_product_field'] );
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_add_cart_item_data', 'd_add_cart_item_data', 10, 2 );

    // load data from session
    function d_get_cart_data_f_session( $cart_item, $values ) {

        if ( isset( $values['extra_product_field'] ) ){
            $cart_item['extra_product_field'] = $values['extra_product_field'];
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_get_cart_item_from_session', 'd_get_cart_data_f_session', 20, 2 );


    //add meta to order
    function d_add_order_meta( $item_id, $values ) {

        if ( ! empty( $values['extra_product_field'] ) ) {
            woocommerce_add_order_item_meta( $item_id, 'extra_product_field', $values['extra_product_field'] );           
        }
    }
    add_action( 'woocommerce_add_order_item_meta', 'd_add_order_meta', 10, 2 );

    // display data in cart
    function d_get_itemdata( $other_data, $cart_item ) {

        if ( isset( $cart_item['extra_product_field'] ) ){

            $other_data[] = array(
                'name' => __( 'Your extra field text' ),
                'value' => sanitize_text_field( $cart_item['extra_product_field'] )
            );

        }

        return $other_data;

    }
    add_filter( 'woocommerce_get_item_data', 'd_get_itemdata', 10, 2 );


    // display custom field data in order view
    function d_dis_metadata_order( $cart_item, $order_item ){

        if( isset( $order_item['extra_product_field'] ) ){
            $cart_item_meta['extra_product_field'] = $order_item['extra_product_field'];
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_order_item_product', 'd_dis_metadata_order', 10, 2 );


    // add field data in email
    function d_order_email_data( $fields ) { 
        $fields['extra_product_field'] = __( 'Your extra field text' ); 
        return $fields; 
    } 
    add_filter('woocommerce_email_order_meta_fields', 'd_order_email_data');

    // again order
    function d_order_again_meta_data( $cart_item, $order_item, $order ){

        if( isset( $order_item['extra_product_field'] ) ){
            $cart_item_meta['extra_product_field'] = $order_item['extra_product_field'];
        }

        return $cart_item;

    }
    add_filter( 'woocommerce_order_again_cart_item_data', 'd_order_again_meta_data', 10, 3 );
Share:
10,106
Saravana
Author by

Saravana

I'm enjoying answering questions on StackOverflow; I found many solutions in StackOverflow. I am working as a Web/Graphic Designer. I have 6+ year of experience with HTML, CSS, Bootstrap 4, JavaScript, jQuery, Wordpress, Adobe Photoshop/Illustrator. Learning Knockout JS

Updated on June 23, 2022

Comments

  • Saravana
    Saravana almost 2 years

    I want create custom order note in single product detail page for user. This one can do using php without plugin. I have attached screenshot and site URL for reference.

    The have tried with this code in function.php its working on checkout page not in product detail page. Anyone help me to achieve this.

    add_action('woocommerce_after_order_notes', 'customise_checkout_field');
    
        function customise_checkout_field($checkout)
        {
        echo '<div id="customise_checkout_field"><h2>' . __('Heading') . '</h2>';
        woocommerce_form_field('customised_field_name', array(
        'type' => 'text',
        'class' => array(
        'my-field-class form-row-wide'
        ) ,
        'label' => __('Customise Additional Field') ,
        'placeholder' => __('Guidence') ,
        'required' => true,
        ) , $checkout->get_value('customised_field_name'));
        echo '</div>';
        }
    

    website url

    enter image description here

  • Tobias
    Tobias almost 6 years
    have you checkt the visual guide? does your function creates the error?
  • Tobias
    Tobias almost 6 years
    i checked this hook...its working fine, maybe your function makes errors
  • Saravana
    Saravana almost 6 years
    Not sure about that. Just I replaced your code. anyway thank for your effort
  • Saravana
    Saravana almost 6 years
    can add custom text above woocommerce_product_meta_end hook?
  • Saravana
    Saravana almost 6 years
    I also found partially using this kathyisawesome.com/add-a-custom-field-to-woocommerce-product‌​. I want the custom text to after product meta
  • dipmala
    dipmala almost 6 years
    Yes its based on above link that you can add in d_extra_product_field function after the field.
  • Saravana
    Saravana almost 6 years
    Yes. But I need add to note section below sku and categories as per my screenshot
  • dipmala
    dipmala almost 6 years
    You can add many custom fields , I give you the example for one field.
  • Reigel Gallarde
    Reigel Gallarde almost 6 years
    To add as info, the location of the textarea is outside the form, hence the need for jQuery to address the problem. :)
  • Saravana
    Saravana almost 6 years
    @LoicTheAztec the added text not showing up with order and cart page
  • Saravana
    Saravana almost 6 years
    @LoicTheAztec I want to display in product detail page but the thing is the entered data to be carry out cart and checkout page and finally the data can visible from the dashboard order section.
  • Saravana
    Saravana almost 6 years
    @LoicTheAztec ok