Sencha TreeGrid 샘플

2024. 12. 1. 15:41Javascript/Sencha

const store = Ext.create('Ext.data.TreeStore', {
    fields: ['id', 'name', 'location'],
    root: {
        expanded: true,
        children: [
            {
                id: 1,
                name: '거실',
                location: '',
                expanded: true,
                children: [
                    {
                        id: 11,
                        name: 'Jane Doe',
                        location: 'jane.doe@example.com',
                        leaf: true
                    },
                    {
                        id: 12,
                        name: 'Mark Doe',
                        location: 'mark.doe@example.com',
                        leaf: true
                    }
                ]
            },
            { id: 2, name: '안방', location: '', leaf: true },
            { id: 3, name: '작은방1', location: '', leaf: true },
            { id: 4, name: '작은방2', location: '', leaf: true }
        ]
    }
});

Ext.define('Home.view.data.Location', {
    extend: 'Ext.form.Panel',
    xtype: 'Data',
    closable: true,
    layout: 'fit',
    items: [
        {
            xtype: 'treepanel',
            title: '위치',
            store: store,
            rootVisible: false,
            plugins: {
                ptype: 'cellediting',
                clicksToEdit: 1
            },
            columns: [
                {
                    xtype: 'treecolumn',
                    text: 'ID',
                    dataIndex: 'id',
                    width: 50
                },
                {
                    text: '이름',
                    dataIndex: 'name',
                    flex: 1,
                    editor: {
                        xtype: 'textfield',
                        allowBlank: false
                    }
                },
                {
                    text: '위치',
                    dataIndex: 'location',
                    flex: 1,
                    editor: {
                        xtype: 'textfield',
                        allowBlank: false
                    }
                }
            ],
            tbar: {
                xtype: 'toolbar',
                layout: { type: 'hbox', pack: 'end' },
                items: [
                    {
                        text: '추가 (자식)',
                        handler: function () {
                            const treePanel = this.up('treepanel');
                            const selection = treePanel.getSelectionModel().getSelection();

                            if (selection.length > 0) {
                                const parentNode = selection[0];
                                if (parentNode.isLeaf()) {
                                    parentNode.set('leaf', false); // Convert leaf to parent
                                    parentNode.set('expanded', true); // Expand the node
                                }
                                parentNode.appendChild({
                                    id: Math.random(), // Generate a unique ID
                                    name: 'New Child Node',
                                    location: '',
                                    leaf: true // Add as a leaf node
                                });
                                parentNode.expand();
                            } else {
                                Ext.Msg.alert('Error', 'Please select a row to add a child.');
                            }
                        }
                    },
                    {
                        text: '삭제',
                        handler: function () {
                            const treePanel = this.up('treepanel');
                            const selection = treePanel.getSelectionModel().getSelection();

                            if (selection.length > 0) {
                                const selectedNode = selection[0];

                                // Check if the node has children
                                if (selectedNode.hasChildNodes()) {
                                    Ext.Msg.alert('Error', 'Cannot delete a node that has children.');
                                } else {
                                    selectedNode.remove();
                                }
                            } else {
                                Ext.Msg.alert('Error', 'No node selected for removal.');
                            }
                        }
                    },
                    {
                        text: 'Save Changes',
                        handler: function () {
                            const treeData = [];
                            const collectData = function (node) {
                                const data = node.getData();
                                if (node.hasChildNodes()) {
                                    data.children = [];
                                    node.eachChild(child => data.children.push(collectData(child)));
                                }
                                return data;
                            };
                            store.getRoot().eachChild(node => treeData.push(collectData(node)));
                            console.log('Tree Data:', treeData);
                            Ext.Msg.alert('Save', `Saved Tree Data:\n${JSON.stringify(treeData, null, 4)}`);
                        }
                    }
                ]
            },
            selModel: {
                type: 'cellmodel'
            }
        }
    ]
});