9f4146df1dae8537e301061b38a2373219ddec288ce717af20ff12a17ec19d5c5adf108ebf5f4236d7b5787c41bd82005a4a2c433f7583a3ef4322d001f423 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. 'use strict';
  2. exports.__esModule = true;
  3. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  4. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  5. var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
  6. var _moment = require('moment');
  7. var _moment2 = _interopRequireDefault(_moment);
  8. var _element = require('./../../helpers/dom/element');
  9. var _array = require('./../../helpers/array');
  10. var _mixed = require('./../../helpers/mixed');
  11. var _object = require('./../../helpers/object');
  12. var _base = require('./../_base');
  13. var _base2 = _interopRequireDefault(_base);
  14. var _plugins = require('./../../plugins');
  15. var _mergeSort = require('./../../utils/sortingAlgorithms/mergeSort');
  16. var _mergeSort2 = _interopRequireDefault(_mergeSort);
  17. var _pluginHooks = require('./../../pluginHooks');
  18. var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
  19. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  20. function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  21. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  22. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  23. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  24. _pluginHooks2.default.getSingleton().register('beforeColumnSort');
  25. _pluginHooks2.default.getSingleton().register('afterColumnSort');
  26. // TODO: Implement mixin arrayMapper to ColumnSorting plugin.
  27. /**
  28. * @plugin ColumnSorting
  29. *
  30. * @description
  31. * This plugin sorts the view by a column (but does not sort the data source!).
  32. * To enable the plugin, set the `columnSorting` property to either:
  33. * * a boolean value (`true`/`false`),
  34. * * an object defining the initial sorting order (see the example below).
  35. *
  36. * @example
  37. * ```js
  38. * ...
  39. * // as boolean
  40. * columnSorting: true
  41. * ...
  42. * // as a object with initial order (sort ascending column at index 2)
  43. * columnSorting: {
  44. * column: 2,
  45. * sortOrder: true, // true = ascending, false = descending, undefined = original order
  46. * sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
  47. * }
  48. * ...
  49. * ```
  50. * @dependencies ObserveChanges
  51. */
  52. var ColumnSorting = function (_BasePlugin) {
  53. _inherits(ColumnSorting, _BasePlugin);
  54. function ColumnSorting(hotInstance) {
  55. _classCallCheck(this, ColumnSorting);
  56. var _this2 = _possibleConstructorReturn(this, (ColumnSorting.__proto__ || Object.getPrototypeOf(ColumnSorting)).call(this, hotInstance));
  57. _this2.sortIndicators = [];
  58. _this2.lastSortedColumn = null;
  59. _this2.sortEmptyCells = false;
  60. return _this2;
  61. }
  62. /**
  63. * Check if the plugin is enabled in the handsontable settings.
  64. *
  65. * @returns {Boolean}
  66. */
  67. _createClass(ColumnSorting, [{
  68. key: 'isEnabled',
  69. value: function isEnabled() {
  70. return !!this.hot.getSettings().columnSorting;
  71. }
  72. /**
  73. * Enable plugin for this Handsontable instance.
  74. */
  75. }, {
  76. key: 'enablePlugin',
  77. value: function enablePlugin() {
  78. var _this3 = this;
  79. if (this.enabled) {
  80. return;
  81. }
  82. this.setPluginOptions();
  83. var _this = this;
  84. this.hot.sortIndex = [];
  85. this.hot.sort = function () {
  86. var args = Array.prototype.slice.call(arguments);
  87. return _this.sortByColumn.apply(_this, _toConsumableArray(args));
  88. };
  89. if (typeof this.hot.getSettings().observeChanges === 'undefined') {
  90. this.enableObserveChangesPlugin();
  91. }
  92. this.addHook('afterTrimRow', function (row) {
  93. return _this3.sort();
  94. });
  95. this.addHook('afterUntrimRow', function (row) {
  96. return _this3.sort();
  97. });
  98. this.addHook('modifyRow', function (row) {
  99. return _this3.translateRow(row);
  100. });
  101. this.addHook('unmodifyRow', function (row) {
  102. return _this3.untranslateRow(row);
  103. });
  104. this.addHook('afterUpdateSettings', function () {
  105. return _this3.onAfterUpdateSettings();
  106. });
  107. this.addHook('afterGetColHeader', function (col, TH) {
  108. return _this3.getColHeader(col, TH);
  109. });
  110. this.addHook('afterOnCellMouseDown', function (event, target) {
  111. return _this3.onAfterOnCellMouseDown(event, target);
  112. });
  113. this.addHook('afterCreateRow', function () {
  114. _this.afterCreateRow.apply(_this, arguments);
  115. });
  116. this.addHook('afterRemoveRow', function () {
  117. _this.afterRemoveRow.apply(_this, arguments);
  118. });
  119. this.addHook('afterInit', function () {
  120. return _this3.sortBySettings();
  121. });
  122. this.addHook('afterLoadData', function () {
  123. _this3.hot.sortIndex = [];
  124. if (_this3.hot.view) {
  125. _this3.sortBySettings();
  126. }
  127. });
  128. if (this.hot.view) {
  129. this.sortBySettings();
  130. }
  131. _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'enablePlugin', this).call(this);
  132. }
  133. /**
  134. * Disable plugin for this Handsontable instance.
  135. */
  136. }, {
  137. key: 'disablePlugin',
  138. value: function disablePlugin() {
  139. this.hot.sort = void 0;
  140. _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'disablePlugin', this).call(this);
  141. }
  142. /**
  143. * afterUpdateSettings callback.
  144. *
  145. * @private
  146. */
  147. }, {
  148. key: 'onAfterUpdateSettings',
  149. value: function onAfterUpdateSettings() {
  150. this.sortBySettings();
  151. }
  152. }, {
  153. key: 'sortBySettings',
  154. value: function sortBySettings() {
  155. var sortingSettings = this.hot.getSettings().columnSorting;
  156. var loadedSortingState = this.loadSortingState();
  157. var sortingColumn = void 0;
  158. var sortingOrder = void 0;
  159. if (typeof loadedSortingState === 'undefined') {
  160. sortingColumn = sortingSettings.column;
  161. sortingOrder = sortingSettings.sortOrder;
  162. } else {
  163. sortingColumn = loadedSortingState.sortColumn;
  164. sortingOrder = loadedSortingState.sortOrder;
  165. }
  166. if (typeof sortingColumn === 'number') {
  167. this.lastSortedColumn = sortingColumn;
  168. this.sortByColumn(sortingColumn, sortingOrder);
  169. }
  170. }
  171. /**
  172. * Set sorted column and order info
  173. *
  174. * @param {number} col Sorted column index.
  175. * @param {boolean|undefined} order Sorting order (`true` for ascending, `false` for descending).
  176. */
  177. }, {
  178. key: 'setSortingColumn',
  179. value: function setSortingColumn(col, order) {
  180. if (typeof col == 'undefined') {
  181. this.hot.sortColumn = void 0;
  182. this.hot.sortOrder = void 0;
  183. return;
  184. } else if (this.hot.sortColumn === col && typeof order == 'undefined') {
  185. if (this.hot.sortOrder === false) {
  186. this.hot.sortOrder = void 0;
  187. } else {
  188. this.hot.sortOrder = !this.hot.sortOrder;
  189. }
  190. } else {
  191. this.hot.sortOrder = typeof order === 'undefined' ? true : order;
  192. }
  193. this.hot.sortColumn = col;
  194. }
  195. }, {
  196. key: 'sortByColumn',
  197. value: function sortByColumn(col, order) {
  198. this.setSortingColumn(col, order);
  199. if (typeof this.hot.sortColumn == 'undefined') {
  200. return;
  201. }
  202. var allowSorting = this.hot.runHooks('beforeColumnSort', this.hot.sortColumn, this.hot.sortOrder);
  203. if (allowSorting !== false) {
  204. this.sort();
  205. }
  206. this.updateOrderClass();
  207. this.updateSortIndicator();
  208. this.hot.runHooks('afterColumnSort', this.hot.sortColumn, this.hot.sortOrder);
  209. this.hot.render();
  210. this.saveSortingState();
  211. }
  212. /**
  213. * Save the sorting state
  214. */
  215. }, {
  216. key: 'saveSortingState',
  217. value: function saveSortingState() {
  218. var sortingState = {};
  219. if (typeof this.hot.sortColumn != 'undefined') {
  220. sortingState.sortColumn = this.hot.sortColumn;
  221. }
  222. if (typeof this.hot.sortOrder != 'undefined') {
  223. sortingState.sortOrder = this.hot.sortOrder;
  224. }
  225. if ((0, _object.hasOwnProperty)(sortingState, 'sortColumn') || (0, _object.hasOwnProperty)(sortingState, 'sortOrder')) {
  226. this.hot.runHooks('persistentStateSave', 'columnSorting', sortingState);
  227. }
  228. }
  229. /**
  230. * Load the sorting state.
  231. *
  232. * @returns {*} Previously saved sorting state.
  233. */
  234. }, {
  235. key: 'loadSortingState',
  236. value: function loadSortingState() {
  237. var storedState = {};
  238. this.hot.runHooks('persistentStateLoad', 'columnSorting', storedState);
  239. return storedState.value;
  240. }
  241. /**
  242. * Update sorting class name state.
  243. */
  244. }, {
  245. key: 'updateOrderClass',
  246. value: function updateOrderClass() {
  247. var orderClass = void 0;
  248. if (this.hot.sortOrder === true) {
  249. orderClass = 'ascending';
  250. } else if (this.hot.sortOrder === false) {
  251. orderClass = 'descending';
  252. }
  253. this.sortOrderClass = orderClass;
  254. }
  255. }, {
  256. key: 'enableObserveChangesPlugin',
  257. value: function enableObserveChangesPlugin() {
  258. var _this = this;
  259. this.hot._registerTimeout(setTimeout(function () {
  260. _this.hot.updateSettings({
  261. observeChanges: true
  262. });
  263. }, 0));
  264. }
  265. /**
  266. * Default sorting algorithm.
  267. *
  268. * @param {Boolean} sortOrder Sorting order - `true` for ascending, `false` for descending.
  269. * @param {Object} columnMeta Column meta object.
  270. * @returns {Function} The comparing function.
  271. */
  272. }, {
  273. key: 'defaultSort',
  274. value: function defaultSort(sortOrder, columnMeta) {
  275. return function (a, b) {
  276. if (typeof a[1] == 'string') {
  277. a[1] = a[1].toLowerCase();
  278. }
  279. if (typeof b[1] == 'string') {
  280. b[1] = b[1].toLowerCase();
  281. }
  282. if (a[1] === b[1]) {
  283. return 0;
  284. }
  285. if ((0, _mixed.isEmpty)(a[1])) {
  286. if ((0, _mixed.isEmpty)(b[1])) {
  287. return 0;
  288. }
  289. if (columnMeta.columnSorting.sortEmptyCells) {
  290. return sortOrder ? -1 : 1;
  291. }
  292. return 1;
  293. }
  294. if ((0, _mixed.isEmpty)(b[1])) {
  295. if ((0, _mixed.isEmpty)(a[1])) {
  296. return 0;
  297. }
  298. if (columnMeta.columnSorting.sortEmptyCells) {
  299. return sortOrder ? 1 : -1;
  300. }
  301. return -1;
  302. }
  303. if (isNaN(a[1]) && !isNaN(b[1])) {
  304. return sortOrder ? 1 : -1;
  305. } else if (!isNaN(a[1]) && isNaN(b[1])) {
  306. return sortOrder ? -1 : 1;
  307. } else if (!(isNaN(a[1]) || isNaN(b[1]))) {
  308. a[1] = parseFloat(a[1]);
  309. b[1] = parseFloat(b[1]);
  310. }
  311. if (a[1] < b[1]) {
  312. return sortOrder ? -1 : 1;
  313. }
  314. if (a[1] > b[1]) {
  315. return sortOrder ? 1 : -1;
  316. }
  317. return 0;
  318. };
  319. }
  320. /**
  321. * Date sorting algorithm
  322. * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending).
  323. * @param {Object} columnMeta Column meta object.
  324. * @returns {Function} The compare function.
  325. */
  326. }, {
  327. key: 'dateSort',
  328. value: function dateSort(sortOrder, columnMeta) {
  329. return function (a, b) {
  330. if (a[1] === b[1]) {
  331. return 0;
  332. }
  333. if ((0, _mixed.isEmpty)(a[1])) {
  334. if ((0, _mixed.isEmpty)(b[1])) {
  335. return 0;
  336. }
  337. if (columnMeta.columnSorting.sortEmptyCells) {
  338. return sortOrder ? -1 : 1;
  339. }
  340. return 1;
  341. }
  342. if ((0, _mixed.isEmpty)(b[1])) {
  343. if ((0, _mixed.isEmpty)(a[1])) {
  344. return 0;
  345. }
  346. if (columnMeta.columnSorting.sortEmptyCells) {
  347. return sortOrder ? 1 : -1;
  348. }
  349. return -1;
  350. }
  351. var aDate = (0, _moment2.default)(a[1], columnMeta.dateFormat);
  352. var bDate = (0, _moment2.default)(b[1], columnMeta.dateFormat);
  353. if (!aDate.isValid()) {
  354. return 1;
  355. }
  356. if (!bDate.isValid()) {
  357. return -1;
  358. }
  359. if (bDate.isAfter(aDate)) {
  360. return sortOrder ? -1 : 1;
  361. }
  362. if (bDate.isBefore(aDate)) {
  363. return sortOrder ? 1 : -1;
  364. }
  365. return 0;
  366. };
  367. }
  368. /**
  369. * Numeric sorting algorithm.
  370. *
  371. * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending).
  372. * @param {Object} columnMeta Column meta object.
  373. * @returns {Function} The compare function.
  374. */
  375. }, {
  376. key: 'numericSort',
  377. value: function numericSort(sortOrder, columnMeta) {
  378. return function (a, b) {
  379. var parsedA = parseFloat(a[1]);
  380. var parsedB = parseFloat(b[1]);
  381. // Watch out when changing this part of code!
  382. // Check below returns 0 (as expected) when comparing empty string, null, undefined
  383. if (parsedA === parsedB || isNaN(parsedA) && isNaN(parsedB)) {
  384. return 0;
  385. }
  386. if (columnMeta.columnSorting.sortEmptyCells) {
  387. if ((0, _mixed.isEmpty)(a[1])) {
  388. return sortOrder ? -1 : 1;
  389. }
  390. if ((0, _mixed.isEmpty)(b[1])) {
  391. return sortOrder ? 1 : -1;
  392. }
  393. }
  394. if (isNaN(parsedA)) {
  395. return 1;
  396. }
  397. if (isNaN(parsedB)) {
  398. return -1;
  399. }
  400. if (parsedA < parsedB) {
  401. return sortOrder ? -1 : 1;
  402. } else if (parsedA > parsedB) {
  403. return sortOrder ? 1 : -1;
  404. }
  405. return 0;
  406. };
  407. }
  408. /**
  409. * Perform the sorting.
  410. */
  411. }, {
  412. key: 'sort',
  413. value: function sort() {
  414. if (typeof this.hot.sortOrder == 'undefined') {
  415. this.hot.sortIndex.length = 0;
  416. return;
  417. }
  418. var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn);
  419. var emptyRows = this.hot.countEmptyRows();
  420. var sortFunction = void 0;
  421. var nrOfRows = void 0;
  422. this.hot.sortingEnabled = false; // this is required by translateRow plugin hook
  423. this.hot.sortIndex.length = 0;
  424. if (typeof colMeta.columnSorting.sortEmptyCells === 'undefined') {
  425. colMeta.columnSorting = { sortEmptyCells: this.sortEmptyCells };
  426. }
  427. if (this.hot.getSettings().maxRows === Number.POSITIVE_INFINITY) {
  428. nrOfRows = this.hot.countRows() - this.hot.getSettings().minSpareRows;
  429. } else {
  430. nrOfRows = this.hot.countRows() - emptyRows;
  431. }
  432. for (var i = 0, ilen = nrOfRows; i < ilen; i++) {
  433. this.hot.sortIndex.push([i, this.hot.getDataAtCell(i, this.hot.sortColumn)]);
  434. }
  435. if (colMeta.sortFunction) {
  436. sortFunction = colMeta.sortFunction;
  437. } else {
  438. switch (colMeta.type) {
  439. case 'date':
  440. sortFunction = this.dateSort;
  441. break;
  442. case 'numeric':
  443. sortFunction = this.numericSort;
  444. break;
  445. default:
  446. sortFunction = this.defaultSort;
  447. }
  448. }
  449. (0, _mergeSort2.default)(this.hot.sortIndex, sortFunction(this.hot.sortOrder, colMeta));
  450. // Append spareRows
  451. for (var _i = this.hot.sortIndex.length; _i < this.hot.countRows(); _i++) {
  452. this.hot.sortIndex.push([_i, this.hot.getDataAtCell(_i, this.hot.sortColumn)]);
  453. }
  454. this.hot.sortingEnabled = true; // this is required by translateRow plugin hook
  455. }
  456. /**
  457. * Update indicator states.
  458. */
  459. }, {
  460. key: 'updateSortIndicator',
  461. value: function updateSortIndicator() {
  462. if (typeof this.hot.sortOrder == 'undefined') {
  463. return;
  464. }
  465. var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn);
  466. this.sortIndicators[this.hot.sortColumn] = colMeta.sortIndicator;
  467. }
  468. /**
  469. * `modifyRow` hook callback. Translates physical row index to the sorted row index.
  470. *
  471. * @param {Number} row Row index.
  472. * @returns {Number} Sorted row index.
  473. */
  474. }, {
  475. key: 'translateRow',
  476. value: function translateRow(row) {
  477. if (this.hot.sortingEnabled && typeof this.hot.sortOrder !== 'undefined' && this.hot.sortIndex && this.hot.sortIndex.length && this.hot.sortIndex[row]) {
  478. return this.hot.sortIndex[row][0];
  479. }
  480. return row;
  481. }
  482. /**
  483. * Translates sorted row index to physical row index.
  484. *
  485. * @param {Number} row Sorted row index.
  486. * @returns {number} Physical row index.
  487. */
  488. }, {
  489. key: 'untranslateRow',
  490. value: function untranslateRow(row) {
  491. if (this.hot.sortingEnabled && this.hot.sortIndex && this.hot.sortIndex.length) {
  492. for (var i = 0; i < this.hot.sortIndex.length; i++) {
  493. if (this.hot.sortIndex[i][0] == row) {
  494. return i;
  495. }
  496. }
  497. }
  498. }
  499. /**
  500. * `afterGetColHeader` callback. Adds column sorting css classes to clickable headers.
  501. *
  502. * @private
  503. * @param {Number} col Column index.
  504. * @param {Element} TH TH HTML element.
  505. */
  506. }, {
  507. key: 'getColHeader',
  508. value: function getColHeader(col, TH) {
  509. if (col < 0 || !TH.parentNode) {
  510. return false;
  511. }
  512. var headerLink = TH.querySelector('.colHeader');
  513. var colspan = TH.getAttribute('colspan');
  514. var TRs = TH.parentNode.parentNode.childNodes;
  515. var headerLevel = Array.prototype.indexOf.call(TRs, TH.parentNode);
  516. headerLevel -= TRs.length;
  517. if (!headerLink) {
  518. return;
  519. }
  520. if (this.hot.getSettings().columnSorting && col >= 0 && headerLevel === -1) {
  521. (0, _element.addClass)(headerLink, 'columnSorting');
  522. }
  523. (0, _element.removeClass)(headerLink, 'descending');
  524. (0, _element.removeClass)(headerLink, 'ascending');
  525. if (this.sortIndicators[col]) {
  526. if (col === this.hot.sortColumn) {
  527. if (this.sortOrderClass === 'ascending') {
  528. (0, _element.addClass)(headerLink, 'ascending');
  529. } else if (this.sortOrderClass === 'descending') {
  530. (0, _element.addClass)(headerLink, 'descending');
  531. }
  532. }
  533. }
  534. }
  535. /**
  536. * Check if any column is in a sorted state.
  537. *
  538. * @returns {Boolean}
  539. */
  540. }, {
  541. key: 'isSorted',
  542. value: function isSorted() {
  543. return typeof this.hot.sortColumn != 'undefined';
  544. }
  545. /**
  546. * `afterCreateRow` callback. Updates the sorting state after a row have been created.
  547. *
  548. * @private
  549. * @param {Number} index
  550. * @param {Number} amount
  551. */
  552. }, {
  553. key: 'afterCreateRow',
  554. value: function afterCreateRow(index, amount) {
  555. if (!this.isSorted()) {
  556. return;
  557. }
  558. for (var i = 0; i < this.hot.sortIndex.length; i++) {
  559. if (this.hot.sortIndex[i][0] >= index) {
  560. this.hot.sortIndex[i][0] += amount;
  561. }
  562. }
  563. for (var _i2 = 0; _i2 < amount; _i2++) {
  564. this.hot.sortIndex.splice(index + _i2, 0, [index + _i2, this.hot.getSourceData()[index + _i2][this.hot.sortColumn + this.hot.colOffset()]]);
  565. }
  566. this.saveSortingState();
  567. }
  568. /**
  569. * `afterRemoveRow` hook callback.
  570. *
  571. * @private
  572. * @param {Number} index
  573. * @param {Number} amount
  574. */
  575. }, {
  576. key: 'afterRemoveRow',
  577. value: function afterRemoveRow(index, amount) {
  578. if (!this.isSorted()) {
  579. return;
  580. }
  581. var removedRows = this.hot.sortIndex.splice(index, amount);
  582. removedRows = (0, _array.arrayMap)(removedRows, function (row) {
  583. return row[0];
  584. });
  585. function countRowShift(logicalRow) {
  586. // Todo: compare perf between reduce vs sort->each->brake
  587. return (0, _array.arrayReduce)(removedRows, function (count, removedLogicalRow) {
  588. if (logicalRow > removedLogicalRow) {
  589. count++;
  590. }
  591. return count;
  592. }, 0);
  593. }
  594. this.hot.sortIndex = (0, _array.arrayMap)(this.hot.sortIndex, function (logicalRow, physicalRow) {
  595. var rowShift = countRowShift(logicalRow[0]);
  596. if (rowShift) {
  597. logicalRow[0] -= rowShift;
  598. }
  599. return logicalRow;
  600. });
  601. this.saveSortingState();
  602. }
  603. /**
  604. * Set options by passed settings
  605. *
  606. * @private
  607. */
  608. }, {
  609. key: 'setPluginOptions',
  610. value: function setPluginOptions() {
  611. var columnSorting = this.hot.getSettings().columnSorting;
  612. if ((typeof columnSorting === 'undefined' ? 'undefined' : _typeof(columnSorting)) === 'object') {
  613. this.sortEmptyCells = columnSorting.sortEmptyCells || false;
  614. } else {
  615. this.sortEmptyCells = false;
  616. }
  617. }
  618. /**
  619. * `onAfterOnCellMouseDown` hook callback.
  620. *
  621. * @private
  622. * @param {Event} event Event which are provided by hook.
  623. * @param {CellCoords} coords Coords of the selected cell.
  624. */
  625. }, {
  626. key: 'onAfterOnCellMouseDown',
  627. value: function onAfterOnCellMouseDown(event, coords) {
  628. if (coords.row > -1) {
  629. return;
  630. }
  631. if ((0, _element.hasClass)(event.realTarget, 'columnSorting')) {
  632. // reset order state on every new column header click
  633. if (coords.col !== this.lastSortedColumn) {
  634. this.hot.sortOrder = true;
  635. }
  636. this.lastSortedColumn = coords.col;
  637. this.sortByColumn(coords.col);
  638. }
  639. }
  640. }]);
  641. return ColumnSorting;
  642. }(_base2.default);
  643. (0, _plugins.registerPlugin)('columnSorting', ColumnSorting);
  644. exports.default = ColumnSorting;