Skip to content

Commit

Permalink
Add lockedRowCount property into matrix dynamic fix #8070 (#8071)
Browse files Browse the repository at this point in the history
* Add lockedRowCount property into matrix dynamic fix #8070

* Do not allow to drop into locked top rows #8070
  • Loading branch information
andrewtelnov authored Apr 8, 2024
1 parent e81b7f6 commit f807ef1
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/dragdrop/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export abstract class DragDropCore<T> implements IDragDropEngine {
}

protected getShortcutText(draggedElement: IShortcutText): string {
return draggedElement.shortcutText;
return draggedElement?.shortcutText;
}

protected createDraggedElementShortcut(
Expand Down
9 changes: 6 additions & 3 deletions src/dragdrop/matrix-rows.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DomDocumentHelper } from "../global_variables_utils";
import { MatrixDropdownRowModelBase } from "../question_matrixdropdownbase";
import { QuestionMatrixDynamicModel } from "../question_matrixdynamic";
import { QuestionMatrixDynamicModel, MatrixDynamicRowModel } from "../question_matrixdynamic";
import { DragDropCore } from "./core";
export class DragDropMatrixRows extends DragDropCore<QuestionMatrixDynamicModel> {
protected get draggedElementType(): string {
Expand Down Expand Up @@ -105,9 +105,12 @@ export class DragDropMatrixRows extends DragDropCore<QuestionMatrixDynamicModel>

return dropTargetRenderedRow.row;
}

public canInsertIntoThisRow(row: MatrixDynamicRowModel): boolean {
const lockedRows = this.parentElement.lockedRowCount;
return lockedRows <= 0 || row.index >= lockedRows;
}
protected isDropTargetValid(dropTarget: any, dropTargetNode?: HTMLElement): boolean {
return true;
return this.canInsertIntoThisRow(dropTarget);
}

protected calculateIsBottom(clientY: number): boolean {
Expand Down
3 changes: 2 additions & 1 deletion src/question_matrixdropdownrendered.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,8 @@ export class QuestionMatrixDropdownRenderedTable extends Base {
}
private getRowDragCell(rowIndex: number) {
const cell = new QuestionMatrixDropdownRenderedCell();
cell.isDragHandlerCell = true;
const lockedRows = (<QuestionMatrixDynamicModel>this.matrix).lockedRowCount;
cell.isDragHandlerCell = lockedRows < 1 || rowIndex >= lockedRows;
cell.className = this.getActionsCellClassName(cell);
cell.row = this.matrix.visibleRows[rowIndex];
return cell;
Expand Down
18 changes: 11 additions & 7 deletions src/question_matrixdynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ export class QuestionMatrixDynamicModel extends QuestionMatrixDropdownModelBase
this.updateShowTableAndAddRow();
}
);
this.registerPropertyChangedHandlers(["allowRowsDragAndDrop", "isReadOnly"], () => { this.clearRowsAndResetRenderedTable(); });
this.registerPropertyChangedHandlers(["allowRowsDragAndDrop", "isReadOnly", "lockedRowCount"], () => { this.clearRowsAndResetRenderedTable(); });
this.dragOrClickHelper = new DragOrClickHelper(this.startDragMatrixRow);
}

public dragDropMatrixRows: DragDropMatrixRows;
public setSurveyImpl(value: ISurveyImpl, isLight?: boolean) {
public setSurveyImpl(value: ISurveyImpl, isLight?: boolean): void {
super.setSurveyImpl(value, isLight);
this.dragDropMatrixRows = new DragDropMatrixRows(this.survey, null, true);
}
Expand Down Expand Up @@ -283,6 +283,12 @@ export class QuestionMatrixDynamicModel extends QuestionMatrixDropdownModelBase
public get isRowsDragAndDrop(): boolean {
return this.allowRowsDragAndDrop && !this.isReadOnly;
}
public get lockedRowCount(): number {
return this.getPropertyValue("lockedRowCount", 0);
}
public set lockedRowCount(val: number) {
this.setPropertyValue("lockedRowCount", val);
}

public get iconDragElement(): string {
return this.cssClasses.iconDragElement;
Expand Down Expand Up @@ -407,11 +413,9 @@ export class QuestionMatrixDynamicModel extends QuestionMatrixDropdownModelBase
}
public canRemoveRow(row: MatrixDropdownRowModelBase): boolean {
if (!this.survey) return true;
return this.survey.matrixAllowRemoveRow(
this,
(<MatrixDynamicRowModel>row).index,
row
);
const index = (<MatrixDynamicRowModel>row).index;
if(this.lockedRowCount > 0 && index < this.lockedRowCount) return false;
return this.survey.matrixAllowRemoveRow(this, index, row);
}
public addRowUI(): void {
this.addRow(true);
Expand Down
23 changes: 23 additions & 0 deletions tests/dragDropMatrixTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,26 @@ QUnit.test("Clear the isGhostRow marker", function (assert) {
dd.clear();
assert.equal(renderedTable.rows[1].isGhostRow, false, "Row 0 isGhostRow marker is reset");
});

QUnit.test("matrix.lockedRowCount", function (assert) {
const survey = new SurveyModel({
elements: [{
type: "matrixdynamic",
name: "test",
rowCount: 2,
allowRowsDragAndDrop: true,
columns: [
{ cellType: "text", name: "value" },
{ cellType: "text", name: "text" },
],

}]
});
const matrixQuestion = survey.getAllQuestions()[0] as QuestionMatrixDynamicModel;
matrixQuestion.lockedRowCount = 1;
const rows = matrixQuestion.visibleRows;
const dd = matrixQuestion.dragDropMatrixRows;
dd.dragInit(<any>undefined, <any>undefined, matrixQuestion);
assert.equal(dd.canInsertIntoThisRow(<any>rows[0]), false, "row0");
assert.equal(dd.canInsertIntoThisRow(<any>rows[1]), true, "row1");
});
29 changes: 28 additions & 1 deletion tests/question_matrixdynamictests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9235,4 +9235,31 @@ QUnit.test("Totals alingment", function (assert) {
renderedTable.footerRow.cells[3].cellQuestionWrapperClassName,
"sd-table__question-wrapper sd-table__question-wrapper--expression sd-table__question-wrapper--center"
);
});
});
QUnit.test("lockedRowCount property", function (assert) {
var survey = new SurveyModel({
elements: [
{
type: "matrixdynamic",
name: "matrix",
allowRowsDragAndDrop: true,
rowCount: 4,
columns: ["col1"]
}
]
});
const matrix = <QuestionMatrixDynamicModel>survey.getQuestionByName("matrix");
matrix.lockedRowCount = 2;
const rows = matrix.visibleRows;
assert.equal(matrix.canRemoveRow(rows[0]), false, "canRemoveRow, row#0");
assert.equal(matrix.canRemoveRow(rows[1]), false, "canRemoveRow, row#1");
assert.equal(matrix.canRemoveRow(rows[2]), true, "canRemoveRow, row#2");
assert.equal(matrix.canRemoveRow(rows[3]), true, "canRemoveRow, row#3");

const table = matrix.renderedTable;
assert.equal(table.headerRow.cells.length, 3, "Drag handler cell + one column + actions cell");
assert.equal(table.rows[1].cells[0].isDragHandlerCell, false, "isDragHandlerCell, row#1");
assert.equal(table.rows[3].cells[0].isDragHandlerCell, false, "isDragHandlerCell, row#2");
assert.equal(table.rows[5].cells[0].isDragHandlerCell, true, "isDragHandlerCell, row#3");
assert.equal(table.rows[7].cells[0].isDragHandlerCell, true, "isDragHandlerCell, row#4");
});

0 comments on commit f807ef1

Please sign in to comment.