5.21 includes a new TypeScript form element API that you can use for building custom form elements using the Geocortex Workflow TypeScript SDK. The existing patterns and APIs you've been using for years to build custom form elements will continue to work, but we encourage you to try the new API when building new form elements.
To use these new features, you will need the latest version of Geocortex Workflow, as well as the Geocortex Workflow SDK.
The new form element API provides a number of new features and benefits:
We've created a new state management API that improves custom form element development in a number of ways. Let's take a look in-depth at what's changed.
We now provide an easy way to extend the props interface with additional public properties for your element. We've also flattened the element's properties from
props.element onto the root of the
props object and have removed unused properties that were used internally in the product but didn't make sense for most custom form elements:
These new APIs are included in the props interface and help to improve developer experience and ensure form consistency of both the UI presentation, but also the underlying element state.
We've added the
setProperty() API which is used to update properties of your element, such as additional public properties that you've added to your element by extending the
We've also added
setValue(value) is equivalent to calling
setProperty("value", value). Using the previous API, developers had to remember to raise the
changed event when updating the
value property on their element. This was necessary so that workflow authors could run sub-workflows on the
change event of the element. This is no longer needed as the
setValue() API will automatically raise the
changed event for you.
Additionally, the previous patterns didn't guarantee that the form would re-render after updating the properties of your element and could result in some challenging UI and data consistency issues. By using the
setValue() APIs, your form will automatically be re-rendered to ensure that the UI shows the most up-to-date state at all times.
To register your custom form elements using the previous API, you would need to create a Workflow activity that registers your element:
This added some extra boilerplate that we felt was unnecessary. More importantly it required the workflow author to run this element registration activity prior to running the Display Form activity that used the custom element. This was an awkward step that Workflow authors had to remember to do for their forms to render correctly.
When registering your element using the new API and the latest version of the Workflow SDK, it is no longer necessary to run the activity prior to Display Form:
setValue() APIs make it much easier to develop Workflow elements using the common patterns developers are familiar with when building React components. Let's look at a simple example of a text input element built using the previous API:
There are a few gotchas here that are likely not obvious at first glance:
- We forgot to call
props.raiseEvent("changed", value). If the workflow author tried to run a sub-workflow on the change event of your element, it would never run.
- The re-rendering of the element wasn't deterministic previously. Even if we updated
props.raiseEvent("changed", value), there was no guarantee that this element would re-render immediately. In that case the UI wouldn't show the updated value, and would be out-of-sync with the underlying state of the element.
undefinedduring the initial render, until the
onChangefires for the first time. There are ways to work around this such as running a sub-workflow on the
loadevent to set the element's value, however this makes development awkward.
- Other parts of the system could update the element's
valueto a type that the element doesn't expect. For example, instead of
stringlike we expect, the workflow author could accidentally set the value to an
objectusing the Set Form Element Property activity.
It was possible to overcome these gotchas, but it required additional logic that often wasn't immediately obvious. We've had to overcome these same challenges when writing form elements within Workflow itself.
So how would we build this element using the new APIs and avoid the gotchas described above? Let's take a look:
So what does all of this mean in practice? Below we'll compare elements built using the new and old APIs.
Here's a simple text input element:
For the sake of brevity, we've excluded the additional logic that would be needed to overcome the gotchas described above.
Notice that updating the
value for the element has been simplified by using the
setValue() API. We're also now able to provide a default
"Hello World" using
Here's a more advanced element that displays a range slider with configurable min, max, and step settings:
Here's the same element but also including configurable