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.
Live example
Shipping Method cart.json:
Payment Method cart.json:

Can I get some help from someone, please?
1 Like
Not seeing a delivery date option.
It’s on the Checkout page, under Shipping Method. Thanks!
Can I get a reply from someone please?
Will you please share code?
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>
I am also facing the same issue. Can someone check and take a look?