/**
*/
export default class PopUpMessage {
/**
* @classdesc
* This class represents a dialog message overlaying a DOM element in order to
* accept / cancel discard changes. The dialog can be closed i.e the overlay disappears
* o canceled. In this last case a callback function should be called.
* @constructs
* @param {Object} popupMessageAttributes - Object containing popup properties.
* @param {HTMLElement} popupMessageAttributes.overlayElement - Element to overlay.
* @param {Object} popupMessageAttributes.callbacks - Contains callback
* methods for close and cancel actions.
* @param {Object} popupMessageAttributes.strings - Contains all the strings needed.
*/
constructor(popupMessageAttributes) {
/**
* Element to be overlaid when the popup appears.
*/
this.overlayElement = popupMessageAttributes.overlayElement;
this.callbacks = popupMessageAttributes.callbacks;
/**
* HTMLElement element to wrap all HTML elements inside the popupMessage.
*/
this.overlayWrapper = this.overlayElement.appendChild(document.createElement('div'));
this.overlayWrapper.setAttribute('class', 'wrs_popupmessage_overlay_envolture');
/**
* HTMLElement to display the popup message, close button and cancel button.
*/
this.message = this.overlayWrapper.appendChild(document.createElement('div'));
this.message.id = 'wrs_popupmessage';
this.message.setAttribute('class', 'wrs_popupmessage_panel');
this.message.setAttribute('role', 'dialog');
this.message.setAttribute('aria-describedby', 'description_txt');
const paragraph = document.createElement('p');
const text = document.createTextNode(popupMessageAttributes.strings.message);
paragraph.appendChild(text);
paragraph.id = 'description_txt';
this.message.appendChild(paragraph);
/**
* HTML element overlaying the overlayElement.
*/
const overlay = this.overlayWrapper.appendChild(document.createElement('div'));
overlay.setAttribute('class', 'wrs_popupmessage_overlay');
// We create a overlay that close popup message on click in there
overlay.addEventListener('click', this.cancelAction.bind(this));
/**
* HTML element containing cancel and close buttons.
*/
this.buttonArea = this.message.appendChild(document.createElement('div'));
this.buttonArea.setAttribute('class', 'wrs_popupmessage_button_area');
this.buttonArea.id = 'wrs_popup_button_area';
// Close button arguments.
const buttonSubmitArguments = {
class: 'wrs_button_accept',
innerHTML: popupMessageAttributes.strings.submitString,
id: 'wrs_popup_accept_button',
};
/**
* Close button arguments.
*/
this.closeButton = this.createButton(buttonSubmitArguments, this.closeAction.bind(this));
this.buttonArea.appendChild(this.closeButton);
// Cancel button arguments.
const buttonCancelArguments = {
class: 'wrs_button_cancel',
innerHTML: popupMessageAttributes.strings.cancelString,
id: 'wrs_popup_cancel_button',
};
/**
* Cancel button.
*/
this.cancelButton = this.createButton(buttonCancelArguments, this.cancelAction.bind(this));
this.buttonArea.appendChild(this.cancelButton);
}
/**
* This method create a button with arguments and return button dom object
* @param {Object} parameters - An object containing id, class and innerHTML button text.
* @param {String} parameters.id - Button id.
* @param {String} parameters.class - Button class name.
* @param {String} parameters.innerHTML - Button innerHTML text.
* @param {Object} callback- Callback method to call on click event.
* @returns {HTMLElement} HTML button.
*/
// eslint-disable-next-line class-methods-use-this
createButton(parameters, callback) {
let element = {};
element = document.createElement('button');
element.setAttribute('id', parameters.id);
element.setAttribute('class', parameters.class);
element.innerHTML = parameters.innerHTML;
element.addEventListener('click', callback);
return element;
}
/**
* Shows the popupmessage containing a message, and two buttons
* to cancel the action or close the modal dialog.
*/
show() {
if (this.overlayWrapper.style.display !== 'block') {
// Clear focus with blur for prevent press any key.
document.activeElement.blur();
this.overlayWrapper.style.display = 'block';
this.closeButton.focus();
} else {
this.overlayWrapper.style.display = 'none';
// _wrs_modalWindow.focus(); This throws an error of not existing _wrs_modalWindow
}
}
/**
* This method cancels the popupMessage: the dialog disappears revealing the overlaid element.
* A callback method is called (if defined). For example a method to focus the overlaid element.
*/
cancelAction() {
this.overlayWrapper.style.display = 'none';
if (typeof this.callbacks.cancelCallback !== 'undefined') {
this.callbacks.cancelCallback();
}
}
/**
* This method closes the popupMessage: the dialog disappears and the close callback is called.
* For example to close the overlaid element.
*/
closeAction() {
this.cancelAction();
if (typeof this.callbacks.closeCallback !== 'undefined') {
this.callbacks.closeCallback();
}
}
/**
* Handle keyboard events detected in modal when elements of this class intervene.
* @param {KeyboardEvent} keyboardEvent - The keyboard event.
*/
onKeyDown(keyboardEvent) {
if (keyboardEvent.key !== undefined) {
// Code to detect Esc event.
if (keyboardEvent.key === 'Escape' || keyboardEvent.key === 'Esc') {
this.cancelAction();
keyboardEvent.stopPropagation();
keyboardEvent.preventDefault();
} else if (keyboardEvent.key === 'Tab') { // Code to detect Tab event.
if (document.activeElement === this.closeButton) {
this.cancelButton.focus();
} else {
this.closeButton.focus();
}
keyboardEvent.stopPropagation();
keyboardEvent.preventDefault();
}
}
}
}