본문 바로가기
공부의/vuejs

[vuejs] json 객체로 테이블 동적 생성하기(체크박스 모두 선택 제어)

by 포로리씨 2023. 3. 21.
728x90
반응형

 

체크박스 테이블 동적 생성하기 

 

- JSON 객체 형태로 data 셋팅하기

export default{
    data() {
        return {
           
            allChecked: false,
            categories: [
                {
                    label: "depth1",
                    key: "depth1",
                    depth: 1,
                    checked: false,
                    menus: [
                    { label: "A1", key: "A1", checked: false, depth: 2, disabled: true },
                    { label: "A2", key: "A2", checked: false, depth: 2, disabled: false },
                    { label: "A3", key: "A3", checked: false, depth: 2, disabled: false },
                    { label: "A4", key: "A4", checked: false, depth: 2, disabled: false  }
                    ]
                },
                {
                    label: "depth2",
                    key: "depth2",
                    depth: 1,
                    checked: false,
                    menus: [
                    { label: "B1", key: "B1", checked: false, depth: 2, disabled: false },
                    { label: "B2", key: "B2", checked: false, depth: 2, disabled: false },
                    { label: "B3", key: "B3", checked: false, depth: 2, disabled: false },
                    { label: "B4", key: "B4", checked: false, depth: 2, disabled: false }
                    ]                },
                {
                    label: "depth3",
                    key: "depth3",
                    depth: 1,
                    checked: false,
                    menus: [
                    { label: "C1", key: "C1", checked: false, depth: 2, disabled: false },
                    { label: "C2", key: "C2", checked: false, depth: 2, disabled: false },
                    { label: "C3", key: "C3", checked: false, depth: 2, disabled: false }
                    ]
                },
                {
                    label: "depth4",
                    key: "depth4",
                    depth: 1,
                    menus: [
                        { label: "D1", key: "D1", checked: false, depth: 2, disabled: true },
                        { label: "D2", key: "D2", checked: false, depth: 2, disabled: true },
                        { label: "D3", key: "D3", checked: false, depth: 2, disabled: true },
                    ]
                },
                {
                    label: "depth5",
                    key: "depth5",
                    depth: 1,
                    menus: [
                        {
                            label: "AA",
                            key: "AA",
                            checked: false,
                            depth: 2,
                            detailMenus: [
                                { label: "AAA1", key: "AAA1", checked: false, disabled: false },
                                { label: "AAA2", key: "AAA2", checked: false, disabled: false },
                                { label: "AAA1", key: "AAA1", checked: false, disabled: false },
                            ]
                        },
                        {
                            label: "BB",
                            key: "BB",
                            checked: false,
                            depth: 2,
                            detailMenus: [
                                { label: "BBB1", key: "BBB1", checked: false, disabled: false  },
                                { label: "BBB2", key: "BBB2", checked: false, disabled: false  },
                                { label: "BBB3", key: "BBB3", checked: false, disabled: false  },
                            ]
                        },
                        {
                            label: "CC",
                            key: "CC",
                            checked: false,
                            depth: 2,
                            detailMenus: [
                                { label: "DDD1", key: "DDD1", checked: false, disabled: false  },
                                { label: "DDD2", key: "DDD2", checked: false, disabled: false  },
                                { label: "DDD3", key: "DDD3", checked: false, disabled: false  },
                            ]
                        }
                    ]
                },
                {
                    label: "depth6",
                    key: "depth6",
                    depth: 1,
                    menus: [
                        { label: "E1", key: "E1", checked: false, depth: 2, disabled: true },
                    ]
                },
            ]
        }
    },

 

- table 동적 생성

<div>
    <div>
        <div>
            <h3><i></i> 체크박스 동적 테이블 생성</h3
            <h4>메뉴권한</h4>>
        </div>
        <div>
            <input v-model="allChecked" @click="toggleAllChecked" type="checkbox"><label for="edit-allchk"> 모두 선택하기</label>
        </div>
    </div>
    <div>
        <table>
            <thead>
                <tr>
                    <th><input type="checkbox"v-model="allChecked" @click="toggleAllChecked"></th>
                    <th>카테고리</th>
                    <th colspan="2">메뉴</th>
                    <th>체크1</th>
                    <th>체크2</th>
                    <th>체크3</th>
                </tr>
            </thead>
            <tbody>
                <template v-for="(category, index) in categories" :key="index">
                    <tr v-for="(menu, menuIndex) in category.menus" :key="menuIndex">
                        <td v-if="menuIndex === 0" :rowspan="category.menus.length">
                            <input type="checkbox":checked="category.checked" @change="toggleAll(1, category)">
                        </td>
                        <td v-if="menuIndex === 0" :rowspan="category.menus.length" >
                            <label for="edit-category01">{{ category.label }}</label>
                        </td>
                        <td>
                            <input type="checkbox":checked="menu.checked" @change="toggleAll(2, menu)" :disabled="menu.disabled">
                        </td>
                        <td>{{ menu.label }}</td>
                        <template v-for="(detail, ckIndex) in menu.detailMenus" :key="ckIndex">
                            <td >
                                <input type="checkbox":checked="detail.checked" @change="toggleAll(3, detail)" :disabled="menu.disabled">
                            </td>
                        </template>
                        <template v-for="i in (3 - (menu.detailMenus ? menu.detailMenus.length : 0))" :key="(menu.detailMenus ? menu.detailMenus.length : 0) + i">
                            <td></td>
                        </template>
                    </tr>
                </template>
            </tbody>
        </table>                                    
    </div>
</div>

 

- method 

  toggleAllChecked() {
    this.allChecked = !this.allChecked;
    this.categories.forEach(category => {
        category.checked = this.allChecked;
        category.menus.forEach(menu => {
            if (!(menu.taxAgentDisabled && this.usrInfo.usrGrpTy === 'G')) {
                menu.checked = this.allChecked;
                if (menu.detailMenus) {
                    menu.detailMenus.forEach(ck => {
                        ck.checked = this.allChecked;
                    })
                }
            }
        });
    });
},
 toggleAll(depth, item) {
    const toggle = (category, menu, detail) => {
        if (detail) {
            detail.checked = !detail.checked;
            menu.checked = menu.detailMenus.every(d => d.checked);
        } else if (menu) {
            menu.checked = !menu.checked;
            if (menu.detailMenus) {
                menu.detailMenus.forEach(d => { d.checked = menu.checked; });
            }
            if (!menu.checked) {
                category.checked = menu.checked;
            }
        } else {
            category.checked = !category.checked;
            if (category.menus) {
                category.menus.forEach(m => {
                if (!(m.disabled)) {
                    m.checked = category.checked;
                    if (m.detailMenus) {
                        m.detailMenus.forEach(d => { d.checked = category.checked; });
                    }
                }
                });
            }
        }
        category.checked = category.menus.every(m => m.checked);
    };

    this.categories.forEach(category => {
        if (depth === 1 && category.key === item.key) {
            toggle(category);
        } else if (depth === 2 && category.menus) {
            category.menus.forEach(menu => {
                if (menu.key === item.key) {
                    toggle(category, menu);
                }
            });
        } else if (depth === 3 && category.menus) {
            category.menus.forEach(menu => {
                if (menu.detailMenus) {
                    const detailMenu = menu.detailMenus.find(detail => detail.key === item.key);
                if (detailMenu) {
                    toggle(category, menu, detailMenu);
                }
                }
            });
        }
    });
},

 

- 체크박스 해제시 모두 체크 해제

watch: {
    'categories': {
        deep: true,
        handler: function() {
            this.updateAllChecked();
        }
    }
},

 

 

 

728x90
반응형