Skip to content

Commit

Permalink
Add matrix column visible property (#6818)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov committed Aug 30, 2023
1 parent 6c25fb0 commit 0a0c2f5
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 33 deletions.
33 changes: 17 additions & 16 deletions src/question_matrixdropdownbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,16 @@ import { IElement, IQuestion, ISurveyData, ISurvey, ISurveyImpl, ITextProcessor,
import { SurveyElement } from "./survey-element";
import { TextPreProcessorValue, QuestionTextProcessor } from "./textPreProcessor";
import { ItemValue } from "./itemvalue";
import { surveyLocalization } from "./surveyStrings";
import { QuestionFactory } from "./questionfactory";
import { ILocalizableOwner, LocalizableString } from "./localizablestring";
import { getCurrecyCodes } from "./question_expression";
import { FunctionFactory } from "./functionsfactory";
import { PanelModel } from "./panel";
import { settings } from "./settings";
import { KeyDuplicationError } from "./error";
import { SurveyModel } from "./survey";
import { SurveyError } from "./survey-error";
import { CssClassBuilder } from "./utils/cssClassBuilder";
import { MatrixDropdownColumn } from "./question_matrixdropdowncolumn";
import { IMatrixColumnOwner, MatrixDropdownColumn } from "./question_matrixdropdowncolumn";
import { QuestionMatrixDropdownRenderedCell, QuestionMatrixDropdownRenderedRow, QuestionMatrixDropdownRenderedTable } from "./question_matrixdropdownrendered";

export interface IMatrixDropdownData {
Expand Down Expand Up @@ -681,7 +679,6 @@ implements ISurveyData, ISurveyImpl, ILocalizableOwner {
var columns = this.data.columns;
for (var i = 0; i < columns.length; i++) {
var column = columns[i];
if (!column.isVisible) continue;
var cell = this.createCell(column);
this.cells.push(cell);
var cellValue = this.getCellValue(value, column.name);
Expand Down Expand Up @@ -783,7 +780,7 @@ export class MatrixDropdownTotalRowModel extends MatrixDropdownRowModelBase {
/**
* A base class for the [QuestionMatrixDropdownModel](https://surveyjs.io/form-library/documentation/questionmatrixdropdownmodel) and [QuestionMatrixDynamicModel](https://surveyjs.io/form-library/documentation/questionmatrixdynamicmodel) classes.
*/
export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<MatrixDropdownRowModelBase, MatrixDropdownColumn> implements IMatrixDropdownData {
export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<MatrixDropdownRowModelBase, MatrixDropdownColumn> implements IMatrixDropdownData, IMatrixColumnOwner {
public static get defaultCellType() {
return settings.matrix.defaultCellType;
}
Expand Down Expand Up @@ -1258,11 +1255,16 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
}
}

onShowInMultipleColumnsChanged(column: MatrixDropdownColumn) {
this.clearGeneratedRows();
this.resetRenderedTable();
onShowInMultipleColumnsChanged(column: MatrixDropdownColumn): void {
this.resetTableAndRows();
}
onColumnVisibilityChanged(column: MatrixDropdownColumn): void {
this.resetTableAndRows();
}
onColumnCellTypeChanged(column: MatrixDropdownColumn): void {
this.resetTableAndRows();
}
onColumnCellTypeChanged(column: MatrixDropdownColumn) {
private resetTableAndRows(): void {
this.clearGeneratedRows();
this.resetRenderedTable();
}
Expand Down Expand Up @@ -1365,7 +1367,7 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
protected runCellsCondition(
values: HashTable<any>,
properties: HashTable<any>
) {
): void {
if (!this.generatedVisibleRows) return;
var newValues = this.getRowConditionValues(values);
var rows = this.generatedVisibleRows;
Expand All @@ -1375,7 +1377,8 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
this.checkColumnsVisibility();
this.checkColumnsRenderedRequired();
}
private checkColumnsVisibility() {
private checkColumnsVisibility(): void {
if(this.isDesignMode) return;
var hasChanged = false;
for (var i = 0; i < this.visibleColumns.length; i++) {
const column = this.visibleColumns[i];
Expand All @@ -1402,7 +1405,7 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
}
}
private isColumnVisibilityChanged(column: MatrixDropdownColumn): boolean {
const curVis = column.hasVisibleCell;
const curVis = column.isColumnVisible;
const isMultipleColumnsVisibility = column.isFilteredMultipleColumns;
const curVisibleChoices = isMultipleColumnsVisibility ? column.getVisibleChoicesInCell : [];
const newVisibleChoices = new Array<any>();
Expand All @@ -1418,14 +1421,12 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
} else break;
}
}
if (curVis != hasVisCell) {
column.hasVisibleCell = hasVisCell;
}
column.hasVisibleCell = hasVisCell;
if(isMultipleColumnsVisibility) {
column.setVisibleChoicesInCell(newVisibleChoices);
if(!Helpers.isArraysEqual(curVisibleChoices, newVisibleChoices, true, false, false)) return true;
}
return curVis != hasVisCell;
return curVis != column.isVisible;
}
private updateNewVisibleChoices(q: Question, dest: Array<any>): void {
const choices = q.visibleChoices;
Expand Down
29 changes: 21 additions & 8 deletions src/question_matrixdropdowncolumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface IMatrixColumnOwner extends ILocalizableOwner {
oldValue: any
): void;
onShowInMultipleColumnsChanged(column: MatrixDropdownColumn): void;
onColumnVisibilityChanged(column: MatrixDropdownColumn): void;
getCellType(): string;
getCustomCellType(column: MatrixDropdownColumn, row: MatrixDropdownRowModelBase, cellType: string): string;
onColumnCellTypeChanged(column: MatrixDropdownColumn): void;
Expand Down Expand Up @@ -122,7 +123,6 @@ export class MatrixDropdownColumn extends Base
private templateQuestionValue: Question;
private colOwnerValue: IMatrixColumnOwner = null;
private indexValue = -1;
private _isVisible = true;
private _hasVisibleCell = true;
private _visiblechoices: Array<any>;

Expand All @@ -131,6 +131,7 @@ export class MatrixDropdownColumn extends Base
this.createLocalizableString("totalFormat", this);
this.createLocalizableString("cellHint", this);
this.registerPropertyChangedHandlers(["showInMultipleColumns"], () => { this.doShowInMultipleColumnsChanged(); });
this.registerPropertyChangedHandlers(["visible"], () => { this.doColumnVisibilityChanged(); });
this.updateTemplateQuestion();
this.name = name;
if (title) {
Expand Down Expand Up @@ -201,17 +202,23 @@ export class MatrixDropdownColumn extends Base
this.colOwner.onColumnCellTypeChanged(this);
}
}
public get templateQuestion() {
public get templateQuestion(): Question {
return this.templateQuestionValue;
}
public get value() {
return this.templateQuestion.name;
}
public get isVisible() {
return this._isVisible;
//For filtering columns
public get isVisible(): boolean {
return true;
}
public setIsVisible(newVal: boolean): void {
this._isVisible = newVal;
public get isColumnVisible(): boolean {
if(this.isDesignMode) return true;
return this.visible && this.hasVisibleCell;
}
public get visible(): boolean { return this.getPropertyValue("visible"); }
public set visible(val: boolean) {
this.setPropertyValue("visible", val);
}
public get hasVisibleCell(): boolean {
return this._hasVisibleCell;
Expand Down Expand Up @@ -616,14 +623,19 @@ export class MatrixDropdownColumn extends Base
}
}

private doShowInMultipleColumnsChanged() {
if (this.colOwner != null && !this.isLoadingFromJson) {
private doShowInMultipleColumnsChanged(): void {
if (this.colOwner != null) {
this.colOwner.onShowInMultipleColumnsChanged(this);
}
if (this.templateQuestion) {
this.templateQuestion.autoOtherMode = this.isShowInMultipleColumns;
}
}
private doColumnVisibilityChanged(): void {
if (this.colOwner != null && !this.isDesignMode) {
this.colOwner.onColumnVisibilityChanged(this);
}
}
private getProperties(curCellType: string): Array<JsonObjectProperty> {
return Serializer.getDynamicPropertiesByObj(this, curCellType);
}
Expand Down Expand Up @@ -710,6 +722,7 @@ Serializer.addClass(
}
},
"width",
{ name: "visible:switch", default: true, overridingProperty: "visibleIf" },
"visibleIf:condition",
"enableIf:condition",
"requiredIf:condition",
Expand Down
8 changes: 4 additions & 4 deletions src/question_matrixdropdownrendered.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ export class QuestionMatrixDropdownRenderedTable extends Base {
if (this.matrix.isColumnLayoutHorizontal) {
for (var i = 0; i < this.matrix.visibleColumns.length; i++) {
var column = this.matrix.visibleColumns[i];
if (!column.hasVisibleCell) continue;
if (!column.isColumnVisible) continue;
if (this.matrix.IsMultiplyColumn(column)) {
this.createMutlipleColumnsHeader(column);
} else {
Expand Down Expand Up @@ -450,7 +450,7 @@ export class QuestionMatrixDropdownRenderedTable extends Base {
var cells = this.matrix.visibleTotalRow.cells;
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
if (!cell.column.hasVisibleCell) continue;
if (!cell.column.isColumnVisible) continue;
if (this.matrix.IsMultiplyColumn(cell.column)) {
this.createMutlipleColumnsFooter(this.footerRow, cell);
} else {
Expand Down Expand Up @@ -686,7 +686,7 @@ export class QuestionMatrixDropdownRenderedTable extends Base {
}
for (var i = 0; i < row.cells.length; i++) {
let cell = row.cells[i];
if (!cell.column.hasVisibleCell) continue;
if (!cell.column.isColumnVisible) continue;
if (this.matrix.IsMultiplyColumn(cell.column)) {
this.createMutlipleEditCells(res, cell);
} else {
Expand Down Expand Up @@ -762,7 +762,7 @@ export class QuestionMatrixDropdownRenderedTable extends Base {
var renderedRows = [];
for (var i = 0; i < columns.length; i++) {
var col = columns[i];
if (col.isVisible && col.hasVisibleCell) {
if (col.isColumnVisible) {
if (this.matrix.IsMultiplyColumn(col)) {
this.createMutlipleVerticalRows(renderedRows, col, i);
} else {
Expand Down
8 changes: 8 additions & 0 deletions tests/jsonobjecttests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2980,4 +2980,12 @@ QUnit.test("multipletextitem, name property should be required and unique", func
const prop = Serializer.findProperty("multipletextitem", "name");
assert.equal(prop.isRequired, true, "name property is required");
assert.equal(prop.isUnique, true, "name property is unique");
});
QUnit.test("load matrix column, visible property", function (assert) {
const matrix = new QuestionMatrixDynamicModel("q1");
const column = matrix.addColumn("col1");
assert.equal(column.visible, true, "It is visible by default");
column.fromJSON({ title: "column1", visible: false });
assert.equal(column.title, "column1", "set column title correctly");
assert.equal(column.visible, false, "column.visible is false");
});
65 changes: 65 additions & 0 deletions tests/question_matrixdropdownbasetests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -635,4 +635,69 @@ QUnit.test("Set incorrect value into matrix dropdown", function (assert) {
assert.notOk(matrix.value, "matrix value is empty, #2");
survey.data = { matrix: { row1: 1 } };
assert.equal(matrix.isEmpty(), false, "Set correct value");
});
QUnit.test("column.visible property", function (assert) {
const survey = new SurveyModel({
elements: [
{
type: "matrixdropdown",
name: "matrix",
columns: [
{ name: "col1", cellType: "text" },
{ name: "col2", cellType: "text", visible: false },
{ name: "col3", cellType: "text" }
],
rows: ["row1"],
},
],
});
const matrix = <QuestionMatrixDropdownModelBase>survey.getQuestionByName("matrix");
assert.equal(matrix.columns[0].visible, true, "The default column.visible is true");
assert.equal(matrix.columns[1].visible, false, "The second column.visible is false");
let table = matrix.renderedTable;
assert.equal(table.headerRow.cells.length, 1 + 2, "Header: One column is invisible, #1");
assert.equal(table.rows[1].cells.length, 1 + 2, "Row: One column is invisible, #1");
assert.equal(table.headerRow.cells[2].headers, "col3", "The second column is col3, #1");
matrix.columns[1].visible = true;
assert.notStrictEqual(table, matrix.renderedTable);
table = matrix.renderedTable;
assert.equal(table.headerRow.cells.length, 1 + 3, "Header: All columns are visible, #2");
assert.equal(table.rows[1].cells.length, 1 + 3, "Row: All columns are visible, #2");
assert.equal(table.headerRow.cells[2].headers, "col2", "The second column is col2, #2");
matrix.columns[2].visible = false;
table = matrix.renderedTable;
assert.equal(table.headerRow.cells.length, 1 + 2, "Header: the last column is invisible, #3");
assert.equal(table.rows[1].cells.length, 1 + 2, "Row: the last column is invisible, #3");
assert.equal(table.headerRow.cells[2].headers, "col2", "The last column is col2, #3");
});
QUnit.test("column.visible property and design time", function (assert) {
const survey = new SurveyModel();
survey.setDesignMode(true);
survey.fromJSON({
elements: [
{
type: "matrixdropdown",
name: "matrix",
columns: [
{ name: "col1", cellType: "text" },
{ name: "col2", cellType: "text", visible: false },
{ name: "col3", cellType: "text" }
],
rows: ["row1"],
},
],
});
const matrix = <QuestionMatrixDropdownModelBase>survey.getQuestionByName("matrix");
assert.equal(matrix.columns[0].visible, true, "Column is visible by default");
assert.equal(matrix.columns[1].visible, false, "visible property is false");
assert.equal(matrix.columns[1].hasVisibleCell, true, "It is visible");
let table = matrix.renderedTable;
assert.equal(table.headerRow.cells.length, 1 + 3, "Header: One column is invisible, but it is visible in design-time, #1");
assert.equal(table.rows[1].cells.length, 1 + 3, "Row: One column is invisible, but it is visible in design-time, #1");
assert.equal(table.headerRow.cells[3].headers, "col3", "The last column is col3, #1");
matrix.columns[2].visible = false;
table = matrix.renderedTable;
assert.equal(table.headerRow.cells.length, 1 + 3, "Header: Two columns are invisible, but it is visible in design-time, #2");
assert.equal(table.rows[1].cells.length, 1 + 3, "Row: Two columns are invisible, but it is visible in design-time, #2");
assert.equal(table.headerRow.cells[3].headers, "col3", "The last column is col3, #2");
});
20 changes: 15 additions & 5 deletions tests/question_matrixdynamictests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1097,11 +1097,14 @@ QUnit.test("Matrixdynamic column.visibleIf", function (assert) {
question.columns.push(new MatrixDropdownColumn("column1"));
question.columns.push(new MatrixDropdownColumn("column2"));
question.columns.push(new MatrixDropdownColumn("column3"));
question.columns[0]["choices"] = [1, 2, 3];
question.columns[1]["choices"] = [4, 5];
question.columns[2]["choices"] = [7, 8, 9, 10];
question.columns[2].isRequired = true;

const columns = question.columns;
columns[0]["choices"] = [1, 2, 3];
columns[1]["choices"] = [4, 5];
columns[2]["choices"] = [7, 8, 9, 10];
columns[2].isRequired = true;
assert.equal(columns[0].visible, true, "columns[0].visible");
assert.equal(columns[1].visible, true, "columns[1].visible");
assert.equal(columns[2].visible, true, "columns[2].visible");
question.columns[1].visibleIf = "{row.column1} = 2";
question.columns[2].visibleIf = "{a} = 5";

Expand Down Expand Up @@ -1327,6 +1330,7 @@ QUnit.test(
"The second column is invisible"
);
survey.setValue("q2", 1);
let table = matrix.renderedTable;
assert.equal(
matrix.columns[0].hasVisibleCell,
true,
Expand Down Expand Up @@ -1362,6 +1366,7 @@ QUnit.test(
"The second column is invisible now"
);
survey.setValue("q2", 2);
table = matrix.renderedTable;
assert.equal(
matrix.columns[0].hasVisibleCell,
false,
Expand Down Expand Up @@ -7955,10 +7960,15 @@ QUnit.test("Summary doesn't work correctly if there is invisible column and clea
clearInvisibleValues: "onHiddenContainer"
});
const matrix = <QuestionMatrixDynamicModel>survey.getAllQuestions()[0];
const rows = matrix.visibleRows;
assert.equal(rows.length, 2, "two rows");
assert.equal(rows[0].cells.length, 4, "row[0].cells.length = 4");
assert.equal(rows[1].cells.length, 4, "row[1].cells.length = 4");
matrix.visibleRows[0].cells[0].question.value = 1;
matrix.visibleRows[0].cells[1].question.value = 2;
matrix.visibleRows[1].cells[0].question.value = 3;
matrix.visibleRows[1].cells[1].question.value = 4;
assert.equal(matrix.visibleTotalRow.cells.length, 4, "There are 4 cells");
assert.equal(matrix.visibleTotalRow.cells[2].value, 1 + 2 + 3 + 4, "summary calculated correctly");
});
QUnit.test("Set empty string to expression with empty total type", function (assert) {
Expand Down

0 comments on commit 0a0c2f5

Please sign in to comment.