0
# Forms and Input Handling
1
2
Comprehensive form elements and input handling with support for both controlled (Compose-managed) and uncontrolled (browser-managed) modes. All input elements are type-safe and support extensive validation attributes.
3
4
## Capabilities
5
6
### Form Container
7
8
Form element for grouping form controls with submission handling.
9
10
```kotlin { .api }
11
/**
12
* Form container element
13
* @param action Form submission URL
14
* @param attrs Additional attributes including method, encType, target
15
* @param content Form content builder
16
*/
17
fun Form(
18
action: String? = null,
19
attrs: AttrBuilderContext<HTMLFormElement>? = null,
20
content: ContentBuilder<HTMLFormElement>? = null
21
)
22
```
23
24
### Generic Input Element
25
26
Base input element with type-safe input type specification.
27
28
```kotlin { .api }
29
/**
30
* Generic input element
31
* @param type Input type specification (determines value type)
32
* @param attrs Additional attributes for input configuration
33
*/
34
fun Input(
35
type: InputType<String>,
36
attrs: AttrBuilderContext<HTMLInputElement>? = null
37
)
38
```
39
40
### Specialized Input Elements
41
42
Type-specific input elements with appropriate value types and attributes.
43
44
```kotlin { .api }
45
/**
46
* Text input for single-line text entry
47
* @param value Current text value (controlled mode) or null (uncontrolled)
48
* @param attrs Additional attributes
49
*/
50
fun TextInput(
51
value: String? = null,
52
attrs: AttrBuilderContext<HTMLInputElement>? = null
53
)
54
55
/**
56
* Password input with masked text entry
57
* @param value Current password value or null
58
* @param attrs Additional attributes
59
*/
60
fun PasswordInput(
61
value: String? = null,
62
attrs: AttrBuilderContext<HTMLInputElement>? = null
63
)
64
65
/**
66
* Number input for numeric values
67
* @param value Current numeric value or null
68
* @param min Minimum allowed value
69
* @param max Maximum allowed value
70
* @param attrs Additional attributes
71
*/
72
fun NumberInput(
73
value: Number? = null,
74
min: Number? = null,
75
max: Number? = null,
76
attrs: AttrBuilderContext<HTMLInputElement>? = null
77
)
78
79
/**
80
* Range slider input
81
* @param value Current range value or null
82
* @param min Minimum value (default 0)
83
* @param max Maximum value (default 100)
84
* @param step Step increment (default 1)
85
* @param attrs Additional attributes
86
*/
87
fun RangeInput(
88
value: Number? = null,
89
min: Number? = null,
90
max: Number? = null,
91
step: Number? = null,
92
attrs: AttrBuilderContext<HTMLInputElement>? = null
93
)
94
95
/**
96
* Email input with built-in email validation
97
* @param value Current email value or null
98
* @param attrs Additional attributes
99
*/
100
fun EmailInput(
101
value: String? = null,
102
attrs: AttrBuilderContext<HTMLInputElement>? = null
103
)
104
105
/**
106
* URL input with built-in URL validation
107
* @param value Current URL value or null
108
* @param attrs Additional attributes
109
*/
110
fun UrlInput(
111
value: String? = null,
112
attrs: AttrBuilderContext<HTMLInputElement>? = null
113
)
114
115
/**
116
* Telephone input for phone numbers
117
* @param value Current phone value or null
118
* @param attrs Additional attributes
119
*/
120
fun TelInput(
121
value: String? = null,
122
attrs: AttrBuilderContext<HTMLInputElement>? = null
123
)
124
125
/**
126
* Search input with search-specific styling
127
* @param value Current search value or null
128
* @param attrs Additional attributes
129
*/
130
fun SearchInput(
131
value: String? = null,
132
attrs: AttrBuilderContext<HTMLInputElement>? = null
133
)
134
135
/**
136
* Checkbox input for boolean values
137
* @param checked Current checked state or null
138
* @param attrs Additional attributes
139
*/
140
fun CheckboxInput(
141
checked: Boolean? = null,
142
attrs: AttrBuilderContext<HTMLInputElement>? = null
143
)
144
145
/**
146
* Radio button input for exclusive selection
147
* @param checked Current checked state or null
148
* @param attrs Additional attributes (name attribute required for grouping)
149
*/
150
fun RadioInput(
151
checked: Boolean? = null,
152
attrs: AttrBuilderContext<HTMLInputElement>? = null
153
)
154
155
/**
156
* File upload input
157
* @param value Current file path or null
158
* @param attrs Additional attributes including accept, multiple
159
*/
160
fun FileInput(
161
value: String? = null,
162
attrs: AttrBuilderContext<HTMLInputElement>? = null
163
)
164
165
/**
166
* Hidden input for storing form data
167
* @param attrs Attributes including value
168
*/
169
fun HiddenInput(attrs: AttrBuilderContext<HTMLInputElement>? = null)
170
171
/**
172
* Submit button input
173
* @param attrs Additional attributes including value (button text)
174
*/
175
fun SubmitInput(attrs: AttrBuilderContext<HTMLInputElement>? = null)
176
```
177
178
### Date and Time Inputs
179
180
Specialized inputs for date and time selection.
181
182
```kotlin { .api }
183
/**
184
* Date picker input
185
* @param value Current date value (YYYY-MM-DD format) or null
186
* @param attrs Additional attributes
187
*/
188
fun DateInput(
189
value: String? = null,
190
attrs: AttrBuilderContext<HTMLInputElement>? = null
191
)
192
193
/**
194
* Time picker input
195
* @param value Current time value (HH:MM format) or null
196
* @param attrs Additional attributes
197
*/
198
fun TimeInput(
199
value: String? = null,
200
attrs: AttrBuilderContext<HTMLInputElement>? = null
201
)
202
203
/**
204
* Date and time picker input
205
* @param value Current datetime value (YYYY-MM-DDTHH:MM format) or null
206
* @param attrs Additional attributes
207
*/
208
fun DateTimeLocalInput(
209
value: String? = null,
210
attrs: AttrBuilderContext<HTMLInputElement>? = null
211
)
212
213
/**
214
* Month picker input
215
* @param value Current month value (YYYY-MM format) or null
216
* @param attrs Additional attributes
217
*/
218
fun MonthInput(
219
value: String? = null,
220
attrs: AttrBuilderContext<HTMLInputElement>? = null
221
)
222
223
/**
224
* Week picker input
225
* @param value Current week value (YYYY-WNN format) or null
226
* @param attrs Additional attributes
227
*/
228
fun WeekInput(
229
value: String? = null,
230
attrs: AttrBuilderContext<HTMLInputElement>? = null
231
)
232
```
233
234
### Form Controls
235
236
Additional form control elements.
237
238
```kotlin { .api }
239
/**
240
* Multi-line text input
241
* @param value Current text value or null
242
* @param attrs Additional attributes including rows, cols, wrap
243
*/
244
fun TextArea(
245
value: String? = null,
246
attrs: AttrBuilderContext<HTMLTextAreaElement>? = null
247
)
248
249
/**
250
* Button element
251
* @param attrs Additional attributes including type (button, submit, reset)
252
* @param content Button content
253
*/
254
fun Button(
255
attrs: AttrBuilderContext<HTMLButtonElement>? = null,
256
content: ContentBuilder<HTMLButtonElement>? = null
257
)
258
259
/**
260
* Select dropdown element
261
* @param attrs Additional attributes
262
* @param multiple Allow multiple selections
263
* @param content Option elements
264
*/
265
fun Select(
266
attrs: AttrBuilderContext<HTMLSelectElement>? = null,
267
multiple: Boolean = false,
268
content: ContentBuilder<HTMLSelectElement>? = null
269
)
270
271
/**
272
* Option element for select dropdowns
273
* @param value Option value
274
* @param attrs Additional attributes including selected
275
* @param content Option display text
276
*/
277
fun Option(
278
value: String,
279
attrs: AttrBuilderContext<HTMLOptionElement>? = null,
280
content: ContentBuilder<HTMLOptionElement>? = null
281
)
282
283
/**
284
* Option group for organizing select options
285
* @param label Group label
286
* @param attrs Additional attributes
287
* @param content Option elements
288
*/
289
fun OptGroup(
290
label: String,
291
attrs: AttrBuilderContext<HTMLOptGroupElement>? = null,
292
content: ContentBuilder<HTMLOptGroupElement>? = null
293
)
294
295
/**
296
* Label element for form controls
297
* @param forId ID of associated form control
298
* @param attrs Additional attributes
299
* @param content Label text or content
300
*/
301
fun Label(
302
forId: String? = null,
303
attrs: AttrBuilderContext<HTMLLabelElement>? = null,
304
content: ContentBuilder<HTMLLabelElement>? = null
305
)
306
307
/**
308
* Fieldset for grouping form controls
309
* @param attrs Additional attributes
310
* @param content Fieldset content including legend
311
*/
312
fun Fieldset(
313
attrs: AttrBuilderContext<HTMLFieldSetElement>? = null,
314
content: ContentBuilder<HTMLFieldSetElement>? = null
315
)
316
317
/**
318
* Legend element for fieldset caption
319
* @param attrs Additional attributes
320
* @param content Legend text
321
*/
322
fun Legend(
323
attrs: AttrBuilderContext<HTMLLegendElement>? = null,
324
content: ContentBuilder<HTMLLegendElement>? = null
325
)
326
327
/**
328
* Data list for input suggestions
329
* @param attrs Additional attributes including id
330
* @param content Option elements
331
*/
332
fun Datalist(
333
attrs: AttrBuilderContext<HTMLDataListElement>? = null,
334
content: ContentBuilder<HTMLDataListElement>? = null
335
)
336
```
337
338
### Input Types
339
340
Type-safe input type hierarchy for the generic Input element.
341
342
```kotlin { .api }
343
/**
344
* Base input type class
345
* @param T Value type for the input
346
*/
347
sealed class InputType<T>
348
349
// Text-based input types
350
object InputType.Text : InputType<String>
351
object InputType.Password : InputType<String>
352
object InputType.Email : InputType<String>
353
object InputType.Url : InputType<String>
354
object InputType.Tel : InputType<String>
355
object InputType.Search : InputType<String>
356
357
// Numeric input types
358
object InputType.Number : InputType<String>
359
object InputType.Range : InputType<String>
360
361
// Boolean input types
362
object InputType.Checkbox : InputType<Boolean>
363
object InputType.Radio : InputType<Boolean>
364
365
// Date/time input types
366
object InputType.Date : InputType<String>
367
object InputType.Time : InputType<String>
368
object InputType.DateTimeLocal : InputType<String>
369
object InputType.Month : InputType<String>
370
object InputType.Week : InputType<String>
371
372
// File input type
373
object InputType.File : InputType<String>
374
375
// Button input types
376
object InputType.Submit : InputType<String>
377
object InputType.Button : InputType<String>
378
object InputType.Reset : InputType<String>
379
380
// Hidden input type
381
object InputType.Hidden : InputType<String>
382
383
// Color input type
384
object InputType.Color : InputType<String>
385
```
386
387
### Form Attributes
388
389
Comprehensive form-related attributes for validation and behavior control.
390
391
```kotlin { .api }
392
/**
393
* Form-specific attributes (available on AttrsScope)
394
*/
395
396
// Input value attributes
397
fun AttrsScope<HTMLInputElement>.value(value: String)
398
fun AttrsScope<HTMLInputElement>.defaultValue(value: String)
399
fun AttrsScope<HTMLTextAreaElement>.value(value: String)
400
fun AttrsScope<HTMLTextAreaElement>.defaultValue(value: String)
401
402
// Input configuration
403
fun AttrsScope<HTMLInputElement>.placeholder(value: String)
404
fun AttrsScope<HTMLTextAreaElement>.placeholder(value: String)
405
fun AttrsScope<*>.name(value: String)
406
fun AttrsScope<*>.required()
407
fun AttrsScope<*>.disabled()
408
fun AttrsScope<*>.readOnly()
409
fun AttrsScope<*>.autoFocus()
410
411
// Validation attributes
412
fun AttrsScope<HTMLInputElement>.minLength(value: Int)
413
fun AttrsScope<HTMLInputElement>.maxLength(value: Int)
414
fun AttrsScope<HTMLTextAreaElement>.minLength(value: Int)
415
fun AttrsScope<HTMLTextAreaElement>.maxLength(value: Int)
416
fun AttrsScope<HTMLInputElement>.min(value: String)
417
fun AttrsScope<HTMLInputElement>.max(value: String)
418
fun AttrsScope<HTMLInputElement>.step(value: Number)
419
fun AttrsScope<HTMLInputElement>.pattern(value: String)
420
421
// File input attributes
422
fun AttrsScope<HTMLInputElement>.accept(value: String)
423
fun AttrsScope<HTMLInputElement>.multiple()
424
fun AttrsScope<HTMLSelectElement>.multiple()
425
426
// Form behavior attributes
427
fun AttrsScope<HTMLInputElement>.autoComplete(value: AutoComplete)
428
fun AttrsScope<HTMLFormElement>.action(value: String)
429
fun AttrsScope<HTMLFormElement>.method(value: FormMethod)
430
fun AttrsScope<HTMLFormElement>.encType(value: FormEncType)
431
fun AttrsScope<HTMLFormElement>.target(value: FormTarget)
432
fun AttrsScope<HTMLFormElement>.noValidate()
433
434
// TextArea specific attributes
435
fun AttrsScope<HTMLTextAreaElement>.rows(value: Int)
436
fun AttrsScope<HTMLTextAreaElement>.cols(value: Int)
437
fun AttrsScope<HTMLTextAreaElement>.wrap(value: TextAreaWrap)
438
439
// Button attributes
440
fun AttrsScope<HTMLButtonElement>.type(value: ButtonType)
441
442
// Select attributes
443
fun AttrsScope<HTMLOptionElement>.selected()
444
fun AttrsScope<HTMLOptionElement>.value(value: String)
445
446
// Label attributes
447
fun AttrsScope<HTMLLabelElement>.forId(value: String)
448
```
449
450
### Form Enums and Constants
451
452
Type-safe enums for form-related attribute values.
453
454
```kotlin { .api }
455
// Form methods
456
enum class FormMethod { Get, Post, Dialog }
457
458
// Form encoding types
459
enum class FormEncType {
460
ApplicationXWwwFormUrlencoded,
461
MultipartFormData,
462
TextPlain
463
}
464
465
// Form and link targets
466
enum class FormTarget { Blank, Self, Parent, Top }
467
enum class ATarget { Blank, Self, Parent, Top }
468
469
// Button types
470
enum class ButtonType { Button, Submit, Reset }
471
472
// Text area wrapping
473
enum class TextAreaWrap { Hard, Soft, Off }
474
475
// Auto-completion values
476
enum class AutoComplete {
477
On, Off, Name, Email, Username, NewPassword, CurrentPassword,
478
OneTimeCode, Organization, StreetAddress, AddressLine1,
479
AddressLine2, AddressLevel1, AddressLevel2, Country,
480
CountryName, PostalCode, CcName, CcGivenName, CcFamilyName,
481
CcNumber, CcExp, CcExpMonth, CcExpYear, CcCsc, CcType,
482
TransactionCurrency, TransactionAmount, Language, Bday,
483
BdayDay, BdayMonth, BdayYear, Sex, Tel, TelCountryCode,
484
TelNational, TelAreaCode, TelLocal, TelExtension, Impp, Url,
485
Photo, Webauthn
486
}
487
```
488
489
**Usage Examples:**
490
491
```kotlin
492
import org.jetbrains.compose.web.dom.*
493
import org.jetbrains.compose.web.attributes.*
494
495
// Controlled input with state management
496
var username by remember { mutableStateOf("") }
497
var password by remember { mutableStateOf("") }
498
var rememberMe by remember { mutableStateOf(false) }
499
500
Form({
501
onSubmit { event ->
502
event.preventDefault()
503
console.log("Login attempt: $username")
504
}
505
}) {
506
Fieldset {
507
Legend { Text("Login Form") }
508
509
// Text input with validation
510
Label(forId = "username") { Text("Username:") }
511
TextInput(value = username, {
512
id("username")
513
placeholder("Enter your username")
514
required()
515
minLength(3)
516
maxLength(20)
517
pattern("[a-zA-Z0-9_]+")
518
autoComplete(AutoComplete.Username)
519
520
onInput { event ->
521
username = (event.target as HTMLInputElement).value
522
}
523
})
524
525
// Password input
526
Label(forId = "password") { Text("Password:") }
527
PasswordInput(value = password, {
528
id("password")
529
placeholder("Enter your password")
530
required()
531
minLength(8)
532
autoComplete(AutoComplete.CurrentPassword)
533
534
onInput { event ->
535
password = (event.target as HTMLInputElement).value
536
}
537
})
538
539
// Checkbox input
540
Label {
541
CheckboxInput(checked = rememberMe, {
542
onChange { event ->
543
rememberMe = (event.target as HTMLInputElement).checked
544
}
545
})
546
Text(" Remember me")
547
}
548
549
// Submit button
550
Button({ type(ButtonType.Submit) }) {
551
Text("Login")
552
}
553
}
554
}
555
556
// Uncontrolled form with default values
557
Form({
558
action("/submit")
559
method(FormMethod.Post)
560
encType(FormEncType.MultipartFormData)
561
}) {
562
// Form will manage its own state
563
TextInput({
564
name("fullName")
565
defaultValue("John Doe")
566
placeholder("Full Name")
567
required()
568
})
569
570
EmailInput({
571
name("email")
572
placeholder("Email Address")
573
required()
574
})
575
576
Select({
577
name("country")
578
required()
579
}) {
580
Option("", { selected() }) { Text("Select Country") }
581
Option("us") { Text("United States") }
582
Option("ca") { Text("Canada") }
583
Option("uk") { Text("United Kingdom") }
584
}
585
586
SubmitInput({ value("Submit") })
587
}
588
589
// Advanced form with file upload and validation
590
var selectedFile by remember { mutableStateOf<File?>(null) }
591
var description by remember { mutableStateOf("") }
592
593
Form({
594
onSubmit { event ->
595
event.preventDefault()
596
597
if (selectedFile != null && description.isNotBlank()) {
598
// Handle file upload
599
console.log("Uploading file: ${selectedFile?.name}")
600
}
601
}
602
}) {
603
Label(forId = "file") { Text("Select File:") }
604
FileInput({
605
id("file")
606
accept("image/*,.pdf,.doc,.docx")
607
required()
608
609
onChange { event ->
610
val input = event.target as HTMLInputElement
611
selectedFile = input.files?.get(0)
612
}
613
})
614
615
Label(forId = "description") { Text("Description:") }
616
TextArea(value = description, {
617
id("description")
618
rows(4)
619
cols(50)
620
placeholder("Describe the file...")
621
required()
622
maxLength(500)
623
624
onInput { event ->
625
description = (event.target as HTMLTextAreaElement).value
626
}
627
})
628
629
Button({ type(ButtonType.Submit) }) {
630
Text("Upload File")
631
}
632
}
633
634
// Radio button group
635
var selectedOption by remember { mutableStateOf("") }
636
637
Fieldset {
638
Legend { Text("Choose an option:") }
639
640
listOf("option1" to "First Option", "option2" to "Second Option", "option3" to "Third Option").forEach { (value, label) ->
641
Label {
642
RadioInput(checked = selectedOption == value, {
643
name("radioGroup")
644
value(value)
645
onChange { event ->
646
if ((event.target as HTMLInputElement).checked) {
647
selectedOption = value
648
}
649
}
650
})
651
Text(" $label")
652
}
653
Br()
654
}
655
}
656
657
// Number and range inputs with validation
658
var quantity by remember { mutableStateOf(1) }
659
var rating by remember { mutableStateOf(5) }
660
661
Label(forId = "quantity") { Text("Quantity:") }
662
NumberInput(value = quantity, min = 1, max = 100, {
663
id("quantity")
664
step(1)
665
required()
666
667
onInput { event ->
668
val value = (event.target as HTMLInputElement).value.toIntOrNull()
669
if (value != null) quantity = value
670
}
671
})
672
673
Label(forId = "rating") { Text("Rating: $rating") }
674
RangeInput(value = rating, min = 1, max = 10, step = 1, {
675
id("rating")
676
677
onInput { event ->
678
rating = (event.target as HTMLInputElement).value.toInt()
679
}
680
})
681
682
// Date and time inputs
683
var selectedDate by remember { mutableStateOf("") }
684
var selectedTime by remember { mutableStateOf("") }
685
686
Label(forId = "date") { Text("Select Date:") }
687
DateInput(value = selectedDate, {
688
id("date")
689
min("2024-01-01")
690
max("2024-12-31")
691
692
onChange { event ->
693
selectedDate = (event.target as HTMLInputElement).value
694
}
695
})
696
697
Label(forId = "time") { Text("Select Time:") }
698
TimeInput(value = selectedTime, {
699
id("time")
700
step(900) // 15-minute increments
701
702
onChange { event ->
703
selectedTime = (event.target as HTMLInputElement).value
704
}
705
})
706
```