Form Handling & Validation
Type-safe form processing with OorianForm and FormListener—no manual parsing required.
Two Form Classes
Form for traditional browser submission to external URLs. OorianForm for interactive, async forms that stay on the page and receive server updates.
Async Submission
OorianForm intercepts browser submission and sends data through the Oorian event system. The page stays loaded and can receive updates after submission.
Parameters API
Access submitted values through typed getters for String, int, long, double, float, and boolean. Multi-value support for checkboxes and multi-select fields.
Input Types
Built-in support for TextInput, PasswordInput, TextArea, Checkbox, RadioButton, Select, FileInput, HiddenInput, and more.
Validation Framework
ValidatedInput wraps any input with a fluent validation API. Thirteen built-in validators cover required, email, length, pattern, range, URL, phone, and more.
Cross-Field Validation
CompareValidator validates relationships between fields—password confirmation, date ranges, and numeric comparisons with six comparison operations.
Form vs. OorianForm
Oorian provides two form classes that serve different purposes. Form renders a standard HTML form that submits through traditional browser mechanisms—the browser navigates to the action URL. OorianForm intercepts submission and sends data through the Oorian event system, keeping the page loaded for server-side updates.
Form — Traditional Submission
Use Form when you need standard browser submission—posting to a payment gateway, submitting to an external API, or navigating to a response page. The browser sends a GET or POST request to the action URL and replaces the current page with the response.
// Traditional form that posts to an external endpoint
Form form = new Form();
form.setAction("https://payment.example.com/checkout");
form.setMethod(FormMethod.POST);
form.setEncType(FormEncoding.URL_ENCODED);
HiddenInput orderId = new HiddenInput("orderId", "12345");
form.addElement(orderId);
Button payBtn = new Button("Proceed to Payment");
form.addElement(payBtn);OorianForm — Interactive Submission
Use OorianForm for interactive forms within Oorian pages. The form submits asynchronously via AJAX, SSE, or WebSocket (depending on the page's communication mode). The page stays loaded, and you handle the submission in a FormListener.
OorianForm form = new OorianForm();
form.registerListener(this, FormEvent.class);
TextInput name = new TextInput();
name.setName("name");
form.addElement(name);
Button submit = new Button("Send");
form.addElement(submit);Most Oorian applications use OorianForm exclusively, since the framework is designed around pages that stay loaded and respond to events. Use Form when you need standard browser submission behavior—for example, posting to a payment gateway or submitting data to an external API that returns its own response page.
Interactive Forms with OorianForm
Implement the FormListener interface to handle OorianForm submissions. Give each input a name with setName(), register a listener, and access submitted values through the Parameters object in your onEvent method. After processing, update any element on the page to show results, errors, or confirmation messages.
@Page("/contact")
public class ContactPage extends HtmlPage implements FormListener
{
private TextInput nameInput;
private TextInput emailInput;
private TextArea messageInput;
private Span statusLabel;
@Override
protected void createBody(Body body)
{
OorianForm form = new OorianForm();
form.registerListener(this, FormEvent.class);
nameInput = new TextInput();
nameInput.setName("name");
form.addElement(nameInput);
emailInput = new TextInput();
emailInput.setName("email");
form.addElement(emailInput);
messageInput = new TextArea();
messageInput.setName("message");
form.addElement(messageInput);
form.addElement(new Button("Send Message"));
statusLabel = new Span();
form.addElement(statusLabel);
body.addElement(form);
}
@Override
public void onEvent(FormEvent event)
{
Parameters params = event.getParameters();
String name = params.getParameterValue("name");
String email = params.getParameterValue("email");
String message = params.getParameterValue("message");
// Process the form data
sendContactEmail(name, email, message);
statusLabel.setText("Thank you! Your message has been sent.");
sendUpdate();
}
}The Parameters Class
The Parameters class provides typed access to form values. All values arrive as strings from the browser, and Parameters handles type conversion for you. Each getter returns null if the parameter is missing or cannot be parsed.
Parameters params = event.getParameters();
// String value
String name = params.getParameterValue("name");
// Numeric values with automatic parsing
Integer age = params.getParameterValueAsInt("age");
Double salary = params.getParameterValueAsDouble("salary");
// Boolean (checkbox)
Boolean subscribe = params.getParameterValueAsBoolean("subscribe");
// Multi-value (checkboxes, multi-select)
List<String> selectedRoles = params.getParameterValues("roles");
// Check if parameter was submitted
if (params.containsParameter("agreeToTerms"))
{
// User checked the terms checkbox
}Available Typed Getters
getParameterValue(name)
Returns the first value as a String, or null if the parameter was not submitted.
getParameterValues(name)
Returns all values as a List<String>. Used for multi-select fields and checkbox groups.
getParameterValueAsInt(name)
Parses the value as an Integer, or returns null if missing or not a valid integer.
getParameterValueAsLong(name)
Parses the value as a Long, or returns null if missing or not a valid long.
getParameterValueAsDouble(name)
Parses the value as a Double, or returns null if missing or not a valid double.
getParameterValueAsFloat(name)
Parses the value as a Float, or returns null if missing or not a valid float.
getParameterValueAsBoolean(name)
Parses the value as a Boolean. Returns false if the parameter is missing.
containsParameter(name)
Returns true if the parameter exists in the submission, regardless of its value.
Validation Framework
OorianForm includes a validation framework that validates fields on submission. Each input field is wrapped in a ValidatedInput that defines validation rules through a fluent API. When validation fails, error messages are automatically displayed next to each invalid field.
// Create a form with validation
OorianForm form = new OorianForm();
form.registerListener(this, FormEvent.class);
// Create input elements
TextInput emailInput = new TextInput();
emailInput.setName("email");
Span emailError = new Span();
PasswordInput passwordInput = new PasswordInput();
passwordInput.setName("password");
Span passwordError = new Span();
// Register validated inputs with rules
form.addValidatedInput(
new ValidatedInput<>(emailInput, emailError)
.required("Email is required")
.email("Please enter a valid email address")
);
form.addValidatedInput(
new ValidatedInput<>(passwordInput, passwordError)
.required("Password is required")
.minLength(8, "Password must be at least 8 characters")
);
// Add elements to the form
form.addElement(emailInput);
form.addElement(emailError);
form.addElement(passwordInput);
form.addElement(passwordError);
form.addElement(new Button("Sign In"));Built-in Validators
Oorian includes thirteen built-in validators that cover common form validation scenarios. Validators are chained using the fluent API and evaluated in order—validation stops at the first failure for each field.
required(message)
Field must not be empty
email(message)
Must be a valid email address
minLength(n, message)
Minimum character length
maxLength(n, message)
Maximum character length
length(min, max, message)
Length must be within range
pattern(regex, message)
Must match a regex pattern
range(min, max, message)
Numeric value within range
url(message)
Must be a valid URL
phone(format, message)
Must match phone format
numeric(message)
Must be a numeric value
alphanumeric(message)
Letters and numbers only
creditCard(message)
Valid credit card number
date(format, message)
Must match a date format
Validator Chaining
new ValidatedInput<>(usernameInput, usernameError)
.required("Username is required")
.minLength(3, "Username must be at least 3 characters")
.maxLength(20, "Username must be 20 characters or fewer")
.alphanumeric("Username must contain only letters and numbers");Handling Validation in onEvent
In your FormListener, call form.validate(event) to validate all fields at once. The returned ValidationResult tells you whether the form is valid, and error messages are automatically displayed next to each invalid field.
@Override
public void onEvent(FormEvent event)
{
ValidationResult result = form.validate(event);
if (result.isValid())
{
// All fields passed validation - process the form
Parameters params = event.getParameters();
String email = params.getParameterValue("email");
String password = params.getParameterValue("password");
createAccount(email, password);
}
// sendUpdate() pushes validation error messages to the browser
sendUpdate();
}Cross-Field Validation
For validation rules that compare two or more fields, use CompareValidator as a form-level validator. This is commonly used for password confirmation and date range validation. The CompareValidator.Operation enum supports EQUALS, NOT_EQUALS, LESS_THAN, LESS_THAN_OR_EQUALS, GREATER_THAN, and GREATER_THAN_OR_EQUALS.
// Password confirmation
form.addFormValidator(
new CompareValidator("password", "confirmPassword",
CompareValidator.Operation.EQUALS)
.withMessage("Passwords do not match")
);
// Date range validation
form.addFormValidator(
new CompareValidator("startDate", "endDate",
CompareValidator.Operation.LESS_THAN)
.withMessage("Start date must be before end date")
);Benefits
Asynchronous, Same-Page Processing
OorianForm submits asynchronously without a page reload. Process the data on the server and update any element on the page to show results, errors, or confirmation—all within the same page.
Type-Safe Parameters
The Parameters API provides typed accessors like getParameterValueAsInt() and getParameterValueAsBoolean(), eliminating manual parsing and type conversion.
Server-Side Validation
Validate submissions with Java code on the server with full access to your domain logic, database, and business rules. No need to duplicate validation in JavaScript.
Fluent Validation API
Chain validation rules with a readable fluent API—required(), email(), minLength(), pattern(), and ten more built-in validators. Rules are evaluated in order with automatic error display.
Cross-Field Validation
CompareValidator handles relationships between fields—password confirmation, date ranges, and numeric comparisons—without writing custom validation logic.
Clean Separation
The FormListener pattern cleanly separates form construction from submission handling, keeping your code organized and testable.