No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

264 líneas
9.7 KiB

  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. define([
  6. 'jquery',
  7. 'mage/template',
  8. 'underscore',
  9. 'jquery-ui-modules/widget',
  10. 'mage/validation'
  11. ], function ($, mageTemplate, _) {
  12. 'use strict';
  13. $.widget('mage.regionUpdater', {
  14. options: {
  15. regionTemplate:
  16. '<option value="<%- data.value %>" <% if (data.isSelected) { %>selected="selected"<% } %>>' +
  17. '<%- data.title %>' +
  18. '</option>',
  19. isRegionRequired: true,
  20. isZipRequired: true,
  21. isCountryRequired: true,
  22. currentRegion: null,
  23. isMultipleCountriesAllowed: true
  24. },
  25. /**
  26. *
  27. * @private
  28. */
  29. _create: function () {
  30. this._initCountryElement();
  31. this.currentRegionOption = this.options.currentRegion;
  32. this.regionTmpl = mageTemplate(this.options.regionTemplate);
  33. this._updateRegion(this.element.find('option:selected').val());
  34. $(this.options.regionListId).on('change', $.proxy(function (e) {
  35. this.setOption = false;
  36. this.currentRegionOption = $(e.target).val();
  37. }, this));
  38. $(this.options.regionInputId).on('focusout', $.proxy(function () {
  39. this.setOption = true;
  40. }, this));
  41. },
  42. /**
  43. *
  44. * @private
  45. */
  46. _initCountryElement: function () {
  47. if (this.options.isMultipleCountriesAllowed) {
  48. this.element.parents('div.field').show();
  49. this.element.on('change', $.proxy(function (e) {
  50. // clear region inputs on country change
  51. $(this.options.regionListId).val('');
  52. $(this.options.regionInputId).val('');
  53. this._updateRegion($(e.target).val());
  54. }, this));
  55. if (this.options.isCountryRequired) {
  56. this.element.addClass('required-entry');
  57. this.element.parents('div.field').addClass('required');
  58. }
  59. } else {
  60. this.element.parents('div.field').hide();
  61. }
  62. },
  63. /**
  64. * Remove options from dropdown list
  65. *
  66. * @param {Object} selectElement - jQuery object for dropdown list
  67. * @private
  68. */
  69. _removeSelectOptions: function (selectElement) {
  70. selectElement.find('option').each(function (index) {
  71. if (index) {
  72. $(this).remove();
  73. }
  74. });
  75. },
  76. /**
  77. * Render dropdown list
  78. * @param {Object} selectElement - jQuery object for dropdown list
  79. * @param {String} key - region code
  80. * @param {Object} value - region object
  81. * @private
  82. */
  83. _renderSelectOption: function (selectElement, key, value) {
  84. selectElement.append($.proxy(function () {
  85. var name = value.name.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, '\\$&'),
  86. tmplData,
  87. tmpl;
  88. if (value.code && $(name).is('span')) {
  89. key = value.code;
  90. value.name = $(name).text();
  91. }
  92. tmplData = {
  93. value: key,
  94. title: value.name,
  95. isSelected: false
  96. };
  97. if (this.options.defaultRegion === key) {
  98. tmplData.isSelected = true;
  99. }
  100. tmpl = this.regionTmpl({
  101. data: tmplData
  102. });
  103. return $(tmpl);
  104. }, this));
  105. },
  106. /**
  107. * Takes clearError callback function as first option
  108. * If no form is passed as option, look up the closest form and call clearError method.
  109. * @private
  110. */
  111. _clearError: function () {
  112. var args = ['clearError', this.options.regionListId, this.options.regionInputId, this.options.postcodeId];
  113. if (this.options.clearError && typeof this.options.clearError === 'function') {
  114. this.options.clearError.call(this);
  115. } else {
  116. if (!this.options.form) {
  117. this.options.form = this.element.closest('form').length ? $(this.element.closest('form')[0]) : null;
  118. }
  119. this.options.form = $(this.options.form);
  120. this.options.form && this.options.form.data('validator') &&
  121. this.options.form.validation.apply(this.options.form, _.compact(args));
  122. // Clean up errors on region & zip fix
  123. $(this.options.regionInputId).removeClass('mage-error').parent().find('.mage-error').remove();
  124. $(this.options.regionListId).removeClass('mage-error').parent().find('.mage-error').remove();
  125. $(this.options.postcodeId).removeClass('mage-error').parent().find('.mage-error').remove();
  126. }
  127. },
  128. /**
  129. * Update dropdown list based on the country selected
  130. *
  131. * @param {String} country - 2 uppercase letter for country code
  132. * @private
  133. */
  134. _updateRegion: function (country) {
  135. // Clear validation error messages
  136. var regionList = $(this.options.regionListId),
  137. regionInput = $(this.options.regionInputId),
  138. postcode = $(this.options.postcodeId),
  139. label = regionList.parent().siblings('label'),
  140. container = regionList.parents('div.field'),
  141. regionsEntries,
  142. regionId,
  143. regionData;
  144. this._clearError();
  145. this._checkRegionRequired(country);
  146. // Populate state/province dropdown list if available or use input box
  147. if (this.options.regionJson[country]) {
  148. this._removeSelectOptions(regionList);
  149. regionsEntries = _.pairs(this.options.regionJson[country]);
  150. regionsEntries.sort(function (a, b) {
  151. return a[1].name > b[1].name ? 1 : -1;
  152. });
  153. $.each(regionsEntries, $.proxy(function (key, value) {
  154. regionId = value[0];
  155. regionData = value[1];
  156. this._renderSelectOption(regionList, regionId, regionData);
  157. }, this));
  158. if (this.currentRegionOption) {
  159. regionList.val(this.currentRegionOption);
  160. }
  161. if (this.setOption) {
  162. regionList.find('option').filter(function () {
  163. return this.text === regionInput.val();
  164. }).attr('selected', true);
  165. }
  166. if (this.options.isRegionRequired) {
  167. regionList.addClass('required-entry').prop('disabled', false);
  168. container.addClass('required').show();
  169. } else {
  170. regionList.removeClass('required-entry validate-select').removeAttr('data-validate');
  171. container.removeClass('required');
  172. if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth
  173. regionList.hide();
  174. container.hide();
  175. } else {
  176. regionList.prop('disabled', false).show();
  177. }
  178. }
  179. regionList.show();
  180. regionInput.hide();
  181. label.attr('for', regionList.attr('id'));
  182. } else {
  183. this._removeSelectOptions(regionList);
  184. if (this.options.isRegionRequired) {
  185. regionInput.addClass('required-entry').prop('disabled', false);
  186. container.addClass('required').show();
  187. } else {
  188. if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth
  189. regionInput.attr('disabled', 'disabled');
  190. container.hide();
  191. }
  192. container.removeClass('required');
  193. regionInput.removeClass('required-entry');
  194. }
  195. regionList.removeClass('required-entry').prop('disabled', 'disabled').hide();
  196. regionInput.show();
  197. label.attr('for', regionInput.attr('id'));
  198. }
  199. // If country is in optionalzip list, make postcode input not required
  200. if (this.options.isZipRequired) {
  201. $.inArray(country, this.options.countriesWithOptionalZip) >= 0 ?
  202. postcode.removeClass('required-entry').closest('.field').removeClass('required') :
  203. postcode.addClass('required-entry').closest('.field').addClass('required');
  204. }
  205. // Add defaultvalue attribute to state/province select element
  206. regionList.attr('defaultvalue', this.options.defaultRegion);
  207. this.options.form.find('[type="submit"]').prop('disabled', false).show();
  208. },
  209. /**
  210. * Check if the selected country has a mandatory region selection
  211. *
  212. * @param {String} country - Code of the country - 2 uppercase letter for country code
  213. * @private
  214. */
  215. _checkRegionRequired: function (country) {
  216. var self = this;
  217. this.options.isRegionRequired = false;
  218. $.each(this.options.regionJson.config['regions_required'], function (index, elem) {
  219. if (elem === country) {
  220. self.options.isRegionRequired = true;
  221. }
  222. });
  223. }
  224. });
  225. return $.mage.regionUpdater;
  226. });