PageSourceSearch

https://kist.re.kr/_custom/kist/resource/js/board.common.js?60725

js kist.re.kr collected 2026-10-02 11:31:59 UTC 29,121 bytes, 1,159 lines download raw bytes

1if(!window.App) {
2	App = {};
3}
4if(!App.board){
5	App.board = {};
6}
7
8$(function() {
9
10	var boardApp = new App.board.Common();
11
12	boardApp.init();
13
14});
15
16App.board.Common = function() {
17
18	var self;
19
20
21	if(locale == 'ko') {
22	    $.datepicker.setDefaults({
23	        dateFormat: 'yymmdd',
24	        prevText: '이전 달',
25	        nextText: '다음 달',
26	        monthNames: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
27	        monthNamesShort: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
28	        dayNames: ['일', '월', '화', '수', '목', '금', '토'],
29	        dayNamesShort: ['일', '월', '화', '수', '목', '금', '토'],
30	        dayNamesMin: ['일', '월', '화', '수', '목', '금', '토'],
31	        showMonthAfterYear: true,
32	        yearSuffix: '년'
33	    });
34	}
35
36	return {
37		init: function() {
38			self = this;
39
40			// selectBox  검색, 쓰기 셀렉트박스 바인딩
41			self.selectBoxBind();
42
43			// sns 로 보내기 버튼 이벤트 바인딩
44			self.bindSendSnsBtn();
45
46			// 에디터 바인딩
47			self.bindEditor();
48
49			// 추천 반대 이벤트 바인딩
50			self.clickRecommend();
51
52			// 2차 분류 셀렉트 박스 동적 로딩
53			// self.loadCategory2Depth();
54
55			// 캘린더 datepicker, class 에 calendar 가 있으면 datepicker 생성
56			self.datePicker();
57
58			// 이메일 도메인 선택
59			self.bindEmailDomain();
60
61			// 공지 체크
62			self.noticeCheck();
63
64			// 공지일때 정렬번호 및 문구 여부 체크
65			self.orderNoUserCheck();
66
67			// 첨부 파일 버튼 바인딩
68			self.initAttachButton();
69
70			// 쓰기폼 유효성 체크
71			self.formValid();
72
73			// 답글 쓰기폼 유효성 체크
74			self.replyfromValid();
75
76			// 비밀번호 입력 유효성 체크
77			self.bindPassword();
78
79			// 기타 바인딩
80			self.bindEtc();
81
82			// 플래시 맵이 존재하면 메시지 출력
83			self.showFlashMessage();
84
85			// tag
86			self.tagInput();
87
88			// captcha
89			self.bindCaptcha();
90
91			// faq 클릭
92			self.faqOpen();
93
94			// 썸네일 이미지 첨부 대체텍스트 필수
95			self.thumbAltCheck();
96
97			// 게시판 복사
98			self.popBoardList();
99
100			//FAQ 답변 toggle 메소드
101			self.toggleText();
102
103			//게시글 개수
104			self.listLimit();
105
106			// 입력형식 이벤트
107			self.bindinputEvent();
108		},
109		thumbAltCheck : function(){
110
111			$('.thumb').change(function(){
112
113				var $this = $(this), val = $this.val(), alt = $this.parent().siblings().children('.file-alt'), isImg = /\.(png|bmp|jpg|gif|jpeg)$/i.test(val);
114
115				if( alt.length > 0 ) {
116
117					if(val !== '' && isImg ) {
118						if ( alt.val() == '' ){
119							alt.addClass('jwvalid-must');
120						}
121					} else {
122						alt.removeClass('jwvalid-must');
123					}
124
125				}
126
127			});
128
129		},
130		faqOpen : function(){
131
132
133			self = this;
134      		$box = $(".board-faq-list li");
135
136      		$box.each(function(){
137
138	        		$(this).find("a.faqTitle").click(function(){
139
140	        		  if($(this).parent().siblings(".board-faq-answer").is(":hidden")){
141				        $(this).parent().siblings(".board-faq-answer").slideDown();
142				        $(this).addClass("faq-close");
143			      } else if($(this).parent().siblings(".board-faq-answer").is(":visible")){
144				        $(this).parent().siblings(".board-faq-answer").slideUp();
145				        $(this).removeClass("faq-close");
146			      }
147				  return false;
148
149	        		});
150
151      		});
152
153		},
154
155		//FAQ 답변 toggle 메소드
156		toggleText: function() {
157			$('.faq .toggleTitle').click(function( event ) {
158				var $this = $(this);
159				$this.closest('.b-quest-box').next('.b-ans-box').slideToggle(0);
160				return false;
161			});
162		},
163
164		// 셀렉트 박스
165		selectBoxBind : function(){
166
167			// 커스텀 셀렉트박스외 영역 클릭시 감춤
168			$(document).on('click',':not(.b-sel-box)',function( e ) {
169
170				var parentSelectBox = $(e.target).closest('.b-sel-box');
171
172				if(parentSelectBox.length == 0) {
173					// 셀렉트 박스 외의 영역 클릭시  모든 셀렉트 박스 감춤
174					$('.b-sel-box ul').hide();
175				} else {
176					// 셀렉트 박스 안을 클릭시 자신의 셀렉트박스 외의 셀렉트 박스 감춤
177					var ul = parentSelectBox.find('ul').get(0);
178					$('.b-sel-box ul').each(function() {
179						if(this !== ul) {
180							$(this).hide();
181						}
182					});
183				}
184			});
185
186			// 커스텀 셀렉트박스 option 클릭시
187			$(document).on("click",".b-sel-box .select-option",function(e) {
188
189				e.preventDefault();
190
191				var value    = $(this).attr("data-value");
192				var text    = $(this).text();
193
194				var $container =  $(this).closest('.b-sel-box');
195
196				$container.find('input[type=hidden]').val(value);
197
198				// 선택된 option 텍스트 표시
199				$container.find("a.b-sel-title").text(text);
200
201				$container.find('li').removeClass('selected');
202
203				if(value !== '' && value !== undefined) {
204					$(this).parent('li').addClass('selected');
205				}
206
207				if(!$container.is('.cate-box')) {
208					return;
209				}
210
211				// 카테고리일 경우
212				// 하위 뎁스가 존재하면
213
214				// 1. 하위의 모든 카테고리 초기화
215				var cateBox = $container;
216				while((cateBox = cateBox.next('.cate-box')).length > 0) {
217					cateBox.find('input[data-category-name]').val('');
218					cateBox.find('a.b-sel-title').text( cateBox.find('label').text() );
219					cateBox.find('li:not(:first)').remove();
220					cateBox.addClass('disabled');
221				}
222
223				// 하위 뎁스의 옵션 추가
224				var cateBox = $container.next('.cate-box');
225				if(cateBox.length > 0) {
226
227					var children = findChildren(value);
228
229					if(children.length > 0) {
230
231						cateBox.removeClass('disabled');
232						var $ul = cateBox.find('ul');
233						for(var i=0; i<children.length; i++) {
234							var item = children[i];
235							$ul.append('<li><a href="#category" class="select-option" data-value="' + item.categoryId + '" title="' + item.categoryNm + '">
235'+ item.categoryNm +'</a></li>');
236
237						}
238
239					}
240				}
241
242
243			});
244
245			// 커스텀셀렉트 박스를 클릭하면 리스트 보임/감춤
246  	        $(document).on('click','.b-sel-box',function(){
247  	        	var $box = $(this);
248  	        	// 비활성이면 클릭 금지
249  	        	if($box.is('.disabled')) {
250  	        		return false;
251  	        	}
252
253				$('.b-sel-box').css('z-index',0);
254  	        	$box.css({zIndex: $box.find("ul").is(":hidden")? 10: 0  });
255		        $box.find("ul").toggle();
256
257	        });
258
259	        // 일반 카테고리 셀렉트박스를 클릭하면 하위 카테고리 셀렉트박스 옵션 변경
260	        $('select[data-category-name]').change(function() {
261
262	        	var $this = $(this), self = this, value = $this.val();
263
264				// 1. 하위의 모든 카테고리 초기화
265	        	var nextsibling = false, $next;
266	        	$('select[data-category-name]').each(function() {
267	        		if(nextsibling && !$next) {
268	        			$next = $(this); // 다음 카테고리
269	        		}
270	        		if(nextsibling) {
271						$(this).val('');
272						$(this).find('option:not(:first)').remove();
273						$(this).attr('disabled','disabled');
274	        		}
275	        		if(self == this) nextsibling = true;
276	        	});
277
278	        	// 하위 카테고리의 옵션 추가
279				if($next) {
280
281					var children = findChildren(value);
282
283					if(children.length > 0) {
284
285						$next.removeAttr('disabled');
286						for(var i=0; i<children.length; i++) {
287							var item = children[i];
288							$next.append($('<option>',{value:item.categoryId,text:item.categoryNm}));
289						}
290
291					}
292				}
293
294	        });
295
296	        // 트리에서 찾기
297	        function findChildren( categoryId ) {
298	        	var stack = [categoryItems];
299	        	while(stack.length !== 0) {
300	        		var items = stack.pop();
301	        		for(var i=0; i<items.length; i++) {
302	        			var item = items[i];
303	        			if(item.categoryId == categoryId) {
304	        				return item.children || [];
305	        				break;
306	        			}
307	        			if((item.children || []).length > 0) {
308	        				stack.push( item.children );
309	        			}
310	        		}
311	        	}
312	        	return [];
313
314	        }
315
316
317			// 커스텀 셀렉트박스 초기값 설정
318			function init( $box ) {
319
320				var val = $box.find('input[type=hidden]').val(), text;
321				$box.find('[data-value]').each(function( index, item ) {
322					var $item = $(item);
323					if(index == 0 && !$item.attr('data-value')) {
324						text = $item.text();
325					}
326					if($item.attr('data-value') == val) {
327						if(val !== '' && val !== undefined) {
328							$item.parent().addClass('selected');
329						}
330						text = $item.text();
331						return false;
332					}
333				});
334				$box.find("a.b-sel-title").text(text);
335
336			}
337
338			// 커스텀 셀렉트박스 초기값 적용
339  	        $(".b-sel-box").each(function(){
340  	        	var $box = $(this);
341				init( $box );
342
343				if($box.find('li').length <= 1) {
344					$box.addClass('disabled');
345				}
346
347	        });
348
349	        // 검색 클릭시 name 을 마지막 카테고리 셀렉트박스에 적용한다. (검색 : srCategoryId, 쓰기 : categoryId)
350	        $('form').filter(function() {
351
352	        	return /get/i.test($(this).attr('method'));
353
354	        }).submit(function() {
355				if($("input[name=mode]:checked").val() == "patent" && $("input[name=type]").val() == "article"){
356					$("input[name=type]").val("1");
357				}
358
359	        	var cateList = $('[data-category-name]');
360	        	cateList.removeAttr('name');
361	        	for(var i=cateList.length-1; i>=0; i--) {
362
363	        		var $cate = $(cateList[i]);
364	        		var val = $cate.val();
365	        		if(val !== '' && val !== undefined) {
366	        			$cate.attr('name',$cate.attr('data-category-name'));
367	        			break;
368	        		}
369	        	}
370
371
372	        });
373
374	        // 저장 클릭시 name 을 마지막 카테고리 셀렉트박스에 적용한다. (검색 : srCategoryId, 쓰기 : categoryId)
375	        $('form[name=writeForm]').submit(function() {
376				console.log("submit this",$(this));
377	        	var cateList = $('[data-category-name]');
378	        	cateList.removeAttr('name');
379	        	cateList.removeClass('jwvalid-must');
380
381	        	// 커스텀 셀렉트 박스
382	        	var $items = $('.b-sel-box.cate-box');
383	        	for(var i=$items.length-1; i>=0; i--) {
384	        		var $box = $($items[i]);
385	        		if($box.find('li').length >
385 1) { // 리스트가 존재하는 셀렉트박스에 name 과 jwvalid-must 를 넣어주어서 필수체크와 서버 전송값으로 지정
386	        			var $input = $box.find('input[data-category-name]');
387	        			// data-valid-must 어트리뷰트가 있는경우만 jwvalid-must 클래수 추가
388	        			if($input.is('[data-valid-must]')) {
389	        				$input.addClass('jwvalid-must');
390	        			}
391	        			$input.attr('name',$input.attr('data-category-name'));
392	        			break;
393	        		}
394	        	}
395
396	        	// 일반 셀렉트 박스
397	        	var $items = $('select[data-category-name]');
398	        	for(var i=$items.length-1; i>=0; i--) {
399	        		var $box = $($items[i]);
400	        		if($box.find('option').length > 1) { // 리스트가 존재하는 셀렉트박스에 name 과 jwvalid-must 를 넣어주어서 필수체크와 서버 전송값으로 지정
401	        			if($box.is('[data-valid-must]')) {
402	        				$box.addClass('jwvalid-must');
403	        			}
404	        			$box.attr('name',$box.attr('data-category-name'));
405	        			break;
406	        		}
407	        	}
408
409
410	        });
411
412
413
414		},
415		tagInput: function() {
416			if($('input.tag').length == 0) {
417				return;
418			}
419			$('input.tag').tagit({
420				// 자동 완성 ajax
421				allowSpaces: true,
422				autocomplete: {
423					source: function( search, showChoices ) {
424					    $.ajax({
425							dataType: 'json',
426					        url: ctx+'/cms/plugin/tag/searchTag.do',
427					        data: {
428					            'tag': search.term,
429					            'limit': 10
430					        },
431					        cache: false,
432					        success: function( json ) {
433					        	if(json.success) {
434					        		showChoices(json.items);
435					        	}
436					        }
437					    });
438					}
439				}
440			});
441
442			$('.ui-autocomplete-input').val(" + TAG");
443			$('.ui-autocomplete-input').autosizeInput();
444
445			$('.ui-autocomplete-input').focus(function(){
446					$(this).val('');
447					$(this).data('autosizeInputInstance').update();
448					$(this).css('color','#555555');
449			});
450
451			$('.ui-autocomplete-input').blur(function(){
452					$(this).val(' + TAG');
453					$(this).data('autosizeInputInstance').update();
454					$(this).css('color','blue');
455			});
456
457		},
458		bindEtc: function() {
459
460			// 본인글만 확인가능 메시지
461			$('a[href="#secureArticle"]').click(function(e) {
462				e.preventDefault();
463				toastr.error($m('본인만조회가능'));
464
465			});
466
467			// 게시물 삭제버튼 바인딩
468			$('.attch-del-check').click(function() {
469				var isDel = this.checked;
470				if(isDel) {
471					//$(this).parent('li').addClass('deleted');
472					$(this).siblings('.del').addClass('deleted');
473				} else {
474					//$(this).parent('li').removeClass('deleted');
475					$(this).siblings('.del').removeClass('deleted');
476				}
477
478			});
479
480			// 처리 전 질문
481			$('a[data-confirm]:not(.adm)').click(function() {
482
483				if(confirm($m($(this).attr('data-confirm')))) {
484					return true;
485				}
486
487				return false;
488
489			});
490
491
492			// 처리 전 질문
493			/*$('a[data-confirm]').not('.adm').not('.college_schedule').click(function() {
494
495				if(confirm($m($(this).attr('data-confirm')))) {
496					return true;
497				}
498
499				return false;
500
501			});
502			*/
503
504		},
505		/**
506		 * 이메일 도메인 선택
507		 */
508		bindEmailDomain: function() {
509
510			$('select.email-domain').each( function() {
511				self.changeDomain( $(this) )
512			});
513
514			$('select.email-domain').change( function() {
515				self.changeDomain( $(this) );
516			});
517
518		},
519		changeDomain: function( $select ) {
520
521			var val  =  $select.val(), $input = $select.prev('input');
522
523			if(val) {
524				$input.val(val);
525			}
526
527			if(!val) {
528				// 도메인 입력필드를 텍스트 로변경
529				$input.attr('type','text');
530				//setTimeout( function() {$input.focus();},100 );
531
532			} else {
533				// 도메인 입력필드를 히든으로변경
534				$input.attr('type','hidden');
535			}
536
537		},
538		/**
539		 * 플래시 맵이 존재하면 메시지 출력
540		 */
541		showFlashMessage: function() {
542
543			if( $('.flash-map').length > 0 ) {
544
545				$('.flash-map').each(function() {
546					// 이전 스크립트에서 호출 했으면 스킵
547					if(!$(this).data('flash-map')) {
548						showAlert($(this).text());
549						$(this).data('flash-map',true)
550					}
551
552				});
553
554			}
555
556		},
557		/**
558		 * sns 로 보내기 버튼 이벤트
559		 */
560		bindSendSnsBtn: function () {
561
562			$('.lsns-lnk-btn').click(function() {
563				var $this = $(this);
564				jwxe_popupWindow( $this.attr('href'), $this.attr('data-width'), $this.attr('data-height'), $this.attr('data-sns'), "yes", "yes");
565				return false;
566			});
567
568		},
569		/**
570		 * 에디터 바인딩
571		 */
572		bindEditor: function() {
573
574			$('textarea.editor').each( function( index ) {
575
576				var height = $(this).attr('data-editor-height') || 300;
577
578				var editor = initEditor({
579					height: height,
580					index: index,
581					$textarea: $(this),
582					el: this,
583					isTemplateEditor: /T|A/.test($('.board form input[name=htmlYn]').val())
584				});
585				$(this).data('editor', editor);
586
587
588				/*
589				var editorHeight = $(this).attr('data-editor-height') || 200;
590				var editor = initEditor(this , resPath + 'js/ck_config.js', editorHeight);
591				// 에디터를 textarea 저장소에 담아 둔다.
592				$(this).data('editor', editor);
593				*/
594
595
596			});
597
598
599		},
600		/**
601		 * 2차 분류를 동적으로 로딩 한다.
602		 */
603		loadCategory2Depth: function() {
604
605			if($('#category2').length ==0) {
606				return;
607			}
608
609			$('#category1').change(function() {
610
611					var $cate1 = $(this), $cate2 = $('#category2'), value = $cate1.val();
612
613					$cate2.val('');
614					//selectBox bug fix
615					$cate2.next('a').find('span.ui-selectBox-label').text( $cate2.find('option:eq(0)').text() );
616
617					if(!value) {
618						$cate2.find('option:not(:eq(0))').remove();
619						return;
620					}
621
622					//$cate2.parent().spinStart();
623
624					$.ajax({
625						url: ctx+'/app/board/board.do',
626						cache: false,
627						data: {
628							mode: 'loadSubCategory',
629							mstCategoryId: value
630						},
631						dataType: 'json',
632						error: function() {
633							$cate2.parent().spinStop();
634						},
635						success: function(data) {
636
637							$cate2.parent().spinStop();
638
639							if(typeof(data.success) != 'undefined' && data.success == true) {
640
641								$cate2.find('option:not(:eq(0))').remove();
642
643								for(var i=0; i<data.items.length; i++) {
644
645									$cate2.append($('<option>',{
646										value: data.items[i].id,
647										text: data.items[i].categoryNm
648									}));
649
650
651								}
652
653
654							}
655						}
656
657					});
658
659			});
660
661
662		},
663		/**
664		 * 폼 유효성 검증
665		 */
666		formValid: function() {
667
668			// 에디터 내용을 textarea 로 옮긴다.
669			$('form[name=writeForm]').submit(function(e) {
670
671				console.log("this1",$(this));
672				console.log("thisData1",$(this).data());
673
674
675				/**
676				if($(this).data('complete')) {
677					console.log("this2",$(this));
678					console.log("thisData2",$(this).data());
679					alert('서버로 전송중 입니다.');
680					e.stopImmediatePropagation();
681					return false;
682				}
683				*/
684
685				$('textarea.editor').each(function() {
686
687					var editor = $(this).data('editor');
688
689					$(this).val( editor.getData() );
690
691				});
692
693				// 개인정보 보호 동의
694				if($('input[name=infoProtectYn]').length > 0) {
695					if($('input[name=infoProtectYn]:checked').val() !== 'Y') {
696						alert('개인정보 보호 동의해 체크해야만 등록이 가능합니다.')
697						return false;
698					}
699				}
700				if(!submit()) {
701					return false;
702				} else {
703					$(this).data('complete',true);
704					return true;
705				}
706			});
707
708			$('form[name=writeForm]').formValid({
709				beforeSubmit: self.validate
710			});
711
712			// $('form[name=writeForm]').submit(function(e) {
713            //     $(this).data('complete',true);
714			// });
715
716			/*
717			$('form[name=writeForm]').formValid({
718				title: [
719					{title: 'writer',	text: $m('writer')	},
720					{title: 'emailid',	text: '이메일 아이디'	},
721					{title: 'emaildomain',	text: '이메일 도메인'	},
722					{title: 'cate1', text: '1차분류'},
723					{title: 'cate2', text: '2차분류'},
724					{title: 'category', text: $m('category')},
725					{title: 'summary', text: '요약글'},
726					{title: 'alt', text: '이미지 대체텍스트'},
727					{title: 'youtobe', text: '동영상'},
728					{title: 'img', text: '이미지'}
729
730
731				],
732				alertFunction: toastr.error,
733				beforeSubmit: self.validate
734			});
735			*/
736		},
737
738		replyfromValid : function(){
739
740			// 에디터 내용을 textarea 로 옮긴다.
741			$('form[name=reply-write]').submit(function() {
742
743				if($(this).data('complete')) {
744					alert('서버로 전송중 입니다.');
745					e.stopImmediatePropagation();
746					return false;
747				}
748
749
750				$('textarea.editor').each(function() {
751
752					var editor = $(this).data('editor');
753
754					$(this).val( editor.getData() );
755
756				});
757
758				return true;
759
760			});
761
762			$('form[name=reply-write]').submit(function(e) {
763                $(this).data('complete',true);
764			});
765
766
767		},
768
769		/**
770		 * 폼 검증 후 세부 검증
771		 */
772		validate: function() {
773
774			// 상단공지 옵션이 있을경우
775			if($('#topNoticeYn').length > 0) {
776
777				var checked = $('#topNoticeYn').get(0).checked;
778
779				// 공지에 체크가 되어있지 않으면 시작일 종료일을 지운다.
780				if(!checked) {
781					$('#noticeStartDt').val(''); $('#noticeEndDt').val('');
782				} else {
783					if(!$('#noticeStartDt').val() || !$('#noticeEndDt').val()) { // 기간 선택이 없으면 유효성 오류
784						toastr.error('공지 기간을 선택 해 주세요');
785						return false;
786					}
787					if($('#noticeStartDt').val() > $('#noticeEndDt').val()) {
788						toastr.error('공지 시작일이 종료일 보다 클 수 없습니다.');
789						return false;
790					}
791				}
792
793			}
794
795
796			//신청 게시판
797			//총 방문인원이 30명을 넘는 경우 return false한다
798			if(boardTy == 'calendar_register'){
799				var totalCnt = $('[data-people=total]').val();
800
801				if(totalCnt > 30){
802					alert('장소가 협소한 관계로 15인 이상 30인 이하 단체 (담당선생님 인솔 필요)만 견학 신청을 받고 있으며, 개인견학은 따로 신청받지 않습니다.');
803					return false;
804				}
805			}
806
807			return true;
808		},
809		/**
810		 * 공지 여부 체크
811		 */
812		noticeCheck: function() {
813
814			if($('#topNoticeYn').length == 0) {
815				return;
816			}
817
818			var toggle = function() {
819				var checked = $('#topNoticeYn').get(0).checked;
820				if(checked) {
821					/*disabled는 값이 전송되지 않으므로 readonly로 수정*/
822					$('#noticeStartDt').removeAttr('readonly').removeClass('dark');
823					$('#noticeEndDt').removeAttr('readonly').removeClass('dark');
824				} else {
825					$('#noticeStartDt').attr('readonly','readonly').addClass('dark').val('');
826					$('#noticeEndDt').attr('readonly','readonly').addClass('dark').val('');
827				}
828
829			}
830
831			toggle();
832
833			//공지 여부를 체크하면 기간 텍스트 박스를 활성/비활성한다.
834			$('#topNoticeYn').click( toggle );
835
836
837		},
838		/**
839		 * 공지일때 정렬 번호 및 문구 여부 체크
840		 */
841		orderNoUserCheck: function() {
842
843			if($('#topNoticeYn').length == 0) {
844				return;
845			}
846
847			var toggle = function() {
848				var checked = $('#topNoticeYn').get(0).checked;
849				if(checked) {
850					$('#order-no-user').attr('readonly','readonly').addClass('dark').val('');
851					$('.orderNoUserInfo').css('display','none');
852				} else {
853					$('#order-no-user').removeAttr('readonly').removeClass('dark');
854					$('.orderNoUserInfo').css('display','initial');
855				}
856
857			}
858
859			toggle();
860
861			//공지 여부를 체크하면 정렬번호 텍스트 박스 및 문구를 활성/비활성한다.
862			$('#topNoticeYn').click( toggle );
863
864
865		},
866		datePicker: function() {
867
868			$('input.calendar').datepicker({
869				dateFormat: 'yy-mm-dd',
870				showMonthAfterYear: true,
871				buttonImageOnly: true,
872				changeMonth: true,
873				changeYear: true
874			});
875
876		},
877
878		changeAttachCount: function( cnt ) {
879
880			$('.file-list').each(function( index ) {
881				$(this).css('display', cnt > index ? 'block':'none') ;
882			});
883
884		},
885		/**
886		 * 첨부 파일 버튼 바인딩
887		 */
888		initAttachButton: function() {
889
890			// 첨부 갯수 선택
891			self.changeAttachCount( $('#attachCnt').val() );
892			$('#attachCnt').change(function() {
893
894				self.changeAttachCount( $(this).val() );
895
896			});
897
898			// 첨부 파일이 선택되면 텍스트에 뿌려준다.
899			$('input[type=file]').change(function() {
900
901				var $this = $(this);
902
903				$this.prev('.file-prev-view').val( $this.val() );
904
905			});
906
907			// 찾아보기 버튼 focus
908			var $fileBox = $('.b-file-box.file-list');
909			$.each($fileBox, function(idx){
910				var $this = $fileBox.eq(idx)
911				, $btnUpload = $this.find('[type="file"]')
912				, $label = $this.find('.b-file-btn');
913
914				$btnUpload.on('focusin focusout', function(e) {
915					e.type == 'focusin' ?
916							$label.addClass('file-focus') : $label.removeClass('file-focus');
917				});
918			});
919
920		},
921		bindPassword: function() {
922
923			$('form[name=password]').formValid({
924				alertFunction: toastr.error
925			});
926
927		},
928
929		/**
930		 * 추천 반대 이벤트 바인딩
931		 */
932		clickRecommend: function() {
933
934			$('.recommend').click(function(e) {
935
936				var $this = $(this), articleNo = $('input[name=articleNo]').val(), mode = $this.attr('data-type');
937
938				e.preventDefault();
939
940
941				$.ajax({
942					url:'/_common/jsp/recommend/set_point.jsp?dc='+new Date().getTime(),
943					data: {
944						mode: mode,
945						article_no: articleNo
946					},
947					dataType: 'json',
948					success: function(data) {
949						if(typeof(data.success) != 'undefined') {
950							if (data.success == true) {
951				  			//$this.html('<em>' + data.cnt + '</em>');
952							$this.parent().find(".goodCnt").text( data.cnt );
953							$this.removeClass("board-like").addClass("board-like-active");
954				  		} else {
955								if(data.msg) {
956									//alert(data.msg);
957									alert("이미 좋아요 를 클릭한 게시글 입니다.");
958								}
959							}
960						}
961					}
962				});
963
964			});
965
966		},
967
968		/**
969		 * 게시글 등록시 캡챠
970		 */
971		bindCaptcha : function() {
972
973			rand = Math.random();
974			$('#jwxe_catpcha').html('<img src="' + ctx + '/cms/CaptCha.jsp?rand=' + rand + '" style="float:left;" alt="자동 가입 방지 CAPTCHA" />');
975
976
977
978			$('#captcha_reLoad').click(function(){ self.bindCaptcha()  }); //새로고침버튼에 클릭이벤트 등록
979			$('#captcha_soundOn').click(function(){ self.bindAudioCapcha(0); });	//음성듣기버튼에 클릭이벤트 등록
980			$('#captcha_soundOnKor').click(function(){ self.bindAudioCapcha(1); }); //한글음성듣기 버튼에 클릭이벤트 등록
981
982		},
983
984		/**
985		 *  캡챠 오디오 요청
986		 */
987		bindAudioCapcha : function(type){
988
989			var kor = (type > 0) ? "lan=kor":"";
990			var uAgent = navigator.userAgent;
991			var soundUrl = ctx+'/cms/captcha/audio.do?' + kor + '&ans=y';
992
993			if (uAgent.indexOf('Trident') > -1 || uAgent.indexOf('MSIE') > -1) {
994				winPlayer(soundUrl+'&agent=msie');
995			} else if (!!document.createElement('audio').canPlayType) {
996				try { new Audio(soundUrl).play(); } catch(e) { winPlayer(soundUrl); }
997			} else window.open(soundUrl, '', 'width=1,height=1');
998
999
1000		},
1001		popBoardList : function(){
1002			$('#copy').click(function(){
1003				jwxe_popupWindow( '/_custom/' + clientId + '/_common/boardList/app.do?boardTy=' + boardTy + '&boardNo=' + boardNo + '&siteId=' + siteId, "1200", "800", true, true);
1004			});
1005		},
1006
1007		//게시글 개수
1008		listLimit : function(){
1009
1010			$("[data-btn=limit]").click(function(){
1011				var selected = $("[data-label=limit]").text().replace( /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g, '' );
1012				var queryString = $("[data-label=limit]").data("query");
1013				var url = '';
1014				if(queryString.indexOf('articleLimit') != -1){
1015					url = queryString.replace(/articleLimit=([^&amp;#]*)/g, 'articleLimit=' + $.trim(selected) );
1016				}else{
1017					url = queryString + '&articleLimit=' + $.trim(selected);
1018				}
1019				location.href = "?" + url;
1020
1021			});
1022
1023			 $.urlParam = function(name){
1024	            var results = new RegExp('[\?&amp;]' + name + '=([^&amp;#]*)').exec(window.location.href);
1025	            return results[1] || 0;
1026	        }
1027
1028
1029		},
1030
1031		phoneNumber : function(value) {
1032			if (!value) {
1033				return "";
1034			}
1035
1036			value = value.replace(/[^0-9]/g, "");
1037
1038			let result = [];
1039			let restNumber = "";
1040
1041			// 지역번호와 나머지 번호로 나누기
1042			if (value.startsWith("02")) {
1043				// 서울 02 지역번호
1044				result.push(value.substr(0, 2));
1045				restNumber = value.substring(2);
1046			} else if (value.startsWith("1")) {
1047				// 지역 번호가 없는 경우
1048				// 1xxx-yyyy
1049				restNumber = value;
1050			} else {
1051				// 나머지 3자리 지역번호
1052				// 0xx-yyyy-zzzz
1053				result.push(value.substr(0, 3));
1054				restNumber = value.substring(3);
1055			}
1056
1057			if (restNumber.length === 7) {
1058				// 7자리만 남았을 때는 xxx-yyyy
1059				result.push(restNumber.substring(0, 3));
1060				result.push(restNumber.substring(3));
1061			} else {
1062				result.push(restNumber.substring(0, 4));
1063				result.push(restNumber.substring(4));
1064			}
1065
1066			return result.filter((val) => val).join("-");
1067		},
1068
1069		telNumber : function(value) {
1070			return value.replace(/[^0-9]/g, "").replace(/(^02|^0505|^1[0-9]{3}|^0[0-9]{2})([0-9]+)?([0-9]{4})$/,"$1-$2-$3").replace("--", "-");
1071		},
1072
1073		setIntOnly : function(value) {
1074			value = value.replace(/[^0-9]/gi, '');
1075			return parseInt(value) == 0 ? '' : value;
1076		},
1077
1078
1079		bindinputEvent : function() {
1080			$('.jwvalid-num').on('keyup', function() {
1081				$(this).val(self.setIntOnly($(this).val()));
1082			});
1083
1084			$('.jwvalid-tel').on('keyup', function() {
1085				$(this).val(self.telNumber($(this).val()));
1086			});
1087
1088			$('.jwvalid-mobile').on('keyup', function() {
1089				$(this).val(self.phoneNumber($(this).val()));
1090			});
1091		},
1092
1093	}
1094}
1095
1096toastr.options = {
1097		closeButton: true,
1098		"debug": false,
1099		"positionClass": "toast-top-right",
1100		"timeOut": "3000"
1101}
1102
1103
1104function showAlert( msg ) {
1105	alert(msg);
1106}
1107
1108const serialize = rawData => {
1109	let rtnData = {};
1110	for (let [key, value] of rawData) {
1111		let sel = document.querySelectorAll("[name=" + key + "]");
1112
1113		// Array Values
1114		if (sel.length > 1) {
1115			if (rtnData[key] === undefined) {
1116				rtnData[key] = [];
1117			}
1118			rtnData[key].push(value);
1119		}
1120		// Other
1121		else {
1122			rtnData[key] = value;
1123		}
1124	}
1125	return rtnData;
1126}
1127const submit = () => {
1128	const frm = $("#writeForm")[0];
1129	const formData = new FormData(frm);
1130	formData.append("reffer", window.location.pathname);
1131	formData.append("action", window.location.host + $("#writeForm").attr("action"));
1132	formData.append("protocol", window.location.href.split(":")[0])
1133	const serializeFormData = serialize(formData);
1134
1135	let result = false;
1136
1137	$.ajax({
1138		url: '/webfilter.do',
1139		async: false,
1140		method: 'post',
1141		dataType: 'json',
1142		data: serializeFormData,
1143		success: function( res ) {
1144			if(res.result === "success"){
1145				result = true;
1146			 }else if(res.result === "bypass"){
1147			// 	//bypass시 처리
1148			result = true;
1149			// 	console.log("result", res.result);
1150			}else{
1151				console.log("result:", res.result);
1152				console.log("denyMessage : ", res.denyMessage);
1153				console.log("cause", res.cause);
1154				alert("개인정보가 포함되어있습니다.\n" + res.cause );
1155			}
1156		}
1157	});
1158	return result;
1159}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.