From dfb4253ec804d10ca1977185f0770000c0b23fde Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Sat, 12 Oct 2024 14:38:38 +0200
Subject: [PATCH] fix: defaultValue is now zero #251

---
 source/components/form/select.mjs | 57 +++++++++++++++++--------------
 1 file changed, 32 insertions(+), 25 deletions(-)

diff --git a/source/components/form/select.mjs b/source/components/form/select.mjs
index 57ca05d6d..32d73c619 100644
--- a/source/components/form/select.mjs
+++ b/source/components/form/select.mjs
@@ -28,7 +28,6 @@ import {
     ATTRIBUTE_ROLE,
 } from "../../dom/constants.mjs";
 import {CustomControl} from "../../dom/customcontrol.mjs";
-import {clone} from "../../util/clone.mjs";
 import {
     assembleMethodSymbol,
     getSlottedElements,
@@ -230,6 +229,12 @@ const statusOrRemoveBadgesElementSymbol = Symbol("statusOrRemoveBadgesElement");
  */
 const areOptionsAvailableAndInitSymbol = Symbol("@@areOptionsAvailableAndInit");
 
+/**
+ * @private
+ * @type {symbol}
+ */
+const disabledRequestMarker = Symbol("@@disabledRequestMarker");
+
 /**
  * @private
  * @type {number}
@@ -367,9 +372,9 @@ class Select extends CustomControl {
      * @property {string} type=radio Multiple (checkbox) or single selection (radio)
      * @property {string} name=(random id) Name of the form field
      * @property {string} url Load options from server per url
-     * @property {string} lookup Load options from server per url
-     * @property {boolean} lookup.url=null Load options from server per url
-     * @property {boolean} lookup.individually=false Load options individually
+     * @property {object} lookup Load options from server per url
+     * @property {string} lookup.url=null Load options from server per url
+     * @property {boolean} lookup.grouping=false Load all selected options from server per url at once (true) or one by one (false)
      * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
      * @property {String} fetch.redirect=error
      * @property {String} fetch.method=GET
@@ -389,8 +394,8 @@ class Select extends CustomControl {
      * @property {Boolean} features.emptyValueIfNoOptions=false If no options are available, the selection is set to an empty array
      * @property {Boolean} features.storeFetchedData=false Store fetched data in the object
      * @property {Boolean} features.useStrictValueComparison=true Use strict value comparison for the selection
-     * @property {Boolean} filter.defaultValue=* Default filter value, if the filter is empty
-     * @property {Boolean} filter.mode=options Filter mode, values: options, remote, disabled (Hint; lazylLoad is not supported with remote filter)
+     * @property {string} filter.defaultValue=null Default filter value, if the filter is empty, if the default value is null, then no request is made
+     * @property {Boolean} filter.mode=options Filter mode, values: options, remote, disabled (Hint; lazylLoad is not supported with remote filter, if you use remote filter, the lazyLoad is disabled)
      * @property {Object} templates Template definitions
      * @property {string} templates.main Main template
      * @property {string} templateMapping Mapping of the template placeholders
@@ -463,7 +468,7 @@ class Select extends CustomControl {
                     },
                 },
                 filter: {
-                    defaultValue: "*",
+                    defaultValue: null,
                     mode: FILTER_MODE_DISABLED,
                     position: FILTER_POSITION_INLINE,
                     marker: {
@@ -511,6 +516,9 @@ class Select extends CustomControl {
         initControlReferences.call(self);
         initEventHandler.call(self);
 
+        let lazyLoadFlag = self.getOption("features.lazyLoad", false);
+        let remoteFilterFlag = self.getOption("filter.mode") === FILTER_MODE_REMOTE
+
         if (self.getOption("filter.mode") === FILTER_MODE_REMOTE) {
             self.getOption("features.lazyLoad", false);
             if (lazyLoadFlag === true) {
@@ -530,7 +538,7 @@ class Select extends CustomControl {
         }
 
         if (self.getOption("url") !== null) {
-            if (lazyLoadFlag) {
+            if (lazyLoadFlag || remoteFilterFlag) {
                 lookupSelection.call(self);
             } else {
                 self.fetch().catch((e) => {
@@ -1287,23 +1295,16 @@ function calcAndSetOptionsDimension() {
     }
 
     if (visible === 0) {
-        if (this.getOption("options").length === 0) {
+        if (this.getOption("filter.mode") === FILTER_MODE_DISABLED) {
             this.setOption(
                 "messages.emptyOptions",
                 this.getOption("labels.no-options-available"),
             );
         } else {
-            if (this.getOption("filter.mode") === FILTER_MODE_DISABLED) {
-                this.setOption(
-                    "messages.emptyOptions",
-                    this.getOption("labels.no-options-available"),
-                );
-            } else {
-                this.setOption(
-                    "messages.emptyOptions",
-                    this.getOption("labels.no-options-found"),
-                );
-            }
+            this.setOption(
+                "messages.emptyOptions",
+                this.getOption("labels.no-options-found"),
+            );
         }
         this[noOptionsAvailableElementSymbol].classList.remove("d-none");
     } else {
@@ -1535,7 +1536,7 @@ function handleFilterKeyEvents() {
  * @private
  */
 function filterFromRemote() {
-    if (!(this[inlineFilterElementSymbol] instanceof HTMLElement)&&!(this[popperFilterElementSymbol] instanceof HTMLElement)) {
+    if (!(this[inlineFilterElementSymbol] instanceof HTMLElement) && !(this[popperFilterElementSymbol] instanceof HTMLElement)) {
         return;
     }
 
@@ -1566,7 +1567,7 @@ function filterFromRemote() {
                 filterValue = this[popperFilterElementSymbol].value.toLowerCase();
             }
     }
-    
+
     return filterFromRemoteByValue.call(
         this,
         url,
@@ -1575,10 +1576,13 @@ function filterFromRemote() {
 }
 
 function formatURL(url, value) {
-    if(value === undefined || value === null|| value === ""){
+    if (value === undefined || value === null || value === "") {
         value = this.getOption("filter.defaultValue");
+        if (value === undefined || value === null || value === "") {
+            value = disabledRequestMarker.toString();
+        }
     }
-    
+
     const formatter = new Formatter({filter: encodeURI(value)});
     const openMarker = this.getOption("filter.marker.open");
     let closeMarker = this.getOption("filter.marker.close");
@@ -1600,6 +1604,9 @@ function filterFromRemoteByValue(optionUrl, value) {
     return new Processing(() => {
 
         let url = formatURL.call(this, optionUrl, value);
+        if (url.indexOf(disabledRequestMarker.toString()) !== -1) {
+            return;
+        }
 
         fetchIt.call(this, url, {
                 disableHiding: true,
@@ -2222,7 +2229,7 @@ function show() {
 
         return;
     }
-    
+
     const hasPopperFilterFlag = this.getOption("filter.position") === FILTER_POSITION_POPPER && this.getOption("filter.mode") !== FILTER_MODE_DISABLED;
 
     const options = getOptionElements.call(this);
-- 
GitLab