Search code examples
odatasapui5

How can I show error message for expanded elements?


I have a SAPUI5 application and using following mechanism for showing errors in case fails in validation (documentation):

oMessage = new sap.ui.core.message.Message({
                message: (typeof sText === "string" && sText.trim().length > 0) ? sText : ex.message,
                type: MessageType.Error,
                target: (oControlBinding.getContext() ? oControlBinding.getContext().getPath() + "/" : "") + oControlBinding.getPath(),
                processor: oControlBinding.getModel()
           });
this._aMessages[oControl.getId()] = oMessage;
sap.ui.getCore().getMessageManager().addMessages(oMessage);

This solution works for normal inputs:

enter image description here

What do I mean by normal elements???

Actually when it is an Input element that shows an expanded value it does not work and when it is not expanded it works.

For example when the element is:

<Input value="{ path: 'BusinessAddress/PostOfficeBox', type : 'sap.ui.model.type.String' , constraints:{search: '^[0-9]*$'}}">

Which shows an expanded value does not get the error message box.

But for the elements that have a path like value="{ path: 'MobilePhone', type: 'sap.ui.model.type.String', constraints: {search: '^[0-9]+$'}}" it shows the error message.

The difference between the two oMessage object that is generated by the snippet code is:

target: "/ContactSet('CO1')/BusinessAddress/PostOfficeBox"   ==> for expanded ones

The BusinessAddress is a foreign key of the entity ContactSet which has been expanded.

And

target: "/ContactSet('CO1')/MobilePhone"

So clearly the problem is about the target of the sap.ui.core.message.Message instance. Therefore my question is how can I target the error message for an expanded element?


Solution

  • It is needed to change the processor from the oDataModel to ControlMessageProcessor. It means instead of the path of the bound data in the model we can address the control itself for binding the error message to its correct place of showing. something like this:

    var oMessageProcessor = new sap.ui.core.message.ControlMessageProcessor();
    var oMessageManager  = sap.ui.getCore().getMessageManager();
    
    oMessageManager.registerMessageProcessor(oMessageProcessor);
    
    var oInput = new sap.m.Input({
        id: "myInputId",
        value: { path: "/Products(1)/Price" , type: new sap.ui.model.type.Float() }
    });
    
    oMessageManager.addMessages(
        new sap.ui.core.message.Message({
            message: "ZIP codes must have at least 23 digits",
            type: sap.ui.core.MessageType.Error,
            target: "/myInputId/value",
            processor: oMessageProcessor
         })
    );
    

    By targeting the control itself it does not matter we bind an expanded property to the control.