Code Monkey home page Code Monkey logo

js_composer's Introduction

JScomposer

Generate HTML forms for generating strongly-type JSON objects! Use JSON-Schema (http://json-schema.org) to define the structure of your objects, then tell JSComposer to build a form using one of your object schemas. It's even easier than it sounds.

Why JSComposer?

JSComposer is built using pure JavaScript. Its only dependency is tv4, which it uses for form validation and schema management. It uses the AMD/Require.JS module structure (with each module corresponding to an object).

JSComposer uses CSS classes and HTML frameworks defined by Bootstrap to arrange the forms it generates, making it very simple to style (just include a copy of bootstrap.css for a nice, basic look).

JSComposer can handle the JSON Schema attributes "anyOf", "allOf", and "oneOf" with ease by "resolving" all referenced schema at the time of instantiation. This means you can easily reuse existing schema definitions with slight modifications, such as changing a title, or increasing the minimum value for an integer.

JSComposer also resolves references across one or more schemas. Additional schemas can be loaded explicitly using JSComposer.Schema.LoadSchema, or implicitly by using a $ref schema to refer to a new schema URI.

More importantly, JSComposer is extensible. If you're not satisfied with the built-in handling of a particular schema or otherwise require customization, it's as simple as extending the base JSComposer.Instance class with your own functionality and registering it for a URI (or several). A good example of this would be a "date" field:

JSComposer = require('JSComposer');
// Alternatively...
Instance = require('JSComposer/Instance');
// Or even
SelectInstance = require('JSComposer/Instance/SelectInstance');

var my_schema = {
    "id": "http://mysite.com/myschema#",
    "definitions": {
        // ...
        "date": {"type":"string","format":"[0-9]{4}/[0-9]{2}/[0-9]{2}"}     // There are better regexes, but at least I'm using ISO
    }
};

function MyDate(context, parent, type_desc, value) {
    Instance.apply(this, arguments);        // Chain the constructor; it does things for you, like giving you a container to render into

    // The default instance for 'enum' is a select box, so lets make a bunch of those because this is an example.
    // Be as fancy as you want, otherwise.
    this.year_selector  = Instance.CreateInstance({'enum':['1980', '1981', '1982', ...]});
    this.month_selector = Instance.CreateInstance({'enum':['01','02','03', ...]});
    this.day_selector   = Instance.CreateInstance({'enum':['01','02','03', ...]});
}

MyDate.prototype = new JSComposer.Instance();
MyDate.prototype.constructor = MyDate;

MyDate.prototype.Render = function(target) {
    this.elements.ctr.appendChild(this.year_selector);
    this.elements.ctr.appendChild(this.year_selector);
    this.elements.ctr.appendChild(this.year_selector);
    target.appendChild(this.elements.ctr);
}

MyDate.prototype.GetValue = function() {
    var a = [this.year_selector, this.month_selector, this.day_selector];
    return a.join('/');
}

// Register the new object constructor
JSComposer.Instance.RegisterInstance("http://mysite.com/myschema#/definitions/date", MyDate);

// Now any time JSComposer.Instance.CreateInstance({"$ref":"http://mysite.com/myschema#/definitions/date"})
// is invoked, your object will be used!

You only have to worry about exporting two functions: Render(target) and GetValue(), so go wild! (in the case of Render, you can use the default Instance function assuming all of your additional elements are added to this.elements.ctr ahead of time)

Usage

EXTREMELY Basic Usage:

    require('JSComposer', function(JSComposer) {
        var d       = document.getElementById('jsc_form'),
            form    = new JSComposer.Form({'type':'string'}, "Look! A Form!");

        form.Render(d);
    });

Of course, you can be as complicated or as simple as you like. Consider this basic schema defining a user for your... I don't know... pet owners forum? Just look already.

    require('JSComposer', function(JSComposer) {
        var d       = document.getElementById('jsc_form'),
            schema  = {
                "type":             "object",
                "title":            "User",
                "properties":       {
                    "id":               {"type":"string"},
                    "password":         {"type":"string"},
                    "email_updates":    {"type":"boolean"},
                    "favorite_pets":    {
                        "enum":             [
                            "Cats",
                            "Dogs",
                            "Horses",
                            "Rabbits",
                            "Guinea Pigs",
                            "Mice",
                            "Rocks"             // Fine, Ricky. Rocks can be pets. Whatever.
                        ]
                    }
                },
                "required":             [
                    "id",
                    "password",
                    "email_updates"
                ]
            },
            form    = new JSComposer.Form(schema, {});

        form.Render(d);
    });

Of course, these kinds of JSON Schema would be a pain to write on every page you needed them, so if your collection of schemas is getting large enough that you want to put it in its own schema file, you can easily refer to it! Simply create a reference to the schema definition (see the $ref property in JSON schema) and JSComposer will automatically load the schema for you! Hooray!

    require('JSComposer', function(JSComposer) {
        var d       = document.getElementById('jsc_form'),
            form    = new JSComposer.Form(JSComposer.Schema.Ref('#/definitions/pet_owner', 'http://petownerparadiso.info/schema#'), {});

            // {"$ref":"http://petownerparadiso.info/schema#/definitions/pet_owner"} works just as well

        form.Render(d);
    });

Hell, you could use JSComposer to build your schema:

    require('JSComposer', function(JSComposer) {
        var d       = document.getElementById('jsc_form'),
            form    = new JSComposer.Form(JSComposer.Schema.Ref('#', 'http://json-schema.org/schema#'), {});

        form.Render(d);
    });

Uh-oh

Ricky's insisting plants can be pets now. Ricky's a jerk. I don't even know how he got administrator access to the database. Regardless, it's getting to be a pain to update my schema definition every time he adds another pet type to the database. I wish there was some way to make this easier.

Oh, wait! There is a way! Instead of storing my enumeration of pet types directly in my schema, I can refer to another URL on my site that will query the database and produce a valid schema!

    {
        ...
                    "favorite_pets":    {"$ref":"http://petownerparadiso.info/api/pet_types/schema#"}
        ...
    }

And the return value from http://petownerparadiso.info/api/pet_types/schema# is:

{
    "enum":     [
        "Cats",
        "Dogs",
        "Horses",
        "Rabbits",
        "Guinea Pigs",
        "Mice",
        "Rocks",
        "Plants",
        "Snowmen"
    ]
}

SERIOUSLY RICKY? Okay, there's NO way snowmen are pets. Quit messing around with my site!

js_composer's People

Contributors

soup-in-boots avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

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.