XPages Tip: Passing an Array to a Custom Control Property

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 string.

There are a number of primitive data types available in the dropdown:

Custom Property - Primitive Types

If you click the folder icons, there are a number of additional options, including Converters, Validators, and other types, but there are no data types for arrays (or vectors or JavaScript objects).

Custom Property - Property Types

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, stringProperty and objectProperty, to test how they handle arrays. They both default to string as the data type.

Custom Property - 1 Custom Property

<xc:ccTest>
  <xc:this.stringProperty><![CDATA[#{javascript:return ['1', '2', '3', '4', '5'];}]]></xc:this.stringProperty>
  <xc:this.objectProperty><![CDATA[#{javascript:return ['1', '2', '3', '4', '5'];}]]></xc:this.objectProperty>
</xc:ccTest>

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 Property - Error - No Property Type Defined

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 java.util.Vector.)

Custom Property - Object Type

Tags:

2 responses to “XPages Tip: Passing an Array to a Custom Control Property”

  1. DavidLeedy (@DavidLeedy) says :

    Brad,
    Great post! Thanks for sharing.

    Unless somethings changed and I missed it, I don’t like to set the data type to just “object”. If you do that it will work but you’ll need to go into the source to add the value. You can’t do it from the “Pretty Panes”. I go into source when needed, but I don’t “live there” so I like to have the option of setting the properties via the property pane.

    If you set the data type to “java.lang.Object” then it will work from source as before but you now get the option of using the property pane.

    While I think you certainly can still pass in a JavaScript array, I personally would try to pass in an actual Java Object – either an List, or Map. Those work great in SSJS. Map is particularly nice because that’s all the scoped variables are – sessionScope, viewScope, etc… So people are using them already hopefully.

    Of course you can’t just make a List or Map – it’s too generic. So you’re typically making an ArrayList, HashMap or even TreeMap

    My SSJS is rusty but in theory you can create the objects list this :

    var myList:java.util.ArrayList = new java.util.ArrayList();
    var myMap:java.util.HashMap = new java.util.HashMap();
    var mySortedMap:java.util.TreeMap = new java.util.TreeMap();

    And then populate them inside SSJS and then pass them to your custom control.

    The nice thing about going to Java Objects is you get to use any of their built in abilities. for example TreeMap will Sort by the key automatically.

    var myMap:java.util.TreeMap = new java.util.TreeMap();
    myMap.put(“Orange”, “Acidic”);
    myMap.put(“Apple”, “Sweet”);

    If you passed that into a repeat control Apple should get listed first since TreeMap will sort by key.

    Also you can, (and probably should) add a specific data type when you do this. That can also be helpful.

    var myList:java.util.ArrayList = new java.util.ArrayList();
    var myMap:javaUtilTreeMap<Integer, String) = new java.utilTreeMap();

    That’s a little better – though might be initially confusing for some. But Java Objects do prefer to know the data type you’re working with.

    var myMap:java.util.TreeMap = new java.util.TreeMap();
    myMap.put(12, “Apples”);
    myMap.put(5, “Oranges”);

    In this case Oranges should go first since it should be sorting by the Key value which is an Integer.

    Just my 2 cents…

Leave a comment