From 06086c8e44785ff2bb40d5907a1a2c31afc9fdf1 Mon Sep 17 00:00:00 2001 From: Kurt92 Date: Mon, 24 Nov 2025 16:23:32 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat=20:=20tui=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EA=B5=AC=EC=84=B1=20=EB=B3=80=EA=B2=BD,?= =?UTF-8?q?=20=ED=94=84=EB=A1=A0=ED=8A=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EC=A0=95=EB=A6=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../init/controller/MinwonInitController.java | 12 + .../WEB-INF/views/biz/minwon/init/init.jsp | 566 ++++++-------- .../views/biz/minwon/init/init_popup.jsp | 504 +++++++++++++ .../biz/totalInfo/totalInfo_photo_dialog.jsp | 82 +- .../views/biz/totalInfo/totalInfo_popup.jsp | 2 +- .../WEB-INF/views/layouts/base/default.jsp | 5 + .../xit/tuiGridCustom/xit-tui-grid.css | 71 ++ .../xit/tuiGridCustom/xit-tui-grid.js | 698 ++++++++++++++++++ 8 files changed, 1554 insertions(+), 386 deletions(-) create mode 100644 src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp create mode 100644 src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.css create mode 100644 src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.js diff --git a/src/main/java/go/kr/project/biz/minwon/init/controller/MinwonInitController.java b/src/main/java/go/kr/project/biz/minwon/init/controller/MinwonInitController.java index 1bdb24e..101bb14 100644 --- a/src/main/java/go/kr/project/biz/minwon/init/controller/MinwonInitController.java +++ b/src/main/java/go/kr/project/biz/minwon/init/controller/MinwonInitController.java @@ -34,6 +34,18 @@ public class MinwonInitController { return "biz/minwon/init/init" + TilesConstants.BASE; } + + /** + * 민원접수 초기자료 팝업 페이지 + * @return 뷰 경로 + */ + @GetMapping("/minwon/init/init_popup.do") + public String initPopupView() { + + return "biz/minwon/init/init_popup" + TilesConstants.POPUP; + } + + @PostMapping("/minwon/init/list.ajax") public ResponseEntity getMinwonInitListAjax(@ModelAttribute MinwonInitDto.Request.SearchMinwonInitList dto) { diff --git a/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp b/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp index 340f828..d8b2b50 100644 --- a/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp +++ b/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp @@ -37,7 +37,7 @@
  • 접수일자 지정
  • - ~ + ~
  • @@ -71,366 +71,244 @@ diff --git a/src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp b/src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp new file mode 100644 index 0000000..f06ba9b --- /dev/null +++ b/src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp @@ -0,0 +1,504 @@ +<%-- + Created by IntelliJ IDEA. + User: kurt + Date: 2025. 7. 31. + Time: 오후 5:34 + To change this template use File | Settings | File Templates. +--%> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + +
    + +
    +
    +
    민원 접수 초기자료 편집
    +
    + Double Click 민원원본보기 + +
    +
    + + +
    + <%-- 부모창에서 받아오는 리스트 배열 --%> + + <%-- 부모창에서 받아오는 리스크 커서 --%> + + <%-- 개별총정보 상태값 --%> + + + +
    + 0of 0
    + +
    + +
    + +
    +
    위반 정보
    +
    등록구분/위반일시/위반내역 등
    + +
    +
    등록구분
    +
    + +
    +
    자료출처
    +
    + +
    + +
    위반일시
    +
    + +
    +
    위반내용
    +
    + +
    + +
    신고자
    +
    + +
    +
    연락처
    +
    + +
    + +
    담당자
    +
    + +
    +
    공개여부
    +
    + +
    + + + +
    신고내용
    +
    + +
    + +
    위반장소
    +
    +
    접수번호
    +
    + +
    접수일자
    +
    +
    목록번호
    +
    + +
    법정동
    +
    +
    + +
    사진등록금액
    +
    + +
    +
    부과금액
    +
    + +
    + +
    감액금액
    +
    + +
    +
    총수납액
    +
    + +
    + +
    잔액
    +
    + +
    +
    특기사항
    +
    + +
    + +
    + +
    처리상태일시
    +
    + +
    +
    처리상태
    +
    + +
    + +
    차량명
    +
    + +
    +
    차량색상
    +
    + +
    + +
    연료구분
    +
    + +
    +
    + +
    + +
    소유주 정보
    + +
    소유주
    +
    + +
    +
    등록구분
    +
    + +
    + +
    주민번호
    +
    + +
    +
    우편번호
    +
    + +
    + +
    주소
    +
    + +
    + +
    번지
    +
    + +
    +
    차대번호
    +
    + +
    + +
    도로코드
    +
    + +
    +
    +
    +
    + + +
    +
    사진
    +
    + <%-- IMG area --%> +
    + +
    + 지도 +
    + +
    + 미리보기 +
    +
    + +
    + + + + + + + + + + +
    +
    + +
    +
    +
    + 3 사진 + +
    +
    +
    + + +
    + +<%----%> +<%----%> + diff --git a/src/main/webapp/WEB-INF/views/biz/totalInfo/totalInfo_photo_dialog.jsp b/src/main/webapp/WEB-INF/views/biz/totalInfo/totalInfo_photo_dialog.jsp index 6fb0fb7..16f3c5c 100644 --- a/src/main/webapp/WEB-INF/views/biz/totalInfo/totalInfo_photo_dialog.jsp +++ b/src/main/webapp/WEB-INF/views/biz/totalInfo/totalInfo_photo_dialog.jsp @@ -22,51 +22,51 @@ -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    - -<%-- --%> -<%--
    --%> -<%-- -<%-- src=""--%> -<%-- alt="사진 보기"--%> -<%-- style="max-width:100%; height:auto; display:block; margin:0 auto;">--%> - -<%--
    --%> -<%-- --%> -<%-- --%> +<%--
    --%> +<%--
    --%> +<%--
    --%> +<%--
    --%> +<%--
    --%> +<%-- --%> +<%--
    --%> +<%--
    --%> +<%--
    --%> +<%--
    --%> +<%--
    --%> +<%--
    --%> <%--
    --%> <%--
    --%> -<%-- --%> -<%-- + + +
    + + <%-- tui grid new --%> + + + " /> diff --git a/src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.css b/src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.css new file mode 100644 index 0000000..ebdebf8 --- /dev/null +++ b/src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.css @@ -0,0 +1,71 @@ +@charset "utf-8"; + + + +tui-grid-content-area {border-radius: 10px;} + +/* selected row */ +table.tui-grid-table tr.tui-grid-cell-current-row > td{ + background-color: rgba(199, 235, 235, 1); +} + +table.tui-grid-table tr.tui-grid-cell-current-row > td:focus{ + outline: none; +} + + +/* font size */ +table.tui-grid-table th{ + border-color: #fff; + font-size: 14px; + font-family: 'notokr-bold'; +} +table.tui-grid-table td div{ + font-size: 0.80rem; +} + + +/* header color */ +table.tui-grid-table th.tui-grid-cell-header, table.tui-grid-table th.tui-grid-cell-row-header{ + background-color: #f2f4ff; + border-right: 1px solid #fff; + /*border-top: 2px solid #d0d0d0;*/ + font-size: 14px; + font-weight: bold; +} +.tui-grid-scrollbar-right-top {background-color: #f2f4ff;} + +.tui-grid-body-area {margin-right: 3px;} +.tui-grid-scrollbar-y-outer-border {background-color: unset !important;} +.tui-grid-scrollbar-right-bottom { border-bottom-right-radius: 10px;} + /* grid cell */ +/* table.tui-grid-table td.tui-grid-cell div.tui-grid-cell-content{ */ +/* overflow: auto; */ +/* } */ +table.tui-grid-table td.tui-grid-cell-editable > div.tui-grid-cell-content{ + /* border: 1px outset; */ + cursor: pointer; + +} + +/* summary영역 수정 */ +.tui-grid-summary-area .tui-grid-cell { + text-align: right; + font-size: 11px; + padding-right: 5px; + background-color: rgba(238, 238, 238, 1); + border: 1px solid white; +} + +.tui-grid-table tr { + border-bottom: 1px solid #eee; +} + +/* "CustomButtonRenderer" print cell .. */ +table.tui-grid-table tr > td > span > p { + color: #0000ee; + cursor: pointer; + padding-bottom: 1px; + border-bottom: solid 1px; + padding-left: 10px; +} \ No newline at end of file diff --git a/src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.js b/src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.js new file mode 100644 index 0000000..a6c6a64 --- /dev/null +++ b/src/main/webapp/resources/xit/tuiGridCustom/xit-tui-grid.js @@ -0,0 +1,698 @@ +const Grid = tui.Grid; + +const customTheme = { + selection: { + background: '#4daaf9', + border: '#004082' + }, + scrollbar: { + background: '#f5f5f5', + thumb: '#d9d9d9', + active: '#c1c1c1' + }, + row: { + even: { + // background: '#f2f4ff' + background: '#fff' + }, + hover: { + background: '#ccc' + } + }, + cell: { + normal: { + background: '#fbfbfb', + border: '#e0e0e0', + showVerticalBorder: false + }, + header: { + background: '#f2f4ff', + // border: '#ccc', + text:'#09097a', + showVerticalBorder: false + }, + rowHeader: { + // border: '#ccc', + showVerticalBorder: false + }, + editable: { + background: '#fbfbfb' + }, + selectedHeader: { + background: '#d8d8d8' + }, + focused: { + border: '#418ed4' + }, + disabled: { + text: '#b0b0b0' + } + } +} + +class CustomRowNumberRenderer { + constructor(props) { + const el = document.createElement('span'); + + this.el = el; + this.el.innerHTML = this.getRowNum(props); + } + + getRowNum(props) { + // paging 처리시 : scroll인 경우 제외 + const currentPage = props.grid.getPagination()?._currentPage; + // You can change the number `5` as your perPage option. + return Number(props.formattedValue) + (currentPage - 1) * props.grid.getPagination()?._options?.itemsPerPage; + } + + getElement() { + return this.el; + } + + render(props) { + this.el.innerHTML = this.getRowNum(props); + } +} + + +/***************************************** + * Tui-Grid 공식문서 + * https://nhn.github.io/tui.grid/latest/ + ******************************************/ +const TuiGrid = { + instance: null, + defaultOptions: { + el: $('#grid'), + //[선택]DataSource 정보(readData|createData|updateData|modifyData|deleteData 등) + data: { + headers: { + AJAX: true + }, + withCredentials: false, + initialRequest: false, + api: { + readData: { + contentType: 'application/json', + dataType: 'json', + method: 'get', + initParams: {} + } + , createData: {url: '', method: 'POST'} + , updateData: {url: '', method: 'PUT'} + , modifyData: {url: '', method: 'PUT'} + , deleteData: {url: '', method: 'DELETE'} + } + }, + header: { + align:'left', //헤더 좌측정렬 + columns: [{name: "_checked", align: "center"}] //헤더 채크박스 가운데정렬 + }, //[선택]헤더정보(헤더 명칭 및 매핑 field) + columns: [], //[필수]컬럼정보(헤더 명칭 및 매핑 field) + rowHeaders: [], //[선택]ROW 헤더 타입(rowNum: 순번, checkbox: 체크박스) + bodyHeight: 467, //[선택]Grid 높이 (number(단위: px)|'auto'|'fitToParent') + minBodyHeight: 350, //[선택]Grid 최소 높이 (단위: px) + rowHeight: 50, //[선택]Grid row 높이 (number(단위: px)|'auto' ) + minRowHeight: 50, //[선택]Grid row 최소 높이 (단위: px) + pageOptions: { + useClient: false, + page: 1, + perPage: 10 + }, //[선택]한 페이지에 출력할 건수 + columnOptions: { //[선택]고정 컬럼 + //frozenCount: 0 //고정컬럼 갯수 + frozenBorderWidth: 2 //고정컬럼 보더(border) 두께 + , resizable: true + , minWidth: 100 //최소 사이즈 + }, + summary: [], //[선택]하단합계 + treeColumnOptions: {}, //[선택]tree 구조 grid + }, + + of: function (options, dataSource, successCallback) { + + this.instance = null; + // rowNum fix + if (options.pageOptions?.type !== 'scroll') { + options.rowHeaders.filter((r, idx) => { + if (r === 'rowNum') { + options.rowHeaders[idx] = { + type: 'rowNum', + renderer: { + type: CustomRowNumberRenderer + } + } + } + }) + } + const newOptions = $.extend(true, {}, this.defaultOptions, options, {data: dataSource}); + newOptions.el = document.getElementById(options.el); + //this.elId = options.el; + + // language + tui.Grid.setLanguage('en', { + display: { + noData: options?.noData + } + }); + // theme + //tui.Grid.applyTheme('custom', eval(customTheme)); + //Grid.applyTheme('custom', customTheme); + Grid.applyTheme('striped', customTheme); + // console.log("newOpt", newOptions); + this.instance = new tui.Grid(newOptions); + + + this.instance.on('successResponse', function (ev) { + // console.log(`successResponse >>>>>>>>>>>>>>>>>> `,ev); + var msg = JSON.parse(ev.xhr.response).message; //tui-grid 기본 format 메시지 + + //if($('#totCnt span')){ + if (document.getElementById('totCnt')) { + const res = JSON.parse(ev.xhr.response); + // paging + if (res.data.pagination) { + $('#totCnt span').text(res.data.pagination.totalCount); + // no paging + } else { + $('#totCnt span').text(res.count) + } + // console.log('totCnt >>>>> ',$('#totCnt span').text()) + } + + if (successCallback) successCallback(JSON.parse(ev.xhr.response)); + //if(successCallback) successCallback(ev); + }); + // 결과가 false인 경우 발생한 경우 + this.instance.on('failResponse', function (ev) { + // console.log(`failResponse >>>>>>>>>>>>>>>>>> `,ev); + try { + //tui-grid 기본 format 메시지 + + const res = JSON.parse(ev.xhr.response); + + let msg = ''; + if (!(res.message == null || res.message == undefined || res.message == '')) { + alert(res.message); + } else { + alert(res); + } + } catch (e) { + alert("오류가 발생하였습니다."); + // console.error('TuiGrid::failResponse parsing error', e) + } + }); + // 오류가 발생한 경우 + this.instance.on('errorResponse', function (ev) { + // console.log(`errorResponse >>>>>>>>>>>>>>>>>> `,ev); + try { + //tui-grid 기본 format 메시지 + const res = JSON.parse(ev.xhr.response); + if (!(res.message == null || res.message == undefined || res.message == '')) { + alert(res.message); + } else { + alert(res); + } + } catch (e) { + alert("오류가 발생하였습니다."); + // console.error('TuiGrid::errorResponse parsing error', e) + } + }); + + /** + * grid check box event start + * */ + // 체크박스 이벤트 + this.instance.on("check", () => { + $("#selectOption").addClass("active"); + $("#remove").attr("disabled", false); + $("#sendMessageBtn").removeClass("disabled"); + $("#sendMessageBtn").attr("disabled", false); + $("#checkedCount").text(GRID.getCheckedRows().length); + $("#assigns-btn").removeClass("disabled"); + $("#assigns-btn").attr("disabled", false); + $("#suspend-btn").attr("disabled", false); + $("#returnBtn").attr("disabled", false); + }); + // 체크박스 해제 이벤트 + this.instance.on("uncheck", () => { + const checkedCount = GRID.getCheckedRows().length; + if (checkedCount === 0) { + $("#selectOption").removeClass("active"); + $("#remove").attr("disabled", true); + $("#sendMessageBtn").addClass("disabled"); + $("#sendMessageBtn").attr("disabled", true); + $("#assigns-btn").addClass("disabled"); + $("#assigns-btn").attr("disabled", true); + $("#suspend-btn").attr("disabled", true); + $("#returnBtn").attr("disabled", true); + } + $("#checkedCount").text(checkedCount); + }); + // 전체 체크박스 이벤트 + this.instance.on("checkAll", () => { + $("#selectOption").addClass("active"); + $("#remove").attr("disabled", false); + $("#sendMessageBtn").removeClass("disabled"); + $("#sendMessageBtn").attr("disabled", false); + $("#checkedCount").text(GRID.getCheckedRows().length); + $("#assigns-btn").removeClass("disabled"); + $("#assigns-btn").attr("disabled", false); + $("#suspend-btn").attr("disabled", false); + $("#returnBtn").attr("disabled", false); + }); + // 전체 체크박스 해제 이벤트 + this.instance.on("uncheckAll", () => { + $("#selectOption").removeClass("active"); + $("#remove").attr("disabled", true); + $("#sendMessageBtn").addClass("disabled"); + $("#sendMessageBtn").attr("disabled", true); + $("#checkedCount").text(GRID.getCheckedRows().length); + $("#assigns-btn").addClass("disabled"); + $("#assigns-btn").attr("disabled", true); + $("#suspend-btn").attr("disabled", true); + $("#returnBtn").attr("disabled", true); + }); + /** + * grid check box event end + * */ + + + return this.instance; + }, + + + /** Excel Export */ + exportExcel: function (_instance, fileName, rowHeader) { + /* 필수값 설정 */ + var _gridId = _instance.el.id; + var _frstColTyp = rowHeader; + var _arrHeader = []; + var _arrName = []; + var _mCustomRenderer = {}; + /* ================= + * 2021.04.30. 박민규 + * 컬럼 취득 방법 변경 + * AsIs: GridConfig 에 설정한 Columns 정보 + * ToBe: instance 에 설정된 Columns 정보 + ================= */ + //2021.04.30. 주석처리 +// this.getOptColumns().forEach(function(opt, idx){ + _instance.getColumns().forEach(function (opt, idx) { + _arrHeader.push(opt.header); + _arrName.push(opt.name); + //2021.04.30. 주석처리 +// if(!fnIsEmpty(opt.renderer)){ + if (!(fnIsEmpty(opt.renderer) || 'DefaultRenderer' == opt.renderer.type.name || fnIsEmpty(opt.renderer.type.name))) { //브라우저별 opt.renderer.type.name 값의 차이 => Chrome: "DefaultRenderer", IE: undefined + _mCustomRenderer[opt.name] = opt.renderer; + } + }); + + + /* grid head Setting */ + var elementTHEAD = document.createElement('table'); + var $sltHeader = $('#' + _gridId + ' .tui-grid-header-area > table.tui-grid-table').clone(); + //head 처리(table 고정셀 이용 시) + if ($sltHeader.length > 1) { + //좌측 table의 head Selector + var firstTableTh = $sltHeader.find('tr:last-child th'); + //우측 table row의 헤드(th)를 좌측 table row에 병합 + for (var i = 1; i < $sltHeader.length; i++) { + $sltHeader.eq(i).find('tr').each(function (idx, row) { + var firstTableRow = $sltHeader.eq(0).find('tr:eq(' + idx + ')'); + if (firstTableRow.length == 0) { + // 신규생성 + var tr = document.createElement('tr'); + tr.innerHTML = row.innerHTML; + $sltHeader.eq(0).append(tr); + //firstTable 의 rowspan 변경 + for (var j = 0; j < firstTableTh.length; j++) { + firstTableTh.eq(j).attr('rowspan', Number(firstTableTh.eq(j).attr('rowspan')) + 1); + } + } else { + firstTableRow.append(row.innerHTML); + } + }); + } + } + elementTHEAD.innerHTML = $sltHeader.eq(0).find('tbody').html(); + + + /* grid body Setting */ + var elementTBODY = document.createElement('tbody'); + _instance.getData().forEach(function (row, idxRow) { + var elementTR = document.createElement('tr'); + + //타입별 element 생성( 첫번째 컬럼타입 설정 시 ) + if (!fnIsEmpty(_frstColTyp)) + elementTR.appendChild(fnCreateTdByFrstCol(_frstColTyp, row)); + // element 생성 + _arrName.forEach(function (columnName, idxColumn) { + var columnVal = ''; + var customRenderer = _mCustomRenderer[columnName]; + if (fnIsEmpty(customRenderer)) { + //column Value 설정 + columnVal = fnNvl(row[columnName]); + } else { + //prop 객체 생성 + var columnInfo = {}; + columnInfo['renderer'] = customRenderer; + columnInfo['name'] = columnName; + var props = {}; + props['columnInfo'] = columnInfo; + props['rowKey'] = row.rowKey; + props['grid'] = _instance; + + //렌더러 호출 + customRenderer.type(props); + + //column Value 설정 + columnVal = fnNvl(row[columnName]); + if (row.rowKey < 15) { +// // console.log('[export]rowKey->'+row.rowKey+'/ column->'+columnName+' / value->'+row[columnName]); +// // console.log(_instance.getRow(row.rowKey)); + } + } + + var elementTD = document.createElement('td'); + elementTD.innerHTML = columnVal; + elementTR.appendChild(elementTD); + }); + elementTBODY.appendChild(elementTR); + }); + + + /* grid table Setting */ + var elementTABLE = document.createElement('table'); + elementTABLE.appendChild(elementTHEAD); + elementTABLE.appendChild(elementTBODY); + + + /* export Excel */ + var fileUtil = new luluFileExportUtil(fileName, 'table', elementTABLE); + fileUtil.exportExcel(); + + + /* member Function Declare */ + + //isEmpty Function + function fnIsEmpty(val) { + if (val == undefined || val == null || val == '' || val == {} || val == []) + return true; + return false; + } + + //nvl Function + function fnNvl(val, replaceVal) { + replaceVal = fnIsEmpty(replaceVal) ? '' : replaceVal; + val = fnIsEmpty(val) ? replaceVal : val; + return val; + } + + // element 생성 Function + function fnCreateTdByFrstCol(colType, row) { + var returnVal = ''; + + /* column 타입별 value 설정 */ + switch (colType) { + case 'rowNum': + returnVal = row._attributes.rowNum; + break; + case 'checkbox': + if (row._attributes.checked) + returnVal = '☑'; + else + returnVal = '□'; + break; + default: + return returnVal; + break; + } + + /* element 생성 */ + var elementFrstTD = document.createElement('td'); + elementFrstTD.innerHTML = returnVal; + + + return elementFrstTD; + } + } +} + +/** + * Button 렌더러 + * -설명: Grid의 cell에 Button을 생성 한다. + * 버튼명칭에 format 사용이 가능하며 사용방법은 아래와 같다. + * ex) value: 'A is {0}. B is {1}. {0}!={1}', + * listColumns: ['컬럼1', '컬럼2'] + * @param value 버튼에 출력 할 명칭 + * @param listColumns format에 매칭할 컬럼 목록 + * @param callbackFnc 버튼 클릭 시 호출 할 함수명 + * @author 박민규 + * @date 2020.05.28. + */ +var LuluButtonRenderer = function (props) { +// // console.log('XitButtonRenderer Called!!-> '+props.columnInfo.name); + //options get + var opt = props.columnInfo.renderer.options; + var value = opt.value; + var id = opt.id; + var btnClass = opt.btnClass; + var callbackFnc = opt.callbackFnc; + var args = opt.listColumns; + + //"value" Formatting + if (args != undefined) { + var row = props.grid.getRow(props.rowKey); + for (var i = 0; i < args.length; i++) { + var regEx = new RegExp('\\{' + i + '\\}', 'gi'); + value = value.replace(regEx, row[args[i]]); + } + } + + //Element Setting + //23.07.24 최정민 추 + //iuput button에서 button으로 수정 (아이콘을 넣기위함) + //el id추가 + //버튼에 아이콘을 쓰기위하여 아이콘 클레스명 인자로 받아갈것. + var el = document.createElement('button'); + var icon = document.createElement('i'); + icon.className = btnClass; // 원하는 아이콘 클래스를 설정하세요. + el.className = btnClass; + el.type = 'button'; + el.value = value; + el.id = id; + + //EventListener Setting + el.addEventListener('click', function () { + var callback = callbackFnc + '(props)'; + eval(callback); + }); + + //Element render + this.el = el; +// this.render(props); + if (props.rowKey < 15) { +// // console.log('[Renderer]rowKey->'+props.rowKey+' column->'+props.columnInfo.name+' / el.value->'+el.value); + } + //DataSet Injection ( Dataset에 추가해야 "복사(ctrl+c)" 기능 사용 가능 ) + props.grid.setValue(props.rowKey, props.columnInfo.name, el.value, false); +} +LuluButtonRenderer.prototype.getElement = function () { + return this.el; +} +LuluButtonRenderer.prototype.render = function (props) { + this.el.value = props.value; +} + + +/** + * column 병합 렌더러 + * -설명: 다수의 Column을 하나의 Column으로 병합하여 cell에 출력 한다. + * 필요 시 format 사용이 가능하며 사용방법은 아래와 같다. (※포맷 사용 시 "구분자(separator)"는 적용되지 않는다) + * [단순 컬럼 병합] + * ex) listColumns: ['컬럼1', '컬럼2'], + * separator: '/' + * [포맷사용 컬럼 병합] + * ex) listColumns: ['컬럼1', '컬럼2'], + * format: 'A is {0}. B is {1}. {0}!={1}' + * @param listColumns 병합할 컬럼 name 목록 + * @param separator 컬럼 연결 구분자(default: 공백(' ')) + * @param format 출력 포맷 + * @author 박민규 + * @date 2020.05.28. + */ +var XitColumnMergeRenderer = function (props) { +// // console.log('XitColumnMergeRenderer Called!!-> '+props.columnInfo.name); + //options get + var opt = props.columnInfo.renderer.options; + var args = opt.listColumns; + var separator = opt.separator; + if (fnIsEmpty(separator)) + separator = ' '; + var value = opt.format; + + //Columns merge + if (fnIsEmpty(value)) { + var arrStr = []; + var row = props.grid.getRow(props.rowKey); + args.forEach(function (column) { + arrStr.push(row[column]); + }); + value = arrStr.join(separator); + } else { + var row = props.grid.getRow(props.rowKey); + for (var i = 0; i < args.length; i++) { + var regEx = new RegExp('\\{' + i + '\\}', 'gi'); + value = value.replace(regEx, fnNvl(row[args[i]])); + } + } + + function fnNvl(val) { + if (val == undefined || val == null) + return ''; + return val; + } + + function fnIsEmpty(val) { + if (val == undefined || val == null || val == '' || val == [] || val == {}) + return true; + return false; + } + + //Element Setting + var el = document.createElement('div'); + el.setAttribute('class', 'tui-grid-cell-content'); + el.innerHTML = value; + + //Element render + this.el = el; +// this.render(props); + if (props.rowKey < 15) { +// // console.log('[Renderer]rowKey->'+props.rowKey+' column->'+props.columnInfo.name+' / el.value->'+el.innerHTML); + } + + //DataSet Injection ( Dataset에 추가해야 "복사(ctrl+c)" 기능 사용 가능 ) + props.grid.setValue(props.rowKey, props.columnInfo.name, el.innerHTML, false); +} +XitColumnMergeRenderer.prototype.getElement = function () { + return this.el; +} +XitColumnMergeRenderer.prototype.render = function (props) { + this.el.value = props.value; +} + + +/** + * Button 렌더러 + * @author 최유수 + * @date 2020.07.15. + * formatter : 셀 안에 입력될 문자열. + ,eventType : 셀에 걸 이벤트. + ,eventFunction : 이벤트에 부여될 함수. + + element 속성 + element : 생성 엘리먼트 속성 + type : 생성 엘리먼트의 타입 + value : 들어갈 텍스트 + */ +/** + * 요구사항 + * 셀 속성을 부여할때 + * + * 1.셀에 개발자가 원하는 Element를 생성 할 수 있음 + * 2.1의 속성에 개발자가 원하는 이벤트를 부여 할 수 있음 + * 3. 2의 이벤트에 개발자가 원하는 함수를 부여 할 수 있음 + * 4. 개발자가 원하는만큼 유형을 추가 할 수 있음.(유형이 여러개일수도 아닐수도 있음) + */ +var CustomButtonRenderer = function (props) { + //options get + var opt = props.columnInfo.renderer.options; + //formatter를 구성할 인자값(해당 인자값은 함수형일때 배열일 수 있음.) + var formatter = opt.formatter; + //이벤트로 사용할 함수 + var eventFunction = opt.eventFunction; + //이벤트 속성 + var eventType = opt.eventType; + //객체 유형 + var element = opt.element; + //객체 속성 + var type = opt.type; + + + var formattObject = formatter; + if (typeof formatter == "function") { + //formatter가 함수에 의해 구현이됨, Return값은 Arr, Objcect임; + //Object는 formatter : Text 와 Element로 구성됨. + formattObject = formatter(props); + } else { + //formatter가 단순 텍스트임. + formattObject = opt; + } + + var ele = cellMaker(formattObject, eventFunction, eventType, element, type, props); + this.el = ele; +} +CustomButtonRenderer.prototype.getElement = function () { + return this.el; +} + +//셀을 만듦. +var cellMaker = function (formattObject, eventFunction, eventType, element, type, props) { + var spanEle = document.createElement("span"); + var ele; + + //셀에 1개 이상의 데이터가 들어가는 경우 + if (formattObject instanceof Array && formattObject.length != 0) { + formattObject.forEach(function (elementObject, index, arrays) { + elementObject["eventFunction"] = eventFunction; + elementObject["eventType"] = eventType; + ele = elMaker(elementObject, props); + $(spanEle).append(ele); + //객체가 다수이면 띄어쓰기 함 + if (index < formattObject.length - 1) { + $(spanEle).append(document.createTextNode('\u00a0 // \u00a0')); + } + }); + } + + //셀에 데이터가 1개이지만 함수로 Obj를 가져와서 만듦 + if (formattObject instanceof Object) { + formattObject["eventFunction"] = eventFunction; + formattObject["eventType"] = eventType; + ele = elMaker(formattObject, props); + spanEle.appendChild(ele); + } + + return spanEle; +} + +var elMaker = function (elementObject, props) { + var text = elementObject.formatter + var eventType = elementObject.eventType + var element = elementObject.element + var eventFunction = elementObject.eventFunction + var type = elementObject.type + + var ele; + if (element == "text") { + ele = document.createElement("p"); + ele.style.whiteSpace = 'nowrap'; + ele.style.display = 'inline-block'; + ele.style.fontSize = '11px'; + ele.style.fontFamily = 'Nanum Barun Gothic'; + ele.appendChild(document.createTextNode(text)); + } else { + ele = document.createElement(element); + ele.type = type; + ele.value = text; + } + //이벤트가 함수이면 이벤트 부여함. + if (typeof eventFunction == "function") { + ele.addEventListener(eventType, function (event) { + eventFunction(props, event) + }); + } + + return ele; + +} From 1ae7b35fc3093f4249ceac37a98e1acbaee92c7e Mon Sep 17 00:00:00 2001 From: Kurt92 Date: Mon, 24 Nov 2025 18:19:25 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat=20:=20=EA=B0=9C=EB=B3=84=20=EC=B4=9D?= =?UTF-8?q?=EC=A0=95=EB=B3=B4,=20=EB=AF=BC=EC=9B=90=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=EC=9E=90=EB=A3=8C=20=ED=8C=9D=EC=97=85=20Flex=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WEB-INF/views/biz/minwon/init/init.jsp | 1 - .../views/biz/minwon/init/init_popup.jsp | 389 +++++++++++------- src/main/webapp/resources/css/cc.css | 35 +- 3 files changed, 267 insertions(+), 158 deletions(-) diff --git a/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp b/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp index d8b2b50..dadc163 100644 --- a/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp +++ b/src/main/webapp/WEB-INF/views/biz/minwon/init/init.jsp @@ -272,7 +272,6 @@ useClient: true, // 클라이언트 페이징 여부(false: 서버 페이징) perPage: perPage, }, - }; GRID = TuiGrid.of(gridOptions, gridDatasource, (res) => { diff --git a/src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp b/src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp index f06ba9b..424afe2 100644 --- a/src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp +++ b/src/main/webapp/WEB-INF/views/biz/minwon/init/init_popup.jsp @@ -29,9 +29,9 @@ <%-- 개별총정보 상태값 --%> -
    - 0of 0
    + 0of 0 +