Dynamic Shipping Restrictions in the Subscription Manager
Your site may have certain products that cannot be shipped to certain states. If this is the case, you can change the state choices available when a customer edits their subscription address.
Below you will find a step-by-step guide to implementing these restrictions. This guide will show you how to do this based on a product ID, but you can target any identifier (i.e. subscription.extra_data, product groups, order items, etc). Check out our full list of Object References to see what targets are available.
Subscription Manager Version
The implementation of dynamic shipping restrictions depends on the version of the theme. Please pick the method based on the Subscription Manager version you have installed.
How to tell what version you're on
Before the September 2024 release of v25, all Subscription Manager installations were on version 0, displayed in the Theme Designer as version 0.X.X. You can check which version you’re on by going to Ordergroove > Subscription > Subscription Manager.
Current - smi-templates 25.0.0+
Log in to Ordergroove, and go to Subscriptions > Subscription Manager > Advanced. Make the following changes to your code:
Views order-summary/change-shipping-dialog.liquid
Locate {% set localized_countries = 'localized_countries' | t %} and add the following line of code. Change or add to Alaska and Hawaii, to the states you do not ship to:
{% set excluded_states = setting('enabled_states_restricted', ['AK', 'HI']) %}
Locate the HTML tag sm-country-state-dropdown
and add a new property .excludedStates="{{ excluded_states }}"
. The full HTML tag should appear as follows:
<sm-country-state-dropdown
.localizedCountries="{{ localized_countries }}"
.enabledCountries="{{ enabled_countries }}"
.excludedStates="{{ excluded_states }}"
>
script.js
Locate the function syncCountryAndStates
inside the SMCountryStateDropdown
custom element definition. Inside the states.forEach
loop, add the line if (this.excludedStates.includes(code)) return;
before calling the createOption
function. The updated function should appear similar to the following (depending on your Subscription Manager version, minor updates may have occurred to the base code):
async syncCountryAndStates(countryValue) {
const countriesByCode = await countriesDataPromise;
const selectedCountry = countriesByCode[countryValue];
const states = selectedCountry ? selectedCountry.regions : null;
const currentOptions = this.stateSelect.querySelectorAll('option');
currentOptions.forEach(option => {
// Clear all options except default blank option
if (option.value !== '') option.remove();
});
if (states && states.length) {
states.forEach(({ code, name }) => {
if (this.excludedStates.includes(code)) return; // this is the updated line
createOption(code, name, this.stateSelect);
});
}
}
Subscription Manager 0.33.3 - 0.41.1
Log in to Ordergroove, and go to Subscriptions > Subscription Manager > Advanced. Make the following changes to your code:
Views change-shipment-address.liquid
Locate {% set localized_countries = 'localized_countries' | t %} and add the following line of code. Change or add to Alaska and Hawaii, to the states you do not ship to:
{% set excluded_states = setting('enabled_states_restricted', ['AK', 'HI']) %}
Locate and replace <select id='state{{ order.publicid }}' class='og-form-select' name='state_province_code' > with the following code:
<select id='state_{{ order.public_id }}' class='og-form-select' name='state_province_code' required data-excluded_states='[{{ 'excluded_states.map(s=> `"${s}"`).join(",")' | js }}]'>
script.js
Locate const stateSelectElement = ev.target.closest('form').querySelector('[name="state_province_code"]')' and add the following line of code.
const excludedStates = JSON.parse(stateSelectElement.dataset.excluded_states || '');
Locate states.forEach(({ code, name }) => { and add the following line:
if (excludedStates.includes(code)) return;
Legacy - Subscription Manager 0.33.2 and earlier
Step 1: Set all states for shipping dropdown
Set a list of all localized_states you want available for selection for non-restricted products and put that in a JSON object in the en-US.json file.
Step 2: Set the variables
In the change-shipment-address.liquid file you'll set the full list of enabled states (enabled_states_all) and the list of restricted states (enabled_states_restricted). These will be the two lists pulled into the select form based on the criteria. You'll also set the states object and point it to the localized_states list that you defined in step 1.
Next you'll set a variable of restricted_products to false and then run a for loop to iterate over all of the items in an order to evaluate the product group name or product id (or both). The restricted_products statement will become true if the product or group is found.
{% set enabled_states_all = setting('enabled_states_all', ["AK", "AL", "AR", "AS", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "GU", "HI", "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MP", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VI", "VT", "WA", "WI", "WV", "WY"]) %}
{% set enabled_states_restricted = setting('enabled_states_restricted', ["CO", "CT", "DC", "DE", "FL"]) %}
{% set states = 'localized_states' | t %}
{% set restricted_products = false %}
{% set current_order_items = order_items | select(order=order.public_id) %}
{% for order_item in current_order_items %}
{% set restricted_products = (restricted_products or (order_item.product == "42328611848362")) %}
{% endfor%}
{% set enabled_states_all = setting('enabled_states_all', ["AK", "AL", "AR", "AS", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "GU", "HI", "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MP", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VI", "VT", "WA", "WI", "WV", "WY"]) %}
{% set enabled_states_restricted = setting('enabled_states_restricted', ["CO", "CT", "DC", "DE", "FL"]) %}
{% set states = 'localized_states' | t %}
{% set restricted_products = false %}
{% set current_order_items = order_items | select(order=order.public_id) %}
{% for order_item in current_order_items %}
{% set product = products | find(id=order_item.product) %}
{% for group in product.groups %}
{% if group.name === 'restricted' %}
{% set restricted_products = true %}
{% endif%}
{% endfor %}
{% endfor%}
Step 3: Adjust the state from an input to a select
Here you'll switch the form from being an input field to a select dropdown. Within the code, you can determine which list of states you want the customer to select from based on whether the order contains a restricted product or not.
<div class='og-form-group og-col'>
<label class='og-form-label {{ 'og-required' if 'required_fields.shipping_address.state_province_code' | setting }}' for='state_{{ order.public_id }}'>
{{ 'form_address_state' | t }}
</label>
<select class='og-form-select' name='state_province_code' id='state_{{ order.public_id }}' ?required='{{ 'required_fields.shipping_address.state_province_code' | setting }}'>
{% if restricted_products %}
{% for state_province_code in enabled_states_restricted %}
<option value='{{ state_province_code }}'>{{ states[state_province_code] }}</option>
{% endfor %}
{% else %}
{% for state_province_code in enabled_states_all %}
<option value='{{ state_province_code }}'>{{ states[state_province_code] }}</option>
{% endfor %}
{% endif %}
</select>
</div>
Step 4: Disable Update All Checkbox
If a customer has products that are not shippable to certain states, you'll want to suppress their ability to use the update for all feature when changing their address. This ensures that other subscriptions and orders don't get updated to an unsupported state.
<div class='og-input-group'>
{% if restricted_products %}
<input type='checkbox' class='og-check-radio' name='use_for_all' id='use_for_all_{{ order.public_id }}' />
<label class='og-check-radio-label' for='use_for_all_{{ order.public_id }}'>Use for all shipments</label>
{% else %}
<input type='checkbox' disabled="disabled" class='og-check-radio' name='use_for_all' id='use_for_all_{{ order.public_id }}' />
<label class='og-check-radio-label' for='use_for_all_{{ order.public_id }}'>Use for all shipments disabled due to product shipping restrictions</label>
{% endif %}
</div>
Example Result
Updated about 2 months ago