Vue.js Dynamic Bootstrap Form Fields Generator From JSON Schema in Browser Using Javascript Full Project For Beginners

Vue.js Dynamic Bootstrap Form Fields Generator From JSON Schema in Browser Using Javascript Full Project For Beginners
  • Post author:
  • Post category:Vue
  • Post comments:0 Comments

 

Welcome folks today in this blog post we will be building a dynamic bootstrap form fields generator from json schema in browser using javascript. All the full source code of the application is given below.

 

 

Get Started

 

 

In order to get started you need to make an index.html file and copy paste the following code

 

index.html

 

 

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css"/>
<h1 class="text-center">A demo of vue-form-generator</h1>
<div class="container" id="page">
  <div class="container col-sm-6" id="editor">
    <div class="panel panel-default">
      <div class="panel-heading">Editor</div>
      <div class="panel-body">
        <vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
      </div>
    </div>
  </div>

  <div class="container col-sm-6" id="form">
    <div class="panel panel-default">
      <div class="panel-heading">Form</div>
      <div class="panel-body">
        <vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
      </div>
    </div>

    <div class="panel panel-default">
      <div class="panel-heading">Schema</div>
      <div class="panel-body">
        <pre v-if="model" v-html="prettyJSON(schema)"></pre>
      </div>
    </div>
    
    <div class="panel panel-default">
      <div class="panel-heading">Model</div>
      <div class="panel-body">
        <pre v-if="model" v-html="prettyJSON(model)"></pre>
      </div>
    </div>
  </div>

  </div>

  <script src="https://unpkg.com/vue"></script>
  <script src="https://unpkg.com/vue-form-generator"></script>
<script src="https://unpkg.com/vue-multiselect@2.1.0"></script>

 

 

Now make a style.css file and copy paste the below code

 

style.css

 

@import url("https://unpkg.com/vue-form-generator@2.2.2/dist/vfg.css");
@Import url("https://unpkg.com/vue-multiselect@2.1.0/dist/vue-multiselect.min.css");

html {
    font-family: Tahoma;
    font-size: 14px;
}

body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 1.42857143;
    color: #333;
}
#page {
  display:flex;
  max-width: 100%;
}
pre {
    overflow: auto;
}
    pre .string { color: #885800; }
    pre .number { color: blue; }
    pre .boolean { color: magenta; }
    pre .null { color: red; }
    pre .key { color: green; }    

h1 {
    text-align: center;
    font-size: 36px;
    margin-top: 20px;
    margin-bottom: 10px;
    font-weight: 500;
}

fieldset {
    border: 0;
}

.panel {
    margin-bottom: 20px;
    background-color: #fff;
    border: 1px solid transparent;
    border-radius: 4px;
    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
    box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
    border-color: #ddd;
}

.panel-heading {
    color: #333;
    background-color: #f5f5f5;
    border-color: #ddd;

    padding: 10px 15px;
    border-bottom: 1px solid transparent;
    border-top-left-radius: 3px;
    border-top-right-radius: 3px;        
}

.panel-body {
    padding: 15px;
}               

.field-checklist .wrapper {
    width: 100%;
}
.form-group label {
  width: 30%;
  float: left;
  text-align:right;
  vertical-align: middle;
  height: 30px;
  padding: 5px 10px;
}
.form-group > div {
  width: 70%;
}
.form-group > div.errors {
  width: 100%;
  padding-left: 30%
}

 

See also  Build a Vue.js Drawing Paint HTML5 Canvas Web App in Browser Using Ionic Framework and Javascript Full Project For Beginners

 

Now make a script.js file and copy paste the following code

 

script.js

 

var editorFields = [
        {
          type: "vueMultiSelect",
          label: "Type",
          model: "type",
          hint: "email, checkbox, select, etc.",
          required: true,
          values:  [
              {id:"input", name:"Short text"}, 
              {id:"textArea", name:"Long text"},
              {id:"select", name:"One choice from a list"},
              {id:"checklist", name:"Multiple choices from a list"},
              {id:"checkbox", name:"Simple on/off switch"},
              {id:"switch", name:"Fancy on/off switch"},
              {id:"email", name:"Email"},
              {id:"name", name:"Name"},
              {id:"password", name:"Password"}
            ],
          styleClasses: "col-sm-12"
        }, 
        {
          type: "input",
          inputType: "text",
          label: "Label",
          model: "label",
          required: true,
          styleClasses: "col-sm-12",
          validator: VueFormGenerator.validators.required
        },  
        {
          type: "select",
          label: "Width",
          model: "width",
          required: true,
          values: function() {
            return [
              {name:"Full Row", id:"col-md-12"}, 
              {name:"5/6 Row", id:"col-md-10"},
              {name:"3/4 Row", id:"col-md-9"},
              {name:"2/3 Row", id:"col-md-8"},
              {name:"1/2 Row", id:"col-md-6"},
              {name:"1/3 Row", id:"col-md-4"},
              {name:"1/4 Row", id:"col-md-3"},
              {name:"1/6 Row", id:"col-md-2"}
            ]},
          get: function(m) {
            return m.width;
          },
          set: function(m, v) {
            m.width = v;
            m.styleClasses = ["col-sm-12"];
            m.styleClasses.push(v);
          },
          styleClasses: "col-sm-12"
        },
        {
          type: "input",
          inputType: "text",
          label: "Hint",
          model: "hint",
          styleClasses: "col-sm-12"
        },
        {
          type: "switch",
          label: "Required",
          model: "required",
          styleClasses: "col-sm-4 offset-sm-3"
        },
        {
          type: "switch",
          label: "Readonly",
          model: "readonly",
          styleClasses: "col-sm-5"
        },
        {
          type: "textArea",
          label: "Options",
          model: "values",
          hint: "List of options (one option per row)",
          rows: 5,
          get: function(m) {
            if (m.values === undefined) {
              m.values = [];
            }
            return m.values.join("\n");
          },
          set: function(m, v) {
            m.values = [];
            var ops = v.split("\n");
              ops.forEach(function(v) {
              m.values.push(v.trim());
            });
          },
          visible: function(model) {
            //visible if business is selected
            return model && (
              model.type == "select" || 
              model.type == "radios" || 
              model.type == "checklist"
            );
          },    
          styleClasses: "col-sm-12"
        },  
        {
          type: "label",
          label: "Advanced Options",
          model: "",
          styleClasses: "col-sm-12 panel-heading"
        },
        {
          type: "input",
          inputType: "text",
          label: "Field Name",
          model: "model",
          hint: "Name for your data field (alphabetic characters ONLY)",
          styleClasses: "col-sm-12",
          required: true,
          validator: VueFormGenerator.validators.alpha
        },
        {
          type: "input",
          inputType: "text",
          label: "Dynamic Visibility (Progressive Disclosure)",
          model: "visibility",
          styleClasses: "col-sm-12"
        }  
];
var editorModel = {
  type: "input",
  inputType: "text",
};
var formFields = [
  {}
];
var formModel = {};

var editorVM = new Vue({
  el: "#editor",

  components: {
    "vue-form-generator": VueFormGenerator.component
  },

  methods: {
    prettyJSON: function(json) {
      if (json) {
        json = JSON.stringify(json, undefined, 4);
        json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
        return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function(match) {
          var cls = 'number';
          if (/^"/.test(match)) {
            if (/:$/.test(match)) {
              cls = 'key';
            } else {
              cls = 'string';
            }
          } else if (/true|false/.test(match)) {
            cls = 'boolean';
          } else if (/null/.test(match)) {
            cls = 'null';
          }
          return '<span class="' + cls + '">' + match + '</span>';
        });
      }
    }
  },

  data: {
    model: editorModel,
    schema: {
      fields: editorFields
    },

    formOptions: {
      validateAfterLoad: true,
      validateAfterChanged: true
    }
  }
});

var formVM = new Vue({
  el: "#form",

  components: {
    "vue-form-generator": VueFormGenerator.component
  },

  methods: {
    prettyJSON: function(json) {
      if (json) {
        json = JSON.stringify(json, undefined, 4);
        json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
        return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function(match) {
          var cls = 'number';
          if (/^"/.test(match)) {
            if (/:$/.test(match)) {
              cls = 'key';
            } else {
              cls = 'string';
            }
          } else if (/true|false/.test(match)) {
            cls = 'boolean';
          } else if (/null/.test(match)) {
            cls = 'null';
          }
          return '<span class="' + cls + '">' + match + '</span>';
        });
      }
    }
  },

  data: {
    model: formModel,
    schema: {
      fields: [editorModel]
    },

    formOptions: {
      validateAfterLoad: true,
      validateAfterChanged: true
    }
  }
});

 

See also  Vue.js Clipboard.js Example to Copy Text to Clipboard From Input Field or TextArea Widget on Button Click in Browser Using Javascript Full Project For Beginners

 

Now if you open the index.html file inside the browser you will see the below screenshot

 

Leave a Reply