Skip to content

Commit

Permalink
Improve question displayValue functionality surveyjs#3124
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov committed Jul 21, 2021
1 parent 2722f46 commit afed752
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/itemvalue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ export class ItemValue extends Base {
}
public static getItemByValue(items: Array<ItemValue>, val: any): ItemValue {
if (!Array.isArray(items)) return null;
const valIsEmpty = Helpers.isValueEmpty(val);
for (var i = 0; i < items.length; i++) {
if (valIsEmpty && Helpers.isValueEmpty(items[i].value)) return items[i];
if (Helpers.isTwoValueEquals(items[i].value, val)) return items[i];
}
return null;
Expand Down
10 changes: 9 additions & 1 deletion src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class Question extends SurveyElement
customWidgetData = { isNeedRender: true };
focusCallback: () => void;
surveyLoadCallback: () => void;
displayValueCallback: (text: string) => string;

private textPreProcessor: TextPreProcessor;
private conditionEnabelRunner: ConditionRunner;
Expand Down Expand Up @@ -1213,17 +1214,24 @@ export class Question extends SurveyElement
* @param value use this parameter, if you want to get display value for this value and not question.value. It is undefined by default.
*/
public getDisplayValue(keysAsText: boolean, value: any = undefined): any {
var res = this.calcDisplayValue(keysAsText, value);
return !!this.displayValueCallback ? this.displayValueCallback(res) : res;
}
private calcDisplayValue(keysAsText: boolean, value: any = undefined): any {
if (this.customWidget) {
var res = this.customWidget.getDisplayValue(this, value);
if (res) return res;
}
value = value == undefined ? this.createValueCopy() : value;
if (this.isValueEmpty(value)) return "";
if (this.isValueEmpty(value)) return this.getDisplayValueEmpty();
return this.getDisplayValueCore(keysAsText, value);
}
protected getDisplayValueCore(keyAsText: boolean, value: any): any {
return value;
}
protected getDisplayValueEmpty(): string {
return "";
}
/**
* Set the default value to the question. It will be assign to the question on loading the survey from JSON or adding a question to the survey or on setting this property of the value is empty.
* Please note, this property is hidden for question without input, for example html question.
Expand Down
3 changes: 3 additions & 0 deletions src/question_baseselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,9 @@ export class QuestionSelectBase extends Question {
protected getDisplayValueCore(keysAsText: boolean, value: any): any {
return this.getChoicesDisplayValue(this.visibleChoices, value);
}
protected getDisplayValueEmpty(): string {
return ItemValue.getTextOrHtmlByValue(this.visibleChoices, undefined);
}
protected getChoicesDisplayValue(items: ItemValue[], val: any): any {
if (val == this.otherItemValue.value)
return this.comment ? this.comment : this.locOtherText.textOrHtml;
Expand Down
3 changes: 3 additions & 0 deletions tests/basetests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ QUnit.test("ItemValue.getItemByValue()", function(assert) {
assert.equal(item["custom"], "mydata", "get custom data correctly");
item = ItemValue.getItemByValue(items, 55);
assert.equal(item, null, "there is no item by this value");
items.push(new ItemValue("", "empty"));
item = ItemValue.getItemByValue(items, undefined);
assert.equal(item.text, "empty", "returns empty value");
});

class BaseTester extends Base implements ILocalizableOwner {
Expand Down
37 changes: 37 additions & 0 deletions tests/surveyquestiontests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5253,3 +5253,40 @@ QUnit.test(
assert.equal(q2.value, "abc", "default value is set, text");
}
);
QUnit.test("Use empty string as a valid value", function(assert) {
var json = {
elements: [
{
type: "dropdown",
name: "q1",
choices: [{ value: "", text: "empty" }, "item2", "item3"],
},
],
};
var survey = new SurveyModel(json);
var q1 = <QuestionDropdownModel>survey.getQuestionByName("q1");
assert.equal(
q1.displayValue,
"empty",
"We get display Value for empty string"
);
});
QUnit.test("Use question onDisplayValueCallback", function(assert) {
var json = {
elements: [
{
type: "dropdown",
name: "q1",
optionsCaption: "Empty",
choices: ["item2", "item3"],
},
],
};
var survey = new SurveyModel(json);
var q1 = <QuestionDropdownModel>survey.getQuestionByName("q1");
q1.displayValueCallback = (val: string): string => {
if (q1.isEmpty()) return q1.optionsCaption;
return val;
};
assert.equal(q1.displayValue, "Empty", "We get display Value on callback");
});

0 comments on commit afed752

Please sign in to comment.