Add Product Item Details to Property Line Item that continues to show on Checkout Page

nuwud
Shopify Partner
20 1 0

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.

Kindest Regards,
Nuwud
Replies 2 (2)
nuwud
Shopify Partner
20 1 0

Update.
This is what I have right now.
My Javascript&colon;

// 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. 

Kindest Regards,
Nuwud
nuwud
Shopify Partner
20 1 0

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.


Kindest Regards,
Nuwud