Visual Form Builder With JavaScript – EasyJsonForm.js

Category: Form , Javascript | October 15, 2023
Author:ricardolima-xyz
Views Total:309 views
Official Page:Go to website
Last Update:October 15, 2023
License:MIT

Preview:

Visual Form Builder With JavaScript – EasyJsonForm.js

Description:

EasyJsonForm.js is a free open-source JavaScript library that provides a visual interface to help you easily create HTML forms.

The form (and its filled-in values) can be exported as JSON, Raw Value, and HTML.

How to use it:

1. Download and load the easyjsonform.js library in the document.

<script src="./easyjsonform.js"></script>

2. Sample form structure.

let sampleEasyJsonFormStructure = 
    [
      {"type":"text","label":"This is a character restricted text field","customattribute":"Custom attribute for character restricted text","mandatory":true,"properties":{"length":{"measure":"bycharacter","min":2,"max":100}},"value":"Test value for character restricted text area"},
      {"type":"text","label":"This is a word restricted text field","customattribute":"Custom attribute word restricted for text","mandatory":true,"properties":{"length":{"measure":"byword","min":2,"max":100}},"value":"Test value for word restricted text area"},
      {"type":"text","label":"This is an unrestricted text field","customattribute":"Custom attribute for unrestricted text","mandatory":true,"properties":{"length":{"measure":"no","min":2,"max":100}},"value":"Test value for unrestricted text area"},
      {"type":"textgroup","label":"This is a text group field","customattribute":"Custom attribute for text group","mandatory":true,"properties":{"items":["a","b","c"]},"value":['å','∫','ç']},
      {"type":"number","label":"This is a number field","customattribute":"Custom attribute for number","mandatory":true,"properties":null,"value":null},
      {"type":"singlechoice","label":"This is a single choice field","customattribute":"Custom attribute for single choice","mandatory":true,"properties":{"items":["m","n","o"]},"value":"1"},
      {"type":"multiplechoice","label":"This is a multiple choice field","customattribute":"Custom attribute for multiple choice","mandatory":true,"properties":{"items":["x","y","z"]},"value":["0","1","0"]},
      {"type":"file","label":"This is a file field","customattribute":"Custom attribute for file","mandatory":true,"properties":{"filetypes":["application/pdf","image/jpeg","image/bmp","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-powerpoint"],"maxsize":42},"value":null},
      {"type":"file","label":"This is another file field","customattribute":"Custom attribute for another file","mandatory":true,"properties":{"filetypes":["image/bmp","image/gif"],"maxsize":42},"value":'somefile'},
];

3. Apply custom styles to form fields.

let sampleEasyJsonFormStyle = {
    Builder: { 
        classList: [],
        style: {},
    },
    BuilderTable: {
        classList: ['table'],
        style: {},
    },
    BuilderToolbar: { 
        classList: ['btn-group', 'mx-auto'],
        style: {},
    },
    BuilderToolbarButton: { 
        classList: ['btn', 'btn-outline-primary', 'btn-sm'],
        style: {},
    },
    BuilderFieldTooldbar: {
        classList: ['btn-group','w-100'],
        style: {},
    },
    BuilderFieldTooldbarButton: {
        classList: ['btn','btn-outline-primary', 'p-2'],
        style: {},
    },
    BuilderFieldTooldbarDeleteButton: {
        classList: ['btn','btn-outline-danger', 'p-2'],
        style: {},
    },
    Form: { 
        classList: [],
        style: {},
    },
    FieldFile: {
        classList: ['my-3'],
        style: {},
    },
    FieldFileLabel: {
        classList: ['form-label'],
        style: {},
    },
    FieldFileInput: {
        classList: ['form-control'],
        style: {},
    },
    FieldFileValue: {
        classList: ['d-flex', 'flex-nowrap', 'btn-group'],
        style: {},
    },
    FieldFileLink: {
        classList: ['btn', 'btn-outline-primary', 'flex-grow-1', 'text-start'],
        style: {},
    },
    FieldFileClear: {
        classList: ['btn', 'btn-outline-danger', 'flex-grow-0'],
        style: {},
    },
    FieldMultiplechoice: {
        classList: ['my-3'],
        style: {},
    },
    FieldMultiplechoiceLabel: {
        classList: ['form-label'],
        style: {},
    },
    FieldMultiplechoiceGroup: {
        classList: ['d-flex','justify-content-start','align-items-start'],
        style: {},
    },
    FieldMultiplechoiceItem: {
        classList: ['form-check', 'flex-grow-1'],
        style: {},
    },
    FieldMultiplechoiceItemLabel: {
        classList: ['form-check-label'],
        style: {},
    },
    FieldMultiplechoiceItemInput: {
        classList: ['form-check-input'],
        style: {},
    },
    FieldSinglechoice: {
        classList: ['my-3'],
        style: {},
    },
    FieldSinglechoiceLabel: {
        classList: ['form-label'],
        style: {},
    },
    FieldSinglechoiceSelect: {
        classList: ['form-select'],
        style: {},
    },
    FieldNumber: {
        classList: ['my-3'],
        style: {},
    },
    FieldNumberLabel: {
        classList: ['form-label'],
        style: {},
    },
    FieldNumberInput: {
        classList: ['form-control'],
        style: {},
    },
    FieldText: {
        classList: ['my-3'],
        style: {},
    },
    FieldTextLabel: {
        classList: ['form-label'],
        style: {},
    },
    FieldTextInfo: {
        classList: ['form-text','float-end'],
        style: {},
    },
    fieldTextInput: {
        classList: ['form-control'],
        style: {},
    },
    FieldTextgroup: {
        classList: ['my-3'],
        style: {},
    },
    FieldTextgroupLabel: {
        classList: ['form-label'],
        style: {},
    },
    FieldTextgroupGroup: {
        classList: ['d-flex','flex-nowrap','justify-content-between','align-items-stretch'],
        style: {},
    },
    FieldTextgroupItem: {
        classList: ['input-group','d-inline-flex'],
        style: {},
    },
    FieldTextgroupItemLabel: {
        classList: ['input-group-text'],
        style: {},
    },
    FieldTextgroupItemInput: {
        classList: ['form-control'],
        style: {},
    },
    ValidationErrorLabel: {
        classList: [],
        style: {}
    },
    ValidationErrorInput: {
        classList: ['is-invalid'],
        style: {}
    },
    ValidationErrorMessage: {
        classList: ['invalid-feedback'],
        style: {},
    },
    ValueExportTable: {
        classList: ['table'],
        style: {},
    },
};

4. Pass options as an object.

let sampleEasyJsonFormOptions = {
    // 'disabled' makes form and structure read-only when set true. Default is false.
    disabled: false,
    // 'fileHandler' contains the set of functions needed to deal with files that are
    // uploaded with EasyJsonForm. The files in EasyJsonForm are uploaded assynchronously and, on success,
    // a text value is returned. With this text value 2 more methods are necessary: One
    // that converts that name into a display name an the other that convert that name 
    // into a http link to be clicked by the user. If fileHandler is not supported, the
    // file operations will return errors
    fileHandler: {
        // Returns a string with the name to be displayed
        displayName: (value) => EasyJsonForm.dictionary['item.file.vaule.uploaded.file'],
        // Returns a Promise (fetch can be used!) which will resolve as an object with keys 
        // 'success' (boolean) and 'value' (string: value to be stored or error message)
        upload: (file) => {
            return new Promise((resolve, reject) => {
                console.log(file);
                setTimeout(()=>resolve({success: true, value: 'sampleFileName'}), 3000);
            });
        },
        // Returns the url for the link to be displayed
        url: (value) => 'https://google.com',
    },
    // Possible values: 'form', 'div' (form is default)
    formContainer: 'form',
    // If not null (and if formContainer is 'form'), sets this form's action
    formAction: null,
    // If not null (and if formConatiner is 'form'), sets this form's method
    formMethod: null,
    // 'onStructureChange' can receive a callback function which is invoked whenever there
    // is a change on the structure of the form caused by the builder
    onStructureChange: () => {
        sampleEasyJsonForm.formUpdate();
        document.querySelector('#jsonData').textContent = JSON.stringify(sampleEasyJsonForm.structureExport(), null, 4);
        document.querySelector('#rawValue').innerHTML = JSON.stringify(sampleEasyJsonForm.valueExport('raw'), null, 4);
        document.querySelector('#simpleValue').innerHTML = JSON.stringify(sampleEasyJsonForm.valueExport('simple'), null, 4);
        document.querySelector('#htmlValueExport').innerHTML = sampleEasyJsonForm.valueExport('html');
    },
    // 'onValueChange' can receive a callback function which is invoked whenever the user
    // changes the values in a form
    onValueChange: () => {
        document.querySelector('#jsonData').textContent = JSON.stringify(sampleEasyJsonForm.structureExport(), null, 4);
        document.querySelector('#rawValue').innerHTML = JSON.stringify(sampleEasyJsonForm.valueExport('raw'), null, 4);
        document.querySelector('#simpleValue').innerHTML = JSON.stringify(sampleEasyJsonForm.valueExport('simple'), null, 4);
        document.querySelector('#htmlValueExport').innerHTML = sampleEasyJsonForm.valueExport('html');
    },
};

5. Initialize the EasyJsonForm.js and generate a form builder on the page.

let sampleEasyJsonForm;
sampleEasyJsonForm = new EasyJsonForm('sample', [], sampleEasyJsonFormStyle, sampleEasyJsonFormOptions);
document.querySelector('#builder').appendChild(sampleEasyJsonForm.builderGet());
document.querySelector('#form').appendChild(sampleEasyJsonForm.formGet());
let btnValidateForm = document.createElement('button');
btnValidateForm.classList.add('btn', 'btn-sm', 'btn-outline-primary');
btnValidateForm.textContent = "Validate Form";
btnValidateForm.onclick = () => sampleEasyJsonForm.formUpdate(true);
document.querySelector('#form').appendChild(btnValidateForm);

Changelog:

10/15/2023

  • Refactoring and bugfixes

09/27/2023

  • v1.0.1

08/26/2023

  • File field html export link now opens in new window

03/03/2023

  • PHP Exporter

04/23/2022

  • Bugfix on file component

v1.0.0 (02/05/2022)

  • update

01/10/2022

  • Word wrapping long text values in HTML export

You Might Be Interested In:


Leave a Reply