1 /* eslint-disable max-len */
2 /* eslint-disable comma-dangle */
3 /* eslint-disable require-jsdoc */
5 // =========================================================
7 // Alert box design by Igor Ferrão de Souza: https://www.linkedin.com/in/igor-ferr%C3%A3o-de-souza-4122407b/
9 // eslint-disable-next-line no-unused-vars
16 cancelText = 'Cancel',
19 return new Promise((resolve) => {
20 setInterval(() => {}, 5000);
21 const body = document.querySelector('body');
23 let closeStyleTemplate = 'alert-close';
24 if (closeStyle === 'circle') {
25 closeStyleTemplate = 'alert-close-circle';
28 let btnTemplate = `<button class="alert-button ${type}-bg ${type}-btn mui-btn mui-btn--primary">${buttonText}</button>`;
29 if (type === 'question') {
31 <div class="question-buttons">
32 <button class="confirm-button error-bg error-btn mui-btn mui-btn--danger">${confirmText}</button>
33 <button class="cancel-button question-bg question-btn mui-btn">${cancelText}</button>
39 <svg class="alert-img" xmlns="http://www.w3.org/2000/svg" fill="#fff" viewBox="0 0 52 52" xmlns:v="https://vecta.io/nano">
40 <path d="M26 0C11.664 0 0 11.663 0 26s11.664 26 26 26 26-11.663 26-26S40.336 0 26 0zm0 50C12.767 50 2 39.233 2 26S12.767 2 26 2s24 10.767 24 24-10.767 24-24
41 24zm9.707-33.707a1 1 0 0 0-1.414 0L26 24.586l-8.293-8.293a1 1 0 0 0-1.414 1.414L24.586 26l-8.293 8.293a1 1 0 0 0 0 1.414c.195.195.451.293.707.293s.512-.098.707
42 -.293L26 27.414l8.293 8.293c.195.195.451.293.707.293s.512-.098.707-.293a1 1 0 0 0 0-1.414L27.414 26l8.293-8.293a1 1 0 0 0 0-1.414z"/>
45 if (type === 'success') {
47 <svg class="alert-img" xmlns="http://www.w3.org/2000/svg" fill="#fff" viewBox="0 0 52 52" xmlns:v="https://vecta.io/nano">
48 <path d="M26 0C11.664 0 0 11.663 0 26s11.664 26 26 26 26-11.663 26-26S40.336 0 26 0zm0 50C12.767 50 2 39.233 2 26S12.767 2 26 2s24 10.767 24 24-10.767 24-24
49 24zm12.252-34.664l-15.369 17.29-9.259-7.407a1 1 0 0 0-1.249 1.562l10 8a1 1 0 0 0 1.373-.117l16-18a1 1 0 1 0-1.496-1.328z"/>
53 if (type === 'info') {
55 <svg class="alert-img" xmlns="http://www.w3.org/2000/svg" fill="#fff" viewBox="0 0 64 64" xmlns:v="https://vecta.io/nano">
56 <path d="M38.535 47.606h-4.08V28.447a1 1 0 0 0-1-1h-4.52a1 1 0 1 0 0 2h3.52v18.159h-5.122a1 1 0 1 0 0 2h11.202a1 1 0 1 0 0-2z"/>
57 <circle cx="32" cy="18" r="3"/><path d="M32 0C14.327 0 0 14.327 0 32s14.327 32 32 32 32-14.327 32-32S49.673 0 32 0zm0 62C15.458 62 2 48.542 2 32S15.458 2 32 2s30 13.458 30 30-13.458 30-30 30z"/>
63 <div class="alert-wrapper">
64 <div class="alert-frame">
65 <div class="alert-header ${type}-bg">
66 <span class="${closeStyleTemplate}">X</span>
69 <div class="alert-body">
70 <span class="alert-title">${title}</span>
71 <span class="alert-message">${message}</span>
78 body.insertAdjacentHTML('afterend', template);
80 const alertWrapper = document.querySelector('.alert-wrapper');
81 const alertFrame = document.querySelector('.alert-frame');
82 const alertClose = document.querySelector(`.${closeStyleTemplate}`);
84 function resolveIt() {
85 alertWrapper.remove();
88 function confirmIt() {
89 alertWrapper.remove();
92 function stopProp(e) {
96 if (type === 'question') {
97 const confirmButton = document.querySelector('.confirm-button');
98 const cancelButton = document.querySelector('.cancel-button');
100 confirmButton.addEventListener('click', confirmIt);
101 cancelButton.addEventListener('click', resolveIt);
103 const alertButton = document.querySelector('.alert-button');
105 alertButton.addEventListener('click', resolveIt);
108 alertClose.addEventListener('click', resolveIt);
109 alertWrapper.addEventListener('click', resolveIt);
110 alertFrame.addEventListener('click', stopProp);
115 // =========================================================
116 // Autocomplete handler
118 // eslint-disable-next-line no-unused-vars
119 function autocomplete(inp, arr) {
120 /* the autocomplete function takes two arguments,
121 the text field element and an array of possible autocompleted values: */
124 /* execute a function when someone writes in the text field: */
125 function handler(e) {
127 const val = this.value;
129 /* close any already open lists of autocompleted values */
132 /* create a DIV element that will contain the items (values): */
133 const a = document.createElement('DIV');
134 a.setAttribute('id', this.id + 'autocomplete-list');
135 a.setAttribute('class', 'autocomplete-items');
136 /* append the DIV element as a child of the autocomplete container: */
137 this.parentNode.appendChild(a);
138 /* for each item in the array... */
139 for (let i = 0; i < arr.length; i++) {
140 /* check if the item starts with the same letters as the text field value :*/
141 if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
142 /* create a DIV element for each matching element: */
143 b = document.createElement('DIV');
144 /* make the matching letters bold :*/
145 b.innerHTML = '<strong>' + arr[i].substr(0, val.length) + '</strong>';
146 b.innerHTML += arr[i].substr(val.length);
147 /* insert a input field that will hold the current array item's value: */
148 b.innerHTML += '<input type="hidden" value="' + arr[i] + '">';
149 /* execute a function when someone clicks on the item value (DIV element): */
150 b.addEventListener('click', ((arg) => (e) => {
151 /* insert the value for the autocomplete text field: */
152 inp.value = arg.getElementsByTagName('input')[0].value;
153 /* close the list of autocompleted values,
154 (or any other open lists of autocompleted values: */
161 inp.addEventListener('input', handler);
162 inp.addEventListener('click', handler);
164 /* execute a function presses a key on the keyboard: */
165 inp.addEventListener('keydown', (e) => {
166 let x = _(this.id + 'autocomplete-list');
167 if (x) x = x.getElementsByTagName('div');
168 if (e.keyCode == 40) {
169 /* If the arrow DOWN key is pressed,
170 increase the currentFocus variable: */
172 /* and and make the current item more visible: */
174 } else if (e.keyCode == 38) { // up
175 /* If the arrow UP key is pressed,
176 decrease the currentFocus variable: */
178 /* and and make the current item more visible: */
180 } else if (e.keyCode == 13) {
181 /* If the ENTER key is pressed, prevent the form from being submitted, */
183 if (currentFocus > -1) {
184 /* and simulate a click on the "active" item: */
185 if (x) x[currentFocus].click();
189 function addActive(x) {
190 /* a function to classify an item as "active": */
191 if (!x) return false;
192 /* start by removing the "active" class on all items: */
194 if (currentFocus >= x.length) currentFocus = 0;
195 if (currentFocus < 0) currentFocus = (x.length - 1);
196 /* add class "autocomplete-active": */
197 x[currentFocus].classList.add('autocomplete-active');
199 function removeActive(x) {
200 /* a function to remove the "active" class from all autocomplete items: */
201 for (let i = 0; i < x.length; i++) {
202 x[i].classList.remove('autocomplete-active');
205 function closeAllLists(elmnt) {
206 /* close all autocomplete lists in the document,
207 except the one passed as an argument: */
208 const x = document.getElementsByClassName('autocomplete-items');
209 for (let i = 0; i < x.length; i++) {
210 if (elmnt != x[i] && elmnt != inp) {
211 x[i].parentNode.removeChild(x[i]);
215 /* execute a function when someone clicks in the document: */
216 document.addEventListener('click', (e) => {
217 closeAllLists(e.target);