Skip to content

Commit 0e5f6c2

Browse files
authored
Column visibilty doesn't work correctly if expression checks element properties fix #11127 (#11131)
1 parent 224dfd8 commit 0e5f6c2

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

packages/survey-core/src/question_matrixdropdownbase.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ export class MatrixDropdownCell {
6666
this.questionValue = this.createQuestion(column, row, data);
6767
this.questionValue.updateCustomWidget();
6868
this.updateCellQuestionTitleDueToAccessebility(row);
69+
this.questionValue.registerPropertyChangedHandlers(
70+
["isVisible"], () => {
71+
this.onQuestionVisibilityChanged();
72+
},
73+
"cell"
74+
);
6975
}
7076
private updateCellQuestionTitleDueToAccessebility(row: MatrixDropdownRowModelBase): void {
7177
this.questionValue.locTitle.onGetTextCallback = (str: string): string => {
@@ -115,6 +121,13 @@ export class MatrixDropdownCell {
115121
public runCondition(properties: HashTable<any>): void {
116122
this.question.runCondition(properties);
117123
}
124+
private onQuestionVisibilityChanged(): void {
125+
this.column.onCellVisibilityChanged(this.question.isVisible);
126+
}
127+
public dispose(): void {
128+
this.questionValue.unregisterPropertyChangedHandlers(["isVisible"], "cell");
129+
this.questionValue.dispose();
130+
}
118131
}
119132

120133
export class MatrixDropdownTotalCell extends MatrixDropdownCell {
@@ -827,6 +840,9 @@ export class MatrixDropdownRowModelBase extends DynamicItemModelBase implements
827840
private onEditingObjPropertyChanged: (sender: Base, options: any) => void;
828841
private editingObjValue: Base;
829842
public dispose(): void {
843+
for (let i = 0; i < this.cells.length; i++) {
844+
this.cells[i].dispose();
845+
}
830846
if (!!this.editingObj) {
831847
this.editingObj.onPropertyChanged.remove(
832848
this.onEditingObjPropertyChanged
@@ -1399,6 +1415,12 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
13991415
onColumnVisibilityChanged(column: MatrixDropdownColumn): void {
14001416
this.resetTableAndRows();
14011417
}
1418+
onColumnCellVisibilityChanged(column: MatrixDropdownColumn): void {
1419+
if (this.isDesignMode || this.isRunningCellsCondition) return;
1420+
if (this.isColumnVisibilityChanged(column, true)) {
1421+
this.resetRenderedTable(true);
1422+
}
1423+
}
14021424
onColumnCellTypeChanged(column: MatrixDropdownColumn): void {
14031425
this.updateDefaultRowValue(column);
14041426
this.resetTableAndRows();
@@ -1547,9 +1569,11 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
15471569
protected shouldRunColumnExpression(): boolean {
15481570
return false;
15491571
}
1572+
private isRunningCellsCondition: boolean;
15501573
protected runCellsCondition(properties: HashTable<any>): boolean {
15511574
if (this.isDesignMode) return false;
15521575
let isRowVisiblilityChanged = false;
1576+
this.isRunningCellsCondition = true;
15531577
const isAlwaysVisible = this.areInvisibleElementsShowing;
15541578
const rowsVisibleIf = this.getExpressionFromSurvey("rowsVisibleIf");
15551579
const rows = this.generatedVisibleRows;
@@ -1564,6 +1588,7 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
15641588
}
15651589
this.checkColumnsVisibility();
15661590
this.checkColumnsRenderedRequired();
1591+
this.isRunningCellsCondition = false;
15671592
return isRowVisiblilityChanged;
15681593
}
15691594
protected runConditionsForColumns(properties: HashTable<any>): boolean {

packages/survey-core/src/question_matrixdropdowncolumn.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface IMatrixColumnOwner extends ILocalizableOwner {
2626
): void;
2727
onShowInMultipleColumnsChanged(column: MatrixDropdownColumn): void;
2828
onColumnVisibilityChanged(column: MatrixDropdownColumn): void;
29+
onColumnCellVisibilityChanged(column: MatrixDropdownColumn): void;
2930
getCellType(): string;
3031
getCustomCellType(column: MatrixDropdownColumn, row: MatrixDropdownRowModelBase, cellType: string): string;
3132
onColumnCellTypeChanged(column: MatrixDropdownColumn): void;
@@ -298,6 +299,10 @@ export class MatrixDropdownColumn extends Base
298299
public set hasVisibleCell(newVal: boolean) {
299300
this._hasVisibleCell = newVal;
300301
}
302+
public onCellVisibilityChanged(isVisible: boolean): void {
303+
if (!this.colOwner || this.hasVisibleCell === isVisible) return;
304+
this.colOwner.onColumnCellVisibilityChanged(this);
305+
}
301306
public isColumnsVisibleIf: boolean = true;
302307
public getVisibleMultipleChoices(): Array<ItemValue> {
303308
const choices = this.templateQuestion.visibleChoices;

packages/survey-core/tests/question_matrixdynamictests.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4438,6 +4438,49 @@ QUnit.test(
44384438
assert.equal(rows.length, 3, "Only one column is shown + remove button + errrors row");
44394439
}
44404440
);
4441+
QUnit.test("Matrixdynamic column.visibleIf, toggle column visibility on and off via external value, Bug#11127", (assert) => {
4442+
const survey = new SurveyModel({
4443+
"checkErrorsMode": "onValueChanged",
4444+
"elements": [{
4445+
"name": "q1",
4446+
"type": "text",
4447+
"inputType": "number",
4448+
"min": 10
4449+
}, {
4450+
"type": "matrixdynamic",
4451+
"name": "matrix",
4452+
"columns": [
4453+
{ "name": "col1", "cellType": "text", "visibleIf": "{q1} notempty && !{$q1.containsErrors}" },
4454+
{ "name": "col2", "cellType": "text" }
4455+
]
4456+
}]
4457+
});
4458+
const matrix = <QuestionMatrixDynamicModel>survey.getQuestionByName("matrix");
4459+
const rows = matrix.visibleRows;
4460+
const column = matrix.columns[0];
4461+
let table = matrix.renderedTable;
4462+
assert.equal(column.hasVisibleCell, false, "Initial: col1 is invisible");
4463+
assert.equal(column.isColumnVisible, false, "Initial: col1 is invisible");
4464+
assert.equal(table.headerRow.cells.length, 2, "Initial: header has col2 + remove button");
4465+
4466+
survey.setValue("q1", 20);
4467+
table = matrix.renderedTable;
4468+
assert.equal(column.hasVisibleCell, true, "q1=20: col1 is visible");
4469+
assert.equal(column.isColumnVisible, true, "q1=20: col1 is visible");
4470+
assert.equal(table.headerRow.cells.length, 3, "q1=20: header has col1 + col2 + remove button");
4471+
4472+
survey.setValue("q1", 5);
4473+
table = matrix.renderedTable;
4474+
assert.equal(column.hasVisibleCell, false, "q1=5: col1 is invisible");
4475+
assert.equal(column.isColumnVisible, false, "q1=5: col1 is invisible");
4476+
assert.equal(table.headerRow.cells.length, 2, "q1=5: header has col2 + remove button");
4477+
4478+
survey.setValue("q1", 20);
4479+
table = matrix.renderedTable;
4480+
assert.equal(column.hasVisibleCell, true, "q1=20 again: col1 is visible");
4481+
assert.equal(column.isColumnVisible, true, "q1=20 again: col1 is visible");
4482+
assert.equal(table.headerRow.cells.length, 3, "q1=20 again: header has col1 + col2 + remove button");
4483+
});
44414484

44424485
QUnit.test("Matrix validation in cells and async functions in expression", (assert) => {
44434486
var returnResults = new Array<any>();

0 commit comments

Comments
 (0)