Skip to content

Commit

Permalink
Custom Widgets - Implement an option to specify validation errors for…
Browse files Browse the repository at this point in the history
… custom widgets fix #7610 (#7861)
  • Loading branch information
andrewtelnov authored Feb 15, 2024
1 parent 5882a14 commit c1ef3be
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2043,13 +2043,12 @@ export class Question extends SurveyElement<Question>
questions.push(this);
}
public getConditionJson(operator: string = null, path: string = null): any {
var json = new JsonObject().toJsonObject(this);
const json = new JsonObject().toJsonObject(this);
json["type"] = this.getType();
return json;
}
public hasErrors(fireCallback: boolean = true, rec: any = null): boolean {
var oldHasErrors = this.errors.length > 0;
var errors = this.checkForErrors(!!rec && rec.isOnValueChanged === true);
const errors = this.checkForErrors(!!rec && rec.isOnValueChanged === true);
if (fireCallback) {
if (!!this.survey) {
this.survey.beforeSettingQuestionErrors(this, errors);
Expand Down Expand Up @@ -2095,12 +2094,15 @@ export class Question extends SurveyElement<Question>
if (!error) return;
let newError: SurveyError = null;
if (typeof error === "string" || error instanceof String) {
newError = new CustomError(<string>error, this.survey);
newError = this.addCustomError(<string>error);
} else {
newError = <SurveyError>error;
}
this.errors.push(newError);
}
private addCustomError(error: string): SurveyError {
return new CustomError(error, this.survey);
}
public removeError(error: SurveyError): void {
var errors = this.errors;
var index = errors.indexOf(error);
Expand Down Expand Up @@ -2150,6 +2152,12 @@ export class Question extends SurveyElement<Question>
err.onUpdateErrorTextCallback = (err) => { err.text = this.requiredErrorText; };
errors.push(err);
}
if(!this.isEmpty() && this.customWidget) {
const text = this.customWidget.validate(this);
if(!!text) {
errors.push(this.addCustomError(text));
}
}
}
protected hasRequiredError(): boolean {
return this.isRequired && this.isEmpty();
Expand Down
5 changes: 5 additions & 0 deletions src/questionCustomWidgets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export class QuestionCustomWidget {
return this.widgetJson.getDisplayValue(question, value);
return null;
}
public validate(question: IQuestion): string {
if (this.widgetJson.validate)
return this.widgetJson.validate(question);
return undefined;
}
public isFit(question: IQuestion): boolean {
if (this.isLibraryLoaded() && this.widgetJson.isFit)
return this.widgetJson.isFit(question);
Expand Down
40 changes: 40 additions & 0 deletions tests/surveyquestiontests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5964,6 +5964,46 @@ QUnit.test("isFit custom widgets on renderAs", function (assert) {
assert.equal(q1.customWidget.name, "pretty", "Correct custom widget name");
CustomWidgetCollection.Instance.clear();
});
QUnit.test("Validate function for custom widget", function (assert) {
CustomWidgetCollection.Instance.clear();
CustomWidgetCollection.Instance.addCustomWidget({
name: "first",
isFit: (question): boolean => {
return question.name == "question1";
},
validate: (question): string => {
const val = question.value;
return val < 1 || val > 3 ? "Out of range" : "";
}
});
var survey = new SurveyModel({
elements: [
{
type: "radiogroup",
name: "question1",
choices: [1, 2, 3]
},
],
});
var q1 = <QuestionSelectBase>(
survey.getQuestionByName("question1")
);
assert.equal(q1.validate(), true, "There is no errors, #1");
q1.value = 1;
assert.equal(q1.validate(), true, "There is no errors, #2");
q1.value = 4;
assert.equal(q1.validate(), false, "There is a error, #3");
assert.equal(q1.errors.length, 1, "Errors list, #4");
assert.equal(q1.errors[0].text, "Out of range", "Error text #5");
q1.value = 2;
assert.equal(q1.errors.length, 0, "Errors list, #6");
q1.value = 5;
assert.equal(q1.validate(), false, "There is a error, #7");
q1.clearValue();
assert.equal(q1.errors.length, 0, "Errors list, #8");
CustomWidgetCollection.Instance.clear();
});

QUnit.test("Update choices order on changing locale, bug #2832", function (
assert
) {
Expand Down

0 comments on commit c1ef3be

Please sign in to comment.