{"id":15102812,"url":"https://github.com/rxnt/react-jsonschema-form-manager","last_synced_at":"2025-09-27T00:31:36.762Z","repository":{"id":57333540,"uuid":"96881779","full_name":"RXNT/react-jsonschema-form-manager","owner":"RXNT","description":"An abstract manager for Mozilla react-jsonschema-form","archived":true,"fork":false,"pushed_at":"2017-11-02T12:12:41.000Z","size":70,"stargazers_count":10,"open_issues_count":2,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-03-24T15:03:44.149Z","etag":null,"topics":["jsonschema","react","react-jsonschema-form","rest-api"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RXNT.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-11T10:33:56.000Z","updated_at":"2023-01-28T21:17:53.000Z","dependencies_parsed_at":"2022-08-24T20:50:51.595Z","dependency_job_id":null,"html_url":"https://github.com/RXNT/react-jsonschema-form-manager","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RXNT","download_url":"https://codeload.github.com/RXNT/react-jsonschema-form-manager/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219871828,"owners_count":16554457,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jsonschema","react","react-jsonschema-form","rest-api"],"created_at":"2024-09-25T19:07:25.284Z","updated_at":"2025-09-27T00:31:36.433Z","avatar_url":"https://github.com/RXNT.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/RxNT/react-jsonschema-form-manager.svg?branch=master)](https://travis-ci.org/RxNT/react-jsonschema-form-manager)\n[![Coverage Status](https://coveralls.io/repos/github/RxNT/react-jsonschema-form-manager/badge.svg?branch=master)](https://coveralls.io/github/RxNT/react-jsonschema-form-manager?branch=master)\n[![npm version](https://badge.fury.io/js/react-jsonschema-form-manager.svg)](https://badge.fury.io/js/react-jsonschema-form-manager)\n\n# react-jsonschema-form-manager\n--------\n\nThis project is opinionated implementation of a manager for [mozilla form](https://github.com/mozilla-services/react-jsonschema-form)\nor any of it's derivative projects, it provides a REST based api layer that\nhandles form submission and update.\n\n## Features\n\n- Saving [react-jsonschema-form](https://github.com/mozilla-services/react-jsonschema-form) related json with configurable `REST` or `LocalStorage` api for testing\n- Configurable form updates on data change, with `PUT` requests\n- Static and `REST` form configuration support\n- Flexible authentication management\n\n## Installation\n\nInstall `react-jsonschema-form-manager` by running:\n\n```bash\nnpm install --s react-jsonschema-form-manager\n```\n\n## Usage\n\nThe simplest use case would be to load static properties and save them in `localStorage`,\nthis can be done like this:\n\n```js\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport Form from \"react-jsonschema-form\";\nimport withManager, { LocalStorageFormManager, StaticConfigResolver, intervalUpdateStrategy } from \"react-jsonschema-form-manager\";\n\nlet config = {\n  schema: {\n    type: \"object\",\n    required: [\"firstName\", \"lastName\"],\n    properties: {\n      firstName: {\n        type: \"string\",\n        title: \"First name\",\n      },\n      lastName: {\n        type: \"string\",\n        title: \"Last name\",\n      }\n    }\n  }\n};\n\nlet configResolver = new StaticConfigResolver(config);\nlet manager = new LocalStorageFormManager();\nlet updateStrategy = intervalUpdateStrategy(10000);\n\nlet FormToDisplay = withManager(manager, configResolver, updateStrategy)(Form);\n\nReactDOM.render(\u003cFormToDisplay /\u003e, document.getElementById(\"app\"));\n```\n\nFunctional part of API consist of 3 parts\n- Configuration loader (`static` or `REST`)\n- Manager (`localStorage` or `REST`)\n- Update strategy (`imediate` or `interval`)\n\nYou can configure and extend them independently of one another, to get functionality you need.\n\n## UI Workflow\n\nUI workflow consists of 2 phases\n- `LoadingScreen` - display loading, while configuration is resolved\n- Show provided `form` with loaded configuration, or display an `ErrorScreen` screen in case configuration can't be resolved\n\nYou can override default presentations, when you call `withManager`\n\n```js\nimport React, { Component } from \"react\";\nimport Form from \"react-jsonschema-form\";\nimport withManager from \"react-jsonschema-form-manager\";\n\nclass CustomLoadingScreen extends Component {\n  render() {\n    return (\n      \u003cdiv className=\"container\"\u003e\n        \u003ch1\u003eAbout to launch\u003c/h1\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nclass CustomErrorScreen extends Component {\n  render() {\n    return (\n      \u003cdiv className=\"container\"\u003e\n        \u003ch4\u003eHouston, we have a problem\u003c/h4\u003e\n        \u003ch2\u003e\n          {this.props.error.message}\n        \u003c/h2\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\n...\n\nexport default withManager(manager, configResolver)(Form, CustomLoadingScreen, CustomErrorScreen);\n```\n\n## Configuration\n\nEach mozilla form needs a configuration, which can be either pre configured or loaded from the server.\n`LoadingScreen` will be displayed while configuration loads. `ConfigResolver` does not make any assumptions regarding the content\n of the configuration, so except for `schema` and `uiSchema` you can return any configuration needed.\n\n\nThe simplest configuration for schema configuration load, would look like this:\n```js\nimport React, { Component } from \"react\";\nimport Form from \"react-jsonschema-form\";\nimport withManager, { StaticConfigResolver, LocalStorageFormManager }  from \"react-jsonschema-form-manager\";\n\nlet config = {\n  schema: {\n    //...\n  },\n  uiSchema: {\n    //...\n  },\n  formData: {\n    //...\n  },\n};\n\nlet configResolver = new StaticConfigResolver(config);\nlet localStorageManager = new LocalStorageFormManager();\n\nlet FormToDisplay = withManager(configResolver, localStorageManager)(Form);\n\nclass ResultForm extends Component {\n  render() {\n    return (\n      \u003cFormToDisplay /\u003e\n    );\n  }\n}\n```\n\nHere the `config` will be used as Form configuration and `StaticConfigResolver` is used to return it.\nThis is enough for forms to operate properly\n\nThere are 2 supported configuration resolvers:\n- Static configuration resolver, which uses pre configured `config` setting\n- REST configuration resolver, which talks to API endpoint for needed `configuration`\n\nYou can also specify your own configuration resolver.\n\n### Static configuration\n\n`StaticConfigResolver` takes 2 parameters `config` and `timeout`,\n- `config` is the configuration to return\n- `timeout` delay before returning configuration, it was added primarily for testing purposes\n\n```js\nimport { StaticConfigResolver }  from \"react-jsonschema-form-manager\";\nlet timeout = 10000;\n\nlet config = {\n  schema: {\n    //...\n  },\n  uiSchema: {\n    //...\n  },\n  formData: {\n    //...\n  },\n};\n\nlet configResolver = new StaticConfigResolver(config, timeout);\n```\n\n### REST configuration\n\nPrimary configuration option is by means of `REST` API, which you can configure with needed authentication\n\n`RESTConfigResolver` takes 3 parameters  \n- `url` configuration url to use\n- `credentials` authentication to use with url\n- `outputHandler` manipulate data returned by the HTTP call before resolving the promise\n\nThe simplest `RESTConfigResolver` will look like this:\n\n```js\nimport { RESTConfigResolver }  from \"react-jsonschema-form-manager\";\n\nlet configResolver = new RESTConfigResolver(`https://example.com/schema`);\n```\nIn this case no authentication is needed and config resolver returnes json result of `REST` request\n\n#### Authentication configuration\n\nThere are 3 options to specify `credentials` for the configuration endpoint\n\n##### Leave it empty\n\nIn this case no authentication will be provided for the request\n\n```js\nimport { RESTConfigResolver }  from \"react-jsonschema-form-manager\";\n\nlet configResolver = new RESTConfigResolver(`https://example.com/schema`);\n```\n\n##### Specify credentials object\n\nIn case authentication can be done with domain Cookies, you can simply specify credentials object in accordance with fetch documentation.\nRefer to [whatwg-fetch sending cookies](https://www.npmjs.com/package/whatwg-fetch#sending-cookies) documentation for more details.\n\n\n```js\nimport { RESTConfigResolver }  from \"react-jsonschema-form-manager\";\n\nlet configResolver = new RESTConfigResolver(\n  `https://example.com/schema`,\n  {\n    credentials: 'same-origin'\n  });\n```\n\nor\n\n```js\nimport { RESTConfigResolver }  from \"react-jsonschema-form-manager\";\n\nlet configResolver = new RESTConfigResolver(\n  `https://example.com/schema`,\n  {\n    credentials: 'include'\n  });\n```\n\n##### Use transformation function for the Request\n\nTransformation function, would sign fetch `Request` with any custom authentication logic needed.\n\nFor example to have a `Basic authentication` can be done like this:\n\n```js\nimport { RESTConfigResolver }  from \"react-jsonschema-form-manager\";\n\nlet credentials = (req) =\u003e new Request(req, { headers: {\n  'Authorization': 'Basic '+ btoa(`${username}:${password}`),\n}});\n\nlet configResolver = new RESTConfigResolver(\n  `https://example.com/schema`,\n  credentials);\n```\n\n#### Manipulating HTTP feedback with outputHandler\n\nUse this if your HTTP resource doesn't return the exact JSON data you want to pass to your Form's props. Also useful for adding/merging default values to the HTTP response.\n\n```js\nimport { RESTConfigResolver }  from \"react-jsonschema-form-manager\";\n\nlet outputHandler = obj =\u003e {\n  let output = {\n    subSetOfData: obj.someProperty,\n  };\n  return output;\n};\n\nlet configResolver = new RESTConfigResolver(\n  \"http://localhost:3000/conf\",\n  {},\n  outputHandler\n);\n\n// if origOutput = JSON response of REST call,\n//configResolver resolves to: { subSetOfData: origOutput.someProperty };\n\n```\n\n### Custom configuration\n\nIf neither `REST` or `Static` configuration fits your needs, you can create your own configuration, by simply providing\n`resolve` method with no params, that would return `Promise` with `config` result\n\nFor example GraphQL ConfigResolver can be defined something like this:\n\n```js\nimport { RESTConfigResolver }  from \"react-jsonschema-form-manager\";\n\nclass GraphQLConfigResolver {\n  constructor(url, credentials) {\n    this.restResolver = new RESTConfigResolver(url, credentials);\n  }\n  resolve = () =\u003e {\n    return this.restResolver.resolve().then(({ data, error }) =\u003e {\n      return new Promise((resolve, reject) =\u003e {\n        if (error) {\n          reject(new Error(error));\n        } else {\n          resolve(data);\n        }\n      });\n    });\n  };\n}\n```\n\n## Saving formData\n\nBesides schema configuration, you need to specify the way to save formData. System supports 2 ways of saving data\n- `LocalStorage` - using LocalStorage for storing submitted data, this is primarily for testing purpose\n- `REST` - saving data in REST endpoint\n\nThe simplest configuration can look like this\n\n```js\nimport React, { Component } from \"react\";\nimport Form from \"react-jsonschema-form\";\nimport withManager, { StaticConfigResolver, LocalStorageFormManager }  from \"react-jsonschema-form-manager\";\n\nlet config = {\n  //...\n};\n\nlet configResolver = new StaticConfigResolver(config);\nlet localStorageManager = new LocalStorageFormManager();\n\nlet FormToDisplay = withManager(configResolver, localStorageManager)(Form);\n\nclass ResultForm extends Component {\n  render() {\n    return (\n      \u003cFormToDisplay onSubmit={() =\u003e onSuccessCallback}/\u003e\n    );\n  }\n}\n```\n\nIn this case data is stored in `LocalStorage` and on successful submit, if there are no errors `onSuccessCallback` is called for further processing.\nImplementation wraps `onSubmit` on original form and calls it only after formData was successfully saved with underlying `FormManager`.\n\n### Local storage\n\n`LocalStorage` store is there only for testing purposes and not supposed to be used in production.  \nYou can specify a `key` under which provided form will be stored. By default `form` is used as a key and you are limited to single form.\n\n### REST storage\n\nAs with schema configuration, this is primary option for storing your data.\n\n`RESTFormManager` takes 2 parameters\n- `url` configuration url to use\n- `credentials` authentication to use with url\n\nAuthentication logic is the same as for `RESTConfigurationResolver`, the only difference is that instead of the `GET`, we send a `POST`\nwith `JSON` of `formData` as a request.\n\n### Custom storage\n\nAs with `ConfigurationResolver` you can create your custom implementation for `FormManager`, which needs only 3 methods\n- `submit` called when form is submitted, should return `Promise` that will be resolved after successful submission\n- `updateIfChanged` called when form needs to update it's transient stay to the server. It must return either a `Promise`, if manager\nconsiders data changed and will trigger an update, or `undefined` if there is nothing to change.\n`updateIfChanged` accepts `force` flag that will always result in update.\n- `onChange` called whenever form data changes, it's needed to manage formData state inside a manager\n\nFor example `FormManager` using `SessionStorage` can look something like this:\n```js\nclass SessionStorageFormManager {\n  constructor(key = DEFAULT_KEY) {\n    this.key = key;\n  }\n  onChange = (state) =\u003e {\n    this.formData = state.formData;\n  }\n  submit = () =\u003e {\n    return new Promise(resolve =\u003e {\n      sessionStorage.setItem(this.key, JSON.stringify(this.formData));\n      resolve(formData);\n    });\n  }\n  updateIfChanged = () =\u003e {\n    return new Promise(resolve =\u003e {\n      sessionStorage.setItem(this.key, JSON.stringify(this.formData));\n      resolve(formData);\n    });\n  }\n}\n```\n\nYou can skip logic in `update`, if you are not planning to use any `UpdateStrategy` in your case.\n\n## Update Strategy\n\n`UpdateStrategy` is needed in case you want to save transient results of work.\n\nFor example\n```js\nimport React, { Component } from \"react\";\nimport Form from \"react-jsonschema-form\";\nimport { instantUpdateStrategy }  from \"react-jsonschema-form-manager\";\n\n...\n\nlet FormToDisplay = withManager(configResolver, manager, instantUpdateStrategy)(Form);\n\nclass ResultForm extends Component {\n  render() {\n    return (\n      \u003cFormToDisplay/\u003e\n    );\n  }\n}\n```\nIn this case all changes to the `formData`, will be instantly submitted by the `FormManager` to the underlying server.\n\nAs with FormManager, UpdateStrategy override embedded `onChange` mozilla-jsonschema functionality.\n\nThere are 2 kinds of `UpdateStrategy` currently supported\n\n### Instant update\n\n`instantUpdateStrategy` updates request on every change of the form. This is a lot of work for the server and not recommended.\n\n```js\nimport React, { Component } from \"react\";\nimport Form from \"react-jsonschema-form\";\nimport { instantUpdateStrategy }  from \"react-jsonschema-form-manager\";\n\nlet FormToDisplay = withManager(configResolver, manager, instantUpdateStrategy)(Form);\n\nclass ResultForm extends Component {\n  render() {\n    return (\n      \u003cFormToDisplay onChange={() =\u003e onSuccessChange}/\u003e\n    );\n  }\n}\n```\n### Interval updates\n\n`intervalUpdateStrategy` updates request in specified interval of time, it takes `timeout` as parameter.\n\nFor example, in order to update server every 100 seconds configuration would look something like this:\n```js\nimport React, { Component } from \"react\";\nimport Form from \"react-jsonschema-form\";\nimport { intervalUpdateStrategy }  from \"react-jsonschema-form-manager\";\n\nlet updateStrategy = intervalUpdateStrategy(100000);\n\nlet FormToDisplay = withManager(configResolver, manager, updateStrategy)(Form);\n\nclass ResultForm extends Component {\n  render() {\n    return (\n      \u003cFormToDisplay/\u003e\n    );\n  }\n}\n```\n\n### Custom update strategy\n\nAs with other components you can easily override `UpdateStrategy` with custom implementation.\nConstruction of the object is done with a currying pattern, you can define any parameters you want on first call,\nand you will get `manager` when updateStrategy is going to be used. Returned object needs 2 methods `onChange` and `stop`.\n- `stop` get called when component unMounts, or after successful submit\n- `onChange` called when ever `formData` changes, in original `Form`\n\nFor example you want to update only on even dates, this would look something like this:\n```js\nexport function evenDaysUpdateStrategy() {\n  return (manager) =\u003e {\n    return {\n      onChange: () =\u003e {\n          if (new Date().getDate() % 2 == 0) {\n            manager.updateIfChanged();\n          }\n        },\n      stop: function() {};\n    };\n  };\n}\n```\n\n### Listening to updates\n\nIf you want to track server data updates, you can do this by specifying `onUpdate` callback on rendered form\n\n\n```js\n...\n\nlet FormToDisplay = withManager(configResolver, manager, updateStrategy)(Form);\n\nclass ResultForm extends Component {\n  render() {\n    return (\n      \u003cFormToDisplay onUpdate={() =\u003e console.log(\"Data updated\")}/\u003e\n    );\n  }\n}\n```\n\n## Contribute\n\n- Issue Tracker: github.com/RxNT/react-jsonschema-form-manager/issues\n- Source Code: github.com/RxNT/react-jsonschema-form-manager\n\n## Support\n\nIf you are having issues, please let us know here or on StackOverflow.\n\n## License\n\nThe project is licensed under the Apache Licence 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frxnt%2Freact-jsonschema-form-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frxnt%2Freact-jsonschema-form-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frxnt%2Freact-jsonschema-form-manager/lists"}