In the previous article we have seen what is WebAtoms Form
. If you haven't seen it, I strongly recommend reading that article.
Today, we will highlight further enhancements and development made to this component.
Applications use forms to enable users to log in, update a profile, enter sensitive information, and perform many other data-entry tasks.
WebAtoms
provides two different approaches to handling user input through forms and without forms.
Let's learn how to build a small screen without the Form
component.
Form without Form component?
<FormField
label="Name: "
required={true}
error={Bind.oneWay(() => this.viewModel.errorContact)}>
<input
type="text"
value={Bind.twoWaysImmediate(() =>
this.viewModel.model.firstName)}
placeholder="First Name" />
</FormField>
<FormField
error={Bind.oneWay(() => this.viewModel.errorEmail)}
label="Email Address:"
required={true}>
<input
type="text"
value={Bind.twoWaysImmediate(() =>
this.viewModel.model.emailAddress)} />
</FormField>
<CommandRow>
<FAButton
icon="fad fa-plus"
eventClick={Bind.event(() => this.viewModel.save())}
text="Save" />
</CommandRow>
ViewModel validations and save button code sample is as shown below:-
@Validate
public get errorContact() {
return this.model.firstName ?
"" : "First name is required";
}
@Validate
public get errorEmail(): string {
const em = (this.model.emailAddress)?.trim();
if (!em) {
return "Email address cannot be empty";
}
if (em.includes(" ")) {
return "Email address cannot contain space";
}
if (!em.includes("@")) {
return "Invalid email address";
}
return "";
}
@Action({ validate: true })
public async save() {
// save api
}
The code snippet explains how to get an alert text message (in red color) underneath the input box when running this code in the browser. The get method helps us write multiple validations.
The important points to keep in mind while working with FormField
without adding the Form component.
We must define the get method with the
@validate
attribute in the ViewModel.We don't have to enclose FormField inside the Form component.
The save button click event must have the @Action attribute with the validate property to true. This will trigger the
ViewModel
validations before actually firing the button event and report errors (if any) to the user.The
required
attribute ofFormField
must be set to true.
Now let's discuss the improvements/enhancements in the form components.
How to use the Form with eventSubmit and data-event?
<Form eventSubmit={Bind.event(() => this.viewModel.save())}>
<FormField
label="Name: "
required={true}
error={Bind.oneWay(() => this.viewModel.model.firstName ?
"" : "First name is required")}>
<input
type="text"
value={Bind.twoWaysImmediate(() =>
this.viewModel.model.firstName)}
placeholder="First Name" />
</FormField>
<FormField
error={Bind.oneWay(() => this.viewModel.model.emailAddress ?
"" : "Email address is required")}
label="Email Address:"
required={true}>
<input
type="text"
value={Bind.twoWaysImmediate(() =>
this.viewModel.model.emailAddress)} />
</FormField>
<CommandRow>
<FAButton
icon="fad fa-plus"
data-event="submit"
text="Save" />
</CommandRow>
</Form>
- Every
FormField
and submit button must be inside the Form component. - We can define the inline error validations in the TSX file.
- In this case, we will not use the @validate attribute on the method.
The form component must have the
event submit
property to bind the event. - Our button must have the
data-event
attribute to submit theForm
. Like data-event="submit". The value submit is not case-sensitive.
How to Add multiple Forms?
you can't nest forms on a single page. You can't nest forms
because then the forms
aren't able to identify which fields are for what.
But, sometimes client design demands the use of multiple forms. For E.g. we may have details to be filled up in multiple tabs or sections like phone number sections, Addresses sections, and formal detail sections.
In this case, we can have multiple forms with a single submit button.
How to write code for multiple Forms?
<AtomToggleView>
<ToggleView>
<Form>Basic Form </Form>
</ToggleView>
<ToggleView>
<Form>Phone number Form </Form>
</ToggleView>
<ToggleView>
<Form>Address Form </Form>
</ToggleView>
</AtomToggleView>
`
How to define the validation in multiple Forms?
<FormField
error={Bind.oneWay(() =>
this.viewModel.errorContact)}
label="Contact:"
required={true}>
<input
type="text"
value={Bind.twoWaysImmediate(() =>
this.viewModel.model.contact)}>
</>
</FormField>
We need to define all validations (Basic, phone number, address validation) in ViewModel.
@Validate
public get errorContact(): string {
return this.model.firstName ?
"" : "First name cannot be empty";
}
The above get method allows us to validate the input field.
We need to keep in mind that the Submit button should be outside the forms. meaning we should have a single button client event (submit) for all the multiple Forms
<FAButton
class="next-button"
text="Save"
eventClick={Bind.event(() =>
this.viewModel.save())}
/>
@Action({ validate: true })
public async save() {
this.model = await this.contactService.save(this.model);
this.close(this.model);
}
Summarization.
- We can also get the error messages without encapsulating the FormField inside the Form Component. We have to define the validation error in ViewModel, and the button must have the
eventClick
to submit the form. - If we define the inline error messages, they will get fired as soon as the forms get loaded.
- When we are encapsulating the FormField inside the Form component, We have to bind the
eventSubmit
event of the form. (like save update delete edit operation). The button should be inside the Form component. It must have thedata-event
attribute to submit.
Like | Comment | Save | Share |