4
votes

I want to create a custom enum type for the custom control like https://sapui5.hana.ondemand.com/docs/api/symbols/sap.ui.core.ValueState.html#.Error.

My questions are:

  • How can I create an enum type?
  • On the custom control, you will be able only to pass property enum
    type. How can I validate if the given enum is valid or not?
2

2 Answers

3
votes

Here is an example: https://embed.plnkr.co/DhtkXOkMi12D1AYK

In order to create an enum type in UI5, there are certain rules to take into account:

  • The enum definition must be a plain object. Internally, it's validated via jQuery.isPlainObject.
  • Each key-value pair must be identical to each other.
  • Renaming is not supported.
  • Only keys and values of type string are supported.
{
  Red: "Red",
  Blue: "Blue",
  Yellow: "Yellow"
}

That being said, in order to actually make use of the enum object:

  1. The enum object must be first globally accessible. One way to do this is to define a module that consists of a plain object and making it available under the module name. For example:

    /**
    * file: MyColor.js
    * path: "custom/control/type/"
    * namespace: "demo"
    */
    sap.ui.define({ // module value
      Red: "Red",
      Blue: "Blue",
      Yellow: "Yellow",
    }, true); // resulting module name: "demo.custom.control.type.MyColor"
    
  2. The module name of the object must be assigned to the type in the property definition:

    sap.ui.define([
      "sap/ui/core/Control",
      "./MyColorBoxRenderer",
      "./type/MyColor", // Defines the module and prevents fetching it via sync XHR
    ], function(Control) {
      "use strict";
    
      return Control.extend("demo.custom.control.MyColorBox", {
        metadata: {
          properties: {
            "selectedColor": {
              type: "demo.custom.control.type.MyColor"
            },
          },
        },
        // ...
      });
    });
    

In my example above, it's the selectedColor property that awaits only "Red", "Blue", or "Yellow". Let's test it:

  • new MyColorBox().getMetadata().getProperty("selectedColor").getType().isEnumType() returns true (getType returns the created sap.ui.base.DataType object) ✔️
  • new MyColorBox().setSelectedColor("Hans") throws an error as expected:

    "Hans" is of type string, expected demo.custom.control.type.enum.PrimaryColor for property "selectedColor" ... ✔️

  • new MyColorBox().setSelectedColor("Yellow") successfully stores the value ✔️

Note

  • Do not try to create an enum type via DataType.create.

    Array types and enumeration types cannot be created with this method. They're created on-the-fly by DataType.getType when such a type is looked up. [source]

  • According to the getType reference, the default value of the enum type will be the first key.

    The defaultValue will be the value of the first key found in the plain object.

    .. which would be "Red" in our case. But this is true only if thatEnumType.getDefaultValue() is called. The value "Red" does not apply to the defaultValue of a Property in control metadata. There, the defaultValue will be simply undefined if not defined otherwise.

References

0
votes

Start off by defining your enum...

MessageType.js

sap.ui.define([], function() {
    "use strict";

    return {
      Unread: "Unread",
      Read: "Read"
    };
});

Next, mark this enum as a dependency in your custom control so that you are able to validate the value.

MyControl.js

    sap.ui.define(["sap/ui/core/Control", "/path/to/MessageType.js"], function(Control, MessageType) {

        Control.extend("myControl", {
            someMethod: function(sMessageType) {
                // Validate if we are dealing with a valid message type
                var aKeys = Object.keys(MessageType);
                var bValidEnumValue = aKeys.some(function(sKey) {
                    if (MessageType[sKey]) {
                        return true;
                    }
                });

                // Do other stuff..
            }
        });
    });

Of course the way to check if you are dealing with a valid enum value can be implemented in different ways depending on what you're trying to do.

if (sMessageType === MessageType.Read) {
   // do something
} else if (sMessageType === MessageType.Unread) {
   // do something else 
} else {
   // throw an error?
}