명박도

원문 : http://blanc.kr/1155

우리나라에는 정말로 많은 섬들이 있습니다. 그 가운데에는 아직까지 정체가 밝혀지지 않은 섬들도 상당히 있는데, 최근에 그동안 신비에 싸여 있던 한 섬이 드디어 베일을 벗으면서 많은 관심이 집중되고 있습니다. 그 섬의 이름은 바로 명박도!


명박도의 자연과 지리

먼저 명박도에는 높이 솟아 있는 두 개의 봉우리가 있습니다. 이 봉우리는 각각 '줄파산'과 '줄도산'으로 명박도의 명물이라 할 수 있습니다. 사람이 살기 위해서는 식수가 필요하게 마련인데, 명박도의 두 봉우리에서는 각각 마르지 않는 식수가 나오고 있습니다. 이 두 식수의 이름은 각각 '어청수'와 '한승수'인데, 주로 '어청수'가 인기가 좋고 '한승수'는 있는 지 없는 지 모르는 사람들도 많습니다. '어청수'가 워낙 유명하다 보니 '어청수'가 나오는 발원지 주변에는 음식점과 술집도 눈에 뜨입니다. 여름에 워낙에 시원해서 많은 사람들이 찾는 대폿집인 '물대포'는 그 중에서도 가장 유명한 곳입니다.

그런데 명박도에는 물이 한 가지 더 있습니다. 그 물의 이름은 '강만수'인데, 워낙에 수질이 나빠서 사람은 도저히 먹을 수 없을 정도입니다. 하지만 일부 사람들은 이 물이 마셔도 문제가 없다면서 끼고 살기도 합니다. 심지어는 이 물에서 물고기가 살고 있다면서 이 물고기를 잡아서 뜬 회인 '소망교회'를 즐기는 사람들도 있습니다. '강만수'를 잘도 마시고 사는 이 종족은 'F족'이라고 부르는데, 늘 자신을 일컬어 'I am F'라고 부르는 버릇에서 유래되었다고 합니다. 최근 이 종족이 세력을 넓히고 있어서 명박도 주민들에게 위협이 되고 있습니다. 특히 'F족'은 최근 들어서 신형총탄인 '경제파탄'을 개발한 것으로 알려져서 더욱 위협이 되고 있습니다. 'F족'에게는 또다른 별명이 있는데 키가 아주 작고 장난을 좋아하는 개구쟁이라서 '개구쟁이 스와프'라고도 부릅니다.

하지만 전설에 따르면 명박도에는 이런 물보다 훨씬 질이 좋은 물이 흐르는 강인 '주가 3천'이라는 강이 있다고 합니다. 그러나 그저 말로만 존재할 뿐, 정말 '주가 3천'이 있는지는 도통 찾을 수가 없어서 역사학계에서는 아무래도 뻥인 것 같다는 쪽으로 정리되고 있습니다. 일설에는 수질이 영 나빠서 물고기도 살지 않는 강인 '비핵개방 3천'하고 헷갈리는 것 아니냐는 주장도 있습니다.

한편 명박도에는 천연자원도 상당히 매장되어 있는 것으로 알려져 있습니다. 특히 금의 일종인 '쌀직불금'은 많은 사람들 사이에 보물찾기 열풍을 불러 일으키면서 공무원이고 부자들이고 마지막 한 알까지 모조리 쓸어가 버렸다고 할 정도로 값비싼 귀금속이었다고 합니다. 또한 옥의 일종인 '전여옥'도 있는데 이상하게도 이 '전여옥'으로 구슬을 만들어서 은쟁반에 굴려 보면 은쟁반에 옥구슬 굴러가는 소리는 커녕 육식동물 풀 뜯어먹는 듣기 싫은 소리만 나서 별 인기가 없습니다.


명박도의 농업

명박도에는 '유인촌'이라는 마을이 있는데, 이 마을은 명마의 주산지로 유명해서 특산물인 '찍지마'는 많은 인기를 누리고 있습니다. 특히 보통 말들은 '이랴' 하고 외쳐야 뛰지만 이 '찍지마'는 '씨바'라고 외쳐야 성질이 뻗쳐서 뛰는 특이한 습성으로도 유명합니다.

명박도에서는 목축업이 발달해서 고품질의 달걀이 나오는 것으로도 유명한데, 특히 알이 큼직큼직하기로 소문난 '취업대란'이 요즘 들어서 인기를 누리고 있습니다. 게다가 양봉업도 상당히 발달해서 명박도의 자랑거리인 '재벌'이 만들어내는 꿀은 주요 특산물 가운데 하나입니다. 그런데 이 '재벌'은 조금 독특한 식습관이 있습니다. 평소에서는 꽃 사이를 돌아다니면서 꿀을 채집하지만 꽃이 시들어서 상황이 나쁠 때에는 물고기도 즐겨 먹는다는 것입니다. 특히 '재벌'이 좋아하는 물고기는 '휠체어'로서 '재벌'들이 '휠체어' 위에 올라타서 살점을 맛있게 먹는 모습을 종종 볼 수 있습니다.


명박도의 식생활

명박도에서 유명한 요리라고 하면 후라이드 치킨을 들 수 있습니다. 특히 명박도 명물 'BBK'는 상당히 높은 인기를 누려서 왕족들도 즐겼고, 심지어는 자신이 명박도에 'BBK' 체인점을 차렸다고 주장하는 왕족도 있었습니다만 뭐가 틀어졌는지 왕족의 미움을 받아서 결국 최근 문을 닫았다는 안타까운 사연도 있습니다. 또한 명박도에서 한때 인기가 높았던 빙과였던 하드 '미네르바' 역시도 명박도 왕족의 미움을 받는 바람에 판매 금지되었습니다. 당시 판매 금지 이유로 든 것은 '정부가 미네르바 가격 인상을 지시하는 공문을 보냈는데 실제로는 요청만 했지 공문을 보내지 않았다는' 조금 석연치 않은 내용이어서 많은 의혹을 불러 일으키고 있습니다.


명박도의 역사

명박도의 역사에 대해서는 별로 알려진 것은 없습니다. 다만 최근 고고학자들에 의해 금속 도구를 사용하기 이전 돌을 이용한 도구를 만들어 쓰던 '김석기'시대가 있었던 것으로 밝혀졌습니다. 특히 명박도의 야트막한 산인 '용산'에서는 이 '김석기'시대의 여러 가지 도구들이 발견되어 화제가 되고 있으며 특히 대형 컨테이너는 역사적 가치가 높은 유물로 '김석기'시대의 생활상을 연구하기 위해 고고학으로 유명한 대학인 '경찰특공대'에서 많은 연구가 진행되고 있습니다. 또한 이 비슷한 시대에 외적의 침입을 막기 위해서 세운 '명박산성'이라는 성 유적이 발굴되어서 역사학계의 관심을 끌고 있습니다.

물론 명박도의 각종 역사를 기록한 역사책이나 소설도 전해져 내려 옵니다. 특히 중국의 '삼국지'에 필적한다는 '어륀지'는 명박도 최고의 역사 소설로 그 이름을 드높이고 있으며 먼 옛날 동이족의 상고사까지 다루고 있는 역사책인 '한단고기'를 능가한다는 '미국쇠고기'도 역시 학계의 비상한 관심을 모으고 있습니다.


명박도의 문화

명박도는 상당한 수준의 문화를 자랑하고 있습니다. 먼저 명박도 사람들이 널리 믿고 있던 종교에 대해서 많은 학자들은 기독교라고 생각해 왔습니다만 놀랍게도 명박도의 종교는 불교였다는 사실이 밝혀졌습니다. 특히 명박도의 불교를 중흥시켰던 주역에 대한 전설이 최근 밝혀졌는데, 그는 스스로 '스님'이라는 존칭을 거부하고 '중'이라는 이름을 쓰기를 자청했던 고승 '최시중'이었다고 합니다. '최시중'은 특히 음악에 탁월한 재능이 있어서 명박도의 고유한 음악 장르인 '방송장악'을 제창한 것으로 알려져 있습니다. 그런데 이 음악을 연주하기 위해서는 말하기가 좀 거시기합니다만 생식기 주변의 털을 필요로 했다고 합니다. 그래서 최근 명박도에서는 '방송장악 음모'라는 악기가 발굴되어 학계의 비상한 관심을 모으고 있습니다.

비록 '방송장악'이 명박도의 전통 음악이긴 하지만 역시 젊은층에게는 락 음악이 큰 인기를 누리고 있습니다. 특히 최근 명박도에서 유행하고 있는 락 음악인 '주가폭락'은 폭발적인 반향을 얻고 있습니다. 그래서 최근 명박도의 젊은이들은 인기 차종인 '사이드카' 안에다가 '주가폭락'을 엄청나게 큰 볼륨으로 틀어대면서 과속 질주를 하는 게 유행이라서 이러한 고성방가가 새로운 사회 문제로 대두되고 있습니다.


아직까지 명박도는 많은 부분이 베일에 싸여 있는 신비의 섬입니다. 앞으로 더 많은 연구를 통해서 명박도에 대한 더 많은 사실들이 밝혀질 것이라 믿으면서, 관심 있는 분들의 많은 연구를 바랍니다.

댓글중에서.
몇가지 최신 연구 결과를 소개합니다.

1. 명박도의 명문대학인 청와대에서 동물 계통 분류학을 연구하는 학자들이 찍지마에 대해 조사한 결과, 발이 없다고 합니다. 그리고 하루에 천리를 간다는군요.
2. 전설에 의하면, 명박산성에서 벌어진 치열한 전투에서는 1만명의 소수 병력으로 100만 대군을 막기 위해 하루만에 명박산성을 축조했다고 합니다. 피라미드, 만리장성과 더불어 "어떻게 지었는지 도저히 알 수 없는 세계 3대 신비한 건축물"에 올라갈 것 같다는 역사학계의 연구 결과가 알려진 바 있습니다.
3. 명박산성의 치열한 전투는 그 일대에서 발굴된 대규모의 촛농 유적으로 그 흔적을 짐작할 수 있다고 합니다.
4. 식물 계통 분류학자들의 연구 결과도 있습니다. 명박도에는 다른 나라 어디에서도 발견되지 않은, 세계 유일의 명물인 "회로 먹을 수 있는 식물"인 "국"이라는 식물이 재배되고 있습니다. 이것의 회는 주로 사람들의 술안주로 식탁에 올라오는데, 1년에 재배 가능한 양이 300여 그루밖에 되지 않아 매우 비싼 음식입니다. 이 "국"을 생산하는 가문은 정품임을 증명하기 위해 금으로 만든 벳지를 포장에 붙여서 판매한다고 합니다.

염려스러운 점이 있다면 섬에 대한 계속적인 연구는 건강에 해로울수도 있지 않을까 싶습니다. 그 섬에 지네가 많은데..."속터지네" 라고 합니다. 물리면 약도 없데요..그 ""속터지네""는 소통이라는 통에 담아야 잡을수 있는데 그섬엔 소통이라는 통이 없다네요.... 선생님 부디 연구하시더라도 건강유념하세요 ...그섬 주민들은 ""민주화"라는 불을 지피며 사는데 요즘 그 ""민주화""가 꺼질듯 하면서 "독재"가 조금씩 휘날린다고 합니다. 숨쉬기도 버거워 질지도 모르갰네요.전설의 섬은 전설로 끝나길 바라며 ..

명박도에는 나경원 이라는 돈이 있는데 아무런 가치가 없어서 아무도 쓰지 않고
퍼세식 화장실에서 화장지 대신 쓰인다고 합니다.
명박도에 가려면 배를 타야 하는데 그 배 이름이 진성호라고 합니다만
아무도 타지 않고 발로 차고 도끼로 내려 쳐서 모양이 진상이라고 합니다.
명박도에는 식당이 하나 있고 장사가 안돼서 문을 닫았다고 하는데 메뉴가 정병국이였다고 하네요.
여러모로 문제가 심각한 섬입니다.
앞으로 우리나라의 모든 쓰레기는 이곳에 갔다 묻어서 제 2의 난지도로 활용하는게 좋을듯 싶습니다.


Posted by SADBLUE

2009/01/29 09:22 2009/01/29 09:22
, , , ,
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/231

Trackback URL : http://sadblue.com/trackback/231

채운국 이야기.

원래는 NT Noble이라는 일본의 소설 레이블에서 나온..(맞나.-_-;;;)
제목만 보고는 상당히 끌리고 있었는데.
양이 많길래..선뜻 손이 안가고있다가.-_-;
작년 여름엔가...
우연히 생긴 무료 다운로드 쿠폰을 쓸데가 없어서 그걸로 몽창 받아 봤었던...
기대 했던만큼 꽤 볼만 했던 터라...
만화책으로도 나오는 것을 다시 보고 있다.
이제 3권까지 나온듯..

그 예전 명랑만화라고 해야 하나.....
밝고 낙천적인 성격의 이쁜 여주인공이 나오는...
신데렐라...라고 해야하나...
여튼 순정만화의 전형적인 꽃미남들 나오고...
그의 사랑를 독점하는 가난한 여주인공...
가문은 상당한 가문인데....말이다..-_-;;
여튼...
3권중 맘에 드는 대사들...
이런 대사를 보면 누군가가 그렇게 좋아 했던 이유도 알것 같기도 하고...

외롭다고 느끼는 것은 사실은 혼자가 아니기 때문이다...
있어주길 바라는 사람이 곁에 없다는 것을 알게 되었기에...

여유가 생기다보니...
이것저것 생각만 많이지는 요즘이다...
어서 봄이 오기를....

Posted by SADBLUE

2009/01/19 22:36 2009/01/19 22:36
,
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/230

Trackback URL : http://sadblue.com/trackback/230

나츠메 우인장 2기.


1기로 끝나는줄 알았다.
전혀 알지 못하고 있다가 2기가 시작 됐음을 알게 되었고...
역시나 1기의 분위기를 그대로 이어가고 있었다.
귀신.원령 같은 주제를 하고 있음에도 불구하고
은은한 분위기와 냥코센세, 나츠메의 장난은 보는내나 만족스럽다.
이번 2기의 엔딩 사랑해 가 되려나..아이시떼루 라는 제목이니...
싱글앨범이 나온다는 말이 나오믄 후딱 찾아봐야지..

잘 있어요, 나츠메 님...잘 있어요..

잘 돌아갔을까..
괜찮겠지...너처럼 약해빠진 녀석이 생각하는 것만큼 요괴는 약하지 않다

그렇겠지
하지만 선생이 생각하는 만큼 나는 아직 이별에는 강하지 않아
그러니까
소중하다고 생각한 건 소중히 하며 살고 싶어
네가 하는 말은 언제나 모르겠구나

겨울이라 그런가...
소중하다고 생각한 건 소중히 하며 살고 싶다.

Posted by SADBLUE

2009/01/17 17:25 2009/01/17 17:25
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/229

Trackback URL : http://sadblue.com/trackback/229

미네르바 구속 100분토론.

보는 내내 짜증나고 답답했던 방송이었다.

작년 쥐박이가 대통령이 되고나서
물만수와 짝짝꿍을 하며 이지경으로 만들어놨다.
그러나 경제쪽의 원론적 지식이 부족한 일반인들은
미국 경제가 어려워 그랬다는 정부의 말을 믿을 수 밖에 없다.
조중동 찌라시들이 그렇게 뒤닦아주고 있으니까.

그 와중에 아고라에 나타난 미네르바가 나타나서 이건 이렇고 저건 저렇고 하며
일반인들의 무지를 깨우쳐 주게 되었다.
촛불집회의 배후네 어쩌네 하며 단단히 찍혀 있던 아고라다보니..
그 파장은 더욱 컸던 것이다.
(DC나 기타 다른 사이트에서 미네르바가 나타났다면 이렇게 까지 일이 커졌을까.?)
정부 정책의 가려두거나 알지 못했던 치부가 하나 둘 드러나고
이런 사실들을 설명해주는 미네르바는 국민의 신임을 얻게 되고
정부의 신뢰도는 더더욱 바닥을 기게된다.

그러다보니 정부를 까는 소리는 더더욱 높아지는 것이 당연하게 되고
여름에 네티즌에 크게 데인 쥐박이는 이게 두려웠는지
미네르바를 구속하게 된다.

죄목은 허위사실 유포죄.

여기서 한 상황의 예를 들어보자.
작년 대통령 선거때에 블로그스피어에서는 막판에 문국현 후보의 지지율이 꽤 높았었다.
그러나 결과는 어떠했는가.?
5~6%정도의 지지율이었다.

결국 인터넷의 어디에서 누군가 떠든다고 해도
그 외침은 그 지역을 벗어나지 않는다는 것이다.
아무리 언론이 미네르바를 띄워줬다고 해도
일반인들이 보기에는 그냥 기사에 나온 이름일 뿐이며 영향력이 미미 하다는 것이다.

미네르바의 한마디로 주식이 폭락하고 달러 사제기를 한다.?
좋다.그런 사람이 있다고 치자.
그게 얼마나 되겠는가.?
그의 발언을 기준으로 전과 후의 개인 투자자의 비율을 비교라도 해 보았는가.?
난 실제 그런 자료를 본 기억이 없다.

또 하나.
DC에서 유명한 둥신 이라는 사람이 있다.
이 사람과 반대로 주식 투자 하면 돈 번다는 전설을 남긴 둥신.
이 사람은 DC주식갤에서 자신은 이러저래 해서 여기 투자 하겠다
라는 글을 꽤 남긴것으로 알고 있다.
근데 상황은 정 반대로 나타난다.
이 사람도 아는 사람은 다 아는 상황을 만드는 사람이다.
DC주식갤의 사람들 몇몇은 재미로라도 이 사람과 반대되게 투자를 했을 수 있다.
오히려 이 사람이 무슨 말을 했다고 한다면
그것이 두려워 투자금을 다 회수 했을 수도 있다.
그럼 이 사람은 왜 안잡아 갔는가.?
DC주식갤에서 상당한 유명인이었는데 말이다.

강원도의 유명인이 언론에서 좀 띄워줬다고 전라도 가서 유명인일 수 있는가.?

김제동도 지금은 아주 유명하지만
처음엔 대군가 부산의 유명MC였다고 들었다.
그러다가 윤도현이 서울로 입성을 시켜주었고.
부단한 노력으로 지금의 위치까지 오게 되었다.

아고라의 유명한 경제박사가
전국의 유명한 경제박사가 될 수 있는 것인가.?

여기서 문제가 나타난다.
쥐박이는 저런 사람들이 두려웠던거다.
자신의 삽질이 다 뽀록날까봐.
그래서 모난 돌이 정 맞는다고.
본보기로 미네르바를 구속 한 것이다.

따라서 미네르바 구속의 문제는 법적문제가 아니라
이런 상황에 따른 해석으로 판단을 해야 한다고 생각 하는 것이다.
이것은 21세기의 분서갱유 인것이다.
쥐박이가 시황제쯤 된다면 아씨바 너 잘났다 라고 하며 울겠지.
기껏해야 촛불 무서워 땅속으로 숨은 쥐박이 주젠데 말이다.

나온 패널들은 원론적인 문제만 해대고...
보는 내내 짜증났다...

전원책 변호사...정말 실망 했다...
토론 하는데 신문 잡지의 기사를 왜 자꾸 들먹이냐 라는 질문은...
정말 할 말을 잃었다...
토론이 무엇인지 알고는 있는 것인가...

아.그리고 토론 내내 대외 신뢰도에 영향을 주었다고 하는데.
그 똑똑한 외국 언론 매체들이 듣보잡 수준으로 전락한 우리나라의 일개 네티즌이
그런 말을 한다고 해서 얼마나 신경을 쓸거라 보는가.?
이미 그들은 대부분 다 알고 있는 것들이었을텐데.

정작 미네르바를 구속 하고 나서 해외의 조롱거리가 되면서
추락한 국가 이미지는 어떻게 생각 하는 것인가.?

마지막으로.
신동아에 투고했다는 그 기사는 누가 거짓말인건가.?
대질 심문 해 보면 나오는거 아닌가.?
거짓이라면 독자를 우롱한 신동아는 허위사실 유포죄에 성립 하지 않는가.?
네티즌도 아닌 언론이라는 회사가 말이다.


쥐박이는 당장 머릿속의 삽을 지우라!!

사용자 삽입 이미지

Posted by SADBLUE

2009/01/16 16:37 2009/01/16 16:37

Trackback URL : http://sadblue.com/trackback/228

아 디런 페이징.-_-
덕분에 그나마 깔끔했던 xml이 아주 지저분해졌다.~_~;
페이징을 위한 param들도 머리를 아프게 했고.-_-
맨 첫 페이지와 맨 마지막 페이지의 링크를 없애는 방법도 머리 아팠다.~_~
여튼 결론은 table을 다 그리는게 어쩌면 더 편해 보일지 모르는 지저분해진 xml인것이다.;

변경점.
1. row data 가 0일때의 처리
2. xml data는 페이지 로딩 시 1번만 요청 하도록 수정
3. paging기능 추가.

고려사항
- paging으로 추가되는 내용역시 cell이기 때문에 기존에 만들어진
stCell클래스를 확장해서 사용. (소스에 주석 달려 있음)

이전에 좀 불친절 했던 소개라는 느낌이 들어서 좀 친절하게 설명 하겠음.-_-;;

view 역할을 하는 table.xml

<?xml version="1.0" encoding="UTF-8" ?>
<gabia>
    <tables>
        <notice>
            <rowCss>noticeRow1</rowCss>
            <rowCss>noticeRow2</rowCss>
            <rowCss>noticeRow3</rowCss>
            <row><![CDATA[noticeTitle^^<a href="#seq#">#title#</a>]]></row>
            <row><![CDATA[noticeAuthor^^#author#]]></row>
            <row><![CDATA[noticeCount^^#viewcount#]]></row>
            <row><![CDATA[noticeDate^^#regdate#]]></row>
            <paging>
                <pagingCss>pagingCell</pagingCss>
                <pageFunction>onclick="goPage('#PAGE#');"</pageFunction>
                <firstPage><![CDATA[<p class="firstPage" #FUNCTION#>FIRST</p> ]]></firstPage>
                <prevPage><![CDATA[<p class="nextPage" #FUNCTION#>PREV</p> ]]></prevPage>
                <currentPage><![CDATA[<p class="currentPage" >#PAGE#</p> ]]></currentPage>
                <otherPage><![CDATA[<p class="pageNumber" #FUNCTION#>#PAGE#</p> ]]></otherPage>
                <nextPage><![CDATA[<p class="nextPage" #FUNCTION#>NEXT</p> ]]></nextPage>
                <lastPage><![CDATA[<p class="firstPage" #FUNCTION#>LAST</p>]]></lastPage>
            </paging>
        </notice>
    </tables>
</gabia>
paging기능 문제로 paging element가 추가 되었다.
pagingCss : paging으로 추가된 td의 css name
pageFunction : page이동시 사용될 스크립트 함수의 형식. 인자는 Page번호만으로 한다.* 맨 마지막 페이지나 맨 처음 페이지일 경우에 링크를 막기 위해 이러한 구조를 취한다.
firstPage : 제일 앞으로 이동 하는 링크 template
prevPage : 현재 페이지 번호보다 1 작은 페이지로 이동하는 링크 template
currentPage : 현재 페이지 번호의 template
nextPage : 현재 페이지 번호보다 1 큰 페이지로 이동하는 링크 template
lastPage : 맨 마지막 페이지로 이동하는 링크 template

기본적으로 style의 cursor모양은 지정하지 않고 page번호 생성 할 때에 onmouseover event를 통해 style을 제어 하도록 한다.
cell을 생성하고 innerHTML을 이용해 문자열을 대입시 <p></p> 태그의 style 속성이 사라지는 버그인지 알수 없는 현상이 발생.

model 역할을 하는 table.php
<?
    $data = "[";
    $data .= "{\"seq\":\"166\",\"title\":\"test166\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"165\",\"title\":\"test165\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"164\",\"title\":\"test164\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"163\",\"title\":\"test163\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"162\",\"title\":\"test162\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"161\",\"title\":\"test161\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"160\",\"title\":\"test160\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"159\",\"title\":\"test159\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"158\",\"title\":\"test158\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"},
            {\"seq\":\"157\",\"title\":\"test157\",\"regdate\":\"2009.01.16\",\"author\":\"SADBLUE\",\"viewcount\":\"0\"}";
    $data .= "]";
   
    $param = "{\"layerid\":\"content\",\"listcount\":\"10\",\"pagingcount\":\"10\"}";

    $return_data = "{";
    $return_data .= "\"resultCode\" : 'SUCCESS',";
    $return_data .= "\"row\" : '10',";
    $return_data .= "\"total\" : '10',";
    $return_data .= "\"result\" : " . $data . ",";
    $return_data .= "\"message\" : '',";
    $return_data .= "\"layerID\" : '',";
    $return_data .= "\"pagingcount\" : '10',";
    $return_data .= "\"listcount\" : '10',";
    $return_data .= "\"param\" : " . $param . ",";
    $return_data .= "\"page\" : '1'";
    $return_data .= "}";

    echo($return_data);
?>
실제 개발을 한다라면 ajax call의 response는 위의 형식으로 되어야 함.
$pCode :결과코드
$pValue : json_encode를 이용해 만들어진 jsondata
$pMessage : message
$pLayerID : 작업 대상 layerid
$pParam : json_encode를 이용해 만들어진 parameter
$pRow : 실제 data의 row수
$pTotal : select된 전체 row수 - paging 관련 인자.
$pPage : 요청 받은 page ? paging 관련 인자.
$pPagingCount : page 번호가 보여지는 수. 몇 page부터  몇 page까지 하단에 보여지는지. - paging 관련 인자.
$pListCount : 게시판에 한번에 보여질 글의 수  - paging 관련 인자.

예전에 빠졌던 ajaxBasic.js

function getAjaxData(URL,params,func, interID)
{
    var myAjax = new Ajax.Request( URL,
        {
            asynchronous: true,
            method: "post",
            parameters: params,
            onSuccess: function(xmlHttp){
                //alert(xmlHttp.responseText);
                try
                {
                    var data = eval('(' + xmlHttp.responseText + ')');
                }
                catch(E)
                {
                    alert("AjaxCall : " + E + " - " + xmlHttp.responseText);
                    return;
                }
                //alert(xmlHttp.responseText);
                func(data);
            },
            onFailure : function (request)
            {
                func("FAIL");
                return;
            }
        }
    );
}

control 역할의 table.js (xmlParser는 이전 post참조.)

/********************************************************************************
    ajax를 이용한 json data를 parsing해서 table을 그리는 class
    작성자 : 이정훈 (ljhoon@gabia.com)
    작성일 : 2009.01.13
    수정일 : 2009.01.15 - paging 기능 완료
********************************************************************************/

var tableXML = "http://local.inmail.co.kr/xml/table.xml";
// 로컬에서 개발 하던 url이므로 테스트 하는 곳의 url로 수정

/********************************************************************************
 stCell : td를 구성하기 위한 기본 정보를 갖게 되는 구조체 성격의 Class
     만약 td에 정의 해야 할 속성이 늘어나면 xml에 ^^ 구분자를 이용해서
     추가를 하고 stCell class에도 속성을 추가 해 주면 된다.
********************************************************************************/
var stCell = Class.create();
stCell.prototype = {
    cssName : null,
    cellData : null,

    initialize : function(pData)
    {
        if (pData == null) this.setNullData();
        else
        {
            if (pData.length < 1)
            {
                this.setNullData();
            }
            else
            {
                this.cssName = pData[0];
                this.cellData = pData[1];
            }
        }
    },

    getCss : function()
    {
        return this.cssName;
    },

    getData : function()
    {
        return this.cellData;
    },

    setData : function(pValue)
    {
        this.cellData = pValue;
    },

    setNullData : function()
    {
        this.cssName = "nodata";
        this.cellData = "nodata";
    }
};

/********************************************************************************
 stPaging : paging cell의 내용을 위한 구조체 성격의 class
     기본적인 stCell보다 디자인적 요소가 많기 때문에 상속받아 구현.
     paging node를 인자로 받는다.
     다중 상속을 위해 임시 객체를 하나 더 만든다.
     paging또한 td(cell)이기 때문에 stCell객체를 확장한다.
********************************************************************************/
var stTemp = Class.create();
stTemp.prototype = Object.extend (new xmlParser, new stCell);

var stPaging = Class.create();
stPaging.prototype = Object.extend (new stTemp, {
    m_oFirst : null,
    m_oPrev : null,
    m_oNumber : null,
    m_oCurrent : null,
    m_oNext : null,
    m_oLast : null,
    m_oFunction : null,

    initialize : function(pData)
    {
        this.getPagingTemplate(pData);
    },

    getPagingTemplate : function(pData)
    {
        if (pData == null)
            return ("paging row Info is null");
        else
        {
            try
            {
                this.cssName = this.getValue(this.getNode(pData, "pagingCss"));
                this.m_oFirst = this.getValue(this.getNode(pData, "firstPage"));
                this.m_oPrev = this.getValue(this.getNode(pData, "prevPage"));
                this.m_oCurrent = this.getValue(this.getNode(pData, "currentPage"));
                this.m_oNumber = this.getValue(this.getNode(pData, "otherPage"));
                this.m_oNext = this.getValue(this.getNode(pData, "nextPage"));
                this.m_oLast = this.getValue(this.getNode(pData, "lastPage"));
                this.m_oFunction = this.getValue(this.getNode(pData, "pageFunction"));
            }
            catch(E)
            {
                alert("Paging Node select fail : " + E);
                return;
            }
        }
    },
   
    setData : function (pPage, pTotal, pListCount, pPagingCount)
    {
        //alert(pPage + " - " + pTotal + " - " + pListCount + " - " + pPagingCount);
        var firstPage = 1;
        var lastPage = Math.ceil(pTotal / pListCount);

        var half = parseInt(pPagingCount/2, 10);

        var startPage = (pPage > half)?(pPage - half) : 1;
        var endPage = startPage + pPagingCount - 1;

        if (pListCount < lastPage)
        {
            endPage = (endPage > lastPage)?lastPage : endPage;
            startPage = ( (endPage - pPagingCount) < startPage )?(endPage - pPagingCount + 1) : startPage;
        }
        else
        {
            endPage = lastPage;
            startPage = firstPage;
        }
       
        prevPage = ((pPage -1) <= 0)?1:pPage-1;
        nextPage = ((pPage+1) > endPage)?pPage : (pPage +1);

        var pagingBuffer = "";

        //alert(half + " - " + startPage + " - " + endPage + " - " + lastPage);
/*
    맨 끝 페이지나 맨 마지막 페이지의 링크를 막기 위해 이런 구조를 취함.
*/
        var regPage = new RegExp("#PAGE#", "ig");
        var overCursor = " onmouseover=\"this.style.cursor='pointer';\"";

        if (pPage == firstPage)
        {
            pagingBuffer += this.m_oFirst.replace(/#FUNCTION#/ig, "");
            pagingBuffer += this.m_oPrev.replace(/#FUNCTION#/ig, "");
        }
        else
        {
            pagingBuffer += (this.m_oFirst.replace("#FUNCTION#", this.m_oFunction + overCursor)).replace(regPage, firstPage);
            pagingBuffer += (this.m_oPrev.replace("#FUNCTION#", this.m_oFunction + overCursor)).replace(regPage, prevPage);
        }

        for (var i=startPage ; i<=endPage ; ++i)
            pagingBuffer += (i == pPage)? this.m_oCurrent.replace(regPage, i) : (this.m_oNumber.replace("#FUNCTION#", this.m_oFunction + overCursor)).replace(regPage, i);

        if (pPage == lastPage)
        {
            pagingBuffer += (this.m_oNext.replace("#FUNCTION#", "")).replace(regPage, nextPage);
            pagingBuffer += (this.m_oLast.replace("#FUNCTION#", "")).replace(regPage, lastPage);
        }
        else
        {
            pagingBuffer += (this.m_oNext.replace("#FUNCTION#", this.m_oFunction + overCursor)).replace(regPage, nextPage);
            pagingBuffer += (this.m_oLast.replace("#FUNCTION#", this.m_oFunction + overCursor)).replace(regPage, lastPage);
        }

        this.cellData = pagingBuffer;
    }
});

/********************************************************************************
 stRow : td 배열을 갖게 되는 row 구조체 class
     row별 배경색이 다른 경우를 위해 css이름 속성을 갖는다.
********************************************************************************/
var stRow = Class.create();
stRow.prototype = {
    m_stCells : null,
    m_oCss : null,
    length : 0,

    initialize : function()
    {
        this.m_oCss = new Array();
        this.m_stCells = new Array();
    },

    insert : function(pCell)
    {
        this.m_stCells[this.m_stCells.length] = pCell;
        this.length++;
    },

    setCss : function(pCss)
    {
        if (typeof(pCss) != "Object")
            this.m_oCss[this.m_oCss.length] = pCss;
        else if (pCss.length > 1)
        {
            var cssCount = pCss.length;
            for (var i=0 ; i<cssCount ; ++i)
                this.m_oCss[cssCount + i] = pCss[i];
        }
    },

    getCell : function(pIndex)
    {
        if (this.m_stCells.length >= pIndex)
        {
            return this.m_stCells[pIndex];
        }
    },

    getColumnCount : function()
    {
        return this.m_stCells.length;
    },

    getCssCount : function()
    {
        return this.m_oCss.length;
    },

    getCss : function(pIndex)
    {
        if (this.m_oCss.length > pIndex)
            return this.m_oCss[pIndex];
        else
            return this.m_oCss[0];
    }
};

/********************************************************************************
 TableTemplate : Table Template XML정보를 가져온다.
 (Table class 생성마다 xml을 읽어오게 되어 있어서 따로 분리)
********************************************************************************/
var TableTemplate = Class.create();
TableTemplate.prototype = Object.extend (new xmlParser, {
    xmlTemplate : null,

    initialize : function()
    {
        this.loadXML();
    },

/********************************************************************************
 table 구조 xml을 읽어 오는 부분. 동기로 처리 했음.
********************************************************************************/
    loadXML : function()
    {
        new Ajax.Request(tableXML, {
            asynchronous: false,
            method: "get",
            onSuccess: function(xmlHttp)
            {
                try
                {
                    xmlTemplate = xmlHttp.responseXML;
                    return true;
                }
                catch(E)
                {
                    xmlTemplate = null;
                    alert("XML Load Fail : " + E);

                    return false;
                }
            },
            onFailure : function (request)
            {
                xmlTemplate = null;
                alert("Table Template XML Request Fail");
                return false;
            }
        });
    },

    getTemplate : function()
    {
        return xmlTemplate;
    }
});

var TemplateInfo = new TableTemplate();

/********************************************************************************
 Table : stRow, stCell을 이용해 실제 Table row를 그린다.
********************************************************************************/
var Table = Class.create();
Table.prototype = Object.extend (new xmlParser, {
    m_nRow : 0,
    m_oData : null,
    m_oTableID : null,
    m_oRowTemplate : null,
    m_oDefaultRowCss : null,
    xmlBuffer : null,
    m_oRows : null,
    m_bHeaderExist : true,
    m_bPaging : true,
    m_oParam : null,
    m_nTotal : 0,
    m_nPagingCount :0,
    m_nListCount : 10,
    m_nPage : 1,
    m_oMessage : null,

/********************************************************************************
 pData : json data
 pTableID : target table id
 pHeaderExist : 테이블 column별 제목이 있다면 true 없다면 false.
      table을 그리기 전에 true이면 1줄을 남기고 없다면 모든 row를 지운다.
********************************************************************************/
    initialize : function(pData, pTableID, pHeaderExist, pPaging)
    {
        if (pData != null)
        {
            this.m_nRow = parseInt(pData.row, 10);
            this.m_oData = pData.result;
            this.m_oTableID = pTableID;
            this.m_bHeaderExist = pHeaderExist;
            this.m_bPaging = pPaging;
            this.m_nListCount = pData.listcount;
            this.m_nPagingCount = parseInt(pData.pagingcount, 10);
            this.m_nTotal = parseInt(pData.total, 10);
            this.m_oParam = pData.param;
            this.m_nPage = parseInt(pData.page, 10);

            xmlBuffer = TemplateInfo.getTemplate();
        }
        this.m_oMessage = pData.message;
    },

/********************************************************************************
 table의 row와 total값을 기준으로 table data가 있는지 여부를 확인한다.
********************************************************************************/
    hasRow : function()
    {
        return (this.m_nTotal > 0 && this.m_nRow > 0)?true : false;
    },
/********************************************************************************
 xml에 정의된 각 td별 설정을 읽어와 rowTemplate 객체를 만든다.
 row별 css정보도 여기서 설정한다. css가 명시된 수 만큼 적용된다.
********************************************************************************/
    getRowTemplate : function()
    {
        if (xmlBuffer == null)
            return ("table row Info is null");
        else
        {
            try
            {
                this.m_oRows = null;
                this.m_oRows = new stRow();

                var objectNode = this.getNode(xmlBuffer, this.m_oTableID);
                var cssTemp = this.getNodeAll(objectNode, "rowCss");

                for(var i=0 ; i<cssTemp.length ; ++i)
                    this.m_oRows.setCss(this.getValue(cssTemp[i]));

                var rowTemp = this.getNodeAll(objectNode, "row");

                for(var i=0 ; i<rowTemp.length ; ++i)
                {
                    var templateValue = this.getValue(rowTemp[i]);
                    this.m_oRows.insert(new stCell(templateValue.split("^^")));
                }
            }
            catch(E)
            {
                alert("Node select fail : " + E);
                return;
            }
        }
    },

/********************************************************************************
 실제로 table row를 생성 하는 부분
 row를 추가 하기 전에 기존에 그려진 모든 row를 지운다.
 json의 인덱스 명은 xml에서 명시한 delimiter명과 같아야 한다.
********************************************************************************/
    insertRow : function()
    {
        if (!this.hasRow())
        {
            var row = $(this.m_oTableID).insertRow(-1);
            var c = row.insertCell(-1);
           
            c.className = "nodata";
            c.colSpan = 10;
            c.innerHTML = this.m_oMessage;
            return;
        }
        if ($(this.m_oTableID) == null)
        {
            alert("Base Table is null.");
            return;
        }

        if ($(this.m_oTableID).rows.length > 1)
        {
            if (this.m_bHeaderExist)
            {
                for(var i=($(this.m_oTableID).rows.length-1) ; i>0 ; --i)
                    $(this.m_oTableID).deleteRow(i);
            }
            else
            {
                for(var i=($(this.m_oTableID).rows.length-1) ; i>=0 ; --i)
                    $(this.m_oTableID).deleteRow(i);
            }
        }

        this.getRowTemplate();

        for(var i=0 ; i<this.m_nRow ; ++i)
        {
            var nLoopCount = 0;
            var row = $(this.m_oTableID).insertRow(-1);
            row.className = this.m_oRows.getCss( (i+1)%this.m_oRows.getCssCount() );

            for (var j=0 ; j<this.m_oRows.length ; ++j)
            {
                var c = row.insertCell(-1);
                var tempCell = this.m_oRows.getCell(nLoopCount).getData();

                for(var tempIndex in this.m_oData[i])
                {
                    var delimiter = new RegExp("#" + tempIndex + "#", "ig");
                    tempCell = tempCell.replace(delimiter, this.m_oData[i][tempIndex]);
                }

                c.innerHTML = tempCell;
                c.className = this.m_oRows.getCell(nLoopCount).getCss();
                nLoopCount++;
            }
        }

        // page 표시가 true이면 표시 한다.
        if (this.m_bPaging) this.paging();
    },

/********************************************************************************
 table pagin 처리
********************************************************************************/
    paging : function()
    {
        var pagingCell = new stPaging(this.getPagingTemplate());

        var row = $(this.m_oTableID).insertRow(-1);
        var c = row.insertCell(-1);

        pagingCell.setData(this.m_nPage, this.m_nTotal, this.m_nListCount, this.m_nPagingCount);

        c.colSpan = this.m_oRows.getColumnCount();
        c.className = pagingCell.getCss();
        c.innerHTML = pagingCell.getData();
    },

    getPagingTemplate : function()
    {
        if (xmlBuffer == null)
            return ("paging row Info is null");
        else
        {
            try
            {
                var objectNode = this.getNode(xmlBuffer, this.m_oTableID);
                return this.getNode(objectNode, "paging");
            }
            catch(E)
            {
                alert("Paging Node select fail : " + E);
                return;
            }
        }
    },

    getParam : function()
    {
        return this.m_oParam;
    }
});

사용 sample table.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>test</title>
    <script language="javascript" type="text/javascript" src="/scripts/prototype.js"></script>
    <script language="javascript" type="text/javascript" src="/scripts/ajaxBasic.js"></script>
    <script language="javascript" type="text/javascript" src="/scripts/simpleXml.js"></script>
    <script language="javascript" type="text/javascript" src="/scripts/table.js"></script>
   
    <style type="text/css">
        p, table, div { float:left; position:relative; display:inline-block; padding:0; margin:0; }
       
        #list { width:800px; border:solid 1px #dddddd; }
        #list #notice {width:600px; font-size:11px; font-family : 맑은고딕, Lucida Grande, Verdana, Sans-serif;}
        #list #notice tr { height:20px; }
        #list #notice .noticeHeader {font-weight:bold; text-align:center;}
        #list #notice .noticeRow1 {border-bottom:solid 1px #dddddd; }
        #list #notice .noticeRow2 {border-bottom:solid 1px #dddddd; background-color:#dddddd; }
        #list #notice .noticeRow3 {border-bottom:solid 1px #dddddd; background-color:#aaaaaa; }
       
        #list #notice .noticeTitleHead {width:250px;}
        #list #notice .noticeDateHead {width:75px;}
        #list #notice .noticeCountHead {width:75px; text-align:right;}
        #list #notice .noticeAuthorHead {width:100px;}
        #list #notice .noticeBoardHead {width:100px;}

        #list #notice .currentPage {font-weight:bold; width:15px;}
        #list #notice .pageNumber { width:15px;}
        #list #notice .firstPage { width:35px;}
        #list #notice .nextPage { width:35px;}
       
        #list #notice .pagingCell { width:100%; height:25px; padding-left:8%;}
        #list #notice .nodata { width:100%; text-align:center; height:50px; font-weight:bold;}

        #list2 { width:800px; border:solid 1px #dddddd; }
        #list2 #freeboard {width:600px; font-size:11px; font-family : 맑은고딕, Lucida Grande, Verdana, Sans-serif;}
        #list2 #freeboard tr { height:20px; }
        #list2 #freeboard .freeHeader {font-weight:bold; text-align:center;}
        #list2 #freeboard .freeRow {border-bottom:solid 1px #dddddd; }
       
        #list2 #freeboard .freeTitleHead {width:250px;}
        #list2 #freeboard .freeDateHead {width:75px;}
        #list2 #freeboard .freeCountHead {width:75px;}
        #list2 #freeboard .freeAuthorHead {width:100px;}
        #list2 #freeboard .freeBoardHead {width:100px;}
    </style>
</head>
<body>
<div>
    <div id="list">
        <table id="notice">
            <tr class="noticeHeader"><td class="noticeTitleHead">제목</td><td class="noticeAuthorHead">등록자</td><td class="noticeCountHead">조회수</td><td class="noticeDateHead">작성일</td></tr>
        </table>
    </div>
</div>
<input type="button" value="test" onclick="getData();">

<script language="javascript">
    var objTable2 = null;    // page당 1번의 xml 로딩을 위해 페이지 전역변수로 선언
    var param = $H({'page' : 1, 'layerid' : "content", 'listcount' : 10, 'pagingcount' : 10});
    // 초기 값을 넘긴다.

    function getData()
    {
        getAjaxData('/table.php', param, rowAppend);
    }
   
    function rowAppend(pValue)
    {
        objTable2 = new Table(pValue, "notice", true, true);
        objTable2.insertRow();
    }
</script>
   
</body>

</html>

테스트 방법
1. 웹서버의 특정 위치에 table.xml을 저장한다.
2. table.js의 주소를 맞게 변경한다.
3. table.php를 웹 서버에 저장한다.
4. table.html의 getData() 함수에서 table.php를 호출 하는 주소를 맞게 수정한다.
5. table.html의 버튼을 누르면 table이 그려질 것이다.

Posted by SADBLUE

2009/01/16 11:39 2009/01/16 11:39
, , , , ,
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/227

Trackback URL : http://sadblue.com/trackback/227

20세기 땅박이.

원본 주소 : http://www.mediamob.co.kr/wizmusa/blog.aspx?id=226678

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

Posted by SADBLUE

2009/01/15 19:12 2009/01/15 19:12
, , , ,
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/226

Trackback URL : http://sadblue.com/trackback/226

json data를 이용한 동적 table 만들기.

model sample

<?
    $data = "[";
    $data .= "{" . "\"no\" : '1793', \"gw_user_info_no\" : '230',\"gw_board_info_no\" : '43',\"title\" : '[메신저] -제안- 채팅 저장 기능 업글',\"name\" : '이정훈',\"readnum\" : '9',\"write_datetime\" : '2009-01-12 11:07:23',\"write_date\" : '09-01-12',\"new_img\" : 'Y',\"poll_img\" : 'N',\"hidden_key\" : 'N',\"depth\" : '0',\"del_flag\" : 'N',\"board_name\" : '메신저 버그/제안',\"board_type\" : 'N', \"attach_cnt\" : '0', \"reply_cnt\" : '0', \"down_cnt\" : '', \"startPage\" : '2', \"current_user_level\" : '2'" . "},";
    $data .= "{" . "\"no\" : '1793', \"gw_user_info_no\" : '230',\"gw_board_info_no\" : '43',\"title\" : '[메신저] -제안- 채팅 저장 기능 업글',\"name\" : '이정훈',\"readnum\" : '9',\"write_datetime\" : '2009-01-12 11:07:23',\"write_date\" : '09-01-12',\"new_img\" : 'Y',\"poll_img\" : 'N',\"hidden_key\" : 'N',\"depth\" : '0',\"del_flag\" : 'N',\"board_name\" : '메신저 버그/제안',\"board_type\" : 'N', \"attach_cnt\" : '0', \"reply_cnt\" : '0', \"down_cnt\" : '', \"startPage\" : '2', \"current_user_level\" : '2'" . "},";
    $data .= "{" . "\"no\" : '1793', \"gw_user_info_no\" : '230',\"gw_board_info_no\" : '43',\"title\" : '[메신저] -제안- 채팅 저장 기능 업글',\"name\" : '이정훈',\"readnum\" : '9',\"write_datetime\" : '2009-01-12 11:07:23',\"write_date\" : '09-01-12',\"new_img\" : 'Y',\"poll_img\" : 'N',\"hidden_key\" : 'N',\"depth\" : '0',\"del_flag\" : 'N',\"board_name\" : '메신저 버그/제안',\"board_type\" : 'N', \"attach_cnt\" : '0', \"reply_cnt\" : '0', \"down_cnt\" : '', \"startPage\" : '2', \"current_user_level\" : '2'" . "},";
    $data .= "{" . "\"no\" : '1793', \"gw_user_info_no\" : '230',\"gw_board_info_no\" : '43',\"title\" : '[메신저] -제안- 채팅 저장 기능 업글',\"name\" : '이정훈',\"readnum\" : '9',\"write_datetime\" : '2009-01-12 11:07:23',\"write_date\" : '09-01-12',\"new_img\" : 'Y',\"poll_img\" : 'N',\"hidden_key\" : 'N',\"depth\" : '0',\"del_flag\" : 'N',\"board_name\" : '메신저 버그/제안',\"board_type\" : 'N', \"attach_cnt\" : '0', \"reply_cnt\" : '0', \"down_cnt\" : '', \"startPage\" : '2', \"current_user_level\" : '2'" . "},";
    $data .= "{" . "\"no\" : '1793', \"gw_user_info_no\" : '230',\"gw_board_info_no\" : '43',\"title\" : '[메신저] -제안- 채팅 저장 기능 업글',\"name\" : '이정훈',\"readnum\" : '9',\"write_datetime\" : '2009-01-12 11:07:23',\"write_date\" : '09-01-12',\"new_img\" : 'Y',\"poll_img\" : 'N',\"hidden_key\" : 'N',\"depth\" : '0',\"del_flag\" : 'N',\"board_name\" : '메신저 버그/제안',\"board_type\" : 'N', \"attach_cnt\" : '0', \"reply_cnt\" : '0', \"down_cnt\" : '', \"startPage\" : '2', \"current_user_level\" : '2'" . "}";
    $data .= "]";

    $return_data = "{";
    $return_data .= "\"resultCode\" : 'OK',";
    $return_data .= "\"row\" : '5',";
    $return_data .= "\"column\" : '5',";
    $return_data .= "\"result\" : " . $data . ",";
    $return_data .= "\"message\" : '',";
    $return_data .= "\"layerID\" : ''";
    $return_data .= "}";

    echo($return_data);
?>

view xml definition
<?xml version="1.0" encoding="UTF-8" ?>
<gabia>
    <tables>
        <notice>
            <rowCss>noticeRow1</rowCss>
            <rowCss>noticeRow2</rowCss>
            <rowCss>noticeRow3</rowCss>
            <row><![CDATA[noticeTitle^^<a href="#no#">#title#</a>]]></row>
            <row><![CDATA[noticeAuthor^^#name#]]></row>
            <row><![CDATA[noticeCountHead^^#readnum#]]></row>
            <row><![CDATA[noticeDateHead^^#write_date#]]></row>
            <row><![CDATA[noticeBoardHead^^#board_name#]]></row>
        </notice>
    </tables>
</gabia>

control class

/********************************************************************************
참조 : http://phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=51107&sca=%BD%BA%C5%A9%B8%B3%C6%AE&sfl=wr_subject&stx=xml&sop=and
prototype을 이용한 xml parser class
********************************************************************************/

var xmlParser = Class.create();
xmlParser.prototype = {
    initialize: function()
    {
    },
    getNode: function (xml, tag)
    { // 싱글노드
        return xml.getElementsByTagName(tag)[0];
    },
    getNodeAll: function (xml, tag)
    { // 멀티노드
        return xml.getElementsByTagName(tag);
    },
    getValue: function (xml)
    { // 노드값 가져오기
        try
        {
            return xml.firstChild.nodeValue;;
        }
        catch(E)
        {
            alert(E);
        }
    }
};

/********************************************************************************
    ajax를 이용한 json data를 parsing해서 table을 그리는 class
    작성자 : 이정훈 (ljhoon@gabia.com)
    작성일 : 2009.01.13
********************************************************************************/

var tableXML = "http://local.inmail.co.kr/test.xml";

/********************************************************************************
 stCell : td를 구성하기 위한 기본 정보를 갖게 되는 구조체 성격의 Class
     만약 td에 정의 해야 할 속성이 늘어나면 xml에 ^^ 구분자를 이용해서
     추가를 하고 stCell class에도 속성을 추가 해 주면 된다.
********************************************************************************/
var stCell = Class.create();
stCell.prototype = {
    cssName : null,
    cellData : null,

    initialize : function(pData)
    {
        if (pData.length < 1)
        {
            this.setNullData();
            return;
        }

        this.cssName = pData[0];
        this.cellData = pData[1];
    },

    getCss : function()
    {
        return this.cssName;
    },

    getData : function()
    {
        return this.cellData;
    },

    setData : function(pValue)
    {
        this.cellData = pValue;
    },

    setNullData : function()
    {
        this.cssName = "nodata";
        this.cellData = "nodata";
    }
};

/********************************************************************************
 stRow : td 배열을 갖게 되는 row 구조체 class
     row별 배경색이 다른 경우를 위해 css이름 속성을 갖는다.
********************************************************************************/
var stRow = Class.create();
stRow.prototype = {
    m_stCells : null,
    m_oCss : null,
    length : 0,

    initialize : function()
    {
        this.m_oCss = new Array();
        this.m_stCells = new Array();
    },

    insert : function(pCell)
    {
        this.m_stCells[this.m_stCells.length] = pCell;
        this.length++;
    },

    setCss : function(pCss)
    {
        if (typeof(pCss) != "Object")
            this.m_oCss[this.m_oCss.length] = pCss;
        else if (pCss.length > 1)
        {
            var cssCount = pCss.length;
            for (var i=0 ; i<cssCount ; ++i)
                this.m_oCss[cssCount + i] = pCss[i];
        }
    },

    getCell : function(pIndex)
    {
        if (this.m_stCells.length >= pIndex)
        {
            return this.m_stCells[pIndex];
        }
    },

    getColumnCount : function()
    {
        return this.m_stCells.length;
    },

    getCssCount : function()
    {
        return this.m_oCss.length;
    },

    getCss : function(pIndex)
    {
        if (this.m_oCss.length > pIndex)
            return this.m_oCss[pIndex];
        else
            return this.m_oCss[0];
    }
};

/********************************************************************************
 Table : stRow, stCell을 이용해 실제 Table row를 그리고 구조 정보 xml을 읽어온다.
********************************************************************************/
var Table = Class.create();
Table.prototype = Object.extend (new xmlParser, {
    m_nCol : 0,
    m_nRow : 0,
    m_oData : null,
    m_oTableID : null,
    m_oRowTemplate : null,
    m_oDefaultRowCss : null,
    xmlBuffer : null,
    m_oRows : null,
    m_bHeaderExist : true,

/********************************************************************************
 pData : json data
 pTableID : target table id
 pHeaderExist : 테이블 column별 제목이 있다면 true 없다면 false.
      table을 그리기 전에 true이면 1줄을 남기고 없다면 모든 row를 지운다.
********************************************************************************/
    initialize : function(pData, pTableID, pHeaderExist)
    {
        this.m_nColumn = pData.row;
        this.m_nRow = pData.column;
        this.m_oData = pData.result;
        this.m_oTableID = pTableID;
        this.m_bHeaderExist = pHeaderExist;

        this.loadXML();
    },

/********************************************************************************
 table 구조 xml을 읽어 오는 부분. 동기로 처리 했음.
********************************************************************************/
    loadXML : function()
    {
        new Ajax.Request(tableXML, {
            asynchronous: false,
            method: "get",
            onSuccess: function(xmlHttp)
            {
                try
                {
                    xmlBuffer = xmlHttp.responseXML;
                    return true;
                }
                catch(E)
                {
                    xmlBuffer = null;
                    alert("XML Load Fail : " + E);

                    return false;
                }
            },
            onFailure : function (request)
            {
                xmlBuffer = null;
                alert("Table Template XML Request Fail");
                return false;
            }
        });
    },

/********************************************************************************
 xml에 정의된 각 td별 설정을 읽어와 rowTemplate 객체를 만든다.
 row별 css정보도 여기서 설정한다. css가 명시된 수 만큼 적용된다.
********************************************************************************/
    getRowTemplate : function()
    {
        if (xmlBuffer == null)
            return ("table row Info is null");
        else
        {
            try
            {
                this.m_oRows = null;
                this.m_oRows = new stRow();

                var objectNode = this.getNode(xmlBuffer, this.m_oTableID);
                var cssTemp = this.getNodeAll(objectNode, "rowCss");

                for(var i=0 ; i<cssTemp.length ; ++i)
                    this.m_oRows.setCss(this.getValue(cssTemp[i]));

                var rowTemp = this.getNodeAll(objectNode, "row");

                for(var i=0 ; i<rowTemp.length ; ++i)
                {
                    var templateValue = this.getValue(rowTemp[i]);
                    this.m_oRows.insert(new stCell(templateValue.split("^^")));
                }
            }
            catch(E)
            {
                alert("Node select fail : " + E);
                return;
            }
        }
    },

/********************************************************************************
 실제로 table row를 생성 하는 부분
 row를 추가 하기 전에 기존에 그려진 모든 row를 지운다.
 json의 인덱스 명은 xml에서 명시한 delimiter명과 같아야 한다.
********************************************************************************/
    insertRow : function()
    {
        if ($(this.m_oTableID) == null)
        {
            alert("Base Table is null.");
            return;
        }

        if ($(this.m_oTableID).rows.length > 1)
        {
            if (this.m_bHeaderExist)
            {
                for(var i=($(this.m_oTableID).rows.length-1) ; i>0 ; --i)
                    $(this.m_oTableID).deleteRow(i);
            }
            else
            {
                for(var i=($(this.m_oTableID).rows.length-1) ; i>=0 ; --i)
                    $(this.m_oTableID).deleteRow(i);
            }
        }

        this.getRowTemplate();

        for(var i=0 ; i<this.m_nRow ; ++i)
        {
            var nLoopCount = 0;

            var row = $(this.m_oTableID).insertRow(-1);
            row.className = this.m_oRows.getCss( (i+1)%this.m_oRows.getCssCount() );

            for (var j=0 ; j<this.m_oRows.length ; ++j)
            {
                var c = row.insertCell(-1);
                var tempCell = this.m_oRows.getCell(nLoopCount).getData();

                for(var tempIndex in this.m_oData[i])
                {
                    var delimiter = new RegExp("#" + tempIndex + "#", "ig");
                    tempCell = tempCell.replace(delimiter, this.m_oData[i][tempIndex]);
                }

                c.innerHTML = tempCell;
                c.className = this.m_oRows.getCell(nLoopCount).getCss();
                nLoopCount++;
            }
        }
    }
});

구동 html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>test</title>
    <script language="javascript" type="text/javascript" src="/scripts/prototype.js"></script>
    <script language="javascript" type="text/javascript" src="/scripts/ajaxBasic.js"></script>
    <script language="javascript" type="text/javascript" src="/scripts/simpleXml.js"></script>
    <script language="javascript" type="text/javascript" src="/scripts/table.js"></script>
   
    <style type="text/css">
        table, div { float:left; position:relative; display:inline-block; padding:0; margin:0; }
       
        #list { width:800px; border:solid 1px #dddddd; }
        #list #notice {width:600px; font-size:11px; font-family : 맑은고딕, Lucida Grande, Verdana, Sans-serif;}
        #list #notice tr { height:20px; }
        #list #notice .noticeHeader {font-weight:bold; text-align:center;}
        #list #notice .noticeRow1 {border-bottom:solid 1px #dddddd; }
        #list #notice .noticeRow2 {border-bottom:solid 1px #dddddd; background-color:#dddddd; }
        #list #notice .noticeRow3 {border-bottom:solid 1px #dddddd; background-color:#aaaaaa; }
       
        #list #notice .noticeTitleHead {width:250px;}
        #list #notice .noticeDateHead {width:75px;}
        #list #notice .noticeCountHead {width:75px; text-align:right;}
        #list #notice .noticeAuthorHead {width:100px;}
        #list #notice .noticeBoardHead {width:100px;}
    </style>
</head>
<body>
<div>
    <div id="list">
        <table id="notice">
            <tr class="noticeHeader"><td class="noticeTitleHead">제목</td><td class="noticeAuthorHead">등록자</td><td class="noticeCountHead">조회수</td><td class="noticeDateHead">작성일</td><td class="noticeBoardHead">게시판</td></tr>
        </table>
    </div>
</div>
<input type="button" value="test" onclick="getData();">

<script language="javascript">
    function getData()
    {
        getAjaxData('/test.php', "", rowAppend);
    }
   
    function rowAppend(pValue)
    {
        var objTable2 = new Table(pValue, "notice", false);
        objTable2.insertRow();
    }
</script>
   
</body>

</html>

Posted by SADBLUE

2009/01/13 14:37 2009/01/13 14:37
, , , , ,
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/225

Trackback URL : http://sadblue.com/trackback/225

아가씨 우째.;ㅁ;

사용자 삽입 이미지

미챠 ;ㅁ;

출처 : http://www.parkoz.com/zboard/view.php?id=express_freeboard&page=1&sn1=&divpage=63&sn=off&ss=on&sc=off&select_arrange=headnum&desc=asc&no=347144

Posted by SADBLUE

2009/01/07 17:01 2009/01/07 17:01
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/224

Trackback URL : http://sadblue.com/trackback/224

올해의 목표.

1. 한겨레21 밀리지 않고 1년간 다 보기.
2. 용돈 기입장 쓰기....
    근데 맘에 드는 프로그램이 없다..;;만들어야 하나.;;이건 정말 구차는데.;;;
3. 연봉 10%올리기.
4. 게임 줄이기.
5. 날 따뜻해지면 자전거로 출퇴근 하기.

아 여지것 살아 오면서 한 해의 목표를 정해본건 첨인듯.-ㅅ-;
1번은 잘 지키고 있는데...
나머지가 걱정이네...
ㅡ,.ㅡ;

Posted by SADBLUE

2009/01/05 00:17 2009/01/05 00:17
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/223

Trackback URL : http://sadblue.com/trackback/223

선유도의 가을과 겨울 사이.

11월 14일날...
더 늦기 전에 사진을 찍지 않으면 겨울로 넘어 갈것 같아서...
휴가 낸김에 갔다온 선유도....
망할 플래쉬의 버전 문제로 파일 업로드를 못하다가...
한가한 회사서 시간때우기로 블로그를 업댓 하고.-ㅅ-;
이제서야..우후후.;;

사용자 삽입 이미지

사용자 삽입 이미지


사용자 삽입 이미지

사용자 삽입 이미지


Posted by SADBLUE

2009/01/05 00:14 2009/01/05 00:14
, , ,
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/222

Trackback URL : http://sadblue.com/trackback/222

미친 정부의 공식 첫 걸음.

정보보호진흥원에서 계약직으로 일 하는 친구가 하나 있다.
갑자기 뜬금 없는 나 짤릴거 같다는 말에...
감원 한파가 거기까지 가는구나 라고 생각하고 있었는데...

단순하게 감원이 아닌 밑돌 빼서 윗돌 괴는 그런 상황이 되어가는 모양이다..

인원 감축 하고 대학 인턴사원을 들인다고 하니 말이다...
인턴사원은 대학생들의 사회생활 경험을 위한제도로 알고 있는데
이젠 인건비 감소하는 편법으로도 쓰이나보다...할당량 까지 떨어졌다는 얘기까지 들린다.
인턴제도로 일 할 수 있는 기간이 그리 길지 않은 것으로 알고 있는데 월급도 80만원에..
그리 길지 않은 기간동안 일 하고 기간이 끝나면 다른 인턴으로 바꾸고..
당연 업무 숙련도는 떨어질 수 밖에 없겠고...
기존에 일 하던 사람들은 실업율 올라가는데 일조를 하겠고...
대졸자 구제 해준다고 기존에 사람들을 실업자로 만들어 버리는 후후...

예전에 내가 썼던 글 미친 정권이 미침에 가속도를 더 한다.와 같은 맥락인거라 생각되어진다.
모든 국민의 파트타임화 알바화.
부자생존 서밀말살.
미친정부다.
새해 정초부터 촛불시위 목소리를 더빙해서 보내는 구라방송(KBS)도 열받게 하더니만..
정말 2009년의 파란만장할거라는 기대감이 등골 서늘하게 다가온다.


Posted by SADBLUE

2009/01/02 17:48 2009/01/02 17:48
, , , , ,
Response
0 Trackbacks , 0 Comments
RSS :
http://sadblue.com/rss/response/221

Trackback URL : http://sadblue.com/trackback/221


블로그 이미지

난 평생 녹지 않는 눈 속에서 살아갈게... 너와 본 꿈을 잊지 않도록.... As if nothing had happened...

- SADBLUE

Notices

Archives

Authors

  1. SADBLUE

Recent Trackbacks

Calendar

«   2009/01   »
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Site Stats

Total hits:
2680794
Today:
1402
Yesterday:
1075