Giter VIP home page Giter VIP logo

quick-form's Introduction

Quick Form

Quick HTML forms.

Features:

  • Easy to use API
  • Dynamic form generation
  • Supports bulma
  • Can be used standalone or as a VueComponent

Installation

Pre-requisites:

  • Bulma (If using standard quick form fields)
  • Vue 2
  • A module bundler (Webpack, ParcelJS, etc)

npm i quick-form

Usage Examples

As a Vue component

import Vue from "vue";
import { QuickForm } from "quick-form";

const Form = Vue.extend({
    components: { QuickForm },
    template: `
        <QuickForm
            :fields="fields
            @submit="onSubmit($event)"></QuickForm>
    `,

    data() {
        return {
            fields: [
                { type: "Input", model: "test1", label: "Field 1", inputType: "text" },
                { type: "Input", model: "test2", label: "Field 2", inputType: "text" },
                { type: "Input", model: "test4", label: "Field 4", inputType: "number" },
                { type: "Submit" }
            ],
        }
    },

    methods: {
        onSubmit(document: object) {
            api.post(document)
        }
    }
})

Standalone (Vanilla)

import Vue from "vue";
import { QuickFormVanilla } from "quick-form";

const form = new QuickFormVanilla({
    fields: [
        { type: "Input", model: "test1", label: "Field 1", inputType: "text" },
        { type: "Input", model: "test2", label: "Field 2", inputType: "text" },
        { type: "Input", model: "test4", label: "Field 4", inputType: "number" },
        { type: "Submit" }
    ]
});

const main = document.getElementById("main")!;
main.appendChild(form);

Vue Component

<QuickForm :fields="fields"><QuickForm>

Properties

  • fields (Required) An array of QuickField objects representing the form (required). QuickFields are documented later.
  • document (Optional) The object the form data is saved to
  • cancellable (Optional) Determines whether or not to show the cancel button
  • resettable (Optional) Determines whether or not to show the reset button

Events

  • submit Fired when the form is submitted, passes document as the first argument to the callback
  • input Fired when the form data is changed, passes document as the first argument to the callback

Vanilla Usage

QuickFormVanilla has the following interface:

class QuickFormVanilla {
    readonly vue: Vue;
    readonly element: HTMLElement;

    constructor({ fields, quickFormComponent }: {
        fields: QuickField[],

        /** Use a Custom version of the quick form component */
        quickFormComponent?: VueConstructor;
    });

    on(event: "submit", cb: (formData: object) => void): this;
    on(event: string, cb: (...args: any[]) => void): this;
}

Fields

The following interfaces represent fields that can be passed to QuickForm

export interface QuickField<T = any> {
    /** The type of field. Equivalent to the name of the field component. */
    type: string;

    /** Default value of the field */
    default?: T;

    /**
     * When a user submits a quick form, the instance will emit a submit event
     * that returns an object with all the values the user supplied. model represents
     * the field of that object the QuickField value will be attached to.
     *
     * Internally, this value is what v-model gets set to on the input. For
     * more information visit: https://vuejs.org/v2/api/#v-model
     */
    model?: string;

    /** The field is required, defaults to true */
    required?: boolean;

    /** A label for the field to present to the user */
    label?: string;

    /**
     * If the value of the specified value does not equal the value specified
     * by is, hide this field.
     */
    showIf?: { field: string, is: any };

    /**
     * A custom validator for the field. Can be async.
     *
     * If the function returns true, this.isInvalid will be set to true.
     * If the function returns a string, this.isInvalid will be set to true
     * and the errorMessage will be set to said string.
     *
     * Note: Will mot work if field has been passed through JSON.stringify.
     *
     * @param val - The value the user has entered for the field in the form
     */
    validator?(val: T): string | undefined | Promise<string | undefined>;

    /**
     * An error message to show the user.
     * This value is automatically set by the validator function.
     * It's best to not set this to anything.
     */
    errorMessage?: string;

    /** Additional data, passed to the corresponding QuickFieldTemplate of this type */
    [extensions: string]: any;
}

export interface QuickInputField<T = any> extends QuickField<T> {
    type: "Input";
    inputType: "text" | "number" | "password" | "email" | "tel" | "url" | "color";
}

export interface QuickTextareaField<T = any> extends QuickField<T> {
    type: "Textarea";
}

export interface QuickSelectField<T = any> extends QuickField<T> {
    type: "Select";
    options: { label: string; value: any }[];
}

export interface QuickCheckboxField<T = any> extends QuickField<T> {
    type: "Checkbox";
}

export interface QuickRadioField<T = any> extends QuickField<T> {
    type: "Radio";
    options: { label: string; value: any }[];
}

export interface QuickSubmitField<T = any> extends QuickField<T> {
    type: "Submit";
}

export interface QuickFormField<T = any> extends QuickField<T> {
    type: "QuickForm";
    fields: QuickField[];
}

quick-form's People

Contributors

dependabot[bot] avatar drew-y avatar nathanbussey avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

quick-form's Issues

Embedded quickform values not populating

With the QuickForm component inside another QuickForm similar to below, the inner QuickForm component values do not auto populate

{ type: "Input", inputType: "number", model: "dispatcherProgram", label: "Dispatcher Program Number" },
    { type: "Input", inputType: "number", model: "cycleStartAddr", label: "Cycle Start Address" },
    { type: "Input", inputType: "number", model: "cycleStartDelay", label: "Cycle Start Delay" },
    { type: "Checkbox", model: "isNGC", label: "is NGC" },
    {
        type: "Select", model: "type", label: "Communication", options: [
            { label: "TCP", value: "TCP" },
            { label: "Serial", value: "serial" },
        ]
    },
    { type: "QuickForm", model: "link", showIf: { field: "type", is: "TCP" }, fields: [
        { type: "Input", inputType: "text", model: "host", label: "CNC IP Address" },
        { type: "Input", inputType: "number", model: "port", label: "CNC Port Number" }
    ]},
    { type: "QuickForm", model: "link", showIf: { field: "type", is: "serial" }, fields: [
        { type: "Input", inputType: "string", model: "devPort", label: "CNC Port Number" },
        { type: "Input", inputType: "number", model: "baudRate", label: "Baud Rate" },
    ]},
    { type: "Submit" }

0.6.0-1 broke the QuickForm component

After updating to 0.6.0-1 the QuickForm component breaks in Vue with the following error

TS2345: Argument of type '{ template: any; components: { QuickForm: VueConstructor<{ shouldShowField(field: QuickField): boolean; submit(): void; } & { fields: QuickField[]; document: any; cancellable: boolean; resettable: boolean; } & Vue>; }; data(this: Vue): { ...; }; created(): void; methods: { ...; }; }' is not assignable to parameter of type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>'.
Types of property 'components' are incompatible.
Type '{ QuickForm: VueConstructor<{ shouldShowField(field: QuickField): boolean; submit(): void; } & { fields: QuickField[]; document: any; cancellable: boolean; resettable: boolean; } & Vue>; }' is not assignable to type '{ [key: string]: VueConstructor | FunctionalComponentOptions<any, PropsDefinition> | ComponentOptions<never, any, any, any, any, Record<string, any>> | AsyncComponent<any, any, any, any>; }'.
Property 'QuickForm' is incompatible with index signature.
Type 'VueConstructor<{ shouldShowField(field: QuickField): boolean; submit(): void; } & { fields: QuickField[]; document: any; cancellable: boolean; resettable: boolean; } & Vue>' is not assignable to type 'VueConstructor | FunctionalComponentOptions<any, PropsDefinition> | ComponentOptions<never, any, any, any, any, Record<string, any>> | AsyncComponent<any, any, any, any>'.
Type 'VueConstructor<{ shouldShowField(field: QuickField): boolean; submit(): void; } & { fields: QuickField[]; document: any; cancellable: boolean; resettable: boolean; } & Vue>' is not assignable to type 'VueConstructor'.
Types of property 'extend' are incompatible.
Type '{ <Data, Methods, Computed, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<{ shouldShowField(field: QuickField): boolean; submit(): void; } & { fields: QuickField[]; document: any; cancellable: boolean; resettable: boolean; } & Vue, Data, Methods, Computed, PropNames> |...' is not assignable to type '{ <Data, Methods, Computed, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<Vue, Data, Methods, Computed, PropNames> | undefined): VueConstructor<Data & Methods & Computed & Record<PropNames, any> & Vue>; <Data, Methods, Computed, Props>(options?: ThisTypedComponentOptionsWithReco...'.
Type 'Vue.VueConstructor' is not assignable to type 'import("/Users/bkelley/dev/versabuilt/millipede/robot2cnc/node_modules/vue/types/vue").VueConstructor'.
Types of property 'extend' are incompatible.
Type '{ <Data, Methods, Computed, PropNames extends string = never>(options?: import("/Users/bkelley/dev/versabuilt/millipede/robot2cnc/node_modules/quick-form/node_modules/vue/types/options").ThisTypedComponentOptionsWithArrayProps<any, Data, Methods, Computed, PropNames> | undefined): Vue.VueConstructor<...>; <Data, Met...' is not assignable to type '{ <Data, Methods, Computed, PropNames extends string = never>(options?: import("/Users/bkelley/dev/versabuilt/millipede/robot2cnc/node_modules/vue/types/options").ThisTypedComponentOptionsWithArrayProps<any, Data, Methods, Computed, PropNames> | undefined): import("/Users/bkelley/dev/versabuilt/millipede/robot2cnc/n...'.
Types of parameters 'options' and 'definition' are incompatible.
Type 'FunctionalComponentOptions<Record<any, any>, any[]>' is not assignable to type 'ThisTypedComponentOptionsWithArrayProps<any, any, any, any, any>'.
Type 'FunctionalComponentOptions<Record<any, any>, any[]>' is not assignable to type 'ComponentOptions<any, any, any, any, any[], Record<any, any>>'.
Types of property 'render' are incompatible.
Type '((this: undefined, createElement: CreateElement, context: RenderContext<Record<any, any>>) => VNode) | undefined' is not assignable to type '((createElement: CreateElement, hack: RenderContext<Record<any, any>>) => VNode) | undefined'.
Type '(this: undefined, createElement: CreateElement, context: RenderContext<Record<any, any>>) => VNode' is not assignable to type '(createElement: CreateElement, hack: RenderContext<Record<any, any>>) => VNode'.
Types of parameters 'createElement' and 'createElement' are incompatible.
Type 'Vue.CreateElement' is not assignable to type 'import("/Users/bkelley/dev/versabuilt/millipede/robot2cnc/node_modules/vue/types/vue").CreateElement'.
Types of parameters 'tag' and 'tag' are incompatible.
Type 'string | VueConstructor | FunctionalComponentOptions<any, PropsDefinition> | ComponentOptions<never, any, any, any, any, Record<string, any>> | AsyncComponent<any, any, any, any> | (() => Component<...>) | undefined' is not assignable to type 'string | VueConstructor | FunctionalComponentOptions<any, PropsDefinition> | ComponentOptions<never, any, any, any, any, Record<string, any>> | AsyncComponentPromise<any, any, any, any> | AsyncComponentFactory<...> | (() => Component<...>) | undefined'.
Type 'VueConstructor' is not assignable to type 'string | VueConstructor | FunctionalComponentOptions<any, PropsDefinition> | ComponentOptions<never, any, any, any, any, Record<string, any>> | AsyncComponentPromise<any, any, any, any> | AsyncComponentFactory<...> | (() => Component<...>) | undefined'.
Type 'VueConstructor' is missing the following properties from type 'VueConstructor': observable, version

Default values not populating on showIf fields

For example, the fields Port, and Baud Rate are not populated when type = Serial in the following example.

{
    type: "Select", model: "type", label: "Communication", options: [
        { label: "TCP", value: "TCP" },
        { label: "Serial", value: "Serial" },
    ]
},
{ type: "QuickForm", model: "link", showIf: { field: "type", is: "TCP" }, fields: [
    { type: "Input", inputType: "text", model: "host", default: "192.168.50.4", label: "IP Address" },
    { type: "Input", inputType: "number", model: "port", default: "9000", label: "Port Number" }
]},
{ type: "QuickForm", model: "link", showIf: { field: "type", is: "Serial" }, fields: [
    { type: "Input", inputType: "string", default: "/dev/ttyUSB0", model: "devPort", label: "Port" },
    { type: "Input", inputType: "number", default: 115200, model: "baudRate", label: "Baud Rate" }
]}

Default value

A default value attribute would be very beneficial

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.