1

I currently have price, sku and variant title swapping when clicking between variants on a products details page.

This works with AlpineJS and looks something this. https://codepen.io/amasci/pen/PoWxbPX

<div class="flex-1 p-8" x-data="{
 price: '{{- product.defaultPriceAsCurrency|trim -}}',
 variant: '{{- product.defaultVariant.title|trim -}}',
 sku: '{{- product.defaultSku|trim -}}'
}"

<div class="flex flex-wrap items-center pb-6 mb-12 space-x-8 border-b border-gray-200">
  <div class="text-2xl text-blue-500" x-text="price"></div>
  <div class="mt-1 text-sm  flex items-center space-x-2">
    <span class="text-blue-200" x-text="variant"></span>
    <span class="mx-1 text-gray-200">&bull;</span>
    <span class="text-blue-200" x-text="sku"></span>
  </div>
</div>

{% for variant in product.variants %}
<label class="relative transition cursor-pointer variant-option choice-button focus-within:ring-1 focus-within:ring-offset-2 focus-within:ring-blue-500"
       for="{{ variant.id }}"
>
  <input type="radio"
         @click="price='{{- variant.priceAsCurrency|trim -}}', variant='{{- variant.title|trim -}}', sku='{{- variant.sku|trim -}}'"
         id="{{ variant.id }}"
         name="purchasables[1][id]"
         value="{{ variant.id }}"
         class="sr-only"
    {{ loop.first ? 'checked' }}
  >
  <span class="block py-2 px-4 text-sm text-gray-400 border border-gray-300 transition variant-label hover:border-gray-400 hover:text-gray-500">
    {{ variant.title }}
  </span>
</label>
{% endfor %}

However, I have come to now add some functionality for sale prices. Whereby I would like to show the Price with a strike and the new sale price.

{% if variant.onSale %}
  <del class="text-sm text-gray-500">{{ variant.priceAsCurrency }}</del>
  <br>{{ variant.salePriceAsCurrency }}
{% else %}
  {{ variant.priceAsCurrency }}
{% endif %}

What is the best way to adopt my code to do this? I cannot pass in the html code to alpine.

Should I just loop the variants and output the code and then show/hide the right block based on which radio is selected or is there a better approach?

1

So, I actually decided a slightly different approach in the end and not sure if it is better or less performant, but I feel gives me a little more flexibility. Basically, more like a 'tabbed' approach that shows the right div based on the option selected. This allows me to be a little more flexible with the information and layout I want in that area of the page.

Here is the final code:

{% block productVariantSelected %}
  {# Price and Variant SKU #}
  {% for variant in product.variants %}
    <div x-show="selectedVariant === {{ variant.id }}" class="mt-3">
      <div class="flex flex-wrap items-center pb-2 mb-8 space-x-8 border-b border-gray-200">
        {% if variant.onSale %}
          <div class="flex items-center">
            <del class="text-sm text-gray-500 mr-2">{{ variant.priceAsCurrency }}</del>
            <span class="text-blue-500 text-2xl font-semibold">{{ variant.salePriceAsCurrency }}</span>
          </div>
        {% else %}
          <span class="text-blue-500 text-2xl font-semibold">{{ variant.priceAsCurrency }}</span>
        {% endif %}
        <div class="mt-1 text-sm  flex items-center space-x-2">
          <span class="text-blue-200">{{ variant.title }}</span>
          <span class="mx-1 text-gray-200">&bull;</span>
          <span class="text-blue-200">{{ variant.sku }}</span>
        </div>
      </div>
    </div>
  {% endfor %}
{% endblock %}

<h3 class="mb-3 text-gray-700 uppercase">{{ variantHeading|default('Options') }}</h3>
<div class="flex flex-wrap items-center space-x-3 mb-12">
  {% for variant in product.variants %}
    <label class="relative transition cursor-pointer variant-option choice-button focus-within:ring-1 focus-within:ring-offset-2 focus-within:ring-blue-500"
           for="{{ variant.id }}"
    >
      <input type="radio"
             @click="selectedVariant={{ variant.id }}, variantTitle='{{- variant.title|trim -}}'"
             id="{{ variant.id }}"
             name="purchasables[1][id]"
             value="{{ variant.id }}"
             class="sr-only"
        {{ loop.first ? 'checked' }}
      >
      <span class="block py-2 px-4 text-sm text-gray-400 border border-gray-300 transition variant-label hover:border-gray-400 hover:text-gray-500">
    {{ variant.title }}
  </span>
    </label>
  {% endfor %}
  
  <div class="text-sm text-gray-400 font-light mb-0 self-center mt-2">
    Can’t find the right size? <a href="{{ siteUrl('contact') }}" class="text-blue-500 underline hover:text-sea-500">Contact Us</a>
  </div>
</div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.