쏘댕

[Javascript] 네이버 스마트에디터 자바스크립트로 에디터에 내용 추가하기 본문

공부/Script

[Javascript] 네이버 스마트에디터 자바스크립트로 에디터에 내용 추가하기

ssodang 2015. 4. 17. 15:22


기존에 textarea로 되어있던 부분에 네이버 스마트에디터를 붙인 뒤 사진과 파일을 업로드 하고,

사진은 본문에 보여주고 파일은 링크를 걸어주도록 구현!

 

- 스마트 에디터 추가에 대한 내용은 다음에 -

<label for="content">Content</label>
<textarea id="content" name="contents" rows="15" cols="100">${post.contents}</textarea>

요렇게 하면 스마트에디터 모양새로 iframe이 뜨고 거기서 쓴 값을 요 textarea 값에 html형태로 저장해서 등록한다.



요 에디터에 사진을 넣는 부분은 스마트에디터에 이미 있지만 그냥 파일 올리는걸 어차피 구현했으니까 그걸로 했고 

파일은 올리고서 파일링크를 본문에 첨부파일 <= 요런 식으로 링크로 제공하도록 구현해야 했다.

 

사진이나 파일을 올리고서 올라간 url을 내려주는 부분을 ajax로 구현했는데,

IE에서 안된당 ㅠ_ㅠ


//ajax를 이용한 파일 업로드는 IE에서 FormData가 먹지 않아 iframe 방식으로 변경
function uploadFile(type) {
if(typeof FormData == "undefined"){
/*
* IE는 FormData undefined 뜨니까 요렇게 하면 된댔는데... 안된다 ㅠ_ㅠ
* files도 IE는 안된댄다 (IE8까지도 지원해야하는 걸 개발하고 있음..............)
*/
var formData = [];
formData.push(type, jQuery("input[name="+type+"]")[0].files[0]);
}
else{
var formData = new FormData();
formData.append(type, jQuery("input[name="+type+"]")[0].files[0]);
}

var serviceId = jQuery('#serviceId').val();
jQuery.ajax({
type: 'POST',
url : '/fileUpload.sso?serviceId='+serviceId+'&name='+jQuery("input[name="+type+"]")[0].value,
data : formData,
contentType: false,
processData: false,
enctype: "multipart/form-data",
success: function (responsemsg) {
if (responsemsg.match('<!DOC')) {
// 업로드 실패시 !
alert(responsemsg);
} else {
jQuery("#input_"+type).val('');
jQuery("#uploadButton_"+type).remove();

if(type === 'image'){
var sHTML = "<p><img src='"+responsemsg+"' /></p>";
oEditors.getById["content"].exec("PASTE_HTML", [sHTML]);
}else{
var sHTML = "<p><a href='"+responsemsg+"' target='_blank'>첨부파일</a></p>";
oEditors.getById["content"].exec("PASTE_HTML", [sHTML]);
}
}
},
error: function (e) {
alert('fail to file upload. try again.'+e);
}
});

}


 

그래서 빈 iframe을 생성해서 거기에 결과 받아다 넣는 것으로 우회해서 구현했다


 

스마트 에디터가 jindo를 쓰고 있는데, 얘도 $를 써서 jQuery랑 충돌이 난다.


그래서 처음에 충돌 금지 선언(?)하고,

jQuery.noConflict();


jQuery코드는

$('#id'); /* 요놈을 */ jQuery('#id'); /* 요렇게 풀어서 썼다 */

 

 

 

일단 아래는 파일 업로드 폼이다.

이미지 업로드와 파일(docx, pptx, xslx, pdf)에 대해 다르게 처리하기 때문에 두개의 인풋으로 구분했다.


<form id="file_form" name="file_form" action="/editor/fileUpload.sso?serviceId=${serviceId}" method="POST" enctype="multipart/form-data" >
<div class="cont_area">
<label id="image_label" for="input_image">Image</label>
<input id="input_image" name="image" type="file" accept="image/*" onchange="onChangeService('image');" />
</div>

<div class="cont_area">
<label id="doc_label" for="input_doc">Doc</label>
<input id="input_doc" name="doc" type="file" accept="*/*" onchange="onChangeService('doc');" />
</div>

<input name="name" id="name" type="hidden" />
<input name="type" id="type" type="hidden" />

<%-- iframe에는 hidden 등의 속성이 안먹으니까 가로, 세로, 테두리 0으로 지정해서 화면에 안보이도록 했다. --%>
<iframe style="border: 0;width: 0;height: 0;" id='file_iframe' name='file_iframe' src=""></iframe>
</form>

 

파일 선택시 onChangeService 함수를 부르는데,

요 함수는 업로드 버튼을 추가하기 위해서 콜한다.

 

즉, 파일 선택하면 업로드하는 버튼이 나타나고

해당 버튼을 누르면 서버에 파일를 업로드 한 후 파일이 올라간 url을 내려준다.

(파일 업로드 후 올라간 url 리턴해주는 부분은 java 로직에서 처리)


function onChangeService(type) {
if (jQuery('#input_' + type) != null && jQuery('#input_' + type).val() != '') {
if (jQuery('#uploadButton_' + type) != null) {
jQuery('#uploadButton_' + type).remove();
}
jQuery('#' + type + '_label').append('<img src="/upload.png" id="uploadButton_' + type + '" onclick="redirect(\'' + type + '\'); return false;" style="cursor: pointer; margin-left: 5px;" />');
} else {
if (jQuery('#uploadButton_' + type) != null) {
jQuery('#uploadButton_' + type).remove();
}
}
}


그러고 나면 업로드 버튼에 걸려있는 클릭 이벤트인 redirect(type) 함수가 호출된다.

type은 요기에서는 image, doc 두개로 나뉜다. (처리가 다르기 때문에 추가한 부분) 

 

function redirect(type) {
document.getElementById('file_form').target = 'file_iframe';
var callback = function () {
if (successFunction) {
successFunction(type);
}
jQuery('#file_iframe').unbind('load', callback);
};

jQuery('#file_iframe').bind('load', callback);

// 파일이 .tmp 파일로 변경되는데 ( 사내 프레임워크 때문일 수도 있음 )
// 요 부분이 자바단에 넘어가면서 그런건지 알수가 없어서 일단 파일명을 파라미터로 넘겨준다.
jQuery('#name').val(jQuery("input[name=" + type + "]")[0].value);

// 타입에 따라 자바단에서 파일이 지정된 포맷에 적합한지 검사하는 등의 로직이 있어 타입을 넘겨준다.
jQuery('#type').val(type);

jQuery('#file_form').submit();
}

 

iframe 콜백함수에서 콜하는 successFunction은 아래와 같다.

 

function successFunction(type) {
jQuery("#input_" + type).val(''); // input file 내용 지우기
jQuery("#uploadButton_" + type).remove(); // 업로드 버튼 추가했던거 지우기

// 자바에서 리턴주는값은 스트링(url 또는 error 텍스트)이라서 body 안에 있는 내용이 텍스트로 그냥 넘어올 줄 알았지만...
// 브라우저마다 다르게 <pre> 태그가 붙어서 넘어오는 것도 있었다. ( 브라우저별로 다른게 맞는지는 확인 필요 )
var bodyVal = jQuery('#file_iframe').contents().find('body').html();
var preVal = jQuery('#file_iframe').contents().find('pre').html();

// 그래서 pre 태그로 된 값이 있으면 그 내용을,
// pre 태그로 된게 없으면 body 내용을 적용하도록 했다.
var sHTML;
if (preVal !== undefined) {
sHTML = preVal;
} else {
sHTML = bodyVal;
}

if (sHTML === undefined) {
alert("undefined error");
} else {
if (sHTML.match("^error")) {
// error 인 경우 에러메세지 얼럿
// 자바단에서 "error : 이미지 파일 포맷이 올바르지 않습니다."와 같은 형식으로 리턴
alert(sHTML);
} else {
if (type === 'image') {
sHTML = "<p><img src='" + sHTML + "' style='max-width:100%;' /></p>"
} else {
sHTML = "<p><a href='" + sHTML + "' target='_blank'>첨부파일</a></p>"
}
oEditors.getById["content"].exec("PASTE_HTML", [sHTML]); // 요부분이 스마트에디터에 내용을 적용하는 부분이다.
}
}
}

 


억지 쓴 부분도 있는거 같지만.. 급해서 일단 패쓰ㅠ_ㅠ

브라우저별 스크립트 에러 이런 삽질은 너무 힘들당 @_@

 

 

[참고1] http://dev.naver.com/projects/smarteditor/issue/41796

[참고2] http://kaushikghosh12.blogspot.kr/2014/02/ajax-fileupload-on-all-browsers.html

 

 


Comments