2

We have a client who sells bespoke cookers. Cookers have numerous colour choices, and also trim options. However not all trim options are available with all colours.

For example the X range has Green, Blue, and Black for colour, and Brushed, Chrome and Brass for trim. Black only has Brushed and Chrome available, but Green and Blue have all three.

I considered using the limit stock row and setting the stock level to 0 (since none of the others are stock tracked since they're build to order) but couldn't see a way to wrap the modifier options in a track_stock conditional, it seems it only works on a product wide basis. I also thought about using the SKU (eg if the SKU is empty, disable the option) but that doesn't seem to work either.

Ideally the code would be something along these lines

<select id="{modifier_input_name}" name="{modifier_input_name}">
    {modifier_options}
        <option value="{option_id}" {if SKU/TRACK_STOCK/ETC == ""}disabled{/if}>
            {option_name} {if price_mod_val} ({price_mod}) {/if}
        </option>
    {/modifier_options}
</select>

Basically, is there a way to disable the options if the variant is unavailable?

1 Answer 1

5

Similar question here, I left the teaser for the out of stock bit, but nobody picked up on it :(

I wrote a plugin that pulls back all the options for multiple modifiers, you can then use JavaScript to query the information and change what options are available for each modifier. So when they select the colour, you can look at what trims are in stock and hide those not in stock.

The template code:

{modifiers}
     {if "{modifier_name}" != ""}
         {if {exp:store_options:total entry_id="{entry_id}" parse="inward"} <= 1}
             <p>{modifier_name}: {modifier_options}{option_name} {/modifier_options}</p>
                 <input type="hidden" name="{modifier_input_name}" value="{modifier_options}{option_id}{/modifier_options}">
         {if:else}
             <label>
                 <select id="{modifier_name}" name="{modifier_input_name}" class="dropdown required" tabindex="1">
                    <option value="">-- Select {modifier_name} --</option>
                    {modifier_options}
                        <option value="{option_id}" {if "{modifier_name}" == "Colour"} itemprop="color"{/if}>{option_name}</option>
                    {/modifier_options}
                </select>
            </label>
        {/if}
    {/if}
{/modifiers}

<ol id="stock-lookup">
    {exp:store_options:all entry_id="{entry_id}"}
        <li data-colour="{Colour}" data-size="{Size}" data-stock="{stock}">{if no_stock} (out of stock){/if}</li>
    {/exp:store_options:all}
</ol>

In the above, I'm allowing 2 modifiers Colour and Size. The OL list #stock-lookup is a hidden element to store the lookup information I need - I expect this could be changed to a JavaScript array if preferred. For the select output I'm checking for a single option - I don't then want to show a select menu, but need to have a hidden field to pass with the form submission.

Then the JavaScript function called upon changing either of the select boxes. $formElement being the JQuery object for the select they selected and "Label" being the value of the item selected - used for matching with the product options:

function checkStockLabels($formElement, label) {
    //###   Update the [other] select box with only the available options (instead of all)    ###
    if ($formElement.attr("id") == "Colour") {
        if ($(".product-desc #Size").length) {
            //###   Check the Size list to show message on unavailable options   ###
            $("#dk_container_Size li a span").remove("span");
            $('#stock-lookup li[data-colour="'+label+'"]').each(function( index ) {
                sizeRef = $("#dk_container_Size li a:contains('"+$(this).attr("data-size")+"')").attr('data-dk-dropdown-value');
                $("#dk_container_Size li a:contains('"+$(this).attr("data-size")+"')").append('<span>'+$(this).html()+'</span>');
                defaultLabel = $("#dk_container_Size .dk_options a:first").html();
                if ($("#dk_container_Size .dk_label").html() != defaultLabel || $("#dk_container_Size li a").length <= 2) {
                    $("#dk_container_Size li a[data-dk-dropdown-value='"+sizeRef+"']").click();
                }
            });
        }

    } else if ($formElement.attr("id") == "Size") {
        if ($("#Colour").length) {
            //###   Check the Colour list to show message on unavailable options   ###
            $("#dk_container_Colour li a span").remove("span");
            $('#stock-lookup li[data-size="'+label+'"]').each(function( index ) {
                $("#dk_container_Colour li a:contains('"+$(this).attr("data-colour")+"')").append('<span>'+$(this).html()+'</span>');
            });
        }
    }
}//###   End of checkStockLabels function   ###

To add to the confusion of JS code, I'm using DropKick as a Select skinning replacement. The spans are the inserted "out of stock" text - because child elements are not valid in a select - option, I'm solving this due to dropkick converting it to an li. But you would simply be removing the select option completely, so no need to insert the spans or remove them, or better still disable and hide.

If you need more clarification, let me know and I'll expand upon the above.

ExpressionEngine Expresso Store Options Plugin can be found here. Note: Not tested on latest Expresso Store version!

2
  • Peter, is there any chance you could show me a sample of where this was implemented? I have this exact issue to solve and I want to get your plugin in place.
    – Aaron
    Feb 23, 2015 at 10:27
  • Hi @aaron, sorry wasn't alerted to this comment - please open a support ticket on fresh-dev.com and I'll help you. Mar 24, 2016 at 20:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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