Shopify quantity field not working when outputting multiple collections on the home page - e-commerce

I’m outputting two collections on my home page, with a quantity textbox and add to cart button for each product.
My problem is that the quantity field is not working - no matter what value I enter, only a single product is added to the cart. If I remove the quantity field from one of the collections, the other one starts working, so it’s only a problem when they are both there.
I feel like this should be very simple, but I’ve been banging my head against it for almost a day now, so I am admitting defeat!
Here’s the code from my liquid file (with most html removed for clarity):
{% for product in collections.mixr.products %}
<div class="product">
{{ product.title }}
{{ product.price | money }}
<form action="/cart/add" method="post" enctype="multipart/form-data" id="AddToCartForm{{ product.variants.first.id }}">
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
<input min="1" type="number" name="quantity" id="product-quantity-{{ product.variants.first.id }} value="1" />
<button type="button" name="add">
{{ 'products.product.add_to_cart' | t }}
</button>
</form>
</div>
{% endfor %}

Related

Update THIS value in an input with Vue3

I have an input field that I need to adjust when a button is clicked for either plus or negative. From documentation I've seen it would be something like a counter.
Where data would contain a variable counter and then I adjust that. However here I have multiple items on the same page. So if I have one "counter" then all would adjust. How can I do this with multiple input values? Code below:
{% for itemDetail in cart.items %}
<div>
{{ itemDetail.variant.option3 }} {{ itemDetail.variant.option1 }}:
<div class="flex-container" style="padding: 5px;">
<div class="flex-child">
<button type="button" class="qty-add-sub-2" #click="updateQty( {{ itemDetail.quantity }}, {{ itemDetail.id }}, 'min' )">
<span class="qty-minus">-</span>
</button>
</div>
<div style="flex: 2;">
<input class="qty-box-2" type="text" id="qty" name="qty" value="{{ itemDetail.quantity }}" >
</div>
<div class="flex-child">
<button type="button" class="qty-add-sub-2" #click="updateQty( {{ itemDetail.quantity }}, {{ itemDetail.id }}, 'add' )">
<span class="qty-add">+</span>
</button>
</div>
</div>
</div>
{% endfor %}
The cart.items loops in Ruby.
<input class="qty-box-2" type="text" id="qty" name="qty" value="{{ itemDetail.quantity }}" >
value="{{ itemDetail.quantity }}" is the quantity when the cart loads. However I need to put that when the button is clicked for either adding or minus.
I'm stuck on how to do this since each item is different. There could be 20 inputs on the page when it's calculated as cart.items is unlimited.
I attempted to add a method in my vue script by doing a v-model like so:
<input class="qty-box-2" type="text" id="qty" name="qty" v-model="updateValItem" #input="updateQty(`${ option.id }`, $event.target.value)" >
methods: {
updateValItem() {
return 10;
}
}
The value in the input displays: function () { [native code] }
Obviously I'm doing this wrong. Any idea how I can accomplish this?

Change "Add to Cart" to "Choose Option" for variant product in collection page Shopify

I have managed to add an Add to Cart button to my collection page in the Flex theme from Out of the Sandbox. However, for variant products, when you click on the Add to Cart, it automatically adds the default variant product to the Cart. I would like to change this so that instead of "Add to Cart" it displays "Choose Option" on the button and when clicked it takes you to the product page, where you then have to select the variant before adding this to the cart.
My code for the Add to Cart button is:
<form method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
<input type="submit" value="{% if product.variants.first.available%}Add to Basket{% else %}Out of Stock{% endif%}" class="button ajax-submit action_button button--add-to-cart" {% unless product.variants.first.available %}disabled{% endunless %} />
</form>
Can anyone help with this?
Thanks
Something like this would work:
{% if product.available == false %}
<span>Out of Stock</span>
{% elsif product.has_only_default_variant %}
<form method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
<input type="submit" value="Add to Basket" class="button ajax-submit action_button button--add-to-cart" />
</form>
{% else %}
Choose option
{% endif %}

how can I add products in a cart in Shopify by through a form in which only product name field is taken?

I have made a form page in Shopify in which following fields I have taken:-
<form action="/cart" method="post">
{% comment %}
Successful message
{% endcomment %}
{% if form.posted_successfully? %}
<p class="note form-success">
{{ 'contact.form.post_success' | t }}
</p>
{% endif %}
<div class="selection-wrapper">
{{ form.errors | default_errors }}
</div>
<div class="selection-wrapper">
<div class="grid">
<label for="Name" class="hidden-label">Name*</label>
<div class="grid__item medium-up--one-half">
<input type="text" style="width:100%;" name="first_name" id="FirstName" {% if form.first_name %}value="{{ form.first_name }}"{% endif %} required>
<label for="FirstName">{{ 'customer.register.first_name' | t }}</label>
</div>
<div class="grid__item medium-up--one-half">
<input type="text" style="width:100%;" name="last_name" id="LastName" {% if form.last_name %}value="{{ form.last_name }}"{% endif %}>
<label for="LastName">{{ 'customer.register.last_name' | t }}</label>
</div>
</div>
<br/>
<div class="grid">
<label for="Email" class="hidden-label">Email Address *</label>
<input type="email" style="width:100%;" id="Email" name="email" autocapitalize="off" value="{% if form.email %}{{ form.email }}{% elsif customer %}{{ customer.email }}{% endif %}">
</div>
<br/>
<div class="grid">
<label for="ContactFormPhone" class="hidden-label">Key Code Card Number*</label>
<input type="text" id="key_cord_card_no" style="width:100%;" name="keyCordCardNo" value="{{ form.keyCordCardNo }}" required>
</div>
<br/>
<div class="grid">
<label for="Product Name" class="hidden-label">Product Name*</label>
<input type="text" id="productName" style="width:100%;" name="product_name" value="{{ form.product_name }}" required>
the </div>
<div class="grid">
<p class="submit">
<input type="submit" class="button solid" value="submit">
</p>
</div>
</div>
</form>
I have to add product to cart by its name how can i do it?
How can I add products in a cart in Shopify by through a form in which only product name field is taken?
The short answer is - you can't add a product only by his name.
A product MUST have a variant ID in order for you to submit it to the cart.
The long answer is:
The only way to add a product by it's name is if you make an AJAX request to the product page and get the variant ID from there and submit that.
You always buy a variant in Shopify, even if a product doesn't have any variants it always have a defaut variant which is bought.
So if you plan to allow the customer to enter the product name in a text field you will need to make an AJAX request to the search page ( since I assume the customer won't be able to enter the exact name of the product in order for you to make a direct AJAX request ) and get the first result ( it will be best if you add the variant ID in the result item as a data attribute for example or some other way so that you don't need to make a second AJAX call to the product page itself ) and submit that to the cart.
Since the information given is so little I can't provide you any code or further instructions how to proceed.

Shopify Variant checkbox instead of dropdown

I'm trying to make it so that my variants are display like the following image instead of the default dropdown Shopify provides.
I'm currently using the following code, but it throws up an error when trying to add something to the basket. The error states "Parameter Missing or Invalid: Required parameter missing or invalid: id"
<form action="/cart/add" method="post" enctype="multipart/form-data">
{% for variant in product.variants %}
{% if variant.available == true %}
<fieldset class="group">
<ul class="checkbox">
<li>
<input type="checkbox" value="{{variant.id}}">
<label>{{ variant.title }} for {{ variant.price | money_with_currency }}</label>
</input>
</li>
</ul>
</fieldset>
{% else %}
<option disabled="disabled"> {{ variant.title }} - sold out!</option>
{% endif %}
{% endfor %}
<input type="submit" name="add" id="add" class="inpost-buy w-button" value="Add to Bag →"></input>
</form>
You are missing your name attribute for the checkbox.
It should have name="id". ( or if you are really determine to have checkboxes and not radio buttons it should be name="id[]" )
In addition, this is not a valid HTML code:
<input type="checkbox" value="{{variant.id}}">
<label>{{ variant.title }} for {{ variant.price | money_with_currency }}</label>
</input>
You can't have label inside of an input. The other way around will be OK.
And there is no point for this, since you are not using select any more:
<option disabled="disabled"> {{ variant.title }} - sold out!</option>

Using Shopify how can I capture the customer address on registration and have it saved as the default address for billing and shipping?

I am creating a shopify website and I am trying to customize it so when a user / customer registers they can put their address information in at the time and have it saved as their default address. Shopify currently has it so you register then it takes you to an account page where you have the option of adding the address in.
I have tried making form elements on the register page which works as in they show up and get data.
But I don't know how to make the form submit the address data to the default address data locations.
In other words I don't know how to make it store the address as the default address.
I have looked at the code for the actual address page and tried plugin in the id's names and form values in the registration section with no luck. I have tried using id's and names associated with the api customer reference with no luck as well. I can't really find documentation on the subject. There is a section on capturing additional information at registration but its capture as "Notes" not as an address.
Any help is greatly appreciated thank you.
I created a second account page (customers/account.new-address.liquid) with the address registration form:
{% assign formID = "" %}
{% if formInfo.id %}
{% assign formID = formInfo.id | prepend: "_"%}
{% endif %}
{% form 'customer_address', formInfo %}
<div class="input-wrapper">
<label for="customer_addresses_first_name{{ formID }}">{{ 'customer.addresses.first_name' | t }}</label>
<input type="text" name="address[first_name]" value="{{form.first_name}}" id="customer_addresses_first_name{{ formID }}" />
</div>
<div class="input-wrapper">
<label for="customer_addresses_last_name{{ formID }}">{{ 'customer.addresses.last_name' | t }}</label>
<input type="text" name="address[last_name]" value="{{form.last_name}}" id="customer_addresses_last_name{{ formID }}" />
</div>
<div class="input-wrapper">
<label for="customer_addresses_company{{ formID }}">{{ 'customer.addresses.company' | t }}</label>
<input type="text" name="address[company]" value="{{form.company}}" id="customer_addresses_company{{ formID }}" />
</div>
<div class="input-wrapper">
<label for="customer_addresses_address1{{ formID }}">{{ 'Street Address' }}</label>
<input type="text" name="address[address1]" value="{{form.address1}}" id="customer_addresses_address1{{ formID }}" />
</div>
<div class="input-wrapper">
<label for="customer_addresses_address2{{ formID }}">{{ 'Suburb' }}</label>
<input type="text" name="address[address2]" value="{{form.address2}}" id="customer_addresses_address2{{ formID }}" />
</div>
<div class="input-wrapper">
<label for="customer_addresses_city{{ formID }}">{{ 'customer.addresses.city' | t }}</label>
<input type="text" name="address[city]" value="{{form.city}}" id="customer_addresses_city{{ formID }}" />
</div>
{% if isNew %}
<div class="input-wrapper">
<label for="address-country">{{ 'customer.addresses.country' | t }}</label>
<div class="select-wrapper">
<div class="selected-text"></div>
<select id="address-country" name="address[country]" data-default="{{form.country}}">{{ country_option_tags }}</select>
</div>
</div>
<div class="input-wrapper" id="address-province-container" style="display:none">
<label for="address-province">{{ 'customer.addresses.province' | t }}</label>
<div class="select-wrapper">
<div class="selected-text"></div>
<select id="address-province" class="new-address-province" name="address[province]" data-default="{{form.province}}"></select>
</div>
</div>
{% else %}
<div class="input-wrapper">
<label for="address-country-{{form.id}}">{{ 'customer.addresses.country' | t }}</label>
<div class="select-wrapper">
<div class="selected-text"></div>
<select id="address-country-{{form.id}}" name="address[country]" data-default="{{form.country}}">{{ country_option_tags }}</select>
</div>
</div>
<div class="input-wrapper" id="address-province-container-{{ address.id }}" style="display:none">
<label for="address-province-{{ address.id }}">{{ 'customer.addresses.province' | t }}</label>
<div class="select-wrapper">
<div class="selected-text"></div>
<select id="address-province-{{ address.id }}" name="address[province]" data-default="{{form.province}}"></select>
</div>
</div>
{% endif %}
<div class="input-wrapper">
<label for="customer_addresses_zip{{ formID }}">{{ 'customer.addresses.zip' | t }}</label>
<input type="text" name="address[zip]" value="{{form.zip}}" id="customer_addresses_zip{{ formID }}" />
</div>
<div class="input-wrapper">
<label for="customer_addresses_phone{{ formID }}">{{ 'customer.addresses.phone' | t }}</label>
<input type="text" name="address[phone]" value="{{form.phone}}" id="customer_addresses_phone{{ formID }}" />
</div>
<div class="inline-input-wrapper">
{% capture defaultAddressID %}
{% if isNew %}
address_default_address_new
{% else %}
address_default_address{{ formID }}
{% endif %}
{% endcapture %}
<label for="{{ defaultAddressID | strip_newlines | strip}}">
{{ form.set_as_default_checkbox }}
<span class="inline-label">
{{ 'customer.addresses.set_as_default' | t }}
</span>
</label>
</div>
<div class="input-wrapper cta-container">
<input class="button" type="submit" id="submit{{ formID }}" value="{{ 'general.general.submit' | t }}">
{% unless isNew %}
<button class="cancel-edit button secondary">{{ 'customer.general.cancel' | t }}</button>
{% endunless %}
{% if customer.addresses.size > 0 and isNew %}
<button class="toggle-new-address button secondary">{{ 'customer.general.cancel' | t }}</button>
{% endif %}
</div>
{% endform %}
and then added the following code to the top of the account page (customers/account.liquid) so when a customer accesses the account page after registering and they have 0 addresses on their profile they are redirected to add an address:
{% if customer.addresses.size == 0 %}
<meta content="0; url=/account?view=new-address" http-equiv="refresh" />
{% endif %}
The ?view=new-address is the link to the alternative account page we created above.
This can't be done on the registration form without the use of a third-party app. The solution provided by Muaaz above is the only workaround I'm aware of, and it's a good solution if you're okay with using 2 forms.
You can follow Shopify's tutorial to collect address fields (or other custom fields), but these fields are saved only to the customer note. Address fields will not save as the default address.
The Customer Fields app allows you to collect address fields and save that data as the customer's default address. This is available on the Lite plan, which allows you to collect any standard Shopify fields during registration.