
javascript class DraggableModal
class DraggableModal {
constructor(modalId, recipientAttribute) {
this.modal = document.getElementById(modalId);
this.modalContent = this.modal.querySelector('.modal-content');
this.modalHeader = this.modal.querySelector('.modal-header');
this.isDragging = false;
this.startX = 0;
this.startY = 0;
this.offsetX = 0;
this.offsetY = 0;
this.recipientAttribute = recipientAttribute;
this.startDrag = this.startDrag.bind(this);
this.drag = this.drag.bind(this);
this.endDrag = this.endDrag.bind(this);
this.modalHeader.addEventListener('mousedown', this.startDrag);
this.modalHeader.addEventListener('touchstart', this.startDrag);
document.addEventListener('mousemove', this.drag);
document.addEventListener('touchmove', this.drag);
document.addEventListener('mouseup', this.endDrag);
document.addEventListener('touchend', this.endDrag);
this.modal.addEventListener('show.bs.modal', (event) => {
const button = event.relatedTarget;
const recipient = button.getAttribute(this.recipientAttribute);
const modalTitle = this.modal.querySelector('.modal-title');
const modalBodyInput = this.modal.querySelector('.modal-body input');
if (recipient) {
modalTitle.textContent = `New Message to ${recipient}`;
if (modalBodyInput) modalBodyInput.value = recipient;
}
});
this.modal.addEventListener('hidden.bs.modal', (event) => {
const remember = this.modal.querySelector('.form-check-input');
if (!remember.checked) {
this.modalContent.removeAttribute('style');
const content = this.modalContent.querySelector('.modal-body p');
if (content) content.textContent = 'The content of your modal.';
} else {
const content = this.modalContent.querySelector('.modal-body p');
if (content) content.textContent = 'I remembered the position';
}
});
}
startDrag(e) {
this.isDragging = true;
this.startX = e.clientX || e.touches[0].clientX;
this.startY = e.clientY || e.touches[0].clientY;
this.offsetX = this.modalContent.offsetLeft;
this.offsetY = this.modalContent.offsetTop;
}
drag(e) {
if (this.isDragging) {
const x =
this.offsetX + (e.clientX || e.touches[0].clientX) - this.startX;
const y =
this.offsetY + (e.clientY || e.touches[0].clientY) - this.startY;
this.modalContent.style.left = x + 'px';
this.modalContent.style.top = y + 'px';
}
}
endDrag() {
this.isDragging = false;
}
}
document.addEventListener('DOMContentLoaded', function () {
new DraggableModal('modal-1');
new DraggableModal('modal-2', 'data-recipient');
});
css
.modal-header {
cursor: move;
}
.modal-title::before {
content: "⠿";
color: #aaa;
margin-right: 1rem;
font-size: 1.5rem;
}