Repair Handsontable Inner Bucket

Tags: #<Tag:0x00007efc6b1605a8>

Original Code:

function onAfterCreateCol(col, count) {
  if (this.mergeCells) {
    this.mergeCells.shiftCollection('right', col, count);
  }
}
function onAfterRemoveCol(col, count) {
  if (this.mergeCells) {
    this.mergeCells.shiftCollection('left', col, count);
  }
}
function onAfterCreateRow(row, count) {
  if (this.mergeCells) {
    this.mergeCells.shiftCollection('down', row, count);
  }
}
function onAfterRemoveRow(row, count) {
  if (this.mergeCells) {
    this.mergeCells.shiftCollection('up', row, count);
  }
}

It is wrong!!!

It shoud be replace by codes blow:

function afterRemoveRow(row, count) {
	var setting = this.getSettings();
	if (setting.manualRowResize) setting.manualRowResize.splice(row, count);
	if (setting.rowHeights) setting.rowHeights.splice(row, count);
	_adjustMergeInfo_afterRemove.call(this, row, count, "row", "rowspan");
}
function afterRemoveCol(col, count) {
	var setting = this.getSettings();
	if (setting.manualColumnResize) setting.manualColumnResize.splice(col, count);
	if (setting.colWidths) setting.colWidths.splice(col, count);
	_adjustMergeInfo_afterRemove.call(this, col, count, "col", "colspan");
}
function afterCreateRow(row, count) {
	var setting = this.getSettings();
	if (setting.manualRowResize) setting.manualRowResize.splice(row, 0, Report.DEFAULT_HEIGHT);
	if (setting.rowHeights) setting.rowHeights.splice(row, 0, Report.DEFAULT_HEIGHT);
	_adjustMergeInfo_afterCreate.call(this, row, count, "row", "rowspan");
}
function afterCreateCol(col, count) {
	var setting = this.getSettings();
	if (setting.manualColumnResize) setting.manualColumnResize.splice(col, 0, Report.DEFAULT_WIDTH);
	if (setting.colWidths) setting.colWidths.splice(col, 0, Report.DEFAULT_WIDTH);
	_adjustMergeInfo_afterCreate.call(this, col, count, "col", "colspan");
}
function _adjustMergeInfo_afterRemove(from, count, rc, rcspan) {
	var mergeInfos = this.mergeCells;
	if (mergeInfos) {
		mergeInfos = mergeInfos.mergedCellInfoCollection;
		var to = from + count;
		for(var i = mergeInfos.length - 1; i >= 0; i--) {
			var info = mergeInfos[i], vrc = info[rc], vspan = info[rcspan];
			if (vrc >= from) {
				from = Math.max(from, vrc - count);
				vspan = vrc + vspan - count - from;
				if (vspan <= 0) {
					mergeInfos.splice(i, 1);
				} else {
					info[rc] = from;
					info[rcspan] = vspan;
				}
			} else {
				vspan = vrc + vspan;
				if (vspan >= from) {
					info[rcspan] = Math.max(from, vspan - count) - vrc;
				}
			}
		}
	}
}
function _adjustMergeInfo_afterCreate(from, count, rc, rcspan) {
	var mergeInfos = this.mergeCells;
	if (mergeInfos) {
		mergeInfos = mergeInfos.mergedCellInfoCollection;
		for(var i = 0, len = mergeInfos.length; i < len; i++) {
			var info = mergeInfos[i], vrc = info[rc], vspan = info[rcspan];
			if (vrc >= from) {
				info[rc] = vrc + count;
			} else if (from < vrc + vspan) {
				info[rcspan] = vspan + count;
			}
		}
	}
}

Thank you for your suggestion. I will add it for our devs to look at.

Hi again @shixia226
I just got a reply from our developers that the following code does not fully support our plans for the plugin refactor. Although I fully appreciate your effort to check our code and propose your point of view.

Hi @shixia226
You can vote on refactoring the mergeCells plugin at our roadmap: https://trello.com/c/4n7ubh6X/23-refactor-of-merge-cells-plugin

Thank you for your apply.
But I want to reiterate my point of view with an example:

 var table = new Handsontable(document.body, {
        data: [
            ["A1", "", ""],
            ["A2", "B2", "C2"]
        ],
        mergeCells: [{
            row: 0,
            col: 0,
            rowspan: 1,
            colspan: 3
        }]
    });
    table.alter("remove_col", 0, 1); //it throw an error here "handsontable.full.js:1800 Uncaught Error: Incorrect value of the columnsRenderCalculator"
    table.alter("remove_col", 1, 1); //we can see table.mergeCells.mergedCellInfoCollection here should be { row: 0, col: 0, rowspan: 1, colspan: 2}, but the result is still { row: 0, col: 0, rowspan: 1, colspan: 3}