ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [개발일지#001] 나만의 그리드 일명 '뚜루리그리드' 만들기 Ver1
    💻 뚝딱뚝딱/뚜루리그리드 2024. 3. 31. 21:29
    728x90
    320x100
    나는 회사에서 리얼그리드를 쓴다. 그러다 문득 과장님이 제안하신다. 바닐라JS와 Html만을 이용하여 리얼그리드 같은걸 만들어보는 건 어떻겠냐고. 너무....재밌겠다 싶어 바로 만들기 시작했다. 

    근데 바로 뚝딱 만들 자신은 없어서 일단 버전을 나눠서 업그레이드를 해보기로 했다.
    의 그 첫번째!

     


     

    [개발 목표]

    이번 개발일지에서는  자바스크립트의 function 기능을 이용해서

    정말 기본적으로 행추가, 행삭제, 체크박스 선택기능까지 만들어 보기로 한다.


     

    html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="">
    
        <title>SB Admin 2 - Tables</title>
    
        <!-- Custom fonts for this template -->
        <link href="../vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
        <link
            href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
            rel="stylesheet">
    
        <!-- Custom styles for this template -->
        <link href="../css/sb-admin-2.min.css" rel="stylesheet">
    
        <!-- Custom styles for this page -->
        <link href="../vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
    
    </head>
    
    <body id="page-top">
     ///생략///
                        <!-- DataTales Example -->
                        <div class="card shadow mb-4" style="margin-top: 20px;">
                            <div class="card-header py-3">
                                <div style="float: left;">
                                    <h6 class="m-0 font-weight-bold text-primary">Total : <span id="totalCount">0</span></h6>
                                </div>
                                <div class="btnArea" style="text-align: right; float: right;">
                                    <button type="button" class="btn btn-primary" id="addBtn">추가</button>
                                    <button type="button" class="btn btn-danger" id="delBtn">삭제</button>
                                </div>
    
                            </div>
                            <div class="card-body">
                                <div class="table-responsive">
                                    <div style="height: 400px;">
                                        <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
                                            <thead>
                                                <tr>
                                                    <th><input type="checkbox" id="allCheckBox"/></th>
                                                    <th>No</th>
                                                    <th>Name</th>
                                                    <th>Position</th>
                                                    <th>Office</th>
                                                    <th>Age</th>
                                                    <th>Start date</th>
                                                    <th>Salary (만원)</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <tr>
                                                    <td><input type="checkbox" id="checkbox_1"/></td>
                                                    <td style="text-align: center;"><span id="gridNo_1">1</span></td>
                                                    <td><input class="form-control" type="text" id="name_1" class="name" placeholder="이름"></td>
                                                    <td><input class="form-control" type="text" id="position_1" class="position" placeholder="직급"></td>
                                                    <td><input class="form-control" type="text" id="office_1" class="office" placeholder="부서"></td>
                                                    <td><input class="form-control" type="text" id="age_1" class="age" placeholder="나이"></td>
                                                    <td><input class="form-control" type="text" id="startDate_1" class="startDate" placeholder="입사일"></td>
                                                    <td><input class="form-control" type="text" id="salary_1" class="salary" placeholder="연봉"></td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </div>
                            </div>
                        </div>
    
    		///생략///
    
        <script src="../js/grid_ver1.js"></script>
    
    </body>
    
    </html>
    • 생각보다 복잡해보이지만 나름 깔끔하게 한다고 부트스트랩 적용했더니 좀 복잡해보이는 것임. 
    • 테이블, tr, td 태그로 이루어진 아주 단순한 Html임.

     

    js - gridAddrow()

    
    function gridAddRow(){
        let newRow = document.createElement('tr');
        let rowCount = document.getElementById('dataTable')
            .getElementsByTagName('tbody')[0].getElementsByTagName('tr').length + 1;
        newRow.innerHTML =
              '<td><input type="checkbox" id="checkbox_' + rowCount + '"></td>'
            + '<td style="text-align: center;"><span id="gridNo_' + rowCount + '">' + rowCount + '</span></td>'
            + '<td><input class="form-control" type="text" id="name_' + rowCount + '" placeholder="이름"></td>'
            + '<td><input class="form-control" type="text" id="position_' + rowCount + '" placeholder="직급"></td>'
            + '<td><input class="form-control" type="text" id="office_' + rowCount + '" placeholder="부서"></td>'
            + '<td><input class="form-control" type="text" id="age_' + rowCount + '" placeholder="나이"></td>'
            + '<td><input class="form-control" type="text" id="startDate_' + rowCount + '" placeholder="입사일"></td>'
            + '<td><input class="form-control" type="text" id="salary_' + rowCount + '" placeholder="연봉"></td>';
    
        document.getElementById('dataTable').getElementsByTagName('tbody')[0].appendChild(newRow);
        gridTotalCount();
    }
    • [추가] 버튼을 클릭하면, 행이 추가되는 함수.
    • 별다른 건 없지만 나중에 작업에 필요하도록 각 행의 input마다 id를 name_1, name_2 요런식으로 주기로 함.
    • 그리고 함수의 마지막에는 행추가를 하게 되면 추가된 행 카운트를 반영함. 이 함수는 좀 더 뒤에 작성해서 넣을 예정. 

     

     

    js - delRow()

    function gridDelRow(){
        let checkedCount = document.querySelectorAll('[id*="checkbox_"]:checked').length;
        let rowCount = document.getElementById('dataTable')
            .getElementsByTagName('tbody')[0].getElementsByTagName('tr').length;
    
        if(rowCount === 0){
            alert("삭제할 행이 없습니다.");
        }
    
        if (checkedCount === 0){
            alert("삭제할 행을 체크해주세요.");
        } else {
            let checkedCheckboxes = document.querySelectorAll('[id^="checkbox_"]:checked');
    
            if (checkedCheckboxes.length > 0) {
                checkedCheckboxes.forEach(function(checkbox) {
                    let row = checkbox.closest('tr');
                    row.parentNode.removeChild(row);
                });
    
                let gridNoSpans = document.querySelectorAll('[id^="gridNo_"]');
                gridNoSpans.forEach(function(span, index) {
                    span.textContent = index + 1;
                });
            } else {
                alert("선택된 행이 없습니다.");
            }
        }
    
        gridTotalCount();
    }
    • 삭제는 체크박스가 체크된 행만 삭제하도록 하고 그럼 다중 삭제도 가능하게끔 해야 함. 그래서 함수의 앞부분에서 행 자체가 아예 없거나 체크박스를 체크한 행이 아예 없는 경우를 체크하고 통과하면 삭제 하도록 했다.
    • 그리고 삭제하면 no부분의 넘버링을 처음부터 다시 하는 부분이 포인트. 나머지 id에 붙은 _1 _2 은 그대로 두는 게 좋을 것 같아서 둠.
    • 그리고 삭제함수의 마지막에도 행 카운트를 다시 한번 해줌.

     

     

    js - gridTotalCount()

    function gridTotalCount(){
        let rowCount = document.getElementById('dataTable')
            .getElementsByTagName('tbody')[0].getElementsByTagName('tr').length;
        document.getElementById("totalCount").textContent = rowCount;
    }
    • 행카운트를 해서 상단에 토탈 카운트를 보여주는 부분.
    • 행추가, 행삭제 그리고 화면 로드 시에 작동되도록 함. 

     

     

    js - checkAllcehckboxes(), attachCheckboxEvents()

    function checkAllCheckboxes(){
        let isChecked = this.checked;
        let checkboxes = document.querySelectorAll('[id^="checkbox_"]');
        checkboxes.forEach(function(checkbox) {
            checkbox.checked = isChecked;
        });
    }
    function attachCheckboxEvents() {
        document.querySelectorAll('[id^="checkbox_"]').forEach(function(checkbox) {
            checkbox.addEventListener('click', function() {
                let allCheckBox = document.getElementById('allCheckBox');
                allCheckBox.checked = [...document.querySelectorAll('[id^="checkbox_"]')].every(checkbox => checkbox.checked);
            });
        });
    }

     

    • 전체 상단에 체크박스를 체크하면 나머지 행의 체크박스가 체크되고 전체체크박스를 해제하면 나머지 행의 체크박스도 해제되게끔 만들었다.
    • attachCehckboxEvents() 함수는 전체체크박스와 나머지 행 체크박스를 동일하게 만들어주는 함수이고, checkAllcehckboxes()함수는 행 체크박스가 모두 체크되었을 때 전체체크박스가 체크되도록 하는 함수로 만들었다. 

     

     

    document.addEventListener('DOMContentLoaded', function() {
        gridTotalCount();
        document.getElementById('addBtn').addEventListener('click', function (){
            gridAddRow();
            attachCheckboxEvents();
        });
        document.getElementById('delBtn').addEventListener('click', gridDelRow );
        document.getElementById('allCheckBox').addEventListener('click', checkAllCheckboxes);
        attachCheckboxEvents();
        
    });
    • 구현되는 순서는 요러케 했다. 

     

     

    [구현된 화면은 요렇게~!]

    728x90
    320x100
Designed by Tistory.