Forms

Forms is a way to gather information to use in a automation (script, workflow). Onify has a built in form editor where customers can create and customize forms for any need. The forms are flexible and support both simple and more advanced form elements.

For some example forms, check out our GitHub repo.

Pug example

Pug

doctype html
html
  head
    title my pug template
  body
    h1 Hello #{name}

HTML output

<!DOCTYPE html>
<html>
  <head>
    <title>my pug template</title>
  </head>
  <body>
    <h1>Hello Bob</h1>
  </body>
</html>

For more pug/jade examples, please visit https://naltatis.github.io/jade-syntax-docs.

Create new form

Create empty form templates

For more information about form templates, see sections below.

  1. Go to form templates resources (/admin/resources?activedirectory=templates%2Fform&isdirectoryopen=true)
  2. Right click on form folder and click Create new file
  3. Pick a name for the form template (eg. createticket.pug)
  4. Copy this text extends ../views/form/default-form to first row of file
  5. Click Save

Create form configuration

  1. Go to form configuration page (/admin/configuration/forms)
  2. Click Create new button
  3. Enter Slug (url friendly name, eg. createincident )
  4. Enter Title (eg. Create incident)
  5. Enter Description (optional)
  6. Check "Test" for testing (you can disable this when you are done testing)
  7. Select Template (eg. createincident.pug)
  8. Click Save

That was the minimum setup for a form...

Form templates

For every form, we need form templates (pug). These templates should be placed in the customer-{customer code}-hub-app GitHub repo in /templates/form folder. Normally we need two form templates, one for the form itself and one for the confirmation page, eg. {form key}.pug and {form key}-confirmation.pug.

Example form

extends ../views/form/default-form

block append formConfig
    +formOptions({
        formDescription: "This is a custom description",
        submitButtonName: "Okidoki"
    })

block formContent
    +formElement({
        name: "firstname",
        label: "First name",
        required: true
    })

    +formElement({
        name: "lastname",
        label: "Last name",
        required: true
    })

    +formElement({
        type: 'select',
        name: 'gender',
        label: "Select gender",
        required: true,
        options: [
            {
                value: 'male', 
                label: 'Male'
            },
            {
                value: 'female', 
                label: 'Female'
            },
            {
                value: 'other', 
                label: 'Other'
            }
        ]
    })

    +formElement({
        type: "textarea",
        name: "reason",
        label: "Reason",
        helpText: "Please enter a reason for the request"
    })
    

Form views

All forms need a form view (base template). This is required to load all nescessary form system features and variables. We can have different views and this could be use for mulitple layouts. By default, we have these views to choose from:

  • default-form ../views/form/default-form
  • box-form ../views/form/box-form

Form options

Form options are optional options/config for a form.

  • width (default: "standard") - The width of the form. Choose between small, standard or large.
  • pageTitle (default: form title) - The page title
  • formTitle (default: form title) - The form title
  • formDescription (default: form description) - The form description
  • warningModal (default: true) - If we should warn user navigating away from a form (that has been updated)
  • emptyCart (default: false) - If we should empty the cart when we load the form. Recommended to use in confirmation form.

Options only for main forms, not confirmation forms.

  • submitButtonName (default: "Submit") - The form submit button name

  • backButtonName (default: "Back") - The form Back button name

  • hideBackButton (default: false) - Disable form Back button

  • hideSubmitButton (default: false) - Disable form Submit button

  • requireChangeToSubmit(default: false) - If we should require any change before user can submit the form. The submit button will be disabled before.

Example: Custom title and description and hidden back button

+formOptions({
    formTitle: "Test form",
    formDescription: "This is a test form",
    hideBackButton: true
})

Form elements

Form elements are fields (input) types like a text, textarea, select, checkbox etc.

General settings

Here are some settings that can be defined for all elements.

  • name - Unique name for the element
  • type (default: text) - What type of element (field) it is
  • label (default: none) - Label (title) for the element
  • autofocus (default: false) - Auto focus on this element when form is loaded
  • helpText (default: none) - Help text that describes the element/field (Supports Markdown)
  • class (default: none) - Specify a custom css class for the element/field
  • readonly (default: false) - If element is read only (supported by most editable form elements)
  • required (default: false) - If element is required (true/false or see Advanced model for Required and Visible settings)
  • visible (default: none) - If element should only be visible depending on other element (see Advanced model for Required and Visible settings)

Advanced model for Required and Visible settings

We support advanced models for both required and visible settings. For required we also support boolean (true/false).

  • ifField - Name of field to check against
  • hasValue - If field has this specific value(s)
  • containsValue - If field contains any value (true or false)

Example: Simple (boolean) required field

+formElement({
    name: "text1",
    label: "Text 1",
    required: true
})

Example: Required if checkbox element is checked

+formElement({
    name: "text2",
    label: "Text 2",
    helpText: "Required if checkbox is true",
    required: {
        ifField: "checkbox1",
        hasValue: true
    }
})

Example: Visible if text element contains any value

+formElement({
    name: "text3",
    label: "Text 3",
    visible: {
        ifField: "text1",
        containsValue: true
    }
})

Example: Visible if text element contains specific values

+formElement({
    name: "text4",
    label: "Text 4",
    visible: {
        ifField: "text1",
        hasValue: ["1", "2", "3"]
    }
})

Example: Required if text field is "OK"

+formElement({
    name: "text4",
    label: "Text 4",
    required: {
        ifField: "text2",
        hasValue: "OK"
    }
})
Text element

Text element are the default type and is used for simple text fields. We also support hidden and password fields.

Settings

  • placeholder (default: none) - Short hint that describes the expected value
  • pattern (default: none) - Specifies a regular expression that the element's value is checked against. For more information see https://www.w3schools.com/tags/att_input_pattern.asp.
  • value (default: none) - Default value
  • image (default: none) - Element image/icon
  • maxlength (default: none) - Maximum number of characters allowed in the element
  • checkduplicate (default: none) - Checks if we can find any duplicate records (see below for details)

Check Duplicate

  • checkduplicate.type - Check for duplicates against item or user results
  • checkduplicate.workspace - Required if type is item
  • checkduplicate.filter (optional) - Filter what items or users to check against
  • checkduplicate.field (optional, default: "name") - What field to search for duplicate text

Example: Text element with pattern

+formElement({
    label: "Order number", 
    name: "ordernumber",
    placeholder: "12345",
    required: true,
    pattern="[0-9]{5}"    
})

Example: Hidden text element

+formElement({
    type: "hidden",
    value: "12345",
    name: id
})

Example: Password text element

+formElement({
    type: "password",
    name: "password",
    required: true
})

Example: Check if (duplicate) asset with same name already exists in assets workspace

+formElement({
  label: "Asset name", 
  name: "name",
  required: true,
  checkduplicate: {
    type: "item",
    workspace: "assets"
  } 
})

Example: Check if (duplicate) customer number exists in CRM workspace using filters

+formElement({
  label: "Customer number", 
  name: "nr",
  required: true,
  checkduplicate: {
    type: "item",
    workspace: "crm",
    filter: ["type:customer"],
    field: "attribute.customernumber"
  } 
})
Text area element

Settings

  • placeholder (default: none) - Short hint that describes the expected value
  • pattern (default: none) - Specifies a regular expression that the element's value is checked against. For more information see https://www.w3schools.com/tags/att_input_pattern.asp.
  • value (default: none) - Default element value
  • rows (default: 3) - The rows specifies the visible height of a text area, in lines.
  • maxlength (default: none) - Maximum number of characters allowed in the element
  • nonBindable (default: true) - Prevent AngularJS to parse for variables that can cause some issues. Also see https://docs.angularjs.org/api/ng/directive/ngNonBindable.

Example: Large text area with max 250 chars

+formElement({
    type: "textarea",
    name: "description",
    rows: 7,
    maxlength: 250
})

Example: Text are element that is only visible when checkbox is checked

+formElement({
    type: "textarea",
    name: "comment",
    label: "Please enter comment",
    visible: {
        ifField: "commentincident",
        hasValue: "1"
    }
})
Checkbox element

Settings

  • checkboxLabel - Label / text for the checkbox itself
  • checked (default: none) - If checkbox should be pre-selected (checked) or not
  • trueValue (default: true) - What value to use if checked
  • falseValue (default: false) - What value to use if NOT checked

Example: Checked checkbox element

+formElement({
    type: "checkbox",
    name: "checkbox",
    checkboxLabel: "Check this box please",
    checked: true
})

Example: Checkbox element with custom true/false values

+formElement({
    type: "checkbox",
    name: "damnsure",
    label: "Are you sure?",
    checkboxLabel: "Damn sure!",
    trueValue: 'yes',
    falseValue: 'no'
})
Radio element

Settings

  • selected (default: none) - What option should be pre-selected (both value or label supported)
  • options (default: none) - Selectable options (static list)
  • lookup (default: none) - See Lookups section (Lookups)[#lookups]
  • reload (default: false) - Reload lookups if form changes

Example: Radio buttons element

+formElement({
    type: 'radio',
    name: 'radio',
    selected: 'Option 1',
    options: [
        {
            value: 'o1',
            label: 'Option 1'
        },
        {
            value: 'o2',
            label: 'Option 2'
        }
    ]
})
Simple text element

Element settings

  • value (default: none) - Element text (Supports Markdown)
  • format (default: none) - Format the result (see http://numeraljs.com/#format) if result is number. Great to use for prices.
  • format_locale (default: none) - Locale settings for the format. Used for currency and number delimiters. Supports Swedish (sv) and Finnish (fi) or default (English).

Example: simpleText element with bold text

+formElement({
    type: "simpleText",
    label: "This is **text**",
    value: "The text!"
})

Example: Format result as currency in Swedish locale

+formElement({
    type: "simpleText",
    label: "Price",
    value: "1000",
    format: "0,0[.]00 $",
    format_locale: "sv"
})
Image element

Settings

  • src - Source (url) to image (supports dynamic values)
  • alt (optional) - Alternative text for image
  • imageWidth (optional) - Image width
  • imageHeight (optional) - Image height

Example: Simple image example

+formElement({
      type: "image",
      src: "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png",
      alt: "Google"
})

Example: Dynamic image based on selection in form

+formElement({
      type: "image",
      src: "{product.attribute._image}"
})
Number element

Element for entering a number (You can also set restrictions on what numbers are accepted).

Settings

  • max (default: none) - Specifies the maximum value allowed
  • min (default: none) - Specifies the minimum value allowed
  • step (default: none) - Specifies the legal number intervals

Example: Simple Number element example

+formElement({
    label: "How old are you?", 
    name: "age",
    min:18
})

Example: Number element with minimum 1 and maximum 10 and step 1 at a time

+formElement({
    label: "Count 1 to 10", 
    name: "count10",
    required: true,
    max: 10,
    min:1,
    step: 1,
    value: 1
})

_Example: Allow 2 decimals in number

+formElement({
    label: "Amount", 
    name: "amount",
    required: true,
    min: 0,
    step: "0.01"
})
preformattedText element

Settings

  • value (default: none) - The preformatted text

Example: preformattedText element

+formElement({
    type: "preformattedText",
    label: "Preformatted Text",
    value: "Displayed in a fixed-width font, and it preserves both      spaces and line breaks"
})
Link element

Settings

  • value - Link (or button) text
  • button (default: false) - If link should be shown as a (bootstrap) button
  • url - The URL
  • onclick - Javascript when user clicks on the button
  • target (default: "_self") - Target to open link

_Example: Link with button style (and custom class) that opens in new window

+formElement({
    type: "link",
    name: "externalLink",
    button: true,
    class: "btn-info",
    value: "External",
    url: "https://external.company.com",
    target: "_blank"
})

_Example: Back button

+formElement({
    type: "link",
    button: true,
    value: "Go back",
    onclick: "history.go(-1);return true;"
}

_Example: Two buttons in a group

+formGroup([{
    width: 'col-md-1',
    type: "link",
    button: true,
    value: "Back",
    onclick: "history.go(-2);return true;"
}, {
    width: 'col-md-2',
    type: "link",
    button: true,
    value: "Startpage",
    url: "/"
}])
Select element

Settings

  • selected (default: none) - What option should be pre-selected (both value or label supported)
  • options (default: none) - Selectable options (static list)
  • search (default: false) - If we should enable searching for options. Handy for large lists.
  • lookup (default: none) - See Lookups section (Lookups)[#lookups]
  • reload (default: false) - Reload lookups if form changes
  • multiple (default: false) - Allow to select multiple options

Example: Select element with static options

+formElement({
    type: 'select',
    name: 'impact',
    label: "Impact",
    selected: 'Single User',
    options: [
        {
            value: 'single', 
            label: 'Single user'
        }, 
        {
            value: 'group', 
            label: 'Group of users'}
    ]
})

Example: Multi select element with lookup options

+formElement({
    type: 'select',
    name: 'multi',
    multiple: true,
    label: "Test multi",
    lookup: {
        type: "option",
        tag: ["multi", "test"]
    }
})
Rating element

Rating is a element where users can give rating using stars in a form.

Settings

  • levels (default: 5) - How many levels (stars) to show. Usually 5 or 10.
  • size (default: medium) - Size of the icons (small, medium or large)
  • icon (default: none) - Use a custom icon instead of default stars

Example: Large rating element with 10 levels that is required

+formElement({
    type: "rating",
    name: "rateus",
    label: "Rate us",
    required: true,
    value: 10,
    size: "large"
})
Item select element

Settings

  • selected (default: none) - It specifies that an option should be pre-selected when the form is loaded. This could be the item or option key.
  • multiple (default: false) - Allow uploading multiple files
  • minimumInputLength (default: 2) - Minimum number of characters required to start a search
  • lookup (default: none) - See Lookups section (Lookups)[#lookups]
  • reload (default: false) - Reload lookups if form changes

Example: Select items (onDemand) element with searchable items and custom result

+formElement({
    type: 'itemSelect',
    name: 'asset',
    label: "Select assets",
    minimumInputLength: 3,
    multiple: true,
    lookup: {
        type: "item",
        workspace: "cmdb",
        term: "tag:asset status:active {searchstring}"
    }
})  
Date picker element

Settings

  • placeholder (default: none) - Short hint that describes the expected value
  • pattern (default: none) - The pattern attribute specifies a regular expression that the element's value is checked against
  • value (default: none) - Default element value
  • minDate (default: none) - Minimum date/time
  • maxDate (default: none) - Maximum date/time
  • dateFormat (default: "YYYY-MM-DD") - The date format
  • weekStart (default: 1 (Monday)) - Day of the week start. 0 (Sunday) to 6 (Saturday)

Example: Date picker with both date and time. Use current date/time as default

+formElement({
    type: "datePicker",
    name: "date",
    label: "Select date",
    dateFormat: "YYYY-MM-DD HH:mm",
    value: (new Date().toISOString())
})

Example: Date picker with min/max date and advanced logic

-var dt = new Date()
-var todayDate = dt.toISOString().slice(0,10)
-var month = dt.getMonth()
-var year = dt.getFullYear()
-var lastDay = new Date(year, month + 1, 0)
-var lastDayDate = lastDay.toISOString().slice(0,10)
+formElement({
    type: "datePicker",
    name: "invoice_date",
    label: "Invoice date",
    required: true,
    minDate: todayDate,
    maxDate: lastDayDate,
    value: todayDate,
    dateFormat: "YYYY-MM-DD"
})
Barcode element

There are some limitations for this...

Example: Barcode element

+formElement({
    type: 'barcode',
    name: 'barcode',
    label: 'Barcode'
})
Message box element

Settings

  • status (default: info) - Status of the message (success, danger, warning or info)
  • title (default: none) - Title for the message
  • message - The message (Supports Markdown)

Example: Warning message if items are missing

if (!form.items)
    +formElement({
        type: "messageBox",
        status: "warning",
        title: "Missing items!",
        message: "You have not selected any items"
    })
File upload element (fileUpload)

Settings

  • multiple (default: true) - Allow uploading multiple files
  • access (default: private) - Can be set to public or private. Public = Allow anyone to access the uploaded file if they url. Private = Only allow authenticated users to download the file. Make sure that you have enabled API proxy mode for to use private mode.

Example: Multiple file upload

+formElement({
    type: "fileUpload",
    label: "Attachments",
})

Example: Allow uploading only one file and allow public access

+formElement({
    type: 'fileUpload',
    access: 'public',
    multiple: false,
    label: "Upload file"
})
Lookups

Lookups are the way we load data from indexed items or options. We support both onLoad and onDemand lookups. Lookups can be used for select, radio and itemSelect elements.

NOTE: This is not supported in public forms.

Options

Option lookups are supported for select and radio elements only. These are role and locale based.

  • Set lookup.type to option
  • lookup.tag (default: none) - Options tags
  • lookup.sort (default: name,asc) - What field and what order to sort options
  • lookup.pagesize (default: 50) - How many records should be returned

Example: Select (onLoad) element with dynamic options and reversed sorting

+formElement({
    type: "select",
    name: "impact",
    label: "Impact",
    selected: "Single User",
    lookup: {
        type: "option",
        tag: ["impact", "incident"],
        sort: "name,desc"
    }
})

Example: Lookup based on client side variables

+formElement({
    type: "select",
    name: "type",
    label: "Type",
    lookup: {
        type: "option",
        tag: ["type", "{customer_type}"]
    }
})

Items

Item lookups are supported by select, radio and itemSelect elements.

  • Set lookup.type to item
  • lookup.workspace (default: none) - What workspace to lookup items. Make sure users have access!
  • lookup.term (default: none) - Search term for finding items
  • lookup.query (default: none) - What (advanced) query/filter to use when searching for items*
  • lookup.sort (default: name,asc) - What field and what order to sort options
  • lookup.pagesize (default: 50) - How many records should be returned
  • lookup.result (default: see below) - How should the list/result be populated
  • lookup.result.label (default: item.name) - The name/label for items
  • lookup.result.description (default: none) - Extra information about option. Supports HTML. (only works on itemSelect element)
  • lookup.result.class (default: none) - Set custom class for items

* Query is the query url used for filtering out items. Supported params are term, filter, sort and pagesize.

Example: Select (onLoad) element with searchable items

+formElement({
    type: 'select',
    search: true,
    name: "software",
    label: "Select Software from AppStore",
    lookup: {
        type: "item",
        workspace: "appstore",
        query: "filter=tag:software&filter=status:requestable"
    }
})

Example: Select items (onDemand) element with searchable items and custom result

+formElement({
    type: 'itemSelect',
    name: 'manager',
    label: "Select manager",
    lookup: {
        type: "item",
        workspace: "users",
        query: "filter=tag:user&filter=tag:manager&term={searchstring}",
        result: {
            label: "{item.name}",
            description: "<a href='/workspace/users/search?term={key}' target='_blank'>{key}</a>",
            class: '{item.key}'
        }
    }
})    

The lookup.query supports both serverside (double cruises) and client side (single cruises) variables.

Users

  • Set lookup.type to user
  • lookup.term (default: none) - Search term for finding items
  • lookup.query (default: none) - What (advanced) query/filter to use when searching for items*
  • lookup.sort (default: name,asc) - What field and what order to sort options
  • lookup.pagesize (default: 50) - How many records should be returned
  • lookup.role (default: none) - Get users with a specific role

_Example: List users with manager role in the sales department

+formElement({
    type: 'select',
    name: 'manager',
    search: true,
    label: "Select manager",
    lookup: {
        type: "user",
        roles: ["manager"],
        term: "user.custom.department:sales",
        sort: "name,asc"
    }
}) 
Form elements table

If you want to build a complex table of rows, use the formElementsTable element.

Settings

  • rows - This is the variable to build the rows from. We usually use the form.items varible.
  • hideHeader (default: false) - Hide column headers
  • hideRemoveButton (default: false) - Hide the remove button so we cannot remove rows in table
  • removeButtonLabel (default: Remove) - Label for the remove button
  • hideCopyButton (default: true) - Hide the copy button
  • copyButtonLabel (default: Copy) - Label for the copy row button
  • hideAddButton (default: true) - Hide the add new row button
  • addButtonLabel (default: Add) - Label for the add button
  • header - The headers with includes width and label
  • elements - These are the actual elements (see form elements above). Selected value for the elements are based on the rows return and the variable name must match the name of the element for this.

Example: Multi row table with items and lookups

+formElementsTable({
    rows: form.items.map(function(item) {
        return {
            service: {
                value: item.key,
                label: item.name
            },
            invoice: {
                value: item.attribute._invoicekey,
                label: item.attribute.invoice
            }
        }
    }),
    name: "services",
    hideRemoveButton: true,
    hideAddButton: false,
    addButtonLabel: "Add new",
    header: [{
        width: "col-md-4",
        label: "Service"
    }, {
        width: "col-md-5",
        label: "Invoice"
    }],
    elements: [{
        width: "col-md-4",
        type: "simpleText",
        name: "service"
    }, {
        width: "col-md-5",
        type: 'select',
        name: 'invoice',
        search: true,
        required: true,
        lookup: {
            type: "item",
            workspace: "invoices",
            query: "filter=type:invoice&term=*",
            result: {
                label: "{item.name}"
            }
        }
    }]
})

Example: Products with prices and amount selection

+formElementsTable({
    rows: form.items.map(function(item) {
        return {
            product: item.name,
            price: String(item.cost.price),
            amount: "1"
        }
    }),
    name: "products",
    header: [{
        width: "col-md-5",
        label: "Product"
    }, {
        width: "col-md-2",
        label: "Price"
    }, {
        width: "col-md-2",
        label: "Amount"
    }],
    elements: [{
        width: "col-md-5",
        type: "simpleText",
        name: "product"
    }, 
    {
        width: "col-md-2",
        type: "simpleText",
        name: "price"
    },
    {
        width: "col-md-2",
        type: "number",
        name: "amount",
        required: true,
        min: 1,
        max: 10
    }]
})
Summary calculation element

This element is used to calculate cost or price summary in forms.

Settings

  • calculation - The calculation that should be the result summary
  • format (default: number with no decimals) - How to format the result (see http://numeraljs.com/#format)
  • format_locale (default: none) - Locale settings for the format. Used for currency and number delimiters. Supports Swedish (sv) and Finnish (fi) or default (English).
  • itemTable (optional) - If you want to calculate summary from a specific itemTable element

Example: Calculate total cost for items in a itemTable and format result with two decimals

+formElement({
        type: "summaryCalculation",
        name: "totalcost",
        itemTable: "cartTable"
        calculation: "{price} * {quantity}",
        format: "0.00 EUR",
        label: "Total cost"
})

Example: Calculate total cost from seperate options elements with Finnish format

+formElement({
      type: "summaryCalculation",
      name: "totalcost",
      calculation: "(cpu.meta.price + ram.meta.price + hdd.meta.price) * validity_period.meta.months",
      format: " $0,0[.]00",
      label: "Total cost",
      format_locale: "fi"
    })
Agent task button element

NOTE: This is not supported in public forms.

Settings

  • identifier (default: none) - Unique identifier for the element
  • name (default: none) - Button name
  • options (default: none) - Agent task options
  • options.fields (default: none) - Elements names used by agent task
  • options.vars (default: none) - Task tags variables
  • options.command (default: none) - Task command

Example: Run Agent task via button

+agentTask({
    identifier: "task",
    name: "Verify mobile number",
    options: {
        fields: ["user", "email"],
        tag: "writer",
        vars: "-username ‘{user}’,-email ‘{email}’",
        command: "ad.getuseremail"
    }
})
Agent task result element

NOTE: This is not supported in public forms.

Example: Agent task result element

+agentTaskResult({
    identifier: "task"
})
Process state element (processState)

If the form is associated with a workflow (and process), it could be nice to show the progress of a workflow/process after submitting the form. This element does just that.

NOTE: This is not supported in public forms and is normally used on confirmation/result forms.

Settings

  • processid (optional) - The id for the process to show.
  • autorefresh (default: 1000) - Milliseconds to wait until process state is refreshed

Example: Show progress of process associated to form

+formElement({
    type: "processState",
    autorefresh: 2000
})
Process output element (processOutput)

If the form is associated with a workflow (and process) it is possible to print the output from that specific process/flow.

NOTE: This is not supported in public forms and is normally used on confirmation/result forms.

Settings

  • outputVariable (optional) - What specific output variable we should get result from. Default is environment.output.output. If set to eg. resultHTML, we will read result from environment.output.output.resultHTML.
  • format (default: plaintext) - If the response from the agent task is in HTML format, plain text or table
  • hideCopyToClipboard (default: true) - Set this to "false" to show the copy to clipboard feature (only used if format is table)
  • tableHeader - If format is table, set the table headers separated by comma
  • loadingText (default: "...") - Text to show while waiting for response
  • autorefresh (default: 1000) - Milliseconds before refreshing the results
  • processId (optional) - The id for process to show.

Example: Show output from specific process

+formElement({
    type: "processOutput",
    processId: "d504382ef89d4103bacaa92ce9389057",
    loadingText: "Please wait..."
})

Example: Show HTML output from specific output variable

+formElement({
    type: "processOutput",
    outputVariable: "resultHTML",
    format: "html",
    loadingText: "Please wait..."
})

GET BLUEPRINTS

Agent task response element

If you have a script or a integration that takes more then 10 seconds to finish, we recommend running it async. The user does not want to wait more then 10 seconds. But it is possible to execute the task and then wait for the result in the confirmation form.

NOTE: This is not supported in public forms and is used on confirmation forms.

Settings

  • format (default: plaintext) - If the response from the agent task is in HTML format, plain text or table
  • hideCopyToClipboard (default: true) - Set this to "false" to show the copy to clipboard feature (only used if format is table)
  • tableHeader - If format is table, set the table headers separated by comma
  • loadingText (default: "...") - Text to show while waiting for response
  • autorefresh (default: 1000) - Milliseconds before refreshing the results
  • allowScripts (default: false) - Allow javascript in repsonse (for HTML5 response)
  • taskid (optional) - The id for agent task to show.

Example: Show HTML response from task and refresh every 2 seconds

+formElement({
      type: "agentTaskSubmitResult",
      format: "html",
      loadingText: "Please wait while we do stuff. It could take up to 5 minutes.",
      autorefresh: 2000
})

Example: Show response as table

+formElement({
      type: "agentTaskSubmitResult",
      format: "table",
      tableHeader: "Program,Publisher,Version",
      loadingText: "Please wait while we generate the report...",
})

Example: Render HTML5 response

+formElement({
      type: "agentTaskSubmitResult",
      format: "html",
      loadingText: "Please wait...",
      allowScripts: true
})
Agent task log element

The agent task response element shows a message when all is done but this element list each log line that eg. a powershell script generates. See full example https://github.com/onify/examples/tree/master/forms/agenttasklog1.

NOTE: This is not supported in public forms and is used on confirmation forms.

Settings

  • hideTimestamp (default: false) - Hide timestamps
  • autorefresh (default: 1000) - Milliseconds before refreshing the results
  • taskid (optional) - The id for agent task to show logs for.

Example: Show logs but hide timestamp

+formElement({
    type: "agentTaskLog",
    hideTimestamp: true
})  

Form group

You can group one or more form elements in a group using the formGroup option.

Settings

  • width (default: none) - Width of the element (Bootstrap CSS class or custom CSS class)

Example: Group elements together

+formGroup([{
    width: 'col-md-4',
    name: "firstname",
    label: "First name",
    required: true
}, {
    width: 'col-md-4',
    name: "lastname",
    label: "Last name",
    required: true
}])

Form query parameters

Basic query parameters

In forms we can utilize and read any query parameter, like /form/form1?param1=test. In this case, param1 is available to use in the form to build logic.

Example: Query parameter (param1) in form element

URL for this example: /form/form1?ordernr=1234

+formElement({
    label: "Order number", 
    name: "ordernr",
    required: true,
    value: (form.queryparam.ordernr) ? form.queryparam.ordernr : ""
})

Example: Query parameter logic for changing submit button label

URL for this example: /form/form1?action=update

+formOptions({
    submitButtonName: (form.queryparam.action === "update") ? "Update item" : "Create item"
})

Items query parameters

We can also send a full item or multiple items using query parameters, but then we also need to include workspace so we know user has access to item in correct workspace. To use a item(s) in form logic, send them like this /form/form1?workspace=ws1&item=key1 and for multiple items, like this /form/form1?workspace=ws1&item=key1&item=key2. Multiple items can also be sent by enable item.action.bulksupported.

Example: Use item attribute in form elements

URL for this example: /form/form1?workspace=users&item=johndoe

+formElement({
    label: "First name", 
    name: "firstname",
    required: true,
    value: form.items[0].attribute.firstname
})

Example: Using multiple items in query to build string of selected item names

URL for this example: /form/form1?workspace=users&item=johndoe&janedoe

-var users = ""
-for (var i=0; i < form.items.length; i++)
    -users += form.items[i].name + "\n";

Embedding forms

We can also embed a form using /form/form1?embed=1. This will remove the navigation header.

Custom CSS stylesheet class

It is possible to set a custom CSS stylesheet class for the form using the css query parameter, like this: /form/form1?css=form-starwars. This will add the css class form-starwars that can be a custom stylesheet class.

Form variables

Every form always comes with some basic server side variables but we can also add more using eg. query parameters. We also have the ability to use client side variables and these can be used for client side logic in form.

Server side varibles

User variables

We can get information about the current logged in user.

  • user.name - Name of the user
    {% comment %}* user.tags (array) - User tag(s) (if any){% endcomment %}
  • user.email - Email for user (if any)
  • user.key - User primary key (id)
  • user.role (array) - User role(s) (if any)
  • user.username - User login-/username
  • user.settings.* - User settings (eg. locale)
  • user.custom.* - User custom fields (if any)
  • user.geolocation - User geolocation (if enabled in config and if user accepts)
  • user.lastlogin - Last time the user logged in (eg. 2018-06-07 06:14:42)
  • user.request.header.host - Hostname of service (eg. demo.onify.co)
  • user.request.header.ipaddress - User IP (v4) address
  • user.request.header.useragent - User web browser agent (eg. Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36)
  • user.request.header.os - User OS (eg. Windows 8.1)
  • user.request.header.browser - User browser (eg. Chrome)

Example: Show form element if user is member of specific role

if (user.role.includes("super-admin"))
    +formElement({
        type: "checkbox",
        checkboxLabel: "Super secret",
        name: "supersecretcheckbox",
        checked: true
    })

Form variables

Form variables contains almost everything you need to know about the form and the data it contains.

  • form.title - Form title
  • form.description - Form description
  • form.slug - Form slug (url friendly name)
  • form.queryparam.* - Form query parameters (if any) (see also Form query parameters section)
  • form.query - Complete query string (if any) (eg. workspace=demo&item=key1&item=key2&action=update)
  • form.path.* - What paths that are availible when submitting the form
  • form.items.* - Items that should be loaded when form is loaded (if any)
  • form.tags (array) - Form tags

Submit variables

  • submit.* - Submitted variables (eg. submit.firstname)
  • form.submit.item.* - Submitted items (eg. {{form.submit.item.manager.[0].key}})
  • form.submit.option.* - Submitted options (eg. {{form.submit.option.memory.[0].key}})

Response variables

This is the response from either webhooks or agent task.

  • response.* - Response variables
  • response.agenttask.* - Response if agent task command was executed (eg. response.agenttask.result.response)

Form translation

Translation is a important part when we work with forms and data. You can read more about translation here.

Advanced form features

Pug helpers

Pug helpers are server side functions that you can use in forms. These are synchronous functions and the form does not load until these are finished.

helper.apiRequest

A very powerful pug helper that can do ANY API request, either as the current user or impersonate other user. The main purpose of this helper is to get information from the API, not updating or creating records. It can be done but it is not recommended if you not 100% sure what you are doing :)

  • token (optional, default: user.token) - User token for authentication
  • url - Url for the request (without /api/vx). Eg. /my/bulletins/servicedesk
  • method (optional, default: GET)- Method for the API request (GET, POST, PUT, PATCH)
  • payload - The payload (body) if we use eg. POST/PUT/PATCH method

Example: Get users bulletins for servicedesk workspace

-var bulletins = helper.apiRequest({url: '/my/bulletins/servicedesk'})

Example: Get output from a process

-var processOutput = helper.apiRequest({url: '/my/processes/' + form.queryparam.processid + '/output'})

GET BLUEPRINTS

helper.loadOptions

Load options on server side based on user and tags.

  • token - User token for authentication. Use user.token for current user.
  • tags - Load options by tags
  • params - Same params as the API endpoint (/my/options/tags/{tags})

Example: Load options that has tags "test" and sort by name

-var optionsTest = helper.loadOptions(user.token, ['test'], {sort: "name", sortby: 'desc'})

Example: Load options that has same tags as form slug

-var optionsForm = helper.lookupOptions(user.token, [form.slug])

helper.loadItems

Load items based on user, workspace and params.

  • token - User token for authentication. Use user.token for current user.
  • workspace - What workspace to get items from
  • params - Same params as the API endpoint (/my/items/{workspace})

Example: Load items by searching

-var itemsBySearch = helper.loadItems(user.token, 'it-self-service', {term: "visio", sort: "name.lower,desc"})

helper.loadItem

Load a single item based workspace and item key.

  • token - User token for authentication. Use user.token for current user.
  • workspace - What workspace to get item from
  • item key - The item key

Example: Load info about logged in user from users workspace

-var myself = helper.loadItem(user.token, 'users', user.key)

helper.loadItemEvents

Load items events based on item, workspace and params.

  • token - User token for authentication. Use user.token for current user.
  • workspace - What workspace to get items from
  • item key - The item key
  • params - Same params as the API endpoint (/my/items/{workspace})

Example: Load events items for specific computer

-var itemEventsResult = helper.loadItemEvents(user.token, 'computers', 'pc01', {level: 'info', tag: 'reinstall', category: 'deploy'})

helper.markdownString

Convert markdown text to HTML.

_Example: Simple as pie :-)

| !{helper.markdownString('My **bold** _text_')}

Javascript scripting

The form templates support Javascript for advanced conditions and general scripting.

Here are some links to some Javascript references:

And here are some examples:

Example: Only show the password form element if user is member of super-admin group

if (user.role.includes("super-admin"))
    +formElement({
        type: "password",
        name: "super-password",
        required: true
    })

Example: Loop through items and list key and name

for item in form.items
    +formGroup([{
        width: 'col-md-4',
        type: "simpleText",
        name: "key",
        value: item.key
    }, {
        width: 'col-md-4',
        type: "simpleText",
        name: "name",
        value: item.name
    }])