I am trying to create additional form fields in the checkout page (I am a Shopify Plus user) to collect more information.
I have created the following fields in Shipping Method - "Delivery Options", "Delivery Instructions" and "Preferred Delivery Date". When a customer fills in the fields, it makes an Ajax request via the Shopify API to set the field values as a cart attribute and note. It worked fine until I click proceed to "Payment Method", then the saved cart attributes and note returns an empty string/array.
I have had successful results during the testing phase, so I'm curious to see what went wrong.
Shipping Method cart.json:
Payment Method cart.json:
Can I get some help from someone, please?
HTML: <div class="hidden-fields"> <div class="streamthing_style_isolation section"> {% include 'deliverydate' %} </div> <div class="form-group section delivery_options"> <div class="layout-flex layout-flex--tight-vertical layout-flex--loose-horizontal layout-flex--wrap"> <h2 class="section__title layout-flex__item layout-flex__item--stretch" id="main-header" tabindex="-1"> {{ 'shopify.checkout.shipping_method.delivery_options' | t }} </h2> </div> <div class="layout-flex"> <div class="first-item"> <div class="radio__input"> <input class="input-radio" onchange="changeDeliveryOption()" type="radio" checked="checked" value="A signature is required." name="attributes[delivery_option]" id="checkout_signature_required"> </div> <label class="radio__label" aria-hidden="true" for="checkout_signature_required"> {{ 'shopify.checkout.shipping_method.a_signature_is_required_on_delivery' | t }} </label> </div> <!-- /radio-wrapper--> <div class=""> <div class="radio__input"> <input class="input-radio" onchange="changeDeliveryOption()" type="radio" value="Please leave the package without a signature." name="attributes[delivery_option]" id="checkout_leave_the_package"> </div> <label class="radio__label" aria-hidden="true" for="checkout_leave_the_package"> {{ 'shopify.checkout.shipping_method.please_leave_the_package_without_a_signature' | t }} </label> </div> <!-- /radio-wrapper--> </div> <div class="input-group delivery-instructions field--required"> <textarea onchange="deliveryInstructions()" class="form-control field__input" id="note_special_delivery" name="attributes[special_delivery]" placeholder="{{ 'shopify.checkout.shipping_method.special_delivery_instructions' | t }}"></textarea> </div> </div> </div> Javascript: <script type="text/javascript"> let fieldShipping = document.querySelector('[data-step="shipping_method"] .step__sections .section--shipping-method') if (fieldShipping !== null) { // variables let html, baseElement = document.querySelector(".section--billing-address .section__content .content-box .content-box__row") // markup html = `<div class="radio-wrapper content-box__row" data-same-billing-address>` html += `<div class="radio__input">` html += `<input class="input-radio" data-backup="different_billing_address_false" data-trekkie-id="same_billing_address_field" type="radio" value="false" checked="checked" name="checkout[different_billing_address]" id="checkout_no_physical_billing_false_false" />` html += `</div>` html += `<label class="radio__label content-box__emphasis" for="checkout_no_physical_billing_false"> No physical billing required </label>` html += `</div>` // load if (baseElement) { baseElement.insertAdjacentHTML("beforeBegin", html) } // Methods cartUpdate = async function (data) { try { const response = await fetch('/cart/update.json', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: data }) }) return response.json() } catch (e) { console.log(e) } } cartNoteUpdate = async function (data) { console.log('updating') try { const response = await fetch('/cart/update.json', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ note: data }) }) return response.json() } catch (e) { console.log(e) } } debounce = function (func, wait, immediate) { let timeout return function executedFunction () { let context = this let args = arguments let later = function() { timeout = null if (!immediate) func.apply(context, args) } let callNow = immediate && !timeout clearTimeout(timeout) timeout = setTimeout(later, wait) if (callNow) func.apply(context, args) } } // Data $(document).on(`page:load page:change`, async function() { console.log('Shipping method loaded.') let currentYear = document.querySelector('.current-year') currentYear.innerHTML = (new Date()).getFullYear() fieldShipping.insertAdjacentHTML("beforeBegin", document.querySelector('.hidden-fields').innerHTML) document.querySelector('.hidden-fields').innerHTML = '' let field1 = document.querySelector('.step__sections #checkout_signature_required') let field2 = document.querySelector('.step__sections #checkout_leave_the_package') if (field1 && field2) { let delivery_option = document.querySelector('input[name="attributes[delivery_option]"]:checked').value if (delivery_option) { cartUpdate({'delivery_option': delivery_option}) } changeDeliveryOption = function () { cartUpdate({'delivery_option': document.querySelector('input[name="attributes[delivery_option]"]:checked').value}) } } deliveryInstructions = function () { cartNoteUpdate(document.getElementById('note_special_delivery').value) } // add content let dateField = document.querySelector('.step__sections #streamthing_delivery_date_picker') if (dateField) { let response = await fetch('/cart.json', { method: 'GET', mode: 'same-origin', credentials: 'same-origin', cache: 'no-cache' }).then(cart => cart.json()) if (response.note) { document.getElementById('note_special_delivery').value = response.note } } }); } </script>
User | Count |
---|---|
25 | |
22 | |
22 | |
19 | |
12 |