-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
23667d6
commit e12fab5
Showing
1 changed file
with
98 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,130 @@ | ||
# Jsonschema Form | ||
|
||
[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] | ||
[![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) | ||
[![License: MIT][license_badge]][license_link] | ||
|
||
A Flutter package capable of using JSON Schema to declaratively build and customize Flutter forms | ||
`jsonschema_form` is a Flutter package designed for developers to dynamically build forms using JSON Schema and UI Schema. It simplifies decoding schemas pre-populating forms and building them dynamically. | ||
|
||
## Features ✨ | ||
- **Dynamic Form Creation**: Automatically generate forms from JSON Schema. | ||
- **Customizable UI**: Use UI Schema for tailored form styling. | ||
- **Pre-Populated Data**: Initialize forms with pre-existing data and update as needed. | ||
- **Flexible Input Sources**: Load schema and data from assets, strings, or decoded JSON objects. | ||
|
||
## Current Package Status ⚠️ | ||
|
||
This package is currently under development in a very early development stage. The plan is to publish it on [pub.dev](https://pub.dev/). | ||
- **JsonSchema** is a model class that tells the form how it should be built. The currently *json* supported properties for now are: | ||
- **title**: A human-readable name or label for a particular schema or field. It’s often displayed as the label or header when generating forms based on the schema. Can be empty. | ||
- **description**: Is shown above each field if is not null, providing neccessary information if needed. | ||
- **default**: Is the default value that this field takes. If there is data present on the corresponding formData property, this is ignored. | ||
- **type**: Defines the data type of a field or schema element. Possible types include "string", "number", "integer", "boolean", "array" and "object". It tells the UI what kind of input widget needs to be rendered. | ||
- **requiredFields**: A list of required fields, is composed by the key properties that corresponds to the jsonSchema. If a jsonKey is required then the form cannot be submitted if there is no value in the corresponding field. | ||
- **properties**: When type is "object", properties is used to define the schema for each of the fields within that object. Each key in properties is a jsonKey and the value is the schema for that field. | ||
- **enum**: Allows to specify a fixed set of acceptable values for a field, effectively creating a dropdown or selection list in form-based UIs. It’s used to restrict the possible values for a field. | ||
- **const**: Used to specify that a field must have a single specific value. It’s useful when a field needs a fixed value. | ||
- **dependencies**: Allows to define conditional logic within the schema, where certain fields are required or change their validation based on the presence or value of another field. Dependencies can work in two ways: *Schema dependencies*: Where certain fields are only required or validated if another field exists. *Property dependencies*: Where certain fields are only required if another field has a specific value. | ||
- **items**: Items is only present when type is equal to array. The form generated will have fields that allow users to enter multiple entries, essentially creating a dynamic list of inputs. If additionalItems is null then the type of items will be JsonSchema. If additionalItems is not null then the type of items will be Array. | ||
- **additionalItems**: When is not null, then items will be an array of items. Form will show those items by default and pressing add button will build a new schema provided by additionalItems. | ||
- **minItems**: If type is array and needs to be populated, minItems can specify the minimum number of items that the array must have. | ||
- **maxItems**: If type is array and needs to be populated, maxItems can specify the maximum number of items that the array can have. | ||
- **uniqueItems**: If type is array and uniqueItems is set to true, all items from the array follows the same schema. | ||
- **oneOf**: A way to define conditional schemas where only one of multiple schemas must be valid, depending on specific conditions. When dependencies is used with oneOf, it enables conditional logic based on the fields in the JSON data, allowing the schema to adapt according to certain field value. | ||
- **format**: Allows to define specific format for some scenarios. If format is data-url a file upload form is built. If format is email, the TextFormField is adapted to an email input. | ||
- **minLength**: When the type is string this will be used as the minimum length user can enter in a TextFormField. | ||
- **maxLength**: When the type is string this will be used as the maximum length user can enter in a TextFormField. | ||
|
||
- **UiSchema** is a model class that tells the form how it should looks like. The currently *json* supported properties for now are: | ||
- **ui:widget**: Defines the type of widget to be used for the given key. | ||
- **ui:autofocus**: Automatically focus on a text input or textarea input when is true. | ||
- **ui:emptyValue**: Provides the default value to use when an input for a field is empty. | ||
- **ui:placeholder**: Add placeholder text to an input | ||
- **ui:title**: The title of a field. If this is null, jsonSchema.title will be used and if jsonSchema.title is null the jsonKey will be used as title. | ||
- **ui:description**: Sometimes it's convenient to change the description of a field. This will be shown as a Text widget above the field. | ||
- **ui:help**: Provides a brief description under the field for helping de user. | ||
- **ui:readonly**: If the field is an input and readonly is true then the input can't be modified. | ||
- **ui:options**: Defines options to be used for the given key, for instance: if options is { removable: false } then this indicates user can't delete items from array. | ||
|
||
### TODOs: | ||
- Add AllOf and AnyOff support to Json Schema | ||
- Widgets need to be reused in OneOf | ||
- Support referencing for reusable form definitions | ||
- Localize error messages | ||
- Improve Camera. There is a bug when building a preview. | ||
- Don’t rebuild the whole form when using dependencies but instead rebuild the specific field. | ||
- Default values may be replacing formData default values | ||
- upDown widget is not correctly implemented yet | ||
- Live Demo to showcase the package | ||
|
||
## Installation 💻 | ||
|
||
**❗ In order to start using Jsonschema Form you must have the [Flutter SDK][flutter_install_link] installed on your machine.** | ||
|
||
Install via `flutter pub add`: | ||
As is not yet published at [pub.dev](https://pub.dev/). Install modifying your *pubspec.yaml* file. Add these lines: | ||
|
||
```sh | ||
dart pub add jsonschema_form | ||
jsonschema_form: | ||
git: | ||
url: https://github.com/martinpelli/jsonschema_form.git | ||
ref: dev | ||
``` | ||
|
||
--- | ||
|
||
## Continuous Integration 🤖 | ||
## Usage 🕹️ | ||
|
||
Jsonschema Form comes with a built-in [GitHub Actions workflow][github_actions_link] powered by [Very Good Workflows][very_good_workflows_link] but you can also add your preferred CI/CD solution. | ||
### Import the package 📦 | ||
|
||
Out of the box, on each pull request and push, the CI `formats`, `lints`, and `tests` the code. This ensures the code remains consistent and behaves correctly as you add functionality or make changes. The project uses [Very Good Analysis][very_good_analysis_link] for a strict set of analysis options used by our team. Code coverage is enforced using the [Very Good Workflows][very_good_coverage_link]. | ||
```sh | ||
import 'package:jsonschema_form/jsonschema_form.dart'; | ||
``` | ||
|
||
--- | ||
### Initializing a JsonSchemaForm class 🎬 | ||
|
||
#### From a JSON Asset | ||
|
||
## Running Tests 🧪 | ||
```sh | ||
final form = JsonschemaForm(); | ||
await form.initFromJsonAsset('assets/form.json'); | ||
``` | ||
|
||
For first time users, install the [very_good_cli][very_good_cli_link]: | ||
#### From a JSON String | ||
|
||
```sh | ||
dart pub global activate very_good_cli | ||
final form = JsonschemaForm(); | ||
form.initFromJsonString('{"jsonSchema": {...}, "uiSchema": {...}, "formData": {...}}'); | ||
``` | ||
|
||
To run all unit tests: | ||
#### From Decoded JSON | ||
|
||
```sh | ||
very_good test --coverage | ||
final form = JsonschemaForm(); | ||
form.initFromDecodedJson({ | ||
"jsonSchema": {...}, | ||
"uiSchema": {...}, | ||
"formData": {...}, | ||
}); | ||
``` | ||
|
||
To view the generated coverage report you can use [lcov](https://github.com/linux-test-project/lcov). | ||
#### From Separate JSON Strings | ||
|
||
```sh | ||
# Generate Coverage Report | ||
genhtml coverage/lcov.info -o coverage/ | ||
final form = JsonschemaForm(); | ||
form.initFromJsonsString('{...}', '{...}', '{...}') | ||
``` | ||
|
||
# Open Coverage Report | ||
open coverage/index.html | ||
### Build the form 🚀 | ||
|
||
```sh | ||
JsonschemaFormBuilder( | ||
jsonSchemaForm: jsonschemaForm, //Previously initialized JsonschemaForm class | ||
onFormSubmitted: (formData) { | ||
ScaffoldMessenger.of(context).showSnackBar(SnackBar( | ||
content: Text(formData.toString()), | ||
backgroundColor: Colors.green, | ||
)); | ||
}, | ||
); | ||
``` | ||
|
||
[flutter_install_link]: https://docs.flutter.dev/get-started/install | ||
[github_actions_link]: https://docs.github.com/en/actions/learn-github-actions | ||
[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg | ||
[license_link]: https://opensource.org/licenses/MIT | ||
[logo_black]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_black.png#gh-light-mode-only | ||
[logo_white]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_white.png#gh-dark-mode-only | ||
[mason_link]: https://github.com/felangel/mason | ||
[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg | ||
[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis | ||
[very_good_cli_link]: https://pub.dev/packages/very_good_cli | ||
[very_good_coverage_link]: https://github.com/marketplace/actions/very-good-coverage | ||
[very_good_ventures_link]: https://verygood.ventures | ||
--- | ||
|
||
|
||
[very_good_ventures_link_light]: https://verygood.ventures#gh-light-mode-only | ||
[very_good_ventures_link_dark]: https://verygood.ventures#gh-dark-mode-only | ||
[very_good_workflows_link]: https://github.com/VeryGoodOpenSource/very_good_workflows |