서명 팁이 반응이 좋아서 (애드온까지 만들어지다니 신나요~) 이번에는 후원금액을 선택 받는 팁을 공개해봅니다.
(물론 이번에도 국민 게시판ㅋ 스케치북 게시판을 이용합니다.)
아마 여러분은 둘 중 하나를 선택하실지 모르겠습니다.
- 라디오 버튼을 이용해서 후원자에게 객관식으로 선택지를 주거나 (예. 1만원, 2만원, 3만원, 5만원),
- 텍스트 입력폼을 이용해 후원자에게 주관식으로 직접 입력하게 하는 방식이겠죠.
이번에 소개해드리는 팁은 쉽게 말해, 객관식과 주관식을 섞는 방식입니다.
예컨대, 저는 게시판 쓰기 화면에서 다음과 같이 나오게 했습니다.
여기서 마지막 버튼('직접 입력')을 누르면 다음과 같이 됩니다.
이렇게 후원자가 후원금액을 직접적으로 입력할 수도 있게 한 거죠.
뿐만 아니라 input 이벤트를 이용해서 최소 금액('첫 번째 버튼에 표시된 금액')보다 후원금액이 적게 입력되는 경우에는 다음과 같이 메시지가 바뀌어서 출력됩니다.
그리고 이 상태에서 입력창을 벗어나려 하면 (천 단위로 콤마를 찍어줌과 동시에) 입력된 금액 부분을 전체 선택(하이라이트) 시키고 커서를 돌아오게 합니다. 아울러 메시지도 바뀌게 되죠.
또한, 엔터를 누르거나 등록 버튼을 클릭해서 입력 내용을 전송하려 하는 경우에는, 화면상에는 특정 숫자가 입력되어 있어도 실제로는 입력값이 초기화되어 입력 불가 경고창이 뜨게 됩니다.
하지만 최소금액 이상의 후원금액이 입력되면 메시지도 본래대로 (사용자정의 설명문 형태로) 돌아오고, 입력 값도 무사히 서버에 전송이 가능해집니다.
객관식 버튼을 눌렀을 때 후원금액이 별탈없이 전송되는 건 물론입니다.^^
... 그러면 이제 그 방법과 (다소 후줄근한ㅋ) 소스를 알려드리겠습니다.
1. 사용자 정의를 만들어줍니다.
- 저는 '사용자 정의 이름'을 'donation'으로 했습니다.
- '입력항목 이름'은 위 그림에서처럼 '후원금액'으로 했구요.
- '형식'은 '단일 선택(radio)', 기본값은 '5000, 10000, 20000, 30000, 50000, etc'로 했습니다.
- '설명'은 다음과 같이 했습니다. '후원회원으로 CMS를 통한 매월 약정액의 후원금 자동이체에 동의합니다.'
- 기본값의 구분은 쉼표로 하는 게 기본인데, 제 경우엔 쉼표와 띄어쓰기를 병행했습니다. 혹시 모르니 여러분도 가급적이면 띄어쓰기에 유의해주세요.
2. write_form.html 파일 수정
- <tr loop="$extra_keys=>$key,$val">에 속해 있는 <td> 태그를 찾고 아래처럼 바꿔주면 됩니다.
<td cond="$val->eid!='donation'">{$val->getFormHTML()}</td> <td cond="$val->eid=='donation'"> <style> .exForm li{display:inline-block;line-height:26px;cursor:pointer} #donation_etc{display:none;margin-top:10px;vertical-align:middle;} #donation_etc input{width:83px;height:26px;font-size:12px;} </style> <ul> {@ $val_array = explode(', ',$val->default); $val_value = implode('',$oDocument->getExtraEidValue($val->eid)); } <li loop="$n=0;$n<count($val_array);$n++"> <!--@if($n+1!=count($val_array))--> <input name="extra_vars{$val->idx}" class="radio" id="extra_vars{$val->idx}-100{$n+1}" type="radio" value="{$val_array[$n]}"> <label for="extra_vars{$val->idx}-100{$n+1}">월 {number_format($val_array[$n])}원</label> <!--@else--> <input name="extra_vars{$val->idx}" class="radio" id="extra_vars{$val->idx}-100{$n+1}" type="radio" value=""> <label for="extra_vars{$val->idx}-100{$n+1}">직접 입력</label> <span id="donation_etc"> 월 <input type="tel" id="etc_val" class="itx" value="<!--@if(!in_array($val_value,$val_array))-->{number_format($val_value)}<!--@end-->" />원 </span> <!--@end--> </li> </ul> <p>{$val->desc}</p> <script> jQuery(document).ready(function(){ var etc = jQuery('#donation_etc'), li_last = etc.parent('li'), para = li_last.parent('ul').next('p'), pText = li_last.parent('ul').next('p').text(), li_rest = li_last.parent('ul').children('li').not(li_last), first_val = Number(li_last.parent('ul').children('li:first').children('input.radio').val()), etc_btn = li_last.children('input'), etc_val = jQuery('#etc_val'), donated = '{$val_value}', msg1 = '최소 5천원 이상의 후원을 받고 있습니다.', msg2 = ' 후원금액 재입력을 부탁드립니다.'; if(donated==0) etc_val.val(''); if(donated!=''&&donated!=0){ etc_btn.val(donated.replace(/[^0-9]/g,'')); etc_btn.prop('checked',true); etc.show(); li_rest.children('input').each(function(){ if(jQuery(this).val()==donated){ jQuery(this).prop('checked',true); etc_val.val(''); etc.hide(); } }); } etc_val.on({ input: function(){ etc_val.val(etc_val.val().replace(/[^0-9,]/g,'').replace(/(^0+)/,'')); etc_btn.val(etc_val.val().replace(/[^0-9]/g,'')); if(etc_btn.val()!=0&&etc_btn.val()<first_val) { etc_btn.val(''); para.text(msg1); } else { etc_btn.val(etc_val.val().replace(/[^0-9]/g,'')); para.text(pText); } }, blur: function(){ if(li_rest.data('mouseDown')!=true){ etc_btn.val(etc_val.val().replace(/[^0-9]/g,'')); etc_val.val(etc_val.val().replace(/[^0-9]/g,'').replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')); if(etc_btn.val()!=0&&etc_btn.val()<first_val) { etc_val.select(); etc_btn.val(''); para.text(msg1+msg2).hide().fadeIn(1000); etc_val.focus(); } } } }); li_last.on('click',function(){ etc_btn.prop('checked',true); etc.show(); etc_val.focus(); etc_val.val(etc_val.val().replace(/[^0-9]/g,'').replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')); if(etc_val.val().replace(/[^0-9]/g,'')!=0&&etc_val.val().replace(/[^0-9]/g,'')<first_val) { etc_val.select(); etc_btn.val(''); para.text(msg1+msg2).hide().fadeIn(1000); } return false; }); etc_btn.on('focus',function(){ etc_btn.prop('checked',true); etc_val.focus(); }); li_rest.on('mousedown',function(e){ li_rest.data('mouseDown',true); }); li_rest.on('mouseup',function(e){ li_rest.data('mouseDown',false); }); li_rest.on('click',function(){ jQuery(this).children('input').prop('checked',true); etc.hide(); para.text(pText); }); }); </script> </td>
3. _read.html 파일 수정
- 쓰기 화면에서 입력된 값은 기본적으로 숫자로만 저장되어 전송됩니다.
- 만약 출력 화면에서는 천단위로 콤마를 찍어주고 싶다면, _read.html을 수정하시면 됩니다.
- 월 정기 후원인 경우에는 숫자 앞뒤로 '월'과 '원'을 붙여줘야겠죠?
- 먼저, 다음 부분을 찾습니다.
<td cond="$val->eid!='rating'">{$val->getValueHTML()}</td>
< td cond="$val->eid=='rating'" class="rating"><span class="starRating" title="{$val->getValueHTML()}{$lang->score}"><span style="width:{$val->getValueHTML()*10}%">{$val->getValueHTML()}</span></span></td>
- 이 부분은 모두 두 부분이 있습니다. '스킨 설정 > 본문 일반 설정 > 확장변수 위치'가 '본문 안에(기본)'인 경우엔 아래쪽 table, '제목 아래'인 경우엔 윗쪽 table이 될 겁니다.
- 이 두 부분을 모두 다음과 같이 바꿔줍니다.
<td cond="$val->eid!='rating'&&$val->eid!='donation'">{$val->getValueHTML()}</td> <td cond="$val->eid!='rating'&&$val->eid=='donation'">월 {number_format(str_replace(',','',$val->getValueHTML()))}원</td> <td cond="$val->eid=='rating'&&$val->eid!='donation'" class="rating"><span class="starRating" title="{$val->getValueHTML()}{$lang->score}"><span style="width:{$val->getValueHTML()*10}%">{$val->getValueHTML()}</span></span></td>
이상입니다.
실제 제가 사용하는 코드와 달리 공개용 팁을 위해 코드를 다시 수정을 했는데요. 혹시라도 실수가 있을지 모릅니다. 안 되는 부분 남겨주시면 다시 살펴보고 일러드리도록 하겠습니다.