기본 콘텐츠로 건너뛰기

Ext JS Grid와 jQuery ajaxForm 연동: 비동기 파일 업로드 하이브리드 패턴 구현

WEB DEVELOPMENT

Ext JS Grid와 jQuery ajaxForm 연동: 비동기 파일 업로드 하이브리드 패턴 구현

Ext JS의 UI 강점과 jQuery ajaxForm의 유연성을 결합하여 Grid 컴포넌트 내에서 비동기 파일 업로드를 구현하는 실무적인 하이브리드 패턴을 상세히 분석합니다.

1. Ext JS와 jQuery 하이브리드 아키텍처

이 기술 가이드는 Ext JS의 강력한 UI 프레임워크와 jQuery의 유틸리티성을 결합하여, 단일 프레임워크만으로는 구현하기 까다로운 기능을 해결하는 사례를 다룹니다. 기본 아키텍처는 다음과 같이 구성됩니다.

  • Data Model & Store: 게시판(BBS) 데이터를 구조화하고 CRUD 처리를 위한 Proxy 설정이 포함된 스토어 객체입니다.
  • Grid Panel: 사용자에게 데이터 목록을 제공하며, 핵심 기능인 파일 첨부를 위한 버튼 렌더러(Renderer)가 포함되어 있습니다.
  • Form Panel: Grid에서 선택된 항목의 상세 정보를 보여주며, selectionchange 이벤트를 통해 Grid와 데이터를 실시간으로 동기화합니다.

2. jQuery ajaxForm을 이용한 동적 업로드 로직

Ext JS 내부의 FileField가 가진 제약을 우회하기 위해, 순수 JavaScript와 jQuery를 활용하여 폼을 동적으로 생성하고 전송하는 전략을 채택했습니다.

핵심 기능을 담당하는 createDataForm 함수는 다음의 프로세스로 동작합니다.

  1. 동적 폼(Form) 생성: DOM에 multipart/form-data 속성을 가진 form 태그를 즉시 생성하여 추가합니다.
  2. 이벤트 트리거링: 생성된 파일 input 요소에 대해 click() 이벤트를 강제로 호출하여 네이티브 파일 선택 창을 활성화합니다.
  3. 상태 동기화: 사용자가 파일을 선택(change 이벤트)하면, 해당 Grid 행(Row)의 상태를 갱신하여 파일 첨부 여부를 시각적으로 피드백합니다.

3. 데이터 유형별 이원화된 처리 흐름

이 하이브리드 패턴의 핵심은 파일 데이터와 일반 텍스트 데이터를 분리하여 처리하는 이원화된 파이프라인에 있습니다. 로직의 분기 과정을 시각적으로 이해하면 다음과 같습니다.

dataSubmit 함수는 데이터의 성격에 따라 다음과 같이 분기 처리됩니다.

  • 파일이 포함된 경우: jQuery의 ajaxForm 플러그인을 호출하여 비동기 멀티파트 업로드를 수행합니다.
  • 파일이 없는 경우: 표준 $.ajax POST 요청을 통해 메타 데이터만 가볍게 전송합니다.

동시에 우측의 Form Panel은 Ext JS 표준 방식인 form.submit() 메서드를 유지하여 텍스트 데이터를 별도로 저장합니다. 즉, jQuery 기반의 파일 처리와 Ext JS 기반의 데이터 관리가 충돌 없이 공존하는 구조입니다.

4. 레거시 환경에서의 기술 통합 전략

본 예제는 프레임워크의 한계를 외부 라이브러리와의 전략적 통합으로 해결한 실용적인 케이스 스터디입니다.

최신 모던 웹 프레임워크에서는 더 간결한 해결책이 존재할 수 있으나, 대규모 레거시 시스템 유지보수나 Ext JS 기반의 엔터프라이즈 환경에서 복잡한 파일 처리가 요구될 때 jQuery ajaxForm과의 통합 패턴은 여전히 강력하고 유효한 솔루션을 제공합니다.

5. [부록] 실전 구현 코드 예제

설명된 로직을 실제 프로젝트에 적용할 수 있는 핵심 코드 스니펫입니다. Ext JS의 renderer와 jQuery의 동적 폼 제어가 어떻게 상호작용하는지 확인해보세요.

// 1. Ext JS Grid Column 설정 (Renderer 활용)
{
    text: '첨부파일',
    dataIndex: 'fileName',
    width: 120,
    renderer: function(value, meta, record) {
        var id = record.get('id');
        // 버튼 클릭 시 createDataForm 호출 (Grid Row ID 전달)
        return '<button type="button" onclick="createDataForm(\'' + id + '\')">파일선택</button> ' + 
               (value ? value : '');
    }
}

// 2. 동적 폼 생성 및 파일 선택기 실행 (jQuery)
function createDataForm(rowId) {
    // 기존에 생성된 임시 폼 제거 (초기화)
    $('#tempUploadForm').remove();

    // 동적으로 Form 및 Input 생성
    var $form = $('<form id="tempUploadForm" method="POST" enctype="multipart/form-data"></form>');
    var $fileInput = $('<input type="file" name="uploadFile" style="display:none;">');

    // Form을 Body에 추가
    $form.append($fileInput);
    $('body').append($form);

    // 파일 선택 시 이벤트: Grid에 파일명 즉시 반영 (UX 향상)
    $fileInput.on('change', function() {
        var fileName = $(this).val().split('\\').pop(); // 경로 제거
        
        // Ext JS Store 접근하여 레코드 업데이트
        var store = Ext.getCmp('mainGrid').getStore();
        var record = store.findRecord('id', rowId);
        if(record) {
            record.set('fileName', fileName); // 화면 갱신
            record.set('isDirty', true);      // 수정 상태 플래그
        }
    });

    // 강제로 파일 선택창 오픈
    $fileInput.click();
}

// 3. 최종 전송 로직 (분기 처리)
function dataSubmit() {
    var $form = $('#tempUploadForm');
    var hasFile = $form.find('input[type="file"]').val() != '';

    if (hasFile) {
        // [Case A] 파일이 있는 경우: jQuery ajaxForm 사용 (Multipart)
        $form.ajaxSubmit({
            url: '/api/board/upload',
            type: 'POST',
            dataType: 'json',
            success: function(response) {
                Ext.Msg.alert('성공', '파일 업로드가 완료되었습니다.');
                // 이후 로직: Ext Grid Reload 등
            }
        });
    } else {
        // [Case B] 파일이 없는 경우: 일반 Ajax 요청
        Ext.Ajax.request({
            url: '/api/board/update',
            method: 'POST',
            params: { /* ... */ },
            success: function(response) {
                Ext.Msg.alert('성공', '텍스트 데이터가 저장되었습니다.');
            }
        });
    }
}

💡 Tip: ajaxSubmit을 사용하기 위해서는 jquery.form.js 플러그인이 페이지에 로드되어 있어야 합니다. 이 패턴은 Grid 내에서 직접 파일 첨부를 구현할 때 매우 유용합니다.

댓글

이 블로그의 인기 게시물

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 (Request Parameter 전체보기)

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 Java Servlet Request Parameter 완전 정복 웹 애플리케이션에서 클라이언트로부터 전달되는 Request Parameter 를 확인하는 것은 필수입니다. 이 글에서는 Java Servlet 과 JSP 에서 GET/POST 요청 파라미터를 전체 출력하고 디버깅하는 방법을 다양한 예제와 함께 소개합니다. 1. 기본 예제: getParameterNames() 사용 Enumeration<String> params = request.getParameterNames(); System.out.println("----------------------------"); while (params.hasMoreElements()){ String name = params.nextElement(); System.out.println(name + " : " + request.getParameter(name)); } System.out.println("----------------------------"); 위 코드는 요청에 포함된 모든 파라미터 이름과 값을 출력하는 기본 방법입니다. 2. HTML Form과 연동 예제 <form action="CheckParamsServlet" method="post"> 이름: <input type="text" name="username"><br> 이메일: <input type="email" name="email"><b...

PostgreSQL 달력(일별,월별)

SQL 팁: GENERATE_SERIES로 일별, 월별 날짜 목록 만들기 SQL 팁: GENERATE_SERIES 로 일별, 월별 날짜 목록 만들기 데이터베이스에서 통계 리포트를 작성하거나 비어있는 날짜 데이터를 채워야 할 때, 특정 기간의 날짜 목록이 필요할 수 있습니다. PostgreSQL과 같은 데이터베이스에서는 GENERATE_SERIES 함수를 사용하여 이 작업을 매우 간단하게 처리할 수 있습니다. 1. 🗓️ 일별 날짜 목록 생성하기 2020년 1월 1일부터 12월 31일까지의 모든 날짜를 '1 day' 간격으로 생성하는 쿼리입니다. WITH date_series AS ( SELECT DATE(GENERATE_SERIES( TO_DATE('2020-01-01', 'YYYY-MM-DD'), TO_DATE('2020-12-31', 'YYYY-MM-DD'), '1 day' )) AS DATE ) SELECT DATE FROM date_series 이 쿼리는 WITH 절(CTE)을 사용하여 date_series 라는 임시 테이블을 만들고, GENERATE_SERIES 함수로 날짜를 채웁니다. 결과 (일별 출력) 2. 📅 월별 날짜 목록 생성하기 동일한 원리로, 간격을 '1 MONTH' 로 변경하면 월별 목록을 생성할 수 있습니다. TO...

CSS로 레이어 팝업 화면 가운데 정렬하는 방법 (top·left·transform 완전 정리)

레이어 팝업 센터 정렬, 이 코드만 알면 끝 (CSS 예제 포함) 이벤트 배너나 공지사항을 띄울 때 레이어 팝업(center 정렬) 을 깔끔하게 잡는 게 생각보다 어렵습니다. 화면 크기가 변해도 가운데에 고정되고, 모바일에서도 자연스럽게 보이게 하려면 position , top , left , transform 을 정확하게 이해해야 합니다. 이 글에서는 아래 내용을 예제로 정리합니다. 레이어 팝업(center 정렬)의 기본 개념 자주 사용하는 position: absolute / fixed 정렬 방식 질문에서 주신 스타일 top: 3.25%; left: 50%; transform: translateX(-50%) 의 의미 실무에서 바로 쓰는 반응형 레이어 팝업 HTML/CSS 예제 1. 레이어 팝업(center 정렬)이란? 레이어 팝업(레이어 팝업창) 은 새 창을 띄우는 것이 아니라, 현재 페이지 위에 div 레이어를 띄워서 공지사항, 광고, 이벤트 등을 보여주는 방식을 말합니다. 검색엔진(SEO) 입장에서도 같은 페이지 안에 HTML이 존재 하기 때문에 팝업 안의 텍스트도 정상적으로 인덱싱될 수 있습니다. 즉, “레이어 팝업 센터 정렬”, “레이어 팝업 만드는 방법”과 같이 관련 키워드를 적절히 넣어주면 검색 노출에 도움이 됩니다. 2. 질문에서 주신 레이어 팝업 스타일 분석 질문에서 주신 스타일은 다음과 같습니다. <div class="layer-popup" style="width:1210px; z-index:9001; position:absolute; top:3.25%; left:50%; transform:translateX(-50%);"> 레이어 팝업 내용 <...