Reactjs - Form input validation

前端 未结 9 1932
悲哀的现实
悲哀的现实 2020-11-28 20:04

My Contact page form is as follows,

<
相关标签:
9条回答
  • 2020-11-28 20:58
    import React from 'react';
    import {sendFormData} from '../services/';
    
    class Signup extends React.Component{
      constructor(props){
        super(props);
         this.state = {
           isDisabled:true
         }                                                                                                 
         this.submitForm = this.submitForm.bind(this);
      }
      validateEmail(email){
       const pattern = /[a-zA-Z0-9]+[\.]?([a-zA-Z0-9]+)?[\@][a-z]{3,9}[\.][a-z]{2,5}/g;
       const result = pattern.test(email);
       if(result===true){
         this.setState({
           emailError:false,
           email:email
         })
       } else{
         this.setState({
           emailError:true
         })
       }
     }
     handleChange(e){
      const target = e.target;
      const value = target.type === 'checkbox' ? target.checked : target.value;
      const name = target.name;
      this.setState({
        [name]: value
      });
      if(e.target.name==='firstname'){
        if(e.target.value==='' || e.target.value===null ){
          this.setState({
            firstnameError:true
          })
        } else {
          this.setState({
            firstnameError:false,     
            firstName:e.target.value
          })
        }
      }
      if(e.target.name==='lastname'){
        if(e.target.value==='' || e.target.value===null){
          this.setState({
            lastnameError:true
          })
        } else {
          this.setState({
            lastnameError:false,
            lastName:e.target.value
          })
        }
      }
      if(e.target.name==='email'){
       this.validateEmail(e.target.value);
      }
      if(e.target.name==='password'){
        if(e.target.value==='' || e.target.value===null){
          this.setState({
            passwordError:true
          })
        } else {
          this.setState({
            passwordError:false,
            password:e.target.value
          })
        }
     }
     if(this.state.firstnameError===false && this.state.lastnameError===false && 
      this.state.emailError===false && this.state.passwordError===false){
        this.setState({
          isDisabled:false
        })
     }
    }
    submitForm(e){
      e.preventDefault();
      const data = {
       firstName: this.state.firstName,
       lastName: this.state.lastName,
       email: this.state.email,
       password: this.state.password
      }
      sendFormData(data).then(res=>{
        if(res.status===200){
          alert(res.data);
          this.props.history.push('/');
        }else{
    
        } 
      });
     }
    render(){
    return(
      <div className="container">
        <div className="card card-login mx-auto mt-5">
          <div className="card-header">Register here</div>
            <div className="card-body">
                <form id="signup-form">
                  <div className="form-group">
                    <div className="form-label-group">
                      <input type="text" id="firstname" name="firstname" className="form-control" placeholder="Enter firstname" onChange={(e)=>{this.handleChange(e)}} />
                      <label htmlFor="firstname">firstname</label>
                      {this.state.firstnameError ? <span style={{color: "red"}}>Please Enter some value</span> : ''} 
                    </div>
                  </div>
                  <div className="form-group">
                    <div className="form-label-group">
                      <input type="text" id="lastname" name="lastname" className="form-control" placeholder="Enter lastname" onChange={(e)=>{this.handleChange(e)}} />
                      <label htmlFor="lastname">lastname</label>
                      {this.state.lastnameError ? <span style={{color: "red"}}>Please Enter some value</span> : ''}
                    </div>
                  </div>
                  <div className="form-group">
                    <div className="form-label-group">
                      <input type="email" id="email" name="email" className="form-control" placeholder="Enter your email" onChange={(e)=>{this.handleChange(e)}} />
                      <label htmlFor="email">email</label>
                      {this.state.emailError ? <span style={{color: "red"}}>Please Enter valid email address</span> : ''}
                    </div>
                  </div>                
                  <div className="form-group">
                    <div className="form-label-group">
                      <input type="password" id="password" name="password" className="form-control" placeholder="Password" onChange={(e)=>{this.handleChange(e)}} />
                      <label htmlFor="password">Password</label>
                      {this.state.passwordError ? <span style={{color: "red"}}>Please enter some   value</span> : ''}
                    </div>
                  </div>                
                  <button className="btn btn-primary btn-block" disabled={this.state.isDisabled} onClick={this.submitForm}>Signup</button>
                </form>
            </div>
          </div>
        </div>
      );
     }
    }
    export default Signup;
    
    0 讨论(0)
  • 2020-11-28 20:58

    Cleaner way is to use joi-browser package. In the state you should have errors object that includes all the errors in the form. Initially it shoud be set to an empty object. Create schema;

    import Joi from "joi-browser";
    schema = {
        username: Joi.string()
          .required()
          .label("Username")
          .email(),
        password: Joi.string()
          .required()
          .label("Password")
          .min(8)
          .regex(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,1024}$/) //special/number/capital
       };
    

    Then validate the form with the schema:

    validate = () => {
        const options = { abortEarly: false };
        const result = Joi.validate(this.state.data, this.schema, options);
        console.log(data) // always analyze your data
        if (!result.error) return null; 
        const errors = {};
        for (let item of result.error.details) errors[item.path[0]] = item.message; //in details array, there are 2 properties,path and message.path is the name of the input, message is the error message for that input.
        return errors;
      };
    

    Before submitting the form, check the form:

    handleSubmit = e => {
        e.preventDefault();
        const errors = this.validate(); //will return an object
        console.log(errors);
        this.setState({ errors: errors || {} }); //in line 9 if we return {}, we dont need {} here
        if (errors) return;
        //so we dont need to call the server
        alert("success");
        //if there is no error call the server
        this.dosubmit();
      };
    
    0 讨论(0)
  • 2020-11-28 21:01

    I've taken your code and adapted it with library react-form-with-constraints: https://codepen.io/tkrotoff/pen/LLraZp

    const {
      FormWithConstraints,
      FieldFeedbacks,
      FieldFeedback
    } = ReactFormWithConstraints;
    
    class Form extends React.Component {
      handleChange = e => {
        this.form.validateFields(e.target);
      }
    
      contactSubmit = e => {
        e.preventDefault();
    
        this.form.validateFields();
    
        if (!this.form.isValid()) {
          console.log('form is invalid: do not submit');
        } else {
          console.log('form is valid: submit');
        }
      }
    
      render() {
        return (
          <FormWithConstraints
            ref={form => this.form = form}
            onSubmit={this.contactSubmit}
            noValidate>
    
            <div className="col-md-6">
              <input name="name" size="30" placeholder="Name"
                     required onChange={this.handleChange}
                     className="form-control" />
              <FieldFeedbacks for="name">
                <FieldFeedback when="*" />
              </FieldFeedbacks>
    
              <input type="email" name="email" size="30" placeholder="Email"
                     required onChange={this.handleChange}
                     className="form-control" />
              <FieldFeedbacks for="email">
                <FieldFeedback when="*" />
              </FieldFeedbacks>
    
              <input name="phone" size="30" placeholder="Phone"
                     required onChange={this.handleChange}
                     className="form-control" />
              <FieldFeedbacks for="phone">
                <FieldFeedback when="*" />
              </FieldFeedbacks>
    
              <input name="address" size="30" placeholder="Address"
                     required onChange={this.handleChange}
                     className="form-control" />
              <FieldFeedbacks for="address">
                <FieldFeedback when="*" />
              </FieldFeedbacks>
            </div>
    
            <div className="col-md-6">
              <textarea name="comments" cols="40" rows="20" placeholder="Message"
                        required minLength={5} maxLength={50}
                        onChange={this.handleChange}
                        className="form-control" />
              <FieldFeedbacks for="comments">
                <FieldFeedback when="*" />
              </FieldFeedbacks>
            </div>
    
            <div className="col-md-12">
              <button className="btn btn-lg btn-primary">Send Message</button>
            </div>
          </FormWithConstraints>
        );
      }
    }
    

    Screenshot:

    This is a quick hack. For a proper demo, check https://github.com/tkrotoff/react-form-with-constraints#examples

    0 讨论(0)
提交回复
热议问题