[AXBoot/Front-end] 샘플 그리드 만들기

yesjm·2021년 4월 25일
0
post-thumbnail

주말동안 알바도 하고 강사님이 내주신 숙제도 했다. 필수는 아니었지만 이런거 받으면 또 해결하고 싶은 마음이 간절해지는 나,,,
1번은 성공을 못했다ㅠ key, value로 검색하는건 기존 컨트롤러 수정만 하면 된다고 하셨는데 아직 잘 모르겠다.

  1. 검색영역에 개선(x)
  • 사용유무 select
  • key, value로 검색
  1. 왼쪽 그리드, 오른 트리(o)

2번은 성공했다(90%?) ㅎㅎ,, 문제는 왼쪽에 빈 데이터(2번째 줄)가 한번 생성되더니 삭제되지 않는다는거? 차차 해결하자

오른쪽 트리는 분명히 되야하는데 안되길래 여기저기 다 찾아봤는데 body: { tree: {}} 구조로 코드 작성해놓고 한참 헤매다가 발견했다. 수정하자마자 성공해서 감격

자바스크립트에 하루빨리 익숙해져야할텐데 쉽지 않다. 생활코딩 감사합니다.


grid-sample.js

var fnObj = {};
var sampleData = [
    { key: 11, value: 'value11', etc1: 1000, etc2: 11 },
    { pid: '11', key: '12', value: 'value12', etc1: 2000, etc2: 12 },
    { pid: '11', key: '13', value: 'value13', etc1: 3000, etc2: 13 },
    { pid: '11', key: '14', value: 'value14', etc1: 4000, etc2: 14 },
    { pid: '14', key: '15', value: 'value15', etc1: 5000, etc2: 15 },
    { pid: '14', key: '16', value: 'value16', etc1: 6000, etc2: 16 },
    { pid: '11', key: '17', value: 'value17', etc1: 7000, etc2: 17 },
];
var ACTIONS = axboot.actionExtend(fnObj, {
    PAGE_SEARCH: function (caller, act, data) {
        axboot.ajax({
            type: 'GET',
            url: ['samples', 'parent'],
            data: $.extend({}, caller.searchView.getData(), caller.gridView01.getPageData(), caller.gridView02.getPageData()),
            callback: function (res) {
                caller.gridView01.setData(res);
                caller.gridView02.setData(sampleData);
            },
        });

        return false;
    },
    PAGE_SAVE: function (caller, act, data) {
        var saveList = [].concat(caller.gridView01.getData('modified'));
        saveList = saveList.concat(caller.gridView01.getData('deleted'));
        saveList = saveList.concat(caller.gridView02.getData('modified'));
        saveList = saveList.concat(caller.gridView02.getData('deleted'));
        axboot.ajax({
            type: 'PUT',
            url: ['samples', 'parent'],
            data: JSON.stringify(saveList),
            callback: function (res) {
                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
                // axToast.push(LANG('ax.script.save'));
            },
        });
    },
    ITEM_CLICK: function (caller, act, data) {},
    ITEM_ADD: function (caller, act, data) {
        caller.gridView01.addRow();
        caller.gridView02.addRow();
    },
    ITEM_DEL: function (caller, act, data) {
        caller.gridView01.delRow('selected');
        caller.gridView02.delRow('selected');
    },
});

// fnObj 기본 함수 스타트와 리사이즈
fnObj.pageStart = function () {
    this.pageButtonView.initView();
    this.searchView.initView();
    this.gridView01.initView();
    this.gridView02.initView();

    ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
};

fnObj.pageResize = function () {};

fnObj.pageButtonView = axboot.viewExtend({
    initView: function () {
        axboot.buttonClick(this, 'data-page-btn', {
            search: function () {
                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
            },
            save: function () {
                ACTIONS.dispatch(ACTIONS.PAGE_SAVE);
            },
            excel: function () {},
        });
    },
});

//== view 시작
/**
 * searchView
 */
fnObj.searchView = axboot.viewExtend(axboot.searchView, {
    initView: function () {
        this.target = $(document['searchView0']);
        this.target.attr('onsubmit', 'return ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);');
        this.filter = $('#filter');
    },
    getData: function () {
        return {
            pageNumber: this.pageNumber,
            pageSize: this.pageSize,
            filter: this.filter.val(),
        };
    },
});

fnObj.selectItems = [
    { value: 'Y', text: '사용' },
    { value: 'N', text: '미사용' },
];

/**
 * gridView
 */
fnObj.gridView01 = axboot.viewExtend(axboot.gridView, {
    initView: function () {
        var _this = this;

        this.target = axboot.gridBuilder({
            showRowSelector: true,
            frozenColumnIndex: 0,
            multipleSelect: true,
            target: $('[data-ax5grid="grid-view-01"]'),
            columns: [
                { key: 'key', label: 'KEY', width: 160, align: 'left', editor: 'text' },
                {
                    key: undefined,
                    label: 'VALUE',
                    align: 'center',
                    columns: [
                        { key: 'value', label: 'display', align: 'left' },
                        { key: 'value', label: 'textarea', align: 'left', editor: { type: 'textarea' } },
                    ],
                },
                {
                    key: undefined,
                    label: 'etc',
                    align: 'center',
                    columns: [
                        { key: 'etc1', label: 'money', width: 100, align: 'center', editor: { type: 'money' } },
                        { key: 'etc2', label: 'number', width: 100, align: 'center', editor: { type: 'number' } },
                        {
                            key: 'cost',
                            label: 'cost',
                            width: 100,
                            align: 'center',
                            formatter: function () {
                                var etc1 = this.item.etc1 || 0;
                                var etc2 = this.item.etc2 || 0;
                                return ax5.util.number(etc1 * etc2, { money: true });
                            },
                        },
                        { key: 'etc3', label: 'date', width: 100, align: 'center', editor: { type: 'date' } },
                    ],
                },
                {
                    key: 'etc4',
                    label: 'select',
                    width: 100,
                    align: 'center',
                    formatter: function () {
                        var i = 0,
                            len = fnObj.selectItems.length,
                            value;
                        for (; i < len; i++) {
                            if (this.item.etc4 === (value = fnObj.selectItems[i].value)) {
                                break;
                            }
                        }
                        return value === 'Y' ? '사용' : '미사용';
                    },

                    editor: { type: 'select', config: { columnsKeys: { optionValue: 'value', optionText: 'text' }, options: fnObj.selectItems } },
                },
                {
                    key: 'etc4',
                    label: 'checkbox',
                    width: 100,
                    align: 'center',
                    editor: { type: 'checkbox', config: { trueValue: 'Y', falseValue: 'N' } },
                },
            ],
            body: {
                mergeCells: ['value'],
                onClick: function () {
                    this.self.select(this.dindex, { selectedClear: true });
                },
                grouping: {
                    by: ['value'],
                    columns: [
                        {
                            label: function () {
                                return this.groupBy.labels.join(', ') + ' SUM';
                            },
                            colspan: 3,
                            align: 'center',
                        },
                        { key: 'etc1', collector: 'avg', formatter: 'money', align: 'right' },
                        { key: 'etc2', collector: 'sum', formatter: 'money', align: 'right' },
                        {
                            key: 'cost',
                            collector: function () {
                                var value = 0;
                                this.list.forEach(function (n) {
                                    if (!n.__isGrouping) value += (n.etc1 || 0) * (n.etc2 || 0);
                                });
                                return ax5.util.number(value, { money: 1 });
                            },
                            align: 'right',
                        },
                    ],
                },
            },
            footSum: [
                [
                    { label: 'SUMMARY', colspan: 3, align: 'center' },
                    { key: 'etc1', collector: 'avg', formatter: 'money', align: 'right' },
                    { key: 'etc2', collector: 'sum', formatter: 'money', align: 'right' },
                    {
                        key: 'cost',
                        collector: function () {
                            var value = 0;
                            this.list.forEach(function (n) {
                                if (!n.__isGrouping) value += (n.etc1 || 0) * (n.etc2 || 0);
                            });
                            return ax5.util.number(value, { money: 1 });
                        },
                        align: 'right',
                    },
                ],
            ],
        });

        axboot.buttonClick(this, 'data-grid-view-01-btn', {
            add: function () {
                ACTIONS.dispatch(ACTIONS.ITEM_ADD);
            },
            delete: function () {
                ACTIONS.dispatch(ACTIONS.ITEM_DEL);
            },
        });
    },
    getData: function (_type) {
        var list = [];
        var _list = this.target.getList(_type);

        if (_type == 'modified' || _type == 'deleted') {
            list = ax5.util.filter(_list, function () {
                delete this.deleted;
                return this.key;
            });
        } else {
            list = _list;
        }
        return list;
    },
    addRow: function () {
        this.target.addRow({ __created__: true }, 'last');
    },
});

/**
 * gridView02
 */
fnObj.gridView02 = axboot.viewExtend(axboot.gridView, {
    initView: function () {
        var _this = this;

        this.target = axboot.gridBuilder({
            showLineNumber: false,
            showRowSelector: true,
            multipleSelect: true,
            target: $('[data-ax5grid="grid-view-02"]'),
            columns: [
                { key: 'key', label: 'KEY', width: 160, align: 'left', editor: 'text' },
                { key: 'value', label: 'VALUE', align: 'left', treeControl: true },
                {
                    key: undefined,
                    label: 'etc',
                    align: 'center',
                    columns: [
                        { key: 'etc1', label: 'money', width: 100, align: 'center', editor: { type: 'money' } },
                        { key: 'etc2', label: 'number', width: 100, align: 'center', editor: { type: 'number' } },
                        {
                            key: 'cost',
                            label: 'cost',
                            width: 100,
                            align: 'center',
                            formatter: function () {
                                var etc1 = this.item.etc1 || 0;
                                var etc2 = this.item.etc2 || 0;
                                return ax5.util.number(etc1 * etc2, { money: true });
                            },
                        },
                        { key: 'etc3', label: 'date', width: 100, align: 'center', editor: { type: 'date' } },
                    ],
                },
                {
                    key: 'etc4',
                    label: 'select',
                    width: 100,
                    align: 'center',
                    formatter: function () {
                        var i = 0,
                            len = fnObj.selectItems.length,
                            value;
                        for (; i < len; i++) {
                            if (this.item.etc4 === (value = fnObj.selectItems[i].value)) {
                                break;
                            }
                        }
                        return value === 'Y' ? '사용' : '미사용';
                    },

                    editor: { type: 'select', config: { columnsKeys: { optionValue: 'value', optionText: 'text' }, options: fnObj.selectItems } },
                },
                {
                    key: 'etc4',
                    label: 'checkbox',
                    width: 100,
                    align: 'center',
                    editor: { type: 'checkbox', config: { trueValue: 'Y', falseValue: 'N' } },
                },
            ],
            body: {
                onClick: function () {
                    this.self.select(this.dindex);
                    ACTIONS.dispatch(ACTIONS.ITEM_CLICK, this.list[this.dindex]);
                },
            },

            tree: {
                use: true,
                indentWidth: 10,
                arrowWidth: 15,
                iconWidth: 18,
                icons: {
                    openedArrow: '<i class="cqc-uni3E" aria-hidden="true"></i>',
                    collapsedArrow: '<i class="cqc-uni76" aria-hidden="true"></i>',
                    groupIcon: '<i class="cqc-folder" aria-hidden="true"></i>',
                    collapsedGroupIcon: '<i class="cqc-folder" aria-hidden="true"></i>',
                    itemIcon: '<i class="cqc-uni4F" aria-hidden="true"></i>',
                },
                columnKeys: {
                    parentKey: 'pid',
                    selfKey: 'key',
                },
            },
        });

        axboot.buttonClick(this, 'data-grid-view-02-btn', {
            'item-add': function () {
                this.addRow();
            },
            'item-remove': function () {
                this.delRow();
            },
        });
    },
    setData: function (_data) {
        this.target.setData(_data);
    },
    getData: function (_type) {
        var list = [];
        var _list = this.target.getList(_type);

        if (_type == 'modified' || _type == 'deleted') {
            list = ax5.util.filter(_list, function () {
                return this.key;
            });
        } else {
            list = _list;
        }
        return list;
    },
    align: function () {
        this.target.align();
    },
});

grid-sample.jsp

<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="ax"
tagdir="/WEB-INF/tags" %>

<ax:set key="title" value="${pageName}" />
<ax:set key="page_desc" value="${PAGE_REMARK}" />
<ax:set key="page_auto_height" value="true" />

<ax:layout name="base">
    <jsp:attribute name="script">
        <script type="text/javascript" src="<c:url value='/assets/js/view/_education/grid-sample.js' />"></script>
    </jsp:attribute>
    <jsp:body>
        <ax:page-buttons></ax:page-buttons>

        <div role="page-header">
            <ax:form name="searchView0">
                <ax:tbl clazz="ax-search-tbl" minWidth="500px">
                    <ax:tr>
                        <ax:td label="key" width="300px">
                            <input type="text" class="form-control" />
                        </ax:td>
                        <ax:td label="value" width="300px">
                            <input type="text" class="form-control" />
                        </ax:td>
                        <ax:td label="search" width="300px">
                            <button type="button" class="btn btn-primary" data-searchview-btn="modal">
                                <i class="cqc-magnifier"></i>
                                검색
                            </button>
                        </ax:td>
                    </ax:tr>
                </ax:tbl>
            </ax:form>
            <div class="H10"></div>
        </div>

        <ax:split-layout name="ax1" orientation="vertical">
            <ax:split-panel width="*" style="">
                <!-- 목록 -->
                <div class="ax-button-group" data-fit-height-aside="grid-view-01">
                    <div class="left">
                        <h2><i class="cqc-list"></i> 프로그램 목록</h2>
                    </div>
                    <div class="right">
                        <button type="button" class="btn btn-default" data-grid-view-01-btn="add"><i class="cqc-circle-with-plus"></i> 추가</button>
                        <button type="button" class="btn btn-default" data-grid-view-01-btn="delete">
                            <i class="cqc-circle-with-plus"></i> 삭제
                        </button>
                    </div>
                </div>
                <div data-ax5grid="grid-view-01" data-fit-height-content="grid-view-01" style="height: 300px"></div>
            </ax:split-panel>
            <ax:splitter></ax:splitter>
            <ax:split-panel width="*" style="padding-left: 10px" scroll="scroll">
                <div class="ax-button-group" data-fit-height-aside="grid-view-02">
                    <div class="left">
                        <h2><i class="cqc-list"></i> 프로그램 목록</h2>
                    </div>
                    <div class="right">
                        <button type="button" class="btn btn-default" data-grid-view-02-btn="add"><i class="cqc-circle-with-plus"></i> 추가</button>
                        <button type="button" class="btn btn-default" data-grid-view-02-btn="delete">
                            <i class="cqc-circle-with-plus"></i> 삭제
                        </button>
                    </div>
                </div>
                <div data-ax5grid="grid-view-02" data-ax5grid-config="{}" data-fit-height-content="grid-view-02" style="height: 300px"></div>
            </ax:split-panel>
        </ax:split-layout>
    </jsp:body>
</ax:layout>
profile
yesjm's second brain

0개의 댓글