Developer's Development

[HTML] smarteditor2 텍스트에디터 (jQuery, thymeleaf) 본문

개발/HTML

[HTML] smarteditor2 텍스트에디터 (jQuery, thymeleaf)

mylee99 2024. 8. 16. 15:11
Case

목록 HTML 화면에서 팝업으로 등록/수정 작업을 관리하여, 한 페이지에 2개 에디터 삽입

Reference

- 네이버 스마트에디터 공식 가이드
- 이미지 업로드 기능이 필요하여, photouploader 폴더가 있는 2.8.2 version을 사용
https://naver.github.io/smarteditor2/user_guide/

- 팝업 오픈 시, 스마트에디터 iframe 영역의 style 중 height 값이 0으로 잡혀 노출이 되지 않는 이슈 해결
https://quantrader.tistory.com/141

- 이미지 업로드 기능 구현을 위한 추가 작업
https://junesker.tistory.com/16

파일

smarteditor2-2.8.2.3.zip 압축 해제 후, static 폴더 안에 smarteditor 폴더 생성하여 전체 파일 복붙
추가로, 인터셉터에서 해당 폴더 경로를 제외

HTML

1. fragment
- fOnBeforeUnload는 에디터 내용 변경 경고창 기능을 끄기 위해 사용

<div th:fragment="editor">
<script th:src="@{/smarteditor/js/HuskyEZCreator.js}"></script>
    <script type="text/javascript">
        const [[${oEditors}]] = [];
        nhn.husky.EZCreator.createInIFrame({
            oAppRef: [[${oEditors}]], elPlaceHolder: "[[${content}]]", sSkinURI: "/smarteditor/SmartEditor2Skin.html",
            htParams: {bUseToolbar: true, bUseVerticalResizer: true, bUseModeChanger: true, fOnBeforeUnload: function (){}},
            fCreator: "createSEditor2"
        });
    </script>
</div>


2. list

<!-- 기타 코드 제외 에디터 영역만 -->
<!-- 등록 팝업 내용 -->
<div class="editorarea" style="min-height: 300px;">
    <textarea id="addContent" name="addContent" style="width: 100%;" rows="13" cols="100"></textarea>
</div>
<!-- 수정 팝업 내용 -->
<div class="editorarea" style="min-height: 300px;">
    <textarea id="editContent" name="editContent" style="width: 100%;" rows="13" cols="100"></textarea>
</div>

<div th:replace="~{fragments/common/fragment :: editor(oEditors='oEditors1', content='addContent')}"></div>
<div th:replace="~{fragments/common/fragment :: editor(oEditors='oEditors2', content='editContent')}"></div>

 

Javascript
// 등록 팝업 오픈
function addPop() {
    // 스마트에디터 iframe reload (Reference의 이슈 해결 링크 참고)
    let srcUrl = $('#addContent_iframe').attr("src");
    $('#addContent_iframe').attr("src", srcUrl);
}

// 등록
function add() {
    oEditors1.getById["addContent"].exec("UPDATE_CONTENTS_FIELD",[]);
    const addContent = $.trim($("#addContent").val());

    if(!addContent || addContent=='&nbsp;' || addContent=='<p>&nbsp;</p>' || addContent=='<p><br></p>') return alert("등록 내용을 입력해 주세요.");

    // 기타 등록 로직 생략
}

// 수정 팝업 오픈
function editPop() {
    // 스마트에디터 iframe reload
    let srcUrl = $('#editContent_iframe').attr("src");
    $('#editContent_iframe').attr("src", srcUrl);
    
    // 내용 불러오기 로직 생략
    $("#editContent").text(data.termsCtts);
}

// 수정
function edit() {
    oEditors2.getById["editContent"].exec("UPDATE_CONTENTS_FIELD",[]);
    const editContent = $.trim($("#editContent").val());

    if(!editContent || editContent=='&nbsp;' || editContent=='<p>&nbsp;</p>' || editContent=='<p><br></p>') return alert("수정 내용을 입력해 주세요.");

    // 기타 수정 로직 생략
}

 
여기까지 하면 이미지 업로드 기능을 제외한 텍스트 에디터의 기능이 정상 작동한다.

이미지 업로드 기능을 위한 작업

1. attach_photo.js
- callFileUploader 함수의 sUrl을 실제 사용할 컨트롤러 URL로 수정 (싱글 이미지 업로드)
- callFileUploader 함수의 sCallback을 실제 callback html이 있는 파일 경로로 수정
- html5Upload 함수의 sUploadURL을 실제 사용할 Controller URL로 수정 (멀티 이미지 업로드)

2. Controller
- 1에서 수정한 URL에 맞춰 각자의 환경에 맞는 서버 이미지 업로드 방식으로 수정

Reference의 링크를 참고하여 작업을 진행해 보았는데, 
스마트에디터의 back단 이미지 전송 방식이 header에 encodeURIComponent이고
back단에서 이걸 받아 처리하기 위해선 request.getHeader와 같은 방식을 사용해야 한다.
하지만, 현재 프로젝트에서 사용 중인 파일 업로드의 방식은 input의 files[0]으로 MultipartFile 자체를 받아 처리 중이라 어떤 코드를 어떻게 변경하여 둘을 맞춰야 할지 고민하다가, 
일단 스마트에디터 메뉴에 있는 사진 첨부 기능을 활용한 방식이 아닌 textarea 영역에 드래그앤드랍으로 사진을 넣는 방식을 사용하기로 했다.
(이 경우 서버 작업이 필요하지 않고, base64로 변경해줌)


스마트에디터 세팅이 이미 완료된 프로젝트에서 활용하는 업무만 하다가,
처음 세팅부터 끝까지 다 해보니 재밌고 흥미로웠던 작업
java 개발자가 back단 포스팅을 해야 하는데.. 어쩌다 보니 요즘 들어 front만 올리는 것 같아 뭔가 잘못된 것 같기도,,
 
 

Comments