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,419 @@
1
+ import { createRow } from './rows.js';
2
+ import { updateCell, updateFormulaChain, updateTable } from './internal.js';
3
+ import { getIdFromColumnName } from './internalHelpers.js';
4
+ import dispatch from './dispatch.js';
5
+ import { setHistory } from './history.js';
6
+ import { updatePagination } from './pagination.js';
7
+ import { setMerge } from './merges.js';
8
+ import { getCoordsFromRange } from './helpers.js';
9
+
10
+ export const setData = function (data) {
11
+ const obj = this;
12
+
13
+ // Update data
14
+ if (data) {
15
+ obj.options.data = data;
16
+ }
17
+
18
+ // Data
19
+ if (!obj.options.data) {
20
+ obj.options.data = [];
21
+ }
22
+
23
+ // Prepare data
24
+ if (obj.options.data && obj.options.data[0]) {
25
+ // 处理不是二维数组的情况
26
+ if (!Array.isArray(obj.options.data[0])) {
27
+ data = [];
28
+ for (let j = 0; j < obj.options.data.length; j++) {
29
+ const row = [];
30
+ // 根据columns长度设置行数据
31
+ for (let i = 0; i < obj.options.columns.length; i++) {
32
+ row[i] = obj.options.data[j][obj.options.columns[i].name];
33
+ }
34
+ data.push(row);
35
+ }
36
+
37
+ obj.options.data = data;
38
+ }
39
+ }
40
+
41
+ // Adjust minimal dimensions
42
+ let j = 0;
43
+ let i = 0;
44
+ const size_i = (obj.options.columns && obj.options.columns.length) || 0;
45
+ const size_j = obj.options.data.length;
46
+ const min_i = obj.options.minDimensions[0];
47
+ const min_j = obj.options.minDimensions[1];
48
+ const max_i = min_i > size_i ? min_i : size_i;
49
+ const max_j = min_j > size_j ? min_j : size_j;
50
+
51
+ for (j = 0; j < max_j; j++) {
52
+ for (i = 0; i < max_i; i++) {
53
+ if (obj.options.data[j] == undefined) {
54
+ obj.options.data[j] = [];
55
+ }
56
+
57
+ if (obj.options.data[j][i] == undefined) {
58
+ obj.options.data[j][i] = '';
59
+ }
60
+ }
61
+ }
62
+
63
+ // Reset containers
64
+ obj.rows = [];
65
+ obj.results = null;
66
+ obj.records = [];
67
+ obj.history = [];
68
+
69
+ // Reset internal controllers
70
+ obj.historyIndex = -1;
71
+
72
+ // Reset data
73
+ obj.tbody.innerHTML = '';
74
+
75
+ let startNumber;
76
+ let finalNumber;
77
+
78
+ // Lazy loading
79
+ if (obj.options.lazyLoading == true) {
80
+ // Load only 100 records
81
+ startNumber = 0;
82
+ finalNumber = obj.options.data.length < 100 ? obj.options.data.length : 100;
83
+
84
+ if (obj.options.pagination) {
85
+ obj.options.pagination = false;
86
+ console.error('Jspreadsheet: Pagination will be disable due the lazyLoading');
87
+ }
88
+ } else if (obj.options.pagination) {
89
+ // Pagination
90
+ if (!obj.pageNumber) {
91
+ obj.pageNumber = 0;
92
+ }
93
+ var quantityPerPage = obj.options.pagination;
94
+ startNumber = obj.options.pagination * obj.pageNumber;
95
+ finalNumber = obj.options.pagination * obj.pageNumber + obj.options.pagination;
96
+
97
+ if (obj.options.data.length < finalNumber) {
98
+ finalNumber = obj.options.data.length;
99
+ }
100
+ } else {
101
+ startNumber = 0;
102
+ finalNumber = obj.options.data.length;
103
+ }
104
+
105
+ // Append nodes to the HTML
106
+ for (j = 0; j < obj.options.data.length; j++) {
107
+ // Create row
108
+ const row = createRow.call(obj, j, obj.options.data[j]);
109
+ // Append line to the table
110
+ if (j >= startNumber && j < finalNumber) {
111
+ obj.tbody.appendChild(row.element);
112
+ }
113
+ }
114
+
115
+ if (obj.options.lazyLoading == true) {
116
+ // Do not create pagination with lazyloading activated
117
+ } else if (obj.options.pagination) {
118
+ updatePagination.call(obj);
119
+ }
120
+
121
+ // Merge cells
122
+ if (obj.options.mergeCells) {
123
+ const keys = Object.keys(obj.options.mergeCells);
124
+ for (let i = 0; i < keys.length; i++) {
125
+ const num = obj.options.mergeCells[keys[i]];
126
+ setMerge.call(obj, keys[i], num[0], num[1], 1);
127
+ }
128
+ }
129
+
130
+ // Updata table with custom configurations if applicable
131
+ updateTable.call(obj);
132
+ };
133
+
134
+ /**
135
+ * Get the value from a cell
136
+ *
137
+ * @param object cell
138
+ * @return string value
139
+ */
140
+ export const getValue = function (cell, processedValue) {
141
+ const obj = this;
142
+
143
+ let x;
144
+ let y;
145
+
146
+ if (typeof cell !== 'string') {
147
+ return null;
148
+ }
149
+
150
+ cell = getIdFromColumnName(cell, true);
151
+ x = cell[0];
152
+ y = cell[1];
153
+
154
+ let value = null;
155
+
156
+ if (x != null && y != null) {
157
+ if (obj.records[y] && obj.records[y][x] && processedValue) {
158
+ value = obj.records[y][x].element.innerHTML;
159
+ } else {
160
+ if (obj.options.data[y] && obj.options.data[y][x] != 'undefined') {
161
+ value = obj.options.data[y][x];
162
+ }
163
+ }
164
+ }
165
+
166
+ return value;
167
+ };
168
+
169
+ /**
170
+ * Get the value from a coords
171
+ *
172
+ * @param int x
173
+ * @param int y
174
+ * @return string value
175
+ */
176
+ export const getValueFromCoords = function (x, y, processedValue) {
177
+ const obj = this;
178
+
179
+ let value = null;
180
+
181
+ if (x != null && y != null) {
182
+ if (obj.records[y] && obj.records[y][x] && processedValue) {
183
+ value = obj.records[y][x].element.innerHTML;
184
+ } else {
185
+ if (obj.options.data[y] && obj.options.data[y][x] != 'undefined') {
186
+ value = obj.options.data[y][x];
187
+ }
188
+ }
189
+ }
190
+
191
+ return value;
192
+ };
193
+
194
+ /**
195
+ * Set a cell value
196
+ *
197
+ * @param mixed cell destination cell
198
+ * @param string value value
199
+ * @return void
200
+ */
201
+ export const setValue = function (cell, value, force) {
202
+ const obj = this;
203
+
204
+ const records = [];
205
+
206
+ if (typeof cell == 'string') {
207
+ const columnId = getIdFromColumnName(cell, true);
208
+ const x = columnId[0];
209
+ const y = columnId[1];
210
+
211
+ // Update cell
212
+ records.push(updateCell.call(obj, x, y, value, force));
213
+
214
+ // Update all formulas in the chain
215
+ updateFormulaChain.call(obj, x, y, records);
216
+ } else {
217
+ let x = null;
218
+ let y = null;
219
+ if (cell && cell.getAttribute) {
220
+ x = cell.getAttribute('data-x');
221
+ y = cell.getAttribute('data-y');
222
+ }
223
+
224
+ // Update cell
225
+ if (x != null && y != null) {
226
+ records.push(updateCell.call(obj, x, y, value, force));
227
+
228
+ // Update all formulas in the chain
229
+ updateFormulaChain.call(obj, x, y, records);
230
+ } else {
231
+ const keys = Object.keys(cell);
232
+ if (keys.length > 0) {
233
+ for (let i = 0; i < keys.length; i++) {
234
+ let x, y;
235
+
236
+ if (typeof cell[i] == 'string') {
237
+ const columnId = getIdFromColumnName(cell[i], true);
238
+ x = columnId[0];
239
+ y = columnId[1];
240
+ } else {
241
+ if (cell[i].x != null && cell[i].y != null) {
242
+ x = cell[i].x;
243
+ y = cell[i].y;
244
+ // Flexible setup
245
+ if (cell[i].value != null) {
246
+ value = cell[i].value;
247
+ }
248
+ } else {
249
+ x = cell[i].getAttribute('data-x');
250
+ y = cell[i].getAttribute('data-y');
251
+ }
252
+ }
253
+
254
+ // Update cell
255
+ if (x != null && y != null) {
256
+ records.push(updateCell.call(obj, x, y, value, force));
257
+
258
+ // Update all formulas in the chain
259
+ updateFormulaChain.call(obj, x, y, records);
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+
266
+ // Update history
267
+ setHistory.call(obj, {
268
+ action: 'setValue',
269
+ records: records,
270
+ selection: obj.selectedCell,
271
+ });
272
+
273
+ // Update table with custom configurations if applicable
274
+ updateTable.call(obj);
275
+
276
+ // On after changes
277
+ const onafterchangesRecords = records.map(function (record) {
278
+ return {
279
+ x: record.x,
280
+ y: record.y,
281
+ value: record.value,
282
+ oldValue: record.oldValue,
283
+ };
284
+ });
285
+
286
+ dispatch.call(obj, 'onafterchanges', obj, onafterchangesRecords);
287
+ };
288
+
289
+ /**
290
+ * Set a cell value based on coordinates
291
+ *
292
+ * @param int x destination cell
293
+ * @param int y destination cell
294
+ * @param string value
295
+ * @return void
296
+ */
297
+ export const setValueFromCoords = function (x, y, value, force) {
298
+ const obj = this;
299
+
300
+ const records = [];
301
+ records.push(updateCell.call(obj, x, y, value, force));
302
+
303
+ // Update all formulas in the chain
304
+ updateFormulaChain.call(obj, x, y, records);
305
+
306
+ // Update history
307
+ setHistory.call(obj, {
308
+ action: 'setValue',
309
+ records: records,
310
+ selection: obj.selectedCell,
311
+ });
312
+
313
+ // Update table with custom configurations if applicable
314
+ updateTable.call(obj);
315
+
316
+ // On after changes
317
+ const onafterchangesRecords = records.map(function (record) {
318
+ return {
319
+ x: record.x,
320
+ y: record.y,
321
+ value: record.value,
322
+ oldValue: record.oldValue,
323
+ };
324
+ });
325
+
326
+ dispatch.call(obj, 'onafterchanges', obj, onafterchangesRecords);
327
+ };
328
+
329
+ /**
330
+ * Get the whole table data
331
+ *
332
+ * @param bool get highlighted cells only
333
+ * @return array data
334
+ */
335
+ export const getData = function (highlighted, processed, delimiter, asJson) {
336
+ const obj = this;
337
+
338
+ // Control vars
339
+ const dataset = [];
340
+ let px = 0;
341
+ let py = 0;
342
+
343
+ // Column and row length
344
+ const x = Math.max(
345
+ ...obj.options.data.map(function (row) {
346
+ return row.length;
347
+ })
348
+ );
349
+ const y = obj.options.data.length;
350
+
351
+ // Go through the columns to get the data
352
+ for (let j = 0; j < y; j++) {
353
+ px = 0;
354
+ for (let i = 0; i < x; i++) {
355
+ // Cell selected or fullset
356
+ if (!highlighted || obj.records[j][i].element.classList.contains('highlight')) {
357
+ // Get value
358
+ if (!dataset[py]) {
359
+ dataset[py] = [];
360
+ }
361
+ if (processed) {
362
+ dataset[py][px] = obj.records[j][i].element.innerHTML;
363
+ } else {
364
+ dataset[py][px] = obj.options.data[j][i];
365
+ }
366
+ px++;
367
+ }
368
+ }
369
+ if (px > 0) {
370
+ py++;
371
+ }
372
+ }
373
+
374
+ if (delimiter) {
375
+ return (
376
+ dataset
377
+ .map(function (row) {
378
+ return row.join(delimiter);
379
+ })
380
+ .join('\r\n') + '\r\n'
381
+ );
382
+ }
383
+
384
+ if (asJson) {
385
+ return dataset.map(function (row) {
386
+ const resultRow = {};
387
+
388
+ row.forEach(function (item, index) {
389
+ resultRow[index] = item;
390
+ });
391
+
392
+ return resultRow;
393
+ });
394
+ }
395
+
396
+ return dataset;
397
+ };
398
+
399
+ export const getDataFromRange = function (range, processed) {
400
+ const obj = this;
401
+
402
+ const coords = getCoordsFromRange(range);
403
+
404
+ const dataset = [];
405
+
406
+ for (let y = coords[1]; y <= coords[3]; y++) {
407
+ dataset.push([]);
408
+
409
+ for (let x = coords[0]; x <= coords[2]; x++) {
410
+ if (processed) {
411
+ dataset[dataset.length - 1].push(obj.records[y][x].element.innerHTML);
412
+ } else {
413
+ dataset[dataset.length - 1].push(obj.options.data[y][x]);
414
+ }
415
+ }
416
+ }
417
+
418
+ return dataset;
419
+ };
@@ -0,0 +1,115 @@
1
+ import jSuites from 'jsuites';
2
+
3
+ /**
4
+ * Prepare JSON in the correct format
5
+ */
6
+ const prepareJson = function (data) {
7
+ const obj = this;
8
+
9
+ const rows = [];
10
+ for (let i = 0; i < data.length; i++) {
11
+ const x = data[i].x;
12
+ const y = data[i].y;
13
+ const k = obj.options.columns[x].name ? obj.options.columns[x].name : x;
14
+
15
+ // Create row
16
+ if (!rows[y]) {
17
+ rows[y] = {
18
+ row: y,
19
+ data: {},
20
+ };
21
+ }
22
+ rows[y].data[k] = data[i].value;
23
+ }
24
+
25
+ // Filter rows
26
+ return rows.filter(function (el) {
27
+ return el != null;
28
+ });
29
+ };
30
+
31
+ /**
32
+ * Post json to a remote server
33
+ */
34
+ const save = function (url, data) {
35
+ const obj = this;
36
+
37
+ // Parse anything in the data before sending to the server
38
+ const ret = dispatch.call(obj.parent, 'onbeforesave', obj.parent, obj, data);
39
+ if (ret) {
40
+ data = ret;
41
+ } else {
42
+ if (ret === false) {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ // Remove update
48
+ jSuites.ajax({
49
+ url: url,
50
+ method: 'POST',
51
+ dataType: 'json',
52
+ data: { data: JSON.stringify(data) },
53
+ success: function (result) {
54
+ // Event
55
+ dispatch.call(obj, 'onsave', obj.parent, obj, data);
56
+ },
57
+ });
58
+ };
59
+
60
+ /**
61
+ * Trigger events
62
+ */
63
+ const dispatch = function (event) {
64
+ const obj = this;
65
+ let ret = null;
66
+
67
+ let spreadsheet = obj.parent ? obj.parent : obj;
68
+
69
+ // Dispatch events
70
+ if (!spreadsheet.ignoreEvents) {
71
+ // Call global event
72
+ if (typeof spreadsheet.config.onevent == 'function') {
73
+ ret = spreadsheet.config.onevent.apply(this, arguments);
74
+ }
75
+ // Call specific events
76
+ if (typeof spreadsheet.config[event] == 'function') {
77
+ ret = spreadsheet.config[event].apply(this, Array.prototype.slice.call(arguments, 1));
78
+ }
79
+
80
+ if (typeof spreadsheet.plugins === 'object') {
81
+ const pluginKeys = Object.keys(spreadsheet.plugins);
82
+
83
+ for (let pluginKeyIndex = 0; pluginKeyIndex < pluginKeys.length; pluginKeyIndex++) {
84
+ const key = pluginKeys[pluginKeyIndex];
85
+ const plugin = spreadsheet.plugins[key];
86
+
87
+ if (typeof plugin.onevent === 'function') {
88
+ ret = plugin.onevent.apply(this, arguments);
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ if (event == 'onafterchanges') {
95
+ const scope = arguments;
96
+
97
+ if (typeof spreadsheet.plugins === 'object') {
98
+ Object.entries(spreadsheet.plugins).forEach(function ([, plugin]) {
99
+ if (typeof plugin.persistence === 'function') {
100
+ plugin.persistence(obj, 'setValue', { data: scope[2] });
101
+ }
102
+ });
103
+ }
104
+
105
+ if (obj.options.persistence) {
106
+ const url = obj.options.persistence == true ? obj.options.url : obj.options.persistence;
107
+ const data = prepareJson.call(obj, arguments[2]);
108
+ save.call(obj, url, data);
109
+ }
110
+ }
111
+
112
+ return ret;
113
+ };
114
+
115
+ export default dispatch;
@@ -0,0 +1,38 @@
1
+ import { copy } from './copyPaste.js';
2
+
3
+ /**
4
+ * Download CSV table
5
+ *
6
+ * @return null
7
+ */
8
+ export const download = function (includeHeaders, processed) {
9
+ const obj = this;
10
+
11
+ if (obj.parent.config.allowExport == false) {
12
+ console.error('Export not allowed');
13
+ } else {
14
+ // Data
15
+ let data = '';
16
+
17
+ // Get data
18
+ data += copy.call(obj, false, obj.options.csvDelimiter, true, includeHeaders, true, undefined, processed);
19
+
20
+ // Download element
21
+ const blob = new Blob(['\uFEFF' + data], { type: 'text/csv;charset=utf-8;' });
22
+
23
+ // IE Compatibility
24
+ if (window.navigator && window.navigator.msSaveOrOpenBlob) {
25
+ window.navigator.msSaveOrOpenBlob(blob, (obj.options.csvFileName || obj.options.worksheetName) + '.csv');
26
+ } else {
27
+ // Download element
28
+ const pom = document.createElement('a');
29
+ pom.setAttribute('target', '_top');
30
+ const url = URL.createObjectURL(blob);
31
+ pom.href = url;
32
+ pom.setAttribute('download', (obj.options.csvFileName || obj.options.worksheetName) + '.csv');
33
+ document.body.appendChild(pom);
34
+ pom.click();
35
+ pom.parentNode.removeChild(pom);
36
+ }
37
+ }
38
+ };