PageSourceSearch

https://scjdwc.or.kr/wp-content/plugins/iwp_jawon/assets/js/form.js?ver=1776744344

js scjdwc.or.kr collected 2026-10-08 20:45:22 UTC 7,230 bytes, 192 lines download raw bytes

1jQuery(document).ready(function($) {
2    var form = $('#volunteer-application-form');
3    var messageDiv = $('#form-message');
4    
5    // 우편번호 검색 (다음 주소 API)
6    $('#search_postal_code').on('click', function(e) {
7        e.preventDefault();
8        new daum.Postcode({
9            oncomplete: function(data) {
10                $('#postal_code').val(data.zonecode);
11                $('#street_address').val(data.roadAddress || data.jibunAddress);
12                $('#detailed_address').focus();
13            }
14        }).open();
15    });
16    
17    // 폼 제출
18    form.on('submit', function(e) {
19        e.preventDefault();
20
21        var validationError = validateRequiredFields();
22        if (validationError) {
23            showMessage(validationError.message, 'error');
24            scrollToInvalidField(validationError.target);
25            return;
26        }
27        
28        // 데이터 수집
29        var formData = {
30            action: 'volunteer_submit',
31            nonce: volunteerAjax.nonce,
32            name: $('#name').val(),
33            gender: $('input[name="gender"]:checked').val(),
34            vms_id: $('#vms_id').val(),
35            phone: $('#phone').val(),
36            email: $('#email').val(),
37            affiliation: $('#affiliation').val(),
38            postal_code: $('#postal_code').val(),
39            street_address: $('#street_address').val(),
40            address_type: $('input[name="address_type"]:checked').val(),
41            detailed_address: $('#detailed_address').val(),
42            has_experience: $('input[name="has_experience"]:checked').val(),
43            days: [],
44            time: $('input[name="time"]').val(),
45            fields: [],
46            other_field: $('input[name="other_field"]').val(),
47            portrait_consent: $('input[name="portrait_consent"]:checked').val(),
48            privacy_consent: $('input[name="privacy_consent"]:checked').val()
49        };
50        
51        // 체크박스 값 수집
52        $('input[name="days[]"]:checked').each(function() {
53            formData.days.push($(this).val());
54        });
55        
56        $('input[name="fields[]"]:checked').each(function() {
57            formData.fields.push($(this).val());
58        });
59        
60        // AJAX 제출
61        $.ajax({
62            url: volunteerAjax.ajaxurl,
63            type: 'POST',
64            data: formData,
65            beforeSend: function() {
66                form.find('button[type="submit"]').prop('disabled', true).text('처리 중...');
67            },
68            success: function(response) {
69                if (response.success) {
70                    showMessage(response.data.message, 'success');
71                    form[0].reset();
72                    // 스크롤을 메시지로 이동
73                    $('html, body').animate({
74                        scrollTop: messageDiv.offset().top - 100
75                    }, 500);
76                } else {
77                    showMessage(response.data.message, 'error');
78                    if (response.data.field) {
79                        highlightFieldByKey(response.data.field);
80                    }
81                }
82            },
83            error: function() {
84                showMessage('서버 오류가 발생했습니다. 다시 시도해주세요.', 'error');
85            },
86            complete: function() {
87                form.find('button[type="submit"]').prop('disabled', false).html('<span class="icon">✏️</span> 자원봉사신청 접수');
88            }
89        });
90    });
91    
92    function validateRequiredFields() {
93        form.find('.form-group').removeClass('error');
94        form.find('input').removeClass('error');
95
96        var rules = [
97            { key: 'privacy_consent', selector: 'input[name="privacy_consent"]', type: 'radio', message: '개인정보처리 동의를 입력하세요.' },
98            { key: 'portrait_consent', selector: 'input[name="portrait_consent"]', type: 'radio', message: '초상권 사용 동의 여부를 입력하세요.' },
99            { key: 'name', selector: '#name', type: 'text', message: '성명을 입력하세요.' },
100            { key: 'gender', selector: 'input[name="gender"]', type: 'radio', message: '성별을 입력하세요.' },
101            { key: 'phone', selector: '#phone', type: 'text', message: '전화번호를 입력하세요.' },
102            { key: 'has_experience', selector: 'input[name="has_experience"]', type: 'radio', message: '자원봉사경험을 입력하세요.' },
103            { key: 'days', selector: 'input[name="days[]"]', type: 'checkbox', message: '요일을 입력하세요.' }
104        ];
105
106        for (var i = 0; i < rules.length; i++) {
107            var rule = rules[i];
108            var target = form.find(rule.selector).first();
109            if (!target.length) {
110                continue;
111            }
112
113            if (rule.type === 'radio' || rule.type === 'checkbox') {
114                if (!form.find(rule.selector + ':checked').length) {
115                    target.closest('.form-group').addClass('error');
116                    return { message: rule.message, target: target };
117                }
118            } else {
119                if (!target.val().trim()) {
120                    target.addClass('error');
121                    target.closest('.form-group').addClass('error');
122                    return { message: rule.message, target: target };
123                }
124            }
125        }
126
127        return null;
128    }
129
130    function scrollToInvalidField(target) {
131        if (!target || !target.length) {
132            return;
133        }
134
135        $('html, body').animate({
136            scrollTop: target.closest('.form-group').offset().top - 120
137        }, 400);
138
139        setTimeout(function() {
140            target.trigger('focus');
141        }, 450);
142    }
143
144    function highlightFieldByKey(fieldKey) {
145        var keyMap = {
146            privacy_consent: 'input[name="privacy_consent"]',
147            portrait_consent: 'input[name="portrait_consent"]',
148            name: '#name',
149            gender: 'input[name="gender"]',
150            vms_id: '#vms_id',
151            phone: '#phone',
152            has_experience: 'input[name="has_experience"]',
153            days: 'input[name="days[]"]'
154        };
155
156        var selector = keyMap[fieldKey];
157        if (!selector) {
158            return;
159        }
160
161        var target = form.find(selector).first();
162        target.closest('.form-group').addClass('error');
163        scrollToInvalidField(target);
164    }
165
166    function showMessage(message, type) {
167        if (type === 'error') {
168            window.alert(message);
169            messageDiv.hide().text('');
170            return;
171        }
172
173        messageDiv.removeClass('success error')
174                  .addClass(type)
175                  .text(message)
176                  .fadeIn();
177        
178        if (type === 'success') {
179            setTimeout(function() {
180                messageDiv.fadeOut();
181            }, 5000);
182        }
183    }
184    
185    // 다음 주소 API 스크립트 로드
186    if (typeof daum === 'undefined') {
187        var script = document.createElement('script');
188        script.src = '//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js';
189        document.head.appendChild(script);
190    }
191});
192

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.