File size: 3,067 Bytes
ab6a63c
a79cff1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import panel as pn
import param
import json

FORM_TEXT = """\
<h1>Join Newsletter</h1>

Get the latest updates and news about Panel.
"""

FORM_ICON = """\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"> <path d="M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z"></path> <path d="M3 7l9 6l9 -6"></path> </svg> 
"""

class FormState(param.Parameterized):
    name = param.String(default="", doc="The name of the user.")
    email = param.String(default="", doc="The email of the user.")
    message = param.String(default="", label="Message", doc="An optional message from the user")

    is_not_valid = param.Boolean(default=False)
    validation_errors = param.Dict()
    validation_message = param.String()

    def __init__(self, **params):
      params["name"]=params.get("name", "")
      super().__init__(**params)
    
    def _validate(self):
        errors = {}
        
        if not self.name:
            errors["name"] = "No *Name* entered."
        if not self.email:
            errors["email"] = "No *Email* entered."
        elif not "@" in self.email or not "." in self.email:
            errors["email"] = "Not a valid *Email*."
        
        self.validation_errors=errors
        self.is_not_valid = bool(errors)
        self.validation_message = "**Error**. " + " ".join(errors.values())
    
    def _to_dict(self):
      return {
        "name": self.name, "email": self.email, "message": self.message
      }

    def _reset_to_defaults(self):
        self.param.update(name=self.param.name.default, email=self.param.email.default, message=self.param.message.default)
    
    def submit(self, event):
        self._validate()
        
        if not self.validation_errors:
            pn.state.notifications.success(f"Form submitted: {self._to_dict()}", duration=2000)
            self._reset_to_defaults()

    

def create_form():
    form_state = FormState()

    header = pn.Row(
      pn.pane.SVG(FORM_ICON, margin=0, height=80, sizing_mode="fixed"),
      FORM_TEXT,
    )

    error_pane = pn.pane.Alert(object=form_state.param.validation_message, visible=form_state.param.is_not_valid, alert_type="danger", stylesheets=["p {margin-bottom: 0}"])
    
    name_input = pn.widgets.TextInput.from_param(form_state.param.name, name="Name*", placeholder="User Name")
    email_input = pn.widgets.TextInput.from_param(form_state.param.email, name="Email*", placeholder="Email Address")
    message_input = pn.widgets.TextAreaInput.from_param(form_state.param["message"], placeholder="An optional message")
    
    submit_button = pn.widgets.Button(name="Send", on_click=form_state.submit, button_type="primary")
    
    return pn.Column(header, error_pane, name_input, email_input, message_input, submit_button, sizing_mode="fixed", width=500, styles={"margin": "auto"})



pn.extension(notifications=True, design="bootstrap", sizing_mode="stretch_width")

form = create_form()
form.servable()