From fade177f10f8f56a7fbcbcef93e1a9a0a6ced987 Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 14 Sep 2023 11:48:30 -0600 Subject: [PATCH] Fix first select option was not set --- api/js/etemplate/Et2Select/Et2Select.ts | 74 ++++++++++++++++++- .../Et2Select/Select/Et2SelectTimezone.ts | 7 +- api/js/etemplate/Et2Select/StaticOptions.ts | 4 +- package-lock.json | 71 ++---------------- 4 files changed, 85 insertions(+), 71 deletions(-) diff --git a/api/js/etemplate/Et2Select/Et2Select.ts b/api/js/etemplate/Et2Select/Et2Select.ts index 12d767605b..340d52aeb7 100644 --- a/api/js/etemplate/Et2Select/Et2Select.ts +++ b/api/js/etemplate/Et2Select/Et2Select.ts @@ -65,6 +65,7 @@ export class Et2WidgetWithSelect extends RowLimitedMixin(Et2WidgetWithSelectMixi // @ts-ignore SlSelect styles is a single CSSResult, not an array, so TS complains export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect) { + private _block_change_event : boolean = false; static get styles() { return [ @@ -303,6 +304,70 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect) } } + /** + * Handle the case where there is no value set, or the value provided is not an option. + * If this happens, we choose the first option or empty label. + * + * Careful when this is called. We change the value here, so an infinite loop is possible if the widget has + * onchange. + * + */ + protected fix_bad_value() + { + // Stop if there are no options + if(!Array.isArray(this.select_options) || this.select_options.length == 0) + { + // Nothing to do here + return; + } + + // emptyLabel is fine + if(this.value === "" && this.emptyLabel) + { + return; + } + + let valueArray = this.getValueAsArray(); + + // Check for value using missing options (deleted or otherwise not allowed) + let filtered = this.filterOutMissingOptions(valueArray); + if(filtered.length != valueArray.length) + { + this.value = filtered; + return; + } + + // Multiple is allowed to be empty, and if we don't have an emptyLabel or options nothing to do + if(this.multiple || (!this.emptyLabel && this.select_options.length === 0)) + { + return; + } + + // See if parent (search / free entry) is OK with it + if(super.fix_bad_value()) + { + return; + } + // If somebody gave '' as a select_option, let it be + if(this.value === '' && this.select_options.filter((option) => this.value === option.value).length == 1) + { + return; + } + // If no value is set, choose the first option + // Only do this on once during initial setup, or it can be impossible to clear the value + + // value not in options --> use emptyLabel, if exists, or first option otherwise + if(this.select_options.filter((option) => valueArray.find(val => val == option.value) || + Array.isArray(option.value) && option.value.filter(o => valueArray.find(val => val == o.value))).length === 0) + { + let oldValue = this.value; + this.value = this.emptyLabel ? "" : "" + this.select_options[0]?.value; + this._block_change_event = (oldValue != this.value); + // ""+ to cast value of 0 to "0", to not replace with "" + this.requestUpdate("value", oldValue); + } + } + @property() get value() { @@ -384,10 +449,17 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect) return filteredArray; } + // Empty is allowed, if there's an emptyLabel + if(value.toString() == "" && this.emptyLabel) + { + return value; + } + const missing = filterBySelectOptions(value, this.select_options); if(missing.length > 0) { - console.warn("Invalid option '" + missing.join(", ") + " ' removed"); + debugger; + console.warn("Invalid option '" + missing.join(", ") + "' removed"); value = value.filter(item => missing.indexOf(item) == -1); } } diff --git a/api/js/etemplate/Et2Select/Select/Et2SelectTimezone.ts b/api/js/etemplate/Et2Select/Select/Et2SelectTimezone.ts index ff8dd669a1..1c008905b5 100644 --- a/api/js/etemplate/Et2Select/Select/Et2SelectTimezone.ts +++ b/api/js/etemplate/Et2Select/Select/Et2SelectTimezone.ts @@ -1,13 +1,16 @@ import {Et2Select} from "../Et2Select"; import {Et2StaticSelectMixin, StaticOptions} from "../StaticOptions"; +import {cleanSelectOptions} from "../FindSelectOptions"; export class Et2SelectTimezone extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - - this._static_options = StaticOptions.timezone(this, {other: this.other || []}); + this.fetchComplete = StaticOptions.timezone(this, {other: this.other ?? []}).then((options) => + { + this.set_static_options(cleanSelectOptions(options)); + }) } } diff --git a/api/js/etemplate/Et2Select/StaticOptions.ts b/api/js/etemplate/Et2Select/StaticOptions.ts index 6bc1110ef6..21d78a8c17 100644 --- a/api/js/etemplate/Et2Select/StaticOptions.ts +++ b/api/js/etemplate/Et2Select/StaticOptions.ts @@ -393,9 +393,9 @@ export const StaticOptions = new class StaticOptionsType return this.cached_server_side(widget, 'select-lang', options); } - timezone(widget : Et2SelectWidgets, attrs) : SelectOption[] | Promise + timezone(widget : Et2SelectWidgets, attrs) : Promise { var options = ',' + (attrs.other || []).join(','); - return this.cached_server_side(widget, 'select-timezone', options); + return >this.cached_server_side(widget, 'select-timezone', options, true); } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cd055225a3..928ef238bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3048,12 +3048,6 @@ "integrity": "sha512-ARATsLdrGPUnaBvxLhUlnltcMgn7pQG312S8ccdYlnyijabrX9RN/KN/iGj9Am96CoW8e/K9628BA7Bv4XHdrA==", "dev": true }, - "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "peer": true - }, "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -3066,17 +3060,6 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, - "node_modules/@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", - "peer": true, - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -3086,12 +3069,6 @@ "@types/node": "*" } }, - "node_modules/@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", - "peer": true - }, "node_modules/@types/serve-static": { "version": "1.13.10", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", @@ -4446,12 +4423,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "peer": true - }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -7287,7 +7258,7 @@ "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "devOptional": true, + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -9736,8 +9707,7 @@ "version": "1.10.11", "resolved": "https://registry.npmjs.org/@interactjs/core/-/core-1.10.11.tgz", "integrity": "sha512-aJ50ccVeszpJt7wPH7Yfqm7f1aG1SA94qd90P0NaESh5/QUXn4CESO6igobo4DFHQ5z+1Rfdl8aphP4JxlH4gw==", - "dev": true, - "requires": {} + "dev": true }, "@interactjs/dev-tools": { "version": "1.10.11", @@ -9927,8 +9897,7 @@ "@lit-labs/react": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.0.1.tgz", - "integrity": "sha512-Nj+XB3HamqaWefN91lpFPJaqjJ78XzGkPWCedB4jyH22GBFEenpE9A/h8B/2dnIGXtNtd9D/RFpUdQ/dBtWFqA==", - "requires": {} + "integrity": "sha512-Nj+XB3HamqaWefN91lpFPJaqjJ78XzGkPWCedB4jyH22GBFEenpE9A/h8B/2dnIGXtNtd9D/RFpUdQ/dBtWFqA==" }, "@lit-labs/ssr-dom-shim": { "version": "1.0.0", @@ -10461,12 +10430,6 @@ "integrity": "sha512-ARATsLdrGPUnaBvxLhUlnltcMgn7pQG312S8ccdYlnyijabrX9RN/KN/iGj9Am96CoW8e/K9628BA7Bv4XHdrA==", "dev": true }, - "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "peer": true - }, "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -10479,17 +10442,6 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, - "@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", - "peer": true, - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -10499,12 +10451,6 @@ "@types/node": "*" } }, - "@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", - "peer": true - }, "@types/serve-static": { "version": "1.13.10", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", @@ -11523,12 +11469,6 @@ "browserslist": "^4.21.5" } }, - "csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "peer": true - }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -13726,7 +13666,7 @@ "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "devOptional": true, + "dev": true, "requires": { "fsevents": "~2.3.2" } @@ -14365,8 +14305,7 @@ "version": "7.5.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", - "dev": true, - "requires": {} + "dev": true }, "yallist": { "version": "4.0.0",