Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

625 wiersze
23 KiB

  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. /* global varienGlobalEvents, varienWindowOnloadCache, RegionUpdater, FormElementDependenceController */
  6. /* eslint-disable strict */
  7. define([
  8. 'jquery',
  9. 'prototype',
  10. 'mage/adminhtml/events'
  11. ], function (jQuery) {
  12. var varienElementMethods;
  13. /*
  14. * @TODO Need to be removed after refactoring all dependent of the form the components
  15. */
  16. (function ($) {
  17. $(function () {
  18. $(document).on('beforeSubmit', function (e) { //eslint-disable-line max-nested-callbacks
  19. if (typeof varienGlobalEvents !== 'undefined') {
  20. varienGlobalEvents.fireEvent('formSubmit', $(e.target).attr('id'));
  21. }
  22. });
  23. });
  24. })(jQuery);
  25. /**
  26. * Additional elements methods
  27. */
  28. varienElementMethods = {
  29. /**
  30. * @param {HTMLElement} element
  31. */
  32. setHasChanges: function (element) {
  33. var elm;
  34. if ($(element) && $(element).hasClassName('no-changes')) {
  35. return;
  36. }
  37. elm = element;
  38. while (elm && elm.tagName != 'BODY') { //eslint-disable-line eqeqeq
  39. if (elm.statusBar) {
  40. Element.addClassName($(elm.statusBar), 'changed');
  41. }
  42. elm = elm.parentNode;
  43. }
  44. },
  45. /**
  46. * @param {HTMLElement} element
  47. * @param {*} flag
  48. * @param {Object} form
  49. */
  50. setHasError: function (element, flag, form) {
  51. var elm = element;
  52. while (elm && elm.tagName != 'BODY') { //eslint-disable-line eqeqeq
  53. if (elm.statusBar) {
  54. /* eslint-disable max-depth */
  55. if (form.errorSections.keys().indexOf(elm.statusBar.id) < 0) {
  56. form.errorSections.set(elm.statusBar.id, flag);
  57. }
  58. if (flag) {
  59. Element.addClassName($(elm.statusBar), 'error');
  60. if (form.canShowError && $(elm.statusBar).show) {
  61. form.canShowError = false;
  62. $(elm.statusBar).show();
  63. }
  64. form.errorSections.set(elm.statusBar.id, flag);
  65. } else if (!form.errorSections.get(elm.statusBar.id)) {
  66. Element.removeClassName($(elm.statusBar), 'error');
  67. }
  68. /* eslint-enable max-depth */
  69. }
  70. elm = elm.parentNode;
  71. }
  72. this.canShowElement = false;
  73. }
  74. };
  75. Element.addMethods(varienElementMethods);
  76. // Global bind changes
  77. window.varienWindowOnloadCache = {};
  78. /**
  79. * @param {*} useCache
  80. */
  81. function varienWindowOnload(useCache) {
  82. var dataElements = $$('input', 'select', 'textarea'),
  83. i;
  84. for (i = 0; i < dataElements.length; i++) {
  85. if (dataElements[i] && dataElements[i].id) {
  86. /* eslint-disable max-depth */
  87. if (!useCache || !varienWindowOnloadCache[dataElements[i].id]) {
  88. Event.observe(dataElements[i], 'change', dataElements[i].setHasChanges.bind(dataElements[i]));
  89. if (useCache) {
  90. varienWindowOnloadCache[dataElements[i].id] = true;
  91. }
  92. }
  93. /* eslint-disable max-depth */
  94. }
  95. }
  96. }
  97. Event.observe(window, 'load', varienWindowOnload);
  98. window.RegionUpdater = Class.create();
  99. RegionUpdater.prototype = {
  100. /**
  101. * @param {HTMLElement} countryEl
  102. * @param {HTMLElement} regionTextEl
  103. * @param {HTMLElement}regionSelectEl
  104. * @param {Object} regions
  105. * @param {*} disableAction
  106. * @param {*} clearRegionValueOnDisable
  107. */
  108. initialize: function (
  109. countryEl, regionTextEl, regionSelectEl, regions, disableAction, clearRegionValueOnDisable
  110. ) {
  111. this.isRegionRequired = true;
  112. this.countryEl = $(countryEl);
  113. this.regionTextEl = $(regionTextEl);
  114. this.regionSelectEl = $(regionSelectEl);
  115. this.config = regions.config;
  116. delete regions.config;
  117. this.regions = regions;
  118. this.sortedRegions = this.getSortedRegions();
  119. this.disableAction = typeof disableAction === 'undefined' ? 'hide' : disableAction;
  120. this.clearRegionValueOnDisable = typeof clearRegionValueOnDisable === 'undefined' ?
  121. false : clearRegionValueOnDisable;
  122. if (this.regionSelectEl.options.length <= 1) {
  123. this.update();
  124. } else {
  125. this.lastCountryId = this.countryEl.value;
  126. }
  127. this.countryEl.changeUpdater = this.update.bind(this);
  128. Event.observe(this.countryEl, 'change', this.update.bind(this));
  129. },
  130. /**
  131. * @private
  132. */
  133. _checkRegionRequired: function () {
  134. var label, wildCard, elements, that, regionRequired;
  135. if (!this.isRegionRequired) {
  136. return;
  137. }
  138. elements = [this.regionTextEl, this.regionSelectEl];
  139. that = this;
  140. if (typeof this.config == 'undefined') {
  141. return;
  142. }
  143. regionRequired = this.config['regions_required'].indexOf(this.countryEl.value) >= 0;
  144. elements.each(function (currentElement) {
  145. var form, validationInstance, field, topElement;
  146. if (!currentElement) {
  147. return;
  148. }
  149. form = currentElement.form;
  150. validationInstance = form ? jQuery(form).data('validation') : null;
  151. field = currentElement.up('.field') || new Element('div');
  152. if (validationInstance) {
  153. validationInstance.clearError(currentElement);
  154. }
  155. label = $$('label[for="' + currentElement.id + '"]')[0];
  156. if (label) {
  157. wildCard = label.down('em') || label.down('span.required');
  158. topElement = label.up('tr') || label.up('li');
  159. if (!that.config['show_all_regions'] && topElement) {
  160. if (regionRequired) {
  161. topElement.show();
  162. } else {
  163. topElement.hide();
  164. }
  165. }
  166. }
  167. if (label && wildCard) {
  168. if (!regionRequired) {
  169. wildCard.hide();
  170. } else {
  171. wildCard.show();
  172. }
  173. }
  174. //compute the need for the required fields
  175. if (!regionRequired || !currentElement.visible()) {
  176. if (field.hasClassName('required')) {
  177. field.removeClassName('required');
  178. }
  179. if (currentElement.hasClassName('required-entry')) {
  180. currentElement.removeClassName('required-entry');
  181. }
  182. if (currentElement.tagName.toLowerCase() == 'select' && //eslint-disable-line eqeqeq
  183. currentElement.hasClassName('validate-select')
  184. ) {
  185. currentElement.removeClassName('validate-select');
  186. }
  187. } else {
  188. if (!field.hasClassName('required')) {
  189. field.addClassName('required');
  190. }
  191. if (!currentElement.hasClassName('required-entry')) {
  192. currentElement.addClassName('required-entry');
  193. }
  194. if (currentElement.tagName.toLowerCase() == 'select' && //eslint-disable-line eqeqeq
  195. !currentElement.hasClassName('validate-select')
  196. ) {
  197. currentElement.addClassName('validate-select');
  198. }
  199. }
  200. });
  201. },
  202. /**
  203. * Disable region validation.
  204. */
  205. disableRegionValidation: function () {
  206. this.isRegionRequired = false;
  207. },
  208. /**
  209. * Update.
  210. */
  211. update: function () {
  212. var option, selectElement, def, regionId, region;
  213. selectElement = this.regionSelectEl;
  214. if (this.sortedRegions[this.countryEl.value]) {
  215. if (this.lastCountryId != this.countryEl.value) { //eslint-disable-line eqeqeq
  216. def = selectElement.getAttribute('defaultValue');
  217. if (this.regionTextEl) {
  218. if (!def) {
  219. def = this.regionTextEl.value.toLowerCase();
  220. }
  221. this.regionTextEl.value = '';
  222. }
  223. selectElement.options.length = 1;
  224. this.sortedRegions[this.countryEl.value].forEach(function (item) {
  225. regionId = item[0];
  226. region = item[1];
  227. option = document.createElement('OPTION');
  228. option.value = regionId;
  229. option.text = region.name.stripTags();
  230. option.title = region.name;
  231. if (selectElement.options.add) {
  232. selectElement.options.add(option);
  233. } else {
  234. selectElement.appendChild(option);
  235. }
  236. if (regionId == def || region.name.toLowerCase() == def || region.code.toLowerCase() == def) { //eslint-disable-line
  237. selectElement.value = regionId;
  238. }
  239. });
  240. }
  241. if (this.disableAction == 'hide') { //eslint-disable-line eqeqeq
  242. if (this.regionTextEl) {
  243. this.regionTextEl.style.display = 'none';
  244. this.regionTextEl.style.disabled = true;
  245. }
  246. this.regionSelectEl.style.display = '';
  247. this.regionSelectEl.disabled = false;
  248. } else if (this.disableAction == 'disable') { //eslint-disable-line eqeqeq
  249. if (this.regionTextEl) {
  250. this.regionTextEl.disabled = true;
  251. }
  252. this.regionSelectEl.disabled = false;
  253. }
  254. this.setMarkDisplay(this.regionSelectEl, true);
  255. this.lastCountryId = this.countryEl.value;
  256. } else {
  257. if (this.disableAction == 'hide') { //eslint-disable-line eqeqeq
  258. if (this.regionTextEl) {
  259. this.regionTextEl.style.display = '';
  260. this.regionTextEl.style.disabled = false;
  261. }
  262. this.regionSelectEl.style.display = 'none';
  263. this.regionSelectEl.disabled = true;
  264. } else if (this.disableAction == 'disable') { //eslint-disable-line eqeqeq
  265. if (this.regionTextEl) {
  266. this.regionTextEl.disabled = false;
  267. }
  268. this.regionSelectEl.disabled = true;
  269. if (this.clearRegionValueOnDisable) {
  270. this.regionSelectEl.value = '';
  271. }
  272. } else if (this.disableAction == 'nullify') { //eslint-disable-line eqeqeq
  273. this.regionSelectEl.options.length = 1;
  274. this.regionSelectEl.value = '';
  275. this.regionSelectEl.selectedIndex = 0;
  276. this.lastCountryId = '';
  277. }
  278. this.setMarkDisplay(this.regionSelectEl, false);
  279. }
  280. varienGlobalEvents.fireEvent('address_country_changed', this.countryEl);
  281. this._checkRegionRequired();
  282. },
  283. /**
  284. * @param {HTMLElement} elem
  285. * @param {*} display
  286. */
  287. setMarkDisplay: function (elem, display) {
  288. var marks;
  289. if (elem.parentNode.parentNode) {
  290. marks = Element.select(elem.parentNode.parentNode, '.required');
  291. if (marks[0]) {
  292. display ? marks[0].show() : marks[0].hide();
  293. }
  294. }
  295. },
  296. /**
  297. * Sort regions from JSON by name
  298. *
  299. * @returns {*[]}
  300. */
  301. getSortedRegions: function () {
  302. var country, regionsEntries, regionsByCountry;
  303. regionsByCountry = [];
  304. for (country in this.regions) { //eslint-disable-line guard-for-in
  305. regionsEntries = Object.entries(this.regions[country]);
  306. regionsEntries.sort(function (a, b) {
  307. return a[1].name > b[1].name ? 1 : -1;
  308. });
  309. regionsByCountry[country] = regionsEntries;
  310. }
  311. return regionsByCountry;
  312. }
  313. };
  314. window.regionUpdater = RegionUpdater;
  315. /**
  316. * Fix errorrs in IE
  317. */
  318. Event.pointerX = function (event) {
  319. try {
  320. return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); //eslint-disable-line
  321. }
  322. catch (e) {}
  323. };
  324. /**
  325. * @param {jQuery.Event} event
  326. * @return {*}
  327. */
  328. Event.pointerY = function (event) {
  329. try {
  330. return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); //eslint-disable-line
  331. }
  332. catch (e) {}
  333. };
  334. /**
  335. * Observer that watches for dependent form elements
  336. * If an element depends on 1 or more of other elements,
  337. * it should show up only when all of them gain specified values
  338. */
  339. window.FormElementDependenceController = Class.create();
  340. FormElementDependenceController.prototype = {
  341. /**
  342. * Structure of elements: {
  343. * 'id_of_dependent_element' : {
  344. * 'id_of_master_element_1' : 'reference_value',
  345. * 'id_of_master_element_2' : 'reference_value'
  346. * 'id_of_master_element_3' : ['reference_value1', 'reference_value2']
  347. * ...
  348. * }
  349. * }
  350. * @param {Object} elementsMap
  351. * @param {Object} config
  352. */
  353. initialize: function (elementsMap, config) {
  354. var idTo, idFrom, values, fromId, radioFrom;
  355. if (config) {
  356. this._config = jQuery.extend(this._config, config);
  357. }
  358. for (idTo in elementsMap) { //eslint-disable-line guard-for-in
  359. for (idFrom in elementsMap[idTo]) { //eslint-disable-line guard-for-in
  360. if ($(idFrom)) {
  361. Event.observe(
  362. $(idFrom),
  363. 'change',
  364. this.trackChange.bindAsEventListener(this, idTo, elementsMap[idTo])
  365. );
  366. } else {
  367. // Check if radio button
  368. values = elementsMap[idTo][idFrom].values;
  369. fromId = $(idFrom + values[0]);
  370. radioFrom = fromId ? $$('[name="' + fromId.name + '"]') : false;
  371. if (radioFrom) {
  372. radioFrom.invoke(
  373. 'on',
  374. 'change',
  375. this.trackChange.bindAsEventListener(this, idTo, elementsMap[idTo])
  376. );
  377. }
  378. }
  379. this.trackChange(null, idTo, elementsMap[idTo]);
  380. }
  381. }
  382. },
  383. /**
  384. * Misc. config options
  385. * Keys are underscored intentionally
  386. */
  387. _config: {
  388. 'levels_up': 1 // how many levels up to travel when toggling element
  389. },
  390. /**
  391. * Define whether target element should be toggled and show/hide its row
  392. *
  393. * @param {Object} e - event
  394. * @param {String} idTo - id of target element
  395. * @param {Object} valuesFrom - ids of master elements and reference values
  396. * @return
  397. */
  398. trackChange: function (e, idTo, valuesFrom) {
  399. // define whether the target should show up
  400. var shouldShowUp = true,
  401. idFrom, from, values, isInArray, isNegative, headElement, isInheritCheckboxChecked, target, inputs,
  402. isAnInputOrSelect, currentConfig, rowElement, fromId, radioFrom, targetArray, isChooser;
  403. for (idFrom in valuesFrom) { //eslint-disable-line guard-for-in
  404. from = $(idFrom);
  405. if (from) {
  406. values = valuesFrom[idFrom].values;
  407. isInArray = values.indexOf(from.value) != -1; //eslint-disable-line
  408. isNegative = valuesFrom[idFrom].negative;
  409. if (!from || isInArray && isNegative || !isInArray && !isNegative) {
  410. shouldShowUp = false;
  411. }
  412. // Check if radio button
  413. } else {
  414. values = valuesFrom[idFrom].values;
  415. fromId = $(idFrom + values[0]);
  416. if (fromId) {
  417. radioFrom = $$('[name="' + fromId.name + '"]:checked');
  418. isInArray = radioFrom.length > 0 && values.indexOf(radioFrom[0].value) !== -1;
  419. isNegative = valuesFrom[idFrom].negative;
  420. if (!radioFrom || isInArray && isNegative || !isInArray && !isNegative) {
  421. shouldShowUp = false;
  422. }
  423. }
  424. }
  425. }
  426. // toggle target row
  427. headElement = jQuery('#' + idTo + '-head');
  428. isInheritCheckboxChecked = $(idTo + '_inherit') && $(idTo + '_inherit').checked;
  429. target = $(idTo);
  430. // Account for the chooser style parameters.
  431. if (target === null && headElement.length === 0 && idTo.substring(0, 16) === 'options_fieldset') {
  432. targetArray = $$('input[id*="' + idTo + '"]');
  433. isChooser = true;
  434. if (targetArray !== null && targetArray.length > 0) {
  435. target = targetArray[0];
  436. }
  437. headElement = jQuery('.field-' + idTo).add('.field-chooser' + idTo);
  438. }
  439. // Target won't always exist (for example, if field type is "label")
  440. if (target) {
  441. inputs = target.up(this._config['levels_up']).select('input', 'select', 'td');
  442. isAnInputOrSelect = ['input', 'select'].indexOf(target.tagName.toLowerCase()) != -1; //eslint-disable-line
  443. if (target.type === 'fieldset') {
  444. inputs = target.select('input', 'select', 'td');
  445. }
  446. } else {
  447. inputs = false;
  448. isAnInputOrSelect = false;
  449. }
  450. if (shouldShowUp) {
  451. currentConfig = this._config;
  452. if (inputs) {
  453. inputs.each(function (item) {
  454. // don't touch hidden inputs (and Use Default inputs too), bc they may have custom logic
  455. if ((!item.type || item.type != 'hidden') && !($(item.id + '_inherit') && $(item.id + '_inherit').checked) && //eslint-disable-line
  456. !(currentConfig['can_edit_price'] != undefined && !currentConfig['can_edit_price']) && //eslint-disable-line
  457. !item.getAttribute('readonly') || isChooser //eslint-disable-line
  458. ) {
  459. item.disabled = false;
  460. jQuery(item).removeClass('ignore-validate');
  461. }
  462. });
  463. }
  464. if (headElement.length > 0) {
  465. headElement.show();
  466. if (headElement.hasClass('open') && target) {
  467. target.show();
  468. } else if (target) {
  469. target.hide();
  470. }
  471. } else {
  472. if (target) {
  473. target.show();
  474. headElement = jQuery('.field-' + idTo).add('.field-chooser' + idTo);
  475. headElement.show();
  476. }
  477. if (isAnInputOrSelect && !isInheritCheckboxChecked) {
  478. if (target) {
  479. if (target.getAttribute('readonly')) {
  480. target.disabled = true;
  481. } else {
  482. target.disabled = false;
  483. }
  484. }
  485. jQuery('#' + idTo).removeClass('ignore-validate');
  486. }
  487. }
  488. } else {
  489. if (inputs) {
  490. inputs.each(function (item) {
  491. // don't touch hidden inputs (and Use Default inputs too), bc they may have custom logic
  492. if ((!item.type || item.type != 'hidden') && //eslint-disable-line eqeqeq
  493. !($(item.id + '_inherit') && $(item.id + '_inherit').checked)
  494. ) {
  495. item.disabled = true;
  496. jQuery(item).addClass('ignore-validate');
  497. }
  498. });
  499. }
  500. if (headElement.length > 0) {
  501. headElement.hide();
  502. } else {
  503. headElement = jQuery('.field-' + idTo).add('.field-chooser' + idTo);
  504. headElement.hide();
  505. }
  506. if (target) {
  507. target.hide();
  508. }
  509. if (isAnInputOrSelect && !isInheritCheckboxChecked) {
  510. if (target) {
  511. target.disabled = true;
  512. }
  513. jQuery('#' + idTo).addClass('ignore-validate');
  514. }
  515. }
  516. rowElement = $('row_' + idTo);
  517. if (rowElement == undefined && target) { //eslint-disable-line eqeqeq
  518. rowElement = target.up(this._config['levels_up']);
  519. if (target.type === 'fieldset') {
  520. rowElement = target;
  521. }
  522. }
  523. if (rowElement) {
  524. if (shouldShowUp) {
  525. rowElement.show();
  526. } else {
  527. rowElement.hide();
  528. }
  529. }
  530. }
  531. };
  532. window.varienWindowOnload = varienWindowOnload;
  533. window.varienElementMethods = varienElementMethods;
  534. });