「ダーティ」の概念は、次のように定義されます。
通常、セル値の変更によってダーティな状態が発生します。
セルがダーティな場合、そのセルを含む行もダーティです。
挿入された行のセルに値が設定された場合、その行はダーティ行ではなく挿入行として扱われます。また、この際のセルもダーティなセルとしては扱われません。
ロード時にバインディングされたアイテムはダーティな状態として扱われません。しかし、バインディングデータに変更があった場合にはダーティな状態になります。
アンドゥ処理が実施された場合でも、ダーティな状態は保持されます。
ダーティなすべての行を取得するには、シートでgetDirtyRowsメソッドを呼び出します。既存の連結データが存在する場合は、ダーティな行からrow、item、およびoriginalItemが返されます。それ以外の場合は、値を保持するrowだけが返されます。
ダーティなすべてのセルを取得するには、getDirtyCellsメソッドを呼び出します。セル範囲を指定する場合は、有効な引数を次の順序で指定します。
row: 範囲における左上の行インデックス
col: 範囲における左上の列インデックス
rowCount: 範囲における行数
colCount: 範囲における列数
個々のダーティセルからは、row、col、oldValue、およびnewValueの値を取得できます。
削除されたすべての行を取得するには、シートでgetDeletedRowsメソッドを呼び出します。既存の連結データが存在する場合は、ダーティな行からrowおよびoriginalItemが返されます。それ以外の場合は、値を保持するrowだけが返されます。
挿入されたすべての行を取得するには、シートでgetInsertRowsメソッドを呼び出します。挿入された個々の行から、rowおよびitem(データ)の値を取得できます。
ダーティな状態、挿入された状態、および削除された状態は、clearPendingChangesによってクリアできます。これらの状態は、setRowCount、setColumnCount、fromJSON、またはsetDataSourceの呼び出し後にも自動的にクリアされます。また、ダーティ/挿入/削除された状態をセル範囲でクリアすることもできます。クリアする内容を指定するために、clearPendingChangesメソッドのオプション引数で clearChangeInfo を提供します。
clearChangeInfo.row: [オプション]クリアする範囲の左上の行インデックス
clearChangeInfo.col: [オプション]クリアする範囲の左上の列インデックス
clearChangeInfo.rowCount: [オプション]クリアする範囲の行数
clearChangeInfo.colCount: [オプション]クリアする範囲の列数
clearChangeInfo.clearType: [オプション]クリアする変更の種類(ダーティ/挿入/削除)。デフォルトは ダーティ。値はGC.Spread.Sheets.ClearPendingChangeTypeのenum値です。
var spreadNS = GC.Spread.Sheets;
window.onload = function () {
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 1 });
initSpread(spread);
};
function initSpread(spread) {
var sheet = spread.getSheet(0);
sheet.suspendPaint();
for (var r = 0; r < 30; r++) {
sheet.setText(r, 0, "A" + (r + 1));
}
for (var c = 1; c < 20; c++) {
sheet.setText(0, c, String.fromCharCode(65 + c) + "1");
}
sheet.resumePaint();
sheet.clearPendingChanges();
var _getElementByIdtaResult = _getElementById("taResult");
function getChangedCellData(dirtyItem) {
return ["Cell (", dirtyItem.row, ",", dirtyItem.col, ") changed from ", dirtyItem.oldValue, " to ", dirtyItem.newValue].join("");
}
function getDirtyCellData(dirtyItem) {
return ["Cell (", dirtyItem.row, ",", dirtyItem.col, ") oldValue: ", dirtyItem.oldValue, " newValue: ", dirtyItem.newValue].join("");
}
function appendResult(txt) {
_getElementByIdtaResult.value=_getElementByIdtaResult.value + txt + "\n";
}
spread.bind(spreadNS.Events.CellChanged, function (event, data) {
var row = data.row, col = data.col;
if (row === undefined || col === undefined) {
return;
}
if (sheet.hasPendingChanges(row, col)) {
var dirtyDataArray = sheet.getDirtyCells(row, col);
if (dirtyDataArray.length > 0) {
appendResult(getChangedCellData(dirtyDataArray[0]));
}
}
});
spread.bind(spreadNS.Events.RowChanged, function (event, data) {
var row = data.row, count = data.count, propName = data.propertyName;
if (row === undefined || count === undefined || propName === undefined) {
return;
}
if (propName === "addRows" || propName === "deleteRows") {
appendResult(propName + " @ " + row + (count > 1 ? " count: " + count : ""));
}
});
_getElementById("btnInsertRow").addEventListener('click',function () {
var sels = sheet.getSelections();
var len = sels.length;
if (len > 0) {
var s = sels[0];
sheet.addRows(s.row, 1);
}
});
_getElementById("btnDeleteRow").addEventListener('click',function () {
var sels = sheet.getSelections();
var len = sels.length;
if (len > 0) {
var s = sels[0];
sheet.deleteRows(s.row, s.rowCount);
}
});
_getElementById("btnGetSelectionDirtyCells").addEventListener('click',function () {
var sels = sheet.getSelections();
var len = sels.length;
if (len > 0) {
var s = sels[0];
var row = s.row, col = s.col;
if (row < 0) {
row = 0;
}
if (col < 0) {
col = 0;
}
var cells = sheet.getDirtyCells(row, col, s.rowCount, s.colCount);
if (cells.length > 0) {
appendResult("Dirty Cells:\n" + cells.map(function (item) { return getDirtyCellData(item); }).join("\n"));
}
}
});
_getElementById("btnGetDirtyCells").addEventListener('click',function () {
var cells = sheet.getDirtyCells();
if (cells.length > 0) {
appendResult("Dirty Cells:\n" + cells.map(function (item) { return getDirtyCellData(item); }).join("\n"));
}
});
_getElementById("btnGetDirtyRows").addEventListener('click',function () {
var rows = sheet.getDirtyRows();
if (rows.length > 0) {
appendResult("Dirty rows @ " + rows.map(function (item) { return item.row; }).join(", "));
}
});
_getElementById("btnGetInsertRows").addEventListener('click',function () {
var rows = sheet.getInsertRows();
if (rows.length > 0) {
appendResult("Inserted rows @ " + rows.map(function (item) { return item.row; }).join(", "));
}
});
_getElementById("btnGetDeleteRows").addEventListener('click',function () {
var rows = sheet.getDeletedRows();
if (rows.length > 0) {
appendResult("Deleted rows @ " + rows.map(function (item) { return item.row; }).join(", "));
}
});
_getElementById("btnClearPendingChanges").addEventListener('click',function () {
var clearByRange = _getElementById("clearByRange").checked;
if (clearByRange) {
var dirty = _getElementById("clearDirty").checked ? 1 : 0;
var insert = _getElementById("clearInsert").checked ? 2 : 0;
var deleted = _getElementById("clearDelete").checked ? 4 : 0;
var clearType = dirty | insert | deleted;
var selections = sheet.getSelections();
selections.forEach((selection) => {
sheet.clearPendingChanges({
clearType: clearType, row: selection.row, rowCount: selection.rowCount, col: selection.col, colCount: selection.colCount
});
});
} else {
sheet.clearPendingChanges();
}
_getElementByIdtaResult.value = '';
});
_getElementById("btnSetRowCount").addEventListener('click',function () {
sheet.setRowCount(60);
});
_getElementById("btnSetColumnCount").addEventListener('click',function () {
sheet.setColumnCount(16);
});
};
function _getElementById(id){
return document.getElementById(id);
}
<!doctype html>
<html style="height:100%;font-size:14px;">
<head>
<meta name="spreadjs culture" content="ja-jp" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets-resources-ja/dist/gc.spread.sheets.resources.ja.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="sample-tutorial">
<div id="ss" class="sample-spreadsheets"></div>
<div class="options-container">
<p>以下の各ボタンを使用して、行の挿入または削除、行数または列数の変更を行います。</p>
<p>その後、[ダーティ行を取得]、[すべてのダーティセルを取得]などのボタンをクリックすると、ダーティな(変更された)行またはセルを取得できます。</p>
<div class="option-row">
<input type="button" id="btnInsertRow" value="行を挿入" title="選択した位置に新しい行を挿入します。" />
<input type="button" id="btnDeleteRow" value="行を削除" title="選択した行を削除します。" />
</div>
<p>変更状態をセル範囲でクリアする場合、クリアするセル範囲と変更状態の種類(ダーティ/挿入/削除)を選択してください。</p>
<div class="option-row">
<div>
<input id="clearByRange" type="checkbox">
<label for="clearByRange">セル範囲でクリアする</label>
</div>
<div>
<input id="clearDirty" type="checkbox">
<label for="clearDirty">ダーティ</label>
<input id="clearInsert" type="checkbox">
<label for="clearInsert">挿入</label>
<input id="clearDelete" type="checkbox">
<label for="clearDelete">削除</label>
</div>
<input type="button" id="btnClearPendingChanges" value="変更状態をクリア" title="変更状態をクリアします。" />
</div>
<div class="option-row">
<input type="button" id="btnSetRowCount" value="行数を設定" title="行数を60に設定します。" />
<input type="button" id="btnSetColumnCount" value="列数を設定" title="列数を16に設定します。" />
</div>
<div class="option-row">
<input type="button" id="btnGetDirtyRows" value="ダーティ行を取得" />
<input type="button" id="btnGetDirtyCells" value="すべてのダーティセルを取得" />
<input type="button" id="btnGetSelectionDirtyCells" value="選択範囲のダーティセルを取得" />
</div>
<div class="option-row">
<input type="button" id="btnGetInsertRows" value="挿入された行を取得" />
<input type="button" id="btnGetDeleteRows" value="削除された行を取得" />
</div>
<div class="option-row" style="width:100%;height:80px;">
<textarea id="taResult" style="width:100%;padding:0;float:right;height:80px;background:none"></textarea>
</div>
</div>
</div>
</body>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: hidden;
float: left;
}
.options-container {
float: right;
width: 280px;
padding: 12px;
height: 100%;
box-sizing: border-box;
background: #fbfbfb;
overflow: auto;
}
.option-row {
font-size: 14px;
padding: 5px;
margin-top: 10px;
}
p{
padding:2px 10px;
background-color:#F4F8EB;
}
input[type="button"] {
width: 100%;
margin-bottom: 2px;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}