# Forms and Inputs
GTML supports HTML form elements for creating interactive UI. This guide covers input types, form handling, and styling.
## Input Types
### Text Input
Standard single-line text input.
```html
```
**Godot Control:** LineEdit
### Password Input
Text input with masked characters.
```html
```
**Godot Control:** LineEdit (with secret mode)
### Email Input
Text input for email addresses (functions as text input).
```html
```
**Godot Control:** LineEdit
### Number Input
Text input that only accepts numeric values.
```html
```
**Godot Control:** LineEdit (with number filter)
### Checkbox
Toggle checkbox input.
```html
```
**Attributes:**
- `checked` - Pre-checked state (boolean attribute)
**Godot Control:** CheckBox
### Radio Buttons
Radio buttons are automatically grouped by the `name` attribute:
```html
```
**Attributes:**
- `name` - Group name (radios with same name are mutually exclusive)
- `value` - Value emitted when selected
- `checked` - Pre-selected option
**Godot Control:** CheckBox (in ButtonGroup)
### Range Slider
Slider input for numeric ranges.
```html
```
**Attributes:**
- `min` - Minimum value (default: 0)
- `max` - Maximum value (default: 100)
- `step` - Step increment (default: 1)
- `value` - Initial value
**Godot Control:** HSlider
### Submit Button
Submit button for forms.
```html
```
**Godot Control:** Button
## Textarea
Multi-line text input.
```html
```
**Attributes:**
- `id` / `name` - Element identifier
- `rows` - Visible rows (default: 4)
- `cols` - Visible columns (default: 20)
- `placeholder` - Placeholder text
**Godot Control:** TextEdit
## Select (Dropdown)
Dropdown selection with options.
```html
```
**Select Attributes:**
- `id` / `name` - Element identifier
**Option Attributes:**
- `value` - Option value (defaults to text content if omitted)
- `selected` - Pre-selected option (boolean attribute)
**Godot Control:** OptionButton
## Form Container
Group form elements in a form container:
```html
```
## Event Handling
### Input Changes
Connect to the `input_changed` signal:
```gdscript
func _ready():
$GmlView.input_changed.connect(_on_input_changed)
func _on_input_changed(input_id: String, value: String):
match input_id:
"username":
print("Username: ", value)
"volume":
AudioServer.set_bus_volume_db(0, linear_to_db(float(value) / 100.0))
"remember":
# Checkbox: value is "true" or "false"
var checked = value == "true"
print("Remember: ", checked)
```
### Selection Changes
Connect to the `selection_changed` signal:
```gdscript
func _ready():
$GmlView.selection_changed.connect(_on_selection_changed)
func _on_selection_changed(select_id: String, value: String):
match select_id:
"country":
print("Selected country: ", value)
"difficulty":
set_difficulty(value)
```
### Form Submission
Connect to the `form_submitted` signal:
```gdscript
func _ready():
$GmlView.form_submitted.connect(_on_form_submitted)
func _on_form_submitted(form_data: Dictionary):
print("Form data: ", form_data)
# form_data contains all input values by ID
```
## Label Association
Use the `for` attribute to associate labels with inputs:
```html
```
Clicking the label will focus the associated input.
## Styling Form Elements
### Basic Styling
```css
input, textarea, select {
background-color: #1a1a28;
border: 1px solid #3a3a5e;
border-radius: 6px;
padding: 10px;
color: #ddddee;
font-size: 14px;
}
input:focus, textarea:focus, select:focus {
border-color: #00d4ff;
background-color: #1e1e2e;
}
```
### Checkbox Styling
```css
input[type="checkbox"] {
/* Checkboxes have limited styling */
/* Use background-color for the box */
}
```
### Range Slider Styling
```css
input[type="range"] {
background-color: #3a3a5e; /* Track color */
color: #00d4ff; /* Filled area color */
}
```
### Disabled State
```css
input:disabled, textarea:disabled, select:disabled {
background-color: #2a2a2a;
color: #666666;
cursor: not-allowed;
}
```
## Complete Form Example
### HTML
```html
```
### CSS
```css
.settings-form {
display: flex;
flex-direction: column;
gap: 20px;
padding: 24px;
background-color: #1a1a2e;
border-radius: 8px;
width: 400px;
}
h2 {
font-size: 24px;
color: #ffffff;
margin-bottom: 8px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.checkbox-group {
flex-direction: row;
align-items: center;
}
.radio-group {
display: flex;
flex-direction: row;
gap: 16px;
}
label {
font-size: 14px;
color: #aaaacc;
}
input, textarea, select {
background-color: #2a2a3e;
border: 1px solid #3a3a5e;
border-radius: 4px;
padding: 10px;
color: #ffffff;
font-size: 14px;
}
input:focus, textarea:focus, select:focus {
border-color: #00d4ff;
}
.buttons {
display: flex;
flex-direction: row;
gap: 12px;
justify-content: flex-end;
margin-top: 16px;
}
button {
padding: 10px 20px;
background-color: #00d4ff;
border-radius: 4px;
color: #000000;
font-size: 14px;
}
button:hover {
background-color: #00a8cc;
}
button.secondary {
background-color: #3a3a5e;
color: #ffffff;
}
button.secondary:hover {
background-color: #4a4a7e;
}
```
### GDScript
```gdscript
extends Control
var settings = {
"player_name": "",
"difficulty": "normal",
"volume": 75,
"fullscreen": false,
"vsync": true,
"quality": "medium"
}
func _ready():
$GmlView.input_changed.connect(_on_input_changed)
$GmlView.selection_changed.connect(_on_selection_changed)
$GmlView.button_clicked.connect(_on_button_clicked)
func _on_input_changed(id: String, value: String):
match id:
"player-name":
settings.player_name = value
"volume":
settings.volume = int(value)
"fullscreen":
settings.fullscreen = value == "true"
"vsync":
settings.vsync = value == "true"
"low", "medium", "high":
settings.quality = id
func _on_selection_changed(id: String, value: String):
if id == "difficulty":
settings.difficulty = value
func _on_button_clicked(method: String):
match method:
"on_save":
save_settings()
"on_cancel":
close_settings()
func save_settings():
print("Saving settings: ", settings)
# Apply settings...
func close_settings():
queue_free()
```
## See Also
- [HTML Elements](html-elements.md) - All element types
- [CSS Properties](css-properties.md) - Styling properties
- [CSS Selectors](css-selectors.md) - Focus pseudo-class
- [Getting Started](getting-started.md) - Signal handling basics