Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

1621 Zeilen
50 KiB

  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. // also depends on a mage/adminhtml/tools.js for Base64 encoding
  6. /* global varienGrid, setLocation, varienGlobalEvents, FORM_KEY,
  7. BASE_URL, Base64, varienGridMassaction, varienStringArray, serializerController
  8. */
  9. /* eslint-disable strict */
  10. define([
  11. 'jquery',
  12. 'mage/template',
  13. 'Magento_Ui/js/modal/alert',
  14. 'Magento_Ui/js/modal/confirm',
  15. 'mage/mage',
  16. 'prototype',
  17. 'mage/adminhtml/form',
  18. 'mage/adminhtml/events'
  19. ], function (jQuery, mageTemplate, alert, confirm) {
  20. /**
  21. * @param {*} grid
  22. * @param {*} event
  23. */
  24. function openGridRow(grid, event) {
  25. var element = Event.findElement(event, 'tr');
  26. if (['a', 'input', 'select', 'option'].indexOf(Event.element(event).tagName.toLowerCase()) !== -1) {
  27. return;
  28. }
  29. if (element.title) {
  30. setLocation(element.title);
  31. }
  32. }
  33. window.openGridRow = openGridRow;
  34. window.varienGrid = new Class.create();
  35. varienGrid.prototype = {
  36. /**
  37. * @param {String} containerId
  38. * @param {String} url
  39. * @param {*} pageVar
  40. * @param {*} sortVar
  41. * @param {*} dirVar
  42. * @param {*} filterVar
  43. */
  44. initialize: function (containerId, url, pageVar, sortVar, dirVar, filterVar) {
  45. this.containerId = containerId;
  46. jQuery('#' + containerId).data('gridObject', this);
  47. this.url = url;
  48. this.pageVar = pageVar || false;
  49. this.sortVar = sortVar || false;
  50. this.dirVar = dirVar || false;
  51. this.filterVar = filterVar || false;
  52. this.tableSufix = '_table';
  53. this.useAjax = false;
  54. this.rowClickCallback = false;
  55. this.checkboxCheckCallback = false;
  56. this.preInitCallback = false;
  57. this.initCallback = false;
  58. this.initRowCallback = false;
  59. this.doFilterCallback = false;
  60. this.sortableUpdateCallback = false;
  61. this.targetElement = undefined;
  62. this.filterKeyPressCallback = false;
  63. this.reloadParams = false;
  64. this.trOnMouseOver = this.rowMouseOver.bindAsEventListener(this);
  65. this.trOnMouseOut = this.rowMouseOut.bindAsEventListener(this);
  66. this.trOnMouseDown = this.rowMouseDown.bindAsEventListener(this);
  67. this.trOnClick = this.rowMouseClick.bindAsEventListener(this);
  68. this.trOnDblClick = this.rowMouseDblClick.bindAsEventListener(this);
  69. this.trOnKeyPress = this.keyPress.bindAsEventListener(this);
  70. this.thLinkOnClick = this.doSort.bindAsEventListener(this);
  71. this.initGrid();
  72. },
  73. /**
  74. * Init grid.
  75. */
  76. initGrid: function () {
  77. var row, columns, col;
  78. if (this.preInitCallback) {
  79. this.preInitCallback(this);
  80. }
  81. if ($(this.containerId + this.tableSufix)) {
  82. this.rows = $$('#' + this.containerId + this.tableSufix + ' tbody tr');
  83. for (row = 0; row < this.rows.length; row++) {
  84. if (row % 2 == 0) { //eslint-disable-line eqeqeq, max-depth
  85. Element.addClassName(this.rows[row], 'even');
  86. }
  87. Event.observe(this.rows[row], 'mouseover', this.trOnMouseOver);
  88. Event.observe(this.rows[row], 'mouseout', this.trOnMouseOut);
  89. Event.observe(this.rows[row], 'mousedown', this.trOnMouseDown);
  90. Event.observe(this.rows[row], 'click', this.trOnClick);
  91. Event.observe(this.rows[row], 'dblclick', this.trOnDblClick);
  92. }
  93. }
  94. if (this.sortVar && this.dirVar) {
  95. columns = $$('#' + this.containerId + this.tableSufix + ' thead [data-sort]');
  96. for (col = 0; col < columns.length; col++) {
  97. Event.observe(columns[col], 'click', this.thLinkOnClick);
  98. }
  99. }
  100. this.bindFilterFields();
  101. this.bindFieldsChange();
  102. if (this.initCallback) {
  103. try {
  104. this.initCallback(this);
  105. } catch (e) {
  106. if (window.console) { //eslint-disable-line max-depth
  107. console.log(e);
  108. }
  109. }
  110. }
  111. jQuery('#' + this.containerId).trigger('gridinit', this);
  112. },
  113. /**
  114. * Init grid ajax.
  115. */
  116. initGridAjax: function () {
  117. this.initGrid();
  118. this.initGridRows();
  119. },
  120. /**
  121. * Init grid rows.
  122. */
  123. initGridRows: function () {
  124. var row;
  125. if (this.initRowCallback) {
  126. for (row = 0; row < this.rows.length; row++) {
  127. try { //eslint-disable-line max-depth
  128. this.initRowCallback(this, this.rows[row]);
  129. } catch (e) {
  130. if (window.console) { //eslint-disable-line max-depth
  131. console.log(e);
  132. }
  133. }
  134. }
  135. }
  136. },
  137. /**
  138. * @param {*} event
  139. */
  140. rowMouseOver: function (event) {
  141. var element = Event.findElement(event, 'tr');
  142. if (!element.title) {
  143. return;
  144. }
  145. Element.addClassName(element, 'on-mouse');
  146. if (!Element.hasClassName('_clickable') && (this.rowClickCallback !== openGridRow || element.title)) {
  147. if (element.title) {
  148. Element.addClassName(element, '_clickable');
  149. }
  150. }
  151. },
  152. /**
  153. * @param {*} event
  154. */
  155. rowMouseOut: function (event) {
  156. var element = Event.findElement(event, 'tr');
  157. Element.removeClassName(element, 'on-mouse');
  158. },
  159. /**
  160. * @param {*} event
  161. */
  162. rowMouseDown: function (event) {
  163. this.targetElement = event.target;
  164. },
  165. /**
  166. * @param {*} event
  167. */
  168. rowMouseClick: function (event) {
  169. if (this.rowClickCallback) {
  170. try {
  171. this.rowClickCallback(this, event);
  172. } catch (e) {
  173. }
  174. }
  175. varienGlobalEvents.fireEvent('gridRowClick', event);
  176. this.targetElement = undefined;
  177. },
  178. /**
  179. * @param {*} event
  180. */
  181. rowMouseDblClick: function (event) {
  182. varienGlobalEvents.fireEvent('gridRowDblClick', event);
  183. },
  184. /**
  185. * Key press.
  186. */
  187. keyPress: function () {
  188. },
  189. /**
  190. * @param {*} event
  191. * @return {Boolean}
  192. */
  193. doSort: function (event) {
  194. var element = Event.findElement(event, 'th');
  195. if (element.readAttribute('data-sort') && element.readAttribute('data-direction')) {
  196. this.addVarToUrl(this.sortVar, element.readAttribute('data-sort'));
  197. this.addVarToUrl(this.dirVar, element.readAttribute('data-direction'));
  198. this.reload(this.url);
  199. }
  200. Event.stop(event);
  201. return false;
  202. },
  203. /**
  204. * @param {Object} element
  205. */
  206. loadByElement: function (element) {
  207. if (element && element.name) {
  208. this.reload(this.addVarToUrl(element.name, element.value));
  209. }
  210. },
  211. /**
  212. * @param {*} data
  213. * @param {*} textStatus
  214. * @param {*} transport
  215. * @private
  216. */
  217. _onAjaxSeccess: function (data, textStatus, transport) {
  218. var responseText, response, divId;
  219. /* eslint-disable max-depth */
  220. try {
  221. responseText = transport.responseText;
  222. if (transport.responseText.isJSON()) {
  223. response = transport.responseText.evalJSON();
  224. if (response.error) {
  225. alert({
  226. content: response.message
  227. });
  228. }
  229. if (response.ajaxExpired && response.ajaxRedirect) {
  230. setLocation(response.ajaxRedirect);
  231. }
  232. } else {
  233. /*eslint-disable max-len*/
  234. /**
  235. * For IE <= 7.
  236. * If there are two elements, and first has name, that equals id of second.
  237. * In this case, IE will choose one that is above
  238. *
  239. * @see https://prototype.lighthouseapp.com/projects/8886/tickets/994-id-selector-finds-elements-by-name-attribute-in-ie7
  240. */
  241. /*eslint-enable max-len*/
  242. divId = $(this.containerId);
  243. if (divId.id == this.containerId) { //eslint-disable-line eqeqeq
  244. divId.update(responseText);
  245. } else {
  246. $$('div[id="' + this.containerId + '"]')[0].update(responseText);
  247. }
  248. }
  249. } catch (e) {
  250. divId = $(this.containerId);
  251. if (divId.id == this.containerId) { //eslint-disable-line eqeqeq
  252. divId.update(responseText);
  253. } else {
  254. $$('div[id="' + this.containerId + '"]')[0].update(responseText);
  255. }
  256. }
  257. /* eslint-enable max-depth */
  258. jQuery('#' + this.containerId).trigger('contentUpdated');
  259. },
  260. /**
  261. * @param {*} url
  262. * @param {Function} onSuccessCallback
  263. * @return {*}
  264. */
  265. reload: function (url, onSuccessCallback) {
  266. var ajaxSettings, ajaxRequest;
  267. this.reloadParams = this.reloadParams || {};
  268. this.reloadParams['form_key'] = FORM_KEY;
  269. url = url || this.url;
  270. if (this.useAjax) {
  271. ajaxSettings = {
  272. url: url + (url.match(new RegExp('\\?')) ? '&ajax=true' : '?ajax=true'),
  273. showLoader: true,
  274. method: 'post',
  275. context: jQuery('#' + this.containerId),
  276. data: this.reloadParams,
  277. error: this._processFailure.bind(this),
  278. complete: this.initGridAjax.bind(this),
  279. dataType: 'html',
  280. /**
  281. * Success callback.
  282. */
  283. success: function (data, textStatus, transport) {
  284. this._onAjaxSeccess(data, textStatus, transport);
  285. if (onSuccessCallback && typeof onSuccessCallback === 'function') {
  286. // execute the callback, passing parameters as necessary
  287. onSuccessCallback();
  288. }
  289. }.bind(this)
  290. };
  291. jQuery('#' + this.containerId).trigger('gridajaxsettings', ajaxSettings);
  292. ajaxRequest = jQuery.ajax(ajaxSettings);
  293. jQuery('#' + this.containerId).trigger('gridajax', ajaxRequest);
  294. return ajaxRequest;
  295. }
  296. if (this.reloadParams) {
  297. $H(this.reloadParams).each(function (pair) {
  298. url = this.addVarToUrl(pair.key, pair.value);
  299. }.bind(this));
  300. }
  301. location.href = url;
  302. },
  303. /**
  304. * @private
  305. */
  306. _processFailure: function () {
  307. location.href = BASE_URL;
  308. },
  309. /**
  310. * @param {*} url
  311. * @param {*} varName
  312. * @param {*} varValue
  313. * @return {String|*}
  314. * @private
  315. */
  316. _addVarToUrl: function (url, varName, varValue) {
  317. var re = new RegExp('\/(' + varName + '\/.*?\/)'),
  318. parts = url.split(new RegExp('\\?'));
  319. url = parts[0].replace(re, '/');
  320. url += varName + '/' + varValue + '/';
  321. if (parts.size() > 1) {
  322. url += '?' + parts[1];
  323. }
  324. return url;
  325. },
  326. /**
  327. * Builds the form with fields containing the and submits
  328. *
  329. * @param {String} url
  330. * @param {String} varName
  331. * @param {String} varValue
  332. * @private
  333. */
  334. _buildFormAndSubmit: function (url, varName, varValue) {
  335. var re = new RegExp('\/(' + varName + '\/.*?\/)'),
  336. parts = url.split(new RegExp('\\?')),
  337. form = jQuery('<form></form>'),
  338. inputProps = [
  339. {
  340. name: varName,
  341. value: varValue
  342. },
  343. {
  344. name: 'form_key',
  345. value: window.FORM_KEY
  346. }
  347. ],
  348. input;
  349. url = parts[0].replace(re, '/');
  350. if (parts.size() > 1) {
  351. url += '?' + parts[1];
  352. }
  353. form.attr('action', url);
  354. form.attr('method', 'POST');
  355. inputProps.forEach(function (item) {
  356. input = jQuery('<input/>');
  357. input.attr('name', item.name);
  358. input.attr('type', 'hidden');
  359. input.val(item.value);
  360. form.append(input);
  361. });
  362. jQuery('[data-container="body"]').append(form);
  363. form.submit();
  364. form.remove();
  365. },
  366. /**
  367. * @param {*} varName
  368. * @param {*} varValue
  369. * @return {*|String}
  370. */
  371. addVarToUrl: function (varName, varValue) {
  372. this.url = this._addVarToUrl(this.url, varName, varValue);
  373. return this.url;
  374. },
  375. /**
  376. * Do export.
  377. */
  378. doExport: function () {
  379. var exportUrl;
  380. if ($(this.containerId + '_export')) {
  381. exportUrl = $(this.containerId + '_export').value;
  382. if (this.massaction && this.massaction.checkedString) {
  383. this._buildFormAndSubmit(
  384. exportUrl,
  385. this.massaction.formFieldNameInternal,
  386. this.massaction.checkedString
  387. );
  388. } else {
  389. location.href = exportUrl;
  390. }
  391. }
  392. },
  393. /**
  394. * Bind filter fields.
  395. */
  396. bindFilterFields: function () {
  397. var filters = $$(
  398. '#' + this.containerId + ' [data-role="filter-form"] input',
  399. '#' + this.containerId + ' [data-role="filter-form"] select'
  400. ),
  401. i;
  402. for (i = 0; i < filters.length; i++) {
  403. Event.observe(filters[i], 'keypress', this.filterKeyPress.bind(this));
  404. }
  405. },
  406. /**
  407. * Bind field change.
  408. */
  409. bindFieldsChange: function () {
  410. var dataElements, i;
  411. if (!$(this.containerId)) {
  412. return;
  413. }
  414. //var dataElements = $(this.containerId+this.tableSufix).down('.data tbody').select('input', 'select');
  415. // eslint-disable-next-line jquery-no-input-event-shorthand
  416. dataElements = $(this.containerId + this.tableSufix).down('tbody').select('input', 'select');
  417. for (i = 0; i < dataElements.length; i++) {
  418. Event.observe(dataElements[i], 'change', dataElements[i].setHasChanges.bind(dataElements[i]));
  419. }
  420. },
  421. /**
  422. * Bind sortable.
  423. */
  424. bindSortable: function () {
  425. if (jQuery('#' + this.containerId).find('.draggable-handle').length) {
  426. jQuery('#' + this.containerId).find('tbody').sortable({
  427. axis: 'y',
  428. handle: '.draggable-handle',
  429. /**
  430. * @param {*} event
  431. * @param {*} ui
  432. * @return {*}
  433. */
  434. helper: function (event, ui) {
  435. ui.children().each(function () {
  436. jQuery(this).width(jQuery(this).width());
  437. });
  438. return ui;
  439. },
  440. update: this.sortableUpdateCallback ? this.sortableUpdateCallback : function () {
  441. },
  442. tolerance: 'pointer'
  443. });
  444. }
  445. },
  446. /**
  447. * @param {Object} event
  448. */
  449. filterKeyPress: function (event) {
  450. if (event.keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq
  451. this.doFilter();
  452. }
  453. if (this.filterKeyPressCallback) {
  454. this.filterKeyPressCallback(this, event);
  455. }
  456. },
  457. /**
  458. * @param {Function} callback
  459. */
  460. doFilter: function (callback) {
  461. var filters = $$(
  462. '#' + this.containerId + ' [data-role="filter-form"] input',
  463. '#' + this.containerId + ' [data-role="filter-form"] select'
  464. ),
  465. elements = [],
  466. i;
  467. for (i in filters) {
  468. if (filters[i].value && filters[i].value.length) {
  469. elements.push(filters[i]);
  470. }
  471. }
  472. if (!this.doFilterCallback || this.doFilterCallback && this.doFilterCallback()) {
  473. this.reload(
  474. this.addVarToUrl(this.filterVar, Base64.encode(Form.serializeElements(elements))),
  475. callback
  476. );
  477. }
  478. },
  479. /**
  480. * @param {Function} callback
  481. */
  482. resetFilter: function (callback) {
  483. this.reload(this.addVarToUrl(this.filterVar, ''), callback);
  484. },
  485. /**
  486. * @param {Object} element
  487. */
  488. checkCheckboxes: function (element) {
  489. var elements = Element.select($(this.containerId), 'input[name="' + element.name + '"]'),
  490. i;
  491. for (i = 0; i < elements.length; i++) {
  492. this.setCheckboxChecked(elements[i], element.checked);
  493. }
  494. /*eslint-enable no-undef*/
  495. },
  496. /**
  497. *
  498. * @param {HTMLElement} element
  499. * @param {*} checked
  500. */
  501. setCheckboxChecked: function (element, checked) {
  502. element.checked = checked;
  503. jQuery(element).trigger('change');
  504. element.setHasChanges({});
  505. if (this.checkboxCheckCallback) {
  506. this.checkboxCheckCallback(this, element, checked);
  507. }
  508. },
  509. /**
  510. * @param {Object} event
  511. * @param {*} lastId
  512. */
  513. inputPage: function (event, lastId) {
  514. var element = Event.element(event),
  515. keyCode = event.keyCode || event.which,
  516. enteredValue = parseInt(element.value, 10),
  517. pageId = parseInt(lastId, 10);
  518. if (keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq
  519. if (enteredValue > pageId) {
  520. this.setPage(pageId);
  521. } else {
  522. this.setPage(enteredValue);
  523. }
  524. }
  525. /*if(keyCode>47 && keyCode<58){
  526. }
  527. else{
  528. Event.stop(event);
  529. }*/
  530. },
  531. /**
  532. * @param {*} pageNumber
  533. */
  534. setPage: function (pageNumber) {
  535. this.reload(this.addVarToUrl(this.pageVar, pageNumber));
  536. }
  537. };
  538. window.varienGridMassaction = Class.create();
  539. varienGridMassaction.prototype = {
  540. /* Predefined vars */
  541. checkedValues: $H({}),
  542. checkedString: '',
  543. oldCallbacks: {},
  544. errorText: '',
  545. items: {},
  546. gridIds: [],
  547. useSelectAll: false,
  548. currentItem: false,
  549. lastChecked: {
  550. left: false,
  551. top: false,
  552. checkbox: false
  553. },
  554. fieldTemplate: mageTemplate('<input type="hidden" name="<%- name %>" value="<%- value %>" />'),
  555. /**
  556. * @param {*} containerId
  557. * @param {*} grid
  558. * @param {*} checkedValues
  559. * @param {*} formFieldNameInternal
  560. * @param {*} formFieldName
  561. */
  562. initialize: function (containerId, grid, checkedValues, formFieldNameInternal, formFieldName) {
  563. this.setOldCallback('row_click', grid.rowClickCallback);
  564. this.setOldCallback('init', grid.initCallback);
  565. this.setOldCallback('init_row', grid.initRowCallback);
  566. this.setOldCallback('pre_init', grid.preInitCallback);
  567. this.useAjax = false;
  568. this.grid = grid;
  569. this.grid.massaction = this;
  570. this.containerId = containerId;
  571. this.initMassactionElements();
  572. this.checkedString = checkedValues;
  573. this.formFieldName = formFieldName;
  574. this.formFieldNameInternal = formFieldNameInternal;
  575. this.grid.initCallback = this.onGridInit.bind(this);
  576. this.grid.preInitCallback = this.onGridPreInit.bind(this);
  577. this.grid.initRowCallback = this.onGridRowInit.bind(this);
  578. this.grid.rowClickCallback = this.onGridRowClick.bind(this);
  579. this.initCheckboxes();
  580. this.checkCheckboxes();
  581. },
  582. /**
  583. * @param {*} flag
  584. */
  585. setUseAjax: function (flag) {
  586. this.useAjax = flag;
  587. },
  588. /**
  589. * @param {*} flag
  590. */
  591. setUseSelectAll: function (flag) {
  592. this.useSelectAll = flag;
  593. },
  594. /**
  595. * Init massaction elements.
  596. */
  597. initMassactionElements: function () {
  598. this.container = $(this.containerId);
  599. this.multiselect = $(this.containerId + '-mass-select');
  600. this.count = $(this.containerId + '-count');
  601. this.formHiddens = $(this.containerId + '-form-hiddens');
  602. this.formAdditional = $(this.containerId + '-form-additional');
  603. this.select = $(this.containerId + '-select');
  604. this.form = this.prepareForm();
  605. jQuery(this.form).mage('validation');
  606. this.select.observe('change', this.onSelectChange.bindAsEventListener(this));
  607. this.lastChecked = {
  608. left: false,
  609. top: false,
  610. checkbox: false
  611. };
  612. this.select.addClassName(this.select.value ? '_selected' : '');
  613. this.initMassSelect();
  614. },
  615. /**
  616. * @return {jQuery|*|HTMLElement}
  617. */
  618. prepareForm: function () {
  619. var form = $(this.containerId + '-form'),
  620. formPlace = null,
  621. formElement = this.formHiddens || this.formAdditional;
  622. if (!formElement) {
  623. formElement = this.container.getElementsByTagName('button')[0];
  624. formElement && formElement.parentNode;
  625. }
  626. if (!form && formElement) {
  627. /* fix problem with rendering form in FF through innerHTML property */
  628. form = document.createElement('form');
  629. form.setAttribute('method', 'post');
  630. form.setAttribute('action', '');
  631. form.id = this.containerId + '-form';
  632. formPlace = formElement.parentNode;
  633. formPlace.parentNode.appendChild(form);
  634. form.appendChild(formPlace);
  635. }
  636. return form;
  637. },
  638. /**
  639. * @param {Array} gridIds
  640. */
  641. setGridIds: function (gridIds) {
  642. this.gridIds = gridIds;
  643. this.updateCount();
  644. },
  645. /**
  646. * @return {Array}
  647. */
  648. getGridIds: function () {
  649. return this.gridIds;
  650. },
  651. /**
  652. * @param {*} items
  653. */
  654. setItems: function (items) {
  655. this.items = items;
  656. this.updateCount();
  657. },
  658. /**
  659. * @return {Object}
  660. */
  661. getItems: function () {
  662. return this.items;
  663. },
  664. /**
  665. * @param {*} itemId
  666. * @return {*}
  667. */
  668. getItem: function (itemId) {
  669. if (this.items[itemId]) {
  670. return this.items[itemId];
  671. }
  672. return false;
  673. },
  674. /**
  675. * @param {String} callbackName
  676. * @return {Function}
  677. */
  678. getOldCallback: function (callbackName) {
  679. return this.oldCallbacks[callbackName] ? this.oldCallbacks[callbackName] : Prototype.emptyFunction;
  680. },
  681. /**
  682. * @param {String} callbackName
  683. * @param {Function} callback
  684. */
  685. setOldCallback: function (callbackName, callback) {
  686. this.oldCallbacks[callbackName] = callback;
  687. },
  688. /**
  689. * @param {*} grid
  690. */
  691. onGridPreInit: function (grid) {
  692. this.initMassactionElements();
  693. this.getOldCallback('pre_init')(grid);
  694. },
  695. /**
  696. * @param {*} grid
  697. */
  698. onGridInit: function (grid) {
  699. this.initCheckboxes();
  700. this.checkCheckboxes();
  701. this.updateCount();
  702. this.getOldCallback('init')(grid);
  703. },
  704. /**
  705. * @param {*} grid
  706. * @param {*} row
  707. */
  708. onGridRowInit: function (grid, row) {
  709. this.getOldCallback('init_row')(grid, row);
  710. },
  711. /**
  712. * @param {Object} evt
  713. */
  714. isDisabled: function (evt) {
  715. var target = jQuery(evt.target),
  716. tr,
  717. checkbox;
  718. tr = target.is('tr') ? target : target.closest('tr');
  719. checkbox = tr.find('input[type="checkbox"]');
  720. return checkbox.is(':disabled');
  721. },
  722. /**
  723. * @param {*} grid
  724. * @param {*} evt
  725. * @return {*}
  726. */
  727. onGridRowClick: function (grid, evt) {
  728. var tdElement = Event.findElement(evt, 'td'),
  729. trElement = Event.findElement(evt, 'tr'),
  730. checkbox, isInput, checked;
  731. if (this.isDisabled(evt)) {
  732. return false;
  733. }
  734. if (!$(tdElement).down('input')) {
  735. if ($(tdElement).down('a') || $(tdElement).down('select')) {
  736. return; //eslint-disable-line
  737. }
  738. if (trElement.title && trElement.title.strip() != '#') { //eslint-disable-line eqeqeq
  739. this.getOldCallback('row_click')(grid, evt);
  740. } else {
  741. checkbox = Element.select(trElement, 'input');
  742. isInput = Event.element(evt).tagName == 'input'; //eslint-disable-line eqeqeq
  743. checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
  744. if (checked) { //eslint-disable-line max-depth
  745. this.checkedString = varienStringArray.add(checkbox[0].value, this.checkedString);
  746. } else {
  747. this.checkedString = varienStringArray.remove(checkbox[0].value, this.checkedString);
  748. }
  749. this.grid.setCheckboxChecked(checkbox[0], checked);
  750. this.updateCount();
  751. }
  752. return; //eslint-disable-line
  753. }
  754. if (Event.element(evt).isMassactionCheckbox) {
  755. this.setCheckbox(Event.element(evt));
  756. } else if (checkbox = this.findCheckbox(evt)) { //eslint-disable-line no-cond-assign
  757. checkbox.checked = !checkbox.checked;
  758. jQuery(checkbox).trigger('change');
  759. this.setCheckbox(checkbox);
  760. }
  761. },
  762. /**
  763. * @param {Object} evt
  764. */
  765. onSelectChange: function (evt) {
  766. var item = this.getSelectedItem();
  767. if (item) {
  768. this.formAdditional.update($(this.containerId + '-item-' + item.id + '-block').innerHTML);
  769. evt.target.addClassName('_selected');
  770. } else {
  771. this.formAdditional.update('');
  772. evt.target.removeClassName('_selected');
  773. }
  774. jQuery(this.form).data('validator').resetForm();
  775. },
  776. /**
  777. * @param {Object} evt
  778. * @return {*}
  779. */
  780. findCheckbox: function (evt) {
  781. if (['a', 'input', 'select'].indexOf(Event.element(evt).tagName.toLowerCase()) !== -1) {
  782. return false;
  783. }
  784. checkbox = false; //eslint-disable-line no-undef
  785. Event.findElement(evt, 'tr').select('[data-role="select-row"]').each(function (element) { //eslint-disable-line
  786. if (element.isMassactionCheckbox) {
  787. checkbox = element; //eslint-disable-line no-undef
  788. }
  789. });
  790. return checkbox; //eslint-disable-line no-undef
  791. },
  792. /**
  793. * Init checkobox.
  794. */
  795. initCheckboxes: function () {
  796. this.getCheckboxes().each(function (checkbox) { //eslint-disable-line no-extra-bind
  797. checkbox.isMassactionCheckbox = true; //eslint-disable-line no-undef
  798. });
  799. },
  800. /**
  801. * Check checkbox.
  802. */
  803. checkCheckboxes: function () {
  804. this.getCheckboxes().each(function (checkbox) {
  805. checkbox.checked = varienStringArray.has(checkbox.value, this.checkedString);
  806. jQuery(checkbox).trigger('change');
  807. }.bind(this));
  808. },
  809. /**
  810. * @return {Boolean}
  811. */
  812. selectAll: function () {
  813. this.setCheckedValues(this.useSelectAll ? this.getGridIds() : this.getCheckboxesValuesAsString());
  814. this.checkCheckboxes();
  815. this.updateCount();
  816. this.clearLastChecked();
  817. return false;
  818. },
  819. /**
  820. * @return {Boolean}
  821. */
  822. unselectAll: function () {
  823. this.setCheckedValues('');
  824. this.checkCheckboxes();
  825. this.updateCount();
  826. this.clearLastChecked();
  827. return false;
  828. },
  829. /**
  830. * @return {Boolean}
  831. */
  832. selectVisible: function () {
  833. this.setCheckedValues(this.getCheckboxesValuesAsString());
  834. this.checkCheckboxes();
  835. this.updateCount();
  836. this.clearLastChecked();
  837. return false;
  838. },
  839. /**
  840. * @return {Boolean}
  841. */
  842. unselectVisible: function () {
  843. this.getCheckboxesValues().each(function (key) {
  844. this.checkedString = varienStringArray.remove(key, this.checkedString);
  845. }.bind(this));
  846. this.checkCheckboxes();
  847. this.updateCount();
  848. this.clearLastChecked();
  849. return false;
  850. },
  851. /**
  852. * @param {*} values
  853. */
  854. setCheckedValues: function (values) {
  855. this.checkedString = values;
  856. },
  857. /**
  858. * @return {String}
  859. */
  860. getCheckedValues: function () {
  861. return this.checkedString;
  862. },
  863. /**
  864. * @return {Array}
  865. */
  866. getCheckboxes: function () {
  867. var result = [];
  868. this.grid.rows.each(function (row) {
  869. var checkboxes = row.select('[data-role="select-row"]');
  870. checkboxes.each(function (checkbox) {
  871. result.push(checkbox);
  872. });
  873. });
  874. return result;
  875. },
  876. /**
  877. * @return {Array}
  878. */
  879. getCheckboxesValues: function () {
  880. var result = [];
  881. this.getCheckboxes().each(function (checkbox) { //eslint-disable-line no-extra-bind
  882. result.push(checkbox.value);
  883. });
  884. return result;
  885. },
  886. /**
  887. * @return {String}
  888. */
  889. getCheckboxesValuesAsString: function () {
  890. return this.getCheckboxesValues().join(',');
  891. },
  892. /**
  893. * @param {Object} checkbox
  894. */
  895. setCheckbox: function (checkbox) {
  896. if (checkbox.checked) {
  897. this.checkedString = varienStringArray.add(checkbox.value, this.checkedString);
  898. } else {
  899. this.checkedString = varienStringArray.remove(checkbox.value, this.checkedString);
  900. }
  901. this.updateCount();
  902. },
  903. /**
  904. * Update count.
  905. */
  906. updateCount: function () {
  907. var checkboxesTotal = varienStringArray.count(
  908. this.useSelectAll ? this.getGridIds() : this.getCheckboxesValuesAsString()
  909. ),
  910. checkboxesChecked = varienStringArray.count(this.checkedString);
  911. jQuery('[data-role="counter"]', this.count).html(checkboxesChecked);
  912. if (!checkboxesTotal) {
  913. this.multiselect.addClassName('_disabled');
  914. } else {
  915. this.multiselect.removeClassName('_disabled');
  916. }
  917. if (checkboxesChecked == checkboxesTotal && checkboxesTotal != 0) { //eslint-disable-line eqeqeq
  918. this.count.removeClassName('_empty');
  919. this.multiselect.addClassName('_checked').removeClassName('_indeterminate');
  920. } else if (checkboxesChecked == 0) { //eslint-disable-line eqeqeq
  921. this.count.addClassName('_empty');
  922. this.multiselect.removeClassName('_checked').removeClassName('_indeterminate');
  923. } else {
  924. this.count.removeClassName('_empty');
  925. this.multiselect.addClassName('_checked').addClassName('_indeterminate');
  926. }
  927. if (!this.grid.reloadParams) {
  928. this.grid.reloadParams = {};
  929. }
  930. this.grid.reloadParams[this.formFieldNameInternal] = this.checkedString;
  931. },
  932. /**
  933. * @return {*}
  934. */
  935. getSelectedItem: function () {
  936. if (this.getItem(this.select.value)) {
  937. return this.getItem(this.select.value);
  938. }
  939. return false;
  940. },
  941. /**
  942. * Apply.
  943. */
  944. apply: function () {
  945. var item, fieldName;
  946. if (varienStringArray.count(this.checkedString) == 0) { //eslint-disable-line eqeqeq
  947. alert({
  948. content: this.errorText
  949. });
  950. return;
  951. }
  952. item = this.getSelectedItem();
  953. if (!item) {
  954. jQuery(this.form).valid();
  955. return;
  956. }
  957. this.currentItem = item;
  958. fieldName = item.field ? item.field : this.formFieldName;
  959. if (this.currentItem.confirm) {
  960. confirm({
  961. content: this.currentItem.confirm,
  962. actions: {
  963. confirm: this.onConfirm.bind(this, fieldName, item)
  964. }
  965. });
  966. } else {
  967. this.onConfirm(fieldName, item);
  968. }
  969. },
  970. /**
  971. * @param {*} fieldName
  972. * @param {*} item
  973. */
  974. onConfirm: function (fieldName, item) {
  975. this.formHiddens.update('');
  976. new Insertion.Bottom(this.formHiddens, this.fieldTemplate({
  977. name: fieldName,
  978. value: this.checkedString
  979. }));
  980. new Insertion.Bottom(this.formHiddens, this.fieldTemplate({
  981. name: 'massaction_prepare_key',
  982. value: fieldName
  983. }));
  984. if (!jQuery(this.form).valid()) {
  985. return;
  986. }
  987. if (this.useAjax && item.url) {
  988. new Ajax.Request(item.url, {
  989. 'method': 'post',
  990. 'parameters': this.form.serialize(true),
  991. 'onComplete': this.onMassactionComplete.bind(this)
  992. });
  993. } else if (item.url) {
  994. this.form.action = item.url;
  995. this.form.submit();
  996. }
  997. },
  998. /**
  999. * @param {*} transport
  1000. */
  1001. onMassactionComplete: function (transport) {
  1002. var listener;
  1003. if (this.currentItem.complete) {
  1004. try {
  1005. listener = this.getListener(this.currentItem.complete) || Prototype.emptyFunction;
  1006. listener(this.grid, this, transport);
  1007. } catch (e) {
  1008. }
  1009. }
  1010. },
  1011. /**
  1012. * @param {*} strValue
  1013. * @return {Object}
  1014. */
  1015. getListener: function (strValue) {
  1016. return eval(strValue); //eslint-disable-line no-eval
  1017. },
  1018. /**
  1019. * Init mass select.
  1020. */
  1021. initMassSelect: function () {
  1022. $$('input[data-role="select-row"]').each(function (element) {
  1023. element.observe('click', this.massSelect.bind(this));
  1024. }.bind(this));
  1025. },
  1026. /**
  1027. * Clear last checked.
  1028. */
  1029. clearLastChecked: function () {
  1030. this.lastChecked = {
  1031. left: false,
  1032. top: false,
  1033. checkbox: false
  1034. };
  1035. },
  1036. /**
  1037. * @param {Object} evt
  1038. */
  1039. massSelect: function (evt) {
  1040. var currentCheckbox, lastCheckbox, start, finish;
  1041. if (this.lastChecked.left !== false &&
  1042. this.lastChecked.top !== false &&
  1043. evt.button === 0 &&
  1044. evt.shiftKey === true
  1045. ) {
  1046. currentCheckbox = Event.element(evt);
  1047. lastCheckbox = this.lastChecked.checkbox;
  1048. if (lastCheckbox != currentCheckbox) { //eslint-disable-line eqeqeq
  1049. start = this.getCheckboxOrder(lastCheckbox);
  1050. finish = this.getCheckboxOrder(currentCheckbox);
  1051. if (start !== false && finish !== false) { //eslint-disable-line max-depth
  1052. this.selectCheckboxRange(
  1053. Math.min(start, finish),
  1054. Math.max(start, finish),
  1055. currentCheckbox.checked
  1056. );
  1057. }
  1058. }
  1059. }
  1060. this.lastChecked = {
  1061. left: Event.element(evt).viewportOffset().left,
  1062. top: Event.element(evt).viewportOffset().top,
  1063. checkbox: Event.element(evt) // "boundary" checkbox
  1064. };
  1065. },
  1066. /**
  1067. * @param {*} curCheckbox
  1068. * @return {Boolean}
  1069. */
  1070. getCheckboxOrder: function (curCheckbox) {
  1071. var order = false;
  1072. this.getCheckboxes().each(function (checkbox, key) {
  1073. if (curCheckbox == checkbox) { //eslint-disable-line eqeqeq
  1074. order = key;
  1075. }
  1076. });
  1077. return order;
  1078. },
  1079. /**
  1080. * @param {*} start
  1081. * @param {*} finish
  1082. * @param {*} isChecked
  1083. */
  1084. selectCheckboxRange: function (start, finish, isChecked) {
  1085. this.getCheckboxes().each(function (checkbox, key) {
  1086. if (key >= start && key <= finish) {
  1087. checkbox.checked = isChecked;
  1088. this.setCheckbox(checkbox);
  1089. }
  1090. }.bind(this));
  1091. }
  1092. };
  1093. window.varienGridAction = {
  1094. /**
  1095. * @param {Object} select
  1096. */
  1097. execute: function (select) {
  1098. var config, win;
  1099. if (!select.value || !select.value.isJSON()) {
  1100. return;
  1101. }
  1102. config = select.value.evalJSON();
  1103. if (config.confirm && !window.confirm(config.confirm)) { //eslint-disable-line no-alert
  1104. select.options[0].selected = true;
  1105. return;
  1106. }
  1107. if (config.popup) {
  1108. win = window.open(config.href, 'action_window', 'width=500,height=600,resizable=1,scrollbars=1');
  1109. win.focus();
  1110. select.options[0].selected = true;
  1111. } else {
  1112. setLocation(config.href);
  1113. }
  1114. }
  1115. };
  1116. window.varienStringArray = {
  1117. /**
  1118. * @param {*} str
  1119. * @param {*} haystack
  1120. * @return {*}
  1121. */
  1122. remove: function (str, haystack) {
  1123. haystack = ',' + haystack + ',';
  1124. haystack = haystack.replace(new RegExp(',' + str + ',', 'g'), ',');
  1125. return this.trimComma(haystack);
  1126. },
  1127. /**
  1128. * @param {*} str
  1129. * @param {*} haystack
  1130. * @return {*}
  1131. */
  1132. add: function (str, haystack) {
  1133. haystack = ',' + haystack + ',';
  1134. if (haystack.search(new RegExp(',' + str + ',', 'g'), haystack) === -1) {
  1135. haystack += str + ',';
  1136. }
  1137. return this.trimComma(haystack);
  1138. },
  1139. /**
  1140. * @param {*} str
  1141. * @param {*} haystack
  1142. * @return {Boolean}
  1143. */
  1144. has: function (str, haystack) {
  1145. haystack = ',' + haystack + ',';
  1146. if (haystack.search(new RegExp(',' + str + ',', 'g'), haystack) === -1) {
  1147. return false;
  1148. }
  1149. return true;
  1150. },
  1151. /**
  1152. * @param {*} haystack
  1153. * @return {*}
  1154. */
  1155. count: function (haystack) {
  1156. var match;
  1157. if (typeof haystack != 'string') {
  1158. return 0;
  1159. }
  1160. /* eslint-disable no-undef, no-cond-assign, eqeqeq */
  1161. if (match = haystack.match(new RegExp(',', 'g'))) {
  1162. return match.length + 1;
  1163. } else if (haystack.length != 0) {
  1164. return 1;
  1165. }
  1166. /* eslint-enable no-undef, no-cond-assign, eqeqeq */
  1167. return 0;
  1168. },
  1169. /**
  1170. * @param {*} haystack
  1171. * @param {*} fnc
  1172. */
  1173. each: function (haystack, fnc) {
  1174. var i;
  1175. haystack = haystack.split(',');
  1176. for (i = 0; i < haystack.length; i++) {
  1177. fnc(haystack[i]);
  1178. }
  1179. },
  1180. /**
  1181. * @param {String} string
  1182. * @return {String}
  1183. */
  1184. trimComma: function (string) {
  1185. string = string.replace(new RegExp('^(,+)', 'i'), '');
  1186. string = string.replace(new RegExp('(,+)$', 'i'), '');
  1187. return string;
  1188. }
  1189. };
  1190. window.serializerController = Class.create();
  1191. serializerController.prototype = {
  1192. oldCallbacks: {},
  1193. /**
  1194. * @param {*} hiddenDataHolder
  1195. * @param {*} predefinedData
  1196. * @param {*} inputsToManage
  1197. * @param {*} grid
  1198. * @param {*} reloadParamName
  1199. */
  1200. initialize: function (hiddenDataHolder, predefinedData, inputsToManage, grid, reloadParamName) {
  1201. //Grid inputs
  1202. this.tabIndex = 1000;
  1203. this.inputsToManage = inputsToManage;
  1204. this.multidimensionalMode = inputsToManage.length > 0;
  1205. //Hash with grid data
  1206. this.gridData = this.getGridDataHash(predefinedData);
  1207. //Hidden input data holder
  1208. this.hiddenDataHolder = $(hiddenDataHolder);
  1209. this.hiddenDataHolder.value = this.serializeObject();
  1210. this.grid = grid;
  1211. // Set old callbacks
  1212. this.setOldCallback('row_click', this.grid.rowClickCallback);
  1213. this.setOldCallback('init_row', this.grid.initRowCallback);
  1214. this.setOldCallback('checkbox_check', this.grid.checkboxCheckCallback);
  1215. //Grid
  1216. this.reloadParamName = reloadParamName;
  1217. this.grid.reloadParams = {};
  1218. this.grid.reloadParams[this.reloadParamName + '[]'] = this.getDataForReloadParam();
  1219. this.grid.rowClickCallback = this.rowClick.bind(this);
  1220. this.grid.initRowCallback = this.rowInit.bind(this);
  1221. this.grid.checkboxCheckCallback = this.registerData.bind(this);
  1222. this.grid.rows.each(this.eachRow.bind(this));
  1223. },
  1224. /**
  1225. * @param {String} callbackName
  1226. * @param {Function} callback
  1227. */
  1228. setOldCallback: function (callbackName, callback) {
  1229. this.oldCallbacks[callbackName] = callback;
  1230. },
  1231. /**
  1232. * @param {String} callbackName
  1233. * @return {Prototype.emptyFunction}
  1234. */
  1235. getOldCallback: function (callbackName) {
  1236. return this.oldCallbacks[callbackName] ? this.oldCallbacks[callbackName] : Prototype.emptyFunction;
  1237. },
  1238. /**
  1239. * @param {*} grid
  1240. * @param {*} element
  1241. * @param {*} checked
  1242. */
  1243. registerData: function (grid, element, checked) {
  1244. var i;
  1245. if (this.multidimensionalMode) {
  1246. if (checked) {
  1247. /*eslint-disable max-depth*/
  1248. if (element.inputElements) {
  1249. this.gridData.set(element.value, {});
  1250. for (i = 0; i < element.inputElements.length; i++) {
  1251. element.inputElements[i].disabled = false;
  1252. this.gridData.get(element.value)[element.inputElements[i].name] =
  1253. element.inputElements[i].value;
  1254. }
  1255. }
  1256. } else {
  1257. if (element.inputElements) {
  1258. for (i = 0; i < element.inputElements.length; i++) {
  1259. element.inputElements[i].disabled = true;
  1260. }
  1261. }
  1262. this.gridData.unset(element.value);
  1263. }
  1264. } else {
  1265. if (checked) { //eslint-disable-line no-lonely-if
  1266. this.gridData.set(element.value, element.value);
  1267. } else {
  1268. this.gridData.unset(element.value);
  1269. }
  1270. }
  1271. this.hiddenDataHolder.value = this.serializeObject();
  1272. this.grid.reloadParams = {};
  1273. this.grid.reloadParams[this.reloadParamName + '[]'] = this.getDataForReloadParam();
  1274. this.getOldCallback('checkbox_check')(grid, element, checked);
  1275. /*eslint-enable max-depth*/
  1276. },
  1277. /**
  1278. * @param {*} row
  1279. */
  1280. eachRow: function (row) {
  1281. this.rowInit(this.grid, row);
  1282. },
  1283. /**
  1284. * @param {*} grid
  1285. * @param {*} event
  1286. */
  1287. rowClick: function (grid, event) {
  1288. var trElement = Event.findElement(event, 'tr'),
  1289. isInput = Event.element(event).tagName == 'INPUT', //eslint-disable-line eqeqeq
  1290. checkbox, checked;
  1291. if (trElement) {
  1292. // eslint-disable-next-line jquery-no-input-event-shorthand
  1293. checkbox = Element.select(trElement, 'input');
  1294. if (checkbox[0] && !checkbox[0].disabled) {
  1295. checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
  1296. this.grid.setCheckboxChecked(checkbox[0], checked);
  1297. }
  1298. }
  1299. this.getOldCallback('row_click')(grid, event);
  1300. },
  1301. /**
  1302. * @param {*} event
  1303. */
  1304. inputChange: function (event) {
  1305. var element = Event.element(event);
  1306. if (element && element.checkboxElement && element.checkboxElement.checked) {
  1307. this.gridData.get(element.checkboxElement.value)[element.name] = element.value;
  1308. this.hiddenDataHolder.value = this.serializeObject();
  1309. }
  1310. },
  1311. /**
  1312. * @param {*} grid
  1313. * @param {*} row
  1314. */
  1315. rowInit: function (grid, row) {
  1316. var checkbox, selectors, inputs, i;
  1317. if (this.multidimensionalMode) {
  1318. // eslint-disable-next-line jquery-no-input-event-shorthand
  1319. checkbox = $(row).select('.checkbox')[0];
  1320. selectors = this.inputsToManage.map(function (name) {
  1321. return ['input[name="' + name + '"]', 'select[name="' + name + '"]'];
  1322. });
  1323. inputs = $(row).select.apply($(row), selectors.flatten());
  1324. if (checkbox && inputs.length > 0) {
  1325. checkbox.inputElements = inputs;
  1326. /* eslint-disable max-depth */
  1327. for (i = 0; i < inputs.length; i++) {
  1328. inputs[i].checkboxElement = checkbox;
  1329. if (this.gridData.get(checkbox.value) && this.gridData.get(checkbox.value)[inputs[i].name]) {
  1330. inputs[i].value = this.gridData.get(checkbox.value)[inputs[i].name];
  1331. }
  1332. inputs[i].disabled = !checkbox.checked;
  1333. inputs[i].tabIndex = this.tabIndex++;
  1334. Event.observe(inputs[i], 'keyup', this.inputChange.bind(this));
  1335. Event.observe(inputs[i], 'change', this.inputChange.bind(this));
  1336. }
  1337. }
  1338. }
  1339. /* eslint-enable max-depth */
  1340. this.getOldCallback('init_row')(grid, row);
  1341. },
  1342. /**
  1343. * Stuff methods.
  1344. *
  1345. * @param {*} _object
  1346. * @return {*}
  1347. */
  1348. getGridDataHash: function (_object) {
  1349. return $H(this.multidimensionalMode ? _object : this.convertArrayToObject(_object));
  1350. },
  1351. /**
  1352. * @return {*}
  1353. */
  1354. getDataForReloadParam: function () {
  1355. return this.multidimensionalMode ? this.gridData.keys() : this.gridData.values();
  1356. },
  1357. /**
  1358. * @return {*}
  1359. */
  1360. serializeObject: function () {
  1361. var clone;
  1362. if (this.multidimensionalMode) {
  1363. clone = this.gridData.clone();
  1364. clone.each(function (pair) {
  1365. clone.set(pair.key, Base64.encode(Object.toQueryString(pair.value)));
  1366. });
  1367. return clone.toQueryString();
  1368. }
  1369. return this.gridData.values().join('&');
  1370. },
  1371. /**
  1372. * @param {Array} _array
  1373. * @return {Object}
  1374. */
  1375. convertArrayToObject: function (_array) {
  1376. var _object = {},
  1377. i, l;
  1378. for (i = 0, l = _array.length; i < l; i++) {
  1379. _object[_array[i]] = _array[i];
  1380. }
  1381. return _object;
  1382. }
  1383. };
  1384. });