PhoenixKit.Modules.Shop.Web.OptionState (phoenix_kit v1.7.71)

Copy Markdown View Source

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_inputs
  • selected_option_values -> state.selected
  • original_option_values -> state.available
  • metadata["_price_modifiers"] -> state.modifiers
  • option_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

t()

@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

add_new_option(state, option_key, value)

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")

add_value(state, option_key, value)

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")

get_all_values(state, option_key)

Gets all values available for an option (schema + custom added).

Examples

OptionState.get_all_values(state, "size")
# => ["S", "M", "L", "XL"]

get_modifier(state, option_key, value)

Gets the modifier value for an option/value pair.

Examples

OptionState.get_modifier(state, "size", "M")
# => "5.00"

get_selected_values(state, option_key, all_values)

Gets selected values for an option (or all if not explicitly set).

Examples

OptionState.get_selected_values(state, "size", ["S", "M", "L"])
# => ["M", "L"]

has_custom_selection?(state, option_key)

Checks if option has custom selection (not all values selected).

Examples

OptionState.has_custom_selection?(state, "size")
# => true

new(product, option_schema)

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: %{}
# }

remove_value(state, option_key, value)

Removes a value from an option.

Removes from available, selected, and any associated modifiers.

Examples

state = OptionState.remove_value(state, "size", "XL")

to_metadata(state)

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"}}
# }

toggle_value(state, option_key, value, all_values)

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"])

update_modifier(state, option_key, value, modifier_value)

Updates a price modifier for a specific option value.

Examples

state = OptionState.update_modifier(state, "size", "M", "5.00")

update_new_input(state, option_key, value)

Updates the new value input for an option key.

Examples

state = OptionState.update_new_input(state, "size", "XL")

value_selected?(state, option_key, value, all_values)

Checks if a value is currently selected for an option.

Examples

OptionState.value_selected?(state, "size", "M", ["S", "M", "L"])
# => true