홈페이지를 만드는 사람들을 위한 안내서
화면 전환 없이 손쉽게 폼을 제출할 수 있도록 지원
조회 수 24 추천 수 0 2024.08.24 08:41:11개요
폼 제출시 화면을 전환하지 않고 AJAX를 사용하면 여러 가지 이점이 있습니다. 한 화면에서 여러 가지 작업을 연속적으로 수행할 수 있고, 처리 시간도 단축되며, 결과 메시지를 별도의 화면이 아닌 alert()
창이나 레이어로 표시할 수 있으므로 사용자 입장에서도 더 편리합니다.
특히 폼 제출 도중 발생한 오류가 화면 전환 후에야 표시되면 내용을 다시 입력해야 하는 불편이 발생합니다. 간단한 폼의 내용은 RXE에서 자동으로 재입력해 줄 수 있으나, 배열이 들어가는 등 구조가 복잡한 폼이거나 자바스크립트를 사용하여 동적으로 생성된 <input>
이 있으면 그것까지 모두 재입력해 줄 수 없기 때문에 내용이 날아가 버립니다.
그렇다고 모든 폼을 AJAX로 제출하도록 코드를 작성하려면 상당한 삽질이 필요합니다. 폼 데이터를 추출하여 정리한 후 exec_xml()
이나 exec_json()
(권장) 함수에 넣어주어야 하지요. <input type="file">
이라도 하나 끼어 있으면 이런 함수마저 사용할 수 없으므로 더욱 곤란해집니다. 복잡한 모듈을 만든다면 이 삽질을 폼마다 반복해 주어야 합니다. 스크립트를 꽤 많이 써야 하지요. 그래서 아직도 폼을 제출할 때마다 볼썽사납게 화면이 전환되는 코어 모듈 및 서드파티 자료가 많습니다.
이제 이 삽질을 코어에서 상당 부분 대신 해 줄 수 있게 되었습니다.
방법
아무 폼이든지 rx_ajax
클래스를 추가해 주기만 하면
<form action="{Context::getRequestUri()}" method="post" class="rx_ajax">
<input type="hidden" name="module" value="mymodule" />
<input type="hidden" name="act" value="procMymoduleInsertWhatever" />
... 중략 ...
</form>
해당 폼은 화면 전환 없이 AJAX로 제출됩니다. 오류가 발생하면 alert()
창으로 표시되고, 제출에 성공하여 redirect URL이 지정되면 해당 화면으로 리다이렉트됩니다.
파일 업로드를 포함한 폼
파일 업로드를 포함한 폼이라도 rx_ajax
클래스만 추가하면 화면 전환 없이 제출할 수 있습니다.
<input type="file">
이 포함된 폼은 일반적인 AJAX 요청으로 제출하기 어렵습니다. 따라서 임시로 <iframe>
을 생성하고, 해당 <iframe>
을 target
으로 지정하여 AJAX와 동일하게 백그라운드에서 제출하는 효과를 발휘합니다. (업로더에서도 브라우저 호환성을 위해 종종 사용하는 방식입니다.) 오류 메시지 표시나 redirect URL 처리도 <iframe>
내에서 실행되는 스크립트에 의해 AJAX와 똑같이 이루어지고, 사용이 끝난 <iframe>
은 자동으로 삭제됩니다.
<input type="file">
의 name
값이 Filedata
인 경우 파일 업로드를 포함한 폼으로 간주하지 않습니다. 부모 폼과 무관하게 파일을 직접 업로드하는 RXE 기본 에디터가 Filedata
라는 이름을 사용하기 때문입니다. 파일 업로드를 포함한 폼을 제출하려면 Filedata
가 아닌 다른 이름을 사용해야 합니다.
기타
폼을 제출받는 controller 쪽에서는 화면 전환이 아닌 AJAX 또는 <iframe>
방식으로 제출된다는 사실에 맞추어 일부 코드 수정이 필요할 수도 있습니다. 그러나 RXE 관례대로 setRedirectUrl()
를 사용하거나 오류 메시지를 BaseObject
에 넣어 반환하도록 (또는 Rhymix\Framework\Exception
을 던지도록) 코딩되어 있다면 대부분은 별다른 수정 없이 작동할 것입니다.
물론 rx_ajax
클래스를 추가하지 않은 기존의 폼에는 아무 영향도 주지 않습니다. 스크립트를 사용할 수 없는 환경에서는 (아직도 그런 게 있나요? ㅋㅋ) 기존과 같이 화면 전환이 발생합니다.
폼에 onsubmit
속성이 있거나 다른 스크립트에서 onsubmit
이벤트를 추가한 경우 이 기능과 충돌할 수 있습니다.
이 방법이 안정화되면 구닥다리 onsubmit="return procFilter(...)"
방식도 상당 부분 대체할 수 있을 것으로 보입니다.