input.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from typing import Any, Callable, Dict, List, Optional
  2. from .icon import Icon
  3. from .mixins.disableable_element import DisableableElement
  4. from .mixins.validation_element import ValidationElement
  5. class Input(ValidationElement, DisableableElement, component='input.js'):
  6. VALUE_PROP: str = 'value'
  7. LOOPBACK = False
  8. def __init__(self,
  9. label: Optional[str] = None, *,
  10. placeholder: Optional[str] = None,
  11. value: str = '',
  12. password: bool = False,
  13. password_toggle_button: bool = False,
  14. on_change: Optional[Callable[..., Any]] = None,
  15. autocomplete: Optional[List[str]] = None,
  16. validation: Dict[str, Callable[..., bool]] = {}) -> None:
  17. """Text Input
  18. This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.
  19. The `on_change` event is called on every keystroke and the value updates accordingly.
  20. If you want to wait until the user confirms the input, you can register a custom event callback, e.g.
  21. `ui.input(...).on('keydown.enter', ...)` or `ui.input(...).on('blur', ...)`.
  22. You can use the `validation` parameter to define a dictionary of validation rules.
  23. The key of the first rule that fails will be displayed as an error message.
  24. Note about styling the input:
  25. Quasar's `QInput` component is a wrapper around a native `input` element.
  26. This means that you cannot style the input directly,
  27. but you can use the `input-class` and `input-style` props to style the native input element.
  28. See the "Style" props section on the `QInput <https://quasar.dev/vue-components/input>`_ documentation for more details.
  29. :param label: displayed label for the text input
  30. :param placeholder: text to show if no value is entered
  31. :param value: the current value of the text input
  32. :param password: whether to hide the input (default: False)
  33. :param password_toggle_button: whether to show a button to toggle the password visibility (default: False)
  34. :param on_change: callback to execute when the value changes
  35. :param autocomplete: optional list of strings for autocompletion
  36. :param validation: dictionary of validation rules, e.g. ``{'Too long!': lambda value: len(value) < 3}``
  37. """
  38. super().__init__(value=value, on_value_change=on_change, validation=validation)
  39. if label is not None:
  40. self._props['label'] = label
  41. if placeholder is not None:
  42. self._props['placeholder'] = placeholder
  43. self._props['type'] = 'password' if password else 'text'
  44. if password_toggle_button:
  45. with self.add_slot('append'):
  46. def toggle_type(_):
  47. is_hidden = self._props.get('type') == 'password'
  48. icon.props(f'name={"visibility" if is_hidden else "visibility_off"}')
  49. self.props(f'type={"text" if is_hidden else "password"}')
  50. icon = Icon('visibility_off').classes('cursor-pointer').on('click', toggle_type)
  51. self._props['_autocomplete'] = autocomplete or []
  52. def set_autocomplete(self, autocomplete: Optional[List[str]]) -> None:
  53. """Set the autocomplete list."""
  54. self._props['_autocomplete'] = autocomplete
  55. self.update()
  56. def _handle_value_change(self, value: Any) -> None:
  57. super()._handle_value_change(value)
  58. if self._send_update_on_value_change:
  59. self.run_method('updateValue')