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 (3.4.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.

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:

In a later step, we’ll transform these sections into steps with CSS.

2. Add progress bar & buttons

Next, we need to add some HTML 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) {
	?>
	<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){
	?>
	<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
}

Note this code will add a progress bar & buttons to all your products. If you’d like to limit the products that require a multi-step form, you can use this code instead:

add_action('wapf_before_wrapper', 'wapf_before_wrapper');
function wapf_before_wrapper($product) {
        $product_ids = array(123,987,630);
        if(!in_array($product->get_id(),$product_ids)) 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) {
        $product_ids = array(123,987,630);
        if(!in_array($product->get_id(),$product_ids)) 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
}

In the code above, note the two lines $product_ids = array(123,987,630);. You should edit those lines to include the product ID’s you want the multi-step form working on.

3. 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 in bold that may be useful to look at.

div.quantity, .woocommerce .button[name=add-to-cart] {
    display:none; /*Hide Add to Cart button until last step*/
}
.wapf-wrapper{
    border-radius: 4px;
    border: 1px solid #ededed;
    padding: 15px 20px;
    margin-bottom:20px;
}
.wapf-field-group .step{
    display:none;
}
.wapf-field-group .step:first-child{
    display:flex;
}
.wapf_step_buttons{
    margin-bottom:20px;
    overflow:hidden;
}
.wapf_btn_next{
    float:right !important;
}
.wapf-progress{
    position:relative;
    max-width:450px;
    margin: 0 auto;
}
.wapf-progress:before, .wapf-progress-bar{
    content:'';
    position:absolute;
    height:3px;
    width:100%;
    background:#ededed;
    top:14px;
    left:0;
}
.wapf-progress-steps{
    margin-bottom: 30px;
    overflow: hidden;
    counter-reset: step;
    display: flex;
    justify-content: space-between;
}
.wapf-progress-steps div{
    position:relative;
}
.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;
}
.wapf-progress-steps div.active:before{
    background:#f0632b; /*The finished step color. Feel free to change*/
    color:white;
}

.wapf-progress-bar{
    background:#f0632b; /*The finished step color. Feel free to change*/
    width:0%;
}

Note this CSS will change the appearance for all product pages. If you want to limit the products that have a multi-step form, some of the CSS should be changed to only affect those products. This can easily be done if you know your product ID.

The below code only adds multi-step styling to a product with ID 123. Note that you only need to change the first two styling blocks (as shown in the example below). All other CSS from the code above remains the same:

.postid-123 div.quantity, .postid-123.woocommerce .button[name=add-to-cart] {
    display:none;
}
.postid-123 .wapf-wrapper{
    border-radius: 4px;
    border: 1px solid #ededed;
    padding: 15px 20px;
    margin-bottom:20px;
}

As you can see, the CSS above contains an extra portion to every rule: .postid-123 where 123 is the ID of your product. If you need it for more than 1 product, you can do it like this:

.postid-123 .wapf-wrapper,.postid-345 .wapf-wrapper, .postid-678 .wapf-wrapper{ ... }

4. 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');
function wapf_steps_script(){
?>
<script>
jQuery(function($) {
	var steps = $('.wapf-section.step');
	if(!steps.length) return;
	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 max = $stepList.find('div:visible').length;
		if(e) e.preventDefault();
		steps.hide();
		steps.eq(currentStep-1).css('display','flex');
		
		$stepList.find('div').removeClass('active').eq(currentStep-1).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();
	}
	
	var isValid = function() {
		
		var $inputs = steps.eq(currentStep-1).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();
	});
});
</script>
<?php
}

The script will make sure the progress bar is updated correctly, the “previous” and “next” buttons do their work, and the correct section is shown at any time.

That’s it! Now you should have a working multi-step product options form!

Share

21 comments

  1. Pinki Biswas
    August 16, 2021 Reply

    How do I add an automatic progress bar? I don’t want to click the next button. This will automatically take me to the next step.

    1. Maarten Belmans
      August 18, 2021 Reply

      Hi there,

      That would require additional custom coding I’m afraid.

  2. Philippe
    August 29, 2021 Reply

    How to translate the Previous and Next buttons ?

    1. Maarten Belmans
      August 29, 2021 Reply

      Hi Philippe,

      You can edit the code from step 2 to add your own wording. I have highlighted the words in this screenshot: https://i.snipboard.io/6Ct47s.jpg

      1. Philippe
        August 29, 2021 Reply

        Thanks Maarten !

  3. Falah Ahmad
    September 19, 2021 Reply

    Can i add a video of instruction on any step to guide users how to fill up fields for that particular step ?

    Can i also show automated options after selecting specific height?

    1. Maarten Belmans
      September 21, 2021 Reply

      Hi there,

      Our plugin allows you to add text/html to your products so you can link to a video with instruction. I’m not sure what you mean with your 2nd question.

  4. Mario R. Vásquez S.
    October 6, 2021 Reply

    We need to know if the plugin can work with conditional products. That is, if I choose option X it offers me a selection of products, if I choose option Y it offers me another selection.

    1. Maarten Belmans
      October 6, 2021 Reply

      Our plugin works with conditional fields, but not products. You can show/hide fields based on values of other fields. You can not show products based on field values.

  5. Mario R. Vásquez S.
    October 10, 2021 Reply

    Thanks for your quick response . We insist on the possibility of using this plugin.
    However, we have the following question.
    Can we associate costs to those fields? . So that they add to the final product.
    Thanks in advance .

    1. Maarten Belmans
      October 10, 2021 Reply

      Yes, that is possible.

  6. Mohammad Ammar
    October 29, 2021 Reply

    Hello, I want to show prices in the last step, except showing at the end of each step. Is that possible?

    1. Maarten Belmans
      November 2, 2021 Reply

      Not without additional custom coding, sorry!

  7. Sofiane MOUMAN
    November 9, 2021 Reply

    Good morning, look at this

    https://preprod-slagon.fr/mamy-eyewear/produit/product-example-2/

    I have 4 steps on my form.

    The last two choices of the first step Screen glasses and Non-prescription don’t need any configuration.

    For these two choices the next steps are empty how to solve this problem sir ?

    I would like to know how to skip empty steps.

    1. Maarten Belmans
      November 9, 2021 Reply

      Hi there,

      This sounds like a technical request. Please use the support form here to get in touch with us so we have all the necessary information to help you out.

      Thank you!

  8. Johnkpapadopoulos
    November 28, 2021 Reply

    Hello i have a list of hundrends of products where i want the multistep to display and a list of hundrends of products where i dont want the multistep to display. Is there a way without hardcoding?

    1. Maarten Belmans
      November 28, 2021 Reply

      Yes, it’s possible by altering the code snippets. Send us a technical support request here and we’ll help you out.

  9. Alex
    November 29, 2021 Reply

    Hello

    With this plugin, i can add some custom fields on variations of products with variation on value?

    Example:

    Product 1> Variation 1> Insert 2 custom fields with diferent values
    Product 2> Variation 1 and 2> Insert 3 custom fields, with one without any value

    1. Maarten Belmans
      November 30, 2021 Reply

      Hi there,

      Yes, that’s possible :).

  10. Fnd
    January 24, 2022 Reply

    Hi!

    Can I add conditions in multi-step product options?

    1. Maarten Belmans
      January 27, 2022 Reply

      Yes you can, but depending on how far you want to take it.

Join the discussion

Your email address will not be published.