handsontableEditor.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import { KEY_CODES } from './../helpers/unicode';
  2. import { extend } from './../helpers/object';
  3. import { setCaretPosition } from './../helpers/dom/element';
  4. import { stopImmediatePropagation, isImmediatePropagationStopped } from './../helpers/dom/event';
  5. import TextEditor from './textEditor';
  6. const HandsontableEditor = TextEditor.prototype.extend();
  7. /**
  8. * @private
  9. * @editor HandsontableEditor
  10. * @class HandsontableEditor
  11. * @dependencies TextEditor
  12. */
  13. HandsontableEditor.prototype.createElements = function(...args) {
  14. TextEditor.prototype.createElements.apply(this, args);
  15. const DIV = document.createElement('DIV');
  16. DIV.className = 'handsontableEditor';
  17. this.TEXTAREA_PARENT.appendChild(DIV);
  18. this.htContainer = DIV;
  19. this.assignHooks();
  20. };
  21. HandsontableEditor.prototype.prepare = function(td, row, col, prop, value, cellProperties, ...args) {
  22. TextEditor.prototype.prepare.apply(this, [td, row, col, prop, value, cellProperties, ...args]);
  23. const parent = this;
  24. const options = {
  25. startRows: 0,
  26. startCols: 0,
  27. minRows: 0,
  28. minCols: 0,
  29. className: 'listbox',
  30. copyPaste: false,
  31. autoColumnSize: false,
  32. autoRowSize: false,
  33. readOnly: true,
  34. fillHandle: false,
  35. autoWrapCol: false,
  36. autoWrapRow: false,
  37. afterOnCellMouseDown(_, coords) {
  38. const sourceValue = this.getSourceData(coords.row, coords.col);
  39. // if the value is undefined then it means we don't want to set the value
  40. if (sourceValue !== void 0) {
  41. parent.setValue(sourceValue);
  42. }
  43. parent.instance.destroyEditor();
  44. }
  45. };
  46. if (this.cellProperties.handsontable) {
  47. extend(options, cellProperties.handsontable);
  48. }
  49. this.htOptions = options;
  50. };
  51. const onBeforeKeyDown = function(event) {
  52. if (isImmediatePropagationStopped(event)) {
  53. return;
  54. }
  55. const editor = this.getActiveEditor();
  56. const innerHOT = editor.htEditor.getInstance();
  57. let rowToSelect;
  58. let selectedRow;
  59. if (event.keyCode === KEY_CODES.ARROW_DOWN) {
  60. if (!innerHOT.getSelectedLast() && !innerHOT.flipped) {
  61. rowToSelect = 0;
  62. } else if (innerHOT.getSelectedLast()) {
  63. if (innerHOT.flipped) {
  64. rowToSelect = innerHOT.getSelectedLast()[0] + 1;
  65. } else if (!innerHOT.flipped) {
  66. const lastRow = innerHOT.countRows() - 1;
  67. selectedRow = innerHOT.getSelectedLast()[0];
  68. rowToSelect = Math.min(lastRow, selectedRow + 1);
  69. }
  70. }
  71. } else if (event.keyCode === KEY_CODES.ARROW_UP) {
  72. if (!innerHOT.getSelectedLast() && innerHOT.flipped) {
  73. rowToSelect = innerHOT.countRows() - 1;
  74. } else if (innerHOT.getSelectedLast()) {
  75. if (innerHOT.flipped) {
  76. selectedRow = innerHOT.getSelectedLast()[0];
  77. rowToSelect = Math.max(0, selectedRow - 1);
  78. } else {
  79. selectedRow = innerHOT.getSelectedLast()[0];
  80. rowToSelect = selectedRow - 1;
  81. }
  82. }
  83. }
  84. if (rowToSelect !== void 0) {
  85. if (rowToSelect < 0 || (innerHOT.flipped && rowToSelect > innerHOT.countRows() - 1)) {
  86. innerHOT.deselectCell();
  87. } else {
  88. innerHOT.selectCell(rowToSelect, 0);
  89. }
  90. if (innerHOT.getData().length) {
  91. event.preventDefault();
  92. stopImmediatePropagation(event);
  93. editor.instance.listen();
  94. editor.TEXTAREA.focus();
  95. }
  96. }
  97. };
  98. HandsontableEditor.prototype.open = function(...args) {
  99. this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
  100. TextEditor.prototype.open.apply(this, args);
  101. if (this.htEditor) {
  102. this.htEditor.destroy();
  103. }
  104. if (this.htContainer.style.display === 'none') {
  105. this.htContainer.style.display = '';
  106. }
  107. // Construct and initialise a new Handsontable
  108. this.htEditor = new this.instance.constructor(this.htContainer, this.htOptions);
  109. this.htEditor.init();
  110. this.htEditor.rootElement.style.display = '';
  111. if (this.cellProperties.strict) {
  112. this.htEditor.selectCell(0, 0);
  113. } else {
  114. this.htEditor.deselectCell();
  115. }
  116. setCaretPosition(this.TEXTAREA, 0, this.TEXTAREA.value.length);
  117. };
  118. HandsontableEditor.prototype.close = function(...args) {
  119. this.htEditor.rootElement.style.display = 'none';
  120. this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
  121. TextEditor.prototype.close.apply(this, args);
  122. };
  123. HandsontableEditor.prototype.focus = function(...args) {
  124. TextEditor.prototype.focus.apply(this, args);
  125. };
  126. HandsontableEditor.prototype.beginEditing = function(...args) {
  127. const onBeginEditing = this.instance.getSettings().onBeginEditing;
  128. if (onBeginEditing && onBeginEditing() === false) {
  129. return;
  130. }
  131. TextEditor.prototype.beginEditing.apply(this, args);
  132. };
  133. HandsontableEditor.prototype.finishEditing = function(...args) {
  134. if (this.htEditor && this.htEditor.isListening()) { // if focus is still in the HOT editor
  135. this.instance.listen(); // return the focus to the parent HOT instance
  136. }
  137. if (this.htEditor && this.htEditor.getSelectedLast()) {
  138. const value = this.htEditor.getInstance().getValue();
  139. if (value !== void 0) { // if the value is undefined then it means we don't want to set the value
  140. this.setValue(value);
  141. }
  142. }
  143. return TextEditor.prototype.finishEditing.apply(this, args);
  144. };
  145. HandsontableEditor.prototype.assignHooks = function() {
  146. this.instance.addHook('afterDestroy', () => {
  147. if (this.htEditor) {
  148. this.htEditor.destroy();
  149. }
  150. });
  151. };
  152. export default HandsontableEditor;