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,430 @@
|
|
|
1
|
+
import jSuites from 'jsuites';
|
|
2
|
+
|
|
3
|
+
import dispatch from './dispatch.js';
|
|
4
|
+
import { getMask, isFormula, updateCell } from './internal.js';
|
|
5
|
+
import { setHistory } from './history.js';
|
|
6
|
+
import { getCellNameFromCoords } from './helpers.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Open the editor
|
|
10
|
+
*
|
|
11
|
+
* @param object cell
|
|
12
|
+
* @return void
|
|
13
|
+
*/
|
|
14
|
+
export const openEditor = function (cell, empty, e) {
|
|
15
|
+
const obj = this;
|
|
16
|
+
|
|
17
|
+
// Get cell position
|
|
18
|
+
const y = cell.getAttribute('data-y');
|
|
19
|
+
const x = cell.getAttribute('data-x');
|
|
20
|
+
|
|
21
|
+
// On edition start
|
|
22
|
+
dispatch.call(obj, 'oneditionstart', obj, cell, parseInt(x), parseInt(y));
|
|
23
|
+
|
|
24
|
+
// Overflow
|
|
25
|
+
if (x > 0) {
|
|
26
|
+
obj.records[y][x - 1].element.style.overflow = 'hidden';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Create editor
|
|
30
|
+
const createEditor = function (type) {
|
|
31
|
+
// Cell information
|
|
32
|
+
const info = cell.getBoundingClientRect();
|
|
33
|
+
|
|
34
|
+
// Create dropdown
|
|
35
|
+
const editor = document.createElement(type);
|
|
36
|
+
editor.style.width = info.width + 'px';
|
|
37
|
+
editor.style.height = info.height - 2 + 'px';
|
|
38
|
+
editor.style.minHeight = info.height - 2 + 'px';
|
|
39
|
+
|
|
40
|
+
// Edit cell
|
|
41
|
+
cell.classList.add('editor');
|
|
42
|
+
cell.innerHTML = '';
|
|
43
|
+
cell.appendChild(editor);
|
|
44
|
+
|
|
45
|
+
return editor;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Readonly
|
|
49
|
+
if (cell.classList.contains('readonly') == true) {
|
|
50
|
+
// Do nothing
|
|
51
|
+
} else {
|
|
52
|
+
// Holder
|
|
53
|
+
obj.edition = [obj.records[y][x].element, obj.records[y][x].element.innerHTML, x, y];
|
|
54
|
+
|
|
55
|
+
let config = obj.options.columns && obj.options.columns[x];
|
|
56
|
+
const cellName = getCellNameFromCoords(x, y);
|
|
57
|
+
const cells = obj.options.cells;
|
|
58
|
+
if (typeof cells === 'object' && cells[cellName]) {
|
|
59
|
+
config = cells[cellName];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// If there is a custom editor for it
|
|
63
|
+
if (config && typeof config.type === 'object') {
|
|
64
|
+
// Custom editors
|
|
65
|
+
config.type.openEditor(cell, obj.options.data[y][x], parseInt(x), parseInt(y), obj, config, e);
|
|
66
|
+
|
|
67
|
+
// On edition start
|
|
68
|
+
dispatch.call(obj, 'oncreateeditor', obj, cell, parseInt(x), parseInt(y), null, config);
|
|
69
|
+
} else {
|
|
70
|
+
// Native functions
|
|
71
|
+
if (config && config.type == 'hidden') {
|
|
72
|
+
// Do nothing
|
|
73
|
+
} else if (config && (config.type == 'checkbox' || config.type == 'radio')) {
|
|
74
|
+
// Get value
|
|
75
|
+
const value = cell.children[0].checked ? false : true;
|
|
76
|
+
// Toogle value
|
|
77
|
+
obj.setValue(cell, value);
|
|
78
|
+
// Do not keep edition open
|
|
79
|
+
obj.edition = null;
|
|
80
|
+
} else if (config && config.type == 'dropdown') {
|
|
81
|
+
// Get current value
|
|
82
|
+
let value = obj.options.data[y][x];
|
|
83
|
+
if (config.multiple && !Array.isArray(value)) {
|
|
84
|
+
value = value.split(';');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Create dropdown
|
|
88
|
+
let source;
|
|
89
|
+
|
|
90
|
+
if (typeof config.filter == 'function') {
|
|
91
|
+
source = config.filter(obj.element, cell, x, y, config.source);
|
|
92
|
+
} else {
|
|
93
|
+
source = config.source;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Do not change the original source
|
|
97
|
+
const data = [];
|
|
98
|
+
if (source) {
|
|
99
|
+
for (let j = 0; j < source.length; j++) {
|
|
100
|
+
data.push(source[j]);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Create editor
|
|
105
|
+
const editor = createEditor('div');
|
|
106
|
+
|
|
107
|
+
// On edition start
|
|
108
|
+
dispatch.call(obj, 'oncreateeditor', obj, cell, parseInt(x), parseInt(y), null, config);
|
|
109
|
+
|
|
110
|
+
const options = {
|
|
111
|
+
data: data,
|
|
112
|
+
multiple: config.multiple ? true : false,
|
|
113
|
+
autocomplete: config.autocomplete ? true : false,
|
|
114
|
+
opened: true,
|
|
115
|
+
value: value,
|
|
116
|
+
width: '100%',
|
|
117
|
+
height: editor.style.minHeight,
|
|
118
|
+
position: obj.options.tableOverflow == true || obj.parent.config.fullscreen == true ? true : false,
|
|
119
|
+
onclose: function () {
|
|
120
|
+
closeEditor.call(obj, cell, true);
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
if (config.options && config.options.type) {
|
|
124
|
+
options.type = config.options.type;
|
|
125
|
+
}
|
|
126
|
+
jSuites.dropdown(editor, options);
|
|
127
|
+
} else if (config && (config.type == 'calendar' || config.type == 'color')) {
|
|
128
|
+
// Value
|
|
129
|
+
const value = obj.options.data[y][x];
|
|
130
|
+
// Create editor
|
|
131
|
+
const editor = createEditor('input');
|
|
132
|
+
|
|
133
|
+
dispatch.call(obj, 'oncreateeditor', obj, cell, parseInt(x), parseInt(y), null, config);
|
|
134
|
+
|
|
135
|
+
editor.value = value;
|
|
136
|
+
|
|
137
|
+
const options = config.options ? { ...config.options } : {};
|
|
138
|
+
|
|
139
|
+
if (obj.options.tableOverflow == true || obj.parent.config.fullscreen == true) {
|
|
140
|
+
options.position = true;
|
|
141
|
+
}
|
|
142
|
+
options.value = obj.options.data[y][x];
|
|
143
|
+
options.opened = true;
|
|
144
|
+
options.onclose = function (el, value) {
|
|
145
|
+
closeEditor.call(obj, cell, true);
|
|
146
|
+
};
|
|
147
|
+
// Current value
|
|
148
|
+
if (config.type == 'color') {
|
|
149
|
+
jSuites.color(editor, options);
|
|
150
|
+
|
|
151
|
+
const rect = cell.getBoundingClientRect();
|
|
152
|
+
|
|
153
|
+
if (options.position) {
|
|
154
|
+
editor.nextSibling.children[1].style.top = rect.top + rect.height + 'px';
|
|
155
|
+
editor.nextSibling.children[1].style.left = rect.left + 'px';
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
if (!options.format) {
|
|
159
|
+
options.format = 'YYYY-MM-DD';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
jSuites.calendar(editor, options);
|
|
163
|
+
}
|
|
164
|
+
// Focus on editor
|
|
165
|
+
editor.focus();
|
|
166
|
+
} else if (config && config.type == 'html') {
|
|
167
|
+
const value = obj.options.data[y][x];
|
|
168
|
+
// Create editor
|
|
169
|
+
const editor = createEditor('div');
|
|
170
|
+
|
|
171
|
+
dispatch.call(obj, 'oncreateeditor', obj, cell, parseInt(x), parseInt(y), null, config);
|
|
172
|
+
|
|
173
|
+
editor.style.position = 'relative';
|
|
174
|
+
const div = document.createElement('div');
|
|
175
|
+
div.classList.add('jss_richtext');
|
|
176
|
+
editor.appendChild(div);
|
|
177
|
+
jSuites.editor(div, {
|
|
178
|
+
focus: true,
|
|
179
|
+
value: value,
|
|
180
|
+
});
|
|
181
|
+
const rect = cell.getBoundingClientRect();
|
|
182
|
+
const rectContent = div.getBoundingClientRect();
|
|
183
|
+
if (window.innerHeight < rect.bottom + rectContent.height) {
|
|
184
|
+
div.style.top = rect.bottom - (rectContent.height + 2) + 'px';
|
|
185
|
+
} else {
|
|
186
|
+
div.style.top = rect.top + 'px';
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (window.innerWidth < rect.left + rectContent.width) {
|
|
190
|
+
div.style.left = rect.right - (rectContent.width + 2) + 'px';
|
|
191
|
+
} else {
|
|
192
|
+
div.style.left = rect.left + 'px';
|
|
193
|
+
}
|
|
194
|
+
} else if (config && config.type == 'image') {
|
|
195
|
+
// Value
|
|
196
|
+
const img = cell.children[0];
|
|
197
|
+
// Create editor
|
|
198
|
+
const editor = createEditor('div');
|
|
199
|
+
|
|
200
|
+
dispatch.call(obj, 'oncreateeditor', obj, cell, parseInt(x), parseInt(y), null, config);
|
|
201
|
+
|
|
202
|
+
editor.style.position = 'relative';
|
|
203
|
+
const div = document.createElement('div');
|
|
204
|
+
div.classList.add('jclose');
|
|
205
|
+
if (img && img.src) {
|
|
206
|
+
div.appendChild(img);
|
|
207
|
+
}
|
|
208
|
+
editor.appendChild(div);
|
|
209
|
+
jSuites.image(div, config);
|
|
210
|
+
const rect = cell.getBoundingClientRect();
|
|
211
|
+
const rectContent = div.getBoundingClientRect();
|
|
212
|
+
if (window.innerHeight < rect.bottom + rectContent.height) {
|
|
213
|
+
div.style.top = rect.top - (rectContent.height + 2) + 'px';
|
|
214
|
+
} else {
|
|
215
|
+
div.style.top = rect.top + 'px';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
div.style.left = rect.left + 'px';
|
|
219
|
+
} else {
|
|
220
|
+
// Value
|
|
221
|
+
const value = empty == true ? '' : obj.options.data[y][x];
|
|
222
|
+
|
|
223
|
+
// Basic editor
|
|
224
|
+
let editor;
|
|
225
|
+
|
|
226
|
+
if ((!config || config.wordWrap != false) && (obj.options.wordWrap == true || (config && config.wordWrap == true))) {
|
|
227
|
+
editor = createEditor('textarea');
|
|
228
|
+
} else {
|
|
229
|
+
editor = createEditor('input');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
dispatch.call(obj, 'oncreateeditor', obj, cell, parseInt(x), parseInt(y), null, config);
|
|
233
|
+
|
|
234
|
+
editor.focus();
|
|
235
|
+
editor.value = value;
|
|
236
|
+
|
|
237
|
+
// Column options
|
|
238
|
+
const options = config;
|
|
239
|
+
|
|
240
|
+
// Apply format when is not a formula
|
|
241
|
+
if (!isFormula(value)) {
|
|
242
|
+
if (options) {
|
|
243
|
+
// Format
|
|
244
|
+
const opt = getMask(options);
|
|
245
|
+
|
|
246
|
+
if (opt) {
|
|
247
|
+
// Masking
|
|
248
|
+
if (!options.disabledMaskOnEdition) {
|
|
249
|
+
if (options.mask) {
|
|
250
|
+
const m = options.mask.split(';');
|
|
251
|
+
editor.setAttribute('data-mask', m[0]);
|
|
252
|
+
} else if (options.locale) {
|
|
253
|
+
editor.setAttribute('data-locale', options.locale);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Input
|
|
257
|
+
opt.input = editor;
|
|
258
|
+
// Configuration
|
|
259
|
+
editor.mask = opt;
|
|
260
|
+
// Do not treat the decimals
|
|
261
|
+
jSuites.mask.render(value, opt, false);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
editor.onblur = function () {
|
|
267
|
+
closeEditor.call(obj, cell, true);
|
|
268
|
+
};
|
|
269
|
+
editor.scrollLeft = editor.scrollWidth;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Close the editor and save the information
|
|
277
|
+
*
|
|
278
|
+
* @param object cell
|
|
279
|
+
* @param boolean save
|
|
280
|
+
* @return void
|
|
281
|
+
*/
|
|
282
|
+
export const closeEditor = function (cell, save) {
|
|
283
|
+
const obj = this;
|
|
284
|
+
|
|
285
|
+
const x = parseInt(cell.getAttribute('data-x'));
|
|
286
|
+
const y = parseInt(cell.getAttribute('data-y'));
|
|
287
|
+
|
|
288
|
+
let config = obj.options.columns && obj.options.columns[x];
|
|
289
|
+
const cellName = getCellNameFromCoords(x, y);
|
|
290
|
+
const cells = obj.options.cells;
|
|
291
|
+
if (typeof cells === 'object' && cells[cellName]) {
|
|
292
|
+
config = cells[cellName];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
let value;
|
|
296
|
+
|
|
297
|
+
// Get cell properties
|
|
298
|
+
if (save == true) {
|
|
299
|
+
// If custom editor
|
|
300
|
+
if (config && typeof config.type === 'object') {
|
|
301
|
+
// Custom editor
|
|
302
|
+
value = config.type.closeEditor(cell, save, parseInt(x), parseInt(y), obj, config);
|
|
303
|
+
} else {
|
|
304
|
+
// Native functions
|
|
305
|
+
if (config && (config.type == 'checkbox' || config.type == 'radio' || config.type == 'hidden')) {
|
|
306
|
+
// Do nothing
|
|
307
|
+
} else if (config && config.type == 'dropdown') {
|
|
308
|
+
value = cell.children[0].dropdown.close(true);
|
|
309
|
+
} else if (config && config.type == 'calendar') {
|
|
310
|
+
value = cell.children[0].calendar.close(true);
|
|
311
|
+
} else if (config && config.type == 'color') {
|
|
312
|
+
value = cell.children[0].color.close(true);
|
|
313
|
+
} else if (config && config.type == 'html') {
|
|
314
|
+
value = cell.children[0].children[0].editor.getData();
|
|
315
|
+
} else if (config && config.type == 'image') {
|
|
316
|
+
const img = cell.children[0].children[0].children[0];
|
|
317
|
+
value = img && img.tagName == 'IMG' ? img.src : '';
|
|
318
|
+
} else if (config && config.type == 'numeric') {
|
|
319
|
+
value = cell.children[0].value;
|
|
320
|
+
if (('' + value).substr(0, 1) != '=') {
|
|
321
|
+
if (value == '') {
|
|
322
|
+
value = config.allowEmpty ? '' : 0;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
cell.children[0].onblur = null;
|
|
326
|
+
} else {
|
|
327
|
+
value = cell.children[0].value;
|
|
328
|
+
cell.children[0].onblur = null;
|
|
329
|
+
|
|
330
|
+
// Column options
|
|
331
|
+
const options = config;
|
|
332
|
+
|
|
333
|
+
if (options) {
|
|
334
|
+
// Format
|
|
335
|
+
const opt = getMask(options);
|
|
336
|
+
if (opt) {
|
|
337
|
+
// Keep numeric in the raw data
|
|
338
|
+
if (value !== '' && !isFormula(value) && typeof value !== 'number') {
|
|
339
|
+
const t = jSuites.mask.extract(value, opt, true);
|
|
340
|
+
if (t && t.value !== '') {
|
|
341
|
+
value = t.value;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Ignore changes if the value is the same
|
|
350
|
+
if (obj.options.data[y][x] == value) {
|
|
351
|
+
cell.innerHTML = obj.edition[1];
|
|
352
|
+
} else {
|
|
353
|
+
obj.setValue(cell, value); // update cell
|
|
354
|
+
}
|
|
355
|
+
} else {
|
|
356
|
+
if (config && typeof config.type === 'object') {
|
|
357
|
+
// Custom editor
|
|
358
|
+
config.type.closeEditor(cell, save, parseInt(x), parseInt(y), obj, config);
|
|
359
|
+
} else {
|
|
360
|
+
if (config && config.type == 'dropdown') {
|
|
361
|
+
cell.children[0].dropdown.close(true);
|
|
362
|
+
} else if (config && config.type == 'calendar') {
|
|
363
|
+
cell.children[0].calendar.close(true);
|
|
364
|
+
} else if (config && config.type == 'color') {
|
|
365
|
+
cell.children[0].color.close(true);
|
|
366
|
+
} else {
|
|
367
|
+
cell.children[0].onblur = null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Restore value
|
|
372
|
+
cell.innerHTML = obj.edition && obj.edition[1] ? obj.edition[1] : '';
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// On edition end
|
|
376
|
+
dispatch.call(obj, 'oneditionend', obj, cell, x, y, value, save);
|
|
377
|
+
|
|
378
|
+
// Remove editor class
|
|
379
|
+
cell.classList.remove('editor');
|
|
380
|
+
|
|
381
|
+
// Finish edition
|
|
382
|
+
obj.edition = null;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Toogle
|
|
387
|
+
*/
|
|
388
|
+
export const setCheckRadioValue = function () {
|
|
389
|
+
const obj = this;
|
|
390
|
+
|
|
391
|
+
const records = [];
|
|
392
|
+
const keys = Object.keys(obj.highlighted);
|
|
393
|
+
for (let i = 0; i < keys.length; i++) {
|
|
394
|
+
const x = obj.highlighted[i].element.getAttribute('data-x');
|
|
395
|
+
const y = obj.highlighted[i].element.getAttribute('data-y');
|
|
396
|
+
|
|
397
|
+
let config = obj.options.columns && obj.options.columns[x];
|
|
398
|
+
const cellName = getCellNameFromCoords(x, y);
|
|
399
|
+
const cells = obj.options.cells;
|
|
400
|
+
if (typeof cells === 'object' && cells[cellName]) {
|
|
401
|
+
config = cells[cellName];
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (config.type == 'checkbox' || config.type == 'radio') {
|
|
405
|
+
// Update cell
|
|
406
|
+
records.push(updateCell.call(obj, x, y, !obj.options.data[y][x]));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (records.length) {
|
|
411
|
+
// Update history
|
|
412
|
+
setHistory.call(obj, {
|
|
413
|
+
action: 'setValue',
|
|
414
|
+
records: records,
|
|
415
|
+
selection: obj.selectedCell,
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// On after changes
|
|
419
|
+
const onafterchangesRecords = records.map(function (record) {
|
|
420
|
+
return {
|
|
421
|
+
x: record.x,
|
|
422
|
+
y: record.y,
|
|
423
|
+
value: record.value,
|
|
424
|
+
oldValue: record.oldValue,
|
|
425
|
+
};
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
dispatch.call(obj, 'onafterchanges', obj, onafterchangesRecords);
|
|
429
|
+
}
|
|
430
|
+
};
|