Axboot 신규화면 만들기 2 - 화면 소스 만들기

Axboot 신규화면 만들기 2 - 화면 소스 만들기

◆  화면소스 작성

   1. 기존에 만들어져있는 화면들을 보고 구성하고자 하는 형태를 미리 본다.

       - 왼쪽의 메뉴를 눌러 화면형태를 보니 공통코드관리화면이 제품코드관리하는데 적합한 화면일 것 같다.

    

   2. 기본적으로 axboot 화면의 jsp 위치는 webapp > jsp 하위에 있고, js 는 webapp > assets > js 하위에 있다.

       시스템공통관련 소스는 그 하위의 system이라는 폴더에 따로 모여있다.

   3. 일단 우리가 만드는 화면소스들은 한폴더에서 관리하기 위해 아래와 같이 shopnmg 라는 폴더를 생성한다. 

      (본인이 원하는 위치로 해도 됨)

       - js 용 폴더 생성 : webapp > assets > js > view > shopmng

 - jsp용 폴더 생성 : webapp > jsp > shopmng 

   4. 그런다음 공통코드관리의 화면소스를 복사하여 이름을 바꾸자.

   이름은 product.js, product.jsp 로 만들도록 하겠다.

     

   5. 소스수정

       1) webapp하위의 axboot.config.js 에 js의 호출할 약식이름과 full명의 mapping설정

    js에서 product로 호출하면 controller에 "/api/v1/product" 로 호출할 수 있도록 내용을 추가한다.

   6. product.js 파일 수정 : url 경로와 gridView를 제품테이블 기준으로 변경한다.

       : 화면속성은  https://localhost:8080/modelExtractor/db 로 접속시 나오는 필드명을 사용하면 된다.

var fnObj = {};

var ACTIONS = axboot.actionExtend(fnObj, {

    PAGE_SEARCH: function (caller, act, data) {

        axboot.ajax({

            type: "GET",

            url: ["product"], 

            data: caller.searchView.getData(),

            callback: function (res) {

                caller.gridView01.setData(res);

            }

        });

        return false;

    },

    PAGE_SAVE: function (caller, act, data) {

        var saveList = [].concat(caller.gridView01.getData("modified"));

        saveList = saveList.concat(caller.gridView01.getData("deleted"));


        axboot.ajax({

            type: "PUT",

            url: ["product"],

            data: JSON.stringify(saveList),

            callback: function (res) {

                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);

                axToast.push(LANG("onsave"));

            }

        });

    },

    ITEM_ADD: function (caller, act, data) {

        caller.gridView01.addRow();

    },

    ITEM_DEL: function (caller, act, data) {

        caller.gridView01.delRow("selected");

    }

});


// fnObj 기본 함수 스타트와 리사이즈

fnObj.pageStart = function () {

    this.pageButtonView.initView();

    this.searchView.initView();

    this.gridView01.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);

            }

        });

    }

});


//== 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()

        }

    }

});



/**

 * gridView

 */

fnObj.gridView01 = axboot.viewExtend(axboot.gridView, {

    initView: function () {

        var _this = this;

        this.target = axboot.gridBuilder({

            showRowSelector: true,

            frozenColumnIndex: 0,

            sortable: true,

            multipleSelect: true,

            target: $('[data-ax5grid="grid-view-01"]'),

            columns: [

                {key: "prdtCd", label: "제품코드", width: 100, align: "center", editor: "text"},

                {key: "prdtNm", label: "제품명", width: 200, align: "center", editor: "text"},

                {key: "origin", label: "원산지", width: 100, align: "center", editor: "text"},

                {key: "purchasePrice", label: "매입가격", width: 150, align: "right", editor: "number"},

                {key: "salesPrice", label: "판매가격", width: 150, align: "right", editor: "number"}                

            ],

            body: {

                onClick: function () {

                    this.self.select(this.dindex, {selectedClear: true});

                }

            }

        });


        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 () {

                return this.prdtCd;  //이부분을 키값으로 수정해줘야 변경된 값을 인식해서 서버로 날려줄 수 있다.

            });

        } else {

            list = _list;

        }

        return list;

    },

    addRow: function () {

        this.target.addRow({__created__: true, posUseYn: "N", useYn: "Y"}, "last");

    }

});

7. product.jsp 수정 : js 가 있는 위치를 변경해준다.

<%@ page contentType="text/html; charset=UTF-8" %>

<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="ax" tagdir="/WEB-INF/tags" %>


<ax:set key="system-common-code-version" value="1.0.0"/>

<ax:set key="title" value="${pageName}"/>

<ax:set key="page_desc" value="${pageRemark}"/>

<ax:set key="page_auto_height" value="true"/>


<ax:layout name="base">

    <jsp:attribute name="script">

        <ax:script-lang key="ax.script" var="LANG" />

        <ax:script-lang key="ax.admin" var="COL" />

        <script type="text/javascript" src="<c:url value='/assets/js/view/shopmng/product.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='ax.admin.search' width="300px">

                            <ax:input type="text" name="filter" id="filter" clazz="form-control" placeholder="ax.admin.input.search"/>

                        </ax:td>

                    </ax:tr>

                </ax:tbl>

            </ax:form>

            <div class="H10"></div>

        </div>


        <ax:split-layout name="ax1" orientation="horizontal">

            <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>

                            <!--<ax:lang id="ax.admin.commoncode.title"/>-->

                            제품코드 관리

                        </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> <ax:lang id="ax.admin.add"/></button>

                        <button type="button" class="btn btn-default" data-grid-view-01-btn="delete"><i class="cqc-circle-with-minus"></i> <ax:lang id="ax.admin.delete"/></button>

                    </div>

                </div>

                <div data-ax5grid="grid-view-01" data-fit-height-content="grid-view-01" style="height: 300px;"></div>


            </ax:split-panel>

        </ax:split-layout>



    </jsp:body>

</ax:layout> 

8. JAVA 소스 수정

 - com/dasdes/shopmng/contrillers/ProductController.java : 조회조건 받을수 있도록 수정 

 - com/dasdes/shopmng/domain/prdt/Product.java           : 필수값체크

 - com/dasdes/shopmng/domain/prdt/ProductService.java  : 조회조건 filter추가 및 list 리턴객체 교체

ProductController.java

package com.dasdes.shopmng.controllers;


import com.chequer.axboot.core.api.response.Responses;

import com.chequer.axboot.core.controllers.BaseController;

import com.chequer.axboot.core.parameter.RequestParams;

import org.springframework.stereotype.Controller;

import com.chequer.axboot.core.api.response.ApiResponse;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import com.dasdes.shopmng.domain.prdt.Product;

import com.dasdes.shopmng.domain.prdt.ProductService;


import javax.inject.Inject;

import java.util.List;


@Controller

@RequestMapping(value = "/api/v1/product")

public class ProductController extends BaseController {


    @Inject

    private ProductService productService;


    @RequestMapping(method = RequestMethod.GET, produces = APPLICATION_JSON)

    public Responses.ListResponse list(RequestParams<Product> requestParams) {

        List<Product> list = productService.gets(requestParams);

        return Responses.ListResponse.of(list);

    }


    @RequestMapping(method = {RequestMethod.PUT}, produces = APPLICATION_JSON)

    public ApiResponse save(@RequestBody List<Product> request) {

        productService.save(request);

        return ok();

    }

}

4. 화면소스 작성

   1) 기존에 만들어져있는 화면들을 보고 구성하고자 하는 형태를 미리 본다.

       - 왼쪽의 메뉴를 눌러 화면형태를 보니 공통코드관리화면이 제품코드관리하는데 적합한 화면일 것 같다.

    

   2) 기본적으로 axboot 화면의 jsp 위치는 webapp > jsp 하위에 있고, js 는 webapp > assets > js 하위에 있다.

       시스템공통관련 소스는 그 하위의 system이라는 폴더에 따로 모여있다.

   3) 일단 우리가 만드는 화면소스들은 한폴더에서 관리하기 위해 아래와 같이 shopnmg 라는 폴더를 생성한다. 

      (본인이 원하는 위치로 해도 됨)

       - js 용 폴더 생성 : webapp > assets > js > view > shopmng

 - jsp용 폴더 생성 : webapp > jsp > shopmng 

   4) 그런다음 공통코드관리의 화면소스를 복사하여 이름을 바꾸자.

   이름은 product.js, product.jsp 로 만들도록 하겠다.

     

   5) 소스수정

       a) axboot.config.js 에 js의 호출할 약식이름과 full명의 mapping설정

    js에서 product로 호출하면 controller에 "/api/v1/product" 로 호출할 수 있도록 내용을 추가한다.

     6) product.js 파일 수정 : url 경로와 gridView를 제품테이블 기준으로 변경한다.

       : 화면속성은  https://localhost:8080/modelExtractor/db 로 접속시 나오는 필드명을 사용하면 된다.

var fnObj = {};

var ACTIONS = axboot.actionExtend(fnObj, {

    PAGE_SEARCH: function (caller, act, data) {

        axboot.ajax({

            type: "GET",

            url: ["product"], 

            data: caller.searchView.getData(),

            callback: function (res) {

                caller.gridView01.setData(res);

            }

        });

        return false;

    },

    PAGE_SAVE: function (caller, act, data) {

        var saveList = [].concat(caller.gridView01.getData("modified"));

        saveList = saveList.concat(caller.gridView01.getData("deleted"));


        axboot.ajax({

            type: "PUT",

            url: ["product"],

            data: JSON.stringify(saveList),

            callback: function (res) {

                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);

                axToast.push(LANG("onsave"));

            }

        });

    },

    ITEM_ADD: function (caller, act, data) {

        caller.gridView01.addRow();

    },

    ITEM_DEL: function (caller, act, data) {

        caller.gridView01.delRow("selected");

    }

});


// fnObj 기본 함수 스타트와 리사이즈

fnObj.pageStart = function () {

    this.pageButtonView.initView();

    this.searchView.initView();

    this.gridView01.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);

            }

        });

    }

});


//== 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()

        }

    }

});



/**

 * gridView

 */

fnObj.gridView01 = axboot.viewExtend(axboot.gridView, {

    initView: function () {

        var _this = this;

        this.target = axboot.gridBuilder({

            showRowSelector: true,

            frozenColumnIndex: 0,

            sortable: true,

            multipleSelect: true,

            target: $('[data-ax5grid="grid-view-01"]'),

            columns: [

                {key: "prdtCd", label: "제품코드", width: 100, align: "center", editor: {type: "text", disabled: "notCreated"}},

                {key: "prdtNm", label: "제품명", width: 200, align: "center", editor: "text"},

                {key: "origin", label: "원산지", width: 100, align: "center", editor: "text"},

                {key: "purchasePrice", label: "매입가격", width: 150, align: "right", editor: "number"},

                {key: "salesPrice", label: "판매가격", width: 150, align: "right", editor: "number"}                

            ],

            body: {

                onClick: function () {

                    this.self.select(this.dindex, {selectedClear: true});

                }

            }

        });


        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 () {

                return this.groupCd && this.code;

            });

        } else {

            list = _list;

        }

        return list;

    },

    addRow: function () {

        this.target.addRow({__created__: true, posUseYn: "N", useYn: "Y"}, "last");

    }

});

7) product.jsp 수정 : js 가 있는 위치를 변경해준다.

<%@ page contentType="text/html; charset=UTF-8" %>

<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="ax" tagdir="/WEB-INF/tags" %>


<ax:set key="system-common-code-version" value="1.0.0"/>

<ax:set key="title" value="${pageName}"/>

<ax:set key="page_desc" value="${pageRemark}"/>

<ax:set key="page_auto_height" value="true"/>


<ax:layout name="base">

    <jsp:attribute name="script">

        <ax:script-lang key="ax.script" var="LANG" />

        <ax:script-lang key="ax.admin" var="COL" />

        <script type="text/javascript" src="<c:url value='/assets/js/view/shopmng/product.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='ax.admin.search' width="300px">

                            <ax:input type="text" name="filter" id="filter" clazz="form-control" placeholder="ax.admin.input.search"/>

                        </ax:td>

                    </ax:tr>

                </ax:tbl>

            </ax:form>

            <div class="H10"></div>

        </div>


        <ax:split-layout name="ax1" orientation="horizontal">

            <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>

                            <!--<ax:lang id="ax.admin.commoncode.title"/>-->

                            제품코드 관리

                        </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> <ax:lang id="ax.admin.add"/></button>

                        <button type="button" class="btn btn-default" data-grid-view-01-btn="delete"><i class="cqc-circle-with-minus"></i> <ax:lang id="ax.admin.delete"/></button>

                    </div>

                </div>

                <div data-ax5grid="grid-view-01" data-fit-height-content="grid-view-01" style="height: 300px;"></div>


            </ax:split-panel>

        </ax:split-layout>



    </jsp:body>

</ax:layout> 

8) 화면에서 확인하기( 프로그램 추가 및 메뉴생성 )

   a) 먼저 서버를 구동하여 초기 셋팅되어있는 system 계정으로 접속한다.

   

    b) 프로그램추가 : 시스템관리 > 프로그램 관리 메뉴로 들어가서 아래와 같이 프로그램을 추가한다. 

        - 경로는 앞부분에 만들었던 product.jsp의 경로를 입력해주면 되며, 권한체크/조회/저장을 체크해준다.

   c) 메뉴추가 : 시스템관리 > 메뉴관리 메뉴에서 아래와 같이 처리한다.

 

    d) 메뉴와 프로그램 연결 및 기타설정

       : 아래와 같이 생성된 "제품정보"를 클릭하여 프로그램 연결 수 다국어명칭 및 권한을 설정한다.

   

  e) 새로고침(F5)을 눌러 생성된 메뉴와 화면이 잘 연결된 것을 확인할 수 있다.

*"Axboot 신규화면 만들기 3 - 정상적인 CRUD를 위한 JAVA소스 수정" 에서 계속..............

  (JAVA소스에 약간의 양념을 넣어줘야 제대로 작동한다.)

만족하셨나요? ~~~~~~~

#axisj #full stack framework #Axboot #Axboot 화면만들기 #Axboot 사용법 #Axboot 프로그래밍 #Axboot매뉴얼 #axboot강좌

Read more

2025년  ERP/CRM/SCM 시스템 종류

2025년 ERP/CRM/SCM 시스템 종류

2025년 글로벌 ERP/CRM/SCM 시스템 순위: 회사, 커뮤니티, 기능 비교 분석 기업들은 효율적인 운영과 경쟁력 강화를 위해 ERP, CRM, SCM 시스템 도입을 적극 검토하고 있습니다. 본 글에서는 시장 점유율, 기능, 고객 만족도, 기술 발전을 고려하여 주요 시스템들의 순위와 특징을 정리했습니다. 아래 순위는 주관적 평가이며, 실제 도입 시 기업의 규모와

해외여행 준비 체크리스트

해외여행 준비 체크리스트

해외여행 준비 체크리스트: 완벽한 여행을 위한 필수 준비 가이드 꿈꿔왔던 해외여행, 설렘과 함께 걱정도 따라옵니다. 꼼꼼한 준비가 완벽한 여행의 시작입니다. 2025년 최신 정보를 바탕으로, 놓치기 쉬운 부분까지 포함한 상세 체크리스트와 함께 걱정 없이 여행을 즐겨보세요! 본 가이드는 항공권 예매부터 현지 적응까지, 단계별로 필요한 정보를 제공합니다. 1. 여행 계획 수립 및

ChatGPT 무료와 유료 차이 비교

ChatGPT 무료와 유료 차이 비교

ChatGPT 무료와 유료(Plus,Pro) 차이 비교 ChatGPT는 오픈AI가 개발한 강력한 대규모 언어 모델로, 다양한 작업에 활용 가능한 놀라운 도구입니다. 무료 버전과 유료 버전인 ChatGPT Plus는 여러 측면에서 차이가 있으며, 어떤 버전을 선택해야 할지는 사용 목적과 예산에 따라 달라집니다. 이 글에서는 ChatGPT 무료와 유료 버전의 차이점을 상세하게 비교 분석하여, 여러분의

손흥민의 축구 인생

손흥민의 축구 인생

손흥민, 축구 역사의 한 페이지: 시대별 주요 활약상 손흥민, 대한민국을 대표하는 축구 스타이자 프리미어 리그를 빛낸 월드클래스 선수. 그의 놀라운 여정을 시대별로 나누어 살펴봅니다. 1. 어린 시절과 유소년 시절 (1992-2008) 손흥민은 1992년 강원도 춘천에서 태어나 어린 시절부터 축구에 몰두했습니다. 아버지 손웅정의 지도 아래 체계적인 훈련을 받으며 뛰어난 기술과 슈팅 능력을

Image 3
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
Image 4
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.