[Modal_Callback]_모달 팝업 사용자 선택 Boolean 값으로 콜백 받기

2022. 11. 4. 16:07[Spring]_/[Spring]_포트폴리오 페이지 만들기

728x90
반응형

환경]

 

개발툴 : IntelliJ

DB : oracle

프레임워크 : spring , mybatis

사용 언어 : ES6, Java , Html5 , CSS


개요]

 

데이터를 저장, 수정을 하는데 있어 사용자에게 확인을 받아야 하는 경우가 있습니다.

 

예를 들어

"입력하신 정보를 저장하시겠습니까?" 라는 알람창이 뜬 다음

사용자가 확인 버튼을 눌러야 실행이 되고,

취소버튼을 누르면 API를 호출하지 않는 경우입니다.

 

이를 공통함수로 원하는 옵션을 부여하여 출력할 수 있도록 해보았습니다.

 

참고 CSS : http://yoonbumtae.com/?p=3632 

 

자바스크립트: 모달(modal window) 만들기 - BGSMM

모달 창이란 사용자 인터페이스 디자인 개념에서 자식 윈도에서 부모 윈도로 돌아가기 전에 사용자의 상호동작을 요구하는 창을 말합니다. 아래 그림에서 가운데 하얀색 부분이 그 예라고 할

yoonbumtae.com

 

공통함수 사용, 생성방법 다음 포스트 참고

https://yn971106.tistory.com/19

 

[common.js]_공통 함수 실전 필드처럼 만들어서 사용하기

개발을 하다 보면 한 페이지에서만 사용하는 함수가 아니라 여러곳에서 사용하는 함수들이 있습니다. 이를 각각 페이지에 적게 되면 시간도 오래걸리고 유지보수가 어려워 한 파일에 넣어서 관

yn971106.tistory.com


시연 화면]

 


<HTML>

<scipt>

우선 SPA 구조로 되어있기 때문에 Index 페이지인 Main 에 common.js 와 css 폴더를 참조시킵니다.

 

해당 페이지 스크립트 

클릭시 이벤트를 걸어줍니다.

공통함수에 선언된 

confirm 메소드에 string 형식의 파라미터만 넘겨줍니다.

 

<CSS>

.modal-overlay{
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(231, 228, 228, 0.63);
    box-shadow: 0 8px 32px 0 rgba(106, 173, 197, 0.37);
    backdrop-filter: blur(1.5px);
    -webkit-backdrop-filter: blur(1.5px);
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.18);
}
.modal-window{
    background: rgba(59, 99, 138, 0.7);
    box-shadow: 0 8px 32px 0 rgba(101, 104, 131, 0.37);
    backdrop-filter: blur( 13.5px );
    -webkit-backdrop-filter: blur( 13.5px );
    border-radius: 10px;
    border: 1px solid rgba( 255, 255, 255, 0.18 );
    width: 400px;
    height: 500px;
    position: relative;
    top: -100px;
    padding: 10px;
}
.title{
    padding-left: 10px;
    display: inline;
    text-shadow: 1px 1px 2px gray;
    color: white;

}
.title h2{
    display: inline;
}
.close-area{
    display: inline;
    float: right;
    padding-right: 10px;
    cursor: pointer;
    text-shadow: 1px 1px 2px gray;
    color: white;
}

.content{
    margin-top: 20px;
    padding: 0px 10px;
    text-shadow: 1px 1px 2px gray;
    color: white;
    height: 300px;
}
.modal_btn_list{
    list-style-type: none;
    width: 100%;
}

.modal_btn_list li{
    float:left;
    margin-left : 10px;
}
.modal_footer{
    height: 20%;
    width: 100%;
}
.modal_right_section{
    margin-top: 78px;
    margin-left: 215px;
    height:100%;
}

 

<common.js>

dialogs:{
    confirm: function(message,checkedCallback,canceledCallback,options){
        let CONFIRM_TEMPLATE =`
        <div class="modal-overlay" data-layer="layer-confirm">
            <div class="modal-window">
               
                    <div class="title">
                        <h2>모달</h2>
                    </div>
                    <div class="close-area">X</div>
                    <div class="content">
                        <div class="ui-layer__body_inner">${message.replace(/(?:\r\n|\r|\n)/g,'<br>')}</div>
                    </div>
                    <div class="modal_footer">
                        <div class="modal_right_section">
                            <ul class="modal_btn_list">
                                <li class="modal_btn_item">
                                    <button type="button" class="modal_btn_cancel layer-cancel">
                                    ${options && options.cancelText ? options.cancelText : '취소'}
                                    </button>
                                </li>
                                <li class="modal_btn_item">
                                    <button type="button" class="modal_btn_cancel layer-checked">
                                    ${options && options.checkedText ? options.checkedText : '확인'}
                                    </button>
                                </li>
                            </ul>
                        </div>
                    </div>
                   
            </div>     
        </div>`

        let confirmElement = _Self.ui.element.create(CONFIRM_TEMPLATE,true);

        confirmElement.onkeyup = function(e){
            if(e.key ==='Enter' || e.key ===' '){
                confirmElement.querySelector('button.layer-checked').click();
            }else if(e.key === 'Escape'){
                confirmElement.querySelector('button.layer-cancel').click();
            }
        }

        document.body.appendChild(confirmElement);

        function _checked(resolve){
            /*uiJSLayer.close('layer-confirm');*/
            document.body.removeChild(confirmElement);
            if(checkedCallback){
                checkedCallback(true)
            }
            resolve(true);
        }


        function _canceled(resolve){
            /*uiJSLayer.close('layer-confirm');*/
            document.body.removeChild(confirmElement);
            if(canceledCallback){
                canceledCallback(false);
            }
            resolve(false);
        }


        return new Promise(function (resolve,reject){

            // uiJSLayer.open('layer-confirm');

            confirmElement.querySelector('button.layer-cancel').onclick = function(){
                _canceled(resolve);
            };

            confirmElement.querySelector('button.layer-checked').onclick = function(){
                _checked(resolve);
            };

            /*$('[data-layer=layer-confirm]').on('layerAfterClosed',function(){
                document.body.removeChild(confirmElement);
            });*/

            $('.close-area').on('click',function(){
                _canceled(resolve);
            })

        });


    }
}

 

감사합니다.

728x90
반응형