Message Renderer

In ReqEase, rendering messages to provide feedback to users is a fundamental aspect of handling responses and ensuring a smooth user experience. Messages can take various forms, such as success messages, error messages, or informational messages, and they can be displayed within your web application in different ways, like in a form, toast notifications, or attached to input fields. To facilitate this, ReqEase provides message rendering capabilities through message handlers and renderers.

DefaultMessage and DefaultMessageRenderer

The core of message rendering in ReqEase revolves around the DefaultMessage class and its corresponding renderer interface, DefaultMessageRenderer. This foundation allows for consistent message handling across different message types, such as form messages, input messages, and toast messages. Here's an overview:

  • DefaultMessage: An abstract class that serves as the base for all message types. It takes generic parameters MessageData (the message's data structure) and MessageRenderer (the associated renderer).

    • messageData: An array of message data to render.

    • messageRenderer: The renderer responsible for displaying the messages.

    • show(): An abstract method to show the messages.

    • destroy(): An abstract method to destroy or remove the messages.

  • DefaultMessageRenderer: An interface specifying methods required for rendering messages. It includes:

    • buildMessage: Builds and returns the HTML representation of a single message.

    • renderMessages: Renders multiple messages.

    • removeMessages: Removes displayed messages.

FormMessage Example

An example of a concrete message type is FormMessage. It extends DefaultMessage and has an associated FormMessageRenderer. Here's how it works:

class FormMessage extends DefaultMessage<FormMessageData, FormMessageRenderer> {
    form: JQuery<HTMLElement>;

    constructor(messageData: FormMessageData[], messageRenderer: FormMessageRenderer, form: JQuery<HTMLElement>) {
        super(messageData, messageRenderer);
        this.form = form;
    }

    destroy(): void {
        this.messageRenderer.removeMessages(this.messageRenderer, this);
    }

    show(): void {
        this.messageRenderer.renderMessages(this.messageRenderer, this, this.messageData);
    }
}

Default Form Message Renderer

defaultFormMessageRenderer is the default renderer for form messages in ReqEase. It builds form messages based on the provided message data. Here's an example of its configuration:

export const defaultFormMessageRenderer: FormMessageRenderer = {
    buildMessage: (_messageRenderer: FormMessageRenderer, _message: FormMessage, messageData: FormMessageData) : JQuery<HTMLElement> => {
        let buttons = "";
        if (!isUndefinedOrNull(messageData.buttons)) {
            for (let button of messageData.buttons) {
                buttons += `<button class="btn btn-sm btn-outline-${button.color??messageData.status}" type="button">${button.text}</button>`;
            }
        }
        if (buttons !== "") {
            buttons = `<hr><div class="buttons mt-3 mb-2">${buttons}</div>`;
        }
        let hideIcon = '<button type="button" class="close" data-dismiss="alert" aria-label="Close">\n' +
            '    <span aria-hidden="true">&times;</span>\n' +
            '  </button>';
        return $("<div class='form-message alert alert-" + messageData.status + " alert-dismissible fade show'>"+ hideIcon + messageData.message + buttons + "</div>");
    },
    renderMessages: (messageRenderer: FormMessageRenderer, message: FormMessage, messagesData: FormMessageData[]) => {
        if (isUndefinedOrNull(message.form)) {
            console.error("FormMessageRenderer: form is undefined");
            return;
        }
        let form = message.form;
        let messages = form.find(".form-messages-parent");
        if (isUndefinedOrNull(messages) || messages.length === 0) {
            let messages_tmp = $('<div class="form-messages-parent"></div>');
            let okBtn = form.find('.btn').last();
            if (okBtn.length === 0) {
                okBtn = form.find('button[type="submit"]').last();
            }
            if (okBtn.parent().hasClass('form-group')) {
                okBtn = okBtn.parent();
            }
            messages_tmp.insertBefore(okBtn);
            messages = messages_tmp;
        }

        messageRenderer.removeMessages(messageRenderer, message);

        for (let messageData of messagesData) {
            let messageElement = messageRenderer.buildMessage(messageRenderer, message, messageData);
            messageElement.appendTo(messages);
        }
    },
    removeMessages: (_messageRenderer: FormMessageRenderer, message: FormMessage) => {
        message.form.find('.form-messages-parent .form-message').each(function (_index, element) {
            $(element).remove();
        });
    }
};

InputMessage and ToastMessage

In addition to FormMessage, ReqEase provides two more message types: InputMessage and ToastMessage. These types follow the same pattern as FormMessage and are used for different display scenarios.

  • InputMessage: Used for attaching messages to input fields and interacting with user input.

  • ToastMessage: Displays messages as toast notifications in the application.

Customizing Message Rendering

ReqEase allows developers to customize message rendering by implementing their own message handlers and renderers. By creating custom message types and corresponding renderers, you can tailor the message presentation to your application's needs. These customizations are especially useful when integrating ReqEase with different frontend frameworks or libraries.

In ReqEase, message rendering is a versatile and extensible feature that enhances user communication and feedback within your web application.

Last updated