facultyai / dash-bootstrap-components

Bootstrap components for Plotly Dash
https://dash-bootstrap-components.opensource.faculty.ai/
Apache License 2.0
1.12k stars 220 forks source link

dbc.Input does not behave like dcc.Input wrt `pattern` option #1045

Open dagnic opened 3 months ago

dagnic commented 3 months ago

What is happening?

When dcc.Input content does not match the pattern, the border is coloured in red. When dbc.Input content does not match the pattern, the border is NOT coloured in red.

What should be happening?

When dbc.Input content does not match the pattern, the border should be coloured in red, as it is the case for dcc.Input (out of the box, without the need to check the pattern in a callback and to set valid/invalid option accordingly).

This is especially true as the option description is identical for dcc and dbc.

pattern (string; optional): A regular expression that the control's value is checked against. The pattern must match the entire value, not just some subset. Use the title attribute to describe the pattern to help the user. This attribute applies when the value of the type attribute is text, search, tel, url, email, or password, otherwise it is ignored. The regular expression language is the same as JavaScript RegExp algorithm, with the 'u' parameter that makes it treat the pattern as a sequence of unicode code points. The pattern is not surrounded by forward slashes.

Code

import dash
from dash import html
from dash.dependencies import Input
from dash import dcc
import dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(
    children=[
        dbc.Input(  # try to replace by dcc.Input
            id="myvalue",
            type="text",
            pattern=u"[a-z]{6}$",
        ),
    ]
)

@app.callback(
    [Input("myvalue", "value")]
)
def write_text(value):
        print(value)

if __name__ == "__main__":
    app.run_server(debug=True)
tcbegley commented 3 months ago

This is because dash-core-components applies some additional styling when the input is in an invalid state. You can achieve the same effect with some custom CSS. Put the following in a CSS file in your assets/ folder

input:invalid {
    outline: solid red;
}

or if you prefer a more Bootstrappy style you could do something like this

input:invalid {
  border-color: #dc3545;
  padding-right: calc(1.5em + 0.75rem);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right calc(0.375em + 0.1875rem) center;
  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
  outline: none;
}
isaacncz commented 3 weeks ago

does it attached with invalid state in case the pattern does not match?

AnnMarieW commented 3 weeks ago

Hi @isaacncz can you make a minimal example where it's not working as expected?

isaacncz commented 3 weeks ago

i was trying to check if the input is valid.

dbc.Input( id="project-name-input", placeholder="Enter project name", type="text", pattern="^[a-zA-Z0-9 _-]*$" )

And want to make the component invalid if pattern doesnt match. Not sure how to get that working

AnnMarieW commented 3 weeks ago

Did you try the solution above? What's not working? A complete example would be helpful.

isaacncz commented 3 weeks ago
import dash
from dash import html
from dash.dependencies import Input
from dash import dcc
import dash_bootstrap_components as dbc

external_stylesheets = ["assets/test.css"]
app = dash.Dash(
      external_stylesheets=[external_stylesheets],
    )

app.layout = html.Div(
    children=[
        dcc.Input(  # try to replace by dcc.Input
            id="myvalue",
            type="text",
            pattern=u"[a-zA-Z0-9_-]*$",
        ),
    ]
)

@app.callback(
    [Input("myvalue", "value")]
)
def write_text(value):
        print(value)

if __name__ == "__main__":
    app.run_server(debug=True)

i have something like that. What is not working: pattern attribute doesn't show invalid in my case.

AnnMarieW commented 3 weeks ago

Is your pattern incorrect? This live example on PyCafe is based on the original post and works for both dbc and dcc Input. Note that the dbc.Input shows the red outline after the input loses focus.

The example is editable - you can try it with your pattern too.

AnnMarieW commented 3 weeks ago

@isaacncz

Just confirming that the problem is likely the pattern - I tried entering it in a vanilla html Input and it didn't work either:

https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern

isaacncz commented 3 weeks ago

@isaacncz

Just confirming that the problem is likely the pattern - I tried entering it in a vanilla html Input and it didn't work either:

https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern

Yea, the culprit is the pattern. I decided to stick with using callback for now.