UI Form

Objective


The Form is a UI library that generates a form look and feel to add/update the data and submit the changes. The library is available in Dashboard UI and can be invoked by any module.



Features


FeatureDescription
RenderingThe form is provided with a fields array, each field is represented by a configuration object that states how it should be rendered. Based on these configuration objects, the form is populated.
Operation AttachingThe form is passed on a list provided with the list buttons that will be displayed below the fields populate and the operations that should be triggered when these buttons are pressed.

The form can be populated in two methods:

  • Page Form: The form will be populated and the hooks are attached, a display directive is generated ngform. You can then use this directive anywhere on your page to print the form.
  • Modal Form: The form will be populated and the hooks are attached, however the form uses the Modal feature of AngularJS's Bootstrap and injects its ngform directive in it.


Usage 


The Form requires a configuration object that includes the fields and actions it needs to populate. Since the form can be displayed in two methods as explained above, there are two constructors provided to build it. The below table explains the parameters passed on to the form constructors.

Build Form:

FeatureDescription
ScopeThe scope of the module's controller, refer to Create UI Module for more information.
ConfigurationA configuration object that contains the fields and operations.

Build Form in Modal:

FeatureDescription
ScopeThe scope of the module's controller, refer to Create UI Module for more information.
ModalAn instance of the Modal feature from AngularJS's Bootstrap.
ConfigurationA configuration object that contains the fields and operations.
Code Sample:
//create a form configuration object
var config = {
    "form": {
        //specify the list of inputs and how they should be rendered
        "entries": [
            {
                'name': 'username',
                'label': 'Username',
                'type': 'text',
                'placeholder': 'Enter Username...',
                'value': '',
                'tooltip': 'Usernames are alphanumeric and support _ & - characters only',
                'required': true
            },
            {
                'name': 'email',
                'label': 'Email',
                'type': 'email',
                'placeholder': 'Enter Email...',
                'value': '',
                'tooltip': 'myemail@example.domain',
                'required': true
            }
        ]
    },

    //give your form a machine name
    "name": 'addMember',

    //add a label for your form, it will show in the form's header
    "label": 'Add New Member',

    //attach some action buttons to the form
    "actions":[
        {
            'type': 'submit',               //button type
            'label': 'Add Member',          //button label
            'btn': 'primary',               //button class name (AngularJs's Bootstrap)
            'action': function(formData) {  //operation function, returns the data entered in the form
                //add your business logic here
            }
        },
        {
            'type': 'reset',
            'label': 'Cancel',
            'btn': 'danger',
            'action': function(formData) {
                //add your business logic here
            }
        }
    ]
};

//call buildForm
buildForm($scope, config);

//call buildForm
buildFormWithModal($scope, $modal, config);

The above code snippets demonstrates how the form configuration should be.


Supported Inputs 


The Form supports several types of field rendering displays; field rendering configuration differ to support the different types of how fields could be rendered.

Property NameProperty TypeDescriptionSupported by Inputs of Type
typeStringThe type of the field, should be one of the values of the forth columntext | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider
nameStringName of the Fieldtext | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider
tabsArray of Objects

Array of Tab Entries where each entry contains:

  • name
  • label
  • description
  • onAction
  • entries: array of Objects, each object represents and input
tabset
descriptionObject

HTML description associated with angular bootstrap alert directive.

Ex: { "type": "info", "content": "input description value..." } 

accordion | group | tabset
iconstring

represents which icon to use from the iconmoon set 

Ref: https://icomoon.io/#preview-free

Ex: <span class="icon icon-{{entry.icon}}"></span>

group
labelStringLabel of the Fieldtext | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider
disabledBooleandepicts whether the input is disabled or nottext | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider
entriesArray of ObjectsArray of Objects, each object represents an inputgroup | accordion
requiredBooleanSpecify if input is required or nottext | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker  | buttonSlider
fieldMsgStringOptional text to display below inputtext | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider
hiddenBooleandepicts whether the inputs should be displayed in the HTML form entries or nottext | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider
placeholderStringOptional text to by default as input placeholdertext | email | number | phone | url | readonly | textarea
tooltipStringOptional text to display in a tooltip above input when mouse is over inputtext | password | email | number | phone | url | textarea | radio | checkbox | select | multi-select | date-picker
rowsintegerOptional number of rows in a textareatextarea
mindateMinimum starting date valuedate-picker | number
limitintegerMaximum number of uploaded files for the given type or 0 for unlimiteddocument | image | audio | video
valueStringThe value of the inputtext | password | email | number | phone | url | readonly | textarea | html
valuearray

Array of available value and which are selected by default. 

Ex: [ {"v": "value1", "l": "Value 1", "selected": true}, {"v": "value2", "l": "Value 2"} ]

select | radio | checkbox | multi-select
valuedateThe value of the date pickerdate-picker
onActionFunction

Triggered when User changes the value of the input this function is associated with. Provides a callback that takes:

  • id: id of the input this method is associated with
  • value: value of the input this method is associated with
  • form: instance representing the form that is bound to the scope of the angular module
text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider
disableRuleObject

Depicts a configuration that gets rendered to an expression and attached to the watcher scope of angular. The expression is associated with to a property in the scope and If matched, this inputs is automatically disabled.

Ex:

Sample Disable Rule
{
  "name": "createNewVirtualNetwork",
  "label": "Create New Virtual Network",
  "type": "buttonSlider",
  "value": true,
  "required": true
},
{
	"name": "newVirtualNetworkName",
	"label": "Virtual Network Name",
	"type": "text",
	"disableRule": {
		"operator": "AND",
		"fields": [
			"!createNewVirtualNetwork" //disable if above is true
		]
	}
}

The above sample illustrates that if the first entry has the value true, then the second entry is automatically disabled.



File Handling 


The Form Library provides support for 4 media types: Documents - Images - Audio Tracks - Videos.
Media inputs have special treatment in the form library. When provided, every input can have multiple medias, grouped under it.

Declaring a media input:

{
    'name': 'my_files',
    'label': 'My Files',
    'type': 'document',
    'limit': 1,
    'value': []
}

The above snippet shows how a media input named my_files of type document with a maximum limit of 1 media is provided to the form library. The above code will result in an input of type file, for the user to browse and select a file to be uploaded.


Modifying an existing media input:

Files should be stored in GridFS and not on the file system, this guarantees that if a service goes down, the data will not be lost.
The form adds 2 event listeners to every value in an existing media input: download - removeFile.
These listeners are used to either call a service API and download the original version of the media or to trigger a remove operation. Therefore when attempting to replace/remove an existing media input, additional information should be supplied.

{
    'name': 'my_files',
    'label': 'My Files',
    'type': 'document',
    'limit': 1,
    'value': [
        {
            '_id': '5551aca9e179c39b760f7a1a',
            'routeName': '/my_service/files/download',
            'headers': {
                'soajsauth': 'soajs_authentication_token'
            },
            'params': {
                'env': 'dev'
            },
            'metadata': {
                'mime': 'text/plain'
            },
            'contentType': 'text/plain',
            'filename': 'my_file.txt'
        }
    ]
}

The above snippet demonstrates how a media input should be provided to the form for editing. The following table explains the entries of every object inside the array:

PropertyDescriptionComputed
_idThe id of the file in GridFS.YES
routeNameThe Service API that should be called to download the original copy of this file.NO
headersAny optional headers that need to be provided when calling the service APIs to either download or remove the file.NO
paramsAny optional params that need to be provided when calling the service APIs to either download or remove the file.NO
metadataComputed Object by GridFS that contains the mime type information of the file.YES
contentTypeA computed value by GridFS representing the mimetype of the fileYES
fileNameA computed value by GridFS representing the mimetype of the fileYES


Input Examples


The below input types can be used to group other inputs or information together:

  1. Accordion
  2. Group
  3. Tabset


Accordion Example
{
	"name": "awsInfra",
	"label": "AWS Infra",
	"type": "accordion",
	"collapsed": false,
	"entries": [...]
}


Group Example
{
	"name": "controllers",
	"label": "SOAJS Controllers",
	"type": "group",
	"collapsed": false,
	"entries": [...]
}


Tabset Example
{
	"type": "tabset",
	"tabs": [
		{
			"label": "Image",
			"entries": [...]
		},
		{
			"label": "Source Code",
			"entries": [
				{
					"name": "attachConfigRepo",
					"label": "Attach Config Repository",
					"type": "buttonSlider",
					"value": false
				}
			]
		},
		{
			"label": "Readiness Probe",
			"entries": [...]
		}
	]
}



The below input types can be used for option selection purposes:

  1. Checkbox
  2. Radio
  3. Select
  4. Multi-select
  5. UISelect
Checkbox Example
{
	"name": "groups",
	"label": "Groups",
	"type": "checkbox",
	"value": [
		{
			"v": "owners",
			"l": "Owner Group"
		}
	],
	"required": false,
	"fieldMsg": ""
}





Radio Button Example
{
	"name": "status",
	"label": "Status",
	"type": "radio",
	"value": [
		{
			"v": "pending",
			"l": "pendingNew"
		},
		{
			"v": "active",
			"l": "active",
			"selected": true
		},
		{
			"v": "inactive",
			"l": "inactive"
		}
	],
	"required": true,
	"fieldMsg": ""
}








Select Example
{
	"name": "recipe",
	"label": "Catalog Recipe",
	"type": "select",
	"value": [
		{
			"v": "mongoRecipe",
			"l": "Mongo Recipe",
			"group": "cluster"
		},
		{
			"v": "mongoRecipeVM",
			"l": "Mongo Recipe VM",
			"group": "cluster"
		}
	],
	"required": true,
	"fieldMsg": ""
}







UI Select Example
{
	"name": "deploymentType",
	"label": "Deployment Type",
	"type": "uiselect",
	"value": [
		{
			"v": "container",
			"l": "container"
		},
		{
			"v": "vm",
			"l": "vm"
		}
	],
	"required": true,
	"fieldMsg": "Choose the type of deployment"
}




The below input types are text editors that allow the user to input blocks of texts:

  1. JSON Editor - a light editor that verifies JSON text
  2. CK Editor - a more complex editor alternative with advanced editing features
JSON Editor Example
{
	"name": "docker",
	"label": "Docker Volume",
	"type": "jsoneditor",
	"value": "",
	"required": true,
	"tooltip": "Enter the docker configuration.",
	"fieldMsg": "<div class='fieldMsg'>For more info about Docker volumes click <a target='_blank' href='hyperlink URL'>Here</a></div>",
	"height": 100
}


CK Editor Example
{
	"name": "docker",
	"label": "Docker Volume",
	"type": "ckeditor",
	"value": "",
	"required": true,
	"fieldMsg": "<div class='fieldMsg'>For more info about Docker volumes click <a target='_blank' href='hyperlink URL'>Here</a></div>",
	"height": 100
}



This input type allows the user to create an HTML input.

In the below example the HTML value creates a button. When clicked, this button adds another volume to the stack of volumes.

HTML Example
{
	"type": "html",
	"value": "<input type='button' class='btn btn-sm btn-success f-right' value='Add Volume'/>",
	"name": "addVolume"
}

Below is a snippet of the "onAction" code that can be found in the service or controller of the corresponding UI module.

formConfig[5].tabs[5].entries[0].onAction = function (id, value, form) {
	$scope.addNewVolume();
};


formConfig[5].tabs[5].entries[0] in the above snippet points to the exact location of the HTML button we previously configured in our UI configuration file, where "addNewVolume()" is a function that adds a new volume to the stack. 




Miscellaneous input types:

These are generic and basic input types such as number, date picker, text area, phone number, and readonly (which is a greyed out field that holds a value and cannot be modified). 


Readonly Example
{
	"type": "readonly",
	"value": "soajs",
	"name": "category",
	"label": "Category"
}