UI Form

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


Feature

Description

Feature

Description

Rendering

The 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 Attaching

The 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:

Feature

Description

Feature

Description

Scope

The scope of the module's controller, refer to Create UI Module for more information.

Configuration

A configuration object that contains the fields and operations.

Build Form in Modal:

Feature

Description

Feature

Description

Scope

The scope of the module's controller, refer to Create UI Module for more information.

Modal

An instance of the Modal feature from AngularJS's Bootstrap.

Configuration

A 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 Name

Property Type

Description

Supported by Inputs of Type

Property Name

Property Type

Description

Supported by Inputs of Type

type

String

The type of the field, should be one of the values of the forth column

text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider

name

String

Name of the Field

text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider

tabs

Array of Objects

Array of Tab Entries where each entry contains:

  • name

  • label

  • description

  • onAction

  • entries: array of Objects, each object represents and input

tabset

description

Object

HTML description associated with angular bootstrap alert directive.

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

accordion | group | tabset

icon

string

represents which icon to use from the iconmoon set 

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

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

group

label

String

Label of the Field

text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider

disabled

Boolean

depicts whether the input is disabled or not

text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider

entries

Array of Objects

Array of Objects, each object represents an input

group | accordion

required

Boolean

Specify if input is required or not

text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker  | buttonSlider

fieldMsg

String

Optional text to display below input

text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider

hidden

Boolean

depicts whether the inputs should be displayed in the HTML form entries or not

text | password | email | number | phone | url | readonly | textarea | radio | checkbox | select | multi-select | date-picker | html | document | image | audio | video | group | accordion | tabset | buttonSlider

placeholder

String

Optional text to by default as input placeholder

text | email | number | phone | url | readonly | textarea

tooltip

String

Optional text to display in a tooltip above input when mouse is over input

text | password | email | number | phone | url | textarea | radio | checkbox | select | multi-select | date-picker

rows

integer

Optional number of rows in a textarea

textarea

min

date

Minimum starting date value

date-picker | number

limit

integer

Maximum number of uploaded files for the given type or 0 for unlimited

document | image | audio | video

value

String

The value of the input

text | password | email | number | phone | url | readonly | textarea | html

value

array

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

value

date

The value of the date picker

date-picker

onAction

Function

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

disableRule

Object

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:

Property

Description

Computed

Property

Description

Computed

_id

The id of the file in GridFS.

YES

routeName

The Service API that should be called to download the original copy of this file.

NO

headers

Any optional headers that need to be provided when calling the service APIs to either download or remove the file.

NO

params

Any optional params that need to be provided when calling the service APIs to either download or remove the file.

NO

metadata

Computed Object by GridFS that contains the mime type information of the file.

YES

contentType

A computed value by GridFS representing the mimetype of the file

YES

fileName

A computed value by GridFS representing the mimetype of the file

YES



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" }