//Tabulator용 공통함수 const tb_common_funtions = { //토글버튼 출력 formatterToggleboxIcon: function (tgt, params) { let cell = tgt._cell; let span = document.createElement("span"); if ( params.checkval && cell.value == params.checkval || !params.checkval && cell.value == true) { span.className = "bi bi-toggle-on tb_toggle"; } else { span.className = "bi bi-toggle-off tb_toggle"; } return span; }, //토글버튼 출력 red formatterToggleboxRedIcon: function (tgt, params) { let cell = tgt._cell; let span = document.createElement("span"); if ( params.checkval && cell.value == params.checkval || !params.checkval && cell.value == true) { span.className = "bi bi-toggle-on tb_toggle red"; } else { span.className = "bi bi-toggle-off tb_toggle red"; } return span; }, //토글버튼 출력 green formatterToggleboxGreenIcon: function (tgt, params) { let cell = tgt._cell; let span = document.createElement("span"); if ( params.checkval && cell.value == params.checkval || !params.checkval && cell.value == true) { span.className = "bi bi-toggle-on tb_toggle green"; } else { span.className = "bi bi-toggle-off tb_toggle green"; } return span; }, //토글버튼 TEXT Icon formatterToggleboxText: function (tgt, params) { let cell = tgt._cell; let label = document.createElement("label"); let span = document.createElement("span"); let span2 = document.createElement("span"); span2.classList.add("switch"); label.classList.add("toggle-switchy"); label.setAttribute("data-size", params.size||"xs");//크기 label.setAttribute("data-style", params.shape||"rounded");//모양 if ( params.checkval && cell.value === params.checkval || !params.checkval && cell.value === true) { span.classList.add('checked'); } else { span.classList.add('notchecked'); } span.classList.add('toggle'); span.setAttribute('on',params.onval||'ON'); span.setAttribute('off',params.offval||'OFF'); span.appendChild(span2); label.appendChild(span); return label; }, //Selected Circle 출력 formatterSelCircleIcon: function (tgt, params) { let cell = tgt._cell; let em = document.createElement("i"); if (cell.value == "Y") { em.className = "bi bi-circle-fill fa-2xs"; } else { em.className = ""; } return em; }, //국가명 출력 formatterNations: function (tgt, params) { let cell = tgt._cell; let nval = Object.keys(varsNations).filter(key => key === cell.value ); return varsNations[nval[0]]; }, //통화 출력 formatterCurrency: function (tgt, params) { let cell = tgt._cell; let nval = Object.keys(varsCurrency).filter(key => key === cell.value ); return varsCurrency[nval[0]]; }, //Number / 통화. 출력 formatterNumber: function (tgt, params) { if(!tgt.getValue()) return; let val = tgt.getValue(); let config = {symbol:params?.symbol||'',precision:params?.precision||0,}; if( params?.group) config.group = params.group; if( params?.pattern) config.pattern = params.pattern; if( params?.decimal) config.decimal = params.decimal; if( params?.separator) config.separator = params.separator; if( params?.negativePattern) config.negativePattern = params.negativePattern; let nval = currency(Number(val), config); return nval.format(); }, //체크버튼 출력 true/false formatterCheckboxIcon: function (tgt, params) { let cell = tgt._cell; let label = document.createElement("label"); let input = document.createElement("input"); input.type = "checkbox"; input.className = "tb_checkbox"; if( cell.value ){ input.checked = true; } label.append(input); return label; }, //체크버튼 출력 Y/N formatterCheckboxIconYn: function (tgt, params) { let cell = tgt._cell; let label = document.createElement("label"); let input = document.createElement("input"); input.type = "checkbox"; input.className = "tb_checkbox"; if( cell.value === 'Y' ){ input.checked = true; } label.append(input); return label; }, //체크버튼 조회용 출력 formatterCheckboxViewIcon: function (tgt, params) { let cell = tgt._cell; let label = document.createElement("label"); if( cell.value ){ let input = document.createElement("input"); input.addEventListener("click",function(e){ e.stopPropagation(); e.preventDefault(); }); input.type = "checkbox"; input.className = "tb_checkbox"; input.checked = true; label.append(input); } //else { input.checked = false; label.append(input); } return label; }, //체크버튼 조회용 출력 formatterCheckboxViewIcon2: function (tgt, params) { let cell = tgt._cell; let label = document.createElement("label"); let input = document.createElement("input"); input.addEventListener("click",function(e){ e.stopPropagation(); e.preventDefault(); }); input.type = "checkbox"; input.className = "tb_checkbox"; label.append(input); if( cell.value ){ input.checked = true; } else { input.checked = false; } return label; }, //Check or Not 조회아이콘 출력 formatterCheckIcon: function (tgt, params) { let cell = tgt._cell; let span = document.createElement("span"); if( cell.value ){ span.className = "bi bi-check-circle-fill tb_icon"; } return span; }, //Check or Not 조회아이콘 출력2 formatterCheckIcon2: function (tgt, params) { let cell = tgt._cell; let span = document.createElement("span"); if( cell.value == params.checkval ){ span.className = "bi bi-check-circle-fill"; }else{ span.className = "bi bi-circle text-black-50"; } return span; }, //O or X 조회아이콘 출력 formatterToggleIcon: function (tgt, params) { var cell = tgt._cell; let span = document.createElement("span"); if( cell.value ){ span.className = "bi bi-toggle-on tb_toggle"; }else{ span.className = "bi bi-toggle-off tb_toggle"; } return span; }, formatterSelect: function (tgt, formatterParams) { var cell = tgt._cell; let div = document.createElement("div"); if(formatterParams.class) div.className = formatterParams.class; let nval = cell.value || formatterParams.default; div.innerHTML = formatterParams.values[nval] || (formatterParams.defaultValue || ''); return div; }, formatterButton: function (tgt, params) { var cell = tgt._cell; let btn = document.createElement("a"); btn.className = params.btnClass; btn.innerHTML = params.btnTitle; if( params.event && params.cfunc ){ if( !Array.isArray(params.event) ) params.event = Array(params.event); params.event.forEach( evt => btn.addEventListener(evt, ()=>{params.cfunc(cell);})); } return btn; }, //Json formatter formatterJson: function( tgt, params ){ var cell = tgt._cell; return params.values[cell.value]; }, //multicheckbox or radio formatter formatterMultiCheckBox: function( tgt, params ){ var cell = tgt._cell; let div = document.createElement("form"); if(params.class) div.className = params.class; params.inputs.forEach( ipt => { let label = document.createElement("label"); label.className = ipt.class; let nipt = document.createElement("input"); nipt.type = params.type||'checkbox'; nipt.value = ipt.value; nipt.name = ipt.name; nipt.checked = ipt.value == (tgt.getData()[ipt.name]||params.default); nipt.addEventListener('change',(e)=>{ if( e.target.checked ){ cell.setValue(ipt.value); } return true; }) label.append(ipt.title); label.append(nipt); div.append(label); } ) return div; }, formatterInvalidVal: function( tgt, params ){ let boool = false; switch( params.sp ){ case "=": boool = tgt.getData()[params.field] === params.value; break; case ">": boool = tgt.getData()[params.field] > params.value; break; case "<": boool = tgt.getData()[params.field] < params.value; break; case ">=": boool = tgt.getData()[params.field] >= params.value; break; case "<=": boool = tgt.getData()[params.field] <= params.value; break; case "!=": case "<>": boool = tgt.getData()[params.field] !== params.value; break; case "in": boool = params.value.includes(tgt.getData()[params.field]); break; } if( boool ){ if( params.validClass ){ tgt.getElement().classList.add(params.validClass); } if( params.validValue ){ return params.validValue; } }else{ if( params.invalidClass ){ tgt.getElement().classList.add(params.invalidClass); } if( params.invalidValue ){ return params.invalidValue; } } return tgt.getValue(); }, editorSelect: function(cell, onRendered, success, cancel, editorParams){ let edSelect = document.createElement("select"); let params = editorParams.values; params = params || {}; Object.keys(params).forEach(key => { let edOption = document.createElement("option"); edOption.value = key; edOption.text = params[key]; edSelect.append(edOption); }); edSelect.className = 'form-select form-select-sm'; edSelect.value = cell._cell.value; onRendered(function() { edSelect.focus(); }); let cback = function(){ success( edSelect.value); } edSelect.addEventListener("change", cback); edSelect.addEventListener("blur", cback); return edSelect; }, editorGrpSelect: function(cell, onRendered, success, cancel, editorParams){ let edSelect = document.createElement("select"); let params = editorParams.values; params = params || {}; params.forEach(optg => { let edOptGrp = document.createElement("optgroup"); edOptGrp.label = optg.name; Object.keys(optg.options).forEach( k => { let edOption = document.createElement("option"); edOption.value = k; edOption.text = optg.options[k]; edOptGrp.append(edOption); } ); edSelect.append(edOptGrp); }); //edSelect.className = 'form-select form-select-sm'; edSelect.value = cell._cell.value; edSelect.classList.add("chosen"); onRendered(function() { edSelect.focus(); edSelect.style.width='100%'; }); let cback = function(){ success( editorParams.cfunc ? editorParams.cfunc(cell, edSelect.value) : edSelect.value ); } edSelect.addEventListener("change", cback); edSelect.addEventListener("blur", cback); return edSelect; }, //필드 입력폼 (날짜입력) editorDate: function(cell, onRendered, success, cancel, editorParams) { let dateInput = document.createElement("input"); dateInput.setAttribute("type", "date"); dateInput.className = 'px-2 w-100'; dateInput.value = cell._cell.value; onRendered(function() { dateInput.focus(); }); let cback = function(){ success( (dateInput.value ? luxon.DateTime.fromISO(dateInput.value).toFormat('yyyy-MM-dd') : "") ); } dateInput.addEventListener("change", cback); dateInput.addEventListener("blur", cback); return dateInput; }, //필드 입력폼 (월/년도) editorMonth: function(cell, onRendered, success, cancel, editorParams) { let dateInput = document.createElement("input"); new Cleave(dateInput, { date: true, datePattern: ['m', 'Y'], delimiter: '/' }); // dateInput.setAttribute("type", "date"); dateInput.className = 'px-2 w-100'; dateInput.value = cell._cell.value; onRendered(function() { dateInput.focus(); }); let cback = function(){ success( dateInput.value); } dateInput.addEventListener("change", cback); dateInput.addEventListener("blur", cback); return dateInput; }, //필드 입력폼 (시간입력,단가입력) editorTm: function(cell, onRendered, success, cancel, editorParams) { let tmInput = document.createElement("input"); tmInput.setAttribute("type", "number"); tmInput.value = cell._cell.value; if (typeof onRendered === "function") { onRendered(function() { tmInput.focus(); }); } else { // onRendered가 함수가 아닐 경우 바로 포커스 tmInput.focus(); } let cback = function(){ success(tmInput.value); } tmInput.addEventListener("change", cback); tmInput.addEventListener("blur", cback); return tmInput; }, //필드 입력폼 (텍스트입력) editorString: function(cell, onRendered, success, cancel, editorParams) { let stringInput = document.createElement("input"); stringInput.setAttribute("type", "textarea"); // stringInput.className = 'px-2 w-100'; stringInput.value = cell._cell.value; onRendered(function() { stringInput.focus(); }); let cback = function(){ success( stringInput.value); } stringInput.addEventListener("change", cback); stringInput.addEventListener("blur", cback); return stringInput; }, //필드 입력폼 (전화번호,팩스) editorTel: function(cell, onRendered, success, cancel, editorParams) { // 입력 요소 생성 let telInput = document.createElement("input"); telInput.setAttribute("type", "text"); telInput.value = cell.getValue(); telInput.addEventListener("input", function() { telInput.value = telInput.value .replace(/[^0-9]/g, "") .replace(/^(\d{2,3})(\d{3,4})(\d{4})$/, "$1-$2-$3"); }); onRendered(function() { telInput.focus(); }); let cback = function() { success(telInput.value); }; telInput.addEventListener("change", cback); telInput.addEventListener("blur", cback); return telInput; }, //Row checked class Toggle toggleRowChecked: function( tgt, row ){ if( typeof tgt == "object" ){ row = tgt; row.parent.element.querySelectorAll(".tabulator-table .tabulator-row.tabulator-checked").forEach(tgt => tgt.classList.remove("tabulator-checked")); }else{ document.querySelectorAll(tgt + " .tabulator-table .tabulator-row.tabulator-checked").forEach(tgt => tgt.classList.remove("tabulator-checked")); } if( row != undefined ){ row.element.classList.add("tabulator-checked"); } }, /* Tabulator to Excel * params : 타블레이터 테이블, 생성할 엑셀 파일명, 엑셀 안에 들어갈 제목, 엑셀에 입력될 데이터(선택) */ tabu2xls: function( tab_table, filename, title, udata ){ //let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined).map(s=>({key:s.field, width:Math.round(((s.minWidth||s.width.replace(/[^0-9]/,''))||100)/6), title:s.title})); //width %는 고려하지 않음 let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined && !v.noxls) .reduce( (retv,row) => { if( row.columns ){ row.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined && !v.noxls).forEach(crow => { retv.push({ key : crow.field, width: Math.round(((crow.minWidth||crow.width.replace(/[^0-9]/,'')*10)||100)/6), title: crow.title.replaceAll('
',''), dcss: crow.dcss, }); }); }else{ retv.push({ key : row.field, width: Math.round(((row.minWidth||row.width.replace(/[^0-9]/,'')*10)||100)/6), title: row.title.replaceAll('
',''), dcss: row.dcss, }); } return retv; }, [] ); let datas = udata || tab_table.getData("active").map(data => header.map(s=>s.key).reduce((ov,cv) => ({...ov, [cv]:(data[cv]||"")}), {})); //"active" <= filtered 된 데이터만 가져온다. console.log(datas); json2xls(filename, title, header, datas); }, /* * Tabulator to Excel * 서브컬럼이 있을때 상위컬럼 대신에 서브 컬럼만 엑셀에 포함된다. * params : 타블레이터 테이블, 생성할 엑셀 파일명, 엑셀 안에 들어갈 제목, 엑셀에 입력될 데이터(선택) */ tabu2xls2: function( tab_table, filename, title, udata ){ //let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined).map(s=>({key:s.field, width:Math.round(((s.minWidth||s.width.replace(/[^0-9]/,''))||100)/6), title:s.title})); //width %는 고려하지 않음 let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined && !v.noxls) .reduce( (retv,row,idx) => { retv.push({ key : row.field, width: Math.round(((row.minWidth||row?.width?.replace(/[^0-9]/,'')*10)||100)/6), title: row.title.replaceAll('
',''), dcss: row.dcss, columns : row.columns ? row.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined && !v.noxls).map(crow => { return{ key : crow.field, width: Math.round(((crow.minWidth||crow?.width?.replace(/[^0-9]/,'')*10)||100)/6), title: crow.title.replaceAll('
',''), dcss: crow.dcss, }; }) : [] }); return retv; }, [] ); let datas = udata || tab_table.getData("active").map(data => header.map(s=>s.key).reduce((ov,cv) => ({...ov, [cv]:(data[cv]||"")}), {})); //"active" <= filtered 된 데이터만 가져온다. json2xls(filename, title, header, datas); }, /* * Tabulator to Excel * 그룹바이한 테이블 + 서브컬럼(상위컬럼도 같이 엑셀에 포함) 있을때 사용 * width는 px * params : 타블레이터 테이블, 생성할 엑셀 파일명, 엑셀 안에 들어갈 제목, 엑셀에 입력될 데이터(선택) */ tabu2xls3: function( tab_table, filename, title, udata ){ //let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined).map(s=>({key:s.field, width:Math.round(((s.minWidth||s.width.replace(/[^0-9]/,''))||100)/6), title:s.title})); //width %는 고려하지 않음 // field 없어도 체크 let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && !v.noxls) .reduce( (retv,row) => { if( row.columns ){ // 그룹바이 const groupRow = { columns: [], title: row.title } row.columns.forEach(crow =>{ groupRow.columns.push({ key : crow.field, width: Math.round(((crow.minWidth||crow.width)||100)/6), title: crow.title.replaceAll('
',''), dcss: crow.dcss, }); }) retv.push(groupRow) }else{ retv.push({ key : row.field, width: Math.round(((row.minWidth||row.width)||100)/6), title: row.title.replaceAll('
',''), dcss: row.dcss, }); } return retv; }, [] ); let headerLst = [] header.forEach(h => { if(h.columns){ h.columns.forEach(col =>{ headerLst.push(col.key); }) }else{ headerLst.push(h.key); } }) let datas = udata || tab_table.getData("active").map(data => headerLst.reduce((ov,cv) => ({...ov, [cv]:(data[cv]||"")}), {})); //"active" <= filtered 된 데이터만 가져온다. json2xls_num(filename, title, header, datas); }, /* * Tabulator to Excel * 서브컬럼이 있을때 상위컬럼 대신에 서브 컬럼만 엑셀에 포함된다. * width는 px * params : 타블레이터 테이블, 생성할 엑셀 파일명, 엑셀 안에 들어갈 제목, 엑셀에 입력될 데이터(선택) */ tabu2xls_px: function( tab_table, filename, title, udata ){ //let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined).map(s=>({key:s.field, width:Math.round(((s.minWidth||s.width.replace(/[^0-9]/,''))||100)/6), title:s.title})); //width는 px let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined && !v.noxls) .reduce( (retv,row) => { if( row.columns ){ row.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined && !v.noxls).forEach(crow => { retv.push({ key : crow.field, width: Math.round(((crow.minWidth||crow.width)||100)/6), title: crow.title.replaceAll('
',''), dcss: crow.dcss, }); }); }else{ retv.push({ key : row.field, width: Math.round(((row.minWidth||row.width)||100)/6), title: row.title.replaceAll('
',''), dcss: row.dcss, }); } return retv; }, [] ); let datas = udata || tab_table.getData("active").map(data => header.map(s=>s.key).reduce((ov,cv) => ({...ov, [cv]:(data[cv]||"")}), {})); //"active" <= filtered 된 데이터만 가져온다. json2xls_num(filename, title, header, datas); }, /* * Tabulator to Excel * visible이 false라도 엑셀에 포함됨. * 서브컬럼이 있을때 상위컬럼 대신에 서브 컬럼만 엑셀에 포함된다. * width는 px * params : 타블레이터 테이블, 생성할 엑셀 파일명, 엑셀 안에 들어갈 제목, 엑셀에 입력될 데이터(선택) */ all_tabu2xls_px: function( tab_table, filename, title, udata ){ //let header = tab_table.options.columns.filter(v=>(v.visible != false || v.yesxls) && v.field != undefined).map(s=>({key:s.field, width:Math.round(((s.minWidth||s.width.replace(/[^0-9]/,''))||100)/6), title:s.title})); let header = tab_table.options.columns.filter(v=> v.field != undefined && !v.noxls) .reduce( (retv,row) => { if( row.columns ){ row.columns.filter(v=>v.field != undefined && !v.noxls).forEach(crow => { retv.push({ key : crow.field, width: Math.round(((crow.minWidth||crow.width)||100)/6), title: crow.title.replaceAll('
',''), dcss: crow.dcss, }); }); }else{ retv.push({ key : row.field, width: Math.round(((row.minWidth||row.width)||100)/6), title: row.title.replaceAll('
',''), dcss: row.dcss, }); } return retv; }, [] ); let datas = udata || tab_table.getData("active").map(data => header.map(s=>s.key).reduce((ov,cv) => ({...ov, [cv]:(data[cv]||"")}), {})); //"active" <= filtered 된 데이터만 가져온다. json2xls_num(filename, title, header, datas); }, precs: function( abool,dnum,num ){ num = (typeof num !== "undefined") ? num : dnum; num = abool?num:dnum; return {precision: num}; } // filter_clear: function(table){ // document.getElementById("filter-clear").addEventListener("click", function(){ // document.getElementsByName("filter-clear")filter.value = ""; // valueEl.value = ""; // table.clearFilter(); // }); // } }