📜 ⬆️ ⬇️

Validation of forms in React

If you have ever used the AngularJS framework, then you know how easily forms are validated in it. However, in React, the situation is somewhat worse. It is understandable, because it is just a library. But thanks to the community from this library you can make a powerful tool for creating full-fledged SPA-applications. At the moment, created a huge variety of components that can meet most of the needs of developers on React. In this article, I would like to describe the approach that I used to validate forms using the Formsy-react component .

To begin with, there are quite a few components for form validation (32 is represented here ). I tried some of them and decided to stop at Formsy, since it didn’t look too sophisticated and yet quite flexible. The principle of operation I will show the example of the login form. In order not to bother with styles, we will use react-bootstrap.

In the test application, login is possible in 3 ways: by login, email or phone number. Accordingly, for each type of login you need your own specific validations. For simplicity of the example, I will show only the component with the login form, you can find a link to the project repository at the end of the article.

So, we have a component Login, which is responsible for our form. It has 3 different login methods, respectively, it would be convenient to display them using tabs:
')
Source code tabs with input fields
<Tab.Pane eventKey="login"> <Formsy.Form onValidSubmit={this.handleLogin} onValid={this.enableButton} onInvalid={this.disableButton}> <FormGroup> <ControlLabel>Login</ControlLabel> <TextInput name="login" type="text" validations={{minLength: 5}} validationErrors={{minLength: 'Enter at least 5 sumbols'}} required/> </FormGroup> <FormGroup> <ControlLabel>Password</ControlLabel> <TextInput name="loginPassword" type="password" validations={{strongPassword: validations.strongPassword}} validationErrors={{strongPassword: "Enter a strong password! At least 6 symbols"}} required/> </FormGroup> <FormGroup> <Button type="submit" bsStyle="primary" disabled={!this.state.isButtonEnabled} block>Login</Button> </FormGroup> </Formsy.Form> </Tab.Pane> <Tab.Pane eventKey="email"> <Formsy.Form onValidSubmit={this.handleLogin} onValid={this.enableButton} onInvalid={this.disableButton}> <FormGroup> <ControlLabel>Email</ControlLabel> <TextInput name="email" type="text" validations={{isGoogleEmail: validations.isGoogleEmail}} validationErrors={{isGoogleEmail: 'Only Gmail boxes are accepted'}} required/> </FormGroup> <FormGroup> <ControlLabel>Password</ControlLabel> <TextInput name="loginPassword" type="password" validations={{strongPassword: validations.strongPassword}} validationErrors={{strongPassword: "Enter a strong password! At least 6 symbols"}} required/> </FormGroup> <FormGroup> <Button type="submit" bsStyle="primary" disabled={!this.state.isButtonEnabled} block>Login</Button> </FormGroup> </Formsy.Form> </Tab.Pane> <Tab.Pane eventKey="phone"> <Formsy.Form onValidSubmit={this.handleLogin} onValid={this.enableButton} onInvalid={this.disableButton}> <FormGroup> <ControlLabel>Phone</ControlLabel> <TextInput name="phone" type="tel" validations={{isPhoneNumber: validations.isPhoneNumber, containsPlusPrefix: validations.containsPlusPrefix}} validationErrors={{isPhoneNumber: 'You should enter a valid phone number', containsPlusPrefix: 'Enter your number without +'}} required/> </FormGroup> <FormGroup> <ControlLabel>Password</ControlLabel> <TextInput name="phonePassword" type="password" validations={{strongPassword: validations.strongPassword}} validationErrors={{strongPassword: "Your password should contain at least 1 number, 1 lowercase letter, 1 uppercase letter"}} required/> </FormGroup> <FormGroup> <Button type="submit" bsStyle="primary" disabled={!this.state.isButtonEnabled} block>Login</Button> </FormGroup> </Formsy.Form> </Tab.Pane> 


Each tab is a form, inside which there are 2 fields and a button to send the form.

Let's start in order, with the Formsy.Form component. We are interested in 3 properties (props): onValidSubmit, onValid, onInvalid.

The onValidSubmit property is responsible for submitting the form. If all the data is entered correctly and the user presses the login button, the function this.handleLogin is called, which sends the data to the server. This function should have one parameter that will contain the object. This object stores the names of the fields and their values.

The onValid and onInvalid properties are responsible for the state of the submit button. They should be passed a function that will enable or disable the button depending on the correctness of the entered data.

Next, we have fields that need to be checked for validity of the entered data. For the normal functioning of this component, we need to create our own component for data entry (TextInput). On the Formsy website, you can find a ready-made component that includes everything you need and requires a minimum of changes before use. In our component, you must pass all the standard properties for the input tag, such as type, etc., as well as several special properties that will help with the validation of the component.

The first such property is name. When the user clicks the send data button, you can easily get the desired input by name, as well as its value.

You also need to designate the validations property The object is expected in this property. The Formsy component already contains some validations, for example, minLength, which I used in the login field. It is not difficult to guess that with the help of this check we can set the minimum number of characters entered. There are many other built-in validations, for example, to verify the correctness of an email address, telephone number and others. However, this component would not be so good if you could not create your own validation functions. And it is possible!

For example, in the email input field I announced my own verification that a person enters an email address registered on gmail.com. The verification function is as follows:

Source code verification function
 function isGoogleEmail(values, value) { if (typeof value !== 'undefined' && value.indexOf('gmail.com') === -1) { return false; } return true; } 


The function takes 2 parameters: all form fields and the current field that is being tested. The first parameter contains an array of all fields and their values ​​that are present in the form. The second parameter value contains the contents of the current field. Inside the function it is necessary to check whether value exists, as well as to make any other checks. If the function returns false, then the check failed and the user will not be able to submit the form. In the opposite case, everything is OK, this field has been tested and contains no errors.

The second property we need to pass to the input field is validationErrors. The beauty of this property is that for each error it will produce its own message. Thus, it is possible to hang different checks on one field (for example, the number of characters entered, the presence of at least one special character, etc.) and for each of these checks give its own error (and not write in one message that the field should contain at least 8 characters, 2 numbers, 3 letters, etc.). This approach is used in the phone entry field, where a “super reliable check” first occurs that the entered text is indeed a phone, and then it is checked whether the beginning of the '+'.

Thus, this component helps a lot with form validation, which is so lacking in React. You can see the full code of this example in this repository , and also do not forget to look into the Formsy repository, there are a lot of interesting things there. I hope that the article will help you when creating your application.

Thanks for attention!

Source: https://habr.com/ru/post/306512/


All Articles