Skip to content

Integration with React

Roberto Prevato edited this page Mar 11, 2016 · 1 revision

The DataEntry widget can be integrated with React.js components. Example with base Form component defined using ES6 code:

/**
 * Reusable form component, with validation strategy implemented using jQuery-DataEntry
 * - Roberto Prevato
 */
import React from "react"
import ReactDOM from "react-dom"

class Form extends React.Component {

  // The following two methods are the only places we need to
  // integrate Bootstrap or jQuery with the components lifecycle methods.
  componentDidMount() {
    // When the component is added, initialize a dataentry
    this.initializeDataEntry();
  }

  componentWillUnmount() {
    this.destroyDataEntry();
  }

  initializeDataEntry() {
    var node = ReactDOM.findDOMNode(this);
    var elem = $(node);
    elem.addClass("ui-dataentry");

    var self = this, state = self.state;
    if (!state)
      throw new Error("missing component state. cannot define a dataentry without a schema.");
    var schema = state.schema;
    if (!schema)
      throw new Error("missing schema definition inside the model. cannot define a dataentry without a schema.");

    //add reference to the dataentry business logic to the model
    self.dataentry = new $.Forms.DataEntry({
      $el: elem,
      schema: schema,
      context: self
    });
    //extend the model with proxy functions
    _.extend(self, {
      validate: function (params) {
        return this.dataentry.validate(params);
      },
      validateTouched: function (params) {
        return this.dataentry.validate(params, {
          onlyIfTouched: true
        });
      },
      validateSync: function (params) {
        return this.dataentry.validateSync(params);
      },
      validateTouchedSync: function (params) {
        return this.dataentry.validateSync(params, {
          onlyIfTouched: true
        });
      },
    });
  }

  destroyDataEntry() {
    var dataentry = this.dataentry;
    dataentry.removeValidation().undelegateEvents();
    dataentry.$el = null;
    dataentry.context = null;
    this.dataentry = null;
  }

}

export default Form;

And then, this base Form class can be reused by other components that inherit from it:

/**
 * Example of form with validation strategy implemented using jQuery-DataEntry
 * - Roberto Prevato
 */
import React from "react"
import ReactDOM from "react-dom"
import BaseForm from "../common/forms/form"

class FormExample extends BaseForm {

  constructor(props) {
    super(props);
    //initial state:
    this.state = {
      //validation schema:
      schema: {
        name: {
          validation: ["required"],
          format: ["cleanSpaces"]
        },
        year: {
          validation: ["required", { name: "integer", params: [{ min: 1900, max: 2015 }] }]
        },
        "only-letters": {
          validation: ["letters"]
        },
        "policy-read": {
          validation: ["mustCheck"]
        }
      }
    };
  }

  save(e) {
    e.preventDefault();
    this.validate().done(function () {
      alert("The form is valid!");
    });
  }

  render() {
    return (
      <div>
        <h1>Form example, with global validation strategy</h1>
        <form id="example-form" method="post" action="?" action="?" autoComplete="off">
          <fieldset>
            <legend>Example form (data is not submitted anywhere!)</legend>
            <label htmlFor="name-field">Username</label>
            <input id="name-field" type="text" name="name" /><br />

            <label htmlFor="year-field">Year (between 1900 and 2015)</label>
            <input id="year-field" type="text" name="year" /><br />

            <label htmlFor="only-letters">A field that is not required, but accepts only letters</label>
            <input id="only-letters" type="text" name="only-letters" /><br />

            <label htmlFor="must-check" className="inline">A checkbox that must be checked (policy acceptance)</label>
            <input id="must-check" type="checkbox" name="policy-read" /><br />
          </fieldset>
          <fieldset className="buttons">
            <button className="submit btn" onClick={this.save.bind(this)}>{I.t("voc.Submit")}</button>
          </fieldset>
        </form>
        <hr />
        <ul>
          <li><a href="https://github.com/RobertoPrevato/jQuery-DataEntry">Validation plugin source code</a></li>
        </ul>
      </div>);
  }
}

export default FormExample;