1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
import Toast from "bootstrap/js/dist/toast";
export class Toaster {
constructor(options) {
if (!options) {
options = {hideAfter: 3500, position: "top-right"};
}
this.root = document.createElement("div");
this.root.id = "toaster-container";
switch (options.position) {
case"top-right":
this.root.style = "display: flex; align-items: end; flex-direction: column; position: absolute; top: 0; right: 0; padding: 15px; z-index: 9999;";
break;
case"top-left":
this.root.style = "position: absolute; top: 0; padding: 15px; z-index: 9999;";
break;
case"bottom-right":
this.root.style = "display: flex; align-items: end; flex-direction: column; position: absolute; bottom: 0; right: 0; padding: 15px; z-index: 9999;";
break;
case"bottom-left":
this.root.style = "position: absolute; bottom: 0; padding: 15px; z-index: 9999;";
break;
default:
this.root.style = "display: flex; align-items: end; flex-direction: column; position: absolute; top: 0; right: 0; padding: 15px; z-index: 9999;";
break;
}
document.body.appendChild(this.root);
this.defaultTimeout = options.hideAfter ? options.hideAfter : 3500;
this.toastTypes = {error: "error", success: "success", info: "info"};
}
display(title, message, autohide, type) {
if (!title || typeof title !== "string" || typeof message !== "string") {
throw new Error("Toaster: title &| message is empty or not a string");
}
let toast = document.createElement("div");
toast.className = "toast";
toast.role = "alert";
toast.id = Math.random().toString(36).substring(2) + Date.now().toString(36);
let toastHeader = document.createElement("div");
toastHeader.className = "toast-header";
let toastTypeIndicator = document.createElement("div");
switch (type) {
case this.toastTypes.error:
toastTypeIndicator.className = "toast-type-indicator rounded me-2 bg-danger";
toast.style = "width: max-content; min-width: 300px; border-color: var(--bs-danger);";
break;
case this.toastTypes.success:
toastTypeIndicator.className = "toast-type-indicator rounded me-2 bg-success";
toast.style = "width: max-content; min-width: 300px; border-color: var(--bs-success);";
break;
case this.toastTypes.info:
toastTypeIndicator.className = "toast-type-indicator rounded me-2 bg-info";
toast.style = "width: max-content; min-width: 300px; border-color: var(--bs-info);";
break;
}
toastTypeIndicator.style = "width: 18px; height: 18px;";
toastHeader.appendChild(toastTypeIndicator);
let toastTitle = document.createElement("strong");
toastTitle.className = "me-auto text-truncate";
toastTitle.innerText = title;
toastHeader.appendChild(toastTitle);
let toastCloseButton = document.createElement("button");
toastCloseButton.className = "ms-2 mb-1 close";
toastCloseButton.setAttribute("data-bs-dismiss","toast");
toastCloseButton.onclick = () => {
setTimeout(() => {
toast.parentNode.removeChild(toast);
}, parseInt(1e3));
};
if (!autohide) {
let toastCloseButtonIcon = document.createElement("img");
toastCloseButtonIcon.src = "data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z\" clip-rule=\"evenodd\"/><path fill-rule=\"evenodd\" d=\"M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z\" clip-rule=\"evenodd\"/><path fill-rule=\"evenodd\" d=\"M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z\" clip-rule=\"evenodd\"/></svg>";
toastCloseButtonIcon.alt = "x";
toastCloseButtonIcon.dataset.ariaHidden = "true";
toastCloseButton.appendChild(toastCloseButtonIcon);
toastHeader.appendChild(toastCloseButton);
}
toast.appendChild(toastHeader);
if (message) {
let toastBody = document.createElement("div");
toastBody.className = "toast-body";
toastBody.style = "word-wrap: break-word;";
toastBody.innerText = message;
toast.appendChild(toastBody);
}
this.root.appendChild(toast);
let delay = 0;
if (typeof autohide === "number" && autohide !== 0) {
delay = autohide;
autohide = true;
} else if (autohide) {
delay = this.defaultTimeout;
}
new Toast(document.getElementById(toast.id), {
animation: true,
autohide: autohide,
delay: delay
}).show();
if (delay) setTimeout(() => {
toast.parentNode.removeChild(toast);
}, parseInt(delay + 1e3));
}
error(title, message = "", autohide = true) {
this.display(title, message, autohide, this.toastTypes.error);
}
errorObj(props) {
if (props.autohide === undefined) props.autohide = true;
this.display(props.title, props.message, props.autohide, this.toastTypes.error);
}
success(title, message = "", autohide = true) {
this.display(title, message, autohide, this.toastTypes.success);
}
successObj(props) {
if (props.autohide === undefined) props.autohide = true;
this.display(props.title, props.message, props.autohide, this.toastTypes.success);
}
info(title, message = "", autohide = true) {
this.display(title, message, autohide, this.toastTypes.info);
}
infoObj(props) {
if (props.autohide === undefined) props.autohide = true;
this.display(props.title, props.message, props.autohide, this.toastTypes.info);
}
}
|