Encapsulates option-related state for product form.
This module manages all option-related data in a single struct, replacing the multiple assigns previously used in product_form.ex:
new_value_inputs->state.new_inputsselected_option_values->state.selectedoriginal_option_values->state.availablemetadata["_price_modifiers"]->state.modifiersoption_schema->state.schema
Usage
# Initialize state from product and schema
state = OptionState.new(product, option_schema)
# Toggle a value selection
state = OptionState.toggle_value(state, "size", "M", ["S", "M", "L"])
# Add a new custom value
state = OptionState.add_value(state, "size", "XL")
# Remove a value
state = OptionState.remove_value(state, "size", "XL")
# Update a price modifier
state = OptionState.update_modifier(state, "size", "M", "5.00")
# Convert back to metadata for saving
metadata = OptionState.to_metadata(state)
Summary
Functions
Adds a completely new option with an initial value.
Adds a new value to an option.
Gets all values available for an option (schema + custom added).
Gets the modifier value for an option/value pair.
Gets selected values for an option (or all if not explicitly set).
Checks if option has custom selection (not all values selected).
Creates a new OptionState from a product and option schema.
Removes a value from an option.
Converts the state back to a metadata map for saving.
Toggles a value selection on/off.
Updates a price modifier for a specific option value.
Updates the new value input for an option key.
Checks if a value is currently selected for an option.
Types
@type t() :: %PhoenixKit.Modules.Shop.Web.OptionState{ available: %{required(String.t()) => [String.t()]}, modifiers: %{required(String.t()) => %{required(String.t()) => String.t()}}, new_inputs: %{required(String.t()) => String.t()}, schema: [map()], selected: %{required(String.t()) => [String.t()]} }
Functions
Adds a completely new option with an initial value.
Returns {:ok, state} or {:error, reason}.
Examples
{:ok, state} = OptionState.add_new_option(state, "material", "Wood")
Adds a new value to an option.
The value is added to both available and selected maps.
Returns {:ok, state} or {:error, reason}.
Examples
{:ok, state} = OptionState.add_value(state, "size", "XL")
{:error, "already exists"} = OptionState.add_value(state, "size", "M")
Gets all values available for an option (schema + custom added).
Examples
OptionState.get_all_values(state, "size")
# => ["S", "M", "L", "XL"]
Gets the modifier value for an option/value pair.
Examples
OptionState.get_modifier(state, "size", "M")
# => "5.00"
Gets selected values for an option (or all if not explicitly set).
Examples
OptionState.get_selected_values(state, "size", ["S", "M", "L"])
# => ["M", "L"]
Checks if option has custom selection (not all values selected).
Examples
OptionState.has_custom_selection?(state, "size")
# => true
Creates a new OptionState from a product and option schema.
Examples
product = %Product{metadata: %{"_option_values" => %{"size" => ["M", "L"]}}}
schema = [%{"key" => "size", "type" => "select", "options" => ["S", "M", "L"]}]
state = OptionState.new(product, schema)
# => %OptionState{
# schema: [...],
# available: %{"size" => ["S", "M", "L"]},
# selected: %{"size" => ["M", "L"]},
# modifiers: %{},
# new_inputs: %{}
# }
Removes a value from an option.
Removes from available, selected, and any associated modifiers.
Examples
state = OptionState.remove_value(state, "size", "XL")
Converts the state back to a metadata map for saving.
Returns a map with _option_values and _price_modifiers keys.
Empty maps are omitted.
Examples
state = %OptionState{
selected: %{"size" => ["M", "L"]},
modifiers: %{"size" => %{"M" => "5.00"}}
}
OptionState.to_metadata(state)
# => %{
# "_option_values" => %{"size" => ["M", "L"]},
# "_price_modifiers" => %{"size" => %{"M" => "5.00"}}
# }
Toggles a value selection on/off.
If the value is selected, it will be deselected. If not selected, it will be selected.
The all_values parameter is used to determine when all values are selected
(in which case the key is removed from selected map).
Examples
state = OptionState.toggle_value(state, "size", "M", ["S", "M", "L"])
Updates a price modifier for a specific option value.
Examples
state = OptionState.update_modifier(state, "size", "M", "5.00")
Updates the new value input for an option key.
Examples
state = OptionState.update_new_input(state, "size", "XL")
Checks if a value is currently selected for an option.
Examples
OptionState.value_selected?(state, "size", "M", ["S", "M", "L"])
# => true