123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- define([
- 'jquery',
- 'mage/template',
- 'underscore',
- 'jquery/ui',
- 'mage/validation'
- ], function ($, mageTemplate, _) {
- 'use strict';
- $.widget('mage.regionUpdater', {
- options: {
- regionTemplate:
- '<option value="<%- data.value %>" <% if (data.isSelected) { %>selected="selected"<% } %>>' +
- '<%- data.title %>' +
- '</option>',
- isRegionRequired: true,
- isZipRequired: true,
- isCountryRequired: true,
- currentRegion: null,
- isMultipleCountriesAllowed: true
- },
- /**
- *
- * @private
- */
- _create: function () {
- this._initCountryElement();
- this.currentRegionOption = this.options.currentRegion;
- this.regionTmpl = mageTemplate(this.options.regionTemplate);
- this._updateRegion(this.element.find('option:selected').val());
- $(this.options.regionListId).on('change', $.proxy(function (e) {
- this.setOption = false;
- this.currentRegionOption = $(e.target).val();
- }, this));
- $(this.options.regionInputId).on('focusout', $.proxy(function () {
- this.setOption = true;
- }, this));
- },
- /**
- *
- * @private
- */
- _initCountryElement: function () {
- if (this.options.isMultipleCountriesAllowed) {
- this.element.parents('div.field').show();
- this.element.on('change', $.proxy(function (e) {
- this._updateRegion($(e.target).val());
- }, this));
- if (this.options.isCountryRequired) {
- this.element.addClass('required-entry');
- this.element.parents('div.field').addClass('required');
- }
- } else {
- this.element.parents('div.field').hide();
- }
- },
- /**
- * Remove options from dropdown list
- *
- * @param {Object} selectElement - jQuery object for dropdown list
- * @private
- */
- _removeSelectOptions: function (selectElement) {
- selectElement.find('option').each(function (index) {
- if (index) {
- $(this).remove();
- }
- });
- },
- /**
- * Render dropdown list
- * @param {Object} selectElement - jQuery object for dropdown list
- * @param {String} key - region code
- * @param {Object} value - region object
- * @private
- */
- _renderSelectOption: function (selectElement, key, value) {
- selectElement.append($.proxy(function () {
- var name = value.name.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, '\\$&'),
- tmplData,
- tmpl;
- if (value.code && $(name).is('span')) {
- key = value.code;
- value.name = $(name).text();
- }
- tmplData = {
- value: key,
- title: value.name,
- isSelected: false
- };
- if (this.options.defaultRegion === key) {
- tmplData.isSelected = true;
- }
- tmpl = this.regionTmpl({
- data: tmplData
- });
- return $(tmpl);
- }, this));
- },
- /**
- * Takes clearError callback function as first option
- * If no form is passed as option, look up the closest form and call clearError method.
- * @private
- */
- _clearError: function () {
- var args = ['clearError', this.options.regionListId, this.options.regionInputId, this.options.postcodeId];
- if (this.options.clearError && typeof this.options.clearError === 'function') {
- this.options.clearError.call(this);
- } else {
- if (!this.options.form) {
- this.options.form = this.element.closest('form').length ? $(this.element.closest('form')[0]) : null;
- }
- this.options.form = $(this.options.form);
- this.options.form && this.options.form.data('validator') &&
- this.options.form.validation.apply(this.options.form, _.compact(args));
- // Clean up errors on region & zip fix
- $(this.options.regionInputId).removeClass('mage-error').parent().find('[generated]').remove();
- $(this.options.regionListId).removeClass('mage-error').parent().find('[generated]').remove();
- $(this.options.postcodeId).removeClass('mage-error').parent().find('[generated]').remove();
- }
- },
- /**
- * Update dropdown list based on the country selected
- *
- * @param {String} country - 2 uppercase letter for country code
- * @private
- */
- _updateRegion: function (country) {
- // Clear validation error messages
- var regionList = $(this.options.regionListId),
- regionInput = $(this.options.regionInputId),
- postcode = $(this.options.postcodeId),
- label = regionList.parent().siblings('label'),
- requiredLabel = regionList.parents('div.field');
- this._clearError();
- this._checkRegionRequired(country);
- // Populate state/province dropdown list if available or use input box
- if (this.options.regionJson[country]) {
- this._removeSelectOptions(regionList);
- $.each(this.options.regionJson[country], $.proxy(function (key, value) {
- this._renderSelectOption(regionList, key, value);
- }, this));
- if (this.currentRegionOption) {
- regionList.val(this.currentRegionOption);
- }
- if (this.setOption) {
- regionList.find('option').filter(function () {
- return this.text === regionInput.val();
- }).attr('selected', true);
- }
- if (this.options.isRegionRequired) {
- regionList.addClass('required-entry').removeAttr('disabled');
- requiredLabel.addClass('required');
- } else {
- regionList.removeClass('required-entry validate-select').removeAttr('data-validate');
- requiredLabel.removeClass('required');
- if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth
- regionList.attr('disabled', 'disabled');
- } else {
- regionList.removeAttr('disabled');
- }
- }
- regionList.show();
- regionInput.hide();
- label.attr('for', regionList.attr('id'));
- } else {
- this._removeSelectOptions(regionList);
- if (this.options.isRegionRequired) {
- regionInput.addClass('required-entry').removeAttr('disabled');
- requiredLabel.addClass('required');
- } else {
- if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth
- regionInput.attr('disabled', 'disabled');
- }
- requiredLabel.removeClass('required');
- regionInput.removeClass('required-entry');
- }
- regionList.removeClass('required-entry').prop('disabled', 'disabled').hide();
- regionInput.show();
- label.attr('for', regionInput.attr('id'));
- }
- // If country is in optionalzip list, make postcode input not required
- if (this.options.isZipRequired) {
- $.inArray(country, this.options.countriesWithOptionalZip) >= 0 ?
- postcode.removeClass('required-entry').closest('.field').removeClass('required') :
- postcode.addClass('required-entry').closest('.field').addClass('required');
- }
- // Add defaultvalue attribute to state/province select element
- regionList.attr('defaultvalue', this.options.defaultRegion);
- },
- /**
- * Check if the selected country has a mandatory region selection
- *
- * @param {String} country - Code of the country - 2 uppercase letter for country code
- * @private
- */
- _checkRegionRequired: function (country) {
- var self = this;
- this.options.isRegionRequired = false;
- $.each(this.options.regionJson.config['regions_required'], function (index, elem) {
- if (elem === country) {
- self.options.isRegionRequired = true;
- }
- });
- }
- });
- return $.mage.regionUpdater;
- });
|