Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input restriction #3657

Merged
merged 19 commits into from
Nov 10, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- CSS error reporting will no longer provide links to the files in question https://github.com/Textualize/textual/pull/3582
- inline CSS error reporting will report widget/class variable where the CSS was read from https://github.com/Textualize/textual/pull/3582
- Added `restrict`, `type`, `max_length`, and `valid_empty` to Input https://github.com/Textualize/textual/pull/3657

## [0.41.0] - 2023-10-31

Expand Down
13 changes: 13 additions & 0 deletions docs/examples/widgets/input_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from textual.app import App, ComposeResult
from textual.widgets import Input


class InputApp(App):
def compose(self) -> ComposeResult:
yield Input(placeholder="An integer", type="integer")
yield Input(placeholder="A number", type="number")


if __name__ == "__main__":
app = InputApp()
app.run()
56 changes: 49 additions & 7 deletions docs/widgets/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,41 @@ The example below shows how you might create a simple form using two `Input` wid
--8<-- "docs/examples/widgets/input.py"
```


### Input Types

The `Input` widget supports a `type` parameter which will prevent the user from typing invalid characters.
There are three valid values for `type`: `"integer"` will limit input to a valid integer, `"number"` will limit input to a floating point number.
The default value for the `type` parameter is `"text"` which will not limit the input.
willmcgugan marked this conversation as resolved.
Show resolved Hide resolved

=== "Output"

```{.textual path="docs/examples/widgets/input_types.py" press="1234"}
```

=== "input_types.py"

```python
--8<-- "docs/examples/widgets/input_types.py"
```

If you set `type` to something other than `"text"`, then the `Input` will apply the appropriate [validator](#validating-input).

### Restricting Input

You can limit input to particular characters by supplying the `restrict` parameter, which should be a regular expression.
The `Input` widget will prevent the addition of any characters that would cause the regex to no longer match.
For instance, if you wanted to limit characters to binary you could set `restrict=r"[01]*"`.

!!! note

The `restrict` regular expression is applied to the full value and not just to the new character.

### Maximum Length

You can limit the length of the input by setting `max_length` to a value greater than zero.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A string of length 0 is a perfectly fine string.
If max_length can be set to None to mean "No restriction", it'd feel cleaner if we lifted the restriction on the number needing to be > 0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it is paradoxical to have an input with a max length of 0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it doesn't sound useful but my lack of imagination shouldn't deter us from implementing things :P

This will prevent the user from typing any more characters when the maximum has been reached.

### Validating Input

You can supply one or more *[validators][textual.validation.Validator]* to the `Input` widget to validate the value.
Expand Down Expand Up @@ -71,15 +106,22 @@ Textual offers several [built-in validators][textual.validation] for common requ
but you can easily roll your own by extending [Validator][textual.validation.Validator],
as seen for `Palindrome` in the example above.

#### Validate Empty

If you set `valid_empty=True` then empty values will bypass any validators, and empty values will be considered valid.

## Reactive Attributes

| Name | Type | Default | Description |
|-------------------|--------|---------|-----------------------------------------------------------------|
| `cursor_blink` | `bool` | `True` | True if cursor blinking is enabled. |
| `value` | `str` | `""` | The value currently in the text input. |
| `cursor_position` | `int` | `0` | The index of the cursor in the value string. |
| `placeholder` | `str` | `str` | The dimmed placeholder text to display when the input is empty. |
| `password` | `bool` | `False` | True if the input should be masked. |
| Name | Type | Default | Description |
willmcgugan marked this conversation as resolved.
Show resolved Hide resolved
| ----------------- | ------ | -------- | --------------------------------------------------------------- |
| `cursor_blink` | `bool` | `True` | True if cursor blinking is enabled. |
| `value` | `str` | `""` | The value currently in the text input. |
| `cursor_position` | `int` | `0` | The index of the cursor in the value string. |
| `placeholder` | `str` | `str` | The dimmed placeholder text to display when the input is empty. |
willmcgugan marked this conversation as resolved.
Show resolved Hide resolved
| `password` | `bool` | `False` | True if the input should be masked. |
| `restrict` | `str` | `None` | Optional regular expression to restrict input. |
| `type` | `str` | `"text"` | The type of the input. |
| `max_length` | `int` | `None` | Maximum length of the input value. |

## Messages

Expand Down
Loading
Loading