CartThrob 9 documentation for ExpressionEngine commerce teams Visit CartThrob.com
CartThrob.com

Item Options

{exp:cartthrob:item_options} outputs option groups for a product or cart row and helps render the correct form inputs for selecting/updating those options.

This tag is commonly used in:

  • product detail templates (entry_id mode)
  • cart/update templates (row_id mode)
  • package sub-item editing (row_id like parent_row:sub_row)

See also:

Parameters

entry_id

Product entry ID used to load price-modifier options from channel data.

Use this when rendering options before the item is in the cart.

entry_id="123"

row_id

Cart row ID used to load selected/dynamic options for a specific cart item.

Use this when rendering options for cart updates.

row_id="{row_id}"

Sub-item/package rows are supported with parent_row:sub_row format.

row_id="{sub:row_id}"

At least one of entry_id or row_id is required. If both are missing, the tag returns no-results output.

field

Limit output to one or more option fields (pipe-delimited).

field="product_size|product_color"

search:option_name

Filter option rows by displayed option name when building option lists.

search:option_name="Small|Medium"

search:selected

Set to yes to return only the choice currently selected on the cart row inside each options, list, or select pair. Use this with row_id when displaying a cart item’s Configurator selections.

search:selected="yes"

Variables

Each item_options loop iteration represents one option field/group.

option_field

Field short name for the option group.

product_size

option_label

Human-readable label for the option group.

If no label is found in field metadata, CartThrob falls back to stored custom labels or a humanized field name.

Product Size

Alias also available:

{item_options:option_label}

configuration_label

Used for configurator-style price modifier fields (top-level configurator label).

Configurable Item

field_type

CartThrob field type for this option field (for example configurator field types).

cartthrob_price_modifiers

option_value

Currently selected/stored value for this option field (if available).

L

dynamic

1 when the option field is dynamic (not defined as a standard price modifier for this entry), otherwise 0.

{if dynamic}This option was added on the fly{/if}

options_exist

True when this option field has configured selectable options in price modifiers.

Use this to hide empty dropdown sections.

{if options_exist}...{/if}

allow_selection

For package/edit contexts, indicates whether this field can be edited (1) or should be display-only (0).

input

Auto-generated <input> element with correct name and current value.

It uses item_options[field] names for entry mode, and item_options[row_id][field] names for row mode.

{input}

item_options_total_results

Total number of option groups returned by this tag call.

{item_options_total_results}

item_options_count

1-based counter for the current option group.

{item_options_count}

Example:

{if "{item_options_count}" == "1"}
    Show this once at the top
{/if}

Variable Pairs

options

Freeform pair that outputs one row per available choice.

{options}
    {option_value}: {option_name} {price}
{/options}

list

Alias of options (same row data, different naming style in templates).

{list}
    {option_name} ({option_value})
{/list}

Option-row variables available in options/list/select pairs:

  • option, option_value, option_name
  • selected (HTML attribute string), checked (HTML attribute string)
  • option_selected (1/0 boolean-style helper)
  • price, option_price
  • price:numeric, price_numeric
  • price:plus_tax, price:plus_tax_numeric, price_numeric:plus_tax
  • option_price:numeric, option_price_numeric
  • option_price:plus_tax, option_price_plus_tax
  • taxed_price, option_taxed_price
  • weight, option_weight
  • option_count, option_total_results, option_first_row, option_last_row
  • input_name, option_field, dynamic
  • custom columns from price modifier rows (if configured)

When the mapped modifier field includes an inventory column, {inventory} is available as one of those custom columns:

  • a positive value means that many units are available;
  • 0 means the option is out of stock;
  • a missing inventory column, null, or a blank value means unlimited inventory.

For the standard Price Modifiers fieldtype, this is the inventory of that option row. The modifier field must be the product channel’s mapped Inventory field for CartThrob to validate and reduce it. An entry with no option rows is unlimited. Once rows exist, a missing or unknown submitted selection is invalid.

The Price Modifiers Configurator tracks inventory on each complete generated configuration/SKU, not on the individual option-group choices rendered by item_options. For example, Large + Green can have inventory, but Green alone does not have one shared inventory value.

The option-row value is useful for labeling or disabling a choice, but the Add to Cart action remains authoritative and validates the submitted option and quantity on the server.

Configurator option groups use generated field names in this form:

configuration:CONFIGURATOR_FIELD_SHORT_NAME:OPTION_GROUP_SHORT_NAME

The generated {select} or {input} uses that complete name under item_options[...]. Keep it intact; posting only the Configurator field short name does not identify the customer’s individual group selections.

select

Generates a <select> wrapper automatically and parses your option markup inside it.

{select}
    <option {selected} value="{option_value}">{option_name} {price}</option>
{/select}

You can pass HTML attributes to generated controls in tag parameters:

  • class, id, onchange
  • attr:* for custom attributes

Examples:

{select class="input-medium" attr:data-role="item-option"}
    <option {selected} value="{option_value}">{option_name}</option>
{/select}

{input type="text" class="input-medium" attr:data-role="item-option-input"}

Conditionals

{if dynamic}

True when option field is dynamic (on-the-fly field, not a configured modifier field).

{if dynamic}...{/if}

{if option_field}

Checks whether option_field has a value.

{if option_field}...{/if}

{if option_label}

Checks whether option_label has a value.

{if option_label}...{/if}

{if options_exist}

True when the current option group has configured selectable values.

{if options_exist}...{/if}

{if allow_selection}

Useful for package/edit flows where some sub-item options are not editable.

{if allow_selection}...{/if}

Examples

Product page (entry mode)

{exp:cartthrob:item_options entry_id="{entry_id}"}
    {if dynamic}
        <label>{option_label}</label>
        {input}
    {if:else}
        {if options_exist}
            <label>{option_label}</label>
            {select}
                <option {selected} value="{option_value}">
                    {option_name}{if option_price_numeric != 0} +{option_price}{/if}
                </option>
            {/select}
        {/if}
    {/if}
{/exp:cartthrob:item_options}

For a Price Modifiers Configurator, the same loop outputs each generated group separately—for example Color and Size—and gives each control the required configuration:FIELD:GROUP name. Do not manually concatenate every option label or value into one <option>.

Product options with stock status

Use this inside the product’s add_to_cart_form:

{exp:cartthrob:item_options entry_id="{entry_id}" field="product_size"}
    <label>{option_label}</label>
    {select}
        <option
            value="{option_value}"
            {selected}
            {if inventory == "0"}disabled{/if}
        >
            {option_name}
            {if inventory == "0"} — Out of stock{/if}
            {if inventory} — {inventory} available{/if}
        </option>
    {/select}
{/exp:cartthrob:item_options}

A missing or blank {inventory} value deliberately remains selectable because only an explicit numeric value activates modifier stock tracking. An entry with no modifier rows is likewise unlimited. If every modifier option is explicitly unavailable, the product-level is_in_stock tag also reports the product as out of stock.

Cart update (row mode)

{exp:cartthrob:item_options row_id="{row_id}"}
    {if options_exist}
        <label>{option_label}</label>
        {select}
            <option {selected} value="{option_value}">
                {option_name}{if option_price_numeric != 0} +{option_price}{/if}
            </option>
        {/select}
    {if:else}
        <label>{option_label}</label>
        {input}
    {/if}
{/exp:cartthrob:item_options}

Display selected Configurator values in the cart

Use the current cart row ID and filter each option pair to its selected value:

{exp:cartthrob:item_options row_id="{row_id}" search:selected="yes"}
    <p>
        <strong>{option_label}:</strong>
        {if options_exist}
            {options}{option_name}{/options}
        {if:else}
            {option_value}
        {/if}
    </p>
{/exp:cartthrob:item_options}

For a Configurator, {option_label} is the group label such as Color or Size. The raw selected value is also exposed by cart_items_info as {item_options:configuration:FIELD:GROUP} when the generated name is known.

Package sub-item option editing

{package}
    <h5>{sub:title}</h5>
    {exp:cartthrob:item_options row_id="{sub:row_id}"}
        {if options_exist}
            {if allow_selection}
                <label>{option_label}</label>
                {select}
                    <option {selected} value="{option_value}">{option_name}</option>
                {/select}
            {if:else}
                {options}
                    {if selected}{option_label}: {option_name}{/if}
                {/options}
            {/if}
        {/if}
    {/exp:cartthrob:item_options}
{/package}

Filter to specific option fields

{exp:cartthrob:item_options row_id="{row_id}" field="product_size|product_color"}
    <label>{option_label}</label>
    {select}
        <option {selected} value="{option_value}">{option_name}</option>
    {/select}
{/exp:cartthrob:item_options}

Freeform option listing

{exp:cartthrob:item_options row_id="{row_id}"}
    {options}
        {if option_first_row}<strong>{option_field}</strong><br />{/if}
        {option_name} ({option_value}) {price}<br />
    {/options}
{/exp:cartthrob:item_options}