Подтверждение удаления через модальное окно. как уменьшить код?
Всем привет. Есть модальное окно написанное в виде плагина. нужно удалить елемент из дом и подтвердить в модальном окне это я сделал двумя способами. но мне кажется это сильно громоздко! можно ли как то в евенте дождаться ответа на модальное окно? P S Или хотел бы услышать мнение как лучше оставить?
<body>
<div class="content">
<h1>javascript modalWindow</h1>
<div class="wrapper-cards"></div>
</div>
<script src="base.js"></script>
<script src="plugins/modal.js"></script>
<script src="index.js"></script>
</body>
base.js
const $ = {};
modal.js
Element.prototype.appendAfter = function (element) {
element.parentNode.insertBefore(this, element.nextSibling);
}
//↓ создаем модальное окно
function _createModal(options) {
// дефолтное значениие ширины окна
const DEFAULT_WIDTH = '600px';
// создаем родительский элемент
const modal = document.createElement('div');
// присваиваем класс
modal.classList.add('artmodal');
// и в нем создаем модальное окно
modal.insertAdjacentHTML("afterbegin", `
<div class="modal-overlay" data-close="close" >
<div class="modal-window" style="width: ${options.width || DEFAULT_WIDTH}">
<div class="modal-header">
<span class="modal-titel">${options.title || 'Окно'}</span>
${options.closable ? `<span class="modal-close" data-close="close">✘</span>` : ''}
</div>
<div class="modal-body" data-content>
${options.content || ' '}
</div>
</div>
</div>
`);
document.body.appendChild(modal);
// ↓ реализуем футер
const footer = _creatModalFooter(options.footerButtons);
// созданная фукция
footer.appendAfter(modal.querySelector('[data-content]'))
return modal;
}
// ↓ создаем футер
function _creatModalFooter(buttonS = []) {
// если не заданы параметры футера,
if (buttonS.length === 0) {
//создаем просто див а лучще ничего не создавать
// но можем что то дефолтное создать
return document.createElement('div');
}
// else создаем родительский элемент елемент присваиваем класс
const wrap = document.createElement('div');
wrap.classList.add('modal-footer');
// создаем кнопки на основе полученного масива
buttonS.forEach(btn => {
const $btn = document.createElement('button')
$btn.textContent = btn.text;
$btn.setAttribute(`${btn.dat}`, "");
$btn.classList.add(`${btn.type || 'defBaton'}`)
$btn.onclick = btn.handler || noop;
// и присваиваем родителю каждый новый в конец
wrap.append($btn);
})
return wrap
}
function noop() {
console.log('noopFunc')
}
$.modal = function (options) {
const ANIM_TIME = 200;
const $modal = _createModal(options);
//закрывается ли окно
let closing = false;
let destroyed = true;
const modal = {
open() { !closing && $modal.classList.add('open') },
close() {
closing = true;
$modal.classList.remove('open');
$modal.classList.add('hide');
setTimeout(() => {
closing = false;
$modal.classList.remove('hide');
}, ANIM_TIME);
},
};
const listener = (event) => event.target.hasAttribute('data-close') && modal.close();
$modal.addEventListener('click', listener);
return Object.assign(modal, {
//уничтожение модального окна и его слушатлей
destroy() {
$modal.parentNode.removeChild($modal);
$modal.removeEventListener('click', listener);
destroyed = true
},
// изменение контента.
setContent(html) {
let setContent = `
<div class="modal-set">${html}</div>
`
$modal.querySelector('[data-content]').innerHTML = setContent
}
});
}
И еще есть тот самый промис
$.confirm = function (options) {
return new Promise((resolve, reject) => {
const modal = $.modal({
title: options.title,
width: '400px',
closable: false,
content: options.content,
footerButtons: [
{
// первая слево
text: 'Удалить', data: data - fdel, type: 'modalBut', handler() {
modal.close()
resolve()
}
},
{
text: 'Закрыть', data: data - fdel, type: 'modalBut', handler() {
modal.close();
reject()
}
},
],
});
modal.open()
});
};
index.js
const fruits = [
{ id: 1, title: 'Яблоки', prise: '10', src: 'https://cdn.fishki.net/upload/post/2021/02/12/3605875/846f718321a71f4713f0faa9d86b5b9d.jpg', },
{ id: 2, title: 'Груши', prise: '15', src: 'https://aif-s3.aif.ru/images/012/449/168b91a9ab6a3f1ac3ae95525e2d0328.jpg', },
{ id: 3, title: 'Апельсин', prise: '25', src: 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Ambersweet_oranges.jpg/200px-Ambersweet_oranges.jpg', },
{ id: 4, title: 'Манго', prise: '20', src: 'https://resizer.mail.ru/p/9a851cf6-ffa8-5974-9d46-261828a9606d/AAAcuzorDYfIhh6m-8-lsk3fiv7VQQgzQWoq8KRQnb8nOkxqcn7O_S7YGbKwI4SQy2KKzk2-2sTYy0brhPSGmWvJQmY.jpg', },
{ id: 5, title: 'Ананас', prise: '28', src: 'https://licey-istra.ru/wp-content/uploads/ananas-podderzhit-vash-organizm-vo-vremya-stressovyh-situacij2.jpg', },
{ id: 6, title: 'Киви', prise: '40', src: 'https://s1.travelask.ru/system/images/files/001/130/309/wysiwyg_jpg/fruit-frukty-kivi-miata.jpg?1534339094', },
{ id: 7, title: 'Вишня', prise: '13', src: 'https://www.gastronom.ru/binfiles/images/20160329/bf63eaa6.jpg', },
{ id: 8, title: 'Арбуз', prise: '56', src: 'https://ethnomir.ru/upload/medialibrary/944/arbuz.jpg', },
]
const cardContainer = document.querySelector('.wrapper-cards')
const toHTML = fruit => `
<div class="cards">
<div class="cards__img">
<img src="${fruit.src}" alt="${fruit.title}">
</div>
<div class="cards__title">
<h2>${fruit.title}</h2>
</div>
<div class="cards__button">
<button class="btn button__prise" data-idfruit="${fruit.id}">Prise</button>
<button class="btn button__clear" data-clear="${fruit.id}">Clear</button>
</div>
</div>
`;
function render() {
const html = fruits.map(toHTML).join(' ');
document.querySelector('.wrapper-cards').innerHTML = html;
}; render();
let dat = 'data-set'
document.addEventListener('click', event => {
// * event.preventDefault()
const btnId = +event.target.dataset.idfruit;
if (event.target.hasAttribute('data-idfruit')) {
const fruit = fruits.find(f => f.id === btnId)
console.log(fruit)
priseModal.setContent(`
<p>Цена на ${fruit.title}: <strong>${fruit.prise}$</strong></p>
`)
priseModal.open()
};
if (event.target.hasAttribute('data-clear')) {
const cards = event.target.closest('.cards');
// могу передать таргет в глобпльную переменную и вызвать удаление из функции кнопки.
// x = cards
clearCards.setContent(cards.querySelector('.cards__img').outerHTML)
clearCards.open()
// хочу избавится от этого колбека
// также есть Промис. с модальным окном, но если его вызывать здесь, каждый раз в дом дереве создается новый элемент. да я могу его разрушить. но это опять пляски туда сюда.
document.addEventListener('click', e => {
if (e.target.hasAttribute('data-fdel')) {
cardContainer.removeChild(cards);
}
})
};
});
// !!!!
let x;
const priseModal = $.modal({
title: 'Цена на товар',
// возможность закрывать окно
closable: true,
content: '',
width: '400px',
footerButtons: [
{
text: 'Закрыть', type: 'modalBut', handler() {
priseModal.close();
}
},
]
});
const clearCards = $.modal({
title: 'Удалить карточку?',
// возможность закрывать окно
closable: true,
content: '',
width: '400px',
footerButtons: [
{
text: 'Удалить', dat: 'data-fdel', type: 'modalBut', handler() {
// cardContainer.removeChild(x);
clearCards.close()
}
},
{
text: 'Закрыть', dat: 'data-fdon', type: 'modalBut', handler() {
clearCards.close();
}
},
]
});