How to create multi-step product options in WooCommerce

If you have a complex WooCommerce product with many different options, it may be a good idea to split those options in a multi-step form. This tutorial will show how to achieve multi-step product options in your WooCommerce store.

What we’re building

We’ll create product options, split into multiple steps. A progress bar indicates how far the user is in the process before being able to add the product to their cart.

What you’ll need

  • A store with WooCommerce (5.0 or higher) installed and configured. We assume this is already done on your end but just in case it’s not, you can read this article to get started with WooCommerce.
  • Our Advanced Product Fields for WooCommerce plugin. This plugin is capable of adding options to your product and creating the multi-step product form.

Let’s get started!

1. Configure the options on your product

If you have our plugin up & running, edit your WooCommerce product and find the Custom fields section under Product Data:

custom fields tab in woocommerce product

Here, you can add all options that belong to your product. The important part is to wrap your options in different sections. Each section will represent one step on your product page.

You can add sections by clicking New Field and then choosing Section and Section End as field types. Adding fields to a section is as simple as dragging them between the Section and Section End fields.

Make sure to add a class name to each section, called “step”. You can do that in the section field settings:

Below is an example of 2 sections each containing a few options:

2 sections created with APF

In a later step, we’ll transform these sections into steps with some styling code (called CSS).

2. Add a tag to your product

Chances are you don’t want all your products to have the multi-step layout. Instead, we’ll create a product tag and only products with that tag will use the multistep layout.

In WooCommerce, create a new tag via Products → Tags. Set both the name and slug to “steps”:

Create a product tag in WooCommerce

Now add this tag to all your products that require the multi-step layout:

Add a tag to a product in WooCommerce

3. Add progress bar & buttons

Next, we need to add some HTML code to display a progress bar and buttons to navigate between the steps. That’s done by adding the code below to your site. Are you unsure how to add this code? Check out this article explaining two easy ways to add it to your site.

add_action('wapf_before_wrapper', 'wapf_before_wrapper');

function wapf_before_wrapper($product) {
    if( ! has_term( 'steps', 'product_tag', $product->get_id() ) ) return;
    ?>
    <div class="wapf-progress">
    <div class="wapf-progress-bar"></div>
        <div class="wapf-progress-steps"></div>
    </div>
    <?php
}

add_action('wapf_before_product_totals', 'wapf_before_product_totals');

function wapf_before_product_totals($product) {
    if( ! has_term( 'steps', 'product_tag', $product->get_id() ) ) return;	
    ?>
    <div class="wapf_step_buttons">
        <button class="button wapf_btn_prev" style="display:none"><?php _e('Previous','sw-wapf'); ?></button>
        <button class="button wapf_btn_next"><?php _e('Next','sw-wapf'); ?></button>
    </div>
    <?php
}Code language: JavaScript (javascript)

4. Add styling

In this step, we’ll add CSS to style the progress bar, buttons, and sections. Add the CSS below to your theme via Appearance → Customize → Additional CSS.

Please note the CSS may be a little different for your WordPress theme, but it should be pretty close. I’ve added some comments that may be useful to look at.

.product_tag-steps div.quantity, .product_tag-steps .button[name=add-to-cart] {
    display:none;
}

.product_tag-steps .wapf-wrapper {
    border-radius: 4px;
    border: 1px solid #ededed;
    padding: 15px 20px;
    margin-bottom:20px;
}

.product_tag-steps .wapf-field-group .step {
    display:none;
}

.product_tag-steps .wapf-field-group .step:first-child {
    display:flex;
}

.product_tag-steps .wapf_step_buttons {
    margin-bottom:20px;
    overflow:hidden;
}

.product_tag-steps .wapf_btn_next {
    float:right !important;
}

.product_tag-steps .wapf-progress {
    position:relative;
    max-width:450px;
    width:100%;
    margin: 0 auto;
}

.product_tag-steps .wapf-progress:before, .product_tag-steps .wapf-progress-bar {
    content:'';
    position:absolute;
    height:3px;
    width:100%;
    background:#ededed;
    top:14px;
    left:0;
}

.product_tag-steps .wapf-progress-steps {
    margin-bottom: 30px;
    overflow: hidden;
    counter-reset: step;
    display: flex;
    justify-content: space-between;
}

.product_tag-steps .wapf-progress-steps div {
    position:relative;
}

.product_tag-steps .wapf-progress-steps div:before {
    content: counter(step);
    counter-increment: step;
    width: 30px;
    height:30px;
    font-size:16px;
    line-height:30px;
    border-radius:50%;
    text-align:center;
    display: block;
    font-size: 10px;
    background: #ededed;
}

.product_tag-steps .wapf-progress-steps div.active:before {
    background:#f0632b; /*The finished step color. Feel free to change*/
    color:white;
}

.product_tag-steps .wapf-progress-bar {
    background:#f0632b; /*The finished step color. Feel free to change*/
    width:0%;
}Code language: CSS (css)

5. Make things dynamic

By now, you’ll see the multi-step form is displayed nicely on your Woo product page. But it needs some Javascript logic to make things work. Add the following code to your theme (remember this article from earlier on how to do it):

add_action('wp_footer', 'wapf_steps_script', 1000);

function wapf_steps_script(){
?>
<script>
jQuery( function($) {
	var steps = $('.wapf-section.step');
	if(!steps.length) return;
        steps.first().addClass('stepActive');
	var maxSteps = steps.length;
	var $prev = $('.wapf_btn_prev');
	var $next = $('.wapf_btn_next');
	var $stepList = $('.wapf-progress-steps');
	var $bar = $('.wapf-progress-bar');
	var $cart = $('div.quantity,[name="add-to-cart"]');
	var $progress = $('.wapf-progress');
	var currentStep = 1;
	
	for(var i = 1; i <= maxSteps; i++) {
		var $div = $('<div>');
		if(i === 1) $div.addClass('active');
		$stepList.append($div);
	}
							
	var post = function(e) {
                var visibleStepLi = $stepList.find('div:visible');
                var idx = $stepList.find('div').index(visibleStepLi.eq(currentStep-1));
                idx = Math.max(0,idx);
		var max = visibleStepLi.length;
		if(e) e.preventDefault();
		steps.hide().removeClass('stepActive');
		steps.eq(idx).css('display','flex').addClass('stepActive');
		
		$stepList.find('div').removeClass('active').eq(idx).addClass('active').prevAll().addClass('active');
		if(currentStep >= max) {
			$cart.show();
		} else $cart.hide();
		
		$bar.css('width', (currentStep-1)*(100/(max-1))+'%');
		
		$prev.hide();
		$next.hide();
		if(currentStep < max) $next.show();
		if(currentStep > 1) $prev.show();
                $(document).trigger('wapf_step', [currentStep, max] );
	}
	
	var isValid = function() {
		
		var $inputs = steps.filter('.stepActive').find(':input');
		
		for(var i = 0; i < $inputs.length; i++) {
			if(!$inputs[i].checkValidity()) return false;
		}
		return true;
	}
	
	$prev.on('click', function(e) {
		currentStep--;
		post(e);
	});
	
	$next.on('click', function(e) {
		var valid = isValid();
		if(isValid()) {
			currentStep++;
			post(e);
		}
	});
	
	$(document).on('wapf/dependencies', function(){
		$stepList.find('div').removeClass('wapf-hide');
		steps.each(function(i,s) {
			var $s = $(s);
			if($s.hasClass('wapf-hide')) $stepList.find('div:eq('+i+')').addClass('wapf-hide');
		});
		if($stepList.find('div:not(.wapf-hide)').length <= 1)
			$progress.hide();
		else $progress.show();
		
		post();
	});

        // Block enter key to prevent jumping to another step on accident.
	steps.find('input, select').keypress(function(event) { return event.key != 'Enter'; });
});
</script>
<?php
}Code language: PHP (php)

The script will make sure the progress bar is updated correctly, and the “previous” and “next” buttons do show the correct section.

That’s it! Now you should have a working multi-step form with additional options on your WooCommerce product(s)!

Creating a multistep product in WooCommerce is easy … with copy & paste!

Phew, thanks for bearing with me during this tutorial!

By following the step-by-step tutorial provided in this blog post, you can split your product options into multiple steps and display a progress bar to guide users through the process.

If your product has many extra options, a multistep form creates a more seamless and user-friendly shopping experience.

Check out our working demo here: