๋ชจ๋‹ฌ์—์„œ ๋น„๋™๊ธฐ๊ฐ€ ์•„๋‹Œ ๋ฐฉ์‹์œผ๋กœ ํผ์„ ์ œ์ถœ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด ์ƒˆ๋กœ๊ณ ์นจ์ด ์ผ์–ด๋‚˜๊ฒŒ ๋˜์–ด ํผ ์ œ์ถœ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋ฅผ ์‚ฌ์šฉ์ œ์—๊ฒŒ ์ง์ ‘์ ์œผ๋กœ ์•Œ๋ ค์ฃผ๊ธฐ ์–ด๋ ค์› ๋‹ค, ๊ทธ๋ž˜์„œ ๋น„๋™๊ธฐ๋กœ ํผ ์ œ์ถœ๊ณ  ๋™์‹œ์— ๋งŒ์•ฝ ์—๋Ÿฌ๊ฐ€ ์žˆ์œผ๋ฉด ๋™์ ์œผ๋กœ ์—๋Ÿฌ๋ฅผ ํ‘œ์‹œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ˆ˜์ • ํ•˜๋Š”๋ฐฉ๋ฒ•์„ ๋ถ„์„ํ•ด๋ณด์ž.

 

๋ชจ๋‹ฌ ๋‚ด ํผ ์ œ์ถœ ์ฒ˜๋ฆฌ

 

๋ชจ๋‹ฌ ๋‚ด์—์„œ ๋น„๋™๊ธฐ ํผ ์ œ์ถœ์„ ๊ตฌํ˜„ํ•  ๋•Œ์˜ ์ฃผ์š” ์ ์€, ํผ ์ œ์ถœ ํ›„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์—๋Ÿฌ๋ฅผ ๋ชจ๋‹ฌ ๋‚ด์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  ํ‘œ์‹œํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋Š” ํผ์„ ์ œ์ถœํ•œ ๊ฐ™์€ ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ๋งŽ์€ ํ˜„๋Œ€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์€ AJAX(Ajax, Asynchronous JavaScript and XML)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์ธํ„ฐ๋ž™์…˜์„ ๋” ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

document.addEventListener('DOMContentLoaded', function() {  
    const smsCreateForm = document.getElementById('smsCreateForm');  

    smsCreateForm.addEventListener('submit', function(event) {  
        event.preventDefault(); // ๊ธฐ๋ณธ ์ œ์ถœ ์ด๋ฒคํŠธ ๋ฐฉ์ง€  
        const formData = new FormData(smsCreateForm);  

        // AJAX ์š”์ฒญ ์„ค์ •  
        fetch(smsCreateForm.action, {  
            method: 'POST',  
            body: formData  
        })  
            .then(response => response.json()) // ์‘๋‹ต์„ JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜  
            .then(data => {  
                if (data.success) {  
                    // ์„ฑ๊ณต ์ฒ˜๋ฆฌ ๋กœ์ง  
                    window.location.href = '/member/sms/list'; // ์„ฑ๊ณต ํ›„ ํŽ˜์ด์ง€ ์ด๋™  
                } else {  
                    // ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ  
                    const errorContainer = document.getElementById('errorContainer');  
                    errorContainer.innerHTML = ''; // ์ด์ „ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ดˆ๊ธฐํ™”  
                    data.errors.forEach(error => {  
                        const errorElement = document.createElement('div');  
                        errorElement.classList.add('alert', 'alert-danger');  
                        errorElement.innerText = error;  
                        errorContainer.appendChild(errorElement);  
                    });  
                }  
            })  
            .catch(error => {  
                console.error('Failed to submit form:', error);  
            });  
    });  
});

๊ธฐ์กด ์ฝ”๋“œ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ํผ ์ œ์ถœ์˜ ๊ตฌํ˜„

1. DOMContentLoaded ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ
์›น ํŽ˜์ด์ง€๊ฐ€ ์™„์ „ํžˆ ๋กœ๋“œ๋˜๊ณ  ์ดˆ๊ธฐํ™”๋˜๋ฉด, JavaScript ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. DOMContentLoaded ์ด๋ฒคํŠธ๋Š” HTML ๋ฌธ์„œ์™€ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋กœ๋“œ๋œ ํ›„์— ๋ฐœ์ƒํ•˜์ง€๋งŒ, ์ด๋ฏธ์ง€๋‚˜ ์Šคํƒ€์ผ์‹œํŠธ ๊ฐ™์€ ๋‹ค๋ฅธ ์ž์›์€ ๋กœ๋“œ๋˜์ง€ ์•Š์•„๋„ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

   document.addEventListener('DOMContentLoaded', function() {
       ...
   });

2. ํผ ์š”์†Œ ์„ ํƒ ๋ฐ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์„ค์ •

๋ฌธ์„œ์—์„œ ํŠน์ • ํผ์„ ์„ ํƒํ•˜๊ณ , ์ด ํผ์˜ submit ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฆฌ์Šค๋„ˆ๋Š” ํผ์ด ์ œ์ถœ๋  ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

   const smsCreateForm = document.getElementById('smsCreateForm');
   smsCreateForm.addEventListener('submit', function(event) {
       ...
   });

3. ์ด๋ฒคํŠธ ๊ธฐ๋ณธ ๋™์ž‘ ๋ฐฉ์ง€

event.preventDefault() ๋ฉ”์†Œ๋“œ๋Š” ํผ์˜ ๊ธฐ๋ณธ ์ œ์ถœ ๋™์ž‘์„ ์ค‘๋‹จ์‹œํ‚ต๋‹ˆ๋‹ค. ์ด๋Š” ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ ์—†์ด JavaScript๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

   event.preventDefault();

4. FormData ๊ฐ์ฒด ์ƒ์„ฑ

FormData ๊ฐ์ฒด๋Š” ํผ ์š”์†Œ ๋‚ด ๋ฐ์ดํ„ฐ๋ฅผ ์‰ฝ๊ฒŒ ์ทจํ•ฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” fetch ํ˜ธ์ถœ์˜ body๋กœ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

   const formData = new FormData(smsCreateForm);

5. fetch๋ฅผ ์ด์šฉํ•œ AJAX ์š”์ฒญ

fetch ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋กœ ๋น„๋™๊ธฐ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์‘๋‹ต ์ฒ˜๋ฆฌ๋Š” .then() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

   fetch(smsCreateForm.action, {
       method: 'POST',
       body: formData
   })

6. ์‘๋‹ต ์ฒ˜๋ฆฌ ๋ฐ UI ์—…๋ฐ์ดํŠธ
์„œ๋ฒ„์˜ ์‘๋‹ต์„ ๋ฐ›์•„ ์„ฑ๊ณต ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์ ์ ˆํ•œ UI ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์„ฑ๊ณต ์‹œ ํŽ˜์ด์ง€๋ฅผ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๊ณ , ์‹คํŒจ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

   .then(response => response.json())
   .then(data => {
       if (data.success) {
           window.location.href = '/member/sms/list';
       } else {
           const errorContainer = document.getElementById('errorContainer');
           errorContainer.innerHTML = '';  // ์—๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ ์ดˆ๊ธฐํ™”
           data.errors.forEach(error => {
               const errorElement = document.createElement('div');
               errorElement.classList.add('alert', 'alert-danger');
               errorElement.innerText = error;
               errorContainer.appendChild(errorElement);
           });
       }
   })

7. ์—๋Ÿฌ ์ฒ˜๋ฆฌ
๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋‚˜ ์„œ๋ฒ„ ์˜ค๋ฅ˜์— ๋Œ€์‘ํ•˜์—ฌ ์ฝ˜์†”์— ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

   .catch(error => {
       console.error('Failed to submit form:', error);
   });

์ด๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ค๋ฉฐ, ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ˜์‘์„ฑ๊ณผ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค. ํผ์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•จ์œผ๋กœ์จ, ์‚ฌ์šฉ์ž๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์„œ๋ฒ„๋กœ ์ „์†ก๋˜๋Š” ๋™์•ˆ์—๋„ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.