Преглед изворни кода

start to implement autocompletion in JavaScript

Falko Schindler пре 1 година
родитељ
комит
ca9bcde6f2
2 измењених фајлова са 46 додато и 22 уклоњено
  1. 40 0
      nicegui/elements/input.js
  2. 6 22
      nicegui/elements/input.py

+ 40 - 0
nicegui/elements/input.js

@@ -0,0 +1,40 @@
+export default {
+  template: `
+    <q-input v-bind="$attrs" v-model="inputValue" :shadow-text="shadowText" @keydown.tab="perform_autocomplete">
+      <template v-for="(_, slot) in $slots" v-slot:[slot]="slotProps">
+        <slot :name="slot" v-bind="slotProps || {}" />
+      </template>
+    </q-input>
+  `,
+  props: {
+    autocomplete: Array,
+    value: String,
+  },
+  data() {
+    return {
+      inputValue: this.value,
+    };
+  },
+  watch: {
+    inputValue(newValue) {
+      this.$emit("update:value", newValue);
+    },
+  },
+  computed: {
+    shadowText() {
+      if (!this.inputValue) return "";
+      const matchingOption = this.autocomplete.find((option) =>
+        option.toLowerCase().startsWith(this.inputValue.toLowerCase())
+      );
+      return matchingOption ? matchingOption.slice(this.inputValue.length) : "";
+    },
+  },
+  methods: {
+    perform_autocomplete(e) {
+      if (this.shadowText) {
+        this.inputValue += this.shadowText;
+        e.preventDefault();
+      }
+    },
+  },
+};

+ 6 - 22
nicegui/elements/input.py

@@ -1,11 +1,15 @@
 from typing import Any, Callable, Dict, List, Optional
 
+from ..dependencies import register_component
 from .icon import Icon
 from .mixins.disableable_element import DisableableElement
 from .mixins.validation_element import ValidationElement
 
+register_component('ng_input', __file__, 'input.js')
+
 
 class Input(ValidationElement, DisableableElement):
+    VALUE_PROP: str = 'value'
     LOOPBACK = False
 
     def __init__(self,
@@ -37,7 +41,7 @@ class Input(ValidationElement, DisableableElement):
         :param autocomplete: optional list of strings for autocompletion
         :param validation: dictionary of validation rules, e.g. ``{'Too long!': lambda value: len(value) < 3}``
         """
-        super().__init__(tag='q-input', value=value, on_value_change=on_change, validation=validation)
+        super().__init__(tag='ng_input', value=value, on_value_change=on_change, validation=validation)
         if label is not None:
             self._props['label'] = label
         if placeholder is not None:
@@ -52,24 +56,4 @@ class Input(ValidationElement, DisableableElement):
                     self.props(f'type={"text" if is_hidden else "password"}')
                 icon = Icon('visibility_off').classes('cursor-pointer').on('click', toggle_type)
 
-        if autocomplete:
-            def find_autocompletion() -> Optional[str]:
-                if self.value:
-                    needle = str(self.value).casefold()
-                    for item in autocomplete or []:
-                        if item.casefold().startswith(needle):
-                            return item
-                return None  # required by mypy
-
-            def autocomplete_input() -> None:
-                match = find_autocompletion() or ''
-                self.props(f'shadow-text="{match[len(self.value):]}"')
-
-            def complete_input() -> None:
-                match = find_autocompletion()
-                if match:
-                    self.set_value(match)
-                self.props('shadow-text=""')
-
-            self.on('keyup', autocomplete_input)
-            self.on('keydown.tab', complete_input)
+        self._props['autocomplete'] = autocomplete or []