Skip to content

Modus-Logo-Long-BlackCreated with Sketch.

  • Services
  • Work
  • Blog
  • Resources

    OUR RESOURCES

    Innovation Podcast

    Explore transformative innovation with industry leaders.

    Guides & Playbooks

    Implement leading digital innovation with our strategic guides.

    Practical guide to building an effective AI strategy
  • Who we are

    Our story

    Learn about our values, vision, and commitment to client success.

    Open Source

    Discover how we contribute to and benefit from the global open source ecosystem.

    Careers

    Join our dynamic team and shape the future of digital transformation.

    How we built our unique culture
  • Let's talk
  • EN
  • FR

Ext JS to React: Form Validations

Published on March 1, 2018
Last Updated on April 8, 2021
Application Development

This is part of the Ext JS to React blog series. You can review the code from this article on the Ext JS to React Git repo.

Form validation creates input boundaries / requirements for data entry. Form validation in Ext JS is handled by normalizing the validation work within the form fields components. With HTML5’s form fields (IE10+), we can let the inputs handle much of the validation work for us. Let’s look at an example of how we might author a custom React field component to display the form fields’ validation messages in the UI.

Note: While not a requirement for React, this article’s code examples assume you’re starting with a starter app generated by create-react-app.

Custom Form Field

First, let’s define a custom Field class where the field type and other particular can be passed in or use a predefined default. We’ll also look at incorporating some layout help from the Pure CSS package.

npm install --save purecss

The Field class:

import React, { Component } from 'react';
import '../node_modules/purecss/build/base.css';
import '../node_modules/purecss/build/forms.css';
import './Field.css';

class Field extends Component {
  static defaultProps = {
    value: '',
    type: 'text'
  }
  state = {
    invalidMsg: null,
    value: this.props.value
  }

  render () {
    const {
      label,
      onChange
    } = this.props;
    const { value, invalidMsg } = this.state;
    const inputProps = {
      ...this.props,
      value,
      onChange: (e) => this.handleChange(e, onChange)
    };
    return (
      <div className="pure-control-group">
        <label>{label}
          <input {...inputProps} style={{minWidth: '200px'}} />
          {
            invalidMsg ? 
              <span className="pure-form-message-inline">{invalidMsg}</span> : 
            null
          }
        </label>
      </div>
    );
  }
  
  handleChange (e, onChange) {
    this.setState({
      value: e.target.value
    });
    this.validateField(e);
    if (onChange && typeof onChange === 'function') {
      onChange(e);
    }
  }
  validateField (e) {
    const { target } = e,
          { validity } = target,
          { valueMissing, valid } = validity;
    let   invalidMsg;
 
    if (valueMissing) {
      invalidMsg = 'This is a required field';
    } else if (!valid) {
      invalidMsg = this.props.invalidMsg || target.validationMessage;
    }
    this.setState({ invalidMsg });
  }
}

export default Field;

We can then use the Field component in our App view:

class App extends Component {
  render() {
    return (
      <div>
        <Field
          required
          name="test"
          label="required text field "
          onChange={(e) => console.log('change', e)}
        /><br/>
        <Field
          type="number"
          max={20}
          name="test"
          label="number field (20 max) "
          onChange={(e) => console.log('change', e)}
        />
      </div>
    )
  }
}

export default App;
Ext JS to React: Form Validations

Custom Form Field Explained

That’s a good chunk of code. Let’s break down what we’re doing here. At the top we have our imports, including React and the CSS we’ll use to style the form on the page. For this example, we’re using the Pure CSS library to add a little bit of styling / layout support for our form elements. You’ll see the Pure CSS classes used as className values in our component’s JSX returned from the render method. In addition, we’ll add a bit of styling in our own {appRoot}/src/Field.css file that will make our validation message red:

input:invalid + .pure-form-message-inline {
  color: #c61c06;
}

Custom Form Field Class Methods

handleChange

  • For each input change we’ll first set the value on our component state giving us our controlled component
  • Next, we’ll call our validateField method which will add the invalid message to the UI if applicable
  • Finally, we’ll call any onChange handler that may have been passed in as a prop when the field component was instantiated

validateField

  • Initially, we collect up a few variables
    • target is the <input> field element we’re validating
    • validity is the ValidityState object of the input field
    • valueMissing will be true if our field is a required field and has no value
    • valid is false if the input is invalid for any reason
  • If the field is required and missing a value we’ll display our own message, else we’ll display the validation message from the field itself
  • Finally, we set the validation message on the component’s state. This will cause the component to re-render and display the validation error if one was discovered.

render

  • First, we extract a number of const variables from the props and the state object to be used as values in our rendered elements
  • Next, the props passed in along with the id, value from the component’s state, and the onChange handler are added to a props object to be passed to the input field of our output JSX
  • Finally, we output our field’s HTML elements using the component’s state / props:
    • A wrapping div used to create rows of input elements (versus inline)
    • A label for our input field
    • The input element with the type passed in as a prop (defaults to type “text”)
    • The span used to display the validation message (only rendered if invalidMsg has been passed in or set by our component’s validateField method)

Wrap Up

The above custom validation solution leverages the HTML5 properties only available to select browsers. So, what if you need to support older browsers such as IE9 and before? Instead of reading from the fields’ built in validation messages / state you could add your own validation logic and messaging logic. The Joi package is a popular validation package that could be used in place of HTML5 validations in your React projects. React-form and Formik are two popular form packages which provide their own form field validation, allowing you to define the validation schema and error message for each form field.

Posted in Application Development
Share this

Seth Lemmons

Seth Lemmons is a Senior Front End Engineer at Modus Create. Seth has devoted several years to learning Ext JS. He has spent the last 10 years building and supporting web applications with an eye for excellent user experience. Outside of work and a young family Seth has very little free time to just do what he wants. But, if he did have some extra time he'd kinda be into learning vector illustration. And someday he hopes to play video games again.
Follow

Related Posts

  • Ext JS to React: Form Submission
    Ext JS to React: Form Submission

    This is part of the Ext JS to React blog series. You can review the…

  • React Landing
    Ext JS to React: Migration to Open Source

    Worried about Migrating from Ext JS? Modus has the Answers Idera’s acquisition of Sencha has…

Want more insights to fuel your innovation efforts?

Sign up to receive our monthly newsletter and exclusive content about digital transformation and product development.

What we do

Our services
AI and data
Product development
Design and UX
IT modernization
Platform and MLOps
Developer experience
Security

Our partners
Atlassian
AWS
GitHub
Other partners

Who we are

Our story
Careers
Open source

Our work

Our case studies

Our resources

Blog
Innovation podcast
Guides & playbooks

Connect with us

Get monthly insights on AI adoption

© 2025 Modus Create, LLC

Privacy PolicySitemap
Scroll To Top
  • Services
  • Work
  • Blog
  • Resources
    • Innovation Podcast
    • Guides & Playbooks
  • Who we are
    • Our story
    • Careers
  • Let’s talk
  • EN
  • FR