Custom properties are extremely useful for modular design and reuse by sending custom values into each instance. There are a number of data types that can be selected, but no obvious way to pass an array value. In this post, I’ll describe the issue and how to work around it.
Custom Property Data Types
The default data type for a custom property is
There are a number of primitive data types available in the dropdown:
String Data Type
In this case, I want a property that can accept an array of values.
To test this, I created a simple custom control with two properties,
objectProperty, to test how they handle arrays. They both default to
string as the data type.
You can leave the data type as
string, but compute an array to return. It won’t throw an error, but it will treat it like a single string.
No Data Type
You can remove the data type from the property definition and it won’t throw an error on the custom control. However, that is not a valid property, so its treated as though that property doesn’t exist.
If you’ve already set up an instance of the custom control and passed a value to it, it will throw an error on the custom control instance: Unknown property this.. It is not defined on tag .
Custom Data Type
Fortunately, there’s a really simple solution — you can manually type in a property type.
If you type in
object as the type, it does the trick. (It effectively works as desired, although it actually accepts the data as
TL;DR – Server-side code in onClientLoad causes a page refresh and prevents additional onClientLoad events with server-side code from running. In this post, I’ll show an example and describe how it behaves.
Page Ready Events
$(document).ready() and Dojo has
dojo.addOnLoad() to make this checking easy.
The Problem with onClientLoad in XPages
XPages provides the
onClientLoad event on pages, custom controls, and panels. XPages allows you to run client-side and/or server-side code in the event. However, running server-side code can cause a tough-to-troubleshoot side effect.
Take, for example, this XPage, which has two panels. Both panels and the page itself have client-side and server-side
onClientLoad code to write a message to the browser console and server console, respectively.
Here’s what happens when the page loads:
- The page-level client-side code runs to write the message to the browser console
- The page-level server-side code runs to write the message to the server console
onClientLoad handlers stops at this point because the page has posted to the server because of the server-side code; the
onClientLoad event handlers for the panels do not execute at all.
You can look in the browser’s developer tools and see the POST that is sent. It doesn’t try to update anything on the page, so there’s no response, but it’s still enough to interrupt everything else.
More details on the behavior:
- You can run multiple client-side
onClientLoadevent scripts without issue — as long as they’re not triggering partial refreshes
- If the event handlers are rearranged on the page, the one that comes first in the source is the one that will run
- If there is only one
onClientLoadevent with server-side code, it will run (based on it’s order in the source), then POST, then let the rest of the
onClientLoadevents on the page that only have client-side code run. (Any with server-side code will not execute — even the client-side event code on handlers that also have server-side code will not run.)
Mitigating the Problem
This may sound like an easy thing to keep in check, but if you have
onClientLoad code on multiple custom controls, it may be hard to make sure that there won’t be a conflict, especially because there won’t be any error thrown.
The strong recommendation is to just not put server-side code in the
onClientLoad event, period.
If you absolutely need it, then you may need a standard of putting any necessary
onClientLoad code in the common layout control that’s loaded on every page, but it still has the potential to interrupt anything else going on the page or annoy the user by causing a delay immediately after the page is loaded waiting for the post and response. I would try to put code in the
afterPageLoad event or use client-side code to trigger an RPC method or custom REST service if server-side code needs to run in that event.