This is the documentation for LemonStand V1, which has been discontinued. You can learn more and upgrade your store here.

LemonStand Version 1 Has Been Discontinued

This documentation is for LemonStand Version 1. LemonStand is now offered as a cloud-based eCommerce platform.
You can try the new LemonStand and learn about upgrading here.

Displaying Extra Product Options

Extra options are free or paid options which could be added to a product. For example, gift wrap is a paid extra option.

You can output product extra options as a list of checkboxes below the product price. We recommend you create a separated partial for displaying extra options, instead of placing the corresponding code directly into the product page code, because partials help you to keep your product page code clean and easy to read.

Start with creating a new partial and assign it some meaningful name, for example shop:product_extra_options. The following code outputs a list of product extra options. Each extra option is presented with a checkbox and label.

<? foreach ($product->extra_options as $option):
  $control_name = 'product_extra_options['.$option->option_key.']';
  $posted_options = post('product_extra_options', array());
  $is_checked = isset($posted_options[$option->option_key]);
?>
  <input name="<?= $control_name ?>" 
    <?= checkbox_state($is_checked) ?> 
    id="extra_option_<?= $option->id ?>" value="1" type="checkbox"/>
    
  <label for="extra_option_<?= $option->id ?>"><?= h($option->description) ?></label>
  <? if ($option->price > 0): ?>
    + <?= format_currency($option->get_price($product)) ?>
  <? else: ?>
    free
  <? endif ?>
<? endforeach ?> 
{% for option in field(product, 'extra_options') %}
  {% set control_name = 'product_extra_options['~option.option_key~']' %}
  {% set posted_options = post('product_extra_options', []) %}
  {% set is_checked = posted_options[option.option_key] is defined %}
  <input name="{{ control_name }}" 
    {{ checkbox_state(is_checked) }} 
    id="extra_option_{{ option.id }}" value="1" type="checkbox"/>
  
  <label for="extra_option_{{ option.id }} ?>">{{ option.description }}</label>
  {% if option.price > 0 %}
    + {{ option.get_price(product)|currency }}
  {% else %}
    free
  {% endif %}
{% endfor %}

A product's extra options are contained in the $extra_options field of the $product object. Each element of the $extra_options field is an object having the $option_key field used for identifying an extra option by LemonStand, the $description field and the $price field.

For each extra option the example code outputs a checkbox. Please note the value of the NAME attribute of the INPUT element corresponding the checkbox. The NAME attribute value has the following format: product_extra_options[option_key]. You should not change this format. The checkbox_state function, used in the code example, keeps the checkboxes checked between page reloads. The product page could be reloaded if a visitor selects another grouped product (in the drop-down menu), or adds the product to the cart.

Depending on the option price the code outputs a price value or the word “free”, in case if an option has price equal to 0. For displaying currency values the format_currency function is used.

Once you finish developing the partial, you can output the list of product options on the product page, below the product price or in any other place, but inside the FORM element:

<? $this->render_partial('shop:product_extra_options') ?>  
{{ render_partial('shop:product_extra_options') }}

Grouping extra options

When you create extra options in the Administration Area you can specify a group name for each option. The group names can be used for grouping options on the Product Details page. The Shop_Product class has a method, which returns extra options grouped by matching group names: list_extra_option_groups(). Usage example:

<?
  $groups = $product->list_extra_option_groups();
  foreach ($groups as $group_name=>$options):
?>
  <h2><?= h($group_name) ?></h2>
    
  <? foreach ($options as $option):
    $control_name = 'product_extra_options['.$option->option_key.']';
    $posted_options = post('product_extra_options', array());
    $is_checked = isset($posted_options[$option->option_key]);
  ?>
    <input name="<?= $control_name ?>" 
      <?= checkbox_state($is_checked) ?> 
      id="extra_option_<?= $option->id ?>" value="1" type="checkbox"/>
      
    <label for="extra_option_<?= $option->id ?>"><?= h($option->description) ?></label>
    <? if ($option->price > 0): ?>
      + <?= format_currency($option->get_price($product)) ?>
    <? else: ?>
      free
    <? endif ?>
  <? endforeach ?> 
<? endforeach ?> 
{% set groups = product.list_extra_option_groups() %}
{% for group_name, options in groups %}
  <h2>{{ group_name }}</h2>
    
  {% for option in options %}
    {% set control_name = 'product_extra_options['~option.option_key~']' %}
    {% set posted_options = post('product_extra_options', []) %}
    {% set is_checked = posted_options[option.option_key] is defined %}
    <input name="{{ control_name }}" 
      {{ checkbox_state(is_checked) }}
      id="extra_option_{{ option.id }}" value="1" type="checkbox"/>
      
    <label for="extra_option_{{ option.id }} ?>">{{ option.description }}</label>
    {% if option.price > 0 %}
      + {{ option.get_price(product)|currency }}
    {% else %}
      free
    {% endif %}
  {% endfor %}
{% endfor %}

Displaying extra option images

In the Administration Area you can assign images to extra options. The Shop_ExtraOption class has the $images filed which allows you to fetch and display extra option images on a page. Example:

<? foreach ($option->images as $image): ?>
  <img src="<?= $image->getThumbnailPath(100, 'auto') ?>">
<? endforeach ?>
{% for image in option.images %}
  <img src="{{ image.getThumbnailPath(100, 'auto') }}">
{% endfor %}

Displaying extra options as radio buttons or drop-down lists

If you use the grouping feature described above you can display extra options as radio button sets or drop-down lists.

Drop-down lists

The following code displays extra options as dropdown menus.

Radio buttons

The following code displays extra options as radio buttons.

<?
  $groups = $product->list_extra_option_groups();
  $posted_options = post('product_extra_options', array());

  $group_index = 0;
  foreach ($groups as $group_name=>$options):
    $group_index++;
    $group_key = 'group_'.$group_index;
?>
  <h4><?= h($group_name) ?></h4>
  <? foreach ($options as $option):
    $is_checked = isset($posted_options[$group_key]) && $posted_options[$group_key] == $option->option_key;
    
  ?>
    <input name="product_extra_options[<?= $group_key ?>]"
      <?= radio_state($is_checked) ?>
      id="extra_option_<?= $option->id ?>"
      value="<?= $option->option_key ?>"
      type="radio"/>

    <label for="extra_option_<?= $option->id ?>">
      <?= h($option->description) ?>
      <?= ($option->price > 0) ? format_currency($option->price) : 'free' ?>
    </label>

    <br/>
  <? endforeach ?>
<? endforeach ?>
{% set groups = product.list_extra_option_groups() %}
{% set posted_options = post('product_extra_options', []) %}
{% set group_index = 0 %}
{% for group_name, options in groups %}
  {% set group_index = group_index+1 %}
  {% set group_key = 'group_'~group_index %}

  <h4>{{ group_name }}</h4>
  {% for option in options %}
    {% set is_checked = attribute(posted_options, group_key) == option.option_key %}
    
    <input name="product_extra_options[{{ group_key }}]"
      {{ radio_state(is_checked) }}
      id="extra_option_{{ option.id }}"
      value="{{ option.option_key }}"
      type="radio"/>

    <label for="extra_option_{{ option.id }}">
      {{ option.description }}
      {% if option.price > 0 %}{{ option.get_price(product)|currency }}{% else %}free{% endif %}
    </label>
  {% endfor %}
{% endfor %}

See also:

Next: Displaying a List of Related Products
Previous: Displaying Product Options
Return to Displaying a List of Products