Skip to content

Instantly share code, notes, and snippets.

@influxweb
Created July 18, 2019 21:03
Show Gist options
  • Save influxweb/2c4b0689d67bc5212b2f7f311a307b5d to your computer and use it in GitHub Desktop.
Save influxweb/2c4b0689d67bc5212b2f7f311a307b5d to your computer and use it in GitHub Desktop.
ReadyTheme Enhancement: State/Province Datalist
<!-- This is an extract from OCST: Customer Information -->
...
<mvt:do name="l.state_datalist_count" file="g.Module_Library_DB" value="StateList_Load_All(l.state_datalist)"/>
<mvt:assign name="g.StateDatalist" value="l.state_datalist"/>
<mvt:if expr="g.States_Empty">
<li class="c-form-list__item o-layout__item u-width-4--m &mvte:global:ShipState_Row;">
<label class="c-form-label u-text-medium u-color-gray-40 is-required u-font-tiny" for="l-ShipState">State/Province</label>
<input id="l-ShipState" class="c-form-input c-form-input--large" type="text" name="ShipState" value="&mvte:global:ShipState;" &mvt:shipping_required;>
</li>
<mvt:else>
<li class="c-form-list__item o-layout__item u-width-4--m &mvte:global:ShipState_Row;">
<label id="ShipStateLabel" class="c-form-label u-text-medium u-color-gray-40 is-required u-font-tiny" for="ShipStateSelect">State/Province</label>
<input id="ShipStateSelect" type="hidden" name="ShipStateSelect" value="&mvte:global:ShipStateSelect;" aria-labelledby="ShipStateLabel">
<input id="ShipState" class="c-form-input c-form-input--large" data-stateDatalist list="ShipStateDatalist" name="ShipState" placeholder="Select or Type" type="text" value="&mvte:global:ShipState;" &mvt:shipping_required;>
<datalist id="ShipStateDatalist">
<mvt:foreach iterator="StateData" array="global:StateDatalist">
<option value="&mvt:StateData:code;">&mvt:StateData:name;</option>
</mvt:foreach>
</datalist>
</li>
</mvt:if>
...
...
<mvt:if expr="g.States_Empty">
<li class="c-form-list__item o-layout__item u-width-4--m &mvte:global:BillState_Row;">
<label class="c-form-label u-text-medium u-color-gray-40 is-required u-font-tiny" for="l-BillState">State/Province</label>
<input id="l-BillState" class="c-form-input c-form-input--large" type="text" name="BillState" value="&mvte:global:BillState;" &mvt:billing_required;>
</li>
<mvt:else>
<li class="c-form-list__item o-layout__item u-width-4--m &mvte:global:BillState_Row;">
<label id="BillStateLabel" class="c-form-label u-text-medium u-color-gray-40 is-required u-font-tiny" for="BillStateSelect">State/Province</label>
<input id="BillStateSelect" type="hidden" name="BillStateSelect" value="&mvte:global:BillStateSelect;" aria-labelledby="BillStateLabel">
<input id="BillState" class="c-form-input c-form-input--large" data-stateDatalist list="BillStateDatalist" name="BillState" placeholder="Select or Type" type="text" value="&mvte:global:BillState;" &mvt:billing_required;>
<datalist id="BillStateDatalist">
<mvt:foreach iterator="StateData" array="global:StateDatalist">
<option value="&mvt:StateData:code;">&mvt:StateData:name;</option>
</mvt:foreach>
</datalist>
</li>
</mvt:if>
...
(function () {
'use strict';
/**
* This function is an enhancement to the `datalist` State/Province replacement.
* Since a customer can type a value in the input, this will check if the entered value
* matches one of the output values or text entries. If so, it passes the value back to
* ensure proper functionality with shipping modules, i.e. 2 letter abbreviations for
* US and Canada. Otherwise, it the entry is used as typed.
* @type {NodeListOf<Element>}
*/
let stateDatalist = document.querySelectorAll('[data-stateDatalist]');
function checkOption(entry, list) {
let datalist = document.querySelector('#' + list);
let datalistOptions = datalist.querySelectorAll('option');
let value = '';
for (let i = 0; i < datalistOptions.length; i++) {
let option = datalistOptions[i];
if (entry.toLowerCase() === option.value.toLowerCase() || entry.toLowerCase() === option.text.toLowerCase()) {
value = option.value;
}
}
return value;
}
if (stateDatalist.length > 0) {
for (let i = 0; i < stateDatalist.length; i++) {
let stateSelect = stateDatalist[i];
stateSelect.addEventListener('blur', function () {
let thisDatalist = stateSelect.getAttribute('list');
let checkValue = checkOption(stateSelect.value, thisDatalist);
if (checkValue) {
stateSelect.value = checkValue;
stateSelect.previousElementSibling.value = checkValue;
}
else {
stateSelect.previousElementSibling.value = stateSelect.value;
}
});
}
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment