Introduction
In IHP, forms are an essential way to interact with your application. IHP provides helpers to generate form markup to help you deal with complexity around consistent styling and validation. By default, forms in IHP follow the class names used by Bootstrap 5. The default form generation can be customized to support other CSS frameworks. Unless JavaScript helpers have been deactivated, your form will be submitted using AJAX and TurboLinks instead of browser-based form submission.Simple Forms
Forms usually begin with aformFor expression. Here’s a simple example:
POST, the action is automatically set to /CreatePost, and all inputs have auto-generated class names, IDs, and name attributes.
Form Controls
IHP has the most commonly-used form control helpers built in. Here’s a list of all built-in form control helpers:{textField #title}{textareaField #body}{colorField #brandColor}{emailField #email}{dateField #dueAt}{passwordField #password}{dateTimeField #createdAt}{numberField #quantity}{urlField #url}{hiddenField #projectId}{checkboxField #termsAccepted}{selectField #projectId allProjects}{radioField #projectId allProjects}{fileField #profilePicture}{submitButton}
{textField #title}, the input value will be set:
Validation
When rendering a record that has failed validation, the validation error message will be rendered automatically. Given a post like this:{textField #title}, the input will have the CSS class is-invalid and an error message will be rendered:
Forms Are Also HSX
While the form helpers are called byformFor, you can still use HSX inside your form:
?formContext variable, which keeps track of the current record, form action, and other options.
Customizing Inputs
Help Texts
Add a help text below a form control:Custom Field Label Text
Customize the auto-generated label:Custom CSS Classes
Add custom CSS classes to inputs and labels:Placeholder
Specify an input placeholder:Required Fields
Mark an input as required:Disabled Fields
Mark an input as disabled:Autofocus
Give input focus on page load:Custom Submit Button Text
Custom Submit Button Class
Select and Radio Inputs
Select inputs require you to pass a list of possible values:CanSelect User instance:
users = [User { id = 1, name = "Marc" }, User { id = 2, name = "Andreas" }], this renders:
Select Inputs with Nullable Value
To allow the user to make a choice of missing/none, adjust theCanSelect instance:
Nothing as the first item:
Select Inputs with Custom Enums
Given an enum:CanSelect ContentType:
allEnumValues in your view:
Select Inputs with Integers
For a select field consisting of integers:CanSelect instance:
Customizing Forms
Custom Form Action / Form URLs
The URL where the form is submitted is specified in theaction attribute. Use formFor' to override:
pathTo:
Custom Form Class
By default forms have the CSS classnew-form or edit-form. Override using formForWithOptions:
Custom Form Id
Set a<form id=""> attribute:
GET Forms / Custom Form Method
By default forms usemethod="POST". Override using formMethod:
Disable Form Submission via JavaScript
Forms are submitted using AJAX and TurboLinks. Disable this behavior:Standalone Validation Errors
If you’re using a custom widget for a form field, usevalidationResult to render standalone validation errors:
CSRF Protection
IHP by default sets session cookies using the Lax SameSite option. This protects against all common CSRF vectors. This browser-based CSRF protection works with all modern browsers, therefore token-based protection is not used.JavaScript Helpers
By default, forms are submitted using AJAX and TurboLinks. This supports SPA-like page transitions and automatically:- Disables the submit button after submission
- Removes flash messages inside the form
window.submitForm(formElement) to trigger a form submission from JavaScript.
The form helpers are designed to improve the User Experience for browsers where JavaScript is enabled. If JavaScript is not enabled or blocked, the form submission will still work as expected.
To disable the form helpers, remove the IHP JavaScript helpers from your layout. In Web/View/Layout.hs remove: