galhavivi / cofi

JavaScript Form Solutions
https://galhavivi.github.io/cofi
Other
2 stars 1 forks source link
cofi dev development form form-validation forms javascript json json-editing json-editor layout persistence react react-components react-form react-forms reactjs ui ui-components web

COFI

Cofi - JavaScript form solutions. A set of tools which implement form capabilities using a simple JSON form object, containing fields and plenty of advanced features.

What The Fork? 🍴

Cofi is a progressive fork of yahoo/jafar library, maintained by Jafar's main contributor and creator.

Table Of Content

Background and Usage

Managing complicated forms is a hard task for developers. Dealing with field validations, dependencies, disable or exclude fields in some conditions and more can make the code complicated, hard to maintain and hard to write to begin with.

Cofi let developers build forms easily by defining a readable and intuitive form definition (model json & resources json) that represent the entire form lifescycle - such as fields and their corresponding data path, initial data, validators, dto conversions and more. It's based on a pure JavaScript, ui free form class which handles the form's definition, lifecycle and data manipulations. With the basic form class, any ui library (such as react, angular and vue) can easily use it to expose Form and Field components.

Supported Form Products

JavaScript Form Class

JavaScript Form class which manage fields and data manipulations. More info

React

Supplies 3 products to manage forms in react applications. More info

Potentially a single page (edit / create / details / list) can be implemented using these 3 packages

Highlights

Install

To install one of our consumable packages:

Run:

using npm - npm install --save @cofi/{package-name-here}

using yarn - yarn add @cofi/{package-name-here}

Examples

The following is a simple JavaScript Form class test example:

JavaScript Form Class

import Form from '@cofi/form';
import UserService from './UserService';

// define form model object that will be the initial state of the form
const model = {
  id: 'user-form',
  fields: {
    firstName: {
      label: 'First Name',
      path: 'firstName',
      required: true,
      validators: [{
        name: 'minLength'
        args: {
          value: 2
        }
      },
    },
    lastName: {
      label: 'Last Name',
      path: 'lastName',
    },
    email: {
      label: 'Email',
      path: 'email',
      validators: [{
        name: 'email',
      }, {
        name: 'uniqueField',
        args: { serverField: 'email' }
      }],
    },
  },
  data: {
    firstName: 'Ross',
    lastName: 'Geller',
    email: 'unagi@salmonskinroll.com',
  },
};

// define form resources object that contains all the handlers that the model needs
const resources = {
  validators: {
    uniqueField: {
      func: async ({ value, args }) => {
        return await UserService.isFieldUnique(args.serverField, value);
      },
      message: ({ value }) => `${ value } is already taken`,
    }
  },
  hooks: {
    submit: async ({ data }) => {
      return await UserService.save(data);
    }
  }
};

// create user form instance
const form = new Form();
await form.init(model, resources);

// verify form is valid
expect(form.invalid).toBeFalsy();

// change field firstName
await form.changeValue('firstName', 'Monica');

// verify form is valid
expect(form.invalid).toBeFalsy();

// change field firstName to undefined
await form.changeValue('firstName', '');

// verify form is invalid (since field 'firstName' is required and has minimum length)
expect(form.invalid).toBeTruthy();

// verify errors
expect(form.fields.firstName.errors).toEqual([
  { name: 'required', message: 'Field required' }, 
  { name: 'minLength', message: 'Minimum length is 2' }
]);

// make form valid again
await form.changeValue('firstName', 'Monica');

// submit the form
const success = await form.submit();

// verify submit success
expect(success).toEqual(true);

React Form Component

The following is a simple react Form & Field components (based on Form class) example:

import { Form, Field } from '@cofi/react-form';

const model = { /*...*/ };
const resources = { /*...*/ };

<Form model={model} resources={resources}>
  <h2>Basic Info</h2>
  <Field id="firstName" />
  <Field id="lastName" />
  <h2>Contact Info</h2>
  <Field id="email" />
</Form>

Docs and Demos

Cofi's full docs and demos are available here.

Run Docs and Demos Locally

Clone repository

git clone https://github.com/galhavivi/cofi.git

Install packages and link them

using npm - cd /cofi && npm run bootstrap

using yarn - cd /cofi && yarn run bootstrap

Run website locally

To run demos and docs locally for one of react-form, react-components, react-layout, react-editor and documentation packages:

using npm - cd /cofi/packages/{package-name-here} && npm start

using yarn - cd /cofi/packages/{package-name-here} && yarn start

Contribute

Please refer to the CONTRIBUTING.md file for information about how to get involved. We welcome issues, questions, and pull requests. Pull Requests are welcome.

Licence

Cofi is MIT licensed.