HTML Mark-up#

HTML Enriched With Your Metadata#

One of the most powerful features of Portals is the HTML component. With it, you can create custom buttons, embed YouTube videos, or provide clear instructions for training objects. Moreover, you can enhance your HTML with metadata from your M-Files objects, putting your data to work in ways you’ve never imagined before.

Here is an example of HTML element that we used to display additional instructions inside the Demo Vault:

HTML_Module_Example

Portals provides special JavaScript functions that make it easy to open documents or related objects from buttons or to display associated images. With this powerful combination of HTML and metadata, you can create custom buttons that operate on M-Files objects, allowing users to interact with your data in new and exciting ways. Using Portals’ HTML module with metadata, you can create a powerful custom module that can help you achieve your goals in previously impossible ways.

Common use cases#

  • Include images or videos from the internet

  • Include content from the internet in iframes

  • Make custom UI components

Styling#

Any HTML you write will be loaded in the context of a Portal. That means that every JavaScript and CSS file used for Portals is at your disposal. As mentioned elsewhere, CtrlPortals makes heavy use of fomantic-ui, meaning that every component from fomantic-ui can be used out of the box.

Using Metadata#

In the configuration, you insert HTML in an HTML component’s Content entry. The content that you insert here is a multiline string, which is later processed further by converting any property-placeholders to their display values. Property-placeholders are added in the format %PROPERTY_<ID>% where <ID> is the property ID number from M-Files. Lookup and multi-select lookup properties can additionally be inserted ‘as Lookups’ which will convert them into their raw JSON values.

E.g. if we have a Portal for an object containing a property with a reference to a different object, let’s call this property 1001, and we configure that property to be inserted as a Lookup, it is inserted as literal JSON. Since JSON is a subset of JavaScript, the object is ready to go immediately.:

var obj = %PROPERTY_1001%;

This works because the placeholder %PROPERTY_1001% expands to a Lookup like so:

var obj = { "ID": 100, "ObjType": 4, /* And many other fields */ };

Thus, the object is parsed and ready to use by JavaScript.

Caveats#

JavaScript Version#

Keep in mind that while your browser is using an up-to-date version of JavaScript, the M-Files desktop is stuck with Microsoft JScript which is equivalent to ES5, meaning that a lot of new features and keywords will not work for M-Files desktop users. You can support the desktop version by simply sticking to ES5, but alternatively you can look into Babel standalone.

Properties in HTML event handlers#

When inserting properties as lookups directly, there are some caveats that must be taken into account. E.g. when declaring a click-handler for a button to open a portal based on a lookup, it is tempting to write something like this:

<button class="ui button" onclick="openPortalFromLookup(%PROPERTY_1001%)">Open Portal</button>

However, this would not work, the lookup would expand to JSON, closing the onclick-code at the start:

<button class="ui button" onclick="openPortalFromLookup({"...})"

It would then be tempting to simply change the onclick-code’s enclosing quotes from " to ':

<button class="ui button" onclick='openPortalFromLookup(%PROPERTY_1001%)'>Open Portal</button>

This would seemingly solve the problem (and it would work in most cases), but would cause a syntax error if a lookup contains a display-value with a ' inside, e.g. a lookup leading to a document called Michael's document.

Instead, we recommend two approaches, depending on your version of CtrlPortals. If you are using version 2.23.* (any version number starting with 2.23) you must use the following approach:

<button class="ui button" id="portal_button">Open Portal</button>
<script>
  document.getElementById('portal_button').addEventListener('click', function(_event) {
    openPortalFromLookup(%PROPERTY_1001%);
  });
</script>

On the other hand, if you are using 2.24.* or a pre-release version, you may use this approach:

<script>
  function openPortal() {
    openPortalFromLookup(%PROPERTY_1001%);
  }
</script>
<button class="ui button" onclick="openPortal()">Open Portal</button>

In both cases, the solution is to move your logic to a script tag, but the ability to declare new arbitrary functions and variables in the global scope was only introduced in version 2.24.*

JavaScript API#

The standard M-Files UI Extensibility Framework is available for use inside HTML <script>-tags.

In addition, CtrlPortals exposes many classes, functions and variables in the global scope (this is not a design choice we want to promote, but it is a side-effect of supporting the M-Files Desktop shell application).

Here are some functions and variables that we find particularly useful when working with the HTML module:

Function openInDefaultBrowser#

openInDefaultBrowser(url: string): void

This function opens a URL in the default browser. If the portal is being shown in M-Files web, it will open a new tab or window, depending on the browser setup.

  • url: string A URL pointing to a website reachable from the client’s pc.

Function openChildPortalTab#

openChildPortalTab(type: number, id: number, callback: undefined | () => void): void

This function tries to open a child portal tab for a given object type and object id combination. If the resolved object exists but is not portal-capable, the basic M-Files Edit-Object-Window will be shown instead. Once the portal or editing window has been opened, the callback-function will be called, if any was provided.

  • type: number The target object type.

  • id: number The target object id.

  • callback: undefined | () => void An optional callback function.

Function openPortalFromLookup#

openPortalFromLookup(lookup: Lookup): void

This function is syntactical sugar for opening a child portal tab using a lookup directly. It expands to:

function openPortalFromLookup(lookup) {
    openChildPortalTabNoChecks(lookup.ObjectType, lookup.Item);
}

Note the lack of a callback-function.

Variable objVer#

objVer: ObjVer

This global variable is used to access the object currently displayed in the portal.

Some useful properties of this object include:

  • Type: number the object type.

  • ID: number the object id.

  • Version: number the object version.

  • ObjID: ObjID a combination of the above information.

Variable platform#

platform: "web" | "client"

This global variable is used to determine if the dashboard is running in the desktop client or in M-Files Web.

You can use this variable to write platform-dependent code.

Minimal Example#

A minimal example of how you can use the HTML module is provided in the examples section of this page.