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

a-wc-form-json-schema

v2.5.0

Published

JSON Schema form binder and layout

Downloads

373

Readme

AWC JSON Schema Form

A JSON Schema form binder web component. Can be used anywhere you can use web components.

Generates form controls, and optionally form layout, from JSON Schema data.

Extends a-wc-form-binder to use a JSON Schema to automatically create form controls based on the schema data types. Validation defined in the JSON schema is also applied to the form controls. (a-wc-form-layout) can be provided which is a set of instructions on how a-wc-form-json-schema should layout the form. Or you can create the form with normal HTML. Controls used for JSON schema data types can be customized.

Usage

npm i -save a-wc-form-json-schema

Using form-binder

Example of binding data to JSON Schema generated form controls. This example does not use a-wc-form-layout and instead relies on you to manually create the form control structure using a-wc-form-binder.

HTML

<json-schema-form>
  <!-- Each json-schema-control will create the control for the data type from a set  -->
  <json-schema-control ref="/name/first"></json-schema-control>
  <json-schema-control ref="/name/second"></json-schema-control>
  <!-- json-schema-control can also render branches or even the whole schema -->
  <json-schema-control ref="#"></json-schema-control>
  <!-- Opt out of json-schema-form but still take advantage of a-wc-form-binder data binding and validation -->
  <input type="text" bind="/name/middle">
</json-schema-form>

Javascript

See a-wc-form-binder package for more info on binders and validation.

import { binderRegistry binders } from "a-wc-form-binder";
import "a-wc-form-json-schema/src/components/json-schema-form.js";
import "a-wc-form-json-schema/src/components/json-schema-control.js";

// add the control binders to bind data to controls
binderRegistry.add(...Object.values(binders));

const formBinder = document.querySelector('form-binder');

// Give form-binder the data
formBinder.data = {
  firstName: 'foo', lastName: 'bar', middleName: '' }
}

// Defined the schema - here we simply declare it inline but you might load it from somewhere like an OpenAPI spec file
const schema = {
  type: "object",
  properties: {
    firstName: {
      type: "string",
      title: "First Name",
      minLength: 3,
      description: "Please enter your first name"
    },
    lastName: {
      type: "string",
      title: "Last Name",
      minLength: 3,
      description: "Please enter your last name"
    },
    middleName: {
      type: "string",
      title: "Middle Name",
      minLength: 3,
      description: "Please enter your middle name"
    }
  },
  required: ["firstName", "lastName"]
}

// Give the json schema to each json-schema-control
document.querySelectorAll('json-schema-control').forEach(control => {
  control.schema = schema;
});
// OR set the schema once on the form-binder
formBinder.schema = schema;

// Listen for changes to the data
jsonSchemaForm.addEventListener('form-binder:change', e => console.info(e.detail.data));

The json-schema-control web component uses a-wc-form-layout templates to render controls based on a properties data types.

Using form-layout

A new a-wc-form-layout control type, JsonSchemaControl, is available. JsonSchemaControl will render the control required for the data type as defined in the JSON Schema provided.

Example showing the use of a-wc-form-layout with JsonSchemaControl to layout out the form controls.

HTML

<!-- json-schema-from extends form-layout -->
<json-schema-form></json-schema-form>

Javascript

import { binderRegistry, binders } from "a-wc-form-binder";
import "a-wc-form-json-schema/src/components/json-schema-form.js";

// add the control binders to bind data to controls
binderRegistry.add(...Object.values(binders));

const jsonSchemaForm = document.querySelector('json-schema-form');

// Give json-schema-form the data
jsonSchemaForm.data = {
  firstName: 'foo', lastName: 'bar', middleName: '' }
}

// Give the json-schema-form the layout
// Optional - if not supplied then a layout will be generated from the schema
jsonSchemaForm.layout = {
  type: "VerticalLayout",
  elements: [
    {
      // Specify the JsonSchemaControl as the component
      type: "JsonSchemaControl",
      ref: "#/firstName"
    },
    {
      type: "JsonSchemaControl",
      ref: "#/lastName"
    }
  ]
}

// Give json-schema-form the schema
jsonSchemaForm.schema = {
  type: "object",
  properties: {
    firstName: {
      type: "string",
      title: "First Name",
      minLength: 3,
      description: "Please enter your first name"
    },
    lastName: {
      type: "string",
      title: "Last Name",
      minLength: 3,
      description: "Please enter your last name"
    },
    middleName: {
      type: "string",
      title: "Middle Name",
      minLength: 3,
      description: "Please enter your middle name"
    }
  },
  required: ["firstName", "lastName"]
}

// Listen for changes to the data
jsonSchemaForm.addEventListener('form-binder:change', e => console.info(e.detail.data));

Customization of JSON Schema to Layout Schema

It is possible to change how the JSON Schema gets transformed into Layout Schema. There is a function responsible for the transformation of each JSON Schema type ('string', 'number', 'integer', 'boolean', 'object', 'array') into a Layout Component. These functions can be replaced.

For example, by default the transformation of a JSON Schema type 'object' is to a VerticalLayout. e.g. each property in the object is rendered in a single column. If you want to switch this to a two column GridLayout you can override the function to generate 'object' JSON Schema types like so:

import { layoutGeneratorRegistry } from 'a-wc-form-json-schema';
import { jsonPointer } from 'a-wc-form-binder';

// The function takes in the full JSON Schema and a JSON Pointer the the part of the JSON Schema being processed.
// It returns a Layout Component. In this case a 2 column GridLayout.

/**
 * @param {import("a-wc-form-json-schema/src/lib/models").JsonSchema} schema to generate uiSchema for
 * @param {string} ref JSON pointer string to use as a starting point. Use if we are generating uiSchema for only a part of the schema.
 * @returns {import("a-wc-form-layout/src/lib/models").GridLayout}
 */
const newObjectGenerator = function (schema, ref) {
    // The full JSON Schema is passed in so we get the part of the schema currently targeted using the ref (JSON Pointer)
    /** @type {import("a-wc-form-json-schema/src/lib/models").JsonSchema} schema to generate layout Schema for */
    const currentSchema = jsonPointer.getSchemaValue(schema, ref);
    return {
        template: 'GridLayout',
        properties: {
            columns: 2,
            label: currentSchema.title,
            // Generate child component layouts
            components: Object.entries(currentSchema.properties).map((entry) => {
                const componentJsonPointer = `${ref}/${entry[0]}`;
                if (typeof entry[1] !== 'boolean' && typeof entry[1].type === 'string') {
                    return {
                        columns: entry[1].type === 'array' ? 2 : 1,
                        component: layoutGeneratorRegistry.getLayoutGenerator(entry[1].type)(
                            schema,
                            componentJsonPointer,
                        ),
                    };
                }
                return null;
            }),
        },
    };
};

layoutGeneratorRegistry.setLayoutGenerator('object', newObjectGenerator);

This layout generator must be registered before the json form is instantiated.

API - json-schema-form

Attributes and properties

| Name | Type | Description | | ---- | ---- | ----------- | | data | property | The JSON data to bind controllers to | | layout | property | The JSON layout containing the component definitions | | schema | property | JSON Schema data which will be used for determining controls and validation to use. |

Events

| Name | Detail | Description | | ---- | ------ | ----------- | | form-binder:change | data | event.detail.data references a copy of the original data that has new values applied to it. | | | validationResults | event.detail.validationResults validation was performed as part of the change process. | | form-binder:report-validity | import("a-wc-form-binder/src/lib/control-validator.js").FormValidationResult | Should be listened to to update the UI with messages. |

API - json-schema-control

Attributes and properties

| Name | Type | Description | | ---- | ---- | ----------- | | schema | property | JSON Schema data which will be used for determining controls and validation to use. Optional. If missing the control will look for a parent form-binder or form-layout and look for a schema property on it to use. |

Events

| Name | Detail | Description | | ---- | ------ | ----------- | | form-binder:change | data | event.detail.data references a copy of the original data that has new values applied to it. |