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

Add Blur message to Input widget #5414

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

edward-jazzhands
Copy link
Contributor

@edward-jazzhands edward-jazzhands commented Dec 20, 2024

I realized working with the Input widget that its options for validate_on are "submitted", "changed", and "blur". However, there's only messages for Submitted and Changed. This makes it trickier to synchronize a function with the blur validator than it is with the other two validators, which I believe in this situation does not make sense.

Now I had figured a Blur event most likely does not exist for a reason (i.e. perhaps if one widget has it then why wouldn't all of them). But in this situation I can't help but feel like its existence is warranted in order to make the validate_on=['blur'] parameter be able to be used in a manner that's identical to "submitted" and "changed" without needing to subclass the Input widget.

The problem:

yield Input(value="foo", validate_on=['changed'], ...)

@on(Input.Changed)
def my_input_changed(self, event: Input.Changed):
    # This works
yield Input(value="foo", validate_on=['submitted'], ...)

@on(Input.Submitted)
def my_input_changed(self, event: Input.Submitted):
    # This works
yield Input(value="foo", validate_on=['blur'], ...)

@on(Input.Blur)
def my_input_blur(self, event: Input.Blur):
    # This does not work

a message when triggered to match the Submitted and Changed messages.
@edward-jazzhands edward-jazzhands changed the title Added Blur message to Input widget Add Blur message to Input widget Dec 20, 2024
@davep
Copy link
Contributor

davep commented Dec 27, 2024

Now I had figured a Blur event most likely does not exist for a reason

The reason is most likely that the DescendentBlur message is the thing to use. For example:

from textual import on
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical
from textual.events import DescendantBlur
from textual.widgets import Input, Log

class InputBlurTest(App[None]):

    def compose(self) -> ComposeResult:
        with Horizontal():
            with Vertical():
                for n in range(10):
                    yield Input(placeholder=str(n), id=f"input-{n}")
            yield Log()

    @on(DescendantBlur, "Input")
    def log_input_blur(self, message: DescendantBlur) -> None:
        self.query_one(Log).write_line(f"This input lost focus: {message.control!r}")

if __name__ == "__main__":
    InputBlurTest().run()

@TomJGooding
Copy link
Contributor

@davep I think the problem being addressed here is that while...

You can check whether the validation succeeded or failed inside an Input.Changed or Input.Submitted handler by looking at the validation_result attribute on these events.

...you can't do the same when the Input is validated on blur.

@davep
Copy link
Contributor

davep commented Dec 27, 2024

I was offering a possible explanation as to why that particular message was missing; not suggesting that this PR shouldn't have been PRd.

Copy link
Collaborator

@willmcgugan willmcgugan left a comment

Choose a reason for hiding this comment

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

Good idea, just a request.

@@ -284,6 +284,29 @@ def control(self) -> Input:
"""Alias for self.input."""
return self.input

@dataclass
class Blur(Message):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's call it Blurred, which is more consistent with existing messages, and avoids confusion with the existing Blur message.

@willmcgugan
Copy link
Collaborator

@davep I believe @edward-jazzhands was talking about a hypothetical Input.Blur message, and not the standard Blur event.

@edward-jazzhands
Copy link
Contributor Author

edward-jazzhands commented Dec 30, 2024

@davep Ah I was not aware of the DescendantBlur and DescendantFocus messages. Didn't notice those in the reference. Yes indeed it would solve the problem. I see now that this would effectively create another message that's doing the same thing as DescendantBlur, but attached specifically to the Input widget, just to give it a message that can be used in a manner that's more similar to the other two messages, and a bit more intuitive to figure out.

Perhaps if this section of the reference (https://textual.textualize.io/widgets/input/#validating-input) was updated to mention the DescendantFocus message then this would be unnecessary. But nevertheless, I've submitted the changes that @willmcgugan requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants