px-jspreadsheet-ce 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +292 -0
  3. package/dist/index.d.ts +2382 -0
  4. package/dist/index.js +11286 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/jspreadsheet.css +723 -0
  7. package/dist/jspreadsheet.themes.css +104 -0
  8. package/package.json +57 -0
  9. package/src/index.js +95 -0
  10. package/src/test.js +50 -0
  11. package/src/utils/cells.js +36 -0
  12. package/src/utils/columns.js +742 -0
  13. package/src/utils/comments.js +87 -0
  14. package/src/utils/config.js +46 -0
  15. package/src/utils/copyPaste.js +438 -0
  16. package/src/utils/data.js +419 -0
  17. package/src/utils/dispatch.js +115 -0
  18. package/src/utils/download.js +38 -0
  19. package/src/utils/editor.js +430 -0
  20. package/src/utils/events.js +1639 -0
  21. package/src/utils/factory.js +216 -0
  22. package/src/utils/filter.js +128 -0
  23. package/src/utils/footer.js +51 -0
  24. package/src/utils/freeze.js +19 -0
  25. package/src/utils/headers.js +74 -0
  26. package/src/utils/helpers.js +409 -0
  27. package/src/utils/history.js +336 -0
  28. package/src/utils/internal.js +1299 -0
  29. package/src/utils/internalHelpers.js +96 -0
  30. package/src/utils/keys.js +406 -0
  31. package/src/utils/lazyLoading.js +143 -0
  32. package/src/utils/libraryBase.js +5 -0
  33. package/src/utils/merges.js +275 -0
  34. package/src/utils/meta.js +81 -0
  35. package/src/utils/orderBy.js +185 -0
  36. package/src/utils/pagination.js +181 -0
  37. package/src/utils/rows.js +624 -0
  38. package/src/utils/search.js +83 -0
  39. package/src/utils/selection.js +744 -0
  40. package/src/utils/style.js +147 -0
  41. package/src/utils/toolbar.js +566 -0
  42. package/src/utils/version.js +9 -0
  43. package/src/utils/worksheets.js +731 -0
  44. package/src/webcomponent.js +59 -0
@@ -0,0 +1,275 @@
1
+ import jSuites from 'jsuites';
2
+
3
+ import { getColumnNameFromId, getIdFromColumnName } from './internalHelpers.js';
4
+ import { updateCell } from './internal.js';
5
+ import { setHistory } from './history.js';
6
+ import dispatch from './dispatch.js';
7
+ import { updateSelection } from './selection.js';
8
+
9
+ /**
10
+ * Is column merged
11
+ */
12
+ export const isColMerged = function (x, insertBefore) {
13
+ const obj = this;
14
+
15
+ const cols = [];
16
+ // Remove any merged cells
17
+ if (obj.options.mergeCells) {
18
+ const keys = Object.keys(obj.options.mergeCells);
19
+ for (let i = 0; i < keys.length; i++) {
20
+ const info = getIdFromColumnName(keys[i], true);
21
+ const colspan = obj.options.mergeCells[keys[i]][0];
22
+ const x1 = info[0];
23
+ const x2 = info[0] + (colspan > 1 ? colspan - 1 : 0);
24
+
25
+ if (insertBefore == null) {
26
+ if (x1 <= x && x2 >= x) {
27
+ cols.push(keys[i]);
28
+ }
29
+ } else {
30
+ if (insertBefore) {
31
+ if (x1 < x && x2 >= x) {
32
+ cols.push(keys[i]);
33
+ }
34
+ } else {
35
+ if (x1 <= x && x2 > x) {
36
+ cols.push(keys[i]);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ return cols;
44
+ };
45
+
46
+ /**
47
+ * Is rows merged
48
+ */
49
+ export const isRowMerged = function (y, insertBefore) {
50
+ const obj = this;
51
+
52
+ const rows = [];
53
+ // Remove any merged cells
54
+ if (obj.options.mergeCells) {
55
+ const keys = Object.keys(obj.options.mergeCells);
56
+ for (let i = 0; i < keys.length; i++) {
57
+ const info = getIdFromColumnName(keys[i], true);
58
+ const rowspan = obj.options.mergeCells[keys[i]][1];
59
+ const y1 = info[1];
60
+ const y2 = info[1] + (rowspan > 1 ? rowspan - 1 : 0);
61
+
62
+ if (insertBefore == null) {
63
+ if (y1 <= y && y2 >= y) {
64
+ rows.push(keys[i]);
65
+ }
66
+ } else {
67
+ if (insertBefore) {
68
+ if (y1 < y && y2 >= y) {
69
+ rows.push(keys[i]);
70
+ }
71
+ } else {
72
+ if (y1 <= y && y2 > y) {
73
+ rows.push(keys[i]);
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ return rows;
81
+ };
82
+
83
+ /**
84
+ * Merge cells
85
+ * @param cellName
86
+ * @param colspan
87
+ * @param rowspan
88
+ * @param ignoreHistoryAndEvents
89
+ */
90
+ export const getMerge = function (cellName) {
91
+ const obj = this;
92
+
93
+ let data = {};
94
+ if (cellName) {
95
+ if (obj.options.mergeCells && obj.options.mergeCells[cellName]) {
96
+ data = [obj.options.mergeCells[cellName][0], obj.options.mergeCells[cellName][1]];
97
+ } else {
98
+ data = null;
99
+ }
100
+ } else {
101
+ if (obj.options.mergeCells) {
102
+ var mergedCells = obj.options.mergeCells;
103
+ const keys = Object.keys(obj.options.mergeCells);
104
+ for (let i = 0; i < keys.length; i++) {
105
+ data[keys[i]] = [obj.options.mergeCells[keys[i]][0], obj.options.mergeCells[keys[i]][1]];
106
+ }
107
+ }
108
+ }
109
+
110
+ return data;
111
+ };
112
+
113
+ /**
114
+ * Merge cells
115
+ * @param cellName
116
+ * @param colspan
117
+ * @param rowspan
118
+ * @param ignoreHistoryAndEvents
119
+ */
120
+ export const setMerge = function (cellName, colspan, rowspan, ignoreHistoryAndEvents) {
121
+ const obj = this;
122
+
123
+ let test = false;
124
+
125
+ if (!cellName) {
126
+ if (!obj.highlighted.length) {
127
+ alert(jSuites.translate('No cells selected'));
128
+ return null;
129
+ } else {
130
+ const x1 = parseInt(obj.highlighted[0].getAttribute('data-x'));
131
+ const y1 = parseInt(obj.highlighted[0].getAttribute('data-y'));
132
+ const x2 = parseInt(obj.highlighted[obj.highlighted.length - 1].getAttribute('data-x'));
133
+ const y2 = parseInt(obj.highlighted[obj.highlighted.length - 1].getAttribute('data-y'));
134
+ cellName = getColumnNameFromId([x1, y1]);
135
+ colspan = x2 - x1 + 1;
136
+ rowspan = y2 - y1 + 1;
137
+ }
138
+ } else if (typeof cellName !== 'string') {
139
+ return null;
140
+ }
141
+
142
+ const cell = getIdFromColumnName(cellName, true);
143
+
144
+ if (obj.options.mergeCells && obj.options.mergeCells[cellName]) {
145
+ if (obj.records[cell[1]][cell[0]].element.getAttribute('data-merged')) {
146
+ test = 'Cell already merged';
147
+ }
148
+ } else if ((!colspan || colspan < 2) && (!rowspan || rowspan < 2)) {
149
+ test = 'Invalid merged properties';
150
+ } else {
151
+ var cells = [];
152
+ for (let j = cell[1]; j < cell[1] + rowspan; j++) {
153
+ for (let i = cell[0]; i < cell[0] + colspan; i++) {
154
+ var columnName = getColumnNameFromId([i, j]);
155
+ if (obj.records[j][i].element.getAttribute('data-merged')) {
156
+ test = 'There is a conflict with another merged cell';
157
+ }
158
+ }
159
+ }
160
+ }
161
+
162
+ if (test) {
163
+ alert(jSuites.translate(test));
164
+ } else {
165
+ // Add property
166
+ if (colspan > 1) {
167
+ obj.records[cell[1]][cell[0]].element.setAttribute('colspan', colspan);
168
+ } else {
169
+ colspan = 1;
170
+ }
171
+ if (rowspan > 1) {
172
+ obj.records[cell[1]][cell[0]].element.setAttribute('rowspan', rowspan);
173
+ } else {
174
+ rowspan = 1;
175
+ }
176
+ // Keep links to the existing nodes
177
+ if (!obj.options.mergeCells) {
178
+ obj.options.mergeCells = {};
179
+ }
180
+
181
+ obj.options.mergeCells[cellName] = [colspan, rowspan, []];
182
+ // Mark cell as merged
183
+ obj.records[cell[1]][cell[0]].element.setAttribute('data-merged', 'true');
184
+ // Overflow
185
+ obj.records[cell[1]][cell[0]].element.style.overflow = 'hidden';
186
+ // History data
187
+ const data = [];
188
+ // Adjust the nodes
189
+ for (let y = cell[1]; y < cell[1] + rowspan; y++) {
190
+ for (let x = cell[0]; x < cell[0] + colspan; x++) {
191
+ if (!(cell[0] == x && cell[1] == y)) {
192
+ data.push(obj.options.data[y][x]);
193
+ updateCell.call(obj, x, y, '', true);
194
+ obj.options.mergeCells[cellName][2].push(obj.records[y][x].element);
195
+ obj.records[y][x].element.style.display = 'none';
196
+ obj.records[y][x].element = obj.records[cell[1]][cell[0]].element;
197
+ }
198
+ }
199
+ }
200
+ // In the initialization is not necessary keep the history
201
+ updateSelection.call(obj, obj.records[cell[1]][cell[0]].element);
202
+
203
+ if (!ignoreHistoryAndEvents) {
204
+ setHistory.call(obj, {
205
+ action: 'setMerge',
206
+ column: cellName,
207
+ colspan: colspan,
208
+ rowspan: rowspan,
209
+ data: data,
210
+ });
211
+
212
+ dispatch.call(obj, 'onmerge', obj, { [cellName]: [colspan, rowspan] });
213
+ }
214
+ }
215
+ };
216
+
217
+ /**
218
+ * Remove merge by cellname
219
+ * @param cellName
220
+ */
221
+ export const removeMerge = function (cellName, data, keepOptions) {
222
+ const obj = this;
223
+
224
+ if (obj.options.mergeCells && obj.options.mergeCells[cellName]) {
225
+ const beforeMerges = { [cellName]: obj.options.mergeCells[cellName] };
226
+ const cell = getIdFromColumnName(cellName, true);
227
+ obj.records[cell[1]][cell[0]].element.removeAttribute('colspan');
228
+ obj.records[cell[1]][cell[0]].element.removeAttribute('rowspan');
229
+ obj.records[cell[1]][cell[0]].element.removeAttribute('data-merged');
230
+ const info = obj.options.mergeCells[cellName];
231
+
232
+ let index = 0;
233
+
234
+ let j, i;
235
+
236
+ for (j = 0; j < info[1]; j++) {
237
+ for (i = 0; i < info[0]; i++) {
238
+ if (j > 0 || i > 0) {
239
+ obj.records[cell[1] + j][cell[0] + i].element = info[2][index];
240
+ obj.records[cell[1] + j][cell[0] + i].element.style.display = '';
241
+ // Recover data
242
+ if (data && data[index]) {
243
+ updateCell.call(obj, cell[0] + i, cell[1] + j, data[index]);
244
+ }
245
+ index++;
246
+ }
247
+ }
248
+ }
249
+
250
+ // Update selection
251
+ updateSelection.call(obj, obj.records[cell[1]][cell[0]].element, obj.records[cell[1] + j - 1][cell[0] + i - 1].element);
252
+
253
+ if (!keepOptions) {
254
+ delete obj.options.mergeCells[cellName];
255
+ }
256
+
257
+ dispatch.call(obj, 'onunmerge', obj, cellName, beforeMerges);
258
+ }
259
+ };
260
+
261
+ /**
262
+ * Remove all merged cells
263
+ */
264
+ export const destroyMerge = function (keepOptions) {
265
+ const obj = this;
266
+
267
+ // Remove any merged cells
268
+ if (obj.options.mergeCells) {
269
+ var mergedCells = obj.options.mergeCells;
270
+ const keys = Object.keys(obj.options.mergeCells);
271
+ for (let i = 0; i < keys.length; i++) {
272
+ removeMerge.call(obj, keys[i], null, keepOptions);
273
+ }
274
+ }
275
+ };
@@ -0,0 +1,81 @@
1
+ import dispatch from './dispatch.js';
2
+
3
+ /**
4
+ * Get meta information from cell(s)
5
+ *
6
+ * @return integer
7
+ */
8
+ export const getMeta = function (cell, key) {
9
+ const obj = this;
10
+
11
+ if (!cell) {
12
+ return obj.options.meta;
13
+ } else {
14
+ if (key) {
15
+ return obj.options.meta && obj.options.meta[cell] && obj.options.meta[cell][key] ? obj.options.meta[cell][key] : null;
16
+ } else {
17
+ return obj.options.meta && obj.options.meta[cell] ? obj.options.meta[cell] : null;
18
+ }
19
+ }
20
+ };
21
+
22
+ /**
23
+ * Update meta information
24
+ *
25
+ * @return integer
26
+ */
27
+ export const updateMeta = function (affectedCells) {
28
+ const obj = this;
29
+
30
+ if (obj.options.meta) {
31
+ const newMeta = {};
32
+ const keys = Object.keys(obj.options.meta);
33
+ for (let i = 0; i < keys.length; i++) {
34
+ if (affectedCells[keys[i]]) {
35
+ newMeta[affectedCells[keys[i]]] = obj.options.meta[keys[i]];
36
+ } else {
37
+ newMeta[keys[i]] = obj.options.meta[keys[i]];
38
+ }
39
+ }
40
+ // Update meta information
41
+ obj.options.meta = newMeta;
42
+ }
43
+ };
44
+
45
+ /**
46
+ * Set meta information to cell(s)
47
+ *
48
+ * @return integer
49
+ */
50
+ export const setMeta = function (o, k, v) {
51
+ const obj = this;
52
+
53
+ if (!obj.options.meta) {
54
+ obj.options.meta = {};
55
+ }
56
+
57
+ if (k && v) {
58
+ // Set data value
59
+ if (!obj.options.meta[o]) {
60
+ obj.options.meta[o] = {};
61
+ }
62
+ obj.options.meta[o][k] = v;
63
+
64
+ dispatch.call(obj, 'onchangemeta', obj, { [o]: { [k]: v } });
65
+ } else {
66
+ // Apply that for all cells
67
+ const keys = Object.keys(o);
68
+ for (let i = 0; i < keys.length; i++) {
69
+ if (!obj.options.meta[keys[i]]) {
70
+ obj.options.meta[keys[i]] = {};
71
+ }
72
+
73
+ const prop = Object.keys(o[keys[i]]);
74
+ for (let j = 0; j < prop.length; j++) {
75
+ obj.options.meta[keys[i]][prop[j]] = o[keys[i]][prop[j]];
76
+ }
77
+ }
78
+
79
+ dispatch.call(obj, 'onchangemeta', obj, o);
80
+ }
81
+ };
@@ -0,0 +1,185 @@
1
+ import jSuites from 'jsuites';
2
+ import { setHistory } from './history.js';
3
+ import dispatch from './dispatch.js';
4
+ import { updateTableReferences } from './internal.js';
5
+ import { loadPage } from './lazyLoading.js';
6
+ import { closeFilter } from './filter.js';
7
+
8
+ /**
9
+ * Update order arrow
10
+ */
11
+ export const updateOrderArrow = function (column, order) {
12
+ const obj = this;
13
+
14
+ // Remove order
15
+ for (let i = 0; i < obj.headers.length; i++) {
16
+ obj.headers[i].classList.remove('arrow-up');
17
+ obj.headers[i].classList.remove('arrow-down');
18
+ }
19
+
20
+ // No order specified then toggle order
21
+ if (order) {
22
+ obj.headers[column].classList.add('arrow-up');
23
+ } else {
24
+ obj.headers[column].classList.add('arrow-down');
25
+ }
26
+ };
27
+
28
+ /**
29
+ * Update rows position
30
+ */
31
+ export const updateOrder = function (rows) {
32
+ const obj = this;
33
+
34
+ // History
35
+ let data = [];
36
+ for (let j = 0; j < rows.length; j++) {
37
+ data[j] = obj.options.data[rows[j]];
38
+ }
39
+ obj.options.data = data;
40
+
41
+ data = [];
42
+ for (let j = 0; j < rows.length; j++) {
43
+ data[j] = obj.records[rows[j]];
44
+
45
+ for (let i = 0; i < data[j].length; i++) {
46
+ data[j][i].y = j;
47
+ }
48
+ }
49
+ obj.records = data;
50
+
51
+ data = [];
52
+ for (let j = 0; j < rows.length; j++) {
53
+ data[j] = obj.rows[rows[j]];
54
+ data[j].y = j;
55
+ }
56
+ obj.rows = data;
57
+
58
+ // Update references
59
+ updateTableReferences.call(obj);
60
+
61
+ // Redo search
62
+ if (obj.results && obj.results.length) {
63
+ if (obj.searchInput.value) {
64
+ obj.search(obj.searchInput.value);
65
+ } else {
66
+ closeFilter.call(obj);
67
+ }
68
+ } else {
69
+ // Create page
70
+ obj.results = null;
71
+ obj.pageNumber = 0;
72
+
73
+ if (obj.options.pagination > 0) {
74
+ obj.page(0);
75
+ } else if (obj.options.lazyLoading == true) {
76
+ loadPage.call(obj, 0);
77
+ } else {
78
+ for (let j = 0; j < obj.rows.length; j++) {
79
+ obj.tbody.appendChild(obj.rows[j].element);
80
+ }
81
+ }
82
+ }
83
+ };
84
+
85
+ /**
86
+ * Sort data and reload table
87
+ */
88
+ export const orderBy = function (column, order) {
89
+ const obj = this;
90
+
91
+ if (column >= 0) {
92
+ // Merged cells
93
+ if (obj.options.mergeCells && Object.keys(obj.options.mergeCells).length > 0) {
94
+ if (!confirm(jSuites.translate('This action will destroy any existing merged cells. Are you sure?'))) {
95
+ return false;
96
+ } else {
97
+ // Remove merged cells
98
+ obj.destroyMerge();
99
+ }
100
+ }
101
+
102
+ // Direction
103
+ if (order == null) {
104
+ order = obj.headers[column].classList.contains('arrow-down') ? 1 : 0;
105
+ } else {
106
+ order = order ? 1 : 0;
107
+ }
108
+
109
+ // Test order
110
+ let temp = [];
111
+ if (
112
+ obj.options.columns &&
113
+ obj.options.columns[column] &&
114
+ (obj.options.columns[column].type == 'number' ||
115
+ obj.options.columns[column].type == 'numeric' ||
116
+ obj.options.columns[column].type == 'percentage' ||
117
+ obj.options.columns[column].type == 'autonumber' ||
118
+ obj.options.columns[column].type == 'color')
119
+ ) {
120
+ for (let j = 0; j < obj.options.data.length; j++) {
121
+ temp[j] = [j, Number(obj.options.data[j][column])];
122
+ }
123
+ } else if (
124
+ obj.options.columns &&
125
+ obj.options.columns[column] &&
126
+ (obj.options.columns[column].type == 'calendar' || obj.options.columns[column].type == 'checkbox' || obj.options.columns[column].type == 'radio')
127
+ ) {
128
+ for (let j = 0; j < obj.options.data.length; j++) {
129
+ temp[j] = [j, obj.options.data[j][column]];
130
+ }
131
+ } else {
132
+ for (let j = 0; j < obj.options.data.length; j++) {
133
+ temp[j] = [j, obj.records[j][column].element.textContent.toLowerCase()];
134
+ }
135
+ }
136
+
137
+ // Default sorting method
138
+ if (typeof obj.parent.config.sorting !== 'function') {
139
+ obj.parent.config.sorting = function (direction) {
140
+ return function (a, b) {
141
+ const valueA = a[1];
142
+ const valueB = b[1];
143
+
144
+ if (!direction) {
145
+ return valueA === '' && valueB !== '' ? 1 : valueA !== '' && valueB === '' ? -1 : valueA > valueB ? 1 : valueA < valueB ? -1 : 0;
146
+ } else {
147
+ return valueA === '' && valueB !== '' ? 1 : valueA !== '' && valueB === '' ? -1 : valueA > valueB ? -1 : valueA < valueB ? 1 : 0;
148
+ }
149
+ };
150
+ };
151
+ }
152
+
153
+ temp = temp.sort(obj.parent.config.sorting(order));
154
+
155
+ // Save history
156
+ const newValue = [];
157
+ for (let j = 0; j < temp.length; j++) {
158
+ newValue[j] = temp[j][0];
159
+ }
160
+
161
+ // Save history
162
+ setHistory.call(obj, {
163
+ action: 'orderBy',
164
+ rows: newValue,
165
+ column: column,
166
+ order: order,
167
+ });
168
+
169
+ // Update order
170
+ updateOrderArrow.call(obj, column, order);
171
+ updateOrder.call(obj, newValue);
172
+
173
+ // On sort event
174
+ dispatch.call(
175
+ obj,
176
+ 'onsort',
177
+ obj,
178
+ column,
179
+ order,
180
+ newValue.map((row) => row)
181
+ );
182
+
183
+ return true;
184
+ }
185
+ };