Rich Webix Form Editor with Automatic Configuration

Developers don’t like monotonous coding. But even with a number of tools and frameworks one often has to configure big forms by hand. Webix offers to exclude this task from your daily routine with the help of a custom Form Editor tool which was built totally on Webix public API.

Form Editor

The widget allows editing complex form data without prior configuration – all you need is to provide the data while the tool builds the layout automatically. It features Webix data loading API alongside with common Form methods for working with values.

You can initialize the Form Editor with an extremely short code line:

webix.ui({ view:"form-editor", data:data });

And you’ll get the rich and functional UI:

Form editor

Webix is as laconic as ever! So don’t hesitate to play with the live demo and look into the source code while following the further story.

Automatic UI Constructor

The Form Editor tool saves you from hard labour:

  1. For editing an associative array it creates a Form with text fields. Each text field takes name, label and value from the corresponding property-value pair:
    //data
    { name:"Vet Clinic", license:"active"}
    //output
    {view:"subform", elements:[
        { view:"text", label:"Name", name:"name", value:"Vet Clinic"},
        { view:"text", label:"License", name:"license", value:"active"}
    ]}
  2. If such hash belongs to a plain Javascript array, the whole array is parsed into an editable DataTable. Its columns are configured on the base of the first element in the array from which they take id and title.
    //data
    [  { owner:"Claire", pet:"cat Purr"},  { owner:"Eric", pet:"dog Adele" } ]
    //output
    { view:"subgrid", name:"clients", rows:[
          { view:"datatable", editable:true, footer:true, columns:[
             { id:"owner", title:"Owner", editor:"text"},
             { id:"pet", title:"Pet", editor:"text"}
          ], data: [{ owner:"Claire", pet:"cat Purr"},  { owner:"Eric", pet:"dog Adele" }]
    }]}
  3. If the Form Editor encounters an array or hash as a property value, it embeds another Form/DataTable for plain/associative array respectively. Note that the DataTable has to build a subview for such a task.

    Not to over-exercise our imagination, let’s visualize it. Here’s our initial data set:

    { name:"Vet Clinic", license:{ from:"2015-05-05", to:"2017-05-05"}, clients: [
       { owner:"Claire", pet:{ name:"Purr", animal: "cat"}},
       { owner:"Eric", pet:{ name:"Adele", animal: "dog" }}
    ] }

    And now let’s look at the output:

    { view:"subform",elements:[
        { view:"text",name:"name",label:"Name",value:"Vet Clinic"},
        { template:"License"},
        { view:"subform",name:"license",elements:[
            { view:"text",name:"from",label:"From",value:"2015-05-05"},
            { view:"text",name:"to",label:"To",value:"2017-05-05"}
        ]},
        { template:"Clients"},
        { view:"subgrid",name:"clients", rows:[
            { view:"datatable",editable:true, columns:[
                {id:"owner",header:"Owner",editor:"text",fillspace:1}
            ], subview:{
                rows:[
                    { template":"Pet},
                    { view:"subform",name:"pet", elements:[
                        { view:"text",name:"name",label:"Name",value:"Purr"},
                        { view:"text",name:"animal",label:"Animal",value:"cat "}
                    ]}
                ]}
            }
        ]}
    ]}

This data has been converted to a Form with three elements:

  • Text for editing clinic name;
  • Form for editing license data;
  • DataTable for editing clients.

The “clients” Datatable, in turn, has produced a subview with a Form for editing pet data.

Working with Form Editor

The Form Editor mimics Form API. You can input the data using Webix loading and parsing API, namely:

  • define inline data in the constructor, or parse it dynamically;
  • define url for fetching remote data, or load it afterwards;
  • use setValues method for inline data like it is with Webix Form

You can output the data by applying a Form-specific getValues method.

Each time you change the data in the editor, it issues the onChange event with the current value as a parameter.

DIY guidelines

The chapter is dedicated to those who want to step aside of the input-output approach and uncover the black box.

The Form Editor widget is built with Webix PRO version. It inherits from:

  • Layout widget with rows collection for arranging the elements;
  • AtomDataLoader mixin to allow for standard data loading operations.

The new widget possesses three public methods of its own:

webix.protoUI({
   name:"form-editor",
   $init:function(config){
     //creating placeholder for the future form while the data loads
     config.rows = [{template:" "}];
    },
    getValues:function(){...}, //getting data
    setValues:function(){...}, //setting data
    clear:function(){} // clearing layout
}, webix.AtomDataLoader, webix.ui.layout);

The layout contains customized Webix Form and DataTable widgets called Subform and Subgrid. Subform is created for associative arrays (hashes) while an editable Subgrid allows editing the array of hashes.
Subgrid and Subform act as form elements and feature common API:

  1. have getValue, setValue and clear methods;
  2. can receive the data from the parent form or datatable according the name property

Once the data is loaded to a Form editor, the newly configured layout replaces the previous one. To achieve this, we need to intercept the default loading logic with the help of the dedicated $onLoad method:

webix.protoUI({
   name:"form-editor",
   $onLoad:function(data, driver){
      this.setValues(data);
      return true;
    },
    setValues:function(values){
       webix.ui([this._getConfig(values)], this);
    },
    _getConfig:function(data){
        return /*configuration object*/;
    }
});

By default the loader either parses the whole dataset into a widget’s DataStore or passes the first record to the widget’s setValues method. As we don’t want anything of this kind, we have declared the custom setValues method and return true for the $onLoad to abort the default logic. The setValues calls webix.ui constructor to reset rows collection with the new one.

The tool has a number of conventionally private methods like the above mentioned _getConfig that turn data into JSON configuration objects. These methods have nothing to do with private methods and properties of Webix views, so the Form Editor can be used with the minified webix.js file.

Subforms and Subgrids are filled with data during creation. At the same time, DataTable subviews are filled dynamically depending on the data of a parent DataTable. Also, we have to update the master record with subview data each time it changes. That is why SubForm and SubGrid have standardized API: the getValue, setValue methods and the onChange event.

Summing Up

Form Editor tool is available for Webix PRO users only as it utilizes such PRO functionality as DataTable subviews. On the positive side, it is created with Webix public API only, and if you don’t need to edit grid-like data, feel free to get rid of the unnecessary code and adjust the tool for your needs.

The widget is available on Github in Webix repository of extra components and integrations. You can not only use these tools in your projects, but also suggest your “homemade” widgets via pull requests. Who knows, maybe your colleagues from abroad are looking for the same solution? 😉