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 Fields

Published on February 27, 2018
Last Updated on April 23, 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.

By this time in the Ext JS to React series you may find yourself asking, “So, is now a good time to talk about form fields?” It sure is! Forms are a primary way for end users to supply feedback through our web applications, so they’re used a lot in the real world. Ext JS includes a number of form fields within the framework designed to make form layouts, validation, and submission easier. Before getting into handling the user input, let’s first take a look at how to create the form fields themselves using React.

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.

Input / Textfield

Ext JS provides a number of text input fields that can be fairly easily replicated in React using the various input types. A number of these are HTML 5 and supported on IE10+ but will require a different strategy if your supported browser base is lower than IE10. The input field type is created using the xtype of “textfield”. Other input types such as “password”, “url”, and “search” have their own xtypes / classes: passwordfield (Ext.field.Password), urlfield (Ext.field.Url), and searchfield (Ext.field.Search). When defining forms in React, you can use the native HTML types:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  render() {
    return (
      <form className="login-form">
        <input type="text" /><br />
        <input type="password" /><br />
        <input type="url" /><br />
        <input type="search" /><br />
      </form>
    );
  }
}

export default App;
Ext JS to React: Form Fields, Field

Note: A number of the Ext JS input field config options have HTML attribute counterparts that can be used when defining input fields in React. One attribute of note is the value. In plain HTML, <textarea> and <select><option> do not use value to set their initial value. However, React normalizes this for you, allowing all three input options to be initially set using a value="" prop.

You can review the sample code on the Git repo.

Textarea

A textarea with 4 rows in React:

import React from 'react';
import './App.css';

export default () => <textarea rows="4"/>;
Ext JS to React: Form Fields, Text Area

You can review the sample code on the Git repo.

Selectfield

The Ext JS combobox (Ext.field.ComboBox) is somewhat of a mashup of the native <select> and <input> field. A combobox configured with editable: false is comparable to a <select> field. In React, you can return a select field with option elements for each eligible choice from the select component’s options array:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  state = {
    value: '_default'
  };
  options = ['Solids', 'Stripes']
  render() {
    return (
      <select
        value={this.state.value}
        onChange={e => this.handleSelectChange(e)}
      >
        {[
          <option disabled key="_default" value="_default">
            select one...
          </option>,
          ...this.options.map(
            item => (
              <option key={item} value={item.toLowerCase()}>{item}</option>
            )
          )
        ]}
      </select>
    );
  }
  handleSelectChange (e) {
    this.setState({
      value: e.target.value
    });
  }
}

export default App;

The above example introduces a couple of nuances. The onChange event handler serves a couple of purposes. First, without an onChange handler, when you define a field with a value=, the select field will be rendered as readonly. Second, the change handler sets the value of the select field via the React component’s internal state by having the value derived from the state initially.

Ext JS to React: Form Fields, Select
<select value={this.state.value} //...

This circular setup is what is known as a controlled component. It is the recommended path, as the value of the field is then settable by the user or any mechanism that has access to the component state. For information on “uncontrolled” components see React’s documentation.

You can review the sample code on the Git repo.

Combobox

To present a list of possible choices, but also allow any user input provided, you can omit the editable config option in the Ext JS example. To provide the same suggestion list, but still allow user input, have your React component return an <input> field using the list attribute along with a datalist (IE10+ and unsupported in Safari). This provides the added benefit of datalist filtering as the user types:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  state = {
    color: ''
  };
  options = ['Red', 'Blonde', 'Brown', 'Black']

  render() {
    return (
      <div>
        <input
          value={this.state.color}
          list="hair-color"
          onChange={e => this.handleChange(e)}
        />
        <datalist id="hair-color">
          {[this.options.map(
            item => <option key={item} value={item} />
          )]}
        </datalist>
      </div>
    );
  }

  handleChange(e) {
    this.setState({
      color: e.target.value
    });
  }
}

export default App;
Ext JS to React: Form Fields, Combo Box

You can review the sample code on the Git repo.

Range / Slider

The slider (Ext.slider.Single) field is comparable to the range field (IE10+) we’ll return from the React example. Let’s initialize the field with a value of 50, a minimum value of 0, a maximum value of 100, and an increment / step of 10.

import React, { Component } from 'react';
import './App.css';

class App extends Component {
 state = {
   value: 50
 };
 render() {
   return (
     <input
       onChange={e => this.handleChange(e)}
       type="range"
       value={this.state.value}
       min="0"
       max="100"
       step="10"
     />
   );
 }
 handleChange (e) {
   this.setState({
     value: e.target.value
   });
 }
}

export default App;
Ext JS to React: Form Fields, Slider

You can review the sample code on the Git repo.

Datefield

The datefield (Ext.field.Date) displays a calendar for easy selection of a day, month, and year. Displaying a calendar view for easy date selection is a bit less trivial in React than in Ext JS. You can use the input field of type date, but the implementation across browsers / platforms is incomplete. An example of the date input field in React is:

// npm install --save moment

import React, { Component } from 'react';
import moment from 'moment';

class App extends Component {
 state = {
   value: moment().format('YYYY-MM-DD')
 };
 render() {
   return <input
     type="date"
     value={this.state.value}
     onChange={e => this.handleChange(e)}
   />;
 }
 handleChange (e) {
   this.setState({
     value: e.target.value
   });
 }
}

export default App;
Ext JS to React: Form Fields, Date Field

The date type is not supported on IE or Safari. For additional cross-browser implementations, you may want to look at using a date field package like react-datepicker or react-dates Alternatively, you may want to consider a component library like kendo UI.

You can review the sample code on the Git repo.

Number / Spinner

In Ext JS there are two fields related to the input of numbers. The numberfield (Ext.field.Number) restricts the input to numeric entries only, while the spinnerfield (Ext.field.Spinner) adds up / down arrows in the field to enable users to increment and decrement the field value without explicitly entering a numeric value. An equivalent implementation of the spinner field (IE10+) in React would be:

import React, { Component } from 'react';

class App extends Component {
 state = {
   value: 50
 };
 render() {
   return <input
     type="number"
     value={this.state.value}
     onChange={e => this.handleChange(e)}
     step="10"
     min="0"
     max="100"
   />;
 }
 handleChange (e) {
   this.setState({
     value: e.target.value
   });
 }
}

export default App;
Ext JS to React: Form Fields, Number Field

You can review the sample code on the Git repo.

Radio

Radio fields (Ext.field.Radio) are defined with a shared name config with each field instance possessing a distinct value to pass on form submission. These are the same conventions used in HTML, as seen in the following React form with ‘red’, ‘blue’, and ‘green’ radio fields:

import React, { Component } from 'react';

class Radio extends Component {
 state = {
   checked: !!this.props.checked
 }
 render () {
   return <input
     type="radio"
     name={this.props.name}
     value={this.props.value}
     checked={this.state.checked}
     onChange={e => this.handleFieldChange(e)}
   />
 }
 handleFieldChange (e) {
   this.setState({
     checked: e.target.checked
   });
 }
}

export default Radio;

Our App class can now use the Radio class directly within a form:

import React, { Component } from 'react';
import Radio from './Radio';

class App extends Component {
 render () {
   const colorRadioName = 'color';
   return (
     <form>
       <label>
         Red
         <Radio name={colorRadioName} value="red" checked />
       </label>
       <br />
       <label>
         Blue
         <Radio name={colorRadioName} value="blue" />
       </label>
       <br />
       <label>
         Green
         <Radio name={colorRadioName} value="green" />
       </label>
     </form>
   );
 }
}

export default App;
Ext JS to React: Form Fields, Radio

Let’s talk a little about some of the other differences in this example. First, we’ve made a couple of allowances for the sake of brevity. We’ve left out the styling of the labels and inputs, and while normally each class would be defined in separate files, we’ve added both the radio component and the form to the same file. The radio component has been defined on its own since the type, change handler, and checked property will be the same across each radio instance. We then pass in the desired name, value, and checked value. The checked value passed (if at all) shows up on the radio component’s props object to then be set on the radio instance.

You can review the sample code on the Git repo.

Checkbox

Ext JS checkbox (Ext.field.Checkbox) fields are defined similar to radio fields, but have unique `name` configs. The React checkbox example is also very similar to our radiofield example where the name fields are unique per field:

import React, { Component } from 'react';

class Checkbox extends Component {
 state = {
   checked: !!this.props.checked
 }
 render () {
   return <input
     type="checkbox"
     name={this.props.name}
     value={this.props.value}
     checked={this.state.checked}
     onChange={e => this.handleFieldChange(e)}
   />
 }
 handleFieldChange (e) {
   this.setState({
     checked: e.target.checked
   });
 }
}

export default Checkbox;

Our App class can now use the Checkbox class:

import React, { Component } from 'react';
import Checkbox from './Checkbox';

class App extends Component {
 render () {
   return (
     <form>
       <label>
         Music
         <Checkbox name="music" value="music" checked />
       </label>
       <br />
       <label>
         Dance
         <Checkbox name="dance" value="dance" />
       </label>
     </form>
   );
 }
}

export default App;
Ext JS to React: Form Fields, Checkbox

You can review the sample code on the Git repo.

Toggle

The Ext JS togglefield (Ext.field.Toggle) is a stylized slider field that accepts only two values. The control has a slider element that is moved left to right when clicked / tapped. Using an existing example for reference, we’ll construct our toggle field’s HTML structure using a checkbox and its wrapping label for the form element. We’ll include a span that will operate as our visual control. First, we’ll define the toggle component:

import React, { Component } from 'react';
import './Toggle.css';

class Toggle extends Component {
 state = {
   checked: !!this.props.checked
 }
 render () {
   return (
     <label className="toggle-wrap">
       <div>{this.props.label}</div>
       <input type="checkbox"
         checked={this.state.checked}
         onChange={this.handleToggleChange}
       />
       <div className="toggle-el"></div>
     </label>
   );
 }
 handleToggleChange = (e) => {
   this.setState({
     checked: e.target.checked
   });
 }
}

export default Toggle;

Toggle CSS

With our React component created, we need to add the CSS that styles the toggle field’s UI. In this case, we’ll add it to an {appRoot}/src/Toggle.css file to be imported by the Toggle class.

.toggle-wrap {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}
.toggle-wrap input {display:none;}
.toggle-el {
  position: relative;
  cursor: pointer;
  border-radius: 34px;
  height: 100%;
  width: 100%;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}
.toggle-el:before {
  content: "";
  position: absolute;
  border-radius: 50%;
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .25s;
  transition: .25s;
}
input:checked + .toggle-el {
  background-color: #f32195;
  box-shadow: inset 0 -20px 37px 0px rgba(0, 0, 0, 0.36);
}
input:focus + .toggle-el {
  box-shadow: 0 0 1px #f32195;
}
input:checked + .toggle-el:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}

Our Toggle field can now be composed in our App:

import React, { Component } from 'react';
import Toggle from './Toggle';

class App extends Component {
 render () {
   return (
     <Toggle />
   );
 }
}

export default App;

This results in a checkbox field (that is hidden, but being toggled via its wrapping <label>) styled as a toggle control.

Ext JS to React: Form Fields, Toggle Field

You can review the sample code on the Git repo.

Wrap Up

In the above field examples we created a loop that populated the field value with either passed-in props or the value manually entered within the field. Often times, the form fields are wrapped by a <form> or some other container that can manage the field values at the container level. Hoisting the value-controlling code above the fields themselves sheds duplicate code, making maintenance of the “dumb” components a bit easier. With the overview of field pieces and parts complete, we’ll focus our attention in the next article on user input moderation using field validations.

Posted in Application Development
Share this

Mitchell Simoens

Mitchell Simoens is a Senior Front End Engineer at Modus Create. Mitchell has spent the last 10 years working with Ext JS including developing core functionality, Sencha Fiddle and (I hope your insurance covers blown minds) supporting the online community with over 40,000 posts on the Sencha Forums. Before working with Ext JS, Mitchell used Perl and PHP but loves spending time with Node JS for today's needs. When not working, you can find Mitchell relaxing with his wife and daughter, or developing his talents as an amateur furniture maker.
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