방명록
- [개발자의품격][부트캠프][1기][16차시] 부트스트랩 #4 | 모달2022년 03월 02일 17시 30분 28초에 업로드 된 글입니다.작성자: DandyNow728x90반응형
부트스트랩 #4
1. Static backdrop 모달 가져오기
1.1 Static backdrop 적용
https://getbootstrap.com/docs/5.1/components/modal/#static-backdrop
<!-- Modal --> <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="staticBackdropLabel">Modal title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> ... </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Understood</button> </div> </div> </div> </div>
1.2 Modal - Passing options
https://getbootstrap.com/docs/5.1/components/modal/#passing-options
모달을 띄우거나 숨긴다.
var myModal = new bootstrap.Modal(document.getElementById('myModal'), { keyboard: false })
1.3 id="customerModal" 설정
2. 최종 코드
<!DOCTYPE html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <!-- Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" /> <title>Hello, world!</title> <style> main { margin-top: 70px; } </style> </head> <body> <header> <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href="#">부트스트랩 실습</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" > <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="navbar-nav me-auto mb-2 mb-md-0"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="#">Home</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link disabled">Disabled</a> </li> </ul> <form class="d-flex"> <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" /> <button class="btn btn-outline-success" type="submit"> Search </button> </form> </div> </div> </nav> </header> <main> <div class="container"> <div class="row row-cols-lg-auto g-2 align-items-center"> <div class="col-12"> <label class="visually-hidden" for="gender">성별선택</label> <select class="form-select" id="gender"> <option value="" selected>전체</option> <option value="male">남자</option> <option value="female">여자</option> </select> </div> <div class="col-12"> <label class="visually-hidden" for="searchName">Username</label> <input type="search" class="form-control" id="searchName" placeholder="Name" /> </div> <div class="col-12"> <button class="btn btn-primary" onclick="doSearch();">조회</button> <button class="btn btn-success">생성</button> <button class="btn btn-danger" id="btnDelete" onclick="doDelete();" disabled > 삭제 </button> </div> </div> <table class="table table-bordered table-striped mt-2"> <thead> <tr> <th> <input type="checkbox" id="chks" class="form-check-input" onchange="checkAll()" /> </th> <th>Name</th> <th>Company</th> <th>Gender</th> <th>Email</th> <th>Phone</th> <th>Addres</th> </tr> </thead> <tbody id="tbBody"></tbody> </table> </div> </main> <!-- 1.1 Static backdrop 적용(https://getbootstrap.com/docs/5.1/components/modal/#static-backdrop) --> <!-- 1.3 id="customerModal" 설정 --> <div class="modal fade" id="customerModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true" > <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="staticBackdropLabel">Modal title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" ></button> </div> <form onsubmit="doSave();"> <div class="modal-body"> <div class="row mb-3"> <label for="name" class="col-sm-2 col-form-label">Name</label> <div class="col-sm-10"> <input type="text" class="form-control" id="name" required /> <input type="hidden" id="selectedId" value="" /> </div> </div> <div class="row mb-3"> <label for="name" class="col-sm-2 col-form-label">Gender</label> <div class="col-sm-10"> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" id="male" value="male" checked /> <label class="form-check-label" for="male">남자</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" id="female" value="female" /> <label class="form-check-label" for="female">여자</label> </div> </div> </div> <div class="row mb-3"> <label for="company" class="col-sm-2 col-form-label" >Company</label > <div class="col-sm-10"> <input type="text" class="form-control" id="company" required /> </div> </div> <div class="row mb-3"> <label for="email" class="col-sm-2 col-form-label">Email</label> <div class="col-sm-10"> <input type="email" class="form-control" id="email" required /> </div> </div> <div class="row mb-3"> <label for="phone" class="col-sm-2 col-form-label">Phone</label> <div class="col-sm-10"> <input type="tel" class="form-control" id="phone" pattern="^010-\d{3,4}-\d{4}$" required /> </div> </div> <div class="row mb-3"> <label for="phone" class="col-sm-2 col-form-label" >Address</label > <div class="col-sm-10"> <div class="input-group mb-3"> <input type="text" class="form-control" placeholder="주소" id="address" aria-label="주소" aria-describedby="button-address" requried /> <button class="btn btn-outline-secondary" type="button" id="button-address" onclick="openDaumAPI();" > 주소찾기 </button> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" > 닫기 </button> <!-- submit은 <form> 태그 안에 있어야 한다. --> <button type="submit" class="btn btn-primary">저장</button> </div> </form> </div> </div> </div> <!-- Optional JavaScript; choose one of the two! --> <!-- Option 1: Bootstrap Bundle with Popper --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous" ></script> <script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> async function doSearch() { const gender = document.querySelector("#gender").value; const name = document.querySelector("#searchName").value; let resource = "http://localhost:3000/customers"; if (gender === "") { if (name !== "") { resource = `http://localhost:3000/customers?name_like=${name}`; } } else { if (name === "") { resource = `http://localhost:3000/customers?gender=${gender}`; } else { resource = `http://localhost:3000/customers?gender=${gender}&name_like=${name}`; } } const res = await fetch(resource); const resJson = await res.json(); console.log(resJson); renderTable(resJson); } let customerData = []; function renderTable(data) { customerData = data; const h = []; for (const item of data) { h.push("<tr>"); h.push( `<td><input type="checkbox" class="form-check-input" value="${item.id}" name="chk" onchange="isChecked();" /></td>` ); h.push( `<td><a href="javascript:openModal('${item.id}');">${item.name}</a></td>` ); h.push(`<td>${item.company}</td>`); h.push(`<td>${item.gender}</td>`); h.push(`<td>${item.email}</td>`); h.push(`<td>${item.phone}</td>`); h.push(`<td>${item.address}</td>`); h.push("</tr>"); } document.querySelector("#tbBody").innerHTML = h.join(""); } function openModal(id) { console.log(id); selectedId = id; document.querySelector("#selectedId").value = id; let customer = customerData.filter((c) => c.id === id)[0]; document.querySelector("#name").value = customer.name; document.querySelector("#company").value = customer.company; document.querySelector("#" + customer.gender).checked = true; document.querySelector("#email").value = customer.email; document.querySelector("#phone").value = customer.phone; document.querySelector("#address").value = customer.address; // 1.2 Modal - Passing options : 모달 창을 보여준다. var myModal = new bootstrap.Modal( document.querySelector("#customerModal") ); myModal.show(); } // 1.2 Modal - Passing options : 모달 창을 숨긴다. function closeModal() { selectedId = ""; var myModal = new bootstrap.Modal( document.querySelector("#customerModal") ); myModal.hide(); } function formSubmit() { document.querySelector("#customerForm").submit(); return false; } async function doSave() { event.preventDefault(); const name = document.querySelector("#name").value.trim(); const gender = document.querySelector("[name=gender]:checked").value; const company = document.querySelector("#company").value.trim(); const email = document.querySelector("#email").value.trim(); const phone = document.querySelector("#phone").value.trim(); const address = document.querySelector("#address").value.trim(); const selectedId = document.querySelector("#selectedId").value; Swal.fire({ title: "정말 저장하시겠습니까?", // text: "삭제된 데이터는 복원되지 않습니다!", icon: "warning", showCancelButton: true, confirmButtonColor: "#3085d6", cancelButtonColor: "#d33", confirmButtonText: "저장", cancelButtonText: "취소", }).then(async (result) => { if (result.isConfirmed) { const res = await fetch( `http://localhost:3000/customers/${selectedId}`, { method: "PUT", body: JSON.stringify({ name, gender, company, email, phone, address, }), headers: { "content-type": "application/json;charset=UTF-8", }, } ); if (res.status === 200) { closeModal(); Swal.fire( "저장 성공!", "데이터가 정상적으로 저장 되었습니다.", "success" ); } else { Swal.fire("고객 정보를 저장하지 못했습니다. 다시 시도하세요."); } } }); } async function doDelete() { const chks = document.querySelectorAll("[name=chk]:checked"); if (chks.length > 0) { Swal.fire({ title: "정말 삭제하시겠습니까?", text: "삭제된 데이터는 복원되지 않습니다!", icon: "warning", showCancelButton: true, confirmButtonColor: "#3085d6", cancelButtonColor: "#d33", confirmButtonText: "삭제", cancelButtonText: "취소", }).then(async (result) => { if (result.isConfirmed) { for (const chk of chks) { await fetch( `http://localhost:3000/customers/${chks[0].value}`, { method: "DELETE", } ); } Swal.fire( "삭제 성공!", "데이터가 정상적으로 삭제 되었습니다.", "success" ); } }); } else { Swal.fire("삭제할 아이템을 선택하세요."); } } function checkAll() { const checkValue = document.querySelector("#chks").checked; const chks = document.querySelectorAll("[name=chk]"); for (const chk of chks) { chk.checked = checkValue; } isChecked(); } function isChecked() { const chks = document.querySelectorAll("[name=chk]:checked"); if (chks.length > 0) { document.querySelector("#btnDelete").disabled = false; } else { document.querySelector("#btnDelete").disabled = true; } } function goToCreate() { document.location.href = "dom_create.html"; } function checkEnter(e) { if (e.keyCode === 13) { doSearch(); } } </script> </body> </html>
728x90반응형'영광의 시대! > 2022 개발자의 품격 부트캠프 1기' 카테고리의 다른 글
[개발자의품격][부트캠프][1기][18차시] Vue.js #2 | 데이터바인딩 (0) 2022.03.05 [개발자의품격][부트캠프][1기][17차시] Vue.js #1 | 설치, 스니핏 설정, 프로젝트 생성, 구조, 라우터 (0) 2022.03.05 [개발자의품격][부트캠프][1기][16차시] 부트스트랩 #3 | 생성 (0) 2022.03.02 [개발자의품격][부트캠프][1기][16차시] 부트스트랩 #2 | 조회, 삭제 (0) 2022.03.02 [개발자의품격][부트캠프][1기][15차시] 부트스트랩 #1 (0) 2022.03.01 다음글이 없습니다.이전글이 없습니다.댓글