How to add an input field to WooCommerce cart items

polina rytova 709444 unsplash

This is a simple method to add a text input field to each WooCommerce cart item. Customers can enter text into the field which will be saved as meta data to the cart item – so you will receive it with the order.

Add a text field to the WooCommerce product page

The easiest way to add custom fields to your WooCommerce product pages is with the Product Add-Ons Ultimate plugin.

WooCommerce Product Add-Ons Ultimate featured image

WooCommerce Product Add-Ons Ultimate

Add custom input fields to your WooCommerce products

Find Out More

Add a textarea field to a WooCommerce cart item using code

First, we just need to add the textarea field. We use the woocommerce_after_cart_item_name hook so our textarea will appear after the product name.

<?php
/**
* Add a text field to each cart item
*/
function prefix_after_cart_item_name( $cart_item, $cart_item_key ) {
$notes = isset( $cart_item['notes'] ) ? $cart_item['notes'] : '';
printf(
'<div><textarea class="%s" id="cart_notes_%s" data-cart-id="%s">%s</textarea></div>',
'prefix-cart-notes',
$cart_item_key,
$cart_item_key,
$notes
);
}
add_action( 'woocommerce_after_cart_item_name', 'prefix_after_cart_item_name', 10, 2 );
/**
* Enqueue our JS file
*/
function prefix_enqueue_scripts() {
wp_register_script( 'prefix-script', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'update-cart-item-ajax.js', array( 'jquery-blockui' ), time(), true );
wp_localize_script(
'prefix-script',
'prefix_vars',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
)
);
wp_enqueue_script( 'prefix-script' );
}
add_action( 'wp_enqueue_scripts', 'prefix_enqueue_scripts' );

You can see below how it’ll look in the cart (using the Storefront theme).

WooCommerce cart item textarea

At the moment, the user will be able to enter text into the field but the text won’t save. We are going to use some AJAX to save the text.

The code above not only adds the textarea to the cart item, it also enqueues a JavaScript file ready for our AJAX.

It’s assumed that you’re using the code on this page to create a new plugin. If so, you should create a new JS file with the code below and place the file in the root directory of your plugin.

However, if you’ve added the PHP above to your theme functions.php or as a snippet on your site, you’ll need to change the location of the JS file by updating line 21 of the snippet above to identify the location of the JS file.

(function($){
$(document).ready(function(){
$('.prefix-cart-notes').on('change keyup paste',function(){
$('.cart_totals').block({
message: null,
overlayCSS: {
background: '#fff',
opacity: 0.6
}
});
var cart_id = $(this).data('cart-id');
$.ajax(
{
type: 'POST',
url: prefix_vars.ajaxurl,
data: {
action: 'prefix_update_cart_notes',
security: $('#woocommerce-cart-nonce').val(),
notes: $('#cart_notes_' + cart_id).val(),
cart_id: cart_id
},
success: function( response ) {
$('.cart_totals').unblock();
}
}
)
});
});
})(jQuery);

Now, when the user types anything, the contents of the text field get sent back to the server ready to be saved as meta data to the cart item.

<?php
/**
* Update cart item notes
*/
function prefix_update_cart_notes() {
// Do a nonce check
if( ! isset( $_POST['security'] ) || ! wp_verify_nonce( $_POST['security'], 'woocommerce-cart' ) ) {
wp_send_json( array( 'nonce_fail' => 1 ) );
exit;
}
// Save the notes to the cart meta
$cart = WC()->cart->cart_contents;
$cart_id = $_POST['cart_id'];
$notes = $_POST['notes'];
$cart_item = $cart[$cart_id];
$cart_item['notes'] = $notes;
WC()->cart->cart_contents[$cart_id] = $cart_item;
WC()->cart->set_session();
wp_send_json( array( 'success' => 1 ) );
exit;
}
add_action( 'wp_ajax_prefix_update_cart_notes', 'prefix_update_cart_notes' );
add_action( 'wp_ajax_nopriv_prefix_update_cart_notes', 'prefix_update_cart_notes' );
function prefix_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
foreach( $item as $cart_item_key=>$cart_item ) {
if( isset( $cart_item['notes'] ) ) {
$item->add_meta_data( 'notes', $cart_item['notes'], true );
}
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'prefix_checkout_create_order_line_item', 10, 4 );

The prefix_update_cart_notes function does a security check using the WooCommerce cart nonce then saves the content of the textarea as meta data in the cart item. You can check out this article for more information about updating cart meta for items that have already been added to the cart.

Add the custom text to the order meta

Finally, we want to pass our meta data to the order so that we can use it after the customer has checked out. The prefix_checkout_create_order_line_item function takes care of that, iterating through each item and saving notes when it finds them.

20 comments

    • User image

      Hi Edwin – yes, you’d need to add a conditional statement in the prefix_after_cart_item_name function to check whether the cart item contained the product ID.

  1. User image

    Thanks this is so cool for what I was looking for, helpme a lot, for the folks looking the same features I make this work by addind manually the urls on function prefix_enqueue_scripts() {
    wp_register_script( ‘prefix-script’, trailingslashit( ‘https://mydomain.com./wp-admin/js/’) . ‘update-cart-item-ajax.js’,

    ‘ajaxurl’ => ‘https://mydomain.com/wp-admin/admin-ajax.php’

    and also changing the update-cart-item-ajax.js script action as follow:
    jquery.ajax(
    {
    type: ‘POST’,
    url: prefix_vars.ajaxurl,
    data: {
    action: ‘wp_ajax_prefix_update_cart_notes’,
    security: $(‘#woocommerce-cart-nonce’).val(),

  2. User image

    Well. I tried using different approaches. Didn’t get the right result.
    Hoping you will reply quickly tho.
    So to make things clear on what I’ve done.
    I took the first code (woocommerce-cart-input.php) and pasted in, as is, on the functions.php on my child theme.
    Yet the JS file didn’t load (as again, I’m using a child theme, so some changes need to be done and I’m not quite sure what)
    so I did what tucson-az commented on the github page (https://gist.github.com/plugin-republic/462975544b9c76c9fc8f503c8722334f#file-update-cart-item-ajax-js) and placed the JS code within the cart, checkout and shop page.

    The option is being added to the cart page, but nothing is being saved, or let me check out.

    So, I’m looking for some more clear instructions on how is the best way to implement this on my website.
    Thank you so much šŸ™‚

    • User image

      Hi Yoske

      I’ve updated the article to provide some further explanation. You’ll need to either use this code to create a new plugin or, if you add the PHP to your theme’s functions.php file or as a snippet, you’ll need to ensure you tell the snippet where to find the JS file.

      Thanks

      Gareth

  3. User image

    Hi, thank you!
    It really helped me! and it works, but when I add text to the custom field and then I update the cart – the field get clear, if I’m not refreshing and straightforward to checkout, the field is added to the order as i need,

    you have an idea how to keep the value even after clicking update Cart or change quantity?
    https://veg.ussl.shop/cart/

  4. User image

    Should the last line of the final code example be this?

    add_action( ‘woocommerce_checkout_create_order_line_item’, ‘prefix_checkout_create_order_line_item’, 10, 4 );

      • User image

        As I was working on implementing this today, I realized that entire function is not quite right. It shouldn’t have the foreach loop, and it should be looking for the individual meta data in the $values array, like this:

        function prefix_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
        if( isset( $values[‘notes’] ) ) {
        $item->add_meta_data( ‘notes’, $values[‘notes’], true );
        }
        }

        • User image

          One other issue I ran into that is now resolved. This was working fine for me if I was logged in, but if I wasn’t, the AJAX spinner on the cart page would just go forever, and there would be an HTTP 400 Bad Request error in the console.

          This is because (and I do this just rarely enough that I always forget it in the meantime) WordPress has two separate hooks for back-end and (non-logged-in) front-end AJAX calls. So in the final code sample above, in addition to this line:

          add_action( ‘wp_ajax_prefix_update_cart_notes’, ‘prefix_update_cart_notes’ );

          You should also have this right after it:

          add_action( ‘wp_ajax_nopriv_prefix_update_cart_notes’, ‘prefix_update_cart_notes’ );

  5. User image

    Hi

    I have added the three files to a zip file and uploaded it as a plugin. However I get a js 400 error, when i start typing into the custom field.

    What iā€™m I going wrong? Does these scripts not work any longer?

  6. User image

    Hi
    I want upload customer image per cart line item on the cart page.No idea for this problem.But I haven’t done it yet.You can help me?
    Thanks All.

  7. User image

    Hi Gareth

    I dont have any questions i just want to thank you for a great work it fixed my problem that customer didnt want to let go of.

    Thank you

  8. User image

    I’m using “Code Snippets Pro” and I do not see a way to add the javascript. Is there some way to use Code Snippets, maybe adding the javascript as snippet and then using it as shortcode in the php?

    Thanks for the inspiration!

  9. User image

    I did figure it out using Code Snippets. Not that hard. I can see the extra field on the Cart page but not on Checkout. Also, it’s included in the outgoing email order confirmation. Is it not programmed to show on Checkout?

Leave a Reply

Your email address will not be published. All fields are required.