본문 바로가기
재밌는 IT 개발/그누보드 테마 제작기(記)

그누보드 테마 제작 32 - 투표(POLL) 페이지 개발

by 만수킴 2020. 7. 24.

투표(Poll) 페이지를 개발합니다.
일단 메뉴에서 페이지가 보이지 않습니다.
어떻게 해야 보여지는지 찾아봅니다.

어드민에 투표 메뉴가 있네요.
우상단에 있는 "투표 추가" 버튼을 눌러 
투표를 생성해보겠습니다.

그누보드 어드민에 있는 투표관리 메뉴
테마 제작을 위한 샘플을 만들기 위한 투표 생성 화면
투표가 생성된 화면
투표가 생성되면 우측 영역에 보여진다.
설문 조사 결과 화면


 

우측 영역에 보여지는 설문 투표 양식 위젯(?) 부터 만들겠습니다.
만들려면 어딘가 보여야 하는데...
전 우측 사이드 영역이 없어 아예 볼 수 없습니다.

메인페이지의 남는 영역에 투표 위젯이 보여지게 하기로 함.

저 화면이 나오게 하기 위해서는 무엇을 해야 하는지 몰라
검색을 통해 찾아다녔습니다.
기본 테마에서는 aside(우측영역)에서
poll() 함수를 호출하면 나오게 되어 있더군요.

그누 기본 테마에서 투표(설문조사) 노출을 위해 호출하는 부분

저는 위에서 말씀드린데로,
메인 화면의 일부분에 노출이 되도록 하겠습니다.

메인 페이지에서 poll() 함수를 호출하도록 함.
제작중인 테마의 메인 화면 중 남는 영역에 나오도록 함.

그대로 써도 되지 않을까 싶을 정도로 괜찮아 보입니다.
그러나 CSS에 주석을 하면... 어쩔 수 없지 작업을 해야 함을 알게 됩니다.
bootstrap의 card를 이용하여 얼기설기 넣어봅니다.

bootstrap card의 header, body, footer영역에 기존 코드를 그대로 넣어본 모습

이제, 기존에 해오던데로
제작중인 테마의 코드들을 사용하여 작업을 진행합니다.

완료된 설문조사의 위젯 영역 모습


투표 결과화면의 모습은 어떤지 확인해봅니다.
우측은 CSS를 주석처리한 결과입니다.

신규 테마로 제작하기 전의 투표 결과 화면

여기서는 저 스크롤바를 어떻게 표현하느냐가 관건이겠습니다.
Metronic Admin에서도 저런 방식의 스크롤바를 제공합니다.
그걸 그대로 가져와서 적용해야겠습니다.

preview.keenthemes.com/metronic/demo1/features/bootstrap/progress.html

 

Metronic | Progress

Bootstrap Progress components are built with two HTML elements, some CSS to set the width, and a few attributes.

preview.keenthemes.com

스크롤까지는 잘 되었는데...
기타 의견의 리스트를 표시하는데서 문제가 발생했습니다.
테마 제작시 여러번 나왔던
/bbs/poll_result.php 에서 기타의견의 삭제 아이콘과
기타의견의 입력창을 HTML로 만들어서 주게 되어 있네요.
그래서 달라진 HTML을 표현하기 위해서는 
스킨 파일에서 다시 만들어야 합니다.

// /bbs/poll_result.php에서 $list2 배열을 만드는 로직
// 기타의견 리스트
$sql = " select a.*, b.mb_open
           from {$g5['poll_etc_table']} a
           left join {$g5['member_table']} b on (a.mb_id = b.mb_id)
          where po_id = '{$po_id}' order by pc_id desc ";
$result = sql_query($sql);
for ($i=0; $row=sql_fetch_array($result); $i++) {
    $list2[$i] = $row;  // 요거 한 줄 추가하였음. by tank. at 200712.
    $list2[$i]['pc_name']  = get_text($row['pc_name']);
    $list2[$i]['name']     = get_sideview($row['mb_id'], get_text(cut_str($row['pc_name'],10)), '', '', $row['mb_open']);
    $list2[$i]['idea']     = get_text(cut_str($row['pc_idea'], 255));
    $list2[$i]['datetime'] = $row['pc_datetime'];
}

 

확실히 쉬운 일은 없네요.
간단하다고 생각했는데도 몇시간은 훌쩍 지나가버립니다.
완료화면과 소스 올려드립니다.

완료된 설문조사(투표) 결과 페이지

// ====== poll.skin.php
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가

// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
//add_stylesheet('<link rel="stylesheet" href="'.$poll_skin_url.'/style.css">', 0);
?>


<!-- 설문조사 시작 { -->
<form name="fpoll" action="<?php echo G5_BBS_URL ?>/poll_update.php" onsubmit="return fpoll_submit(this);" method="post">
<input type="hidden" name="po_id" value="<?php echo $po_id ?>">
<input type="hidden" name="skin_dir" value="<?php echo urlencode($skin_dir); ?>">
    <!--begin::설문 위젯-->
    <div class="card card-custom card-stretch gutter-b">
        <!--begin::Header-->
        <div class="card-header pt-5">
            <h2 class="sound_only">설문조사</h2>
            <h3 class="card-title align-items-start flex-column">
                <span class="card-label font-weight-bolder text-dark">설문 조사</span>
            </h3>
            <div class="card-toolbar d-flex justify-content-end">
                <a href="<?php echo G5_BBS_URL."/poll_result.php?po_id=$po_id&amp;skin_dir=".urlencode($skin_dir); ?>" target="_blank" onclick="poll_result(this.href); return false;" class="btn btn-light-primary btn-hover-primary font-weight-bold">결과보기</a>
            </div>
        </div>
        <!--end::Header-->
        <!--begin::Body-->
        <div class="card-body pt-8">
            <h4 class="card-title align-items-start flex-column">
                <span class="card-label font-weight-bolder text-dark"><?php echo $po['po_subject'] ?></span>
            </h4>

            <div class="form-group">
                <div class="radio-list">
            <?php for ($i=1; $i<=9 && $po["po_poll{$i}"]; $i++) {  ?>
                    <label class="radio" for="gb_poll_<?php echo $i ?>">
                        <input type="radio" name="gb_poll" value="<?php echo $i ?>" id="gb_poll_<?php echo $i ?>">
                        <span></span><?php echo $po['po_poll'.$i] ?>
                    </label>
            <?php }  ?>
                </div>
            </div>
        </div>
        <!--end::Body-->
        <!--begin::Body-->
        <div class="card-footer d-flex justify-content-between py-3">
            <button type="submit" class="btn btn-light-success btn-hover-success font-weight-bold">투표하기</button>
            <?php if ($is_admin == "super") {  ?>
            <span onclick="location.href='<?php echo G5_ADMIN_URL ?>/poll_form.php?w=u&amp;po_id=<?php echo $po_id ?>';" class="btn btn-default btn-icon btn-sm btn-danger mr-2" data-toggle="tooltip" title="" data-original-title="설문관리">
                <i class="fa fa-cog fa-spin fa-fw"></i><span class="sound_only">투표관리</span>
            </span>
            <?php }  ?>

        </div>
        <!--end::Body-->
    </div>
    <!--end::설문 위젯-->
</form>

<script>
function fpoll_submit(f)
{
    <?php
    if ($member['mb_level'] < $po['po_level'])
        echo " alert('권한 {$po['po_level']} 이상의 회원만 투표에 참여하실 수 있습니다.'); return false; ";
     ?>

    var chk = false;
    for (i=0; i<f.gb_poll.length;i ++) {
        if (f.gb_poll[i].checked == true) {
            chk = f.gb_poll[i].value;
            break;
        }
    }

    if (!chk) {
        alert("투표하실 설문항목을 선택하세요");
        return false;
    }

    var new_win = window.open("about:blank", "win_poll", "width=616,height=500,scrollbars=yes,resizable=yes");
    f.target = "win_poll";

    return true;
}

function poll_result(url)
{
    <?php
    if ($member['mb_level'] < $po['po_level'])
        echo " alert('권한 {$po['po_level']} 이상의 회원만 결과를 보실 수 있습니다.'); return false; ";
     ?>

    win_poll(url);
}
</script>
<!-- } 설문조사 끝 -->
// ===== poll_result_skin.php
<?php
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가

$get_max_cnt = 0;

if ((int) $total_po_cnt > 0){
    foreach( $list as $k => $v ) {
        $get_max_cnt = max( array( $get_max_cnt, $v['cnt'] ) );     // 가장 높은 투표수를 뽑습니다.
    }
}

// /bbs/result_skin.php에서 HTML을 미리 만들어서 전달하기때문에, 테마에 맞는 배열을 다시 만들어야 한다. by tank. at 200712.
// 기타의견 리스트
$sql = " select a.*, b.mb_open
           from {$g5['poll_etc_table']} a
           left join {$g5['member_table']} b on (a.mb_id = b.mb_id)
          where po_id = '{$po_id}' order by pc_id desc ";
$result = sql_query($sql);
for ($i=0; $row=sql_fetch_array($result); $i++) {
    $list2[$i] = $row;
    $list2[$i]['pc_name']  = get_text($row['pc_name']);
    $list2[$i]['name']     = get_sideview($row['mb_id'], get_text(cut_str($row['pc_name'],10)), '', '', $row['mb_open']);
    $list2[$i]['idea']     = get_text(cut_str($row['pc_idea'], 255));
    $list2[$i]['datetime'] = $row['pc_datetime'];
}


// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
//add_stylesheet('<link rel="stylesheet" href="'.$poll_skin_url.'/style.css">', 0);
?>


<!-- 설문조사 결과 시작 { -->
<div class="d-flex flex-column-fluid">
    <!--begin::Container-->
    <div class="container">


<!--begin::설문 위젯-->
<div class="card card-custom mt-3">
    <!--begin::Header-->
    <div class="card-header">
        <h3 class="card-title">
            <span class="card-label font-weight-bolder text-dark"><?php echo $g5['title'] ?></span>
        </h3>
        <div class="card-toolbar d-flex justify-content-end">
            <button type="button" class="btn btn-light-secondary text-info font-weight-bolder">전체 <?php echo $nf_total_po_cnt ?>표</button>
        </div>
        <div class="row col-12">
            <span class="font-size-h3 font-weight-bolder text-dark mx-auto"><?php echo $po_subject ?> - 결과</span>
        </div>
    </div>
    <!--end::Header-->
    <!--begin::Body-->
    <div class="card-body pt-8">
        <!-- 설문조사 결과 그래프 시작 { -->
        <?php
        for ($i=1; $i<=count($list); $i++) {
            // 가장 높은 투표수와 같으면 li 태그에 poll_1st 클래스가 붙습니다.
            $poll_1st_class = ($get_max_cnt && ((int) $list[$i]['cnt'] === (int) $get_max_cnt)) ? 'progress-bar-striped progress-bar-animated bg-primary' : 'bg-success';
        ?>
            <div class="row mb-2">
                <div class="col">
                    <p class="font-size-lg mb-0"><?php echo $list[$i]['content'] ?></p>
                    <div class="progress mb-3">
                        <div class="progress-bar <?php echo $poll_1st_class; ?>" role="progressbar" style="width:<?php echo number_format($list[$i]['rate'], 1) ?>%" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100"></div>
                    </div>
                </div>
                <div class="col-md-1 col-sm-2 col-2">
                    <p class="font-size-lg font-weight-bolder mb-0"><?php echo $list[$i]['cnt'] ?> 표</p>
                    <span class="font-size-lg poll_percent"><?php echo number_format($list[$i]['rate'], 1) ?> %</span>
                </div>
            </div>
        <?php }  ?>
        <!-- } 설문조사 결과 그래프 끝 -->
    </div>
    <!--end::Body-->
    <!--begin::footer-->
    <div class="card-footer py-3" id="poll_result_cmt">
        <h2 class="sound_only">이 설문에 대한 기타의견</h2>

        <?php for ($i=0; $i<count($list2); $i++) { //tLog("list2", $list2); ?>
        <div class="row border-bottom my-2">
            <h2 class="sound_only"><?php echo $list2[$i]['pc_name'] ?>님의 의견</h2>
            <div class="col">
                <div class="d-flex mb-1">
                    <?php echo $list2[$i]['name'] ?>
                    <span class="sound_only">작성일</span>
                    <span class="ml-2 bo_vc_hdinfo"><i class="fa fa-clock-o" aria-hidden="true"></i> <time datetime="<?php echo date('Y-m-d\TH:i:s+09:00', strtotime($list2[$i]['datetime'])) ?>"><?php echo $list2[$i]['datetime'] ?></time></span>
                </div>
                <p><?php echo $list2[$i]['idea'] ?></p>
            </div>
            <div class="col-1">
                <?php if ($is_admin == 'super' || ($list2[$i]['mb_id'] == $member['mb_id'] && $list2[$i]['mb_id'])) { ?>
                    <a href="'.G5_BBS_URL.'/poll_etc_update.php?w=d&amp;pc_id='.$row['pc_id'].'&amp;po_id='.$po_id.'&amp;skin_dir='.$skin_dir.'"  class="btn btn-default btn-hover-light-danger btn-icon btn-sm mr-2 poll_delete">
                        <i class="fa fa-trash-o"></i><span class="sound_only">삭제</span>
                    </a>
                <?php } ?>
            </div>
        </div>
        <?php }  ?>

        <!-- 설문조사 기타의견 시작 { -->
        <?php if ($is_etc) {  ?>
        <div class="card border-radius mx-1 mt-3">
            <?php if ($member['mb_level'] >= $po['po_level']) {  ?>
            <form name="fpollresult" action="./poll_etc_update.php" onsubmit="return fpollresult_submit(this);" method="post" autocomplete="off" id="poll_other_q">
            <input type="hidden" name="po_id" value="<?php echo $po_id ?>">
            <input type="hidden" name="w" value="">
            <input type="hidden" name="skin_dir" value="<?php echo urlencode($skin_dir); ?>">

            <div class="card-header p-2">
                <span class="btn btn-sm btn-secondary font-weight-bold font-size-lg text-dark mr-2 d-inline">기타의견</span>
                <span class="font-weight-bolder font-size-h4"><?php echo $po_etc ?></span>
            </div>

            <div class="card-body p-2">
                <div id="poll_result_wcmt">
                    <div>
                        <label for="pc_idea" class="sound_only">의견<strong>필수</strong></label>
                        <input type="text" id="pc_idea" name="pc_idea" required class="form-control full_input required" maxlength="100" placeholder="의견을 입력해주세요">
                    </div>
                </div>
                <?php if ($is_member) {  ?>
                <input type="hidden" name="pc_name" value="<?php echo get_text(cut_str($member['mb_nick'],255)) ?>">
                <?php }  ?>
                <?php if ($is_guest) {  ?>
                <div class="">
                    <label for="pc_name" class="sound_only">이름<strong>필수</strong></label>
                    <input type="text" name="pc_name" id="pc_name" required class="form-control full_input required" size="20" placeholder="이름">
                </div>
                <?php }  ?>
                <div class="row col-12 mt-2 mx-auto">
                    <?php echo captcha_html_mt703(); ?>
                    <button type="submit" class="btn btn-secondary btn-sm btn-hover-light-success font-weight-bold font-size-lg ml-5">의견남기기</button>
                </div>
            </div>
            </form>
            <?php }  ?>
        </div>
        <?php }  ?>
        <!-- } 설문조사 기타의견 끝 -->

    </div>
    <!--end::footer-->
</div>
<!--end::설문 위젯-->



<div class="card card-custom mt-3">
    <div class="card-header p-2">
        <span class="font-weight-bolder font-size-h4">다른 투표 결과 보기</span>
    </div>
    <div class="card-body p-2">
        <?php for ($i=0; $i<count($list3); $i++) {  ?>
        <div class="row border-bottom mx-3 py-3">
            <div class="col px-3">
                <a href="./poll_result.php?po_id=<?php echo $list3[$i]['po_id'] ?>&amp;skin_dir=<?php echo urlencode($skin_dir); ?>" class="font-size-lg font-weight-bolder text-left">
                    <?php echo $list3[$i]['subject'] ?>
                </a>
            </div>
            <div class="col-md-2 col-sm-3 col-3 text-right">
                <span class="pr-2 ml-2"><i class="fa fa-clock-o" aria-hidden="true"></i> <?php echo $list3[$i]['date'] ?></span>
            </div>
        </div>
        <?php }  ?>
    </div>
</div>


<div class="card card-custom mt-3 mb-5">
    <div class="card-body text-center py-1">
        <button type="button" onclick="window.close();" class="btn btn-secondary btn-sm btn-hover-light-danger font-weight-bold font-size-lg">창닫기</button>
    </div>
</div>



    </div>
    <!--end::Container-->
</div>
<!-- } 설문조사 결과 끝 -->

<script>
$(function() {
    $(".poll_delete").click(function() {
        if(!confirm("해당 기타의견을 삭제하시겠습니까?"))
            return false;
    });
});

function fpollresult_submit(f)
{
    <?php if ($is_guest) { echo chk_captcha_js(); }  ?>

    return true;
}
</script>
<!-- } 설문조사 결과 끝 -->

 

이제 일반페이지만 남았네요.
거의 다 왔어요.
헥헥...

댓글