WooCommerce Product Add-Ons Ultimate allows you to enable or disable options based on what the user selects in other fields.

This functionality is available in the Pro version of the plugin from version 3.26.10 and upwards.
There’s a simple demo product here where you can see how it works.
How to set conditions on options in WooCommerce add-on fields
To enable option conditions, you’ll need to add the snippet at the end of this article. Then follow the steps below.
First, create your fields and options. The, to create a condition on an option, update the ‘Conditions’, ‘Operator’, and ‘Action’ fields for the option.
Conditions
Define the condition’s rules in the ‘Conditions’ field. The rule is defined using specific notation. (Note that this notation might change in future versions).
The notation uses the following format:
Field ID ^ Option Value
The first element is the ID of the field that this option depends on; the second element is the value of the option; and they’re separated by a ^
caret character.. So, in this example, if you want to enable your swatch called ‘Red Hoodie’ if ‘Red’ in Field ID #4244 is selected, then you would enter the following:
4244^Red
If the condition depends on the value of multiple fields / options, you can enter multiple rules like this:
Field ID 1 ^ Option Value A | Field ID 2 ^ Option Value B
Note that each rule is separated by a |
pipe character.

I you are checking values from a number field in your condition, you should include an extra element in the condition:
Field ID ^ Number Field Value ^ Comparitor
A comparitor can be ‘>=’, ‘>’, ‘>’, ‘<‘, or ‘<=’. So if you want to enable an option if the value of a number field is greater than 10, you would use notation like the following:
2499^10^>
Where 2499 is the ID of the number field.
Operator
If you have multiple rules for your condition, i.e. the condition depends on the value of more than one field or option, you can set the ‘Operator’ field either to AND
or to OR
.

If the ‘Operator’ field is set to AND
, all the rules in the condition must obtain.
If the ‘Operator’ field is set to OR
, only one of the rules in the condition must obtain.
Action
You can use the ‘Action’ setting to decide whether to enable or disable the option if the condition obtains.

Code snippet
This is the code snippet you need to add in order to enable conditions on options. Here’s how to add a snippet.
<?php | |
function demo_radio_label_classes( $label_classes, $item, $option_value, $option_index ) { | |
// Check for custom params | |
if( ! empty( $item['field_options'][$option_index]['conditions'] ) ) { | |
$label_classes[] = 'pewc-option-conditions'; | |
} | |
return $label_classes; | |
} | |
add_filter( 'pewc_radio_label_classes', 'demo_radio_label_classes', 10, 4 ); | |
function demo_option_attribute_string( $option_attribute_string, $item, $option_value, $option_index ) { | |
$action = ! empty( $item['field_options'][$option_index]['action'] ) ? $item['field_options'][$option_index]['action'] : 'ENABLE'; | |
$option_attribute_string .= " data-condition-action='" . esc_attr( trim( $action ) ) . "'"; | |
$operator = ! empty( $item['field_options'][$option_index]['operator'] ) ? $item['field_options'][$option_index]['operator'] : 'AND'; | |
$option_attribute_string .= " data-condition-operator='" . esc_attr( trim( $operator ) ) . "'"; | |
if( ! empty( $item['field_options'][$option_index]['conditions'] ) ) { | |
$conditions = explode( '|', $item['field_options'][$option_index]['conditions'] ); | |
$fields_list = array(); | |
$options_list = array(); | |
$comparitors_list = array(); | |
if( is_array( $conditions ) ) { | |
foreach( $conditions as $index=>$condition ) { | |
$condition = explode( '^', $condition ); | |
if( is_array( $condition ) ) { | |
$fields_list[$index] = isset( $condition[0] ) ? trim( $condition[0] ) : false; | |
$options_list[$index] = isset( $condition[1] ) ? trim( $condition[1] ) : false; | |
$comparitors_list[$index] = isset( $condition[2] ) ? trim( $condition[2] ) : ''; | |
} | |
} | |
} | |
$option_attribute_string .= " data-required-field-ids='" . json_encode( $fields_list, JSON_FORCE_OBJECT ) . "'"; | |
$option_attribute_string .= " data-required-option-ids='" . json_encode( $options_list, JSON_FORCE_OBJECT ) . "'"; | |
$option_attribute_string .= " data-required-comparitors='" . json_encode( $comparitors_list, JSON_FORCE_OBJECT ) . "'"; | |
} | |
return $option_attribute_string; | |
} | |
add_filter( 'pewc_option_attribute_string', 'demo_option_attribute_string', 10, 4 ); | |
function demo_add_roles_after_option_params_titles( $group_id, $item_key, $item ) { | |
printf( | |
'<th class="pewc-option-condition-col pewc-option-extra-title"><div class="pewc-label">%s</div></th>', | |
__( 'Conditions', 'pewc' ) | |
); | |
printf( | |
'<th class="pewc-option-condition-col pewc-option-extra-title"><div class="pewc-label">%s</div></th>', | |
__( 'Operator', 'pewc' ) | |
); | |
printf( | |
'<th class="pewc-option-condition-col pewc-option-extra-title"><div class="pewc-label">%s</div></th>', | |
__( 'Action', 'pewc' ) | |
); | |
} | |
add_action( 'pewc_after_option_params_titles', 'demo_add_roles_after_option_params_titles', 10, 3 ); | |
function demo_add_option_param( $option_count, $group_id, $item_key, $item, $key ) { | |
$name = '_product_extra_groups_' . esc_attr( $group_id ) . '_' . esc_attr( $item_key ) . '[field_options][' . esc_attr( $option_count ) . ']'; | |
$conditions = isset( $item['field_options'][esc_attr( $key )]['conditions'] ) ? $item['field_options'][esc_attr( $key )]['conditions'] : ''; | |
$operator = isset( $item['field_options'][esc_attr( $key )]['operator'] ) ? $item['field_options'][esc_attr( $key )]['operator'] : 'AND'; | |
$action = isset( $item['field_options'][esc_attr( $key )]['action'] ) ? $item['field_options'][esc_attr( $key )]['action'] : 'ENABLED'; | |
?> | |
<td class="pewc-option-condition-col pewc-option-extra"> | |
<input type="text" class="pewc-field-option-extra pewc-field-option-conditions" name="<?php echo $name; ?>[conditions]" value="<?php echo esc_attr( $conditions ); ?>"> | |
</td> | |
<td class="pewc-option-condition-col pewc-option-extra pewc-option-extra-radio"> | |
<label for="<?php echo $name; ?>[operator]_AND"> | |
<input type="radio" class="pewc-field-option-extra pewc-field-option-operator" name="<?php echo $name; ?>[operator]" id="<?php echo $name; ?>_operator_AND" value="AND" <?php checked( $operator, 'AND', true ); ?>> | |
<?php _e( 'AND', 'pewc' ); ?> | |
</label> | |
<label for="<?php echo $name; ?>[operator]_OR"> | |
<input type="radio" class="pewc-field-option-extra pewc-field-option-operator" name="<?php echo $name; ?>[operator]" id="<?php echo $name; ?>_operator_OR" value="OR" <?php checked( $operator, 'OR', true ); ?>> | |
<?php _e( 'OR', 'pewc' ); ?> | |
</label> | |
</td> | |
<td class="pewc-option-condition-col pewc-option-extra pewc-option-extra-radio"> | |
<label for="<?php echo $name; ?>_action_ENABLED"> | |
<input type="radio" class="pewc-field-option-extra pewc-field-option-action" name="<?php echo $name; ?>[action]" id="<?php echo $name; ?>_action_ENABLED" value="ENABLED" <?php checked( $action, 'ENABLED', true ); ?>> | |
<?php _e( 'Enable', 'pewc' ); ?> | |
</label> | |
<label for="<?php echo $name; ?>_action_DISABLED"> | |
<input type="radio" class="pewc-field-option-extra pewc-field-option-action" name="<?php echo $name; ?>[action]" id="<?php echo $name; ?>_action_DISABLED" value="DISABLED" <?php checked( $action, 'DISABLED', true ); ?>> | |
<?php _e( 'Disable', 'pewc' ); ?> | |
</label> | |
</td> | |
<?php } | |
add_action( 'pewc_after_option_params', 'demo_add_option_param', 10, 5 ); | |
function demo_options_js() { | |
if( ! function_exists( 'is_product' ) || ! is_product() ) { | |
return; | |
} | |
?> | |
<script> | |
( function( $ ) { | |
var option_conditions = { | |
init: function() { | |
$( '.pewc-option-conditions input' ).each( function() { | |
if( $( this ).attr( 'data-required-field-ids' ).length > 0 ) { | |
required_field_id = JSON.parse( $( this ).attr( 'data-required-field-ids' ) ); | |
if( required_field_id ) { | |
for( var i in required_field_id ) { | |
$( '.pewc-field-' + required_field_id[i] ).addClass( 'pewc-option-required' ); | |
} | |
} | |
} | |
}); | |
$( 'body' ).find( '.pewc-option-required input' ).each( this.required_update ); | |
$( 'body' ).on( 'change keyup','.pewc-option-required input, .pewc-option-required select', this.required_update ); | |
}, | |
required_update: function() { | |
$( '.pewc-option-conditions' ).each( function( ind, v ) { | |
// Iterate through each option that has conditions | |
if( typeof( $( this ).find( 'input' ).attr( 'data-required-field-ids' ) ) !== 'undefined' ) { | |
// The field ID(s) that this option requires to be enabled | |
var required_field_ids = JSON.parse( $( this ).find( 'input' ).attr( 'data-required-field-ids' ) ); | |
// The option(s) within each field that the option needs for it to be enabled | |
var required_option_ids = JSON.parse( $( this ).find( 'input' ).attr( 'data-required-option-ids' ) ); | |
var required_comparitors = JSON.parse( $( this ).find( 'input' ).attr( 'data-required-comparitors' ) ); | |
var action = $( this ).find( 'input' ).attr( 'data-condition-action' ); // Whether to enable or disable if the condition is met | |
var operator = $( this ).find( 'input' ).attr( 'data-condition-operator' ); // AND / OR | |
var check_option = $( this ); | |
var matches = true; // True if the condition is met; false if not met | |
for( var f in required_field_ids ) { | |
// Check the list of required fields | |
required_field_id = required_field_ids[f]; | |
required_option_val = required_option_ids[f]; | |
// Check the value of the required field + options | |
console.log( 'Required option val', required_option_val ); | |
field_name = $( '.pewc-field-' + required_field_id ).attr( 'data-id' ); // Option field ID | |
// Check for the field type and get the field value accordingly | |
if( $( '.' + field_name ).attr( 'data-field-type' ) == 'image_swatch' ) { | |
field_value = $( 'input[name="' + field_name + '[]"]:checked' ).val(); | |
} else if( $( '.' + field_name ).attr( 'data-field-type' ) == 'select' || $( '.' + field_name ).attr( 'data-field-type' ) == 'number' ) { | |
field_value = $( '#' + field_name ).val(); | |
} | |
if( $( '.' + field_name ).attr( 'data-field-type' ) == 'number' ) { | |
// If we're evaluating a number field, we do some additional work to to set the required_option_val and field_value | |
// Here we check if the condition has been met or not | |
var comparitor = required_comparitors[f]; | |
// Set required_option_val and field_value with arbitrary values so we can use them in the next section to evaluate the condition | |
if( ( comparitor == '>=' && parseInt( field_value ) >= parseInt( required_option_val ) ) || | |
( comparitor == '>' && parseInt( field_value ) > parseInt( required_option_val ) ) || | |
( comparitor == '=' && parseInt( field_value ) == parseInt( required_option_val ) ) || | |
( comparitor == '<' && parseInt( field_value ) < parseInt( required_option_val ) ) || | |
( comparitor == '<=' && parseInt( field_value ) <= parseInt( required_option_val ) ) ) { | |
field_value = required_option_val = 1; // Set them to the same value so the condition will evaluate as met below | |
} else { | |
field_value = 1; | |
required_option_val = 2; // Set them to a different value so the condition will evaluate as false below | |
} | |
} | |
if( required_option_val != field_value ) { | |
// The option value doesn't match the required value | |
if( action == 'ENABLED' ) { | |
// Disable options where the condition isn't met and the action is set to ENABLED | |
$( check_option ).closest( '.pewc-radio-image-wrapper' ).addClass( 'pewc-option-inactive' ); | |
matches = false; | |
} else { | |
// Enable options where the condition isn't met and the action is set to DISABLED | |
$( check_option ).closest( '.pewc-radio-image-wrapper' ).removeClass( 'pewc-option-inactive' ); | |
matches = false; | |
} | |
if( operator == 'AND' ) { | |
// If all conditions must be met, and this condition doesn't, then the condition has failed | |
matches = false; | |
break; | |
} | |
} else { | |
// If the option value matches the required value | |
if( action == 'ENABLED' ) { | |
// Enable options where the condition matches and the action is set to ENABLED | |
$( check_option ).closest( '.pewc-radio-image-wrapper' ).removeClass( 'pewc-option-inactive' ); | |
} else { | |
// Disable options where the condition matches and the action is set to DISABLE | |
$( check_option ).closest( '.pewc-radio-image-wrapper' ).addClass( 'pewc-option-inactive' ); | |
} | |
if( operator == 'OR' ) { | |
// If any conditions can be met, and this condition is met, then the condition has succeeded | |
matches = true; | |
break; | |
} | |
} | |
} | |
if( matches && action == 'ENABLED' || ! matches && action == 'DISABLED' ) { | |
$( check_option ).closest( '.pewc-radio-image-wrapper' ).removeClass( 'pewc-option-inactive' ); | |
} else if( matches && action == 'DISABLED' || ! matches && action == 'ENABLED' ) { | |
$( check_option ).closest( '.pewc-radio-image-wrapper' ).addClass( 'pewc-option-inactive' ); | |
} | |
// All inactive options must be deselected | |
$( '.pewc-option-inactive' ).each( function( i,v ) { | |
$( this ).closest( '.pewc-radio-image-wrapper' ).removeClass( 'checked' ); | |
$( this ).find( 'input' ).prop( 'checked', false ); | |
}); | |
} | |
}); | |
} | |
} | |
option_conditions.init(); | |
})( jQuery ); | |
</script> | |
<?php | |
} | |
add_action( 'wp_footer', 'demo_options_js' ); |
Known limitations
At the moment, you can only enable or disable options in the Swatch field type. And you can only set conditions on options based on selections or values in other swatch fields, in select fields, or in number fields.
So a user can choose ‘Option A’ in a select field to enable ‘Option X’ in a separate swatch field; or enter a value of 5 in a number field to disable an option in a swatch field; and so on.
We will be reviewing the GUI and notation for option conditions in order to make this more user-friendly in future versions.