rails_handsontable 0.0.1 → 0.0.2
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.
- data/lib/rails_handsontable/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.handsontable.full.js +563 -503
- data/vendor/assets/javascripts/jquery.handsontable.js +563 -503
- data/vendor/assets/stylesheets/jquery.handsontable.css +2 -2
- data/vendor/assets/stylesheets/jquery.handsontable.full.css +2 -2
- metadata +3 -8
@@ -1,12 +1,12 @@
|
|
1
1
|
/**
|
2
|
-
* Handsontable 0.10.
|
2
|
+
* Handsontable 0.10.2
|
3
3
|
* Handsontable is a simple jQuery plugin for editable tables with basic copy-paste compatibility with Excel and Google Docs
|
4
4
|
*
|
5
5
|
* Copyright 2012, Marcin Warpechowski
|
6
6
|
* Licensed under the MIT license.
|
7
7
|
* http://handsontable.com/
|
8
8
|
*
|
9
|
-
* Date:
|
9
|
+
* Date: Thu Jan 23 2014 23:06:23 GMT+0100 (CET)
|
10
10
|
*/
|
11
11
|
/*jslint white: true, browser: true, plusplus: true, indent: 4, maxerr: 50 */
|
12
12
|
|
@@ -227,486 +227,9 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
227
227
|
isPopulated: null,
|
228
228
|
scrollable: null,
|
229
229
|
extensions: {},
|
230
|
-
colToProp: null,
|
231
|
-
propToCol: null,
|
232
|
-
dataSchema: null,
|
233
|
-
dataType: 'array',
|
234
230
|
firstRun: true
|
235
231
|
};
|
236
232
|
|
237
|
-
datamap = {
|
238
|
-
recursiveDuckSchema: function (obj) {
|
239
|
-
var schema;
|
240
|
-
if ($.isPlainObject(obj)) {
|
241
|
-
schema = {};
|
242
|
-
for (var i in obj) {
|
243
|
-
if (obj.hasOwnProperty(i)) {
|
244
|
-
if ($.isPlainObject(obj[i])) {
|
245
|
-
schema[i] = datamap.recursiveDuckSchema(obj[i]);
|
246
|
-
}
|
247
|
-
else {
|
248
|
-
schema[i] = null;
|
249
|
-
}
|
250
|
-
}
|
251
|
-
}
|
252
|
-
}
|
253
|
-
else {
|
254
|
-
schema = [];
|
255
|
-
}
|
256
|
-
return schema;
|
257
|
-
},
|
258
|
-
|
259
|
-
recursiveDuckColumns: function (schema, lastCol, parent) {
|
260
|
-
var prop, i;
|
261
|
-
if (typeof lastCol === 'undefined') {
|
262
|
-
lastCol = 0;
|
263
|
-
parent = '';
|
264
|
-
}
|
265
|
-
if ($.isPlainObject(schema)) {
|
266
|
-
for (i in schema) {
|
267
|
-
if (schema.hasOwnProperty(i)) {
|
268
|
-
if (schema[i] === null) {
|
269
|
-
prop = parent + i;
|
270
|
-
priv.colToProp.push(prop);
|
271
|
-
priv.propToCol[prop] = lastCol;
|
272
|
-
lastCol++;
|
273
|
-
}
|
274
|
-
else {
|
275
|
-
lastCol = datamap.recursiveDuckColumns(schema[i], lastCol, i + '.');
|
276
|
-
}
|
277
|
-
}
|
278
|
-
}
|
279
|
-
}
|
280
|
-
return lastCol;
|
281
|
-
},
|
282
|
-
|
283
|
-
createMap: function () {
|
284
|
-
if (typeof datamap.getSchema() === "undefined") {
|
285
|
-
throw new Error("trying to create `columns` definition but you didnt' provide `schema` nor `data`");
|
286
|
-
}
|
287
|
-
var i, ilen, schema = datamap.getSchema();
|
288
|
-
priv.colToProp = [];
|
289
|
-
priv.propToCol = {};
|
290
|
-
if (priv.settings.columns) {
|
291
|
-
for (i = 0, ilen = priv.settings.columns.length; i < ilen; i++) {
|
292
|
-
priv.colToProp[i] = priv.settings.columns[i].data;
|
293
|
-
priv.propToCol[priv.settings.columns[i].data] = i;
|
294
|
-
}
|
295
|
-
}
|
296
|
-
else {
|
297
|
-
datamap.recursiveDuckColumns(schema);
|
298
|
-
}
|
299
|
-
},
|
300
|
-
|
301
|
-
colToProp: function (col) {
|
302
|
-
col = Handsontable.PluginHooks.execute(instance, 'modifyCol', col);
|
303
|
-
if (priv.colToProp && typeof priv.colToProp[col] !== 'undefined') {
|
304
|
-
return priv.colToProp[col];
|
305
|
-
}
|
306
|
-
else {
|
307
|
-
return col;
|
308
|
-
}
|
309
|
-
},
|
310
|
-
|
311
|
-
propToCol: function (prop) {
|
312
|
-
var col;
|
313
|
-
if (typeof priv.propToCol[prop] !== 'undefined') {
|
314
|
-
col = priv.propToCol[prop];
|
315
|
-
}
|
316
|
-
else {
|
317
|
-
col = prop;
|
318
|
-
}
|
319
|
-
col = Handsontable.PluginHooks.execute(instance, 'modifyCol', col);
|
320
|
-
return col;
|
321
|
-
},
|
322
|
-
|
323
|
-
getSchema: function () {
|
324
|
-
if (priv.settings.dataSchema) {
|
325
|
-
if (typeof priv.settings.dataSchema === 'function') {
|
326
|
-
return priv.settings.dataSchema();
|
327
|
-
}
|
328
|
-
return priv.settings.dataSchema;
|
329
|
-
}
|
330
|
-
return priv.duckDataSchema;
|
331
|
-
},
|
332
|
-
|
333
|
-
/**
|
334
|
-
* Creates row at the bottom of the data array
|
335
|
-
* @param {Number} [index] Optional. Index of the row before which the new row will be inserted
|
336
|
-
*/
|
337
|
-
createRow: function (index, amount) {
|
338
|
-
var row
|
339
|
-
, colCount = instance.countCols()
|
340
|
-
, numberOfCreatedRows = 0
|
341
|
-
, currentIndex;
|
342
|
-
|
343
|
-
if (!amount) {
|
344
|
-
amount = 1;
|
345
|
-
}
|
346
|
-
|
347
|
-
if (typeof index !== 'number' || index >= instance.countRows()) {
|
348
|
-
index = instance.countRows();
|
349
|
-
}
|
350
|
-
|
351
|
-
currentIndex = index;
|
352
|
-
while (numberOfCreatedRows < amount && instance.countRows() < priv.settings.maxRows) {
|
353
|
-
|
354
|
-
if (priv.dataType === 'array') {
|
355
|
-
row = [];
|
356
|
-
for (var c = 0; c < colCount; c++) {
|
357
|
-
row.push(null);
|
358
|
-
}
|
359
|
-
}
|
360
|
-
else if (priv.dataType === 'function') {
|
361
|
-
row = priv.settings.dataSchema(index);
|
362
|
-
}
|
363
|
-
else {
|
364
|
-
row = $.extend(true, {}, datamap.getSchema());
|
365
|
-
}
|
366
|
-
|
367
|
-
if (index === instance.countRows()) {
|
368
|
-
GridSettings.prototype.data.push(row);
|
369
|
-
}
|
370
|
-
else {
|
371
|
-
GridSettings.prototype.data.splice(index, 0, row);
|
372
|
-
}
|
373
|
-
|
374
|
-
numberOfCreatedRows++;
|
375
|
-
currentIndex++;
|
376
|
-
}
|
377
|
-
|
378
|
-
|
379
|
-
instance.PluginHooks.run('afterCreateRow', index, numberOfCreatedRows);
|
380
|
-
instance.forceFullRender = true; //used when data was changed
|
381
|
-
|
382
|
-
return numberOfCreatedRows;
|
383
|
-
},
|
384
|
-
|
385
|
-
/**
|
386
|
-
* Creates col at the right of the data array
|
387
|
-
* @param {Number} [index] Optional. Index of the column before which the new column will be inserted
|
388
|
-
* * @param {Number} [amount] Optional.
|
389
|
-
*/
|
390
|
-
createCol: function (index, amount) {
|
391
|
-
if (priv.dataType === 'object' || priv.settings.columns) {
|
392
|
-
throw new Error("Cannot create new column. When data source in an object, " +
|
393
|
-
"you can only have as much columns as defined in first data row, data schema or in the 'columns' setting." +
|
394
|
-
"If you want to be able to add new columns, you have to use array datasource.");
|
395
|
-
}
|
396
|
-
var rlen = instance.countRows()
|
397
|
-
, data = GridSettings.prototype.data
|
398
|
-
, constructor
|
399
|
-
, numberOfCreatedCols = 0
|
400
|
-
, currentIndex;
|
401
|
-
|
402
|
-
if (!amount) {
|
403
|
-
amount = 1;
|
404
|
-
}
|
405
|
-
|
406
|
-
currentIndex = index;
|
407
|
-
|
408
|
-
while (numberOfCreatedCols < amount && instance.countCols() < priv.settings.maxCols){
|
409
|
-
constructor = Handsontable.helper.columnFactory(GridSettings, priv.columnsSettingConflicts);
|
410
|
-
if (typeof index !== 'number' || index >= instance.countCols()) {
|
411
|
-
for (var r = 0; r < rlen; r++) {
|
412
|
-
if (typeof data[r] === 'undefined') {
|
413
|
-
data[r] = [];
|
414
|
-
}
|
415
|
-
data[r].push(null);
|
416
|
-
}
|
417
|
-
// Add new column constructor
|
418
|
-
priv.columnSettings.push(constructor);
|
419
|
-
}
|
420
|
-
else {
|
421
|
-
for (var r = 0 ; r < rlen; r++) {
|
422
|
-
data[r].splice(currentIndex, 0, null);
|
423
|
-
}
|
424
|
-
// Add new column constructor at given index
|
425
|
-
priv.columnSettings.splice(currentIndex, 0, constructor);
|
426
|
-
}
|
427
|
-
|
428
|
-
numberOfCreatedCols++;
|
429
|
-
currentIndex++;
|
430
|
-
}
|
431
|
-
|
432
|
-
instance.PluginHooks.run('afterCreateCol', index, numberOfCreatedCols);
|
433
|
-
instance.forceFullRender = true; //used when data was changed
|
434
|
-
|
435
|
-
return numberOfCreatedCols;
|
436
|
-
},
|
437
|
-
|
438
|
-
/**
|
439
|
-
* Removes row from the data array
|
440
|
-
* @param {Number} [index] Optional. Index of the row to be removed. If not provided, the last row will be removed
|
441
|
-
* @param {Number} [amount] Optional. Amount of the rows to be removed. If not provided, one row will be removed
|
442
|
-
*/
|
443
|
-
removeRow: function (index, amount) {
|
444
|
-
if (!amount) {
|
445
|
-
amount = 1;
|
446
|
-
}
|
447
|
-
if (typeof index !== 'number') {
|
448
|
-
index = -amount;
|
449
|
-
}
|
450
|
-
|
451
|
-
index = (instance.countRows() + index) % instance.countRows();
|
452
|
-
|
453
|
-
// We have to map the physical row ids to logical and than perform removing with (possibly) new row id
|
454
|
-
var logicRows = this.physicalRowsToLogical(index, amount);
|
455
|
-
|
456
|
-
var actionWasNotCancelled = instance.PluginHooks.execute('beforeRemoveRow', index, amount);
|
457
|
-
|
458
|
-
if(actionWasNotCancelled === false){
|
459
|
-
return;
|
460
|
-
}
|
461
|
-
|
462
|
-
var newData = GridSettings.prototype.data.filter(function (row, index) {
|
463
|
-
return logicRows.indexOf(index) == -1;
|
464
|
-
});
|
465
|
-
|
466
|
-
GridSettings.prototype.data.length = 0;
|
467
|
-
Array.prototype.push.apply(GridSettings.prototype.data, newData);
|
468
|
-
|
469
|
-
instance.PluginHooks.run('afterRemoveRow', index, amount);
|
470
|
-
|
471
|
-
instance.forceFullRender = true; //used when data was changed
|
472
|
-
},
|
473
|
-
|
474
|
-
/**
|
475
|
-
* Removes column from the data array
|
476
|
-
* @param {Number} [index] Optional. Index of the column to be removed. If not provided, the last column will be removed
|
477
|
-
* @param {Number} [amount] Optional. Amount of the columns to be removed. If not provided, one column will be removed
|
478
|
-
*/
|
479
|
-
removeCol: function (index, amount) {
|
480
|
-
if (priv.dataType === 'object' || priv.settings.columns) {
|
481
|
-
throw new Error("cannot remove column with object data source or columns option specified");
|
482
|
-
}
|
483
|
-
if (!amount) {
|
484
|
-
amount = 1;
|
485
|
-
}
|
486
|
-
if (typeof index !== 'number') {
|
487
|
-
index = -amount;
|
488
|
-
}
|
489
|
-
|
490
|
-
index = (instance.countCols() + index) % instance.countCols();
|
491
|
-
|
492
|
-
var actionWasNotCancelled = instance.PluginHooks.execute('beforeRemoveCol', index, amount);
|
493
|
-
|
494
|
-
if(actionWasNotCancelled === false){
|
495
|
-
return;
|
496
|
-
}
|
497
|
-
|
498
|
-
var data = GridSettings.prototype.data;
|
499
|
-
for (var r = 0, rlen = instance.countRows(); r < rlen; r++) {
|
500
|
-
data[r].splice(index, amount);
|
501
|
-
}
|
502
|
-
priv.columnSettings.splice(index, amount);
|
503
|
-
|
504
|
-
instance.PluginHooks.run('afterRemoveCol', index, amount);
|
505
|
-
instance.forceFullRender = true; //used when data was changed
|
506
|
-
},
|
507
|
-
|
508
|
-
/**
|
509
|
-
* Add / removes data from the column
|
510
|
-
* @param {Number} col Index of column in which do you want to do splice.
|
511
|
-
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end
|
512
|
-
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed
|
513
|
-
* param {...*} elements Optional. The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array
|
514
|
-
*/
|
515
|
-
spliceCol: function (col, index, amount/*, elements...*/) {
|
516
|
-
var elements = 4 <= arguments.length ? [].slice.call(arguments, 3) : [];
|
517
|
-
|
518
|
-
var colData = instance.getDataAtCol(col);
|
519
|
-
var removed = colData.slice(index, index + amount);
|
520
|
-
var after = colData.slice(index + amount);
|
521
|
-
|
522
|
-
Handsontable.helper.extendArray(elements, after);
|
523
|
-
var i = 0;
|
524
|
-
while (i < amount) {
|
525
|
-
elements.push(null); //add null in place of removed elements
|
526
|
-
i++;
|
527
|
-
}
|
528
|
-
Handsontable.helper.to2dArray(elements);
|
529
|
-
instance.populateFromArray(index, col, elements, null, null, 'spliceCol');
|
530
|
-
|
531
|
-
return removed;
|
532
|
-
},
|
533
|
-
|
534
|
-
/**
|
535
|
-
* Add / removes data from the row
|
536
|
-
* @param {Number} row Index of row in which do you want to do splice.
|
537
|
-
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end
|
538
|
-
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed
|
539
|
-
* param {...*} elements Optional. The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array
|
540
|
-
*/
|
541
|
-
spliceRow: function (row, index, amount/*, elements...*/) {
|
542
|
-
var elements = 4 <= arguments.length ? [].slice.call(arguments, 3) : [];
|
543
|
-
|
544
|
-
var rowData = instance.getDataAtRow(row);
|
545
|
-
var removed = rowData.slice(index, index + amount);
|
546
|
-
var after = rowData.slice(index + amount);
|
547
|
-
|
548
|
-
Handsontable.helper.extendArray(elements, after);
|
549
|
-
var i = 0;
|
550
|
-
while (i < amount) {
|
551
|
-
elements.push(null); //add null in place of removed elements
|
552
|
-
i++;
|
553
|
-
}
|
554
|
-
instance.populateFromArray(row, index, [elements], null, null, 'spliceRow');
|
555
|
-
|
556
|
-
return removed;
|
557
|
-
},
|
558
|
-
|
559
|
-
/**
|
560
|
-
* Returns single value from the data array
|
561
|
-
* @param {Number} row
|
562
|
-
* @param {Number} prop
|
563
|
-
*/
|
564
|
-
getVars: {},
|
565
|
-
get: function (row, prop) {
|
566
|
-
datamap.getVars.row = row;
|
567
|
-
datamap.getVars.prop = prop;
|
568
|
-
instance.PluginHooks.run('beforeGet', datamap.getVars);
|
569
|
-
if (typeof datamap.getVars.prop === 'string' && datamap.getVars.prop.indexOf('.') > -1) {
|
570
|
-
var sliced = datamap.getVars.prop.split(".");
|
571
|
-
var out = priv.settings.data[datamap.getVars.row];
|
572
|
-
if (!out) {
|
573
|
-
return null;
|
574
|
-
}
|
575
|
-
for (var i = 0, ilen = sliced.length; i < ilen; i++) {
|
576
|
-
out = out[sliced[i]];
|
577
|
-
if (typeof out === 'undefined') {
|
578
|
-
return null;
|
579
|
-
}
|
580
|
-
}
|
581
|
-
return out;
|
582
|
-
}
|
583
|
-
else if (typeof datamap.getVars.prop === 'function') {
|
584
|
-
/**
|
585
|
-
* allows for interacting with complex structures, for example
|
586
|
-
* d3/jQuery getter/setter properties:
|
587
|
-
*
|
588
|
-
* {columns: [{
|
589
|
-
* data: function(row, value){
|
590
|
-
* if(arguments.length === 1){
|
591
|
-
* return row.property();
|
592
|
-
* }
|
593
|
-
* row.property(value);
|
594
|
-
* }
|
595
|
-
* }]}
|
596
|
-
*/
|
597
|
-
return datamap.getVars.prop(priv.settings.data.slice(
|
598
|
-
datamap.getVars.row,
|
599
|
-
datamap.getVars.row + 1
|
600
|
-
)[0]);
|
601
|
-
}
|
602
|
-
else {
|
603
|
-
return priv.settings.data[datamap.getVars.row] ? priv.settings.data[datamap.getVars.row][datamap.getVars.prop] : null;
|
604
|
-
}
|
605
|
-
},
|
606
|
-
|
607
|
-
/**
|
608
|
-
* Saves single value to the data array
|
609
|
-
* @param {Number} row
|
610
|
-
* @param {Number} prop
|
611
|
-
* @param {String} value
|
612
|
-
* @param {String} [source] Optional. Source of hook runner.
|
613
|
-
*/
|
614
|
-
setVars: {},
|
615
|
-
set: function (row, prop, value, source) {
|
616
|
-
datamap.setVars.row = row;
|
617
|
-
datamap.setVars.prop = prop;
|
618
|
-
datamap.setVars.value = value;
|
619
|
-
instance.PluginHooks.run('beforeSet', datamap.setVars, source || "datamapGet");
|
620
|
-
if (typeof datamap.setVars.prop === 'string' && datamap.setVars.prop.indexOf('.') > -1) {
|
621
|
-
var sliced = datamap.setVars.prop.split(".");
|
622
|
-
var out = priv.settings.data[datamap.setVars.row];
|
623
|
-
for (var i = 0, ilen = sliced.length - 1; i < ilen; i++) {
|
624
|
-
out = out[sliced[i]];
|
625
|
-
}
|
626
|
-
out[sliced[i]] = datamap.setVars.value;
|
627
|
-
}
|
628
|
-
else if (typeof datamap.setVars.prop === 'function') {
|
629
|
-
/* see the `function` handler in `get` */
|
630
|
-
datamap.setVars.prop(priv.settings.data.slice(
|
631
|
-
datamap.setVars.row,
|
632
|
-
datamap.setVars.row + 1
|
633
|
-
)[0], datamap.setVars.value);
|
634
|
-
}
|
635
|
-
else {
|
636
|
-
priv.settings.data[datamap.setVars.row][datamap.setVars.prop] = datamap.setVars.value;
|
637
|
-
}
|
638
|
-
},
|
639
|
-
/**
|
640
|
-
* This ridiculous piece of code maps rows Id that are present in table data to those displayed for user.
|
641
|
-
* The trick is, the physical row id (stored in settings.data) is not necessary the same
|
642
|
-
* as the logical (displayed) row id (e.g. when sorting is applied).
|
643
|
-
*/
|
644
|
-
physicalRowsToLogical: function (index, amount) {
|
645
|
-
var physicRow = (GridSettings.prototype.data.length + index) % GridSettings.prototype.data.length;
|
646
|
-
var logicRows = [];
|
647
|
-
var rowsToRemove = amount;
|
648
|
-
|
649
|
-
while (physicRow < GridSettings.prototype.data.length && rowsToRemove) {
|
650
|
-
this.get(physicRow, 0); //this performs an actual mapping and saves the result to getVars
|
651
|
-
logicRows.push(this.getVars.row);
|
652
|
-
|
653
|
-
rowsToRemove--;
|
654
|
-
physicRow++;
|
655
|
-
}
|
656
|
-
|
657
|
-
return logicRows;
|
658
|
-
},
|
659
|
-
|
660
|
-
/**
|
661
|
-
* Clears the data array
|
662
|
-
*/
|
663
|
-
clear: function () {
|
664
|
-
for (var r = 0; r < instance.countRows(); r++) {
|
665
|
-
for (var c = 0; c < instance.countCols(); c++) {
|
666
|
-
datamap.set(r, datamap.colToProp(c), '');
|
667
|
-
}
|
668
|
-
}
|
669
|
-
},
|
670
|
-
|
671
|
-
/**
|
672
|
-
* Returns the data array
|
673
|
-
* @return {Array}
|
674
|
-
*/
|
675
|
-
getAll: function () {
|
676
|
-
return priv.settings.data;
|
677
|
-
},
|
678
|
-
|
679
|
-
/**
|
680
|
-
* Returns data range as array
|
681
|
-
* @param {Object} start Start selection position
|
682
|
-
* @param {Object} end End selection position
|
683
|
-
* @return {Array}
|
684
|
-
*/
|
685
|
-
getRange: function (start, end) {
|
686
|
-
var r, rlen, c, clen, output = [], row;
|
687
|
-
rlen = Math.max(start.row, end.row);
|
688
|
-
clen = Math.max(start.col, end.col);
|
689
|
-
for (r = Math.min(start.row, end.row); r <= rlen; r++) {
|
690
|
-
row = [];
|
691
|
-
for (c = Math.min(start.col, end.col); c <= clen; c++) {
|
692
|
-
row.push(datamap.get(r, datamap.colToProp(c)));
|
693
|
-
}
|
694
|
-
output.push(row);
|
695
|
-
}
|
696
|
-
return output;
|
697
|
-
},
|
698
|
-
|
699
|
-
/**
|
700
|
-
* Return data as text (tab separated columns)
|
701
|
-
* @param {Object} start (Optional) Start selection position
|
702
|
-
* @param {Object} end (Optional) End selection position
|
703
|
-
* @return {String}
|
704
|
-
*/
|
705
|
-
getText: function (start, end) {
|
706
|
-
return SheetClip.stringify(datamap.getRange(start, end));
|
707
|
-
}
|
708
|
-
};
|
709
|
-
|
710
233
|
grid = {
|
711
234
|
/**
|
712
235
|
* Inserts or removes rows and columns
|
@@ -828,7 +351,7 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
828
351
|
}
|
829
352
|
|
830
353
|
//should I add empty cols to meet minSpareCols?
|
831
|
-
if (!priv.settings.columns &&
|
354
|
+
if (!priv.settings.columns && instance.dataType === 'array' && emptyCols < priv.settings.minSpareCols) {
|
832
355
|
for (; emptyCols < priv.settings.minSpareCols && instance.countCols() < priv.settings.maxCols; emptyCols++) {
|
833
356
|
datamap.createCol();
|
834
357
|
}
|
@@ -1580,7 +1103,7 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
1580
1103
|
}
|
1581
1104
|
}
|
1582
1105
|
|
1583
|
-
if (
|
1106
|
+
if (instance.dataType === 'array' && priv.settings.minSpareCols) {
|
1584
1107
|
while (datamap.propToCol(changes[i][1]) > instance.countCols() - 1) {
|
1585
1108
|
datamap.createCol();
|
1586
1109
|
}
|
@@ -1779,7 +1302,7 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
1779
1302
|
* param {...*} elements Optional. The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array
|
1780
1303
|
*/
|
1781
1304
|
this.spliceCol = function (col, index, amount/*, elements... */) {
|
1782
|
-
return datamap.spliceCol.apply(
|
1305
|
+
return datamap.spliceCol.apply(datamap, arguments);
|
1783
1306
|
};
|
1784
1307
|
|
1785
1308
|
/**
|
@@ -1790,7 +1313,7 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
1790
1313
|
* param {...*} elements Optional. The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array
|
1791
1314
|
*/
|
1792
1315
|
this.spliceRow = function (row, index, amount/*, elements... */) {
|
1793
|
-
return datamap.spliceRow.apply(
|
1316
|
+
return datamap.spliceRow.apply(datamap, arguments);
|
1794
1317
|
};
|
1795
1318
|
|
1796
1319
|
/**
|
@@ -1902,22 +1425,17 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
1902
1425
|
GridSettings.prototype.data = data;
|
1903
1426
|
|
1904
1427
|
if (priv.settings.dataSchema instanceof Array || data[0] instanceof Array) {
|
1905
|
-
|
1428
|
+
instance.dataType = 'array';
|
1906
1429
|
}
|
1907
1430
|
else if (typeof priv.settings.dataSchema === 'function') {
|
1908
|
-
|
1431
|
+
instance.dataType = 'function';
|
1909
1432
|
}
|
1910
1433
|
else {
|
1911
|
-
|
1434
|
+
instance.dataType = 'object';
|
1912
1435
|
}
|
1913
1436
|
|
1914
|
-
|
1915
|
-
|
1916
|
-
}
|
1917
|
-
else {
|
1918
|
-
priv.duckDataSchema = {};
|
1919
|
-
}
|
1920
|
-
datamap.createMap();
|
1437
|
+
datamap = new Handsontable.DataMap(instance, priv, GridSettings);
|
1438
|
+
|
1921
1439
|
clearCellSettingCache();
|
1922
1440
|
|
1923
1441
|
grid.adjustRowsAndCols();
|
@@ -1954,12 +1472,12 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
1954
1472
|
return datamap.getAll();
|
1955
1473
|
}
|
1956
1474
|
else {
|
1957
|
-
return datamap.getRange({row: r, col: c}, {row: r2, col: c2});
|
1475
|
+
return datamap.getRange({row: r, col: c}, {row: r2, col: c2}, datamap.DESTINATION_RENDERER);
|
1958
1476
|
}
|
1959
1477
|
};
|
1960
1478
|
|
1961
1479
|
this.getCopyableData = function (startRow, startCol, endRow, endCol) {
|
1962
|
-
return datamap.
|
1480
|
+
return datamap.getCopyableText({row: startRow, col: startCol}, {row: endRow, col: endCol});
|
1963
1481
|
}
|
1964
1482
|
|
1965
1483
|
/**
|
@@ -2204,7 +1722,7 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
2204
1722
|
* @return value (mixed data type)
|
2205
1723
|
*/
|
2206
1724
|
this.getDataAtCol = function (col) {
|
2207
|
-
return [].concat.apply([], datamap.getRange({row: 0, col: col}, {row: priv.settings.data.length - 1, col: col}));
|
1725
|
+
return [].concat.apply([], datamap.getRange({row: 0, col: col}, {row: priv.settings.data.length - 1, col: col}, datamap.DESTINATION_RENDERER));
|
2208
1726
|
};
|
2209
1727
|
|
2210
1728
|
/**
|
@@ -2214,7 +1732,7 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
2214
1732
|
* @return value (mixed data type)
|
2215
1733
|
*/
|
2216
1734
|
this.getDataAtProp = function (prop) {
|
2217
|
-
return [].concat.apply([], datamap.getRange({row: 0, col: datamap.propToCol(prop)}, {row: priv.settings.data.length - 1, col: datamap.propToCol(prop)}));
|
1735
|
+
return [].concat.apply([], datamap.getRange({row: 0, col: datamap.propToCol(prop)}, {row: priv.settings.data.length - 1, col: datamap.propToCol(prop)}, datamap.DESTINATION_RENDERER));
|
2218
1736
|
};
|
2219
1737
|
|
2220
1738
|
/**
|
@@ -2300,8 +1818,9 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
2300
1818
|
}
|
2301
1819
|
};
|
2302
1820
|
|
1821
|
+
var rendererLookup = Handsontable.helper.cellMethodLookupFactory('renderer');
|
2303
1822
|
this.getCellRenderer = function (row, col) {
|
2304
|
-
var renderer =
|
1823
|
+
var renderer = rendererLookup.call(this, row, col);
|
2305
1824
|
return Handsontable.renderers.getRenderer(renderer);
|
2306
1825
|
|
2307
1826
|
};
|
@@ -2477,15 +1996,15 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
2477
1996
|
* @return {Number}
|
2478
1997
|
*/
|
2479
1998
|
this.countCols = function () {
|
2480
|
-
if (
|
1999
|
+
if (instance.dataType === 'object' || instance.dataType === 'function') {
|
2481
2000
|
if (priv.settings.columns && priv.settings.columns.length) {
|
2482
2001
|
return priv.settings.columns.length;
|
2483
2002
|
}
|
2484
2003
|
else {
|
2485
|
-
return
|
2004
|
+
return datamap.colToPropCache.length;
|
2486
2005
|
}
|
2487
2006
|
}
|
2488
|
-
else if (
|
2007
|
+
else if (instance.dataType === 'array') {
|
2489
2008
|
if (priv.settings.columns && priv.settings.columns.length) {
|
2490
2009
|
return priv.settings.columns.length;
|
2491
2010
|
}
|
@@ -2752,7 +2271,7 @@ Handsontable.Core = function (rootElement, userSettings) {
|
|
2752
2271
|
/**
|
2753
2272
|
* Handsontable version
|
2754
2273
|
*/
|
2755
|
-
this.version = '0.10.
|
2274
|
+
this.version = '0.10.2'; //inserted by grunt from package.json
|
2756
2275
|
};
|
2757
2276
|
|
2758
2277
|
var DefaultSettings = function () {};
|
@@ -2816,6 +2335,7 @@ DefaultSettings.prototype = {
|
|
2816
2335
|
readOnly: false,
|
2817
2336
|
nativeScrollbars: false,
|
2818
2337
|
type: 'text',
|
2338
|
+
copyable: true,
|
2819
2339
|
debug: false //shows debug overlays in Walkontable
|
2820
2340
|
};
|
2821
2341
|
Handsontable.DefaultSettings = DefaultSettings;
|
@@ -4200,6 +3720,545 @@ Handsontable.SelectionPoint.prototype.arr = function (arr) {
|
|
4200
3720
|
}
|
4201
3721
|
return [this._row, this._col]
|
4202
3722
|
};
|
3723
|
+
(function (Handsontable) {
|
3724
|
+
'use strict';
|
3725
|
+
|
3726
|
+
/**
|
3727
|
+
* Utility class that gets and saves data from/to the data source using mapping of columns numbers to object property names
|
3728
|
+
* TODO refactor arguments of methods getRange, getText to be numbers (not objects)
|
3729
|
+
* TODO remove priv, GridSettings from object constructor
|
3730
|
+
*
|
3731
|
+
* @param instance
|
3732
|
+
* @param priv
|
3733
|
+
* @param GridSettings
|
3734
|
+
* @constructor
|
3735
|
+
*/
|
3736
|
+
Handsontable.DataMap = function (instance, priv, GridSettings) {
|
3737
|
+
this.instance = instance;
|
3738
|
+
this.priv = priv;
|
3739
|
+
this.GridSettings = GridSettings;
|
3740
|
+
this.dataSource = this.instance.getSettings().data;
|
3741
|
+
|
3742
|
+
if (this.dataSource[0]) {
|
3743
|
+
this.duckSchema = this.recursiveDuckSchema(this.dataSource[0]);
|
3744
|
+
}
|
3745
|
+
else {
|
3746
|
+
this.duckSchema = {};
|
3747
|
+
}
|
3748
|
+
this.createMap();
|
3749
|
+
|
3750
|
+
this.getVars = {}; //used by modifier
|
3751
|
+
this.setVars = {}; //used by modifier
|
3752
|
+
};
|
3753
|
+
|
3754
|
+
Handsontable.DataMap.prototype.DESTINATION_RENDERER = 1;
|
3755
|
+
Handsontable.DataMap.prototype.DESTINATION_CLIPBOARD_GENERATOR = 2;
|
3756
|
+
|
3757
|
+
Handsontable.DataMap.prototype.recursiveDuckSchema = function (obj) {
|
3758
|
+
var schema;
|
3759
|
+
if ($.isPlainObject(obj)) {
|
3760
|
+
schema = {};
|
3761
|
+
for (var i in obj) {
|
3762
|
+
if (obj.hasOwnProperty(i)) {
|
3763
|
+
if ($.isPlainObject(obj[i])) {
|
3764
|
+
schema[i] = this.recursiveDuckSchema(obj[i]);
|
3765
|
+
}
|
3766
|
+
else {
|
3767
|
+
schema[i] = null;
|
3768
|
+
}
|
3769
|
+
}
|
3770
|
+
}
|
3771
|
+
}
|
3772
|
+
else {
|
3773
|
+
schema = [];
|
3774
|
+
}
|
3775
|
+
return schema;
|
3776
|
+
};
|
3777
|
+
|
3778
|
+
Handsontable.DataMap.prototype.recursiveDuckColumns = function (schema, lastCol, parent) {
|
3779
|
+
var prop, i;
|
3780
|
+
if (typeof lastCol === 'undefined') {
|
3781
|
+
lastCol = 0;
|
3782
|
+
parent = '';
|
3783
|
+
}
|
3784
|
+
if ($.isPlainObject(schema)) {
|
3785
|
+
for (i in schema) {
|
3786
|
+
if (schema.hasOwnProperty(i)) {
|
3787
|
+
if (schema[i] === null) {
|
3788
|
+
prop = parent + i;
|
3789
|
+
this.colToPropCache.push(prop);
|
3790
|
+
this.propToColCache[prop] = lastCol;
|
3791
|
+
lastCol++;
|
3792
|
+
}
|
3793
|
+
else {
|
3794
|
+
lastCol = this.recursiveDuckColumns(schema[i], lastCol, i + '.');
|
3795
|
+
}
|
3796
|
+
}
|
3797
|
+
}
|
3798
|
+
}
|
3799
|
+
return lastCol;
|
3800
|
+
};
|
3801
|
+
|
3802
|
+
Handsontable.DataMap.prototype.createMap = function () {
|
3803
|
+
if (typeof this.getSchema() === "undefined") {
|
3804
|
+
throw new Error("trying to create `columns` definition but you didnt' provide `schema` nor `data`");
|
3805
|
+
}
|
3806
|
+
var i, ilen, schema = this.getSchema();
|
3807
|
+
this.colToPropCache = [];
|
3808
|
+
this.propToColCache = {};
|
3809
|
+
var columns = this.instance.getSettings().columns;
|
3810
|
+
if (columns) {
|
3811
|
+
for (i = 0, ilen = columns.length; i < ilen; i++) {
|
3812
|
+
this.colToPropCache[i] = columns[i].data;
|
3813
|
+
this.propToColCache[columns[i].data] = i;
|
3814
|
+
}
|
3815
|
+
}
|
3816
|
+
else {
|
3817
|
+
this.recursiveDuckColumns(schema);
|
3818
|
+
}
|
3819
|
+
};
|
3820
|
+
|
3821
|
+
Handsontable.DataMap.prototype.colToProp = function (col) {
|
3822
|
+
col = Handsontable.PluginHooks.execute(this.instance, 'modifyCol', col);
|
3823
|
+
if (this.colToPropCache && typeof this.colToPropCache[col] !== 'undefined') {
|
3824
|
+
return this.colToPropCache[col];
|
3825
|
+
}
|
3826
|
+
else {
|
3827
|
+
return col;
|
3828
|
+
}
|
3829
|
+
};
|
3830
|
+
|
3831
|
+
Handsontable.DataMap.prototype.propToCol = function (prop) {
|
3832
|
+
var col;
|
3833
|
+
if (typeof this.propToColCache[prop] !== 'undefined') {
|
3834
|
+
col = this.propToColCache[prop];
|
3835
|
+
}
|
3836
|
+
else {
|
3837
|
+
col = prop;
|
3838
|
+
}
|
3839
|
+
col = Handsontable.PluginHooks.execute(this.instance, 'modifyCol', col);
|
3840
|
+
return col;
|
3841
|
+
};
|
3842
|
+
|
3843
|
+
Handsontable.DataMap.prototype.getSchema = function () {
|
3844
|
+
var schema = this.instance.getSettings().dataSchema;
|
3845
|
+
if (schema) {
|
3846
|
+
if (typeof schema === 'function') {
|
3847
|
+
return schema();
|
3848
|
+
}
|
3849
|
+
return schema;
|
3850
|
+
}
|
3851
|
+
return this.duckSchema;
|
3852
|
+
};
|
3853
|
+
|
3854
|
+
/**
|
3855
|
+
* Creates row at the bottom of the data array
|
3856
|
+
* @param {Number} [index] Optional. Index of the row before which the new row will be inserted
|
3857
|
+
*/
|
3858
|
+
Handsontable.DataMap.prototype.createRow = function (index, amount) {
|
3859
|
+
var row
|
3860
|
+
, colCount = this.instance.countCols()
|
3861
|
+
, numberOfCreatedRows = 0
|
3862
|
+
, currentIndex;
|
3863
|
+
|
3864
|
+
if (!amount) {
|
3865
|
+
amount = 1;
|
3866
|
+
}
|
3867
|
+
|
3868
|
+
if (typeof index !== 'number' || index >= this.instance.countRows()) {
|
3869
|
+
index = this.instance.countRows();
|
3870
|
+
}
|
3871
|
+
|
3872
|
+
currentIndex = index;
|
3873
|
+
var maxRows = this.instance.getSettings().maxRows;
|
3874
|
+
while (numberOfCreatedRows < amount && this.instance.countRows() < maxRows) {
|
3875
|
+
|
3876
|
+
if (this.instance.dataType === 'array') {
|
3877
|
+
row = [];
|
3878
|
+
for (var c = 0; c < colCount; c++) {
|
3879
|
+
row.push(null);
|
3880
|
+
}
|
3881
|
+
}
|
3882
|
+
else if (this.instance.dataType === 'function') {
|
3883
|
+
row = this.instance.getSettings().dataSchema(index);
|
3884
|
+
}
|
3885
|
+
else {
|
3886
|
+
row = $.extend(true, {}, this.getSchema());
|
3887
|
+
}
|
3888
|
+
|
3889
|
+
if (index === this.instance.countRows()) {
|
3890
|
+
this.dataSource.push(row);
|
3891
|
+
}
|
3892
|
+
else {
|
3893
|
+
this.dataSource.splice(index, 0, row);
|
3894
|
+
}
|
3895
|
+
|
3896
|
+
numberOfCreatedRows++;
|
3897
|
+
currentIndex++;
|
3898
|
+
}
|
3899
|
+
|
3900
|
+
|
3901
|
+
this.instance.PluginHooks.run('afterCreateRow', index, numberOfCreatedRows);
|
3902
|
+
this.instance.forceFullRender = true; //used when data was changed
|
3903
|
+
|
3904
|
+
return numberOfCreatedRows;
|
3905
|
+
};
|
3906
|
+
|
3907
|
+
/**
|
3908
|
+
* Creates col at the right of the data array
|
3909
|
+
* @param {Number} [index] Optional. Index of the column before which the new column will be inserted
|
3910
|
+
* * @param {Number} [amount] Optional.
|
3911
|
+
*/
|
3912
|
+
Handsontable.DataMap.prototype.createCol = function (index, amount) {
|
3913
|
+
if (this.instance.dataType === 'object' || this.instance.getSettings().columns) {
|
3914
|
+
throw new Error("Cannot create new column. When data source in an object, " +
|
3915
|
+
"you can only have as much columns as defined in first data row, data schema or in the 'columns' setting." +
|
3916
|
+
"If you want to be able to add new columns, you have to use array datasource.");
|
3917
|
+
}
|
3918
|
+
var rlen = this.instance.countRows()
|
3919
|
+
, data = this.dataSource
|
3920
|
+
, constructor
|
3921
|
+
, numberOfCreatedCols = 0
|
3922
|
+
, currentIndex;
|
3923
|
+
|
3924
|
+
if (!amount) {
|
3925
|
+
amount = 1;
|
3926
|
+
}
|
3927
|
+
|
3928
|
+
currentIndex = index;
|
3929
|
+
|
3930
|
+
var maxCols = this.instance.getSettings().maxCols;
|
3931
|
+
while (numberOfCreatedCols < amount && this.instance.countCols() < maxCols) {
|
3932
|
+
constructor = Handsontable.helper.columnFactory(this.GridSettings, this.priv.columnsSettingConflicts);
|
3933
|
+
if (typeof index !== 'number' || index >= this.instance.countCols()) {
|
3934
|
+
for (var r = 0; r < rlen; r++) {
|
3935
|
+
if (typeof data[r] === 'undefined') {
|
3936
|
+
data[r] = [];
|
3937
|
+
}
|
3938
|
+
data[r].push(null);
|
3939
|
+
}
|
3940
|
+
// Add new column constructor
|
3941
|
+
this.priv.columnSettings.push(constructor);
|
3942
|
+
}
|
3943
|
+
else {
|
3944
|
+
for (var r = 0; r < rlen; r++) {
|
3945
|
+
data[r].splice(currentIndex, 0, null);
|
3946
|
+
}
|
3947
|
+
// Add new column constructor at given index
|
3948
|
+
this.priv.columnSettings.splice(currentIndex, 0, constructor);
|
3949
|
+
}
|
3950
|
+
|
3951
|
+
numberOfCreatedCols++;
|
3952
|
+
currentIndex++;
|
3953
|
+
}
|
3954
|
+
|
3955
|
+
this.instance.PluginHooks.run('afterCreateCol', index, numberOfCreatedCols);
|
3956
|
+
this.instance.forceFullRender = true; //used when data was changed
|
3957
|
+
|
3958
|
+
return numberOfCreatedCols;
|
3959
|
+
};
|
3960
|
+
|
3961
|
+
/**
|
3962
|
+
* Removes row from the data array
|
3963
|
+
* @param {Number} [index] Optional. Index of the row to be removed. If not provided, the last row will be removed
|
3964
|
+
* @param {Number} [amount] Optional. Amount of the rows to be removed. If not provided, one row will be removed
|
3965
|
+
*/
|
3966
|
+
Handsontable.DataMap.prototype.removeRow = function (index, amount) {
|
3967
|
+
if (!amount) {
|
3968
|
+
amount = 1;
|
3969
|
+
}
|
3970
|
+
if (typeof index !== 'number') {
|
3971
|
+
index = -amount;
|
3972
|
+
}
|
3973
|
+
|
3974
|
+
index = (this.instance.countRows() + index) % this.instance.countRows();
|
3975
|
+
|
3976
|
+
// We have to map the physical row ids to logical and than perform removing with (possibly) new row id
|
3977
|
+
var logicRows = this.physicalRowsToLogical(index, amount);
|
3978
|
+
|
3979
|
+
var actionWasNotCancelled = this.instance.PluginHooks.execute('beforeRemoveRow', index, amount);
|
3980
|
+
|
3981
|
+
if (actionWasNotCancelled === false) {
|
3982
|
+
return;
|
3983
|
+
}
|
3984
|
+
|
3985
|
+
var data = this.dataSource;
|
3986
|
+
var newData = data.filter(function (row, index) {
|
3987
|
+
return logicRows.indexOf(index) == -1;
|
3988
|
+
});
|
3989
|
+
|
3990
|
+
data.length = 0;
|
3991
|
+
Array.prototype.push.apply(data, newData);
|
3992
|
+
|
3993
|
+
this.instance.PluginHooks.run('afterRemoveRow', index, amount);
|
3994
|
+
|
3995
|
+
this.instance.forceFullRender = true; //used when data was changed
|
3996
|
+
};
|
3997
|
+
|
3998
|
+
/**
|
3999
|
+
* Removes column from the data array
|
4000
|
+
* @param {Number} [index] Optional. Index of the column to be removed. If not provided, the last column will be removed
|
4001
|
+
* @param {Number} [amount] Optional. Amount of the columns to be removed. If not provided, one column will be removed
|
4002
|
+
*/
|
4003
|
+
Handsontable.DataMap.prototype.removeCol = function (index, amount) {
|
4004
|
+
if (this.instance.dataType === 'object' || this.instance.getSettings().columns) {
|
4005
|
+
throw new Error("cannot remove column with object data source or columns option specified");
|
4006
|
+
}
|
4007
|
+
if (!amount) {
|
4008
|
+
amount = 1;
|
4009
|
+
}
|
4010
|
+
if (typeof index !== 'number') {
|
4011
|
+
index = -amount;
|
4012
|
+
}
|
4013
|
+
|
4014
|
+
index = (this.instance.countCols() + index) % this.instance.countCols();
|
4015
|
+
|
4016
|
+
var actionWasNotCancelled = this.instance.PluginHooks.execute('beforeRemoveCol', index, amount);
|
4017
|
+
|
4018
|
+
if (actionWasNotCancelled === false) {
|
4019
|
+
return;
|
4020
|
+
}
|
4021
|
+
|
4022
|
+
var data = this.dataSource;
|
4023
|
+
for (var r = 0, rlen = this.instance.countRows(); r < rlen; r++) {
|
4024
|
+
data[r].splice(index, amount);
|
4025
|
+
}
|
4026
|
+
this.priv.columnSettings.splice(index, amount);
|
4027
|
+
|
4028
|
+
this.instance.PluginHooks.run('afterRemoveCol', index, amount);
|
4029
|
+
this.instance.forceFullRender = true; //used when data was changed
|
4030
|
+
};
|
4031
|
+
|
4032
|
+
/**
|
4033
|
+
* Add / removes data from the column
|
4034
|
+
* @param {Number} col Index of column in which do you want to do splice.
|
4035
|
+
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end
|
4036
|
+
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed
|
4037
|
+
* param {...*} elements Optional. The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array
|
4038
|
+
*/
|
4039
|
+
Handsontable.DataMap.prototype.spliceCol = function (col, index, amount/*, elements...*/) {
|
4040
|
+
var elements = 4 <= arguments.length ? [].slice.call(arguments, 3) : [];
|
4041
|
+
|
4042
|
+
var colData = this.instance.getDataAtCol(col);
|
4043
|
+
var removed = colData.slice(index, index + amount);
|
4044
|
+
var after = colData.slice(index + amount);
|
4045
|
+
|
4046
|
+
Handsontable.helper.extendArray(elements, after);
|
4047
|
+
var i = 0;
|
4048
|
+
while (i < amount) {
|
4049
|
+
elements.push(null); //add null in place of removed elements
|
4050
|
+
i++;
|
4051
|
+
}
|
4052
|
+
Handsontable.helper.to2dArray(elements);
|
4053
|
+
this.instance.populateFromArray(index, col, elements, null, null, 'spliceCol');
|
4054
|
+
|
4055
|
+
return removed;
|
4056
|
+
};
|
4057
|
+
|
4058
|
+
/**
|
4059
|
+
* Add / removes data from the row
|
4060
|
+
* @param {Number} row Index of row in which do you want to do splice.
|
4061
|
+
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end
|
4062
|
+
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed
|
4063
|
+
* param {...*} elements Optional. The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array
|
4064
|
+
*/
|
4065
|
+
Handsontable.DataMap.prototype.spliceRow = function (row, index, amount/*, elements...*/) {
|
4066
|
+
var elements = 4 <= arguments.length ? [].slice.call(arguments, 3) : [];
|
4067
|
+
|
4068
|
+
var rowData = this.instance.getDataAtRow(row);
|
4069
|
+
var removed = rowData.slice(index, index + amount);
|
4070
|
+
var after = rowData.slice(index + amount);
|
4071
|
+
|
4072
|
+
Handsontable.helper.extendArray(elements, after);
|
4073
|
+
var i = 0;
|
4074
|
+
while (i < amount) {
|
4075
|
+
elements.push(null); //add null in place of removed elements
|
4076
|
+
i++;
|
4077
|
+
}
|
4078
|
+
this.instance.populateFromArray(row, index, [elements], null, null, 'spliceRow');
|
4079
|
+
|
4080
|
+
return removed;
|
4081
|
+
};
|
4082
|
+
|
4083
|
+
/**
|
4084
|
+
* Returns single value from the data array
|
4085
|
+
* @param {Number} row
|
4086
|
+
* @param {Number} prop
|
4087
|
+
*/
|
4088
|
+
Handsontable.DataMap.prototype.get = function (row, prop) {
|
4089
|
+
this.getVars.row = row;
|
4090
|
+
this.getVars.prop = prop;
|
4091
|
+
this.instance.PluginHooks.run('beforeGet', this.getVars);
|
4092
|
+
if (typeof this.getVars.prop === 'string' && this.getVars.prop.indexOf('.') > -1) {
|
4093
|
+
var sliced = this.getVars.prop.split(".");
|
4094
|
+
var out = this.dataSource[this.getVars.row];
|
4095
|
+
if (!out) {
|
4096
|
+
return null;
|
4097
|
+
}
|
4098
|
+
for (var i = 0, ilen = sliced.length; i < ilen; i++) {
|
4099
|
+
out = out[sliced[i]];
|
4100
|
+
if (typeof out === 'undefined') {
|
4101
|
+
return null;
|
4102
|
+
}
|
4103
|
+
}
|
4104
|
+
return out;
|
4105
|
+
}
|
4106
|
+
else if (typeof this.getVars.prop === 'function') {
|
4107
|
+
/**
|
4108
|
+
* allows for interacting with complex structures, for example
|
4109
|
+
* d3/jQuery getter/setter properties:
|
4110
|
+
*
|
4111
|
+
* {columns: [{
|
4112
|
+
* data: function(row, value){
|
4113
|
+
* if(arguments.length === 1){
|
4114
|
+
* return row.property();
|
4115
|
+
* }
|
4116
|
+
* row.property(value);
|
4117
|
+
* }
|
4118
|
+
* }]}
|
4119
|
+
*/
|
4120
|
+
return this.getVars.prop(this.dataSource.slice(
|
4121
|
+
this.getVars.row,
|
4122
|
+
this.getVars.row + 1
|
4123
|
+
)[0]);
|
4124
|
+
}
|
4125
|
+
else {
|
4126
|
+
return this.dataSource[this.getVars.row] ? this.dataSource[this.getVars.row][this.getVars.prop] : null;
|
4127
|
+
}
|
4128
|
+
};
|
4129
|
+
|
4130
|
+
var copyableLookup = Handsontable.helper.cellMethodLookupFactory('copyable');
|
4131
|
+
|
4132
|
+
/**
|
4133
|
+
* Returns single value from the data array (intended for clipboard copy to an external application)
|
4134
|
+
* @param {Number} row
|
4135
|
+
* @param {Number} prop
|
4136
|
+
* @return {String}
|
4137
|
+
*/
|
4138
|
+
Handsontable.DataMap.prototype.getCopyable = function (row, prop) {
|
4139
|
+
if (copyableLookup.call(this.instance, row, this.propToCol(prop))) {
|
4140
|
+
return this.get(row, prop);
|
4141
|
+
}
|
4142
|
+
return '';
|
4143
|
+
};
|
4144
|
+
|
4145
|
+
/**
|
4146
|
+
* Saves single value to the data array
|
4147
|
+
* @param {Number} row
|
4148
|
+
* @param {Number} prop
|
4149
|
+
* @param {String} value
|
4150
|
+
* @param {String} [source] Optional. Source of hook runner.
|
4151
|
+
*/
|
4152
|
+
Handsontable.DataMap.prototype.set = function (row, prop, value, source) {
|
4153
|
+
this.setVars.row = row;
|
4154
|
+
this.setVars.prop = prop;
|
4155
|
+
this.setVars.value = value;
|
4156
|
+
this.instance.PluginHooks.run('beforeSet', this.setVars, source || "datamapGet");
|
4157
|
+
if (typeof this.setVars.prop === 'string' && this.setVars.prop.indexOf('.') > -1) {
|
4158
|
+
var sliced = this.setVars.prop.split(".");
|
4159
|
+
var out = this.dataSource[this.setVars.row];
|
4160
|
+
for (var i = 0, ilen = sliced.length - 1; i < ilen; i++) {
|
4161
|
+
out = out[sliced[i]];
|
4162
|
+
}
|
4163
|
+
out[sliced[i]] = this.setVars.value;
|
4164
|
+
}
|
4165
|
+
else if (typeof this.setVars.prop === 'function') {
|
4166
|
+
/* see the `function` handler in `get` */
|
4167
|
+
this.setVars.prop(this.dataSource.slice(
|
4168
|
+
this.setVars.row,
|
4169
|
+
this.setVars.row + 1
|
4170
|
+
)[0], this.setVars.value);
|
4171
|
+
}
|
4172
|
+
else {
|
4173
|
+
this.dataSource[this.setVars.row][this.setVars.prop] = this.setVars.value;
|
4174
|
+
}
|
4175
|
+
};
|
4176
|
+
|
4177
|
+
/**
|
4178
|
+
* This ridiculous piece of code maps rows Id that are present in table data to those displayed for user.
|
4179
|
+
* The trick is, the physical row id (stored in settings.data) is not necessary the same
|
4180
|
+
* as the logical (displayed) row id (e.g. when sorting is applied).
|
4181
|
+
*/
|
4182
|
+
Handsontable.DataMap.prototype.physicalRowsToLogical = function (index, amount) {
|
4183
|
+
var totalRows = this.instance.countRows();
|
4184
|
+
var physicRow = (totalRows + index) % totalRows;
|
4185
|
+
var logicRows = [];
|
4186
|
+
var rowsToRemove = amount;
|
4187
|
+
|
4188
|
+
while (physicRow < totalRows && rowsToRemove) {
|
4189
|
+
this.get(physicRow, 0); //this performs an actual mapping and saves the result to getVars
|
4190
|
+
logicRows.push(this.getVars.row);
|
4191
|
+
|
4192
|
+
rowsToRemove--;
|
4193
|
+
physicRow++;
|
4194
|
+
}
|
4195
|
+
|
4196
|
+
return logicRows;
|
4197
|
+
};
|
4198
|
+
|
4199
|
+
/**
|
4200
|
+
* Clears the data array
|
4201
|
+
*/
|
4202
|
+
Handsontable.DataMap.prototype.clear = function () {
|
4203
|
+
for (var r = 0; r < this.instance.countRows(); r++) {
|
4204
|
+
for (var c = 0; c < this.instance.countCols(); c++) {
|
4205
|
+
this.set(r, this.colToProp(c), '');
|
4206
|
+
}
|
4207
|
+
}
|
4208
|
+
};
|
4209
|
+
|
4210
|
+
/**
|
4211
|
+
* Returns the data array
|
4212
|
+
* @return {Array}
|
4213
|
+
*/
|
4214
|
+
Handsontable.DataMap.prototype.getAll = function () {
|
4215
|
+
return this.dataSource;
|
4216
|
+
};
|
4217
|
+
|
4218
|
+
/**
|
4219
|
+
* Returns data range as array
|
4220
|
+
* @param {Object} start Start selection position
|
4221
|
+
* @param {Object} end End selection position
|
4222
|
+
* @param {Number} destination Destination of datamap.get
|
4223
|
+
* @return {Array}
|
4224
|
+
*/
|
4225
|
+
Handsontable.DataMap.prototype.getRange = function (start, end, destination) {
|
4226
|
+
var r, rlen, c, clen, output = [], row;
|
4227
|
+
var getFn = destination === this.DESTINATION_CLIPBOARD_GENERATOR ? this.getCopyable : this.get;
|
4228
|
+
rlen = Math.max(start.row, end.row);
|
4229
|
+
clen = Math.max(start.col, end.col);
|
4230
|
+
for (r = Math.min(start.row, end.row); r <= rlen; r++) {
|
4231
|
+
row = [];
|
4232
|
+
for (c = Math.min(start.col, end.col); c <= clen; c++) {
|
4233
|
+
row.push(getFn.call(this, r, this.colToProp(c)));
|
4234
|
+
}
|
4235
|
+
output.push(row);
|
4236
|
+
}
|
4237
|
+
return output;
|
4238
|
+
};
|
4239
|
+
|
4240
|
+
/**
|
4241
|
+
* Return data as text (tab separated columns)
|
4242
|
+
* @param {Object} start (Optional) Start selection position
|
4243
|
+
* @param {Object} end (Optional) End selection position
|
4244
|
+
* @return {String}
|
4245
|
+
*/
|
4246
|
+
Handsontable.DataMap.prototype.getText = function (start, end) {
|
4247
|
+
return SheetClip.stringify(this.getRange(start, end, this.DESTINATION_RENDERER));
|
4248
|
+
};
|
4249
|
+
|
4250
|
+
/**
|
4251
|
+
* Return data as copyable text (tab separated columns intended for clipboard copy to an external application)
|
4252
|
+
* @param {Object} start (Optional) Start selection position
|
4253
|
+
* @param {Object} end (Optional) End selection position
|
4254
|
+
* @return {String}
|
4255
|
+
*/
|
4256
|
+
Handsontable.DataMap.prototype.getCopyableText = function (start, end) {
|
4257
|
+
return SheetClip.stringify(this.getRange(start, end, this.DESTINATION_CLIPBOARD_GENERATOR));
|
4258
|
+
};
|
4259
|
+
|
4260
|
+
})(Handsontable);
|
4261
|
+
|
4203
4262
|
(function (Handsontable) {
|
4204
4263
|
'use strict';
|
4205
4264
|
|
@@ -5711,7 +5770,8 @@ Handsontable.HandsontableCell = {
|
|
5711
5770
|
|
5712
5771
|
Handsontable.PasswordCell = {
|
5713
5772
|
editor: Handsontable.editors.PasswordEditor,
|
5714
|
-
renderer: Handsontable.renderers.PasswordRenderer
|
5773
|
+
renderer: Handsontable.renderers.PasswordRenderer,
|
5774
|
+
copyable: false
|
5715
5775
|
};
|
5716
5776
|
|
5717
5777
|
Handsontable.DropdownCell = {
|