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

@jaspero/form-builder

v5.12.0

Published

[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) ![Release](https://github.com/Jaspero/schema-forms/workflows/Release/badge.svg)

Downloads

331

Readme

semantic-release Release

| Library | Version | | ---- | ---- | | Core | NPM Version | | Fields Material | NPM Version | | Segments Materila | NPM Version | | Page Builder | NPM Version | | Form UI | NPM Version | | Tinymce | NPM Version | | Monaco Editor | NPM Version |

@jaspero/form-builder

Installation

To install this library, run:

$ npm install --save @jaspero/form-builder

Add Fields and Segments

If you need to render the forms in the UI you'll need to add fields and segments. Fields and segments are installed separably from the core module. We provide one set of fields and segments built with material.

$ npm install --save @jaspero/fb-fields-mat
$ npm install --save @jaspero/fb-segments-mat

Add them in to your module like this:

@NgModule({
  imports: [
    FbFieldsMatModule.forRoot({prefix: ''}),
    FbSegmentsMatModule.forRoot({prefix: ''}),
  ]
})

Giving them an empty prefix defines them as the defaults.

Provide services and values

  1. Provide necessary services
  • StorageService - Used for storing files when FileComponent, ImageComponent or GalleryComponent are used.
  • DbService - Used for fetching referenced relations from your server in runtime
  1. Provide necessary values
  • STORAGE_URL - Root URL for fetching files from your server
  • ROLE - Segments and fields can be conditionally shown/hidden if the value of the role matches what is expected in the schema

Styles

In order to make the generated forms customizable, this library doesn't provide any default styles. This means that the styles need to be loaded in the root of your application. A good starting point are the example styles provided here.

Composing Forms

Definitions

This configuration is used for defining addition field based options. Changing the label or what component is used to represent the field in the form. The Definitions interface looks like this:

| Property | Type | Description | Default | | ------------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | label | string | Label of the field | uses the name of the property | | hint | string | Shows a hint below the field if defined | - | | defaultValue | any | What the value of the field should be if empty | - | | component | object | {type: string, configuration: any} - The type defines the field to use and the configuration is used for any additional component specific options | What ever is the default for the property type |

Component Types

| Name | Selector | Description | Configuration Options | | ----- | -------- | -------------- | ----------------------------------- | | Input | input | A simple input | {type: 'text', 'number', 'email'} |

Example

{
  "name": {
    "label": "Name",
    "defaultValue": "John"
  },
  "age": {
    "label": "Age",
    "component": {
      "type": "slider"
    }
  }
}

Adding custom fields

  1. Create a new component that extends FieldComponent. You should inject COMPONENT_DATA in order to receive FieldData, most importantly the underlining FormControl.
  2. Map the newly added component through the CUSTOM_FIELDS provider e.g.
    providers: [{
        provide: CUSTOM_FIELDS,
        useValue: {
            'new-component': NewComponent
        }
    }]
  3. You can now use the new field in a forms definitions.

Adding custom components

  1. Create a new component that extends CustomComponent. It receives the CUSTOM_COMPONENT_DATA which has the form and id properties.
  2. Map the newly added component through the CUSTOM_COMPONENTS provider e.g.
    providers: [{
      provide: CUSTOM_COMPONENTS,
      useValue: {
        example: ExampleComponent  
      }
    }] 
  3. You can now use the new component in a segment e.g.
    "segments": [{
      "components": [{"selector": "example"}]
    }]

Handling arrays

The form builder supports both arrays of primitives and object arrays.

Object arrays

The following is required to render an object array:

  1. An object array defined in the schema:
    {
      "addresses": {
       "type": "array",
       "items": {
         "type": "object",
         "properties": {
           "city": {
             "type": "string"
           },
           "address": {
             "type": "string"
           }
         }
       }
      }
    }
  2. A dedicated segment with an array property:
    {
      "segments": [{
        "array": "/addresses",
        "fields": [
          "/city",
          "/address"
        ] 
      }]
    }
  3. You can also optionally define options for each field in the definitions:
    {
      "definitions": {
        "addresses/city": {
          "label": "City"
        }  
      }    
    } 

Primitive arrays

Primitive arrays can be displayed in two variations as a dedicated segment or as a field.

If the property is defined with out an items value. It's expected to be used as a field. In that case the following components can be used:

  • select in combination with {multiple: true}
  • chips
  • draggable-list

If an items value is defined then it's expected to be rendered as its own segments.

Plugins

Official plugins

TinyMCE WYSIWYG Editor

This plugin registers a field tinymce for rendering the TinyMCE WYSIWYG Editor.

Dependencies

|Library|Version| |----|----| |Tinymce|5.x|

Set up
  1. Install the plugin npm i --save @jaspero/fb-tinymce
  2. Add the plugin module TinymceModule to your module
  3. Install tinymce npm i --save tinymce
  4. Add the following to the assets array in angular.json
    {
        "glob": "**/*",
        "input": "node_modules/tinymce/themes/silver",
        "output": "/themes/silver"
    },
    {
        "glob": "**/*",
        "input": "node_modules/tinymce/skins/ui/oxide",
        "output": "/skins/ui/oxide"
    },
    {
        "glob": "**/*",
        "input": "node_modules/tinymce/skins/content/default",
        "output": "/skins/content/default"
    },
    {
        "glob": "**/*",
        "input": "node_modules/tinymce/plugins",
        "output": "/plugins"
    },
    {
        "glob": "**/*",
        "input": "node_modules/tinymce/icons",
        "output": "/icons"
    }
  5. Add the tinymce script to the scripts array in angular.json "./node_modules/tinymce/tinymce.min.js"
  6. You can optionally add/extend your commonjs dependencies whitelist to get rid of console warnings
        "allowedCommonJsDependencies": [
          "json-pointer",
          "tinymce/plugins/wordcount",
          "tinymce/plugins/table",
          "tinymce/plugins/lists",
          "tinymce/plugins/print",
          "tinymce/plugins/link",
          "tinymce/plugins/image",
          "tinymce/plugins/imagetools",
          "tinymce/plugins/fullscreen",
          "tinymce/plugins/code",
          "tinymce/plugins/autolink",
          "tinymce/plugins/advlist"
        ]

RefTable

This plugin registers a field ref-table that enables the editing of referenced item in an array and adding new references.

Dependencies

This plugin doesn't have any additional dependencies.

Set up
  1. Install the plugin npm i --save @jaspero/fb-ref-table
  2. Add the plugin module FbRefTableModule to your module

Note: If doing something like users/{{id}}/notifications it's important to have an initial value for the id.

Page Builder

This plugin registers a field pb-blocks for rendering a page builder module.

Dependencies

This plugin doesn't have any additional dependencies.

Inline Editor

Using InlineEditorModule allows for editing blocks inline (not just in the sidebar on the left). There are 3 directives you can utilize.

  • ImageIEDirective(fbPbImageIE) - This directive is for editing image urls. It adds an edit icon and optionally other custom components. It strictly needs to be used on a block element that is the direct parent to an image element that has no siblings.
  • SingleLineIEDirective(fbPbSingleLineIE) - This directive is for editing a single element. It adds a toolbar that allows for element type changes, alignment and decoration. The directive needs to be placed on the parent element, and the target element should have no siblings.
  • MultiLineIEDirective(fbPbMultiLineIE) - This directive provides the same functionality as the single line directive but allows for multiline editing.

Form UI

This plugin registers a field fu-fields for rendering a form builder module.

Dependencies

This plugin doesn't have any additional dependencies.

Set up
  1. Install the plugin npm i --save @jaspero/fb-form-ui

  2. Add the plugin module TinymceModule to your module

  3. Add translation files for your specific language. This is en:

    {
      "FU": {
        "ID": "ID",
        "LABEL": "Label",
        "VALUE": "Value", 
        "HINT": "Hint",
        "ORGANIZE": "Organize",
        "PLACEHOLDER": "Placeholder",
        "ADJUST_SIZE": "Adjust Size",
        "ADD_FIELD": "Add Field",
        "REQUIRED": "Required",
        "CHANGE_TYPE": "Change Type",
        "EDIT": "Edit",
        "REMOVE": "Remove",
        "OPTIONS": "Options",
        "SETTINGS": "Settings",
        "DEFAULT_PLACEHOLDER": "There are no fields currently.",
        "SIZE": {
          "DESKTOP": "Desktop",
          "TABLET": "Tablet",
          "MOBILE": "Mobile"
        },
        "TYPE": {
          "checkbox": "Checkbox",
          "email": "Email",
          "number": "Number",
          "select": "Select",
          "text": "Text",
          "textarea": "Textarea"
        }
      }
    }
  4. You can now use the field in your schemas like this:

    schema.properties

    {"fields": {"type": "array"}}

    layout.segments

    {
      "fields": {
        "component": {
          "type": "fu-fields"
        }
      }
    }

    layout.instance.segments

    {
      "type": "empty",
      "fields": ["/fields"]
    }

    Conditional Segments

    {
      "fields": [
        "/showTitle",
        {
          "field": "/title", // Field to assign actions
          "deps": ["/showTitle"], // Array of fields on which to listen for a change, if none are provided whole form is used as a listener
          "action": // Single action object or an array of objects
            [
              {
                "type": "show", // "show" | "hide" | "set-to"
                "eval": "(row) => row.showTitle"
              },
              {
                "type": "set-to",
                "eval": "(row) => !row.title",
                "configuration": {
                  "value": "Placeholder Title"
                }
              }
            ]
        }
      ]
    }
Set up
  1. Install the plugin npm i --save @jaspero/fb-page-builder
  2. Add the plugin module PageBuilderModule to your module

Monaco Editor

This plugin registers a field monaco for rendering the Microsoft Monaco Editor.

Dependencies

|Library|Version| |----|----| |@monaco-editor/loader|1.0.0| |monaco-editor|^0.23.0|

Set up
  1. Install the plugin, monaco editor and its loader npm i --save @jaspero/fb-monaco-editor monaco-editor @monaco-editor/loader
  2. Add the plugin module MonacoEditorModule to your module
  3. Add the following to the assets array in angular.json
    {
        "glob": "**/*",
        "input": "node_modules/ngx-monaco-editor/assets/monaco",
        "output": "./assets/monaco/"
    }

Development

Running locally

  1. Install dependencies npm ci
  2. Run the app with npm start

Creating a plugin

  1. Run ng g library [plugin-name] --prefix="fb-[library-prefix]"
  2. Add @jaspero/ prefix in the projects package.json
  3. Add a release property as well. Example from tincymce plugin.
      "release": {
        "pkgRoot": "../../dist/@jaspero/fb-tinymce",
        "branch": "master",
        "verifyConditions": [
          "@semantic-release/changelog",
          "@semantic-release/npm",
          "@semantic-release/git"
        ],
        "prepare": [
          "@semantic-release/changelog",
          "@semantic-release/npm",
          "@semantic-release/git"
        ],
        "publish": [
          "@semantic-release/npm",
          [
            "@semantic-release/github",
            {
              "assets": [
                "dist/@jaspero/fb-tinymce"
              ]
            }
          ]
        ],
        "plugins": [
          "@semantic-release/commit-analyzer",
          "@semantic-release/release-notes-generator"
        ]
      }
  4. Create ng-package.prod.json example from tinymce
    {
      "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
      "dest": "../../dist/@jaspero/fb-tinymce",
      "lib": {
        "entryFile": "src/public-api.ts"
      }
    }
  5. In angular.json extend the architect.configurations.production with ng-package.prod.json
     "configurations": {
       "production": {
         "tsConfig": "projects/page-builder/tsconfig.lib.prod.json",
         "project": "projects/page-builder/ng-package.prod.json"
       }
    }
  6. If you need to register fields do it in the plugins module like this:
    export class TinymceModule {
      constructor(
        private ctx: FormBuilderContextService
      ) {
        this.ctx.registerField(
          'tinymce',
          TinymceComponent
        );
      }
    }
  7. Add build scripts for the library in to the root package.json. Make sure to include the build command in the build:library script.
  8. Build the library and publish an initial version manually. This is required because since it's a scoped package it needs to be explicitly flagged as public. You can do this by running npm publish --access public in dist/@jaspero/[package-name].

License

MIT © Jaspero Ltd