Skip to content

Commit

Permalink
Merge pull request #17 from simomosi/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
simomosi committed Jun 6, 2023
2 parents ce814e6 + 3812e99 commit d052cbb
Show file tree
Hide file tree
Showing 23 changed files with 353 additions and 172 deletions.
32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Table of Contents <!-- omit in toc -->
- [Dynamic Forms](#dynamic-forms)
- [What is it and what can I do with it](#what-is-it-and-what-can-i-do-with-it)
- [Select with variable options](#select-with-variable-options)
- [Form values easy initialisation](#form-values-easy-initialisation)
- [Progressive filtering](#progressive-filtering)
- [Automatic fields initialisation with dynamic content](#automatic-fields-initialisation-with-dynamic-content)
- [Visibility changes depending on fields' state](#visibility-changes-depending-on-fields-state)
- [Updating rules](#updating-rules)
- [Much much more](#much-much-more)
- [Documentation, installation and examples of use](#documentation-installation-and-examples-of-use)
- [Main features](#main-features)
- [Support](#support)

# Dynamic Forms
![npm bundle size](https://img.shields.io/bundlephobia/min/@simomosi/dynamic-forms)
Expand All @@ -15,18 +17,24 @@
![GitHub User's stars](https://img.shields.io/github/stars/simomosi?style=social)

## What is it and what can I do with it
DynamicForms is a javascript library that handles all the interaction in forms with dynamic content in an easy and fast way.
DynamicForms is a client library that handles all the interaction in forms with dynamic content in an easy and fast way.

It was born to automate progressive filtering and initialisation of dynamic fields. Then it evolved to support the developer in managing and centralizing all forms interactions.

It's written in *typescript* and compiled in *javascript*. It is later transpiled with *webpack* and *babel* to create a single lightweight bundle which ensure the maximum compatibility with older browsers.

Here's some examples.

### Select with variable options
### Progressive filtering

![Dynamic Select example gif](./docs/imgs/dynamic-select.gif)

### Form values easy initialisation
### Automatic fields initialisation with dynamic content

![Dynamic Form initialisation gif](./docs/imgs/initialisation.gif)

The progressive filtering status is restored: all the available options are automatically fetched.

### Visibility changes depending on fields' state

![Dynamic Checkbox example gif](./docs/imgs/dynamic-checkbox.gif)
Expand All @@ -38,7 +46,19 @@ Here's some examples.
### Much much more
Got your attention? Try it!

Dynamic Forms is released as a **single file**. You can also find already functioning examples!
Dynamic Forms is released as a **single file**. You can also find an already functioning example!

## Documentation, installation and examples of use
See [**DynamicForms page**](https://simomosi.github.io/dynamic-forms/).

## Main features
- [x] **Easy to use**: DynamicForms works in a declarative way; no code with the default behavior, just a simple configuration!
- [x] **Modern javascript and backward compatible**: works on all browsers!
- [x] **Lightweight**: having no dependencies, you can integrate it everywhere!
- [x] **Automate repetitive and boring operations**: read values, fetch data making async remote calls, update fields' status, clear other fields, hide/show sections... even listing them is BORING!
- [x] **Highly customizable**: are you using an external library with custom html elements? Don't worry as you can specify your own functions to read/write data

## Support
If you want to support me just star the project on [github](https://github.com/simomosi/dynamic-forms) and share it with your collegues. If you have questions or suggestions open an issue on github.

**Thank you very much for your support ❤**
21 changes: 14 additions & 7 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@
![GitHub User's stars](https://img.shields.io/github/stars/simomosi?style=social)

## What is it and what can I do with it
DynamicForms is a javascript library that handles all the interaction in forms with dynamic content in an easy and fast way.
DynamicForms is a client library that handles all the interaction in forms with dynamic content in an easy and fast way.

It was born to automate progressive filtering and initialisation of dynamic fields. Then it evolved to support the developer in managing and centralizing all forms interactions.

It's written in *typescript* and compiled in *javascript*. It is later transpiled with *webpack* and *babel* to create a single lightweight bundle which ensure the maximum compatibility with older browsers.

Here's some examples.

### Select with variable options
### Progressive filtering

![Dynamic Select example gif](./imgs/dynamic-select.gif){ loading=lazy }

### Form values easy initialisation
### Automatic fields initialisation with dynamic content

![Dynamic Form initialisation gif](./imgs/initialisation.gif){ loading=lazy }

The progressive filtering status is restored: all the available options are automatically fetched.

### Visibility changes depending on fields' state

![Dynamic Checkbox example gif](./imgs/dynamic-checkbox.gif){ loading=lazy }
Expand All @@ -31,12 +37,13 @@ Got your attention? Try it!
Dynamic Forms is released as a **single file**. You can also find an already functioning example!

## Main features
- [x] **Easy to use**: DynamicForms works in a declarative way; no code, just a simple configuration!
- [x] **Simple and modern javascript**: having no dependencies, you can integrate it everywhere!
- [x] **Easy to use**: DynamicForms works in a declarative way; no code with the default behavior, just a simple configuration!
- [x] **Modern javascript and backward compatible**: works on all browsers!
- [x] **Lightweight**: having no dependencies, you can integrate it everywhere!
- [x] **Automate repetitive and boring operations**: read values, fetch data making async remote calls, update fields' status, clear other fields, hide/show sections... even listing them is BORING!
- [x] **Highly customizable**: are you using an external library with custom html elements? Don't worry: you can specify your own functions to read/write data
- [x] **Highly customizable**: are you using an external library with custom html elements? Don't worry as you can specify your own functions to read/write data

## Support
If you want to support me just star the project on [github](https://github.com/simomosi/dynamic-forms): I'm not looking for fame, I need to pass a threshold to put dynamic-forms on famous cdn sites and make it even easier to integrate!
If you want to support me just star the project on [github](https://github.com/simomosi/dynamic-forms) and share it with your collegues. If you have questions or suggestions open an issue on github.

**Thank you very much for your support ❤**
1 change: 1 addition & 0 deletions docs/configurations/init-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ The field name.
The field value. It can be any primitive value.

This attribute has 2 purposes:

- It's passed to all other fields during initialisation;
- It will be the value automatically selected as the current field value; if the field type is *select*, the value must be available to be selected.
2 changes: 2 additions & 0 deletions docs/configurations/update-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ A collection of other fields name whose value will be automatically fetched and
A function to collect other data used in the update function but external to the form (e.g. a timestamp).

Parameters

- {`object`} `data`: data obtained from the [additional data](#additionalData-optional) function
- {`string | null`} `subjectName`: the name of the subject who triggered the update. It can be null if the update is triggered manually

Returns

- {`object`} An object with external data values (*key-value* format)
24 changes: 18 additions & 6 deletions docs/dev/contribute.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Contribute
Help me develop DynamicForms!

Remember to work on `dist/dynamicforms.js` file to access source code (or import the `src/index.js` file as a module if you prefer).
Remember to work on `src/*.ts` files and test them building the bundle and importing `dist/dynamicforms.js` (of course you can import individual files manually if you prefer so).

Useful commands:

Expand All @@ -10,22 +10,22 @@ Useful commands:
- `yarn build` - Build both dev file and prod file
- `yarn build:diagrams` - Updates *classdiagram.svg* from *classdiagram.mmd* <!-- TODO remove if gh-deploy succeeds -->

Please, update also the documentation if you can.
Please, update also the documentation if you change anything.

**Thank you very much for your support ❤**

## Disclaimer
DynamicForms is build considered some use-cases I faced in my career.

If you can offer me other *real* use cases to test it on please let me know.
It is a very generic library but there may be other use cases which I didn't account for. In this case please let me know, we can work together in implementing new features.

## Issues/Suggestions
If you have trouble using it open an issue, I'll be glad to help you. Suggestions are also welcome!
If you have trouble using DynamicForms open an issue, I'll be glad to help you. Suggestions are also welcome!

It will be useful if you pass me some code to try: you can use tools like CodePen, PasteBin etc.

# Project Structure
Here is the UML Class Diagram to help you understand the project structure.
Here is the UML Class Diagram to help you understand the project structure. Types are not specified for space reasons: the diagram is created using Mermaid which places elements automatically.

<!-- ![Class Diagram](./imgs/classdiagram.svg) -->
<!-- TODO: remove from assets if gh-deploy succeeds -->
Expand Down Expand Up @@ -60,6 +60,14 @@ classDiagram
note for dynamicForms "Library entrypoint"
class ConfigurationFixer {
+fix(formHtmlElement, formConfiguration) FormConfiguration
}
class FieldBuilder {
+createFieldsMap(fieldsCollection, htmlForm)
}
class DynamicElement {
-FieldConfiguration config
-NodeList htmlElement
Expand All @@ -80,8 +88,12 @@ classDiagram
+saveData(data) void
}
DynamicForm <.. dynamicForms
dynamicForms --> ConfigurationFixer
dynamicForms --> FieldBuilder
DynamicForm <-- dynamicForms
DynamicForm o-- DynamicElement
DynamicElement <|-- DynamicSelect
DynamicElement <|-- DynamicCheckbox
DynamicElement <|-- DynamicRadio
Expand Down
2 changes: 1 addition & 1 deletion docs/dev/cool_stuff.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Cool computer science stuff
- DynamicForms is a particular instance of the **Observer Design Pattern** in which Observers and Subjects are all of the same type: html elements
- The function used to clear fields *on cascade* is the **Depth-first search (DFS)** used in Graph theory
- The library entry point (*src/index.js*) implements the **Facade Design Pattern** to improve software usability: it masks more complex underlying code e.g. explicit objects instantiation
- The library entry point (*src/index.js*) implements the **Facade Design Pattern** to improve software usability: it masks more complex underlying code e.g. explicit objects instantiation and configuration fixing
4 changes: 2 additions & 2 deletions docs/start/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
<script src='https://unpkg.com/@simomosi/dynamic-forms@latest'></script>
```

You can set the specific version (e.g. `dynamic-forms@1.2.0`), use tags (e.g. `dynamic-forms@latest`) or semver ranges (e.g. `dynamic-forms@^1.2.0`).
You can set the specific version (e.g. `[email protected].0`), use tags (e.g. `dynamic-forms@latest`) or semver ranges (e.g. `dynamic-forms@^2.0.0`).
See [UNPKG page](https://www.unpkg.com/) for more information.

## Using local files
Download the last release from [GitHub release section](https://github.com/simomosi/dynamic-forms/releases). Extracts files in your assets folder and load them in your project (see next section).

This is not the recommended method because you can't get security updates automatically.

If you still want to proceed this way, it is recommended to use the minified file (*dynamicforms.min.js*) for better performance.
If you still want to proceed this way, it is recommended to use the minified file (`dist/dynamicforms.min.js`) for better performance.
10 changes: 6 additions & 4 deletions docs/start/loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Choose your favorite import method
=== "ES6 Module"
```html
<script type="module">
import 'your-assets-path/@simomosi/dynamic-forms/dist/dynamicforms.min.js';
import './node_modules/@simomosi/dynamic-forms/dist/dynamicforms.min.js';
</script>
```

Expand All @@ -17,13 +17,13 @@ Choose your favorite import method

=== "Script tag"
```html
<script src='your-assets-path/@simomosi/dynamic-forms/dist/dynamicforms.min.js'></script>
<script src='./node_modules/@simomosi/dynamic-forms/dist/dynamicforms.min.js'></script>
```

Note that 2 different sources exist:

- `@simomosi/dynamic-forms/dist` (recommended) is transpiled with *Webpack* and *Babel* to enhance performance and ensure compatibility with different browsers
- `@simomosi/dynamic-forms/src` is the actual source
- `@simomosi/dynamic-forms/src` is the actual source code
- `@simomosi/dynamic-forms/dist` (recommended) is built bundle: sources are transpiled with *Webpack* and *Babel* to enhance performance and ensure compatibility with different browsers

## From CDN

Expand All @@ -38,3 +38,5 @@ Note that 2 different sources exist:
import 'https://unpkg.com/@simomosi/dynamic-forms@latest';
</script>
```

Be careful to not include the library twice!
27 changes: 17 additions & 10 deletions docs/tldr/create_instance.md → docs/tutorial/create_instance.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# TL;DR - Form creation
# Tutorial - Form creation

## Preconditions

<!-- Did you already [installed](../start/installation.md) and [loaded](../start/loading.md) the library? Then go on, you are almost there! -->
Did you already [installed](../start/installation.md) and [loaded](../start/loading.md) the library? Then go on, you are almost there!

Let's assume we are working on the following html form:

Expand All @@ -11,6 +11,8 @@ Let's assume we are working on the following html form:
<label for="field_one">Field one</label>
<select id="field_one" name='field_one'>
<option value="" selected></option>
<option value="1">One</option>
<option value="2">Two</option>
</select>

<label for="field_two">Field two</label>
Expand All @@ -20,21 +22,26 @@ Let's assume we are working on the following html form:
</form>
```

Let's assume we loaded dynamic-forms using a CDN:
```html
<script src = 'https://unpkg.com/@simomosi/dynamic-forms@latest'></script>
```

## Write form configuration

For the form configuration we need to write 2 lists:

1. **fields**: a list of form fields with custom behavior (using the following [format](../configurations/fields-configuration.md))
2. **rules**: a list which indicates when a field related event (usually a `change`) should notify other fields (using the following [format](../configurations/update-rules.md))
1. **fields**: a list of form fields with custom behavior (using the [field configuration](../configurations/fields-configuration.md) format); a field with a remote url for fetching its values is a custom behavior field;
2. **rules**: a list which indicates when a field related event (usually a `change`) should notify other fields (using the [update rule](../configurations/update-rules.md) format)

```javascript
const formConfiguration = {
id: 'form_id',
fields: [
{
name: 'field_one',
name: 'field_two',
fetch: {
makeUrl: (data) => `https://url/to/api`,
makeUrl: (data) => `https://url/to/api/`,
}
}
],
Expand All @@ -47,7 +54,7 @@ const formConfiguration = {
};
```

Note: we didn't specify `field_two`'s configuration.
Note: we didn't specify `field_one`'s configuration.

## Create the dynamic form

Expand All @@ -59,8 +66,8 @@ const form = dynamicForms.makeForm(formConfiguration);

## Done!

You can now play with your form!
Look at the network tab in developer console/tools while you play with your form!

This is a basic configuration which works with default values. To customize it to your needs check the [documentation chapter](../configurations/form-configuration.md).
Of course you need a real api-endpoint to load your values. For a working example open files in the [example folder](https://github.com/simomosi/dynamic-forms/blob/main/examples) in your browser.

For a working example open files in the [example folder](https://github.com/simomosi/dynamic-forms/blob/main/examples) in your browser.
This is a basic configuration which works with default values. To customize it to your needs check the [documentation chapter](../configurations/form-configuration.md).
14 changes: 8 additions & 6 deletions docs/tldr/initial_status.md → docs/tutorial/initial_status.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# TL;DR - Set the Initial Status
# Tutorial - Set the Initial Status

Dynamic-forms can automatically set the form initial status if you don't want to retrieve all values manually.
Dynamic-forms can automatically set the form initial status if you don't want to retrieve all values manually. It is useful for restoring the progressive filtering status because you don't need to query for all the available options anymore.

You need to list all the fields which requires the initialisation, describing:

1. Their **name**
2. Their initial **value**, if you want to set one
2. Their initial **value** (optional)


```javascript
Expand All @@ -22,12 +22,14 @@ const formConfiguration = {
};
```

Note: you need to specify an API-endpoint in `fields` for `field_one` to work.

Dynamic-forms uses:

- the information specified in the `fields` section to retrieve remote data for each field in the `init` section
- the informations specified in the `rules` section to infer what data should be retrieved next
- the information specified in the `fields` section to retrieve remote data for each field specified in the `init` section
- the informations specified in the `rules` section to infer what data should be retrieved after the initialisation

In the example above, first `fields` and `init` rules will initialise `field_one`, then (update) `rules` will initialise `field_two` as specified in the previous page.
In the example above, dynamic-forms will first initialise `field_one` using `fields` and `init` rules, then it will initialise `field_two` using (update) `rules` as specified in the previous page.

If you need to specify other data, just list their name and value in the `init` collection just like they were form fields.

Expand Down
6 changes: 3 additions & 3 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ nav:
- Start:
- Installation: start/installation.md
- Loading: start/loading.md
- TL;DR show me the code:
- Form creation: tldr/create_instance.md
- Initial status: tldr/initial_status.md
- Tutorial with code:
- Form creation: tutorial/create_instance.md
- Initial status: tutorial/initial_status.md
- Documentation:
- How to use it: dynamic-forms-module.md
- Form configuration: configurations/form-configuration.md
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@simomosi/dynamic-forms",
"version": "1.3.0",
"version": "2.0.0",
"description": "DynamicForms is a js library that handles all interactions in forms with dynamic content (e.g. select with variable options, updating rules and visibility changes depending on fields' state).",
"main": "dist/dynamicforms.min.js",
"browser": "dist/dynamicforms.min.js",
Expand Down Expand Up @@ -32,7 +32,12 @@
"json",
"configuration",
"vanilla",
"javascript"
"javascript",
"progressive",
"filtering",
"typescript",
"webpack",
"babel"
],
"devDependencies": {
"@babel/cli": "^7.21.0",
Expand Down
Loading

0 comments on commit d052cbb

Please sign in to comment.