PageSourceSearch

https://www.unescoicm.org/ko/_assets/js/common.js?ver=1783756563

js unescoicm.org collected 2026-10-02 12:36:57 UTC 16,676 bytes, 614 lines download raw bytes

1(function($) {
2
3    'use strict';
4
5    // prevent backward event
6    window.onpageshow = function(e){
7        if(e.persisted || (window.performance && window.performance.navigation.type == 2)) {
8            complete_ajax_loader();
9        }
10    }
11
12    $(function(){
13
14        // modal scroll issue
15        const df_modal = document.getElementById('df_modal');
16        df_modal.addEventListener('show.bs.modal', function(e){
17            if($(window).height() != $(document).height()) {
18                disable_scroll();
19            }
20        });
21        df_modal.addEventListener('hide.bs.modal', function(e){
22            if($(window).height() != $(document).height()) {
23                enable_scroll();
24            }
25        });
26
27        // form input prevent enter key (헤더 검색 .sch_input 은 Enter 가 유일한 제출 수단 — 예외)
28        $(document).on('keydown', 'input[type="text"]:not(.sch_input)', function(e){
29            if(e.keyCode == 13) {
30                e.preventDefault();
31                return false;
32            }
33        });
34
35        // list search submit
36        $(document).on('keydown', '#search_form input[type="search"]', function(e){
37            if(e.keyCode == 13) {
38                e.preventDefault();
39                search_submit();
40            }
41        });
42
43        // move page
44        $(document).on('click', '[data-df-toggle="move-page"]', function(e){
45            e.preventDefault();
46            e.stopPropagation();
47
48            const $this = $(this);
49            const href  = $this.attr('href');
50
51            ajax_move_page(href);
52        });
53
54        // button href
55        $(document).on('click', '[data-df-toggle="href"]', function(e){
56            e.preventDefault();
57            e.stopPropagation();
58
59            const $this = $(this);
60            const href  = $this.data('df-href');
61
62            ajax_move_page(href);
63        });
64
65        // copy text
66        $(document).on('click', '[data-df-toggle="copy-text"]', function(e){
67            e.preventDefault();
68            e.stopPropagation();
69
70            const $this = $(this);
71            const title  = $this.data('df-text');
72
73            const $temp = $("<input>");
74            $this.append($temp);
75            $temp.val(title).select();
76            document.execCommand("copy");
77            $temp.remove();
78
79            toast_message('success', '복사되었습니다.');
80        });
81
82        // datepicker
83        $(document).on('focus', '.date-picker', function(e){
84            $(this).datepicker({
85                format: 'yyyy-mm-dd',
86                todayHighlight: true,
87                setDate: new Date(),
88                autoclose: true,
89                disableTouchKeyboard: true,
90                showWeekDays: true,
91                language: 'ko',
92            }).on('changeDate', function(e){
93                $(this).datepicker('hide');
94            });
95        });
96
97        // Show/Hide Password
98        $(document).on('click', '[data-password]', function(e){
99            if($(this).attr('data-password') == "false") {
100                $(this).siblings("input").attr("type", "text");
101                $(this).attr('data-password', 'true');
102                $(this).removeClass("bi-eye-slash");
103                $(this).addClass("bi-eye");
104            } else {
105                $(this).siblings("input").attr("type", "password");
106                $(this).attr('data-password', 'false');
107                $(this).removeClass("bi-eye");
108                $(this).addClass("bi-eye-slash");
109            }
110        });
111    });
112})(jQuery)
113
114let df_ajax_busy = false;
115
116// 로딩 오버레이 지연 표시 타이머 — 빠른 작업은 오버레이를 아예 안 띄워 배경 깜빡임 제거
117let df_loader_timer = null;
118
119/**
120 * ajax move page
121 */
122function ajax_move_page(page_url)
123{
124    if(df_ajax_busy) return;
125    df_ajax_busy = true;
126
127    $.ajax({
128        url: FRONT_URL+'/move-page-ajax',
129        type: 'get',
130        dataType: 'json',
131        timeout: 30000,
132        data: {
133            url: page_url
134        },
135        beforeSend: function() {
136            before_ajax_loader();
137        },
138        success: function(data, status, xhr) {
139            if(data.mode == 'success') {
140                location.href = data.url;
141            } else {
142                location.href = BASE_URL+'/front';
143            }
144        },
145        error: function(xhr, status, error) {
146            location.href = BASE_URL+'/front';
147        },
148        complete: function(xhr, status) {
149            df_ajax_busy = false;
150            complete_ajax_loader();
151        }
152    });
153}
154
155/**
156 * ajax data submit
157 */
158function ajax_data_submit(form_action, form_data)
159{
160    if(df_ajax_busy) return;
161    df_ajax_busy = true;
162
163    const csrf_token = $('meta[name="csrf_token"]').attr('content');
164    if(csrf_token) {
165        if(form_data instanceof FormData) {
166            if(!form_data.has('csrf_token')) form_data.append('csrf_token', csrf_token);
167        } else if(typeof form_data === 'object') {
168            form_data.csrf_token = csrf_token;
169        }
170    }
171    const auth_token = $('meta[name="auth_token"]').attr('content');
172    if(auth_token) {
173        if(form_data instanceof FormData) {
174            if(!form_data.has('auth_token')) form_data.append('auth_token', auth_token);
175        } else if(typeof form_data === 'object') {
176            form_data.auth_token = auth_token;
177        }
178    }
179    const is_form_data = form_data instanceof FormData;
180
181    $.ajax({
182        url: form_action,
183        type: 'post',
184        dataType: 'json',
185        data: form_data,
186        cache: false,
187        timeout: 60000,
188        contentType: is_form_data ? false : 'application/x-www-form-urlencoded; charset=UTF-8',
189        processData: is_form_data ? false : true,
190        beforeSend: function() {
191            before_ajax_loader();
192        },
193        success: function(data, status, xhr) {
194            if(data.mode == 'delete') {
195                df_ajax_busy = false;
196                const new_form_data = new FormData($('#action_form')[0]);
197                Object.keys(data).forEach(key => {
198                    if(new_form_data.has(key)) new_form_data.delete(key);
199                    new_form_data.append(key, data[key]);
200                });
201                ajax_data_submit(data.url, new_form_data);
202            } else if(data.mode == 'success') {
203                if(data.msg != '') {
204                    sweet_alert_url('success', data.code, data.msg, data.url);
205                } else {
206                    if(data.url == '') {
207                        location.reload();
208                    } else {
209                        location.href = data.url;
210                    }
211                }
212            } else {
213                $('#loader').fadeOut('fast', function() {
214                    toast_message(data.mode, data.msg, data.tid);
215                });
216            }
217        },
218        error: function(xhr, status, error) {
219            $('#loader').fadeOut('fast', function() {
220                const err_msg = (status === 'timeout') ? '요청 시간이 초과되었습니다. 다시 시도해주세요.' : '데이터 처리 중 오류가 발생했습니다.';
221                toast_message('error', err_msg);
222            });
223        },
224        complete: function(xhr, status) {
225            df_ajax_busy = false;
226            complete_ajax_loader();
227        }
228    });
229}
230
231/**
232 * ajax before loader
233 */
234function before_ajax_loader()
235{
236    $('.btn-insert').prop('disabled', true);
237    $('.btn-submit').prop('disabled', true);
238    // 오버레이는 250ms 넘게 걸리는 작업에만 표시 — 빠른 이동/저장은 배경 깜빡임 없이 지나감
239    clearTimeout(df_loader_timer);
240    df_loader_timer = setTimeout(function() {
241        $('#loader').show();
242        $('#status').show();
243    }, 250);
244}
245
246/**
247 * ajax after loader
248 */
249function complete_ajax_loader()
250{
251    clearTimeout(df_loader_timer);
252    $('.btn-submit').prop('disabled', false);
253    $('.btn-insert').prop('disabled', false);
254    $('#status').fadeOut();
255    $('#loader').fadeOut();
256}
257
258/**
259 * alert
260 */
261function sweet_alert(mode, code, msg, tid)
262{
263    Swal.fire({
264        position: 'center',
265        icon: mode,
266        title: code,
267        html: msg,
268        allowOutsideClick: false,
269        allowEscapeKey: false,
270        confirmButtonText: "확인",
271        didClose: () => {
272            if(tid != '') {
273                $('[name="'+ tid + '"]').focus();
274            }
275        }
276    });
277}
278
279function sweet_confirm(mode, code, msg, form_action, form_data)
280{
281    Swal.fire({
282        position: 'center',
283        icon: mode,
284        title: code,
285        html: msg,
286        allowOutsideClick: false,
287        allowEscapeKey: false,
288        showCancelButton: true,
289        confirmButtonText: '확인',
290        cancelButtonText: '취소'
291    }).then((result) => {
292        if(result.isConfirmed) {
293            ajax_data_submit(form_action, form_data);
294        }
295    });
296}
297
298function sweet_alert_url(mode, code, msg, url='')
299{
300    Swal.fire({
301        position: 'center',
302        icon: mode,
303        title: code,
304        html: msg,
305        confirmButtonText: "확인"
306    })
307    .then(function(){
308        if(url == '') {
309            location.reload();
310        } else {
311            location.href = url;
312        }
313    });
314}
315
316function toast_message(icon, msg, tid='')
317{
318    const bg_color = (icon == 'error') ? '#d81b60' : '#536DE6';
319    $.toast({
320        icon: icon,
321        text: msg,
322        bgColor: bg_color,
323        textColor: 'white',
324        position: 'bottom-right',
325        hideAfter: (icon == 'success') ? 3000 : 4500,   // 에러·안내는 여러 줄 메시지가 많아 읽을 시간 확보, 완료 확인은 짧게
326        showHideTransition: 'slide',
327        allowToastClose: false,
328        stack: 8,
329        afterShown: function(){
330            if(tid != '') {
331                $('[name="'+ tid + '"]').focus();
332            }
333        }
334    });
335}
336
337/**
338 * disable scrolling
339 */
340function disable_scroll()
341{
342    $('html, body').css({
343        'overflow-y': 'scroll',
344        'position': 'fixed',
345        'top': -$(window).scrollTop(),
346        'left': 0,
347        'width': '100%'
348    });
349}
350
351/**
352 * enable scrolling
353 */
354function enable_scroll()
355{
356    const scroll_position = Math.abs($('html, body').css('top').split('px')[0]);
357    $('html, body').removeAttr('style');
358    window.scrollTo({top:scroll_position, left:0, behavior: "instant"});
359}
360
361/**
362 * find address
363 */
364function popup_zip(frm_name, zip_code, zip_address, zip_address_sub)
365{
366    if(typeof daum === 'undefined') {
367        toast_message('error', '[DAUM juso.js] File not loaded.');
368        return false;
369    }
370
371    new daum.Postcode({
372        oncomplete: function(data) {
373            console.log(data);
374            const of = document[frm_name];
375            of[zip_code].value = data.zonecode;
376            of[zip_address].value = data.roadAddress;
377            of[zip_address_sub].value = data.buildingName;
378
379            of[zip_address_sub].focus();
380        }
381    }).open();
382}
383
384/**
385 * remove object
386 */
387function remove_object(id)
388{
389    $('#'+id).remove();
390}
391
392/**
393 * set date
394 */
395function set_date(fr_date, to_date, fr_obj, to_obj)
396{
397    document.getElementById(fr_obj).value = (fr_date) ? fr_date : "";
398    document.getElementById(to_obj).value = (to_date) ? to_date : "";
399}
400
401/**
402 * get today
403 */
404function get_today()
405{
406    const date  = new Date();
407    const year  = date.getFullYear();
408    const month = ("0" + (1 + date.getMonth())).slice(-2);
409    const day   = ("0" + date.getDate()).slice(-2);
410
411    return year + "-" + month + "-" + day;
412}
413
414/**
415 * auto hyphen tel
416 */
417function auto_hyphen_tel(target)
418{
419    target.value = target.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('--', '-');
420}
421
422/**
423 * validation
424 */
425/**
426 * validation
427 */
428function valid_name(val)
429{
430    const regex = /^[가-힣]{2,4}$/;
431
432    if(val.match(regex)) {
433      return true;
434    } else {
435      return false;
436    }
437}
438function valid_tel(val)
439{
440    const regex = /[0-9]{2,4}-[0-9]{3,4}-[0-9]{4}/;
441
442    if(val.match(regex)) {
443      return true;
444    } else {
445      return false;
446    }
447}
448function valid_phone(val)
449{
450    const regex = /01[016789]-[^0][0-9]{2,3}-[0-9]{3,4}/;
451
452    if(val.match(regex)) {
453      return true;
454    } else {
455      return false;
456    }
457}
458function valid_email(val)
459{
460    const regex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
461
462    if(val.match(regex)) {
463      return true;
464    } else {
465      return false;
466    }
467}
468
469/**
470 * add comma
471 */
472function add_comma(x)
473{
474    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
475}
476
477/**
478 * check all toggle
479 */
480function check_all_toggle(all_selector, check_selector)
481{
482    let el_check_selector = $(check_selector);
483    if($(all_selector).is(':checked') === true) {
484        el_check_selector.each(function () {
485            let el_this = $(this);
486            if(el_this.is(':disabled') !== true) {
487                el_this.attr({ checked: true }).prop({ checked: true });
488            }
489        });
490    } else {
491        el_check_selector.attr({ checked: false }).prop({ checked: false });
492    }
493}
494
495/**
496 * checkbox toggle
497 */
498function check_box_toggle(all_selector, check_selector)
499{
500    let el_all_selector = $(all_selector);
501    let checkbox_ln = $(check_selector).length;
502    let check_ln = $(`${check_selector}:checked`).length;
503    if(checkbox_ln === check_ln) {
504        el_all_selector.attr({ checked: true }).prop({ checked: true });
505    } else {
506        el_all_selector.attr({ checked: false }).prop({ checked: false });
507    }
508}
509
510/**
511 * checkbox toggle event
512 */
513function check_all(all_selector, check_selector)
514{
515    let el_all_selector = $(all_selector);
516    el_all_selector.on('change', function () {
517        check_all_toggle(all_selector, check_selector);
518    });
519    let el_check_selector = $(check_selector);
520    el_check_selector.on('change', function () {
521        check_box_toggle(all_selector, check_selector);
522    });
523}
524
525/**
526 * set cookie
527 */
528function set_cookie(name, value, expirehours, domain)
529{
530    const today = new Date();
531    today.setTime(today.getTime() + (60*60*1000*expirehours));
532    document.cookie = name + "=" + escape( value ) + "; path=/; expires=" + today.toGMTString() + ";";
533    if(domain) {
534        document.cookie += "domain=" + domain + ";";
535    }
536}
537
538/**
539 * get cookie
540 */
541function get_cookie(name)
542{
543    const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
544    if(match) return unescape(match[2]);
545    return "";
546}
547
548/**
549 * delete cookie
550 */
551function delete_cookie(name)
552{
553    const today = new Date();
554
555    today.setTime(today.getTime() - 1);
556    const value = get_cookie(name);
557    if(value != "") {
558        document.cookie = name + "=" + value + "; path=/; expires=" + today.toGMTString();
559    }
560}
561
562/**
563 * get device
564 */
565function get_device_type()
566{
567    if(navigator.userAgentData) {
568        if(navigator.userAgentData.mobile) {
569            return "M";
570        }
571        return "D";
572    }
573    const ua = navigator.userAgent;
574    if(/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
575        return "T";
576    }
577    if(/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(ua)) {
578        return "M";
579    }
580
581    return "D";
582}
583
584/**
585 * remove modal
586 */
587function remove_modal(id) {
588    const modal_element = document.getElementById(id);
589
590    if(!modal_element) {
591        console.warn(`Modal with ID "${modalId}" not found.`);
592        return;
593    }
594
595    const modal_instance = bootstrap.Modal.getInstance(modal_element);
596
597    if(modal_instance) {
598        modal_instance.hide();
599        modal_instance.dispose();
600    }
601
602    //modal_element.remove();
603
604    const backdrops = document.querySelectorAll('.modal-backdrop');
605    backdrops.forEach(backdrop => {
606        backdrop.remove();
607    });
608
609    if(document.querySelectorAll('.modal.show').length === 0) {
610        document.body.style.overflow = '';
611        document.body.style.paddingRight = '';
612        document.body.classList.remove('modal-open');
613    }
614}

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.