Skip to content

Creating a new field

Patrick Sachs edited this page Sep 22, 2018 · 13 revisions

Basic Setup

Creating new fields in react-formilicious is rather straight forward. Let's walk through the creation of a simple ToggleField. It works just like a checkbox, just more stylish!

At it's core fields are just React Components. So let's create a component for our ToggleField.

// my-own-fields/ToggleField.js
import * as React from "react";

export default class ToggleField extends React.Component {
  
}

Let's just add the bare minimum for our field to actually be recognizable as a field for Formilicious:

// my-own-fields/ToggleField.js
import * as React from "react";

export default class ToggleField extends React.Component {
  static getDefaultValue() {
    return false;
  }

  render() {
    return (<div>I am a Formilicious field!</div>);
  }
}

The getDefaultValue function is called in case our data prop in the form did not have a value for the field.

Let's add it to a form somewhere in our project:

// index.js
import ToggleField from './my-own-fields/ToggleField';

<Form
  data={{}}
  onSubmit={data => alert(JSON.stringify(data, null, 2))}
  elements={[
    {
      type: ToggleField,
      key: "newsletter"
    }
  ]} />

Hit "Submit", and we see the following:

Fair enough, that's pretty much what we expected to get.

Changing & displaying the value

While showing some static text is really neat, let's start extending this functionality by displaying the current value. We can get the current value of the field by using the value prop.

// my-own-fields/ToggleField.js
render() {
  const { value } = this.props;
  return (<div>I am a Formilicious field! My value is <strong>{value.toString()}</strong>.</div>);
}

That's some progess. Now it wouldn't be much of a form field if we couldn't change it. Let's add a way to do this.

// my-own-fields/ToggleField.js
render() {
  const { value, onChange } = this.props;
  return (<div className="field has-addons">
    <p className="control">
      <a className={value ? "button is-info" : "button"} onClick={() => onChange(true)} disabled={value}>
        <span>πŸ¦„ Yes</span>
      </a>
    </p>
    <p className="control">
      <a className={value ? "button" : "button is-info"} onClick={() => onChange(false)} disabled={!value}>
        <span>No πŸ‘Ή</span>
      </a>
    </p>
  </div>);
}

We use the onChange function passed as a prop to submit the new value to our form. Calling this function will run the field validators, and call the optional onChange function passed to the form.

Hint!

Your fields can also return promises. The value will then be updated once the Promise resolves. Learn more about promises in fields in the props table on the start page.

Aesthetic Perfection

Let's finish up with some final aesthetic touches: The user will want to know the name of the field they are currently editing, as well as see the validation result of the field.

// index.js
elements={[
  {
    type: ToggleField,
    key: "newsletter",
    name: <span>Subscribe to our <em>awesome</em> newsletter?</span>,
    validator: required("You MUST subscribe to our totally-not-spam newsletter! πŸ“¨")
  }
]}
// my-own-fields/ToggleField.js
import ValidationResult from "@react-formilicious/core/validators/ValidationResult";

render() {
  const { value, name, onChange, field } = this.props;
  return (<div className="field">
    <label className="label">{name}</label>
    <div className="field has-addons">
      <p className="control">
        <a className={value ? "button is-info" : "button"} onClick={() => onChange(true)} disabled={value}>
          <span>πŸ¦„ Yes</span>
        </a>
      </p>
      <p className="control">
        <a className={value ? "button" : "button is-info"} onClick={() => onChange(false)} disabled={!value}>
          <span>No πŸ‘Ή</span>
        </a>
      </p>
    </div>
    <ValidationResult {...field} />
  </div>);

Besides adding new properties to the element in the form we adjusted the renderer of the field to account for the new properties:

  • Get the name property of our field and display it in a label (Hint: All properties in your element will be passed to your field, so feel free to go wild with customization options!)
  • And use the <ValidationResult /> to display the validation result of our field, which is in the field prop(Among with some other things).

We're done! πŸŽ‰

We now have a simple toggle field allowing us to toggle between two boolean values. Take a look at some of the included default fields under /src/fields for some more advanced concepts and some information about which properties react-formilicious inserts into your fields.

If some things didn't work out for you at some point or you'd like to toy around with this field a bit, simply clone the repository. The field is included under the /example project.