{% extends "docs/base.html" %}
{% block main %}
{% markdown %}
# Form API Javascript
## Dependencies
- `snek.system.form.Form`
- `snek.system.form.HTMLElement`
- `snek.system.form.FormInputElement`
- `snek.system.form.FormButtonElement`
## Usage
Here is an example with custom validation.
This example contains a field that checks if user already exists.
If invalid, it adds an error message which automatically invalidates the field.
Handling of the error messages will automatically done client side.
Forms are usaly located in `snek/form/[form name].py`.
```python
from snek.system.form import Form, HTMLElement,FormInputElement,FormButtonElement
class UsernameField(FormInputElement):
@property
async def errors(self):
result = await super().errors
if self.value and await self.app.services.user.count(username=self.value):
result.append("Username is not available.")
return result
class RegisterForm(Form):
title = HTMLElement(tag="h1", text="Register")
username = UsernameField(
name="username",
required=True,
min_length=2,
max_length=20,
regex=r"^[a-zA-Z0-9_]+$",
place_holder="Username",
type="text"
)
email = FormInputElement(
name="email",
required=False,
regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
place_holder="Email address",
type="email"
)
password = FormInputElement(
name="password",
required=True,
regex=r"^[a-zA-Z0-9_.+-]{6,}",
type="password",
place_holder="Password"
)
action = FormButtonElement(
name="action",
value="submit",
text="Register",
type="button"
)
```
## Set data
```python
# The input structure is in same format as output structure.
# Output structure is the result of await form.to_json()
data = dict(
username=dict(value="retoor"),
password=dict(value="retoorded")
)
form.set_user_data(data)
# Check if form is valid.
is_valid = await form.is_valid
# Convert form to a record (kv pairs) to be used for persistance.
# It does contain an filled uid (UUID4) field already to be used as primary key.
# Default fields:
# - uid (automatically generated, it's an UUID4 wich you can use as private key for database)
# - created_at (automatically generated, it's a string representation of UTC locale)
# - updated_at (execute await form.updated_at.update() before saving to set value)
key_value_values = await form.record
```
{% endmarkdown %}
{% endblock %}