웹마스터 팁
사용자 정의를 활용하여 폼 형식으로 개발하는 무식한 방법(2)
2014.08.22 16:36
지난 번에 이어서 사용자 정의 변수 중에 전화번호를 국내에 한정 짓거나,
시간입력을 jQuery 의 timepicker 를 쓰지 않고 입력할 수 있게끔 아예 정의에 넣어버려서
타잎을 결정할 때에 시간입력을 선택하는 방법을 알아보겠습니다.
이렇게 하면 사용자 정의를 활용해서
사용자 정의를 활용하여 폼 형식으로 개발하는 무식한 방법(2)
: 사용자 변수를 입맛대로 형태 만들고 쑤셔 넣기
일단 가장 쉽게 전화번호부터 접근해보겠습니다.
능력이 되시는 분들은 jQuery 와 혼용해서 쓰면 가장 좋구요 ^^;
자 일단,
(XE설치경로)/classes/extravar/Extravar.class.php를 열어줍니다.
이제부터 설명하는 모든 문서는 저장시에 UTF-8 로 저장해야 합니다.
처음에 열면 ANSI 로 되어 있을 건데요, 한글 다 깨집니다 -_-;
찾아보면,
// Phone Number case 'tel' : $buff[] = '<input type="text" name="' . $column_name . '[]" value="' . $value[0] . '" size="4" maxlength="4" class="tel" />'; $buff[] = '<input type="text" name="' . $column_name . '[]" value="' . $value[1] . '" size="4" maxlength="4" class="tel" />'; $buff[] = '<input type="text" name="' . $column_name . '[]" value="' . $value[2] . '" size="4" maxlength="4" class="tel" />'; break;
이렇게 나온 부분이 있을 것입니다.
이해하기 쉬운 코드인데요, $buff[] 가 3개 있는 이유는 전화번호를 구별코드(지방/핸드폰/인터넷폰) 으로 해주고,
뒤에 2개는 국번과 번호입니다.
여기서 잠시 생각할 것은 어딘가 입력 필드의 갯수를 바꾸는 경우 또 손을 대어야 하는 구나 하는 정도입니다.
맨 첫줄을 다음처럼 바꿔줍니다.
//$buff[] = '<input type="text" name="' . $column_name . '[]" value="' . $value[0] . '" size="4" maxlength="4" class="tel" />'; //이 부분을 주석 처리
일단 주석으로 처리한 후에 (지워도 무방하지만, 언제나 원본 소스를 보존하는 게 낫겠죠)
$buff[] = '<select name="' . $column_name . '[]" class="select"><option value="">선택</option><option value="010">010</option><option value="011">011</option><option value="016">016</option><option value="017">017</option><option value="018">018</option><option value="019">019</option><option value="02">02</option><option value="031">031</option><option value="032">032</option><option value="033">033</option><option value="041">041</option><option value="042">042</option><option value="043">043</option><option value="051">051</option><option value="052">052</option><option value="053">053</option><option value="054">054</option><option value="055">055</option><option value="061">061</option><option value="062">062</option><option value="064">064</option><option value="070">070</option></select>';
이렇게 바꿔주는 거죠.
보면 사실 별 것 아닙니다.
' 와 " 만 잘 구별해서 사용하면 되고 구별번호를 아예 선택하게 바꿔준 것이죠.
더 있을 지도 모르겠지만; 일단 그냥 찾아본 그대로 넣었습니다.
마찬가지로 정규표현식 등을 도입해서 숫자를 3개이상 4개이하로 국번을 지정도 가능하구요,
번호는 무조건 숫자 네자리를 입력하게 해줄 수도 있습니다.
맨 처음의
<option value="">선택</option>
부분에서 value="" 이렇게 해주는 이유가 있습니다.
보통 value="선택" 이렇게 해줄 수도 있는데, 이러면 필수 입력 코드에 "선택" 이라는 값이 들어가 버리기 때문에,
항상 입력되어 있는 것으로 오해를 하고 넘어가죠. 그래서 그냥 "" 를 밸류로 해준 것입니다.
선택을 해야만 값이 입력되는 거죠.
XE 에서 사용자 정의 형식은 말이 이메일, 전화번호이지 아무거나 때려 박기만 하면 넘어갑니다.
jQuery 로 날짜처럼 그냥 나오던가 하는 것도 없죠.
(실상 날짜도 그냥 아무렇게나 타자로 때려박을 수도 있습니다)
그래서 앞에서 정말 대충 짰구나 하는 것이고, 코딩을 하시는 분들이나, 디자인을 통해 홈피를 만들어 주시는 그런 분들은
XE 를 쓰면 안된다는 생각을 했습니다.
너무 대충 만들어진 코드를 넣는 것 같잖아요.
아무튼, 이번에는 시간입력 부분을 타잎으로 설정해보겠습니다.
먼저, 형식 리스트에 시간입력을 선택가능하게 해야하죠.
그러려니까 language 를 설정해두는 xml 파일에 먼저 쑤셔넣어야 하겠죠.
(XE설치경로)/common/lang/lang.xml 를 열어줍니다.
<item name="column_type_list" type="array">
부분을 찾아줍니다.
거기에 보면,
<item name="date">
<value xml:lang="ko"><![CDATA[일자(연월일)]]></value>
<value xml:lang="en"><![CDATA[date(yyyy/mm/dd)]]></value>
<value xml:lang="jp"><![CDATA[日付(年月日)]]></value>
<value xml:lang="zh-CN"><![CDATA[日期(年月日)]]></value>
<value xml:lang="zh-TW"><![CDATA[日期(年月日)]]></value>
<value xml:lang="fr"><![CDATA[Jour(yyyy/mm/dd)]]></value>
<value xml:lang="de"><![CDATA[Datum(dd / mm /jjjj)]]></value>
<value xml:lang="ru"><![CDATA[Дата(гггг / мм / дд)]]></value>
<value xml:lang="es"><![CDATA[fecha(dd/mm/aaaa)]]></value>
<value xml:lang="tr"><![CDATA[tarih(gg/aa/yyyy)]]></value>
<value xml:lang="vi"><![CDATA[Ngày(yyyy/mm/dd)]]></value>
<value xml:lang="mn"><![CDATA[Онсар (Жил сар өдөр)]]></value>
</item>
이런 식으로 되어 있는 부분이 날짜 형식입니다.
그 밑에 비슷하게 형식을 만드는 거죠.
ko 만 정의해도 별 문제는 없지만, 어찌되었든 모든 언어에 대응하게 만들려면 다 넣어야죠.
문제는 제가 외국어를 저렇게나 많이 알지는 못한다는 거 ㅠㅠ
시간인데 time 이나 datetime 은 XE 에서 쓰니까 (물론 형식 지원은 제대로 안합니다만)
아무튼 시간 입력 부분이니까 what_time 을 쓰기로 합니다.
<item name="what_time">
<value xml:lang="ko"><![CDATA[시간(00시00분)]]></value>
<value xml:lang="en"><![CDATA[time(hh/mm)]]></value>
<value xml:lang="jp"><![CDATA[時刻(時分)]]></value>
<value xml:lang="zh-CN"><![CDATA[时间(時分)]]></value>
<value xml:lang="zh-TW"><![CDATA[时间(時分)]]></value>
<value xml:lang="fr"><![CDATA[Heure(hh/mm)]]></value>
<value xml:lang="de"><![CDATA[Zeit(hh / mm)]]></value>
<value xml:lang="ru"><![CDATA[время(гггг / мм / дд)]]></value>
<value xml:lang="es"><![CDATA[hora(hh/mm)]]></value>
<value xml:lang="tr"><![CDATA[zaman(hh/mm)]]></value>
<value xml:lang="vi"><![CDATA[thời(hh/mm)]]></value>
<value xml:lang="mn"><![CDATA[цаг (hh / mm)]]></value>
</item>
이제 이렇게 시간(00시00분) 을 추가하는 거죠.
절대적으로 외국어는 스스로 점검하세요. 대충 넣은 거라서;;;
음, 갑자기 생각을 바꿨습니다.
24시간보다는 오전 오후로 하는 게 낫겠네요.
왜냐면 -_-; 셀렉하게 만들까 하는데 01~24 보다는 01~12 가 짧습니다;;;
일단 이렇게 해준 후에,
(XE설치경로)/classes/extravar/Extravar.class.php를 다시 열어줍니다.
//case 'date' :
//case 'email_address' :
//case 'text' :
//case 'textarea' :
default :
return htmlspecialchars($value, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
}
}
이 부분을 찾아갑니다.
그래서 이 부분 위에 다음 코드를 추가하죠.
case 'what_time' : //WEDIF Reminisce 사용자 변수 종류 추가
if(is_array($value))
{
$values = $value;
}
elseif(strpos($value, '|@|') !== FALSE)
{
$values = explode('|@|', $value);
}
elseif(strpos($value, ',') !== FALSE)
{
$values = explode(',', $value);
}
return $values;
//case 'date' :
//case 'email_address' :
//case 'text' :
//case 'textarea' :
default :
return htmlspecialchars($value, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
}
}
그럼 이렇게 될 건데요,
위 코드를 추가하지 않고 억지로 앞에서처럼 형식만 만들어서 buff[1], buff[2], buff[3] ... 이렇게 넣어주면,
게시글에서 표시형태를 결정해줄 수가 없습니다.
필드간 구별을
|@| 로 하게 되거든요.
즉, 08시 15분 이라고 나오게 하려 했는데,
08|@|15 이런 식으로 나오게 되는 거죠.
이제 표시형태를 지정하러 갑니다.
function getValueHTML()
{
$value = $this->_getTypeValue($this->type, $this->value);
switch($this->type)
{
case 'homepage' :
return ($value) ? (sprintf('<a href="%s" target="_blank">%s</a>', $value, strlen($value) > 60 ? substr($value, 0, 40) . '...' . substr($value, -10) : $value)) : "";
case 'email_address' :
return ($value) ? sprintf('<a href="mailto:%s">%s</a>', $value, $value) : "";
case 'tel' :
return sprintf('%s - %s - %s', $value[0], $value[1], $value[2]);
case 'textarea' :
return nl2br($value);
case 'date' :
return zdate($value, "Y-m-d");
이 부분을 찾아서,
case 'what_time' : //WEDIF Reminisce 사용자변수종류
return sprintf('%s %s 시 %s 분', $value[0], $value[1], $value[2]);
여기에 case 'what_time' 을 추가해줍니다.
%s 뒤에 쓰고 싶은데로 쓰시면 되어요.
오전/오후, 시, 분 형식으로 넣을 거라서 저렇게 해줬습니다만, 2개 만들고 싶은 분은 2개 만들고,
3개 만들고 싶은 분은 3개 만드시면 됩니다.
하나 더 추가해서 나라입력까지 받으면 국제 시간도 얼마든 가능하겠죠.
약속시간 정하는 거니까 ^^;
뭐 처리 형태나, 형식지정도 다 해줬는데 문제는 정작 입력을 받아야 하는 곳을 손대지 않았습니다.
// date
case 'date' :
// datepicker javascript plugin load
Context::loadJavascriptPlugin('ui.datepicker');
$buff[] = '<input type="hidden" name="' . $column_name . '" value="' . $value . '" />';
$buff[] = '<input type="text" id="date_' . $column_name . '" value="' . zdate($value, 'Y-m-d') . '" class="date" />';
$buff[] = '<input type="button" value="' . Context::getLang('cmd_delete') . '" class="btn" id="dateRemover_' . $column_name . '" />';
$buff[] = '<script type="text/javascript">';
$buff[] = '//<![CDATA[';
$buff[] = '(function($){';
$buff[] = '$(function(){';
$buff[] = ' var option = { dateFormat: "yy-mm-dd", changeMonth:true, changeYear:true, gotoCurrent:false, yearRange:\'-0:+2\', onSelect:function(){';
$buff[] = ' $(this).prev(\'input[type="hidden"]\').val(this.value.replace(/-/g,""))}';
$buff[] = ' };';
$buff[] = ' $.extend(option,$.datepicker.regional[\'' . Context::getLangType() . '\']);';
$buff[] = ' $("#date_' . $column_name . '").datepicker(option);';
$buff[] = ' $("#dateRemover_' . $column_name . '").click(function(){';
$buff[] = ' $(this).siblings("input").val("");';
$buff[] = ' return false;';
$buff[] = ' })';
$buff[] = '});';
$buff[] = '})(jQuery);';
$buff[] = '//]]>';
$buff[] = '</script>';
break;
위 부분을 찾아갑니다.
case 'date' 를 검색해보면 좀 여러개 뜨는데 많지는 않으니까 검색해서,
실제로 입력을 받는 이 부분을 가시면 됩니다.
switch 구문만 봐도 그냥 마구 아무데나 껴 있고 코드 최적화는 안되어 있습니다.
저도 귀찮아서 그건 고치기 싫구요 -_-;
능력되면 줄여서 고치시고 코어 수정을 해서 github 에 공유를;;;
자 이 부분 아래에...
// what_time
case 'what_time' :
$buff[] = '<select name="' . $column_name . '[]" value="' . $value[0] . '" class="select"><option value="">오전/오후</option><option value="오전">오전</option><option value="오후">오후</option></select>';
$buff[] = '<select name="' . $column_name . '[]" value="' . $value[1] . '" class="select"><option value="">시간</option><option value="01">01</option><option value="02">02</option><option value="03">03</option><option value="04">04</option><option value="05">05</option><option value="06">06</option><option value="07">07</option><option value="08">08</option><option value="09">09</option><option value="10">10</option><option value="11">11</option><option value="12">12</option></select>';
$buff[] = '<select name="' . $column_name . '[]" value="' . $value[2] . '" class="select"><option value="">분</option><option value="00">00</option><option value="10">10</option><option value="20">20</option><option value="30">30</option><option value="40">40</option><option value="50">50</option></select>';
break;
이것을 넣어줍니다.
말씀드린 것처럼 위에 date 입력 부분처럼 jQuery 의 timepicker 를 쓰면 여러가지로 좋지만,
그런 거에 머리쓰기 싫은 분들은 그냥 저렇게 해주면 됩니다.
그리고 제 경우는 10분 간격으로 지정을 했는데, 5분 간격이든, 15분 간격이든 그건 설마 응용 가능하겠죠 -_-;
1분 간격? 하시려면 하셔도 됩니다. 60개만 하면 되는데요 뭘.
그리고 60개를 하는데 성공하면 -_-; 초도 넣을 수 있습니다~ 복사 한 번 더 해주는 센스가;;;
아무튼 이렇게 해주면 이제 제대로 사용가능한 거죠.
호응이 있으면;; (위디프를 선전해주시면 됩니다. 제가 웹쪽은 안 건들다가 웹쪽에 뛰어 들어서 ㅎㅎㅎ)
A 값을 선택 시에 B 값이 나오고, 체크 박스를 하나만 선택 가능하게 하거나...
약관 동의를 간단히 사용자 변수로 만드는 방법 등을 함께 해보죠.
고수분들에겐 전혀 쓸모 없는 예제이겠지만,
XE 초보분들에겐 여러가지 응용을 시작해보실 수 있는 가장 간단한 예제일 겁니다.
그럼 저는 일하러;;;
- [2017/06/17] 묻고답하기 contentextended 사용자정의 출력 시, select type 은 array 이로 나옵니다.
- [2016/08/10] 묻고답하기 사용자정의(확장변수)에 입력하는 설명에 태그를 적용할 수 없을까요? *1
- [2016/07/22] 묻고답하기 덧글단 회원에게만 확장변수 공개 질문 입니다. *2
- [2016/04/02] 묻고답하기 게시판 사용자정의 이미지 첨부 *1
- [2016/03/25] 묻고답하기 확장변수로 새로운 카테고리(분류)를 만들고 싶습니다
댓글 5
-
sejin7940
2014.08.23 04:41
-
Reminisce
2014.08.24 00:01
아 죄송합니다. 저는 사용자 확장변수 부분만 신경을 덜 쓴 듯 해서 쓴 글입니다.
확장변수로 되어 있는 값들은 통합 검색도 안되고, 뭐랄까 그냥 낑겨 넣은 부수 요소...
그런 느낌을 받은 것에 대해 쓴 것이구요.
오해는 없으시기 바랍니다.
업으로 하시는 분들을 뭐라하려던 건 아니었는데 이게 오해의 소지는 분명 있겠네요.
다만 제 뜻은 대충만든 부분처럼 보이는 부분들 때문에
업으로 하시는 분들은 그저 XE 라는 게시판과 사이트 관리자 모듈을 불러다 쓴 것인데
XE 로 개발을 하시는 분들이 오해를 살 소지가 있겠다는 뜻이었습니다.
역시 말은 귀찮아도 정확하게 표현 되었는 지를 봐야겠네요;
사용자정의 를 화살표로 한칸씩만 옮기는건.. 사용자정의를 하나 바꾸면 단순히 폼 구조만 바뀌는게 아니라 저장되어 있는 글전체의 idx 값을 바꿔야합니다. 그래야 view 에서 idx 만으로 값을 불러내는 구조가 만들어지죠.
-> 이 부분은 솔직히 저로서는 잘 이해가 안되는 부분인데요,
이미 메뉴에서 구현되어 있지 않은지요 ^^? GNB 부분이나 기타 등등에서 그렇게 되어 있지 않은가 해서 여쭈는 것입니다.
-
GG
2014.08.23 12:21
음... 장문의 글 잘 읽었습니다.
그런데 저는 글을 본 후 느낀점이
"아니 그럼 왜 이렇게 수정을 하시지요? 모듈을 하나 만드는게 더 낫겠네요."
입니다.
꼭 확장변수를 써야 합니까?
-
Reminisce
2014.08.24 00:02
모듈을 개발할 수도 있겠지만, 사람들에 따라서는 간단히 입맛에만 맞게끔
필요한 부분만 (노가다를 해서라도 구현을 하고 싶은) 고치고 싶은 사람도 있습니다.
그리고 너무 복잡하면 더 어려워 할테구요.
그냥 이건 초보들이 느끼는 느낌에 대해서 쓴 글일 뿐이고 오해는 없으시길 바랍니다.
-
GG
2014.08.24 01:14
넹, 말씀하시는 방법이 잘못되었다는 뜻이 아니라
수정할 곳이 많아 보여서 거의 모듈 하나 만드는 급으로 노력이 들어가는것 같아서요.
제가 잘 몰라서 복잡하게 느끼고 있는가 봅니당..
제가 앞글을 보고, 힌트를 좀 기재하다가.. 이 글에서..
"그래서 앞에서 정말 대충 짰구나 하는 것이고, 코딩을 하시는 분들이나, 디자인을 통해 홈피를 만들어 주시는 그런 분들은 XE 를 쓰면 안된다는 생각을 했습니다.
너무 대충 만들어진 코드를 넣는 것 같잖아요."
라는 부분을 보고 쓰던 댓글을 지워버렸습니다.
혹시 왜 저렇게 만들었을지 생각해본적이 있으신지요? (귀찮아서? 대충? 이겠습니까...)
기능 하나 만들때 정말 많은 걸 생각하고, 장단점을 파악하고, 선택적으로 구현하게 됩니다.
그러다보면 일부 불편을 줄 수 있지만, 또 다른 어떤 이유의 편의를 위해서 보통 그렇게 짠겁니다.
(예를들어 사용자정의 를 화살표로 한칸씩만 옮기는건.. 사용자정의를 하나 바꾸면 단순히 폼 구조만 바뀌는게 아니라 저장되어 있는 글전체의 idx 값을 바꿔야합니다. 그래야 view 에서 idx 만으로 값을 불러내는 구조가 만들어지죠. 그러다보면 안전성을 위해 하나씩 맞바꾸게 해야 안전합니다. 귀찮더라도 안전한게 더 중요한거 아닌가요?)
어떻게 '대충' 만든것 같다는 표현을 쓰실 수 있는지 모르겠네요
업으로 하시는 일이 있으실텐데, 고객분이 해주신 일을 보고
자기 마음에 안 든다고, "일 대충 하셨어요? " 라고 하면 기분이 어떠세요??
불만을 갖는건 자유지만...
그 불만을 공개적으로 쓰실때는 다른 사람들도 좀 생각을 해주셨으면 합니다