admin.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. $(function ()
  2. {
  3. var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
  4. var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
  5. return new bootstrap.Tooltip(tooltipTriggerEl)
  6. });
  7. var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
  8. var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
  9. return new bootstrap.Popover(popoverTriggerEl)
  10. });
  11. $(".date-picker").datepicker({
  12. dayViewHeaderFormat: 'YYYY MMMM',
  13. format: 'YYYY-MM-DD',
  14. useCurrent: false,
  15. dateFormat: 'yy-mm-dd', // 날짜 포맷이다. 보통 yy-mm-dd 를 많이 사용하는것 같다.
  16. prevText: '이전 달', // 마우스 오버시 이전달 텍스트
  17. nextText: '다음 달', // 마우스 오버시 다음달 텍스트
  18. closeText: '닫기', // 닫기 버튼 텍스트 변경
  19. currentText: '오늘', // 오늘 텍스트 변경
  20. monthNames: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'], //한글 캘린더중 월 표시를 위한 부분
  21. monthNamesShort: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'], //한글 캘린더 중 월 표시를 위한 부분
  22. dayNames: ['일', '월', '화', '수', '목', '금', '토'], //한글 캘린더 요일 표시 부분
  23. dayNamesShort: ['일', '월', '화', '수', '목', '금', '토'], //한글 요일 표시 부분
  24. dayNamesMin: ['일', '월', '화', '수', '목', '금', '토'], // 한글 요일 표시 부분
  25. showMonthAfterYear: true, // true : 년 월 false : 월 년 순으로 보여줌
  26. yearSuffix: '년', //
  27. showButtonPanel: true, // 오늘로 가는 버튼과 달력 닫기 버튼 보기 옵션
  28. // showOn: "button", // 이미지로 사용 , both : 엘리먼트와 이미지 동시사용
  29. // buttonImage: "/admin/common/images/btn_cal.gif", // 이미지 주소
  30. // buttonImageOnly: true // 이미지만 보이기
  31. onClose: function(value) {
  32. var date = getOnlyDigit(value);
  33. if(date) {
  34. this.value = moment(date, "YYYY-MM-DD").format("YYYY-MM-DD");
  35. }else{
  36. this.value = "";
  37. }
  38. }
  39. });
  40. // 로그아웃
  41. $(document).on("click", "#logout", function() {
  42. $("#logoutForm").submit();
  43. });
  44. var isSubmit = 0;
  45. var $fAdminWrite = $('#fAdminWrite');
  46. var $formOrigin = $fAdminWrite.serialize().trim();
  47. $(window).on('beforeunload', function() {
  48. if ($('#fAdminWrite').serialize().trim() !== $formOrigin && !isSubmit) {
  49. return '저장하지 않은 정보가 있습니다. 저장하지 않은 상태로 이동하시겠습니까 ?';
  50. }
  51. });
  52. $fAdminWrite.submit(function(){
  53. isSubmit = 1;
  54. });
  55. // 이미지 없으면 기본값으로
  56. var images = document.getElementsByTagName("img");
  57. if (images.length > 0) {
  58. for (var i = 0; i < images.length; i++) {
  59. images[i].onerror = function imgError(Ee) {
  60. e.srcElement.src = BASE_URL + "/images/no_image.png";
  61. e.srcElement.style.width = "60px";
  62. e.srcElement.style.height = "60px";
  63. };
  64. }
  65. }
  66. });
  67. $.validator.setDefaults({ // Bootstrap Required.
  68. ignore: [], // hidden
  69. debug: false,
  70. invalidHandler: function(event, validator) {
  71. return onlyInputUnComma(event.currentTarget);
  72. },
  73. submitHandler: function (form) {
  74. return onlyInputUnComma(form);
  75. },
  76. showErrors: function (errorMap, errorList) {
  77. $.each(this.successList, function (index, value) {
  78. var field = $(value);
  79. if (field.is(':hidden')) {
  80. field = field.parent();
  81. }
  82. if (typeof field.tooltip !== "undefined") { // 3.3.7은 destroy 4.0 이후 dispose
  83. field.tooltip('dispose');
  84. }
  85. });
  86. if (errorList.length <= 0) {
  87. $(".tooltip").tooltip("dispose");
  88. }
  89. $.each(errorList, function (index, value) {
  90. var field = $(value.element);
  91. if (field.is(':hidden')) {
  92. field = field.parent();
  93. }
  94. field.tooltip('dispose').tooltip({
  95. placement: 'bottom',
  96. title: value.message,
  97. trigger: 'manual'
  98. }).tooltip('show');
  99. });
  100. }
  101. });
  102. // 목록 버튼상자
  103. function formSubmit(f, actType, actPage, actDesc)
  104. {
  105. if ($("input:checkbox.list-check-box:checked", f).length < 1) {
  106. alert('자료를 하나 이상 선택하세요.');
  107. return false;
  108. }
  109. // if (actType === 'update' && !confirm('선택한 자료를 정말 수정 하시겠습니까?')) return false;
  110. // if (actType === 'save' && !confirm('선택한 자료를 정말 저장 하시겠습니까?')) return false;
  111. // if (actType === 'delete' && !confirm('선택한 자료를 정말 삭제 하시겠습니까?')) return false;
  112. // if (actType === 'recover' && !confirm('선택한 자료를 정말 복원 하시겠습니까?')) return false;
  113. // if (actType === 'trash' && !confirm('선택한 자료를 정말 휴지통으로 이동하시겠습니까?')) return false;
  114. var msg;
  115. var input = document.createElement('input');
  116. input.setAttribute('type', 'hidden');
  117. input.setAttribute('name', '_method');
  118. switch(actType) {
  119. case 'update' :
  120. msg = '선택한 자료를 정말 수정 하시겠습니까?';
  121. input.setAttribute('value', 'PUT');
  122. break;
  123. case 'save' :
  124. msg = '선택한 자료를 정말 저장 하시겠습니까?';
  125. break;
  126. case 'delete' :
  127. msg = '선택한 자료를 정말 삭제 하시겠습니까?';
  128. input.setAttribute('value', 'DELETE');
  129. break;
  130. case 'recover' :
  131. msg = '선택한 자료를 정말 복원 하시겠습니까?';
  132. break;
  133. case 'trash' :
  134. msg = '선택한 자료를 정말 휴지통으로 이동하시겠습니까?';
  135. break;
  136. case 'action' :
  137. msg = '선택한 자료를 정말 ' + actDesc + '처리 하시겠습니까?';
  138. break;
  139. }
  140. if(!confirm(msg)) {
  141. return false;
  142. }
  143. f.appendChild(input);
  144. f.action = actPage;
  145. f.submit();
  146. }
  147. // 상단으로 스크롤 이동
  148. function moveTopDocument()
  149. {
  150. $('body').scrollTop(0);
  151. }
  152. // 모든 라디오, 체크박스 선택/해제
  153. function allCheckThis(obj){
  154. var that = obj || null;
  155. if(that){
  156. if(that.name){
  157. var checkBoxs = document.getElementsByName(that.name + '[]');
  158. checkBoxs.forEach(function(item, index){
  159. if(item.checked){
  160. item.checked = false;
  161. }else{
  162. item.checked = true;
  163. }
  164. });
  165. }else{ // name이 설정되지 않으면 근처 input 검색하여 처리
  166. var checkBoxs = $(that).parent().parent().find('input');
  167. checkBoxs.each(function(e){
  168. if(this.value != ''){
  169. if(this.checked){
  170. this.checked = false;
  171. }else{
  172. this.checked = true;
  173. }
  174. }
  175. });
  176. }
  177. }
  178. }
  179. // 팝업창 생성
  180. // http://naiyumie.tistory.com/entry/windowopen-windowshowModalDialog-%EC%98%B5%EC%85%98-%EC%9C%88%EB%8F%84%EC%9A%B0-%EC%98%A4%ED%94%88 사용법 참조
  181. function ShowModalWindow(url, winName, width, height, reload){
  182. var reload = (reload || true);
  183. /*
  184. var ua = window.navigator.userAgent;
  185. if(ua.indexOf('MSIE') > 0 || ua.indexOf('Trident') > 0){
  186. aWindow = window.showModalDialog(url, self, 'dialogWidth='+width+'px;dialogHeight='+height+'px;scroll:yes;');
  187. if(!reload){
  188. if(typeof aWindow != "undefined" && aWindow) {
  189. document.location.reload();
  190. }
  191. }
  192. }else{
  193. aWindow = window.open(url, winName, 'menubar=no,status=no,toolbar=no,resizable=no,width='+width+',height='+height+',titlebar=no,scrollbars=no,alwaysRaised=yes,directories=no');
  194. }
  195. */
  196. var aWindow = window.open(url, winName, 'menubar=no,status=no,toolbar=no,resizable=no,width='+width+',height='+height+',titlebar=no,scrollbars=no,alwaysRaised=yes,directories=no');
  197. function bodyLoaded(){
  198. if((aWindow && aWindow.document && aWindow.document.body)){ // Loaded
  199. aWindow.focus();
  200. }else if(aWindow && !aWindow.closed){ // looks like we have a pop up blocker
  201. aWindow.location.reload(true);
  202. aWindow.focus();
  203. }else{
  204. window.setTimeout( function(){ bodyLoaded(); }, 100);
  205. }
  206. }
  207. bodyLoaded();
  208. return aWindow;
  209. }
  210. // 팝업 크기 자동조절
  211. function popupAutoResize() {
  212. var strWidth;
  213. var strHeight;
  214. // innerWidth / innerHeight / outerWidth / outerHeight 지원 브라우저
  215. if ( window.innerWidth && window.innerHeight && window.outerWidth && window.outerHeight ) {
  216. strWidth = parseInt(document.body.children[1].scrollWidth) + (window.outerWidth - window.innerWidth);
  217. strHeight = parseInt(document.body.children[1].scrollHeight) + (window.outerHeight - window.innerHeight);
  218. } else {
  219. var strDocumentWidth = $(document).outerWidth();
  220. var strDocumentHeight = $(document).outerHeight();
  221. window.resizeTo ( strDocumentWidth, strDocumentHeight );
  222. var strMenuWidth = strDocumentWidth - $(window).width();
  223. var strMenuHeight = strDocumentHeight - $(window).height();
  224. strWidth = parseInt(document.body.children[1].scrollWidth) + strMenuWidth;
  225. strHeight = parseInt(document.body.children[1].scrollHeight) + strMenuHeight;
  226. }
  227. window.resizeTo( strWidth, strHeight );
  228. }
  229. // 모달 열기
  230. function initializeModal(element, url)
  231. {
  232. if(typeof(element) == undefined || typeof(url) == undefined){
  233. return false;
  234. }
  235. var modalPopup = $(element);
  236. modalPopup.load(url, function(response, status, xhr){
  237. var msg = null;
  238. switch(status){
  239. case 'error' :
  240. msg = '페이지를 호출 할 수 없습니다.';
  241. break;
  242. case 'timeout' :
  243. msg = '호출 시간이 초과 되었습니다.';
  244. break;
  245. case 'notmodified' :
  246. msg = 'NOT MODIFIED';
  247. break;
  248. case 'parsererror' :
  249. msg = 'PARSE ERROR';
  250. break;
  251. case 'success' :
  252. modalPopup.modal('show');
  253. break;
  254. }
  255. if(msg){
  256. alert(msg);
  257. return false;
  258. }
  259. });
  260. }
  261. // 모달 페이징 처리
  262. function showAjaxCards(obj)
  263. {
  264. var baseUrl = obj.id;
  265. $.ajax({
  266. url: baseUrl,
  267. data: {csrf_hash_name : usCsrfHash, baseUrl : "baseUrl=" + baseUrl},
  268. type: 'POST',
  269. async: false,
  270. success: function (html) {
  271. if(obj.dataset.target){
  272. $(obj.dataset.target).html(html);
  273. }
  274. }
  275. });
  276. }
  277. // 검색기간 지정
  278. function setDateRange(type, so, eo)
  279. {
  280. var w = '';
  281. var m = '';
  282. var y = '';
  283. var d = new Date();
  284. var c = new Date(new Date(new Date().toLocaleDateString()).getTime()+24*60*60*1000-1);
  285. var endDate = $.datepicker.formatDate('yy-mm-dd', d);
  286. $((typeof eo !== "undefined" ? eo : '.s-end-date')).val(endDate);
  287. switch(type) {
  288. case '1d' :
  289. d.setDate(d.getDate() - 1);
  290. break;
  291. case '7d' :
  292. w = d.getDate();
  293. d.setDate(w - 7);
  294. break;
  295. case '15d' :
  296. w = d.getDate();
  297. d.setDate(w - 15);
  298. break;
  299. case '1m' :
  300. m = d.getMonth();
  301. d.setMonth(m - 1);
  302. break;
  303. case '2m' :
  304. m = d.getMonth();
  305. d.setMonth(m - 2);
  306. break;
  307. case '3m' :
  308. m = d.getMonth();
  309. d.setMonth(m - 3);
  310. break;
  311. case '6m' :
  312. m = d.getMonth();
  313. d.setMonth(m - 6);
  314. break;
  315. default :
  316. // y = d.getFullYear();
  317. // d.setFullYear(y - 1);
  318. break;
  319. }
  320. var startDate = d.toISOString().split('T')[0];
  321. $((typeof so !== "undefined" ? so : '.s-start-date')).val(startDate);
  322. }
  323. function byteCheck(txt, byte) {
  324. txt = document.getElementById(txt);
  325. byte = document.getElementById(byte);
  326. var i = 0;
  327. var cnt = 0;
  328. var exceed = 0;
  329. var ch = '';
  330. var maxByte = 2000;
  331. for (i = 0; i < txt.value.length; i++) {
  332. ch = txt.value.charAt(i);
  333. if (escape(ch).length > 4) {
  334. cnt += 2;
  335. } else {
  336. cnt += 1;
  337. }
  338. }
  339. byte.innerHTML = cnt;
  340. if (cnt > maxByte) {
  341. exceed = cnt - maxByte;
  342. alert('메시지 내용은 80바이트를 넘을수 없습니다.\n\n작성하신 메세지 내용은 ' + exceed + 'byte 가 초과되었습니다.\n\n초과된 부분은 자동으로 삭제됩니다.');
  343. var tcnt = 0;
  344. var xcnt = 0;
  345. var tmp = txt.value;
  346. for (i = 0; i < tmp.length; i++) {
  347. ch = tmp.charAt(i);
  348. if (escape(ch).length > 4) {
  349. tcnt += 2;
  350. } else {
  351. tcnt += 1;
  352. }
  353. if (tcnt > 80) {
  354. tmp = tmp.substring(0, i);
  355. break;
  356. } else {
  357. xcnt = tcnt;
  358. }
  359. }
  360. txt.value = tmp;
  361. byte.innerHTML = xcnt;
  362. return true;
  363. }
  364. }
  365. $(document).on('click', '.btn-list-update', function () { // 선택수정
  366. formSubmit(document.f_admin_list, 'update', this.dataset.listUpdateUrl);
  367. });
  368. $(document).on('click', '.btn-list-save', function () { // 선택저장
  369. formSubmit(document.f_admin_list, 'save', this.dataset.listSaveUrl);
  370. });
  371. $(document).on('click', '.btn-list-delete', function () { // 선택삭제
  372. formSubmit(document.f_admin_list, 'delete', this.dataset.listDeleteUrl);
  373. });
  374. $(document).on('click', '.btn-list-trash', function () { // 전체삭제
  375. formSubmit(document.f_admin_list, 'trash', this.dataset.listTrashUrl);
  376. });
  377. $(document).on('click', '.btn-list-recover', function () { // 전체복구
  378. formSubmit(document.f_admin_list, 'recover', this.dataset.listRecoverUrl);
  379. });
  380. $(document).on('click', '.btn-list-action', function () { // 전체복구
  381. formSubmit(document.f_admin_list, 'action', this.dataset.listActionUrl, this.dataset.desc);
  382. });
  383. $(document).on('click', '.btn-write-cancel', function () { // 취소하기
  384. location.href = this.value;
  385. });
  386. $(document).on('click', '.btn-popup-cancel', function () { // 팝업 닫기
  387. window.close();
  388. });
  389. $(document).on('click', '.btn-one-delete', function () {
  390. if (confirm("한번 삭제한 자료는 복구할 방법이 없습니다.\n\n정말 삭제하시겠습니까?")) {
  391. document.location.href = $(this).attr('data-one-delete-url');
  392. return true;
  393. } else {
  394. return false;
  395. }
  396. });
  397. $(document).on('click', '.btn-list-truncate', function () {
  398. if (confirm("휴지통 전체를 비웁니다.\n\n비운 자료는 절대 복구가 불가능합니다. \n\n그래도 진행하시겠습니까?")) {
  399. document.location.href = $(this).attr('data-list-truncate-url');
  400. return true;
  401. } else {
  402. return false;
  403. }
  404. });
  405. $(document).on('click', '.btn-one-recover', function () {
  406. if (confirm('선택한 자료를 정말 복원하시겠습니까?')) {
  407. document.location.href = $(this).attr('data-one-recover-url');
  408. return true;
  409. } else {
  410. return false;
  411. }
  412. });
  413. $(document).on('click', '.btn-one-trash', function () {
  414. if (confirm('선택한 자료를 정말 휴지통으로 이동하시겠습니까?')) {
  415. document.location.href = $(this).attr('data-one-trash-url');
  416. return true;
  417. } else {
  418. return false;
  419. }
  420. });
  421. // 목록에 행 선택시 선택관련 버튼 활성화
  422. $(document).on('click', '.list-check-box, #chkAll', function(e) {
  423. setTimeout(function(){
  424. var $checkedCheckboxes = $('.list-check-box:checked');
  425. var $btnListUpdate = $('.btn-list-update');
  426. var $btnListSelected = $('.btn-list-selected');
  427. if ($checkedCheckboxes.length > 0) {
  428. $btnListUpdate.removeClass('disabled');
  429. $btnListSelected.removeClass('disabled');
  430. } else {
  431. $btnListUpdate.addClass('disabled');
  432. $btnListSelected.addClass('disabled');
  433. }
  434. }, 300);
  435. });
  436. // 목록 전체선택
  437. $(document).on('click', '#chkAll', function(e) {
  438. var chk = document.getElementsByClassName('list-check-box');
  439. for (var i = 0; i < chk.length; i++){
  440. if(e.target.getAttribute('form') == chk[i].getAttribute('form')){
  441. chk[i].checked = this.checked;
  442. }
  443. }
  444. if (this.checked) {
  445. $('[data-action]').prop('disabled', false);
  446. } else {
  447. $('[data-action]').prop('disabled', true);
  448. }
  449. });
  450. // 이미지 크게 보기
  451. $(document).on('click', '.view-full-image', function() {
  452. childWin[childWin.length] = window.open( BASE_URL + '/helpTool/viewImage?imgUrl=' + encodeURIComponent($(this).attr('data-origin-image-url')), 'large_image', 'location=yes,links=no,toolbar=no,top=10,left=10,width=10,height=10,resizable=yes,scrollbars=no,status=no');
  453. return false;
  454. });
  455. // 부트스트랩 모달 열기
  456. $(document).on("change click", ".modal-popup", function(e)
  457. {
  458. if(typeof (this.dataset.href) != undefined && this.dataset.href != '')
  459. {
  460. var index = $('.modal-popup').index(this);
  461. var href = this.dataset.href;
  462. if (params('index', href) != 1) {
  463. if (href.indexOf('?') != -1) {
  464. // this.dataset.href = href + '&index=' + index;
  465. } else {
  466. this.dataset.href = href + '/?index=' + index;
  467. }
  468. }
  469. initializeModal('#modal-popup', this.dataset.href);
  470. }
  471. });
  472. // 체크박스 하나만 선택하기
  473. $(document).on('change', '.only-one-checked', function(e){
  474. if(this.checked){
  475. var obj = document.getElementsByName(e.target.name);
  476. for(var i = 0; i < obj.length; i++){
  477. if(obj[i].value != e.target.value){
  478. obj[i].checked = false;
  479. }
  480. }
  481. }
  482. });
  483. // 데이터 테이블
  484. if ($.isFunction($.fn.dataTable)) {
  485. $.extend(true, $.fn.dataTable.defaults, {
  486. columnDefs: [
  487. {
  488. targets: 'actions',
  489. className: 'actions',
  490. searchable: false,
  491. sortable: false
  492. }
  493. ],
  494. lengthMenu: [5, 10, 25, 50, 100, 250, 500],
  495. pageLength: 25,
  496. language: {
  497. search: '',
  498. searchPlaceholder: 'Search'
  499. },
  500. processing: true,
  501. stateSave: true,
  502. stateDuration: 0,
  503. responsive: true,
  504. stateSaveParams: function (settings, data) {
  505. data.search.search = '';
  506. data.start = 0;
  507. },
  508. stateSaveCallback: function (settings, data) {
  509. localStorage.setItem($(this).attr('id'), JSON.stringify(data));
  510. },
  511. stateLoadCallback: function () {
  512. return JSON.parse(localStorage.getItem($(this).attr('id')));
  513. },
  514. initComplete: function (settings, json) {
  515. var self = this.api();
  516. var filter_input = $('#' + settings.nTable.id + '_filter input').unbind();
  517. var search_button = $('<button type="button" class="btn btn-link btn-sm btn-icon ms-2 mb-1" data-bs-toggle="tooltip" title="Search"><i class="fa fa-fw fa-search"></i></button>').click(function () {
  518. self.search(filter_input.val()).draw();
  519. });
  520. var reset_button = $('<button type="button" class="btn btn-link btn-sm btn-icon mb-1" data-bs-toggle="tooltip" title="Reset"><i class="fa fa-fw fa-undo"></i></button>').click(function () {
  521. filter_input.val('');
  522. search_button.click();
  523. });
  524. $(document).keypress(function (event) {
  525. if (event.which === 13) {
  526. search_button.click();
  527. }
  528. });
  529. $('#' + settings.nTable.id + '_filter').append(search_button, reset_button);
  530. }
  531. });
  532. }
  533. // 체크박스 클릭 시 해당 컨텐츠 내용을 숨김/표시 처리
  534. $(document).on("change", ".content-collapse", function(e){
  535. var target = e.target.dataset.target;
  536. var content = $("#" + target);
  537. if(this.checked){
  538. content.show();
  539. }else{
  540. content.hide();
  541. }
  542. });