1

First off, I'd like to thank Jeremy for his help.

I have a set of add-on products that go along with my primary product. The options are a radio group.

I am using Multi-Add to tie everything together - and it's all working great. I'm able to add the primary and optional products to the cart.

Where I am hung up is, because I have a radio group - no matter which option I choose, I am always ending up with the last option being chosen. Which makes perfect sense since that's the last radio in the group that gets picked up.

Here is what I have so far:

... // items[1][qty] is a <select> input for the primary product ... {% for foo in products %} <div class="radio"> <label> <input type="radio" name="items[2][qty]" value="1"> {{ foo.title }} &ndash; {% if foo.defaultVariant.price == 0 %} Included with registration {% else %} {{ foo.defaultVariant.price|currency(cart.currency) }}{% endif %} </label> <input type="hidden" name="items[2][purchasableId]" value="{{ foo.defaultVariant.purchasableId }}"> </div> {% endfor %} 

As you can see whatever the last radio input is, will be the value that is picked up by Craft regardless of what the user has actually chosen.

So I thought since each radio is a product (with no variants), I could just use the loop index:

<input type="hidden" name="items[{{ loop.index }}][purchasableId]" value="{{ foo.defaultVariant.purchasableId }}"> 

Which works, but the loop will start at 1 each time. I am hung up on how I can start the loop at a specific number. Or, perhaps there is a better way?

If I were using checkboxes, I'd only have one option per product/input name.

I have also tried using a <select> element, but I get hung up on how I can offer a "No thanks" option.

<select name="items[2][purchasableId]" class="form-control required"> <option value="">Select</option> {% for foo in products %} <option value="{{ foo.defaultVariant.purchasableId }}"> {{ foo.title }} &ndash; {% if foo.defaultVariant.price == 0 %} Included with registration {% else %} {{ foo.defaultVariant.price|currency(cart.currency) }}{% endif %} </option> {% endfor %} </select> <input type="hidden" name="items[2][qty]" value="1"> 

Which also works well, but if the user does not choose an option, because I am passing a value of 1 with the hidden input, I get an error that I am attempting to use an invalid purchasable ID. Which also makes perfect sense.

I feel like I am so close, but just can't quite see clear enough to know what to do. Worst case I suppose I just listen for either a change/click event via javascript and update the qty value accordingly.

Thank you for any suggestions!

1 Answer 1

1

You definitely don't need JS here.

I'm a bit pushed for time, so this won't be an epic answer, but e.g. with your select, you should not be using a hidden field for the qty.

The select itself just sets the quantity value - either 1 if the option is chosen or no value if the option is not chosen....it really is as simple as:

<form> {# primary item - use whatever input you like for qty, or just do it in a hidden... #} <input type="hidden" name="items[9999][purchasableId" value="{{ mainproduct.purchasableId }}"> <input type="hidden" name="items[9999][qty]" value="1"> {# accessories #} {% for accessory in accessories %} <input type="hidden" name="items[loop.index][puchasableId]" value=="{{ accessory.purchasableId }}" <select name="items[loop.index][qty]"> <option value="1">Yes Please</option> <option value="0">No Thanks</option> </select> {% endfor %} </form> 

This will cause the following to be posted - items[0][purchasableId] = 45

and depending on the user choice, either

items[0][qty] = 1 or items[0][qty] = 0

...and multiAdd will just ignore this if the qty = 0.

The key thing to understand is the value of the index is totally irrelevant as long as it is the same for the purchasableId and the qty - it just acts to join the data together - you could literally send:

items['TrumpIsInsane'][purchasableId] = 45 items['TrumpIsInsane'][qty] = 1 

...and it should still work. So for the primary product I just use something like 9999 so that I am sure it won't conflict with any of the loop indexes (I'm not going to have 10000 accessories eh?) -> it's just a made up number.

For completeness, radios would only be slightly different:

<form> {# primary item - use whatever input you like for qty, or just do it in a hidden... #} <input type="hidden" name="items[9999][purchasableId" value="{{ mainproduct.purchasableId }}"> <input type="hidden" name="items[9999][qty]" value="1"> {# accessories #} {% for accessory in accessories %} <input type="hidden" name="items[loop.index][puchasableId]" value=="{{ accessory.purchasableId }}" <input type="radio" name="items[loop.index][qty]" value="1" checked> Yes Please<br> <input type="radio" name="items[loop.index][qty]" value=""> No Thanks<br> {% endfor %} </form> 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.