Liquid, JavaScript, themes, sales channels
I am using Shopify 2.0 with the Symmetry theme.
I need to add my Variant Global Status Metafield to the property line items that show up for a product on the checkout page without having to use authentication.
I am having little luck using AJAX API to add some info to a product in checkout.
I was able to pass along line item properties with a separate add-on item product, but it won't seem to work with the current product variant.
Here is the script I have thus far:
// Wait until the document is fully loaded before executing the script $(document).ready(function() { // Retrieve the product JSON data embedded within the element with the ID 'ProductJson-product-template' var productJson = $('#ProductJson-product-template').html(); if (productJson) { // Parse the product JSON data to a JavaScript object var product = JSON.parse(productJson); // Get the first variant of the product (Note: Adjust this if needed to get the 'current' variant) var currentVariant = product.variants[0]; if (currentVariant) { // Extract various details about the current variant var variantId = currentVariant.id; var variantName = currentVariant.title; var variantPrice = currentVariant.price; var variantSku = currentVariant.sku; // Log the extracted details to the console console.log('Variant ID: ', variantId); console.log('Variant Name: ', variantName); console.log('Variant Price: ', variantPrice); console.log('Variant SKU: ', variantSku); } } }); // Event listener for the click event on the submit button inside the form with the class 'product-purchase-form' and method 'post' $(".product-purchase-form[method='post'] button[type='submit']").on('click', function (event) { // Prevent the default submit action to handle it with AJAX event.preventDefault(); // Find the closest form element to the clicked button var form = $(this).closest('form'); // Retrieve the variant ID and product ID from the respective input fields within the form var variantId = $('input[name="id"]', form).val(); var productId = $('input[name="product_id"]', form).val(); // Note: You might need to add this input field in your liquid file // Step 1: AJAX request to fetch the variant's metafields based on the product and variant IDs $.ajax({ url: '/admin/api/2023-07/products/'+productId+'/variants/'+variantId+'/metafields.json', method: 'GET', dataType: 'json', success: function(response) { // Step 2: Find the 'status' metafield within the global namespace from the response var statusMetafield = response.metafields.find(metafield => metafield.key === 'status' && metafield.namespace === 'global'); if(statusMetafield) { // Step 3: Create a hidden input element to hold the value of the 'status' metafield var hiddenInput = $('<input>').attr({ type: 'hidden', name: 'properties[_Status]', value: statusMetafield.value }); // Step 4: Append the created hidden input to the form form.append(hiddenInput); } // Step 5: Trigger the default submit action of the button (after removing the current click event handler to prevent a loop) form.find("button[type='submit']").off('click').trigger('click'); }, error: function(xhr, textStatus, error) { // Log an error message to the console if the AJAX request fails console.error('Error fetching metafield: ', textStatus, error); // In case of error, still allow the form to be submitted by triggering the default submit action of the button (after removing the current click event handler to prevent a loop) form.find("button[type='submit']").off('click').trigger('click'); } }); });
I put this in my product page's liquid section:
{% assign status_metafield = product.metafields.global.status %}
And I put this in my buy-button (add to cart) class on the product page:
{% endif %} {% if variant.metafields.global.status %} <input type="hidden" name="properties[_Status]" value=" {{ variant.metafields.global.status }}" /> {% endif %}
Any help would be greatly appreciated.
Update.
This is what I have right now.
My Javascript:
// Wait until the DOM is fully loaded before executing the script
$(document).ready(function() {
// Variable to store the variant ID
var variantId;
// Retrieve the product JSON data embedded within the element with the ID 'ProductJson-product-template'
var productJson = $('#ProductJson-product-template').html();
// Check if the productJson variable contains any data
if (productJson) {
// Parse the JSON data to a JavaScript object
var product = JSON.parse(productJson);
// Get the first variant of the product (Adjust this if needed to get the 'current' variant)
var currentVariant = product.variants[0];
// Check if the currentVariant object exists
if (currentVariant) {
// Extract various details about the current variant and store them in variables
variantId = currentVariant.id;
var variantName = currentVariant.title;
var variantPrice = currentVariant.price;
var variantSku = currentVariant.sku;
// Log the extracted details to the console for debugging purposes
console.log('Variant ID: ', variantId);
console.log('Variant Name: ', variantName);
console.log('Variant Price: ', variantPrice);
console.log('Variant SKU: ', variantSku);
}
}
// Event listener for the form submission on the element with ID 'product'
$('#product').on('submit', function(e) {
// Prevent the form from submitting the traditional way
e.preventDefault();
// Check if the variantId variable has been set (i.e., is not undefined)
if(variantId) {
// Make an AJAX POST request to add the item to the cart
$.ajax({
type: 'POST',
url: '/cart/add.js',
data: $(this).serialize(), // Serialize the form data for the AJAX request
dataType: 'json', // Expect a JSON response
success: function() {
// On success, redirect the user to the cart page
window.location.href = '/cart';
},
error: function(xhr, textStatus, error) {
// On error, display an alert with the error details
alert('Error adding item to cart: ' + textStatus + ' - ' + error);
}
});
} else {
// If variantId is not found, log an error message to the console
console.error("Variant ID not found.");
}
});
});
My Liquid:
{% if variant.metafields.global.status %}
<input type="hidden" name="properties[Metafield Status]" value="{{ variant.metafields.global.status }}" />
{% endif %}
I tried that and it still does not work.
Ok, since those and subsequent efforts failed and Shopify isn't budging on the checkout thing, I think I found an off-the-wall solution inspired by my embroidery product add-on script which does, in fact, tack on form input values onto the product details that continue to carry through to checkout.
I am going to try a method that involves creating a product called Backorder with a style variant of Message for $0.00.
Then have a hidden input form field or a checkmark input to acknowledge that this will be a Backordered product. Loop that through a Javascript to add-on the product along with product line-item-properties same as with the embroidery product add-ons.
Hide the price with some script.
It could work.
The downside is I find I have to scroll down to see additional items sometimes.
So, maybe this isn't the brilliant solution I think it is.
It seems absolutely ridiculous to have to pay 2000 per month to maybe be able to add a simple message to a checkout page item that alerts the customer as to the backorder situation and to have it pass to Shipstsation for the owner to stay ware. I have it on the cart. I don't need more help with that. I found a "million" posts for that and figured that out pretty quickly.
User | RANK |
---|---|
38 | |
29 | |
13 | |
12 | |
9 |
On our Shopify Expert Marketplace, you can find many trusted third party developers and fr...
By Arno Nov 27, 2023You've downloaded the Search & Discovery app from the Shopify App store, and as you're ...
By Skye Nov 8, 2023The year-end shopping season is just around the corner. Is a flash sale on your radar? Are...
By Jasonh Nov 6, 2023