Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
dk981234 committed Apr 2, 2024
2 parents b6f772d + 9779d03 commit 132e0aa
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 5 deletions.
12 changes: 9 additions & 3 deletions src/mask/input_element_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import { ITextInputParams } from "./mask_utils";
export class InputElementAdapter {
private prevUnmaskedValue: string = undefined;

constructor(private inputMaskInstance: InputMaskBase, private inputElement: HTMLInputElement, value: string = "") {
this.inputElement.value = inputMaskInstance.getMaskedValue(value);
this.prevUnmaskedValue = value;
constructor(private inputMaskInstance: InputMaskBase, private inputElement: HTMLInputElement, value?: string) {
let _value: any = value;
if(_value === null || _value === undefined) {
_value = "";
} else if(typeof _value !== "string") {
_value = _value.toString();
}
this.inputElement.value = inputMaskInstance.getMaskedValue(_value);
this.prevUnmaskedValue = _value;

inputMaskInstance.onPropertyChanged.add(this.inputMaskInstancePropertyChangedHandler);
this.addInputEventListener();
Expand Down
21 changes: 21 additions & 0 deletions src/question_custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { ItemValue } from "./itemvalue";
import { QuestionTextProcessor } from "./textPreProcessor";
import { CssClassBuilder } from "./utils/cssClassBuilder";
import { LocalizableString } from "./localizablestring";
import { SurveyError } from "./survey-error";
import { CustomError } from "./error";

/**
* An interface used to create custom question types.
Expand Down Expand Up @@ -243,6 +245,12 @@ export interface ICustomQuestionTypeConfiguration {
* @see questionJSON
*/
createQuestion?: any;
/**
* A function that allows you to display different error texts based on conditions.
* @param question A custom question. Use the `question.value` property to access the question's value.
* @returns An error text.
*/
getErrorText?: (question: Question) => string;
valueToQuestion?: (val: any) => any;
valueFromQuestion?: (val: any) => any;
getValue?: (val: any) => any;
Expand Down Expand Up @@ -310,6 +318,10 @@ export class ComponentQuestionJSON {
if (!this.json.onValueChanging) return newValue;
return this.json.onValueChanging(question, name, newValue);
}
public onGetErrorText(question: Question): string {
if (!this.json.getErrorText) return undefined;
return this.json.getErrorText(question);
}
public onItemValuePropertyChanged(
question: Question,
item: ItemValue,
Expand Down Expand Up @@ -599,6 +611,15 @@ export abstract class QuestionCustomModelBase extends Question
super.setNewValue(newValue);
this.updateElementCss();
}
protected onCheckForErrors(errors: Array<SurveyError>, isOnValueChanged: boolean): void {
super.onCheckForErrors(errors, isOnValueChanged);
if (!!this.customQuestion) {
const text = this.customQuestion.onGetErrorText(this);
if(!!text) {
errors.push(new CustomError(text, this));
}
}
}
//ISurveyImpl
getSurveyData(): ISurveyData {
return this;
Expand Down
2 changes: 1 addition & 1 deletion src/question_rating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ export class QuestionRatingModel extends Question {
return this.inputId + "_" + index;
}
supportGoNextPageAutomatic(): boolean {
return this.isMouseDown === true;
return this.isMouseDown === true || this.renderAs === "dropdown";
}
public supportOther(): boolean {
return false;
Expand Down
77 changes: 77 additions & 0 deletions tests/question_customtests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3031,4 +3031,81 @@ QUnit.test("Single: showPreviewBeforeComplete Bug#8005", function (assert) {
survey.completeLastPage();
assert.deepEqual(survey.data, { question1: 1 }, "survey.data #2");
ComponentCollection.Instance.clear();
});
QUnit.test("Single: validate", function (assert) {
let errorText = "";
ComponentCollection.Instance.add({
name: "test",
questionJSON: { type: "dropdown", choices: [1, 2, 3] },
getErrorText: (question): string => {
if(question.value !== 1) {
errorText = "val";
return "value should be 1";
}
return "";
}
});
const survey = new SurveyModel({
elements: [{ type: "test", name: "question1" }],
showPreviewBeforeComplete: "showAllQuestions"
});
const q = survey.getQuestionByName("question1");
q.value = 2;
survey.validate();
assert.equal(errorText, "val", "errorText");
assert.equal(q.errors.length, 1, "Errors length #1");
assert.equal(q.errors[0].text, "value should be 1", "Error text");
q.value = 1;
assert.equal(q.errors.length, 0, "Errors length #2");
ComponentCollection.Instance.clear();
});
QUnit.test("Composite: validate", function (assert) {
ComponentCollection.Instance.add({
name: "test",
elementsJSON: [
{ type: "text", name: "q1" },
{ type: "dropdown", name: "q2", choices: [1, 2, 3], visibleIf: "{composite.q1} notempty" },
{ type: "text", name: "q3", choices: [1, 2, 3], visibleIf: "{composite.q2} notempty" }
],
onValueChanged(question, name, newValue) {
if (name === "q1") {
question.contentPanel.getQuestionByName("q2").clearValue();
}
if (name === "q2") {
question.contentPanel.getQuestionByName("q3").value = newValue;
}
},
getErrorText: (question): string => {
const q1 = question.contentPanel.getQuestionByName("q1");
const q3 = question.contentPanel.getQuestionByName("q3");
if(!q1.isEmpty() && q3.isEmpty()) return "Select q2";
return "";
}
});
const survey = new SurveyModel({
elements: [
{ type: "test", name: "q1" },
{ type: "test", name: "q2", isRequired: true }
]
});
const q1 = <QuestionCompositeModel>survey.getQuestionByName("q1");
const q2 = <QuestionCompositeModel>survey.getQuestionByName("q2");
survey.validate();
assert.equal(q1.errors.length, 0, "q1 errors #1");
assert.equal(q2.errors.length, 1, "q2 errors #1");
q1.contentPanel.getQuestionByName("q1").value = "val";
q2.contentPanel.getQuestionByName("q1").value = "val";
survey.validate();
assert.equal(q1.errors.length, 1, "q1 errors #2");
assert.equal(q1.errors[0].text, "Select q2", "q1 errors text #2");
assert.equal(q2.errors.length, 1, "q2 errors #2");
assert.equal(q2.errors[0].text, "Select q2", "q2 errors text #2");
q1.contentPanel.getQuestionByName("q2").value = 1;
q2.contentPanel.getQuestionByName("q2").value = 2;
assert.equal(q1.contentPanel.getQuestionByName("q3").value, 1, "q1.q3 value");
assert.equal(q2.contentPanel.getQuestionByName("q3").value, 2, "q2.q3 value");
survey.validate();
assert.equal(q1.errors.length, 0, "q1 errors #3");
assert.equal(q2.errors.length, 0, "q2 errors #3");
ComponentCollection.Instance.clear();
});
13 changes: 12 additions & 1 deletion tests/question_ratingtests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1555,4 +1555,15 @@ QUnit.test("Generate empty rating in column", (assert) => {
] });
assert.equal(col1.itemComponent, "sv-rating-item");
assert.equal(col2.itemComponent, "sv-rating-item-star");
});
});
QUnit.test("supportGoNextPageAutomatic", (assert) => {
const q1 = new QuestionRatingModel("q1");
q1.value = 1;
assert.equal(q1.supportGoNextPageAutomatic(), false, "#1");
q1.onMouseDown();
assert.equal(q1.supportGoNextPageAutomatic(), true, "#2");
q1.value = 2;
assert.equal(q1.supportGoNextPageAutomatic(), false, "#3");
q1.displayMode = "dropdown";
assert.equal(q1.supportGoNextPageAutomatic(), true, "#4");
});

0 comments on commit 132e0aa

Please sign in to comment.