{% import "_includes/forms" as forms %} {% do view.registerTranslations('commerce', [ "Example" ]) %}
{{ forms.textField({ first: true, label: "Name"|t('commerce'), instructions: "What this tax zone will be called in the control panel."|t('commerce'), id: 'name', name: 'name', value: taxZone is defined ? taxZone.name, errors: taxZone is defined ? taxZone.getErrors('name'), autofocus: true, required: true }) }} {{ forms.textField({ label: "Description"|t('commerce'), instructions: "Describe this tax zone."|t('commerce'), id: 'description', name: 'description', value: taxZone is defined ? taxZone.description, errors: taxZone is defined ? taxZone.getErrors('description'), }) }} {% if craft.commerce.settings.useBillingAddressForTax %} {% set labelDefault = "Default to this tax zone when no billing address is set"|t('commerce') %} {% else %} {% set labelDefault = "Default to this tax zone when no shipping address is set"|t('commerce') %} {% endif %} {{ forms.checkboxField({ label: labelDefault, id: 'default', name: 'default', value: 1, checked: taxZone is defined ? taxZone.default, errors: taxZone is defined ? taxZone.getErrors('default') }) }} {{ forms.radioGroupField({ label: 'Type'|t('commerce'), id: 'isCountryBased', name: 'isCountryBased', options: {1 : 'Country-based'|t('commerce'), 0 : 'State-based'|t('commerce')}, value: taxZone is defined ? taxZone.isCountryBased, errors: taxZone is defined ? taxZone.getErrors('isCountryBased'), required: true, }) }} {{ forms.multiselectField({ label: 'Countries'|t('commerce'), instructions: 'Choose the countries that this zone applies to.'|t('commerce'), id: 'countries', name: 'countries', options: countries, values: taxZone is defined ? taxZone.getCountryIds(), errors: taxZone is defined ? taxZone.getErrors('countries'), required: true, class: 'selectize fullwidth', }) }} {{ forms.multiselectField({ label: 'States'|t('commerce'), id: 'states', instructions: 'Choose the states that this zone applies to.'|t('commerce'), name: 'states', options: states, values: taxZone is defined ? taxZone.getStateIds(), errors: taxZone is defined ? taxZone.getErrors('states'), required: true, class: 'selectize fullwidth', }) }} {% embed '_includes/forms/field' with { label: 'Zip Code Condition Formula'|t('commerce'), id: 'zipCodeConditionFormula', rows: 5, instructions: 'Use a formula to match the zip code. Leave this blank to match all zip codes. Use the `zipCode` variable.', tip: 'This field uses the Twig expression syntax. Learn More', errors: taxZone is defined ? taxZone.getErrors('zipCodeConditionFormula'), } %} {% block input %} {% import "_includes/forms" as forms %}
{{ forms.textarea({ value: taxZone is defined ? taxZone.zipCodeConditionFormula, name: 'zipCodeConditionFormula', class: 'code', rows: 5, placeholder: 'Example'|t('commerce') ~ ': zipCode[0:2] == \'NG\'' }) }}
{% embed '_includes/forms/field' with { label: 'Test Zip Code'|t('commerce'), class: 'zip-test-input', instructions: 'Type a test zip to see if your match works.'|t('commerce'), fieldClass: 'last' } only %} {% block input %} {% import "_includes/forms" as forms %}
{{ forms.text({ class: 'code', }) }}
{% endblock %} {% endembed %}
{% endblock %} {% endembed %}
{% set countriesId = 'countries'|namespaceInputId|e('js') %} {% set statesId = 'states'|namespaceInputId|e('js') %} {% set isCountryBasedName = 'isCountryBased'|namespaceInputName|e('js') %} {% set zipCodeFieldId = 'zipCodeField'|namespaceInputId|e('js') %} {% js %} $('#{{ countriesId }}, #{{ statesId }}').selectize({ plugins: ['remove_button'], dropdownParent: 'body' }); $('[name="{{ isCountryBasedName }}"]').change(function () { if (!$(this).is(':checked')) { return; } if ($(this).val() * 1) { $('#{{ countriesId }}')[0].selectize.enable(); $('#{{ statesId }}')[0].selectize.disable(); $('#{{ countriesId }}-field').show(); $('#{{ statesId }}-field').hide(); } else { $('#{{ countriesId }}')[0].selectize.disable(); $('#{{ statesId }}')[0].selectize.enable(); $('#{{ countriesId }}-field').hide(); $('#{{ statesId }}-field').show(); } }); $('[name="{{ isCountryBasedName }}"]:checked').trigger('change'); // setup for debouncing var typingTimer; //timer identifier var doneTypingInterval = 1000; //time in ms, 5 second for example // top level fov containing the field var $zipCodeField = $('#{{ zipCodeFieldId }}'); var $zipCodeConditionFormula = $zipCodeField.find('textarea').first(); var $testZipCode = $zipCodeField.find('.zip-test-input input').first(); var $zipTestStatus = $zipCodeField.find('.zip-test-status').first(); var $zipTestStatusSuccess = $zipTestStatus.find('.zip-test-status-icon.success'); var $zipTestStatusFailed = $zipTestStatus.find('.zip-test-status-icon.failure'); var $zipTestStatusSpinner = $zipTestStatus.find('.zip-test-status-spinner'); function startedTyping () { if($zipCodeConditionFormula.val() == ''){ $zipTestStatusSpinner.addClass('hidden'); $zipTestStatusFailed.addClass('hidden'); $zipTestStatusSuccess.addClass('hidden'); return; } $zipTestStatusSpinner.removeClass('hidden'); $zipTestStatusFailed.addClass('hidden'); $zipTestStatusSuccess.addClass('hidden'); } //on keyup, start the countdown $testZipCode.on('keyup', function () { clearTimeout(typingTimer); typingTimer = setTimeout(doneTyping, doneTypingInterval); startedTyping(); }); //on keyup, start the countdown $zipCodeConditionFormula.on('keyup', function () { clearTimeout(typingTimer); typingTimer = setTimeout(doneTyping, doneTypingInterval); startedTyping(); }); //on keydown, clear the countdown $zipCodeConditionFormula.on('keydown', function () { clearTimeout(typingTimer); }); //user is "finished typing," do something function doneTyping () { $.post({ url: Craft.getActionUrl('commerce/formulas/validate-condition'), data: { condition: $zipCodeConditionFormula.val(), params: { zipCode : '' } }, dataType: 'json', headers: { 'X-CSRF-Token': Craft.csrfTokenValue }, success: function(data){ if(data.hasOwnProperty('error')){ $zipCodeConditionFormula.addClass('error'); $zipTestStatusSpinner.addClass('hidden'); }else{ $zipCodeConditionFormula.removeClass('error'); $.post({ url: Craft.getActionUrl('commerce/tax-zones/test-zip'), data: { zipCodeConditionFormula: $zipCodeConditionFormula.val(), testZipCode : $testZipCode.val() }, dataType: 'json', headers: { 'X-CSRF-Token': Craft.csrfTokenValue }, success: function(data){ $zipTestStatusSpinner.addClass('hidden'); if(data.hasOwnProperty('error')){ $zipTestStatusFailed.removeClass('hidden'); }else { $zipTestStatusSuccess.removeClass('hidden'); } } }); } } }); } {% endjs %} {% css %} .zip-test{ background-color: #f1f5f8; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1); padding: 12px 14px; } .zip-test-input { position: relative; } .zip-test-status { position: absolute; top: 0; } body.ltr .zip-test-status { right: 4px; } body.rtl .zip-test-status { left: 4px; } .zip-test-status-icon { position: relative; top: 5px; width: 24px; text-align: center; } .zip-test-status-icon.success { color: #00b007; } .zip-test-status-icon.failure { color: #da5a47; } {% endcss %}