innerHTML을 사용해 js에서 모달 만들기

ahncheer·2023년 7월 26일
0

LWC & LWR

목록 보기
38/52

1. 모달을 불러올 버튼이 있는 컴포넌트 만들기

1-1) lwc036ReuseModal.html

<button onclick={openConfirm}>openConfirm</button>

1-1) lwc036ReuseModal.js

import { LightningElement } from 'lwc';
import { alert, confirm } from './deModal';

export default class Lwc036ReuseModal extends LightningElement {
    openConfirm(){
        confirm('알럿 메세지').then(isConfirm => {
            console.log('isConfirm : ', isConfirm);
        });
    }
}

1-1) lwc036ReuseModal.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>57.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
      <target>lightning__AppPage</target>
      <target>lightning__RecordPage</target>
      <target>lightning__HomePage</target>
      <target>lightningCommunity__Page</target>
      <target>lightningCommunity__Default</target>
    </targets>
</LightningComponentBundle>

2. 모달을 만드는 JS 만들기


deModal.js파일을 만들어 위와 같은 구조로 만들었습니다.

// 커스텀 Confirm 모달
const confirm = (title) => {
    if (!window._isOpenConfirmModal) {
        window._isOpenConfirmModal = true;
        return new Promise((resolve) => {
            // modal을 새로 만들어 body태그에 추가하고, 
            // body 태그에 aside태그로 감싸인 modal이 추가되면 active class를 추가해 보이게 함
            let confirmModal = document.createElement("aside");
            confirmModal.classList.add("confirm-modal");
            confirmModal.innerHTML = `
                <div class="confirm-container">
                    <style>${alertConfirmStyle}</style>
                    <div class="confirm-body">
                        <h5 class="ca-title">${title}</h5>
                    </div>
                    <div class="confirm-bottom">
                        <button type="button" class="cancel">취소</button>
                        <button type="button" class="confirm">확인</button>
                    </div>
                </div>`;
            document.body.appendChild(confirmModal);
            setTimeout(function () {
                document
                    .querySelector(".confirm-modal")
                    .classList.add("active");
            }, 150);

            // 모달이 만들어지면, 버튼에 onclick 이벤트를 추가
            let buttons = confirmModal.querySelectorAll(
                ".confirm-bottom > button"
            );
            buttons.forEach((item, idx) => {
                // 확인을 눌렀으면 true, 취소를 눌렀으면 false 반환
                let isConfirm = item.classList.contains("confirm");
                item.addEventListener("click", () => {
                    setResolve(isConfirm);
                });
            });

            // 확인, 또는 취소를 눌러 모달을 닫음 
            function setResolve(bool) {
                document
                    .querySelector(".confirm-modal")
                    .classList.remove("active");

                setTimeout(function () {
                    document.querySelector(".confirm-modal").remove();
                    window._isOpenConfirmModal = false;
                    resolve(bool);
                }, 350);
            }
        });
    }
}

export {
    alert,
    confirm
}

const alertConfirmStyle = `
    .confirm-modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: rgba(0,0,0,0.5);
        padding: 20px 0;
        z-index: 999999;
    }
    .confirm-modal .confirm-container {
        background-color: white;
        width: 500px;
        max-width: calc(100% - 40px);
        max-height: 100%;
        text-align: center;
        overflow-y: auto;
        opacity: 0;
        transform: scale(0.85);
        transition: all 0.25s;
        padding: 20px;
    }
    .confirm-modal.active .confirm-container {
        opacity: 1;
        transform: none;
    }
`;

화면 확인

뒷 배경은 무시해주세요

↑ GIF입니다 안보이면 새로고침

+) 만약 transform: scale(0.85);이 없다면 화면이 어색해집니다.

↑ GIF입니다 안보이면 새로고침

+) 컴포넌트 안에 JS를 만드는 것이 아닌, 다른 컴포넌트에 넣고 공용으로 사용하고 싶으면 deModal이라는 컴포넌트를 따로 만들고, 버튼이 있는 컴포넌트의 JS에서 다음과 같이 불러옵니다.
import { alert, confirm } from 'c/deModal';

profile
개인 공부 기록용.

0개의 댓글