Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tsv2013 committed Jan 24, 2023
2 parents 7c22493 + 8dde058 commit 674302d
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/base-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface ISurveyData {
getAllValues(): any;
getFilteredValues(): any;
getFilteredProperties(): any;
findQuestionByName(name: string): IQuestion;
}
export interface ITextProcessor {
processText(text: string, returnDisplayValue: boolean): string;
Expand Down
16 changes: 9 additions & 7 deletions src/question_baseselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class QuestionSelectBase extends Question {
private noneItemValue: ItemValue = new ItemValue(settings.noneItemValue);
private newItemValue: ItemValue;
private canShowOptionItemCallback: (item: ItemValue) => boolean;
private isUsingCarrayForward: boolean;
@property() protected selectedItemValues: any;

constructor(name: string) {
Expand Down Expand Up @@ -236,6 +237,7 @@ export class QuestionSelectBase extends Question {
}
public runCondition(values: HashTable<any>, properties: HashTable<any>) {
super.runCondition(values, properties);
if(this.isUsingCarrayForward) return;
this.runItemsEnableCondition(values, properties);
this.runItemsCondition(values, properties);
}
Expand Down Expand Up @@ -463,6 +465,7 @@ export class QuestionSelectBase extends Question {
return;
super.setQuestionValue(newValue, updateIsAnswered);
this.setPropertyValue("renderedValue", this.rendredValueFromData(newValue));
this.updateChoicesDependedQuestions();
if (this.hasComment || !updateComment) return;
var isOtherSel = this.isOtherSelected;
if (isOtherSel && !!this.prevOtherValue) {
Expand Down Expand Up @@ -927,16 +930,17 @@ export class QuestionSelectBase extends Question {
: this.activeChoices;
}
protected get activeChoices(): Array<ItemValue> {
var question = this.getQuestionWithChoices();
if (!!question) {
const question = this.getQuestionWithChoices();
this.isUsingCarrayForward = !!question;
if (this.isUsingCarrayForward) {
this.addIntoDependedQuestion(question);
return this.getChoicesFromQuestion(question);
}
return this.choicesFromUrl ? this.choicesFromUrl : this.getChoices();
}
private getQuestionWithChoices(): QuestionSelectBase {
if (!this.choicesFromQuestion || !this.survey) return null;
var res: any = this.survey.getQuestionByName(this.choicesFromQuestion);
if (!this.choicesFromQuestion || !this.data) return null;
var res: any = this.data.findQuestionByName(this.choicesFromQuestion);
return !!res && !!res.visibleChoices && Array.isArray(res.dependedQuestions) && res !== this ? res : null;
}
protected getChoicesFromQuestion(
Expand Down Expand Up @@ -1235,17 +1239,15 @@ export class QuestionSelectBase extends Question {
}
private isUpdatingChoicesDependedQuestions = false;
protected updateChoicesDependedQuestions() {
if (this.isUpdatingChoicesDependedQuestions) return;
if (this.isLoadingFromJson || this.isUpdatingChoicesDependedQuestions) return;
this.isUpdatingChoicesDependedQuestions = true;
for (var i = 0; i < this.dependedQuestions.length; i++) {
this.dependedQuestions[i].onVisibleChoicesChanged();
this.dependedQuestions[i].updateChoicesDependedQuestions();
}
this.isUpdatingChoicesDependedQuestions = false;
}
onSurveyValueChanged(newValue: any) {
super.onSurveyValueChanged(newValue);
if (this.isLoadingFromJson) return;
this.updateChoicesDependedQuestions();
}
protected onVisibleChoicesChanged() {
Expand Down
11 changes: 11 additions & 0 deletions src/question_custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ITextProcessor,
IPanel,
IElement,
IQuestion,
IProgressInfo
} from "./base-interfaces";
import { SurveyElement } from "./survey-element";
Expand Down Expand Up @@ -488,6 +489,9 @@ export abstract class QuestionCustomModelBase extends Question
getFilteredProperties(): any {
return !!this.data ? this.data.getFilteredProperties() : {};
}
findQuestionByName(name: string): IQuestion {
return !!this.data ? this.data.findQuestionByName(name): null;
}
//IPanel
addElement(element: IElement, index: number) { }
removeElement(element: IElement): boolean {
Expand Down Expand Up @@ -722,6 +726,13 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
getTextProcessor(): ITextProcessor {
return this.textProcessing;
}
findQuestionByName(name: string): IQuestion {
if(!!this.contentPanel) {
const res = this.contentPanel.getQuestionByName(name);
if(!!res) return res;
}
return super.findQuestionByName(name);
}
protected clearValueIfInvisibleCore(): void {
super.clearValueIfInvisibleCore();
var questions = this.contentPanel.questions;
Expand Down
9 changes: 9 additions & 0 deletions src/question_matrixdropdownbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,15 @@ implements ISurveyData, ISurveyImpl, ILocalizableOwner {
public setComment(name: string, newValue: string, locNotification: any) {
this.setValueCore(name, newValue, true);
}
findQuestionByName(name: string): IQuestion {
if(!name) return undefined;
const prefix = MatrixDropdownRowModelBase.RowVariableName + ".";
if(name.indexOf(prefix) === 0) {
return this.getQuestionByName(name.substring(prefix.length));
}
const survey = this.getSurvey();
return !!survey ? survey.getQuestionByName(name): null;
}
private setValueCore(name: string, newColumnValue: any, isComment: boolean) {
if (this.isSettingValue) return;
this.updateQuestionsValue(name, newColumnValue, isComment);
Expand Down
5 changes: 5 additions & 0 deletions src/question_multipletext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ISurvey,
IPanel,
IElement,
IQuestion,
ITextProcessor,
IProgressInfo
} from "./base-interfaces";
Expand Down Expand Up @@ -256,6 +257,10 @@ export class MultipleTextItemModel extends Base
getFilteredProperties(): any {
return { survey: this.getSurvey() };
}
findQuestionByName(name: string): IQuestion {
const survey = this.getSurvey();
return !!survey ? survey.getQuestionByName(name): null;
}
//IValidatorOwner
getValidatorTitle(): string {
return this.title;
Expand Down
9 changes: 9 additions & 0 deletions src/question_paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,15 @@ export class QuestionPanelDynamicItem implements ISurveyData, ISurveyImpl {
public setComment(name: string, newValue: string, locNotification: any) {
this.setValue(name + settings.commentSuffix, newValue);
}
findQuestionByName(name: string): IQuestion {
if(!name) return undefined;
const prefix = QuestionPanelDynamicItem.ItemVariableName + ".";
if(name.indexOf(prefix) === 0) {
return this.panel.getQuestionByName(name.substring(prefix.length));
}
const survey = this.getSurvey();
return !!survey ? survey.getQuestionByName(name): null;
}
getAllValues(): any {
return this.data.getPanelItemData(this);
}
Expand Down
3 changes: 3 additions & 0 deletions src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5185,6 +5185,9 @@ export class SurveyModel extends SurveyElementCore
if (!res) return null;
return res[0];
}
findQuestionByName(name: string): IQuestion {
return this.getQuestionByName(name);
}
/**
* Returns a question by its value name
* @param valueName a question name
Expand Down
25 changes: 24 additions & 1 deletion tests/question_customtests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1894,4 +1894,27 @@ QUnit.test("Composite: getProgressInfo", function (assert) {
requiredAnsweredQuestionCount: 0,
}, "q4");
ComponentCollection.Instance.clear();
});
});
QUnit.test("Composite: Support carry-forward", function (assert) {
const json = {
name: "newquestion",
elementsJSON: [
{ type: "checkbox", name: "q1", choices: [1, 2, 3, 4, 5] },
{ type: "radiogroup", name: "q2", choicesFromQuestion: "q1", choicesFromQuestionMode: "selected" }
]
};
ComponentCollection.Instance.add(json);
const survey = new SurveyModel({
elements: [{ type: "newquestion", name: "q1" }],
});
const q = <QuestionCompositeModel>survey.getAllQuestions()[0];
const q1 = q.contentPanel.getQuestionByName("q1");
const q2 = q.contentPanel.getQuestionByName("q2");
assert.equal(q2.choicesFromQuestion, "q1", "choicesFromQuestion is loaded");
assert.equal(q2.choicesFromQuestionMode, "selected", "choicesFromQuestionMode is loaded");
assert.equal(q2.visibleChoices.length, 0, "There is no visible choices");
q1.value = [1, 3, 5];
assert.equal(q2.visibleChoices.length, 3, "Choices are here");
assert.equal(q2.visibleChoices[1].value, 3, "A choice value is correct");
ComponentCollection.Instance.clear();
});
27 changes: 27 additions & 0 deletions tests/question_matrixdynamictests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8001,3 +8001,30 @@ QUnit.test("Update expressions on setting matrixdropdown rows, Bug#5526", functi
"matrix-total": { col1: 1, col3: 3 } }, "#2");
});

QUnit.test("Carry forward in matrix cells", function (assert) {
const survey = new SurveyModel({
"elements": [
{
"type": "matrixdynamic",
"name": "matrix",
columns: [
{ cellType: "checkbox", name: "col1", choices: [1, 2, 3, 4, 5] },
{ cellType: "dropdown", name: "col2", choicesFromQuestion: "row.col1", choicesFromQuestionMode: "selected" }
],
rowCount: 1
}
]
});
const matrix = <QuestionMatrixDropdownModel>survey.getQuestionByName("matrix");
const rows = matrix.visibleRows;
const cellQ1 = rows[0].cells[0].question;
const cellQ2 = <QuestionDropdownModel>rows[0].cells[1].question;
assert.equal("col1", cellQ1.name, "col1 question is correct");
assert.equal("col2", cellQ2.name, "col2 question is correct");
assert.equal(cellQ2.choicesFromQuestion, "row.col1", "choicesFromQuestion is loaded");
assert.equal(cellQ2.choicesFromQuestionMode, "selected", "choicesFromQuestionMode is loaded");
assert.equal(cellQ2.visibleChoices.length, 0, "There is no visible choices");
cellQ1.value = [1, 3, 5];
assert.equal(cellQ2.visibleChoices.length, 3, "Choices are here");
assert.equal(cellQ2.visibleChoices[1].value, 3, "A choice value is correct");
});
24 changes: 24 additions & 0 deletions tests/surveypaneldynamictests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4915,3 +4915,27 @@ QUnit.test("NoentriesText and readOnly", (assert) => {
survey.mode = "display";
assert.equal(panel1.noEntriesText.indexOf("There are no entries."), 0, "panel1: text for readonly");
});
QUnit.test("Carry forward in panel dynamic", function (assert) {
const survey = new SurveyModel({
"elements": [
{
"type": "paneldynamic",
"name": "panel",
templateElements: [
{ type: "checkbox", name: "q1", choices: [1, 2, 3, 4, 5] },
{ type: "dropdown", name: "q2", choicesFromQuestion: "panel.q1", choicesFromQuestionMode: "selected" }
],
panelCount: 1
}
]
});
const panel = <QuestionPanelDynamicModel>survey.getQuestionByName("panel").panels[0];
const q1 = panel.getQuestionByName("q1");
const q2 = panel.getQuestionByName("q2");
assert.equal(q2.choicesFromQuestion, "panel.q1", "choicesFromQuestion is loaded");
assert.equal(q2.choicesFromQuestionMode, "selected", "choicesFromQuestionMode is loaded");
assert.equal(q2.visibleChoices.length, 0, "There is no visible choices");
q1.value = [1, 3, 5];
assert.equal(q2.visibleChoices.length, 3, "Choices are here");
assert.equal(q2.visibleChoices[1].value, 3, "A choice value is correct");
});

0 comments on commit 674302d

Please sign in to comment.