1.0.0 • Published 5 years ago

@ghalusa/formschemahalusa v1.0.0

Weekly downloads
2
License
MIT
Repository
gitlab
Last release
5 years ago

FormSchema Native

Vue component form based on JSON Schema and Native HTML

npm Build status Test coverage

This is the branch for @formschema/native 2.0 Alpha, not ready for production. For the 1x version, please switch to the v1 branch.

Status: Alpha

Core features are not ready and the API could changed. Don't use this in production.

Install

npm install --save @formschema/native

Demo

formschema-demo-elementui

Usage

<template>
  <FormSchema :schema="schema" v-model="model" @submit.prevent="submit">
    <button type="submit">Subscribe</button>
  </FormSchema>
</template>

<script>
  import FormSchema from '@formschema/native'
  import schema from './schema/newsletter-subscription.json'

  export default {
    data: () => ({
      schema: schema,
      model: {}
    }),
    methods: {
      submit (e) {
        // this.model contains the valid data according your JSON Schema.
        // You can submit your model to the server here
      }
    },
    components: { FormSchema }
  }
</script>

Features

Supported Keywords

Irrelevant (ignored) Keywords

Since FormSchema is just a form generator, some JSON Schema validation keywords are irrelevant:

FormSchema API

props

  • schema Object (required)

    The input JSON Schema object.

  • v-model Number|String|Array|Object|Boolean (optional) default: undefined

    Use this directive to create two-way data bindings with the component. It automatically picks the correct way to update the element based on the input type.

  • id String (optional)

    The id property of the Element interface represents the form's identifier, reflecting the id global attribute.

  • name String (optional) default: undefined

    The name of the form. It must be unique among the forms in a document.

  • bracketed-object-input-name Boolean (optional) default: true

    When set to true (default), checkbox inputs will automatically include brackets at the end of their names (e.g. name="Multicheckbox-Value1[]". Setting this property to false, disables this behaviour.

  • search Boolean (optional) default: false

    Use this prop to enable search landmark role to identify a section of the page used to search the page, site, or collection of sites.

  • disabled Boolean (optional) default: false

    Indicates whether the form elements are disabled or not.

  • components Components (optional) default: GLOBAL.components

    Use this prop to overwrite the default Native HTML Elements with custom components.

events

  • input

    Fired synchronously when the value of an element is changed.

methods

  • form()

    Get the HTML form reference.

    return value:

    • HTMLFormElement|VNode|undefined - Returns the HTML form element or undefined for empty object

Working with Async Schema

<template>
  <FormSchema v-model="schema"/>
</template>

<script>
  import axios from 'axios'
  import FormSchema from '@formschema/native'

  export default {
    components: { FormSchema },
    data: () => ({
      schema: {}
    }),
    created() {
      axios.get('/api/schema/subscription.json').then(({ data: schema }) => {
        this.schema = schema
      });
    }
  };
</script>

Working with Async Schema and Vue Router

<template>
  <FormSchema v-model="schema"/>
</template>

<script>
  import axios from 'axios'
  import FormSchema from '@formschema/native'

  export default {
    components: { FormSchema },
    data: () => ({
      schema: {}
    }),
    beforeRouterEnter(from, to, next) {
      axios.get('/api/schema/subscription.json')
        .then(({ data: schema }) => next((vm) => vm.setSchema(schema)))
        .catch(next);
    },
    methods: {
      setSchema(schema) {
        this.schema = schema;
      }
    }
  };
</script>

Render a Textarea element

Add a text/* media types to a string schema to render a Textarea element.

Example schema.json

{
  "type": "string",
  "contentMediaType": "text/plain"
}

You can also use a custom descriptor to force the Render to use a Textarea element:

Example descriptor.json

{
  "kind": "textarea"
}

Render an Input File element

String schemas with media types not starting with text/* are automatically render as Input File elements.

Example schema.json

{
  "type": "string",
  "contentMediaType": "image/png"
}

There is a list of MIME types officially registered by the IANA, but the set of types supported will be application and operating system dependent. Mozilla Developer Network also maintains a shorter list of MIME types that are important for the web.

Render a hidden Input element

String schemas with defined const property are automatically render as Input File elements.

Example schema.json

{
  "type": "string",
  "const": "value of the hidden input"
}

Multiple Checkbox elements

To define multiple checkbox, use the JSON Schema keyword anyOf:

Example schema.json

{
  "type": "object",
  "properties": {
    "multipleCheckbox": {
      "type": "array",
      "anyOf": [
        "daily",
        "promotion"
      ]
    }
  }
}

Grouped Radio elements

To group radio elements, use the JSON Schema keyword enum:

Example schema.json

{
  "type": "object",
  "properties": {
    "groupedRadio": {
      "type": "string",
      "enum": [
        "daily",
        "promotion"
      ]
    }
  }
}

Array Inputs Elements

To render a array field, define your schema like:

Example schema.json

{
  "type": "object",
  "properties": {
    "arrayInput": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}

FormSchema will render a text input by adding a button to add more inputs.

Regex Inputs

To render a regex input, define your schema like:

Example schema.json

{
  "type": "object",
  "properties": {
    "regexInput": {
      "type": "string",
      "pattern": "[a-e]+"
    }
  }
}

JSON Schema $ref Pointers

To load a JSON Schema with $ref pointers, you need to install an additional dependency to resolve them:

import $RefParser from 'json-schema-ref-parser';
import FormSchema from '@formschema/native';
import schemaWithPointers from './schema/with-pointers.json';

export default {
  created () {
    $RefParser.dereference(schemaWithPointers)
      .then((schema) => {
        // `schema` is the resolved schema that contains your entire JSON
        // Schema, including referenced files, combined into a single object
        this.schema = schema;
      });
  },
  components: { FormSchema }
}

See json-schema-ref-parser documentation page for more details.

Custom Form Elements

To define custom elements for rendering, you need to use the Components class and the components prop:

// MyCustomElements.js

import { Components } from '@formschela/native';
import { InputElement } from '@/components/InputElement';
import { ArrayElement } from '@/components/ArrayElement';
import { FieldsetElement } from '@/components/FieldsetElement';
import { ListElement } from '@/components/ListElement';
import { TextareaElement } from '@/components/TextareaElement';
import { StateElement } from '@/components/StateElement';

export const MyCustomElements = new Components();

MyCustomElements.set('array', ArrayElement);
MyCustomElements.set('string', InputElement);
MyCustomElements.set('boolean', StateElement);
MyCustomElements.set('radio', StateElement);
MyCustomElements.set('checkbox', StateElement);
MyCustomElements.set('enum', FieldsetElement);
MyCustomElements.set('number', InputElement);
MyCustomElements.set('integer', InputElement);
MyCustomElements.set('object', FieldsetElement);
MyCustomElements.set('list', ListElement);
MyCustomElements.set('textarea', TextareaElement);

See the file NativeElements.ts for an example.

<template>
  <FormSchema v-model="model" :schema="schema" :components="components"/>
</template>

<script>
  import FormSchema from '@formschema/native'
  import { MyCustomElements } from './MyCustomElements'

  export default {
    data: () => ({
      schema: { /* ... */ },
      components: MyCustomElements,
      model: {}
    }),
    components: { FormSchema }
  }
</script>

ElementUI Example

Contributing

Please see contributing guide.

License

Under the MIT license. See LICENSE file for more details.

1.0.0

5 years ago