@prp-apps-solutions/ui5-message-handler
v1.0.3
Published
A package including utils to handle messages in UI5 applications.
Readme
ui5-message-handler
This packages serves as a lightweight and simple message handling utility using JSONModels and the MessageBox. The main features are custom message handling as well as error handling.
Further controls are provided, e.g., a simple SelectionDialog to enable a user to select a key-value-pair using a dropdown and displaying a text area with predefined content based on the selection/ enabling a user to write custom text to a selected key.
Installation
- NPM:
npm install @prp-apps-solutions/ui5-message-handler - PNPM:
pnpm add @prp-apps-solutions/ui5-message-handler
Description & Usage
The error handler and the message handler can be used in your application in parallel. Both handle the messages/errors in a similar way by
- displaying them in a MessageBox
- adding them to a global error model/ one of your message models
- enabling further control handling by providing optional methods for method chaining
The SelectionDialog is another possibility to display information, handle custom actions or enforce users to provide more context for a specific selection.
Error Handler
All errors are added to an error model by default. The error model's name is errorModel. If you want to give the model a different name, provide the modelName property of the error handler instance on initial instantiation.
:bulb: The following usage descriptions contain examples only which may differ from your actual usage.
(Optional) Error Handler - Place Button, MessageStrip and add MessagePopover
You can optionally add a button, a message strip and a message popover to directly display your error messages:
- The button opens the message popover on press while showing the amount of errors as button text.
- The message strip displays the latest error message.
- The message popover displays the details of the errors added to the error model.
Example Usage
Place the controls within a toolbar in the init method of your corresponding controller:
// Main.controller.ts
class Main extends Controller {
public onInit(): void {
ErrorMessageControlHelper.getInstance().placeErrorMessageStrip(
this.getView().byId("MyToolbarId")
);
// ...
}
// ...
}
The final result may look like this (if an error occurred):

Error Handler – Usage
It is highly recommended to initialize the error handler in your component. Therefore, set a global error handler which can be accessed from all your controllers across your application. Further – if you use a base controller from which all your other controllers inherit –, a convenience method to get this error handler in your base class is also recommended.
- First instantiation in your
Component.ts:
export default class Component extends UIComponent {
// if not passing the second parameter, the model's name will be "errorModel"
private _errorHandler: ErrorHandler = new ErrorHandler(this, "myErrorModel");
public init(): void {
// call the base component's init function
super.init();
// create the error model with the default name
this.setModel(models.createErrorModel(), this._errorHandler.getModelName());
// create the views based on the url/hash
this.getRouter().initialize();
}
// ...
}- (Optional) Convenience method in your BaseController:
export default class BaseController extends Controller {
// ...
protected getErrorHandler(): ErrorHandler {
const errorHandler = this.getOwnerComponent().getErrorHandler();
return errorHandler;
}
// ...
}- Usage in one of your controller – Odata request failed:
// handle error only
this.getODataModel().create("/<anyPath>", payload, {
success: (response: any) => {
// do sth.
},
error: (error: OdataError) => {
// get the error handler and add message to the error model
this.getErrorHandler().handleError(error);
},
});
// show custom error message
this.getODataModel().create("/<anyPath>", payload, {
success: (response: any) => {
// do sth.
},
error: (error: OdataError) => {
// get the error handler, add message to the error model, and display the custom message
this.getErrorHandler().showCustomError("My custom error message.", true, {
title: "Watch out for my error message",
});
},
});
// optional method chaining example
this.getODataModel().create("/<anyPath>", payload, {
success: (response: any) => {
// do sth.
},
error: (error: OdataError) => {
// any control that's busy state should be set to false
const control = this.getView();
// any dialog
const dialog = this.getView().byId("myDialogId")
// get the error handler and add message to the error model
// 1. set a controls busy state to false
this.getErrorHandler().handleError(error).setBusyFalse(control);
// 2. set busy state of dialog to false and close it.
// Attention: closeDialog() is only available, if the control passed to setBusyFalse is a dialog
this.getErrorHandler().handleError(error).setBusyFalse(dialog).closeDialog();
// 3. close any dialog
this.getErrorHandler().handleError(error).closeDialog(dialog);
},
});Message Handler
The message handler can be used to display a message box of the following types displaying the corresponding icons and buttons:
- alert
- information
- confirm
- success
- warning
It is also possible to add your messages to a JSONModel for further processing or only adding it to a model.
Message Handler - Usage
- Create a new instance in your controller or Component
// without message model
// controller
private _messageHandler = new MessageHandler(this.getOwnerComponent());
// component
private _messageHandler = new MessageHandler(this);
// with message model
private _messageHandler = new MessageHandler(this, "myMessageModel");
- Create a model for your handler (if not initially done)
// example in your controller with default name 'messageModel'
this._messageHandler.createMessageModel();
// example in your controller with custom model name
this._messageHandler.createMessageModel("myMessageModel");
- Show custom message
// show message
this._messageHandler.showCustomMessage({
title: "My Custom Title",
message: "My beautiful message to be displayed",
messageType: "information"
});
// show message and add to your model – if model exists
this._messageHandler.showCustomMessage({
title: "My Custom Title",
message: "My beautiful message to be displayed",
messageType: "information"
}).addToModel();- Add message to model only
this._messageHandler
.setMessage("information", "My beautiful message to add to my model")
.addToModel();SelectionDialog
The SelectionDialog can be used to display any key-value-pair in a dropdown (see Select). Further, a TextArea is provided which can be used for the following cases:
- Displaying further information to the selected key of the dropdown.
- Displaying pre-defined texts - based on a selected key - and enable a client to change the text before submitting it.
- Using the TextArea to provide an option for clients to submit a text to a selected key.
SelectionDialog - Hints
:bulb: Hints When passing the data to be displayed as a JSONModel, you must provide an array of objects which (at least) have the following properties:
key: The key used for the Select control.description: The value to be displayed as additional text when the dropdown (Select control) is used.detail: The text to be displayed in the TextArea (ifundefined, the area is set to '--' by default).Moreover,
- the event handler of the provided close button is provided and destroys it to prevent duplicate id errors.
- the selection change event handler of the Select control is implemented and sets the TextArea's value (
model>detail) based on the selected key.
SelectionDialog - Usage
- Create a new instance where needed
const selectionDialog = SelectionDialog.getInstance();- Open the SelectionDialog using the
openSelectionDialogmethod within a button press event handler:
// map your data to the appropriate structure as defined in the type ResultType
const mapped = {
results: data.results.map((res) => {
return {
key: res.myKey,
description: res.myDescription,
detail: res.myDetail,
};
}),
};
// create and open the SelectionDialog
this.selectionDialogInstance = SelectionDialog.getInstance();
const { select, textArea }= await selectionDialog.openSelectionDialog(
event, // Button$PressEvent
{
modelData: mapped,
modelName: "myModelName",
calculateWidths: true,
selectDialog: {
selectDialogTitle: "MyTitle",
}
select: {
selectLabel: "My select label",
selectColumnRatio: "1:2",
}
textArea: {
editable: true,
rows: 10,
textAreaLabel: "My text area label",
},
button: {
cancelButton: {
text: "Cancel",
type: ButtonType.Default,
},
confirmButton: {
text: "Confirm",
type: ButtonType.Accept,
press: this.handleConfirmButtonPress.bind(this), // bind your own logic for a positive action
},
},
},
this.getView() // view to add the dialog to
);
// access data
const selectedKey = select.getSelectedKey();
const text = textArea.getValue();
// close the dialog
this.selectionDialogInstance.closeDialog();openSelectionDialog – parameters
event
The corresponding Button press event on which the dialog should be opened.
options
/**
* Minimal set of general properties to display
* data in the {@link SelectionDialog}.
*/
type ResultType = {
/**
* Key used to be bound to the
* Select control of the SelectionDialog.
*/
key: string;
/**
* Description that is displayed when using
* the Select control.
*/
description: string;
/**
* Detail property to display text in the Dialog's
* TextArea control.
*
* @remarks
* If no text should be displayed on selection change,
* provide the property as `detail: undefined` in your model.
*/
detail: string;
};/**
* Options to provide for the SelectionDialog.
*/
export interface SelectDialogOptions<T extends ResultType> {
/**
* The name of the model to be bound
* to the Selection dialog.
*/
modelName: string;
/**
* Data to be bound to the JSONModel
* of the SelectionDialog.
*
* @remarks
* The Model must be provided as an object
* containing the actual data as an array.
*/
modelData: {
/**
* An array of data to be displayed,
* see {@link ResultType}.
*/
results: T[];
};
selectDialog: {
/**
* Title property of the Dialog control.
*
* See `title` property of [Dialog](https://ui5.sap.com/#/api/sap.m.Dialog%23controlProperties).
*/
selectDialogTitle: string;
/**
* The content width of the {@link Dialog}.
*
* See `contentWidth` property of [Dialog](https://ui5.sap.com/#/api/sap.m.Dialog%23controlProperties).
*/
selectDialogContentWidth?: string;
/**
* Optional indicator whether the dialog and it's control widths should be calculated based
* on the user's screen width and the select items.
*
* @remarks
* If provided as `true`, all provided widths are ignored.
*/
calculateWidths?: boolean;
};
select: {
/**
* Text that is displayed above
* the Select control within the SelectionDialog.
*
* @remarks
* Provide a short description of what the client
* can choose from.
*/
selectLabel: string;
/**
* Determines the column ratio when displaying the key and an additional text
* for the {@link Select}.
*
* @remarks
* Pattern must follow: 1:1, 1:2, 2:1, 3:2, etc.
* Default value is 1:1.
*/
selectColumnRatio?: string;
/**
* The width of the select field.
* For more information see [sap.m.Select#Properties](https://sapui5.hana.ondemand.com/#/api/sap.m.Select%23controlProperties).
*/
selectWidth?: string;
};
/**
* Options of the TextArea control.
*/
textArea: {
/**
* Text to be displayed above the TextArea
* control.
*
* @remarks
* Provide a short description of what is displayed/
* should be entered in the TextArea.
*/
textAreaLabel: string;
/**
* Indicator whether the TextArea can be edited.
*
* See [TextArea](https://ui5.sap.com/#/api/sap.m.TextArea).
*/
editable: boolean;
/**
* Row property of the TextArea to render
* at least the provided number of rows.
*
* See [TextArea](https://ui5.sap.com/#/api/sap.m.TextArea).
*/
rows: number;
};
/**
* Options of the dialog's buttons aggregation.
*
* @remarks
* Currently, the Dialog is limited to two buttons.
*/
button: {
/**
* Button options for the 'confirm' button, i.e., a button
* invoking a 'positive' action on press.
*/
confirmButton: {
/**
* {@link ButtonType} that determines
* the style of the button.
*
* See [ButtonType](https://ui5.sap.com/#/api/sap.m.ButtonType).
*/
type: ButtonType;
/**
* Text to be displayed within the Button.
*
* See [Button](https://ui5.sap.com/#/api/sap.m.Button%23controlProperties).
*/
text: string;
/**
* Function to be invoked when the 'confirm button'
* of the SelectionDialog is pressed.
*
* @param event - The button's press event.
*/
press: (event: Button$PressEvent) => void | Promise<void>;
/**
* Optional custom property as aggregation to the button.
* Can be used to save a key for further processing on button
* press.
*/
customKey?: string;
};
/**
* Cancel button options.
*
* @remarks
* The close method is provided out the box,
* no implementation needed.
*/
cancelButton: {
/**
* {@link ButtonType} that determines
* the style of the button.
*
* See [ButtonType](https://ui5.sap.com/#/api/sap.m.ButtonType).
*/
type: ButtonType;
/**
* Text to be displayed within the Button.
*
* See [Button](https://ui5.sap.com/#/api/sap.m.Button%23controlProperties).
*/
text: string;
};
};
}view
The view of the calling application to which the SelectionDialog should be added.
