Handle submission
Now your first form is almost ready. There is only one little thing missing and that is the data processing when the form is submitted.
Submit event
To process the values on submission, you need to pass a function to the onSubmit$ property of the Form component. The first parameter passed to the function contains the validated form values.
import { Field, Form, type SubmitHandler, useForm$ } from '@formisch/qwik';
import { component$ } from '@qwik.dev/core';
import * as v from 'valibot';
const LoginSchema = v.object({
email: v.pipe(v.string(), v.email()),
password: v.pipe(v.string(), v.minLength(8)),
});
export default component$(() => {
const loginForm = useForm$({
schema: LoginSchema,
});
const handleSubmit: SubmitHandler<typeof LoginSchema> = (values) => {
// Process the validated form values
console.log(values); // { email: string, password: string }
};
return (
<Form of={loginForm} onSubmit$={handleSubmit}>
{/* Form fields will go here */}
</Form>
);
});The SubmitHandler type ensures type safety for your submission handler, automatically inferring the types of validated values from your schema.
Prevent default
When the form is submitted, event.preventDefault() is executed by default to prevent the window from reloading so that the values can be processed directly in the browser and the state of the form is preserved.
Loading state
While the form is being submitted, you can use loginForm.isSubmitting.value to display a loading animation and disable the submit button:
<button type="submit" disabled={loginForm.isSubmitting.value}>
{loginForm.isSubmitting.value ? 'Submitting...' : 'Login'}
</button>The form store also provides other reactive properties like isSubmitted, isValidating, isTouched, isDirty, isValid, and errors for tracking form state. Note that errors only contains validation errors at the root level of the form — to get all errors from all fields, use the getAllErrors method.
Async submission
The submit handler can be asynchronous, allowing you to perform API calls or other async operations:
const handleSubmit: SubmitHandler<typeof LoginSchema> = async (values) => {
try {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(values),
});
if (response.ok) {
// Handle successful login
console.log('Login successful!');
} else {
// Handle error
console.error('Login failed');
}
} catch (error) {
console.error('Error during submission:', error);
}
};Next steps
Congratulations! You've learned the core concepts of building forms with Formisch. To learn more about advanced features, check out the form methods guide to discover how to programmatically control your forms.