diff --git a/src/localizablestring.ts b/src/localizablestring.ts index 67799c4991..27a8510e93 100644 --- a/src/localizablestring.ts +++ b/src/localizablestring.ts @@ -105,19 +105,19 @@ export class LocalizableString implements ILocalizableString { var loc = this.locale; if (!loc) loc = this.defaultLoc; var res = this.getValue(loc); - if (!res && loc === this.defaultLoc) { + if (this.isValueEmpty(res) && loc === this.defaultLoc) { res = this.getValue(surveyLocalization.defaultLocale); } - if(!res) { + if(this.isValueEmpty(res)) { const dialect = this.getRootDialect(loc); if(!!dialect) { res = this.getValue(dialect); } } - if (!res && loc !== this.defaultLoc) { + if (this.isValueEmpty(res) && loc !== this.defaultLoc) { res = this.getValue(this.defaultLoc); } - if (!res && !!this.getLocalizationName()) { + if (this.isValueEmpty(res) && !!this.getLocalizationName()) { res = this.getLocalizationStr(); if(!!this.onGetLocalizationTextCallback) { res = this.onGetLocalizationTextCallback(res); @@ -141,47 +141,52 @@ export class LocalizableString implements ILocalizableString { public get hasHtml(): boolean { return this.hasHtmlValue(); } - public get html() { + public get html(): string { if (!this.hasHtml) return ""; return this.getHtmlValue(); } public get isEmpty(): boolean { return this.getValuesKeys().length == 0; } - public get textOrHtml() { + public get textOrHtml(): string { return this.hasHtml ? this.getHtmlValue() : this.calculatedText; } - public get renderedHtml() { + public get renderedHtml(): string { return this.textOrHtml; } public getLocaleText(loc: string): string { - if (!loc) loc = this.defaultLoc; - var res = this.getValue(loc); + const res = this.getLocaleTextCore(loc); return res ? res : ""; } - private getLocaleTextWithDefault(loc: string): string { - let res = this.getLocaleText(loc); + private getLocaleTextCore(loc: string): string { + if (!loc) loc = this.defaultLoc; + return this.getValue(loc); + } + private isLocaleTextEqualsWithDefault(loc: string, val: string): boolean { + let res = this.getLocaleTextCore(loc); if(!res && this.onGetDefaultTextCallback) { - return this.onGetDefaultTextCallback(); + res = this.onGetDefaultTextCallback(); } - return res; + if(res === val) return true; + return this.isValueEmpty(res) && this.isValueEmpty(val); + } + public clear(): void { + this.setJson(undefined); } public setLocaleText(loc: string, value: string): void { loc = this.getValueLoc(loc); - if (!this.storeDefaultText && value == this.getLocaleTextWithDefault(loc)) { - if(!!value || !!loc && loc !== this.defaultLoc) return; + if (!this.storeDefaultText && this.isLocaleTextEqualsWithDefault(loc, value)) { + if(!this.isValueEmpty(value) || !!loc && loc !== this.defaultLoc) return; let dl = surveyLocalization.defaultLocale; let oldValue = this.getValue(dl); - if(!!dl && !!oldValue) { + if(!!dl && !this.isValueEmpty(oldValue)) { this.setValue(dl, value); this.fireStrChanged(dl, oldValue); } return; } if (!settings.localization.storeDuplicatedTranslations && - value && - loc && - loc != this.defaultLoc && + !this.isValueEmpty(value) && loc && loc != this.defaultLoc && !this.getValue(loc) && value == this.getLocaleText(this.defaultLoc) ) @@ -190,7 +195,7 @@ export class LocalizableString implements ILocalizableString { if (!loc) loc = this.defaultLoc; var oldValue = this.onStrChanged && loc === curLoc ? this.pureText : undefined; delete (this).htmlValues[loc]; - if (!value) { + if (this.isValueEmpty(value)) { if (this.getValue(loc)) this.deleteValue(loc); } else { if (typeof value === "string") { @@ -206,6 +211,11 @@ export class LocalizableString implements ILocalizableString { } this.fireStrChanged(loc, oldValue); } + private isValueEmpty(val: string): boolean { + if(val === undefined || val === null) return true; + if(this.localizationName) return false; + return val === ""; + } private get curLocale(): string { return !!this.locale ? this.locale : this.defaultLoc; } diff --git a/tests/localizablestringtests.ts b/tests/localizablestringtests.ts index c2bf0efe99..2cabfc248f 100644 --- a/tests/localizablestringtests.ts +++ b/tests/localizablestringtests.ts @@ -3,15 +3,13 @@ import { LocalizableString, LocalizableStrings, } from "../src/localizablestring"; -import { JsonObject, propertyArray, Serializer } from "../src/jsonobject"; +import { JsonObject, Serializer } from "../src/jsonobject"; import { ItemValue } from "../src/itemvalue"; import { HashTable } from "../src/helpers"; import { settings } from "../src/settings"; import { surveyLocalization } from "../src/surveyStrings"; import { englishStrings } from "../src/localization/english"; import { Base } from "../src/base"; -import { Question } from "../src/question"; -import { SurveyElementCore } from "../src/survey-element"; export default QUnit.module("LocalizableString"); @@ -810,3 +808,13 @@ QUnit.test("Support disableLocalization", function(assert) { locString.setJson("default-2"); assert.deepEqual(locString.getJson(), "default-2", "#4"); }); +QUnit.test("Allow to set empty string if there is localization name", function(assert) { + var owner = new LocalizableOwnerTester(""); + var locString = new LocalizableString(owner, true); + locString.localizationName = "completeText"; + assert.equal(locString.renderedHtml, "Complete", "get value from localizationName, renderedHtml"); + assert.equal(locString.text, "Complete", "get value from localizationName, text"); + locString.text = ""; + assert.equal(locString.renderedHtml, "", "empty rendred html"); + assert.equal(locString.text, "", "empty text"); +}); diff --git a/tests/surveyserializationtests.ts b/tests/surveyserializationtests.ts index 11dddaa04a..252d3ace57 100644 --- a/tests/surveyserializationtests.ts +++ b/tests/surveyserializationtests.ts @@ -715,4 +715,22 @@ QUnit.test("choiceValuesFromQuestion properties visibility", function (assert) { assert.equal(propMode.visibleIf(col2), false, "col2.choicesFromQuestionMode"); assert.equal(propValues.visibleIf(col2), true, "col2.choiceValuesFromQuestion"); assert.equal(propTexts.visibleIf(col2), true, "col2.choiceTextsFromQuestion"); +}); +QUnit.test("Allow to save empty string for localization strings & strings with default value", function (assert) { + const survey = new SurveyModel({ + questions: [ + { name: "q1", type: "dropdown", choices: [1, 2, 3] } + ] + }); + const q1 = survey.getQuestionByName("q1"); + assert.equal(q1.placeholder, "Select...", "Default string for placeholder"); + q1.placeholder = "test"; + assert.equal(q1.placeholder, "test", "set value for placeholder"); + q1.placeholder = ""; + assert.equal(q1.placeholder, "", "set empty string for placeholder"); + assert.strictEqual(q1.locPlaceholder.getJson(), "", "JSON has empty string"); + q1.placeholder = "test"; + assert.equal(q1.placeholder, "test", "set value for placeholder, #2"); + q1.locPlaceholder.clear(); + assert.equal(q1.placeholder, "Select...", "Clear value for placeholder"); }); \ No newline at end of file