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.
- package/LICENSE +21 -0
- package/README.md +292 -0
- package/dist/index.d.ts +2382 -0
- package/dist/index.js +11286 -0
- package/dist/index.js.map +1 -0
- package/dist/jspreadsheet.css +723 -0
- package/dist/jspreadsheet.themes.css +104 -0
- package/package.json +57 -0
- package/src/index.js +95 -0
- package/src/test.js +50 -0
- package/src/utils/cells.js +36 -0
- package/src/utils/columns.js +742 -0
- package/src/utils/comments.js +87 -0
- package/src/utils/config.js +46 -0
- package/src/utils/copyPaste.js +438 -0
- package/src/utils/data.js +419 -0
- package/src/utils/dispatch.js +115 -0
- package/src/utils/download.js +38 -0
- package/src/utils/editor.js +430 -0
- package/src/utils/events.js +1639 -0
- package/src/utils/factory.js +216 -0
- package/src/utils/filter.js +128 -0
- package/src/utils/footer.js +51 -0
- package/src/utils/freeze.js +19 -0
- package/src/utils/headers.js +74 -0
- package/src/utils/helpers.js +409 -0
- package/src/utils/history.js +336 -0
- package/src/utils/internal.js +1299 -0
- package/src/utils/internalHelpers.js +96 -0
- package/src/utils/keys.js +406 -0
- package/src/utils/lazyLoading.js +143 -0
- package/src/utils/libraryBase.js +5 -0
- package/src/utils/merges.js +275 -0
- package/src/utils/meta.js +81 -0
- package/src/utils/orderBy.js +185 -0
- package/src/utils/pagination.js +181 -0
- package/src/utils/rows.js +624 -0
- package/src/utils/search.js +83 -0
- package/src/utils/selection.js +744 -0
- package/src/utils/style.js +147 -0
- package/src/utils/toolbar.js +566 -0
- package/src/utils/version.js +9 -0
- package/src/utils/worksheets.js +731 -0
- package/src/webcomponent.js +59 -0
|
@@ -0,0 +1,744 @@
|
|
|
1
|
+
import dispatch from './dispatch.js';
|
|
2
|
+
import { getFreezeWidth } from './freeze.js';
|
|
3
|
+
import { getCellNameFromCoords } from './helpers.js';
|
|
4
|
+
import { setHistory } from './history.js';
|
|
5
|
+
import { updateCell, updateFormula, updateFormulaChain, updateTable } from './internal.js';
|
|
6
|
+
import { getColumnNameFromId, getIdFromColumnName } from './internalHelpers.js';
|
|
7
|
+
import { updateToolbar } from './toolbar.js';
|
|
8
|
+
|
|
9
|
+
export const updateCornerPosition = function () {
|
|
10
|
+
const obj = this;
|
|
11
|
+
|
|
12
|
+
// If any selected cells
|
|
13
|
+
if (!obj.highlighted || !obj.highlighted.length) {
|
|
14
|
+
obj.corner.style.top = '-2000px';
|
|
15
|
+
obj.corner.style.left = '-2000px';
|
|
16
|
+
} else {
|
|
17
|
+
// Get last cell
|
|
18
|
+
const last = obj.highlighted[obj.highlighted.length - 1].element;
|
|
19
|
+
const lastX = last.getAttribute('data-x');
|
|
20
|
+
|
|
21
|
+
const contentRect = obj.content.getBoundingClientRect();
|
|
22
|
+
const x1 = contentRect.left;
|
|
23
|
+
const y1 = contentRect.top;
|
|
24
|
+
|
|
25
|
+
const lastRect = last.getBoundingClientRect();
|
|
26
|
+
const x2 = lastRect.left;
|
|
27
|
+
const y2 = lastRect.top;
|
|
28
|
+
const w2 = lastRect.width;
|
|
29
|
+
const h2 = lastRect.height;
|
|
30
|
+
|
|
31
|
+
const x = x2 - x1 + obj.content.scrollLeft + w2 - 4;
|
|
32
|
+
const y = y2 - y1 + obj.content.scrollTop + h2 - 4;
|
|
33
|
+
|
|
34
|
+
// Place the corner in the correct place
|
|
35
|
+
obj.corner.style.top = y + 'px';
|
|
36
|
+
obj.corner.style.left = x + 'px';
|
|
37
|
+
|
|
38
|
+
if (obj.options.freezeColumns) {
|
|
39
|
+
const width = getFreezeWidth.call(obj);
|
|
40
|
+
// Only check if the last column is not part of the merged cells
|
|
41
|
+
if (lastX > obj.options.freezeColumns - 1 && x2 - x1 + w2 < width) {
|
|
42
|
+
obj.corner.style.display = 'none';
|
|
43
|
+
} else {
|
|
44
|
+
if (obj.options.selectionCopy != false) {
|
|
45
|
+
obj.corner.style.display = '';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
if (obj.options.selectionCopy != false) {
|
|
50
|
+
obj.corner.style.display = '';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
updateToolbar(obj);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const resetSelection = function (blur) {
|
|
59
|
+
const obj = this;
|
|
60
|
+
|
|
61
|
+
let previousStatus;
|
|
62
|
+
|
|
63
|
+
// Remove style
|
|
64
|
+
if (!obj.highlighted || !obj.highlighted.length) {
|
|
65
|
+
previousStatus = 0;
|
|
66
|
+
} else {
|
|
67
|
+
previousStatus = 1;
|
|
68
|
+
|
|
69
|
+
for (let i = 0; i < obj.highlighted.length; i++) {
|
|
70
|
+
obj.highlighted[i].element.classList.remove('highlight');
|
|
71
|
+
obj.highlighted[i].element.classList.remove('highlight-left');
|
|
72
|
+
obj.highlighted[i].element.classList.remove('highlight-right');
|
|
73
|
+
obj.highlighted[i].element.classList.remove('highlight-top');
|
|
74
|
+
obj.highlighted[i].element.classList.remove('highlight-bottom');
|
|
75
|
+
obj.highlighted[i].element.classList.remove('highlight-selected');
|
|
76
|
+
|
|
77
|
+
const px = parseInt(obj.highlighted[i].element.getAttribute('data-x'));
|
|
78
|
+
const py = parseInt(obj.highlighted[i].element.getAttribute('data-y'));
|
|
79
|
+
|
|
80
|
+
// Check for merged cells
|
|
81
|
+
let ux, uy;
|
|
82
|
+
|
|
83
|
+
if (obj.highlighted[i].element.getAttribute('data-merged')) {
|
|
84
|
+
const colspan = parseInt(obj.highlighted[i].element.getAttribute('colspan'));
|
|
85
|
+
const rowspan = parseInt(obj.highlighted[i].element.getAttribute('rowspan'));
|
|
86
|
+
ux = colspan > 0 ? px + (colspan - 1) : px;
|
|
87
|
+
uy = rowspan > 0 ? py + (rowspan - 1) : py;
|
|
88
|
+
} else {
|
|
89
|
+
ux = px;
|
|
90
|
+
uy = py;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Remove selected from headers
|
|
94
|
+
for (let j = px; j <= ux; j++) {
|
|
95
|
+
if (obj.headers[j]) {
|
|
96
|
+
obj.headers[j].classList.remove('selected');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Remove selected from rows
|
|
101
|
+
for (let j = py; j <= uy; j++) {
|
|
102
|
+
if (obj.rows[j]) {
|
|
103
|
+
obj.rows[j].element.classList.remove('selected');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Reset highlighted cells
|
|
110
|
+
obj.highlighted = [];
|
|
111
|
+
|
|
112
|
+
// Reset
|
|
113
|
+
obj.selectedCell = null;
|
|
114
|
+
|
|
115
|
+
// Hide corner
|
|
116
|
+
obj.corner.style.top = '-2000px';
|
|
117
|
+
obj.corner.style.left = '-2000px';
|
|
118
|
+
|
|
119
|
+
if (blur == true && previousStatus == 1) {
|
|
120
|
+
dispatch.call(obj, 'onblur', obj);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return previousStatus;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Update selection based on two cells
|
|
128
|
+
*/
|
|
129
|
+
export const updateSelection = function (el1, el2, origin) {
|
|
130
|
+
const obj = this;
|
|
131
|
+
|
|
132
|
+
const x1 = el1.getAttribute('data-x');
|
|
133
|
+
const y1 = el1.getAttribute('data-y');
|
|
134
|
+
|
|
135
|
+
let x2, y2;
|
|
136
|
+
if (el2) {
|
|
137
|
+
x2 = el2.getAttribute('data-x');
|
|
138
|
+
y2 = el2.getAttribute('data-y');
|
|
139
|
+
} else {
|
|
140
|
+
x2 = x1;
|
|
141
|
+
y2 = y1;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
updateSelectionFromCoords.call(obj, x1, y1, x2, y2, origin);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const removeCopyingSelection = function () {
|
|
148
|
+
const copying = document.querySelectorAll('.jss_worksheet .copying');
|
|
149
|
+
for (let i = 0; i < copying.length; i++) {
|
|
150
|
+
copying[i].classList.remove('copying');
|
|
151
|
+
copying[i].classList.remove('copying-left');
|
|
152
|
+
copying[i].classList.remove('copying-right');
|
|
153
|
+
copying[i].classList.remove('copying-top');
|
|
154
|
+
copying[i].classList.remove('copying-bottom');
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export const updateSelectionFromCoords = function (x1, y1, x2, y2, origin) {
|
|
159
|
+
const obj = this;
|
|
160
|
+
|
|
161
|
+
// select column
|
|
162
|
+
if (y1 == null) {
|
|
163
|
+
y1 = 0;
|
|
164
|
+
y2 = obj.rows.length - 1;
|
|
165
|
+
|
|
166
|
+
if (x1 == null) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
} else if (x1 == null) {
|
|
170
|
+
// select row
|
|
171
|
+
x1 = 0;
|
|
172
|
+
x2 = obj.options.data[0].length - 1;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Same element
|
|
176
|
+
if (x2 == null) {
|
|
177
|
+
x2 = x1;
|
|
178
|
+
}
|
|
179
|
+
if (y2 == null) {
|
|
180
|
+
y2 = y1;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Selection must be within the existing data
|
|
184
|
+
if (x1 >= obj.headers.length) {
|
|
185
|
+
x1 = obj.headers.length - 1;
|
|
186
|
+
}
|
|
187
|
+
if (y1 >= obj.rows.length) {
|
|
188
|
+
y1 = obj.rows.length - 1;
|
|
189
|
+
}
|
|
190
|
+
if (x2 >= obj.headers.length) {
|
|
191
|
+
x2 = obj.headers.length - 1;
|
|
192
|
+
}
|
|
193
|
+
if (y2 >= obj.rows.length) {
|
|
194
|
+
y2 = obj.rows.length - 1;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Limits
|
|
198
|
+
let borderLeft = null;
|
|
199
|
+
let borderRight = null;
|
|
200
|
+
let borderTop = null;
|
|
201
|
+
let borderBottom = null;
|
|
202
|
+
|
|
203
|
+
// Origin & Destination
|
|
204
|
+
let px, ux;
|
|
205
|
+
|
|
206
|
+
if (parseInt(x1) < parseInt(x2)) {
|
|
207
|
+
px = parseInt(x1);
|
|
208
|
+
ux = parseInt(x2);
|
|
209
|
+
} else {
|
|
210
|
+
px = parseInt(x2);
|
|
211
|
+
ux = parseInt(x1);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
let py, uy;
|
|
215
|
+
|
|
216
|
+
if (parseInt(y1) < parseInt(y2)) {
|
|
217
|
+
py = parseInt(y1);
|
|
218
|
+
uy = parseInt(y2);
|
|
219
|
+
} else {
|
|
220
|
+
py = parseInt(y2);
|
|
221
|
+
uy = parseInt(y1);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Verify merged columns
|
|
225
|
+
for (let i = px; i <= ux; i++) {
|
|
226
|
+
for (let j = py; j <= uy; j++) {
|
|
227
|
+
if (obj.records[j][i] && obj.records[j][i].element.getAttribute('data-merged')) {
|
|
228
|
+
const x = parseInt(obj.records[j][i].element.getAttribute('data-x'));
|
|
229
|
+
const y = parseInt(obj.records[j][i].element.getAttribute('data-y'));
|
|
230
|
+
const colspan = parseInt(obj.records[j][i].element.getAttribute('colspan'));
|
|
231
|
+
const rowspan = parseInt(obj.records[j][i].element.getAttribute('rowspan'));
|
|
232
|
+
|
|
233
|
+
if (colspan > 1) {
|
|
234
|
+
if (x < px) {
|
|
235
|
+
px = x;
|
|
236
|
+
}
|
|
237
|
+
if (x + colspan > ux) {
|
|
238
|
+
ux = x + colspan - 1;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (rowspan) {
|
|
243
|
+
if (y < py) {
|
|
244
|
+
py = y;
|
|
245
|
+
}
|
|
246
|
+
if (y + rowspan > uy) {
|
|
247
|
+
uy = y + rowspan - 1;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Vertical limits
|
|
255
|
+
for (let j = py; j <= uy; j++) {
|
|
256
|
+
if (obj.rows[j].element.style.display != 'none') {
|
|
257
|
+
if (borderTop == null) {
|
|
258
|
+
borderTop = j;
|
|
259
|
+
}
|
|
260
|
+
borderBottom = j;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
for (let i = px; i <= ux; i++) {
|
|
265
|
+
for (let j = py; j <= uy; j++) {
|
|
266
|
+
// Horizontal limits
|
|
267
|
+
if (!obj.options.columns || !obj.options.columns[i] || obj.options.columns[i].type != 'hidden') {
|
|
268
|
+
if (borderLeft == null) {
|
|
269
|
+
borderLeft = i;
|
|
270
|
+
}
|
|
271
|
+
borderRight = i;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Create borders
|
|
277
|
+
if (!borderLeft) {
|
|
278
|
+
borderLeft = 0;
|
|
279
|
+
}
|
|
280
|
+
if (!borderRight) {
|
|
281
|
+
borderRight = 0;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const ret = dispatch.call(obj, 'onbeforeselection', obj, borderLeft, borderTop, borderRight, borderBottom, origin);
|
|
285
|
+
if (ret === false) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Reset Selection
|
|
290
|
+
const previousState = obj.resetSelection();
|
|
291
|
+
|
|
292
|
+
// Keep selected cell
|
|
293
|
+
obj.selectedCell = [x1, y1, x2, y2];
|
|
294
|
+
|
|
295
|
+
// Add selected cell
|
|
296
|
+
if (obj.records[y1][x1]) {
|
|
297
|
+
obj.records[y1][x1].element.classList.add('highlight-selected');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Redefining styles
|
|
301
|
+
for (let i = px; i <= ux; i++) {
|
|
302
|
+
for (let j = py; j <= uy; j++) {
|
|
303
|
+
if (obj.rows[j].element.style.display != 'none' && obj.records[j][i].element.style.display != 'none') {
|
|
304
|
+
obj.records[j][i].element.classList.add('highlight');
|
|
305
|
+
obj.highlighted.push(obj.records[j][i]);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
for (let i = borderLeft; i <= borderRight; i++) {
|
|
311
|
+
if (
|
|
312
|
+
(!obj.options.columns || !obj.options.columns[i] || obj.options.columns[i].type != 'hidden') &&
|
|
313
|
+
obj.cols[i].colElement.style &&
|
|
314
|
+
obj.cols[i].colElement.style.display != 'none'
|
|
315
|
+
) {
|
|
316
|
+
// Top border
|
|
317
|
+
if (obj.records[borderTop] && obj.records[borderTop][i]) {
|
|
318
|
+
obj.records[borderTop][i].element.classList.add('highlight-top');
|
|
319
|
+
}
|
|
320
|
+
// Bottom border
|
|
321
|
+
if (obj.records[borderBottom] && obj.records[borderBottom][i]) {
|
|
322
|
+
obj.records[borderBottom][i].element.classList.add('highlight-bottom');
|
|
323
|
+
}
|
|
324
|
+
// Add selected from headers
|
|
325
|
+
obj.headers[i].classList.add('selected');
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
for (let j = borderTop; j <= borderBottom; j++) {
|
|
330
|
+
if (obj.rows[j] && obj.rows[j].element.style.display != 'none') {
|
|
331
|
+
// Left border
|
|
332
|
+
obj.records[j][borderLeft].element.classList.add('highlight-left');
|
|
333
|
+
// Right border
|
|
334
|
+
obj.records[j][borderRight].element.classList.add('highlight-right');
|
|
335
|
+
// Add selected from rows
|
|
336
|
+
obj.rows[j].element.classList.add('selected');
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
obj.selectedContainer = [borderLeft, borderTop, borderRight, borderBottom];
|
|
341
|
+
|
|
342
|
+
// Handle events
|
|
343
|
+
if (previousState == 0) {
|
|
344
|
+
dispatch.call(obj, 'onfocus', obj);
|
|
345
|
+
|
|
346
|
+
removeCopyingSelection();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
dispatch.call(obj, 'onselection', obj, borderLeft, borderTop, borderRight, borderBottom, origin);
|
|
350
|
+
|
|
351
|
+
// Find corner cell
|
|
352
|
+
updateCornerPosition.call(obj);
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Get selected column numbers
|
|
357
|
+
*
|
|
358
|
+
* @return array
|
|
359
|
+
*/
|
|
360
|
+
export const getSelectedColumns = function (visibleOnly) {
|
|
361
|
+
const obj = this;
|
|
362
|
+
|
|
363
|
+
if (!obj.selectedCell) {
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const result = [];
|
|
368
|
+
|
|
369
|
+
for (let i = Math.min(obj.selectedCell[0], obj.selectedCell[2]); i <= Math.max(obj.selectedCell[0], obj.selectedCell[2]); i++) {
|
|
370
|
+
if (!visibleOnly || obj.headers[i].style.display != 'none') {
|
|
371
|
+
result.push(i);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return result;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Refresh current selection
|
|
380
|
+
*/
|
|
381
|
+
export const refreshSelection = function () {
|
|
382
|
+
const obj = this;
|
|
383
|
+
|
|
384
|
+
if (obj.selectedCell) {
|
|
385
|
+
obj.updateSelectionFromCoords(obj.selectedCell[0], obj.selectedCell[1], obj.selectedCell[2], obj.selectedCell[3]);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Remove copy selection
|
|
391
|
+
*
|
|
392
|
+
* @return void
|
|
393
|
+
*/
|
|
394
|
+
export const removeCopySelection = function () {
|
|
395
|
+
const obj = this;
|
|
396
|
+
|
|
397
|
+
// Remove current selection
|
|
398
|
+
for (let i = 0; i < obj.selection.length; i++) {
|
|
399
|
+
obj.selection[i].classList.remove('selection');
|
|
400
|
+
obj.selection[i].classList.remove('selection-left');
|
|
401
|
+
obj.selection[i].classList.remove('selection-right');
|
|
402
|
+
obj.selection[i].classList.remove('selection-top');
|
|
403
|
+
obj.selection[i].classList.remove('selection-bottom');
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
obj.selection = [];
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
const doubleDigitFormat = function (v) {
|
|
410
|
+
v = '' + v;
|
|
411
|
+
if (v.length == 1) {
|
|
412
|
+
v = '0' + v;
|
|
413
|
+
}
|
|
414
|
+
return v;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Helper function to copy data using the corner icon
|
|
419
|
+
*/
|
|
420
|
+
export const copyData = function (o, d) {
|
|
421
|
+
const obj = this;
|
|
422
|
+
|
|
423
|
+
// Get data from all selected cells
|
|
424
|
+
const data = obj.getData(true, false);
|
|
425
|
+
|
|
426
|
+
// Selected cells
|
|
427
|
+
const h = obj.selectedContainer;
|
|
428
|
+
|
|
429
|
+
// Cells
|
|
430
|
+
const x1 = parseInt(o.getAttribute('data-x'));
|
|
431
|
+
const y1 = parseInt(o.getAttribute('data-y'));
|
|
432
|
+
const x2 = parseInt(d.getAttribute('data-x'));
|
|
433
|
+
const y2 = parseInt(d.getAttribute('data-y'));
|
|
434
|
+
|
|
435
|
+
// Records
|
|
436
|
+
const records = [];
|
|
437
|
+
let breakControl = false;
|
|
438
|
+
|
|
439
|
+
let rowNumber, colNumber;
|
|
440
|
+
|
|
441
|
+
if (h[0] == x1) {
|
|
442
|
+
// Vertical copy
|
|
443
|
+
if (y1 < h[1]) {
|
|
444
|
+
rowNumber = y1 - h[1];
|
|
445
|
+
} else {
|
|
446
|
+
rowNumber = 1;
|
|
447
|
+
}
|
|
448
|
+
colNumber = 0;
|
|
449
|
+
} else {
|
|
450
|
+
if (x1 < h[0]) {
|
|
451
|
+
colNumber = x1 - h[0];
|
|
452
|
+
} else {
|
|
453
|
+
colNumber = 1;
|
|
454
|
+
}
|
|
455
|
+
rowNumber = 0;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Copy data procedure
|
|
459
|
+
let posx = 0;
|
|
460
|
+
let posy = 0;
|
|
461
|
+
|
|
462
|
+
for (let j = y1; j <= y2; j++) {
|
|
463
|
+
// Skip hidden rows
|
|
464
|
+
if (obj.rows[j] && obj.rows[j].element.style.display == 'none') {
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Controls
|
|
469
|
+
if (data[posy] == undefined) {
|
|
470
|
+
posy = 0;
|
|
471
|
+
}
|
|
472
|
+
posx = 0;
|
|
473
|
+
|
|
474
|
+
// Data columns
|
|
475
|
+
if (h[0] != x1) {
|
|
476
|
+
if (x1 < h[0]) {
|
|
477
|
+
colNumber = x1 - h[0];
|
|
478
|
+
} else {
|
|
479
|
+
colNumber = 1;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// Data columns
|
|
483
|
+
for (let i = x1; i <= x2; i++) {
|
|
484
|
+
// Update non-readonly
|
|
485
|
+
if (
|
|
486
|
+
obj.records[j][i] &&
|
|
487
|
+
!obj.records[j][i].element.classList.contains('readonly') &&
|
|
488
|
+
obj.records[j][i].element.style.display != 'none' &&
|
|
489
|
+
breakControl == false
|
|
490
|
+
) {
|
|
491
|
+
// Stop if contains value
|
|
492
|
+
if (!obj.selection.length) {
|
|
493
|
+
if (obj.options.data[j][i] != '') {
|
|
494
|
+
breakControl = true;
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Column
|
|
500
|
+
if (data[posy] == undefined) {
|
|
501
|
+
posx = 0;
|
|
502
|
+
} else if (data[posy][posx] == undefined) {
|
|
503
|
+
posx = 0;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Value
|
|
507
|
+
let value = data[posy][posx];
|
|
508
|
+
|
|
509
|
+
if (value && !data[1] && obj.parent.config.autoIncrement != false) {
|
|
510
|
+
if (
|
|
511
|
+
obj.options.columns &&
|
|
512
|
+
obj.options.columns[i] &&
|
|
513
|
+
(!obj.options.columns[i].type || obj.options.columns[i].type == 'text' || obj.options.columns[i].type == 'number')
|
|
514
|
+
) {
|
|
515
|
+
if (('' + value).substr(0, 1) == '=') {
|
|
516
|
+
const tokens = value.match(/([A-Z]+[0-9]+)/g);
|
|
517
|
+
|
|
518
|
+
if (tokens) {
|
|
519
|
+
const affectedTokens = [];
|
|
520
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
521
|
+
const position = getIdFromColumnName(tokens[index], 1);
|
|
522
|
+
position[0] += colNumber;
|
|
523
|
+
position[1] += rowNumber;
|
|
524
|
+
if (position[1] < 0) {
|
|
525
|
+
position[1] = 0;
|
|
526
|
+
}
|
|
527
|
+
const token = getColumnNameFromId([position[0], position[1]]);
|
|
528
|
+
|
|
529
|
+
if (token != tokens[index]) {
|
|
530
|
+
affectedTokens[tokens[index]] = token;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
// Update formula
|
|
534
|
+
if (affectedTokens) {
|
|
535
|
+
value = updateFormula(value, affectedTokens);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
} else {
|
|
539
|
+
if (value == Number(value)) {
|
|
540
|
+
value = Number(value) + rowNumber;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
} else if (obj.options.columns && obj.options.columns[i] && obj.options.columns[i].type == 'calendar') {
|
|
544
|
+
const date = new Date(value);
|
|
545
|
+
date.setDate(date.getDate() + rowNumber);
|
|
546
|
+
value =
|
|
547
|
+
date.getFullYear() +
|
|
548
|
+
'-' +
|
|
549
|
+
doubleDigitFormat(parseInt(date.getMonth() + 1)) +
|
|
550
|
+
'-' +
|
|
551
|
+
doubleDigitFormat(date.getDate()) +
|
|
552
|
+
' ' +
|
|
553
|
+
'00:00:00';
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
records.push(updateCell.call(obj, i, j, value));
|
|
558
|
+
|
|
559
|
+
// Update all formulas in the chain
|
|
560
|
+
updateFormulaChain.call(obj, i, j, records);
|
|
561
|
+
}
|
|
562
|
+
posx++;
|
|
563
|
+
if (h[0] != x1) {
|
|
564
|
+
colNumber++;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
posy++;
|
|
568
|
+
rowNumber++;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Update history
|
|
572
|
+
setHistory.call(obj, {
|
|
573
|
+
action: 'setValue',
|
|
574
|
+
records: records,
|
|
575
|
+
selection: obj.selectedCell,
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
// Update table with custom configuration if applicable
|
|
579
|
+
updateTable.call(obj);
|
|
580
|
+
|
|
581
|
+
// On after changes
|
|
582
|
+
const onafterchangesRecords = records.map(function (record) {
|
|
583
|
+
return {
|
|
584
|
+
x: record.x,
|
|
585
|
+
y: record.y,
|
|
586
|
+
value: record.value,
|
|
587
|
+
oldValue: record.oldValue,
|
|
588
|
+
};
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
dispatch.call(obj, 'onafterchanges', obj, onafterchangesRecords);
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
export const hash = function (str) {
|
|
595
|
+
let hash = 0,
|
|
596
|
+
i,
|
|
597
|
+
chr;
|
|
598
|
+
|
|
599
|
+
if (!str || str.length === 0) {
|
|
600
|
+
return hash;
|
|
601
|
+
} else {
|
|
602
|
+
for (i = 0; i < str.length; i++) {
|
|
603
|
+
chr = str.charCodeAt(i);
|
|
604
|
+
hash = (hash << 5) - hash + chr;
|
|
605
|
+
hash |= 0;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
return hash;
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Move coords to A1 in case overlaps with an excluded cell
|
|
613
|
+
*/
|
|
614
|
+
export const conditionalSelectionUpdate = function (type, o, d) {
|
|
615
|
+
const obj = this;
|
|
616
|
+
|
|
617
|
+
if (type == 1) {
|
|
618
|
+
if (obj.selectedCell && ((o >= obj.selectedCell[1] && o <= obj.selectedCell[3]) || (d >= obj.selectedCell[1] && d <= obj.selectedCell[3]))) {
|
|
619
|
+
obj.resetSelection();
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
} else {
|
|
623
|
+
if (obj.selectedCell && ((o >= obj.selectedCell[0] && o <= obj.selectedCell[2]) || (d >= obj.selectedCell[0] && d <= obj.selectedCell[2]))) {
|
|
624
|
+
obj.resetSelection();
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Get selected rows numbers
|
|
632
|
+
*
|
|
633
|
+
* @return array
|
|
634
|
+
*/
|
|
635
|
+
export const getSelectedRows = function (visibleOnly) {
|
|
636
|
+
const obj = this;
|
|
637
|
+
|
|
638
|
+
if (!obj.selectedCell) {
|
|
639
|
+
return [];
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
const result = [];
|
|
643
|
+
|
|
644
|
+
for (let i = Math.min(obj.selectedCell[1], obj.selectedCell[3]); i <= Math.max(obj.selectedCell[1], obj.selectedCell[3]); i++) {
|
|
645
|
+
if (!visibleOnly || obj.rows[i].element.style.display != 'none') {
|
|
646
|
+
result.push(i);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
return result;
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
export const selectAll = function () {
|
|
654
|
+
const obj = this;
|
|
655
|
+
|
|
656
|
+
if (!obj.selectedCell) {
|
|
657
|
+
obj.selectedCell = [];
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
obj.selectedCell[0] = 0;
|
|
661
|
+
obj.selectedCell[1] = 0;
|
|
662
|
+
obj.selectedCell[2] = obj.headers.length - 1;
|
|
663
|
+
obj.selectedCell[3] = obj.records.length - 1;
|
|
664
|
+
|
|
665
|
+
obj.updateSelectionFromCoords(obj.selectedCell[0], obj.selectedCell[1], obj.selectedCell[2], obj.selectedCell[3]);
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
export const getSelection = function () {
|
|
669
|
+
const obj = this;
|
|
670
|
+
|
|
671
|
+
if (!obj.selectedCell) {
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
return [
|
|
676
|
+
Math.min(obj.selectedCell[0], obj.selectedCell[2]),
|
|
677
|
+
Math.min(obj.selectedCell[1], obj.selectedCell[3]),
|
|
678
|
+
Math.max(obj.selectedCell[0], obj.selectedCell[2]),
|
|
679
|
+
Math.max(obj.selectedCell[1], obj.selectedCell[3]),
|
|
680
|
+
];
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
export const getSelected = function (columnNameOnly) {
|
|
684
|
+
const obj = this;
|
|
685
|
+
|
|
686
|
+
const selectedRange = getSelection.call(obj);
|
|
687
|
+
|
|
688
|
+
if (!selectedRange) {
|
|
689
|
+
return [];
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const cells = [];
|
|
693
|
+
|
|
694
|
+
for (let y = selectedRange[1]; y <= selectedRange[3]; y++) {
|
|
695
|
+
for (let x = selectedRange[0]; x <= selectedRange[2]; x++) {
|
|
696
|
+
if (columnNameOnly) {
|
|
697
|
+
cells.push(getCellNameFromCoords(x, y));
|
|
698
|
+
} else {
|
|
699
|
+
cells.push(obj.records[y][x]);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
return cells;
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
export const getRange = function () {
|
|
708
|
+
const obj = this;
|
|
709
|
+
|
|
710
|
+
const selectedRange = getSelection.call(obj);
|
|
711
|
+
|
|
712
|
+
if (!selectedRange) {
|
|
713
|
+
return '';
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
const start = getCellNameFromCoords(selectedRange[0], selectedRange[1]);
|
|
717
|
+
const end = getCellNameFromCoords(selectedRange[2], selectedRange[3]);
|
|
718
|
+
|
|
719
|
+
if (start === end) {
|
|
720
|
+
return obj.options.worksheetName + '!' + start;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
return obj.options.worksheetName + '!' + start + ':' + end;
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
export const isSelected = function (x, y) {
|
|
727
|
+
const obj = this;
|
|
728
|
+
|
|
729
|
+
const selection = getSelection.call(obj);
|
|
730
|
+
|
|
731
|
+
return x >= selection[0] && x <= selection[2] && y >= selection[1] && y <= selection[3];
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
export const getHighlighted = function () {
|
|
735
|
+
const obj = this;
|
|
736
|
+
|
|
737
|
+
const selection = getSelection.call(obj);
|
|
738
|
+
|
|
739
|
+
if (selection) {
|
|
740
|
+
return [selection];
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
return [];
|
|
744
|
+
};
|