npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mobx-json/mui-form

v0.2.2

Published

create material-ui forms by json & mobx

Downloads

7

Readme

mobx-json

npm version dependencies Status CircleCI codecov Netlify Status

The simplest way to manage your form in React.

State management is charged by mobx, but you can use the materia-ui wrapped one without any knowledge of it.

You can check some examples here: https://mobx-json.thundermiracle.com

Table of Contents

Installation

npm i -S @mobx-json/mui-form react react-dom validatorjs

or

yarn @mobx-json/mui-form react react-dom validatorjs

How to use

  1. Define your form in JSON or javascript.

    {
      "fields": [
        {
          "settings": {
            "widget": "TextField",
            "rule": "required|min:3"
          },
          "attrs": {
            "name": "id",
            "label": "Use Id",
            "placeholder": "input your user id"
          }
        },
        {
          "settings": {
            "widget": "Password",
            "rule": "required|min:8"
          },
          "attrs": {
            "name": "password",
            "label": "Password",
            "placeholder": "at least 8 chars"
          }
        }
      ]
    }
  2. Create the form

    import { useMuiJsonForm } from '@mobx-json/form';
    import LoginFormJson from './blueprints/login-form.json';
    
    const IndexPage = props => {
      const { form, getDataWithCheck } = useMuiJsonForm({
        blueprint: LoginFormJson,
      });
    
      const handleSubmit = React.useCallback(async () => {
        const data = getDataWithCheck();
        if (data) {
          await tryLogin(data);
        }
      }, [getDataWithCheck]);
    
      // the following one is material-ui, you can use native ones as well
      return (
        <Container maxWidth="xs">
          <Card>
            <CardContent>{form}</CardContent>
            <CardActions>
              <Button color="primary" onClick={handleSubmit}>
                LOGIN
              </Button>
            </CardActions>
          </Card>
        </Container>
      );
    }
  3. Display

    simple

A more useful sample

./examples/mui-form

How to define blueprint

The blueprint MUST be defined as follows.

{
  "fields": [
    ...
  ]
}

Each field should contains 3 parts including settings, attrs and fields (which is only necessary for settings.valueType = container).

  • normal component

    {
      "fields": [
        {
          "settings": {
            "widget": "TextField",
            "valueType": "string"
            ...
          },
          "attrs": {
            "name": "firstName"
            ...
          }
        }
      ]
    }
  • container

    {
      "fields": [
        {
          "settings": {
            "widget": "GridItemContainer",
            "valueType": "container"
            ...
          },
          "attrs": {
            "name": "baseInfoGrid"
            ...
          },
          "fields": [
            {
              "settings": {
                "widget": "TextField",
                "valueType": "string"
                ...
              },
              "attrs": {
                "name": "firstName"
                ...
              }
            }
          ]
        }
      ]
    }

settings

To define which component to use and validation, etc.

exp:

{
  "settings": {
    "widget": "TextField", // required
    "valueType": "string", // default: string
    "rule": "required"
  }
}

generate: TextField component and display error if input is empty.

| Property | Required | Type | Default | Description | |:---------:|:--------:|:----:|:--------|:------------| | widget | 〇 | string | | 1. components contained in the package(TextField, Select...) 2. component you passed by widgetMap 3. native component in html(div, span...) | | valueType | | string | string | one of number, string, array, boolean, container | | rule | | string | null | using validatorjs as default validation tool, you can check the default validation rules here | | propRule | | string | null | rule to apply prop dynamically by input values. | | computeRule | | string | null | rule to compute value dynamically by target fields' value. |

widget

Following basic components are included in this package for quicker start: Checkbox, Checkboxes, Display, Password, PasswordOutlined, Radio, Select, SelectOutlined, Switch, TextField, TextFieldOutlined.

valueType (optional)

As every value from e.target.value is converted into string, we have to define a correct valueType to format.

※ container: a special valueType which means sub fields are contained

rule (optional)

A rule to validate the input.

exp: "rule": "required|max:30" will throws error if input is empty or over 30.

here for details

sample page

service (optional)

※ See Autocomplete's example

serviceRouter (optional)

Use get as default router in service.

※ See Autocomplete's example

serviceParamFields (optional)

Get paramFields' value and pass them as parameters.

※ See Autocomplete's example

propRule (optional)

Apply defined prop to attrs if meets theYou can define multiple propRule and split them by |

Format:

propName,propValueWhenMeetCondition,propValueType:targetFieldName,targetFieldValue

* Which means if (targetFieldName.value == targetFieldValue) set propName->propValue

exp: "propRule": "hidden,true,boolean:firstName,Daniel" will hide the component when the firstName equals 'Daniel'.

sample page

computeRule (optional)

Compute by other fields value. You can define multiple computeRule and split them by |, but the last rule will win.

Format:

computeMethod:targetFieldName1,targetFieldName2,targetFieldName3...:extraInfo

Now supports 3 computeMethods:

  • concat

    concat all targetFields' value into one string

    exp: "computeRule": "concat:firstName,lastName:, "

    When firstName is 'Daniel', lastName is Wood, component's value will automatically changed to 'Daniel, Woo'.

  • sum

    sum all targetFields' value include string numbers. return 0 if character is contained.

    exp: "computeRule": "sum:profit1,profit2"

    When profit1 is 100, profit2 is 200, component's value will automatically changed to 300.

  • format

    get and format targetField's value.

    exp: "computeRule": "format:sex", "format": { "type": "items", "itemsSource": "Sex"}

    Transform field [sex]'s value by itemsSource. itemsSource: [{ value: 0, label: 'Male'}] will get 'Male' if value is 0.

    sample page

reloadRule (optional)

Reload items by calling asyncLoadItems when meets reloadRule. You can define multiple computeRule and split them by |, but the last rule will win.

Format:

computeMethodtargetFieldName,compareMethod,targetFieldValue

List of compareMethod: =, >, <, >=, <=, <> (DEFAULT)

exp: "reloadRule": "prefecture" means call asyncLoadItems if prefecture's value is not empty & changed

exp: "reloadRule": "age>18" means call asyncLoadItems if age's value is greater than 18.

attrs

All props defined in attrs will be passed to each component. And attrs.name MUST be unique in each form.

exp:

{
  "settings": {
    "widget": "TextField",
    "valueType": "string"
  },
  "attrs": {
    "name": "firstName",  // required & MUST be unique
    "label": "First Name",
    "placeholder": "input your first name"
  }
}

generates:

<TextField name="firstName" label="First Name" placeholder="input your first name" />

Extended props in every component:

| Property | Required | Type | Default | Description | |:---------:|:--------:|:----:|:--------|:------------| | grid | | object | { "xs": 12 } | responsive grid layout. Automatically add xs=12 to every component unless noGrid is true. See here for details. | | noGrid | | boolean | false | if true, grid will be ignored | | defaultValue | | any | null | applied to value if it's undefined | | value | | any | null | value for display | | keepLabelSpace | | boolean | false | if true, margin-top: 16px | | icon | | string | | 1. iconsMap MUST be passed in initialization. see iconsMap example and how to initialize. 2. icon is one of the keys defined in iconsMap.js. 3. IconComponent will be passed to each component. | | itemsSource | | string | | 1. itemsSource MUST be passed in initialization. see itemsSource example and how to initialize. 2. itemsSource is one of the keys defined in itemsSource.js. 3. itemsSource will be converted to items and passed to each component. 4. Available in Radio, Checkboxes component |

Components

Check the example page:

GridItemContainer

rest props are the same with material-ui's Grid component.

{
  "settings": {
    "widget": "GridItemContainer", // required
    "valueType": "container" // required
    ... // others like propRule
  },
  "attrs": {
    "name": "nameGrid", // required
    "divider": false, // show divider in the bottom of the Grid component if true
    "primary": '', // primary text size h4 in Grid
    "primaryProps": {}, // props for primary text's typography
    "secondary": '', // secondary text size body2 under the primary text
    "secondaryProps": {}, // props for secondaryProps text's typography
    "subPrimary": '', // subPrimary text size h6 right of the primary text
    "subPrimaryProps": {}, // props for subPrimaryProps text's typography
    "hidden": false, // hide all sub fields if true (propagate hidden prop to all children)
    "disabled": false, // disable all sub fields if true (propagate disable prop to all children)
    ...rest props
  }
}

Checkbox

rest props are the same with material-ui's Grid component.

{
  "settings": {
    "widget": "Checkbox",
    "valueType": "boolean",
    "rule": "required" // invalid if not checked
  },
  "attrs": {
    "name": "subscription",
    "label": "Subscribe the news letter!"
    ...rest props
  }
}

Checkboxes

{
  "settings": {
    "widget": "Checkboxes",
    "valueType": "array",
    "rule": "required"
  },
  "attrs": {
    "name": "interest",
    "label": "Your Interests",
    "selectAll": false, // if true, show SelectAll checkbox
    "selectAllLabel": "ALL",  // default label of SelectAll checkbox is ALL
    "icon": "", // get IconComponent from iconsMap
    "itemsSource": "", // get items definition from itemsSource
    "items": [   // items MUST be an array with label&value
      {
        "label": "Movie",
        "value": 1
      },
      {
        "label": "Gaming",
        "value": 2
      },
      {
        "label": "Coding",
        "value": 3
      }
    ]
  }
}

Data

For keeping data and will not be rendered.

exp:

{
  "settings": {
    "widget": "Data"
  },
  "attrs": {
    "name": "id"
  }
}

Display

For display and format value. See examples.

formatters:

  • date: yyyy/MM/dd HH:mm:ss
  • time: HH:mm
  • age: compute age
  • digit: toLocaleString() (1234 -> 1,234)
{
  "settings": {
    "widget": "Display"
  },
  "attrs": {
    "name": "birthday",
    "label": "Birthday",
    "icon": "Today",
    "format": {
      "type": "date",
      "template": "yyyy年MM月dd日"
    }
  }
}

Password

PasswordOutlined

Radio

Select

SelectOutlined

Switch

TextField

TextFieldOutlined

Autocomplete

See examples.

{
  "settings": {
    "widget": "Autocomplete",
    "rule": "required",
    "service": "filmService", // service passed by serviceContainer,
    "serviceRouter": "get", // default: get
    "serviceParamFields": [], // list of fieldName, get value of these fields and pass to service as { params: {fieldName1: value1, fieldName2: value2} }
  },
  "attrs": {
    "name": "film",
    "label": "FavoriteFilm",
    "freeSolo": true, // false: clear input's value when not selected from suggestions list
    "icon": "MenuBook", // get IconComponent from iconsMap
    "reloadOnInput": true, // true: reload suggestions onChange; false: load suggestions once after mounted;
    "reloadExcludeRegex": "[0-9]", // regex that not trigger reload onChange
    "reloadDelay": 300, // throttle of reloadOnInput
    "loaderText": "Loading...", // text when loading suggestions
    "extraAutocompleteProps": {}, // props applied to Autocomplete(material-ui's)
    "autoHighlight": false,
    "autoComplete": false,
    "autoSelect": false,
    ...               // restProps are the same with TextField
  }
  +
}

AutocompleteOutlined

How to use in React

Package is using hook to make the form and return submit functions. React > 16.8 is needed.

Initialize (optional)

Need if icon, itemsSource is used, use customized components or display self-defined error messages.

See example.

| Parameter | Required | Type | Default | Description | |:---------:|:--------:|:----:|:--------|:------------| | locale | | string | en | validatorjs' locale string | | messages | | object | {} | key-value object for extended error messages| | itemsSource | △ | object | {} | key-value object for items definition. ※ required if itemsSource is used in blueprint | | iconsMap | △ | object | {} | key-value object for IconComponent definition. ※ required if icon is used in blueprint | | serviceContainer | △ | object | {} | key-value object for services' definition. pass asyncLoadItems to component which returns items asynchronously ※ required if service is used in blueprint | | extraWidgetMap | | object | {} | key-value object for extra Widget(component) |

  • initialize example:

    import { initialize } from '@mobx-json/mui-form';
    
    initialize({
      locale: 'zh',
      messages,
      itemsSource,
      iconsMap,
      extraWidgetMap
    });
  • itemsSource example:

    export default {
      City: [
        {
          label: '東京都',
          value: 'tokyo',
        },
        {
          label: '神奈川県',
          value: 'kanagawa',
        },
        {
          label: '千葉県',
          value: 'chiba',
        },
      ],
      Sex: [
        {
          label: 'Male',
          value: 0,
        },
        {
          label: 'Female',
          value: 1,
        },
        {
          label: 'Other',
          value: -1,
        },
      ],
    }
  • iconsMap example:

    import AccountCircle from '@material-ui/icons/AccountCircle';
    import ContactMail from '@material-ui/icons/ContactMail';
      
    export default {
      AccountCircle,
      ContactMail,
    };
  • extraWidgetMap example:

    import MyTextField from './MyTextField';
    
    export default {
      AdvancedTextField: MyTextField,
    };

Generate form

Use hook useMuiJsonForm to generate form.

example:

import { useMuiJsonForm } from '@mobx-json/mui-form';

const { form, getDataWithCheck, setData, setBlueprint } = useMuiJsonForm({
  blueprint,
  formUniqName,
  data,
});

// load data after mounted
React.useEffect(async () => {
  const dataFromServer = await readDataFromServer();
  setData(dataFromServer);
}, []);

// save to server if validation pass
const handleSubmit = React.useCallback(async () => {
  const submitData = getDataWithCheck();
  if (submitData) {
    await saveDataToServer(submitData);
  }
}, [getDataWithCheck]);

See example.

useMuiJsonForm's parameters

| Parameter | Required | Type | Default | Description | |:---------:|:--------:|:----:|:--------|:------------| | blueprint | 〇 | object | | blueprint for rendering form. See details. | | blueprintExtra | {} | object | | key-value object: fieldName: { attrs: {}, settings: {}} for override definitions in blueprint. See details. | | formUniqName | △ | string | '' | necessary if define multiple forms in one page, or auto focus when errors occur will fail. | | data | | object | {} | data for form in initialization | | options | | object | { smoothScroll: true, gridContainerProps: {} } | 1. smoothScroll: if true, append style scroll-behavior:smooth; to the latest overflow: auto; component. 2. gridContainerProps: props applied to root grid container |

useMuiJsonForm's output

useMuiJsonForm returns an object contains following parameters:

| key | Type | Description | |:---------:|:--------:|:------------| | form | React.Element | React form generated by blueprint | | store | object | mobx JsonFormStore | | setData | Function | apply data object to form | | getData | Function | returns input data without running validation | | getDataWithCheck | Function | validate all inputs, if ok, returns input data; if not, returns false and automatically focus the first error field. | | setBlueprint | Function | apply a new blueprint. ※ re-render all fields! | | clearError | Function | clear all error messages | | clearData | Function | clear all data, set it to defaultValue if exists | | clearAll | Function | clearError & clearData | | revertToInit | Function | clearError & revert inputs to initialized data | | changeFieldAttrs | Function | change field's props to trigger re-rendering by mobx |

License

This project is licensed under the terms of the MIT license.