npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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):

Button Message Strip example

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 (if undefined, 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 openSelectionDialog method 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.