rails_handsontable 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 = {
|