http://asrada2001.mireene.com/asrada/test/editable_text_test.html
제목을 정하기가 참 난감합니다...
그냥 수정이 가능한 텍스트라고만 하면 금방 이해가 안되니 부연 설명을 좀 하자면
스프레드시트와 비슷하게 보시면 되겠습니다.
그렇다고 엑셀의 엄청난 기능을 구현했구나..라고 생각하시면 곤란하겠구요....ㅡㅡ;
단순하게 테이블 셀이나 인라인 엘리먼트 안의 텍스트를 수정하게 해주는 스크립트입니다.
가계부를 대충 만들어 쓰다가 이 기능이 필요해서 만들어봤는데 요긴하게 쓰고 있어서 공개합니다.
블로그에 올린 글을 그대로 복사해서 올리는 관계로 반말에 노여워 마시길;;;;
=================================================
[editableText.js]
/*
작성자: 물결(asrada2001.mireene.com)
작성일: 2007-05-29
*/
function createEditor(callback){
var editor = new Editor();
editor.callback = callback;
try{
document.addEventListener('click',clickEventHandler,false);
}catch(e){
document.attachEvent('onclick',clickEventHandler);
}
return editor;
}
function clickEventHandler(e){
var evt = e || window.event;
var target;
if(evt.target){
target = evt.target;
}else{
target = evt.srcElement;
}
if(target.className.search('editable') > -1){
editor.editing(target);
}
}
function Editor(){
this.autosave = false;
this.source = null;
this.callback = null;
this.container = null;
this.frm = document.createElement('INPUT');
this.frm.className = 'editor';
this.frm.model = this;
this.frm.onkeydown = function(e){
var evt = e || window.event;
if(evt.keyCode == 13){
try{
evt.preventDefault();
}catch(ex){
evt.returnValue = false;
}
this.model.complete();
}
}
this.frm.onblur! = function(e){
if(this.model.autosave == true){
this.model.complete();
}else{
this.model.cancel();
}
}
}
Editor.prototype.editing = function(obj){
try{
this.container = obj;
if(obj.hasChildNodes() == false){
obj.appendChild(document.createTextNode(''));
}
this.source = obj.firstChild;
this.frm.value = this.source.nodeVal!ue;
this.frm.style.width = '100%';
if(this.container.style.textAlign != undefined && this.container.style.textAlign != ''){
this.frm.style.textAlign = this.container.style.textAlign;
}else if(this.container.align != undefined && this.container.align != ''){
this.frm.style.textAlign = this.container.align;
}else{
this.frm.style.textAlign = 'left';
}
this.container.replaceChild(this.frm,this.source);
this.frm.focus();
this.frm.value += '';
}catch(e){
}
}
Editor.prototype.cancel = function(){
this.finish();
}
Editor.prototype.complete = function(){
this.save();
this.finish();
if(this.callback instanceof Function){
this.callback(this.container);
}else{
}
}
Editor.prototype.finish = function(){
this.container.replaceChild(this.source,this.frm);
}
Editor.prototype.save = function(){
this.source = document.createTextNode(this.frm.value);
}
모듈을 페이지에 로드시키고 에디터 객체를 생성하면 준비는 끝.
<script type="text/javascript" src="editableText.js"></script>
<script type="text/javascript">
var editor = createEditor(callback);
function callback(obj){
}
</script>
사용자가 문서의 텍스트 부분을 클릭하면 텍스트 노드를 담고있는 container 객체의 className 속성에 'editable' 가 있는지 확인한 후 에디터 객체(INPUT)에 텍스트를 전달하고 텍스트노드와 에디터를 바꿔치기한다.
에디터는 싱글턴(singleton)으로 하나의 에디터가 문서 전역에서 동작한다.
autosave 속성이 true로 설정되면 에디터에서 수정후 포커스가 다른 곳으로 이동하면 자동으로 수정한 내용이 원본 텍스트 노드에 그대로 적용이 되고 반대로 false면 원 상태로 되돌린다.
autosave를 적용하지 않으면 사용자는 데이터 수정 후 엔터키를 눌러야 수정한 내용이 반영된다.
callback 함수를 지정하면 save() 메서드를 실행 후 callback 함수를 호출한다.
xmlHttpRequest 객체를 사용할 경우 동적으로 DB의 내용을 수정 할 수 있다.
원래는 source를 <span>태그에만 할당 하려했으나 셀작업에 쓰는게 더 좋을 것 같아서 'edtiable'을 className으로 갖는 모든 객체로 수정하였다.
하지만 변경 후 맘에 안드는 것이, 원글 너비(offsetWidth)의 반영이다.
<span>,<div>등 block 객체에 edtiable 을 적용하면 원글의 사이즈에 맞게 에디터의 사이즈를 조절할 수 있는 반면 테이블의 셀(TD)에 적용 할 경우 테이블 셀 크기에 맞춰버리니 맞춤 사이즈는 포기할 수 밖에 없다....
방법을 아시는 분은 코멘트를 부탁...^^;
*주의*
Editor는 멀티라인 편집을 지원하지 않는다.
<span>,<td>,<div>,<p> 의 엘리먼트에서 오직 가장 처음에 위치한 텍스트 노드를 편집 할 수 있다.
멀티라인 편집을 위해 Editor 객체에 에디터를 input과 textarea 두개로 구분하여 childNodes.lenth로 멀티라인 여부를 판별한 후 해당 엘리먼트에 맞는 에디터를 쓰게끔 리펙토링을 시도하였으나,
editing() 메서드와 finish() 메서드에서 replaceChild를 쓸 수 없고,
텍스트 노드 사이의 태그를 검출해야 하며, 멀티라인의 경우 줄바꿈 처리를 하는 등 코드가 복잡해지는 관계로 단문 인라인 엘리먼트에 이 스크립트를 사용할 것을 당부하는 것으로 대신한다.
'인터넷정보' 카테고리의 다른 글
팝업차단 체킹 스크립트 (0) | 2007.10.13 |
---|---|
팝업차단 체킹 스크립트 (0) | 2007.10.13 |
글씨의 색을 자동으로 변환시켜주는 함수 (0) | 2007.10.13 |
글씨의 색을 자동으로 변환시켜주는 함수 (0) | 2007.10.13 |
수정이 가능한 텍스트 (인라인텍스트에디터) (0) | 2007.10.13 |
이미지 슬라이드쇼 (0) | 2007.10.13 |
이미지 슬라이드쇼 (0) | 2007.10.13 |
폼에대한 142가지의 다양한 js 소스 (0) | 2007.10.13 |
폼에대한 142가지의 다양한 js 소스 (0) | 2007.10.13 |
실시간검색어 예제 - 다음(daum) 스타일 (0) | 2007.10.13 |