How to press "Enter" on TextInput to trigger a Button?

import panel as pn
pn.extension()

text = pn.widgets.TextInput()
button = pn.widgets.Button()
pn.Column(text, button).servable()

One way is to watch the param “value” change, but that can be triggered from other than “Enter”.

Use case is two text inputs (user / pass) and button (submit). When user clicks enter on the password text input, it triggers validation.

1 Like

Maybe something like this?

import panel as pn
pn.extension()

text = pn.widgets.TextInput(placeholder="Username")
button = pn.widgets.Button(name="Submit")
button.on_click(lambda x: print("Button"))

@pn.depends(text, watch=True)
def test(t):
    print("Text:", t)
    button.clicks += 1

pn.Column(text, button).servable()

Thanks. If you click away, it automatically presses submit which I don’t want:

import time
import panel as pn
pn.extension()

text = pn.widgets.TextInput(placeholder="Username")
button = pn.widgets.Button(name="Submit")
button.on_click(lambda x: print("Button"))

@pn.depends(text, watch=True)
def test(t):
    print("Text:", t)
    button.clicks += 1
    button.loading = True
    time.sleep(1)
    button.loading = False

pn.Column(text, button).servable()

I tried playing around with ReactiveHTML (for the first time) and got something to work. It is in no way perfect but I think it is a good starting point.

import param
import panel as pn


# Inspiration:
# https://www.w3schools.com/howto/howto_css_login_form.asp
# https://stackoverflow.com/questions/25983603/how-to-submit-an-html-form-without-redirection
# https://panel.holoviz.org/user_guide/Custom_Components.html


RAW_CSS = """
body {font-family: Arial, Helvetica, sans-serif;}
form {border: 3px solid #f1f1f1;}

input[type=text], input[type=password] {
  width: 100%;
  padding: 12px 20px;
  margin: 8px 0;
  display: inline-block;
  border: 1px solid #ccc;
  box-sizing: border-box;
}

button {
  background-color: #04AA6D;
  color: white;
  padding: 14px 20px;
  margin: 8px 0;
  border: none;
  cursor: pointer;
  width: 100%;
}

button:hover {
  opacity: 0.8;
}
"""
pn.config.raw_css.append(RAW_CSS)


class Login(pn.reactive.ReactiveHTML):
    username = param.String()
    password = param.String()
    logged_in = param.Boolean()

    _template = """
    <iframe name="dummyframe" id="dummyframe" style="display: none;"></iframe>
    <form target="dummyframe">
        <input id="username" type="text" value="${username}" placeholder="Username" required></input>
        <input id="password" type="password" value="${password}" placeholder="Password" required></input>
        <button id="button" onclick="${_validates_login}">Login</button>
    </form>

    <div id="login">${logged_in}</div>
    """
    _dom_events = {"username": ['change'], "password": ['change']}

    def _validates_login(self, *events):
        if self.username == "s" and self.password == "s":
            self.logged_in = True
        else:
            self.logged_in = False

        print(self.logged_in)

        return False


Login().servable()

Some problems which needs to be ironed out:

  • The fields gives a Bokeh error when I insert numbers only.
  • Sometimes I have to press double enter to get the login to work.
  • Be sure that there isn’t any security risks or similar.
2 Likes

Hi @ahuang11 just try to understand your example code in here, kindly please advise if I want to use input widget and button, after user click button will perform selection based on input user. Example case:
there is an input x,y coordinate and submit button, then from that after submit button click, nearest data location will be show up. Is there any example for that.

thanks

Use pn.bind with multiple args passed Add reactivity to components — Panel v1.3.2 (holoviz.org)