728x90

MDB(Meterial Design for Bootstrap) 에서 sidenav 에 표시할 메뉴를 PHP 와 연동하여 자동으로 표시하는 방법을 구현했다.


먼저, 구글에서 multi level sidenav 를 검색하면 https://mdbootstrap.com/support/jquery/multi-level-in-sidenav-items/ 가 검색될 것이다.


검색된 Tree 구조는 아래와 같다.

 <li>
    <ul class="collapsible collapsible-accordion">
    <li><a class="collapsible-header waves-effect arrow-r"><i class="fa fa-hand-pointer-o"></i>메뉴1-1<i class="fa fa-angle-down rotate-icon"></i></a>
    <div class="collapsible-body">
        <ul>
            <li>
            <ul class="collapsible collapsible-accordion">
            <li><a class="collapsible-header waves-effect arrow-r"><i class="fa fa-hand-pointer-o"></i>메뉴2-1</a>
            <div class="collapsible-body">
                <ul>
                <li><a href="#" class="waves-effect">메뉴3-1</a></li>
                <li><a href="#" class="waves-effect">메뉴3-2</a></li>
                <li><a href="#" class="waves-effect">메뉴3-3</a></li>
                </ul>
            </div>
            </li>
        </ul>

        <ul>
        <li><a href="#" class="collapsible-header waves-effect">메뉴2-2</a></li>
        </ul>

    </div>
    </li>
    </ul>
</li>

<li>
    <a href="#" class="collapsible-header waves-effect">메뉴1-2</a>
</li>


이걸 가지고 PHP 와 연동된 자동 메뉴를 만들어 보자.

MDB 는 bootstrap 4 기반으로 연동된 템플릿이다.

bootstrap 4 에서는 순환구조가 매끄럽지 못한 거 같다. (내가 제대로 이해를 못했겠지만....)


테이블 구조

CREATE TABLE IF NOT EXISTS `menu_item` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) NOT NULL DEFAULT '0',
  `depth` int(3) NOT NULL DEFAULT '1',
  `name` varchar(50) NOT NULL,
  `text` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 


Treeview 메뉴 코드

아래 코드는 https://link2me.tistory.com/1194 게시글과 비교하면서 살펴보면 도움될 것이다.

파일명 : muti_treeview.php

 <?php
if(!isset($_SESSION)) {
    session_start();
}
require_once 'path.php'; // root 폴더를 기준으로 상대적인 경로 자동 구하기
require_once $g['path_config'].'config.php';
require_once $g['path_config'].'dbconnect.php';
require_once $g['path_class'].'dbDataClass.php';
$d = new DBDataClass();
$res = $d->getDbresult("menu_item", "", "id,parent_id,name");
while($row = mysqli_fetch_assoc($res)){
    $sidemenu[] = $row;
}

$side_menu = bootstrap4_sideMenu($sidemenu);
echo $side_menu;

function bootstrap4_sideMenu($array,$parent_id = 0,$parents = array())
{
    global $d,$key;
    if($parent_id==0){ // sub가 있는 parent_id 값 추출
        foreach ($array as $element) {
            if (($element['parent_id'] != 0) && !in_array($element['parent_id'],$parents)) {
                $parents[] = $element['parent_id'];
            }
        }
    }

    $menu_html = '';
    foreach($array as $element){
        if($element['parent_id']==$parent_id){
            $url = $element['id'].";".$element['parent_id'];            

            if(in_array($element['id'],$parents)){
                $menu_html .= '<li>';
                $menu_html .= '<ul class="collapsible collapsible-accordion">';
                $menu_html .= '<li><a class="collapsible-header waves-effect arrow-r" href="'.$url.'"><i class="fa-hand-pointer-o">';
                $menu_html .= '</i>'.$element['name'].'<i class="fas fa-angle-down rotate-icon"></i></a>';
                $menu_html .= '<div class="collapsible-body">';

            } else {
                $menu_html .= '<li>';
                $menu_html .= '<a class="collapsible-header waves-effect" href="'.$url.'">'.$element['name'].'</a>';
                $menu_html .= '</li>';
            }

            if(in_array($element['id'],$parents)){
                $menu_html .= '<ul>';
                $menu_html .= bootstrap4_sideMenu($array, $element['id'], $parents);
                $menu_html .= '</ul>';
                $menu_html .= '</div>';
                $menu_html .= '</ul>';
                $menu_html .= '</li>';
            }
           
        }
    }
    return $menu_html;
}
?>


이제 MDB 템플릿 구조에 포함된 HTML 파일구조다. jQuery 코드는 모두 생략했다.

<!DOCTYPE html>
<head>
<?php require_once 'path.php';// root 폴더를 기준으로 상대적인 경로 자동 구하기 ?>
<?php require_once $g['path_config'].'config.php';?>
<?php require_once $g['path_layout'].'default/_import.head.php';?>
<?php require_once $g['path_root'].'deviceChk.php';?>
</head>

<body class="fixed-sn mdb-skin">
<header>
    <!-- Sidebar navigation -->
    <div id="slide-out" class="side-nav sn-bg-4 fixed">
        <ul class="custom-scrollbar">
            <!-- Side navigation links -->
            <?php require_once $g['path_menu'].'item/multi_treeview.php' ?>
        </ul>
        <div class="sidenav-bg mask-strong"></div>
    </div><!--/. Sidebar navigation -->
    <!-- Navbar -->
    <nav class="navbar fixed-top navbar-toggleable-md navbar-expand-lg scrolling-navbar double-nav">
        <!-- SideNav slide-out button -->
        <div class="float-left">
            <a href="#" data-activates="slide-out" class="button-collapse"><i class="fas fa-bars"></i></a>
        </div>
        <!-- Breadcrumb-->
        <div class="breadcrumb-dn mr-auto">
            <p><?=$hostName;?></p>
        </div>
        <ul class="nav navbar-nav nav-flex-icons ml-auto">
            <?php require_once $g['path_menu'].'item/item_login.php' ?>
        </ul>
    </nav>
    <!-- /.Navbar -->
</header>

<!--Main layout-->
<main>
    <div class="container-fluid text-center">
        <div class="row">
            <div class="col-md-12">
                <div class="content" id="panel_content">
                </div>
                <div id="ajaxPath" menu-path="<?php echo $g['path_help'];?>"  ></div>
            </div>
        </div>
    </div>
</main>
<!--/Main layout-->
<!-- SCRIPTS -->
<?php require_once $g['path_layout'].'default/_import.tail.php';?>
</body>
</html>


블로그 이미지

Link2Me

,
728x90

부트스트랩에서 메뉴버튼을 누르면 왼쪽 화면에 사이드바 메뉴화면이 나오고 없어지는 예제에 대한 설명이다.


출처 : https://bootsnipp.com/snippets/featured/fancy-sidebar-navigation


CSS 부분 주석을 달아 향후 다시 볼 때 이해를 높이도록 했다.

overflow 속성은 http://triki.net/wiki/792# 에 설명이 잘 되어 있다.

아래 사이드 메뉴에 대한 설명은 https://bootstrapious.com/p/bootstrap-sidebar 에 잘 설명되어 있는 편이다.

http://link2me.tistory.com/1194 게시글을 참조하여 수정/활용하면 좋을 것이다.


<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<style>
body {
    position: relative;
    overflow-x: hidden;
}
body,
html { height: 100%;}
.nav .open > a,
.nav .open > a:hover,
.nav .open > a:focus {background-color: transparent;}

/*-------------------------------*/
/*           Wrappers            */
/*-------------------------------*/

#wrapper {
    padding-left: 0;
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
}

#wrapper.toggled {
    padding-left: 220px;
}

#sidebar-wrapper {
   /* z-index는 태그들이 겹칠 때 누가 더 위로 올라가는지를 결정하는 속성, 기본값은 0 */
    z-index: 1000; /* z축 상의 위치를 나타내며, 정수값(음수, 양수). 높은 번호를 가진 레이어는 낮은 번호를 가진 레이어 위에 렌더링된다 */
    left: 220px;
    width: 0;
    height: 100%;
    margin-left: -220px;
    overflow-y: auto; /* 본문에 표시되는 내용에 따라 세로 스크롤이 생긴다. */
    overflow-x: hidden; /* 부모요소의 범위를 넘어가는 자식요소의 부분은 보이지 않도록 처리 */
    background: #1a1a1a;
    -webkit-transition: all 0.5s ease; /* CSS 속성을 변경할 때 애니메이션 속도를 조절하는 방법을 제공 */
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
}

#sidebar-wrapper::-webkit-scrollbar {
  display: none; /* 보이지 않음 */
}

#wrapper.toggled #sidebar-wrapper {
    width: 220px;
}

#page-content-wrapper {
    width: 100%;
    padding-top: 70px;
}

#wrapper.toggled #page-content-wrapper {
    position: absolute; /* 가장 가까운 곳에 위치한 조상 엘리먼트에 상대적으로 위치가 지정된다. */
    /* relative가 static인 상태를 기준으로 주어진 픽셀만큼 움직였다면, */
    /* absolute는 position: static 속성을 가지고 있지 않은 부모를 기준으로 움직인다. */
    /* 만약 부모 중에 포지션이 relative, absolute, fixed인 태그가 없다면 가장 위의 태그(body)가 기준이 된다. */
    margin-right: -220px;
}

/*-------------------------------*/
/*     Sidebar nav styles        */
/*-------------------------------*/

.sidebar-nav {
    position: absolute;
    top: 0;
    width: 220px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.sidebar-nav li {
    position: relative;
    line-height: 20px;
    display: inline-block;
    width: 100%;
}

.sidebar-nav li:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    height: 100%;
    width: 3px;
    background-color: #1c1c1c;
    -webkit-transition: width .2s ease-in;
      -moz-transition:  width .2s ease-in;
       -ms-transition:  width .2s ease-in;
            transition: width .2s ease-in;

}
.sidebar-nav li:first-child a {
    color: #fff;
    background-color: #1a1a1a;
}

.sidebar-nav li:before {
    background-color: #D8D8D8;  
}
.sidebar-nav li:hover:before,
.sidebar-nav li.open:hover:before {
    width: 100%;
    -webkit-transition: width .2s ease-in;
      -moz-transition:  width .2s ease-in;
       -ms-transition:  width .2s ease-in;
            transition: width .2s ease-in;

}

.sidebar-nav li a {
    display: block; /* 요소를 block 요소처럼 표시한다. 요소 앞뒤로 줄바꿈 된다. */
    color: #ddd;
    text-decoration: none; /* 선을 만들지 않는다. */
    padding: 10px 15px 10px 30px;    
}

.sidebar-nav li a:hover,
.sidebar-nav li a:active,
.sidebar-nav li a:focus,
.sidebar-nav li.open a:hover,
.sidebar-nav li.open a:active,
.sidebar-nav li.open a:focus{
    color: #fff;
    text-decoration: none;
    background-color: transparent;
}

.sidebar-nav > .sidebar-brand {
    height: 45px;
    font-size: 16px;
    line-height: 24px;
}
.sidebar-nav .dropdown-menu {
    position: relative;
    width: 100%;
    padding: 0;
    margin: 0;
    border-radius: 0;
    border: none;
    background-color: #222;
    box-shadow: none;
}

/*-------------------------------*/
/*       Link2me-Cross         */
/*-------------------------------*/

.link2me {
  position: fixed; /* fixed: 스크롤과 상관없이 항상 문서 최 좌측상단을 기준으로 좌표를 고정 */
  top: 20px;  
  z-index: 999; /* z-index는 태그들이 겹칠 때 누가 더 위로 올라가는지를 결정하는 속성, 기본값은 0 */
  display: block; /* 요소를 block 요소처럼 표시한다. 요소 앞뒤로 줄바꿈 된다. */
  width: 32px;
  height: 32px;
  margin-left: 15px;
  background: transparent;
  border: none;
}
.link2me:hover,
.link2me:focus,
.link2me:active {
  outline: none;
}
.link2me.is-closed:before {
  content: '';
  display: block;
  width: 100px;
  font-size: 14px;
  color: #fff;
  line-height: 32px;
  text-align: center;
  opacity: 0;
  -webkit-transform: translate3d(0,0,0);
  -webkit-transition: all .35s ease-in-out;
}
.link2me.is-closed:hover:before {
  opacity: 1;
  display: block;
  -webkit-transform: translate3d(-100px,0,0);
  -webkit-transition: all .35s ease-in-out;
}

.link2me.is-closed .hamb-top,
.link2me.is-closed .hamb-middle,
.link2me.is-closed .hamb-bottom,
.link2me.is-open .hamb-top,
.link2me.is-open .hamb-middle,
.link2me.is-open .hamb-bottom {
  position: absolute;
  left: 0;
  height: 4px;
  width: 100%;
}
.link2me.is-closed .hamb-top,
.link2me.is-closed .hamb-middle,
.link2me.is-closed .hamb-bottom {
  background-color: #1a1a1a;
}
.link2me.is-closed .hamb-top {
  top: 5px;
  -webkit-transition: all .35s ease-in-out;
}
.link2me.is-closed .hamb-middle {
  top: 50%;
  margin-top: -2px;
}
.link2me.is-closed .hamb-bottom {
  bottom: 5px;  
  -webkit-transition: all .35s ease-in-out;
}

.link2me.is-closed:hover .hamb-top {
  top: 0;
  -webkit-transition: all .35s ease-in-out;
}
.link2me.is-closed:hover .hamb-bottom {
  bottom: 0;
  -webkit-transition: all .35s ease-in-out;
}
.link2me.is-open .hamb-top,
.link2me.is-open .hamb-middle,
.link2me.is-open .hamb-bottom {
  background-color: #1a1a1a;
}
.link2me.is-open .hamb-top,
.link2me.is-open .hamb-bottom {
  top: 50%;
  margin-top: -2px;  
}
.link2me.is-open .hamb-top {
  -webkit-transform: rotate(45deg);
  -webkit-transition: -webkit-transform .2s cubic-bezier(.73,1,.28,.08);
}
.link2me.is-open .hamb-middle { display: none; }
.link2me.is-open .hamb-bottom {
  -webkit-transform: rotate(-45deg);
  -webkit-transition: -webkit-transform .2s cubic-bezier(.73,1,.28,.08);
}
.link2me.is-open:before {
  content: '';
  display: block;
  width: 100px;
  font-size: 14px;
  color: #fff;
  line-height: 32px;
  text-align: center;
  opacity: 0;
  -webkit-transform: translate3d(0,0,0);
  -webkit-transition: all .35s ease-in-out;
}
.link2me.is-open:hover:before {
  opacity: 1;
  display: block;
  -webkit-transform: translate3d(-100px,0,0);
  -webkit-transition: all .35s ease-in-out;
}

/*-------------------------------*/
/*            Overlay            */
/*-------------------------------*/

.overlay {
    position: fixed; /* fixed: 스크롤과 상관없이 항상 문서 최 좌측상단을 기준으로 좌표를 고정 */
    display: none;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(250,250,250,.8);
    z-index: 1;
}
</style>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script>
$(document).ready(function () {
  var trigger = $('.link2me'),
      overlay = $('.overlay'),
     isClosed = false;

    trigger.click(function () {
      link2me_cross();      
    });

    function link2me_cross() {

      if (isClosed == true) {          
        overlay.hide();
        trigger.removeClass('is-open');
        trigger.addClass('is-closed');
        isClosed = false;
      } else {   
        overlay.show();
        trigger.removeClass('is-closed');
        trigger.addClass('is-open');
        isClosed = true;
      }
  }
 
  $('[data-toggle="offcanvas"]').click(function () {
        $('#wrapper').toggleClass('toggled');
  });  
});
</script>
</body>
    <div id="wrapper">
        <div class="overlay"></div>
    
        <!-- Sidebar 숨김으로 보였다 보이지 않았다 하는 부분 -->
        <nav class="navbar navbar-inverse navbar-fixed-top" id="sidebar-wrapper" role="navigation">
            <ul class="nav sidebar-nav">
                <li class="sidebar-brand">
                    <a href="#">
                       Brand
                    </a>
                </li>
                <li>
                    <a href="#">Home</a>
                </li>
                <li>
                    <a href="#">About</a>
                </li>
                <li>
                    <a href="#">메뉴1</a>
                </li>
                <li>
                    <a href="#">메뉴2</a>
                </li>
                <li class="dropdown">
                  <a href="#" class="dropdown-toggle" data-toggle="dropdown">메뉴3<span class="caret"></span></a>
                  <ul class="dropdown-menu" role="menu">
                    <li class="dropdown-header">Dropdown heading</li>
                    <li><a href="#">서브메뉴3.1</a></li>
                    <li><a href="#">서브메뉴3.2</a></li>
                    <li><a href="#">서브메뉴3.3</a></li>
                    <li><a href="#">서브메뉴3.4</a></li>
                    <li><a href="#">서브메뉴3.5</a></li>
                  </ul>
                </li>
                <li>
                    <a href="#">메뉴4</a>
                </li>
                <li>
                    <a href="#">메뉴5</a>
                </li>
                <li>
                    <a href="https://twitter.com/maridlcrmn">메뉴6</a>
                </li>
            </ul>
        </nav>
        <!-- /#sidebar-wrapper -->

        <!-- Page Content -->
        <div id="page-content-wrapper">
            <button type="button" class="link2me is-closed" data-toggle="offcanvas">
                <span class="hamb-top"></span>
                <span class="hamb-middle"></span>
                <span class="hamb-bottom"></span>
            </button>
            <div class="container">
                <div class="row">
                    <div class="col-lg-8 col-lg-offset-2">
                        <h1>Toggle Sidebar Navigation</h1>
                        <p>토글 사이드바 네비게이션에 대한 본문 내용입니다.</p>
                    </div>
                </div>
            </div>
        </div>
        <!-- /#page-content-wrapper -->

    </div>
    <!-- /#wrapper -->
</body>
</html>


블로그 이미지

Link2Me

,
728x90

출처 : https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sidenav

에서 테스트해볼 수 있다.

CSS에 대한 설명을 약간 추가하기 위해서 적었다.


 <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
    font-family: "Lato", sans-serif;
}

.sidenav {
    height: 100%;
    width: 0;
    position: fixed; /* fixed: 스크롤과 상관없이 항상 문서 최 좌측상단을 기준으로 좌표를 고정 */
    z-index: 1; /* z-index는 태그들이 겹칠 때 누가 더 위로 올라가는지를 결정하는 속성, 기본값은 0 */
    top: 0;
    left: 0;
    background-color: #111;
    overflow-x: hidden; /* 부모요소의 범위를 넘어가는 자식요소의 부분은 보이지 않도록 처리 */
    /* 자식 요소가 부모요소의 범위를 초과 할 때 어떻게 처리 할지를 결정 하므로 부모요소에 overflow 속성 값을 결정해 주어야 한다. */
    transition: 0.5s;
    padding-top: 60px;
}

.sidenav a {
    padding: 8px 8px 8px 32px;
    text-decoration: none;
    font-size: 25px;
    color: #818181;
    display: block;
    transition: 0.3s;
}

.sidenav a:hover {
    color: #f1f1f1;
}

.sidenav .closebtn {
    position: absolute;
    top: 0;
    right: 25px;
    font-size: 36px;
    margin-left: 50px;
}

@media screen and (max-height: 450px) {
  .sidenav {padding-top: 15px;}
  .sidenav a {font-size: 18px;}
}
</style>
</head>
<body>

<div id="mySidenav" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<h2>Animated Sidenav Example</h2>
<p>Click on the element below to open the side navigation menu.</p>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; open</span>

<script>
function openNav() {
    document.getElementById("mySidenav").style.width = "250px";
}

function closeNav() {
    document.getElementById("mySidenav").style.width = "0";
}
</script>
     
</body>
</html>


블로그 이미지

Link2Me

,
728x90

메뉴를 가로 정렬을 하고 div 배경색을 지정했는데 안먹힌다.

검색을 해보니 height:auto;min-height: 50px;overflow: hidden;  속성을 지정해주면 된다고 나온다.

box1:after 가상 선택자를 사용했더니 컨텐츠 내용에 따라 높이가 자동인식된다.


<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style type="text/css">
@charset "UTF-8";
body {font-family: '맑은 고딕', 'Apple SD Gothic Neo', sans-serif}

.menu {list-style-type: none;
    margin: 0;
    padding: 0;
}

.menu li a {display:block;
    padding:10px;
    color:#000000;
    font-size:16px;
    text-decoration:none;}
.menu li a:hover{background-color:#75dbe7;}
.menu:after{content: "";
    display:block;
    celar:both;}
.menu li {float:left;
    width:auto;}

.box1 {background-color:#f1f1f1;}
.box1:after {content: "";
    display: block;
    clear: both;}
</style>
</head>
<body>
<div class="box1">
<ul class="menu">
  <li><a href="#home">Home</a></li>
  <li><a href="#about">About Us</a></li>
  <li><a href="#clients">Our Clients</a></li>
  <li><a href="#contact">Contact Us</a></li>
  <li><a href="#map">Map</a></li>
</ul>
</div>

</body>
</html>

블로그 이미지

Link2Me

,
728x90

메뉴 가로 정렬과 세로 정렬의 차이점을 살펴보자.

<div class="menu">
<ul>
<li><a href="#">메인</a></li>
<li><a href="#">잡화</a></li>
<li><a href="#">도구</a></li>
<li><a href="#">외출</a></li>
<li><a href="#">음식</a></li>
<li><a href="#">문의</a></li>
</ul>
</div>


메뉴(세로 정렬)

메뉴(가로 정렬)

<style>
.menu ul    {margin: 0;
    padding: 0;
    list-style: none}

.menu li a    {display: block;
    padding: 5px;
    color: #000000;
    font-size: 14px;
    text-decoration: none}

.menu li a:hover    {background-color: #eeeeee}
</style>







<style>
.menu ul    {margin: 0;
    padding: 0;
    list-style: none}

.menu li a    {display: block;
    padding: 5px;
    color: #000000;
    font-size: 14px;
    text-decoration: none;}

.menu li a:hover    {background-color: #eeeeee}

.menu ul:after  {
    display: block;
    clear: both}

.menu li    {float: left;
    width: auto}
</style>


li 태그도 기본적으로 세로 정렬을 한다.

가로 정렬을 하도록 하려면 float:left; 로 하고 width 속성을 auto로 지정한다.

float 는 블록 요소를 좌우 정렬시킬 때 사용한다.

float 속성 설명은 http://link2me.tistory.com/1452 참조

text-decoration: none; /* Remove underline from links */

https://www.w3schools.com/howto/howto_css_vertical_menu.asp 에 Vertical Menu 에 대해 직접 실행해 볼 수 있다.


list-style: none; /* 항목 표시가 되지 않음 */

disc : 기본값, 검은 원
circle : 원
square 사각형
decimal : 숫자(1로 시작하는 십진수)
lower-alpha  : 알파벳 소문자 (a, b, c, d, e,..)
lower-roman : 로마자 소문자 (i, ii, iii, iv, v,..)
upper-alpha : 알파벳 대문자 (A, B, C, D, E...)
upper-roman :  로마자 대문자 (I, II, III, IV, V,...)
none : 항목 표시가 되지 않음
initial  : 기본값으로 초기화


display:block; /* 요소를 block 요소처럼 표시한다. 따라서 요소 앞 뒤로 줄바꿈 된다 */

display:inline; /* 기본값, 요소 앞 뒤로 줄바꿈되지 않는다 */

display:none; /* 박스가 생성되지 않는다. 공간을 차지 하지 않는다 */

display:inline-block; /* 요소는 inline 인데 내부는 block 처럼 표시함. */


overflow : auto; /* 내용이 잘릴때만 스크롤바가 보인다 */

overflow : visible; /* 기본값으로 내용이 더 길어도 그대로 보인다 */

overflow : hidden; /* 내용이 넘치면 자른다. 자른 부분은 보이지 않는다 */

overflow : scroll; /* 내용이 넘치지 않아도 항상 스크롤바가 보인다 */


clear : float 를 해제할 때 사용한다.

clear : none /* 기본값으로 clear 를 설정하지 않는 것과 같다 */

clear : left   /* float:left 값을 취소한다. */

clear : right /* float:right 값을 취소한다. */

clear : both /* 왼쪽, 오른쪽을 취소한다 */

블로그 이미지

Link2Me

,
728x90

array, sub array 등 다차원 배열을 단순화 시키는 경우가 필요하다.

아래 코드와 같이 편법(?) 처리하였다.

SQL 문으로 처리하는 걸 검색해보니 해결하기가 너무 어렵다.

오라클은 쉽게 제공하는 기능이 있는데 MySQL은 너무 복잡하다.


$c = new LoginClass;
$rows = $c -> getDbData('menu_items', '', '*');
foreach ($rows as $row) {
    $TreeMenu[] = $row;
}

$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($c->TreeSQL($TreeMenu)));
$c->TableTruncate('menu_treesort'); // 테이블 비우기
$i=0;
foreach($it as $k=>$v) {
    $key = '_id';
    $val = "$v";
    $c->getDbInsert('menu_treesort', $key, $val);
    $i++;
}
$c->getDbUpdate('menu_items m join menu_treesort s on m.id=s._id', "sort=s.idx", NULL,'');

echo $i.'개 Data inserted';


TreeSQL 함수

이 함수가 TreeView Sort 의 핵심이다.

function TreeSQL($array, $parent_id = 0, $parents = array()) {
    if ($parent_id == 0) {
        foreach ($array as $element) {
            if (($element['parent_id'] != 0) && !in_array($element['parent_id'], $parents)) {
                $parents[] = $element['parent_id'];
            }
        }
    }

    $R = array();
    foreach ($array as $element) {
        if ($element['parent_id'] == $parent_id) {
            if (in_array($element['id'], $parents)) {
                array_push($R,$element['id']);
                array_push($R, TreeSQL($array, $element['id'], $parents));
            } else {
                array_push($R,$element['id']);
            }
        }
    }
    return $R;
}

블로그 이미지

Link2Me

,
728x90

메뉴를 수동으로 일일이 작성하지 않고 PHP/MySQL 과 연동하여 테이블 정보를 자동으로 읽어서 메뉴가 생성되도록 하는 방법이다.


=== index.php ===

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="robots" content="noindex,nofollow"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
    <meta http-equiv="pragma" content="no-cache" />
    <meta name="apple-mobile-web-app-capable" content="no" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <title>Multi level dropdown menu in Bootstrap 3</title>
    <link rel="stylesheet" href="css/topmenu.css" />
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
    <script src="http://code.jquery.com/jquery.min.js" ></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <!--[if lt IE 9]> <!-- 5. 인터넷익스플로러 9버전 이하일 경우 html5가 인식될 수 있게 해주는 스크립트 -->
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <script src="bootstrap/js/respond.min.js"></script>
    <script src="js/topmenu.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="index.php">Home</a>
        </div>
        <div class="collapse navbar-collapse" id="navbar-collapse-1">
            <ul class="nav navbar-nav">
                <?php require_once 'menu.php';?>
            </ul>
        </div>
    </div>
</nav>
</body>
</html>


=== menu.php ===

<?php
require_once 'dbconnect.php';
$sql = "SELECT * FROM menu_items";
$res = mysqli_query($dbconn, $sql);
while($row = mysqli_fetch_assoc($res)){
    $menu[] = $row;
}

$top_menu = bootstrap_menu($menu);
echo $top_menu;

function bootstrap_menu($array,$parent_id = 0,$parents = array())
{
    if($parent_id==0) {
        foreach ($array as $element) {
            if (($element['parent_id'] != 0) && !in_array($element['parent_id'],$parents)) {
                $parents[] = $element['parent_id'];
            }
        }
    }
    $php_menu = '';
    foreach($array as $element) {
        if($element['parent_id']==$parent_id) {
            if(in_array($element['id'],$parents)) {
                $dropdown_sub=$parent_id > 0 ? 'dropdown-submenu':'';
                $php_menu .= '<li class="dropdown '.$dropdown_sub.'">';
                $php_menu .= '<a href="'.$element['url'].'" class="dropdown-toggle" data-toggle="dropdown">'.$element['name'].' <span class="caret"></span></a>';
            } else {
                $php_menu .= '<li>';
                $php_menu .= '<a href="' . $element['url'] . '">' . $element['name'] . '</a>';
            }
            if(in_array($element['id'],$parents)) {
                $php_menu .= '<ul class="dropdown-menu">';
                $php_menu .= bootstrap_menu($array, $element['id'], $parents);
                $php_menu .= '</ul>';
            }
            $php_menu .= '</li>';
        }
    }
    return $php_menu;
}

?>


=== topmenu.css ===

/* dropdown submenu */
.dropdown-submenu{position:relative;}
.dropdown-submenu>.dropdown-menu{
    top:0;left:100%;
    margin-top:-6px;
    margin-left:-1px;
    -webkit-border-radius:0 6px 6px 6px;
    -moz-border-radius:0 6px 6px 6px;
    border-radius:0 6px 6px 6px;
}
.dropdown-submenu>a:after{
    display:block;
    content:" ";
    float:right;
    width:0;
    height:0;
    border-color:transparent;
    border-style:solid;
    border-width:5px 0 5px 5px;
    border-left-color:#cccccc;
    margin-top:5px;
    margin-right:-10px;
}
.dropdown-submenu:hover>a:after{
    border-left-color:#555;
}
.dropdown-submenu.pull-left{float:none;}
.dropdown-submenu.pull-left>.dropdown-menu{
    left:-100%;
    margin-left:10px;
    -webkit-border-radius:6px 0 6px 6px;
    -moz-border-radius:6px 0 6px 6px;
    border-radius:6px 0 6px 6px;
}

@media only screen and (max-width: 768px) {
   
}

@media only screen and (min-width: 768px) {

    /* 스마트폰에서는 동작하지 않게 */

    .dropdown-submenu:hover>.dropdown-menu {
        display: block;
    }
}


=== topmenu.js ===

$(function(){
    $('ul.dropdown-menu [data-toggle=dropdown]').on('click', function(event) {
        event.preventDefault();
        event.stopPropagation();
        $(this).parent().siblings().removeClass('open');
        $(this).parent().toggleClass('open');
    });
    // 현재 선택한 메뉴 : active
    $("ul li").click(function() {
        // remove classes from all
        $("ul .active").removeClass("active");
        // add class to the one we clicked
        $(this).addClass("active");
    });

});


=== db 스키마 ===

CREATE TABLE IF NOT EXISTS `menu_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` varchar(11) DEFAULT NULL,
  `name` varchar(200) NOT NULL,
  `url` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=12 ;


INSERT INTO `menu_items` (`id`, `parent_id`, `name`, `url`) VALUES
(1, '0', 'Daum', 'http://www.daum.net'),
(2, '0', 'Java', '#'),
(3, '0', 'PHP', '#'),
(4, '3', 'PHP Tutorial', '#'),
(5, '3', '사이트', '#'),
(6, '5', '티스토리', '#'),
(7, '2', 'Java Tutorial', '#'),
(8, '2', 'Java Resources', '#'),
(9, '2', '테이블', 'table.php'),
(10, '5', '네이버', 'http://www.naver.com'),
(11, '3', 'PHP Resources', '#');


메뉴 자동으로 생성하는 것은 구글에서 treemenu 를 검색하면 나온다.

이걸 부트스트랩 기반에 적용하는 것이다.

관리자 화면에서 메뉴를 자동으로 생성하는 것은 아직 완벽하게 만들어놓지 않아서 작성하지 않는다.

다만, 참조할 게시글만 적어둔다.


http://link2me.tistory.com/1146


http://www.phpzag.com/ 사이트에 보면 도움된다.

그리고 구글링으로 jstree 를 검색하면 나온다.

http://phpflow.com/php/dynamic-tree-with-jstree-php-and-mysql/


기존 treemenu를 부트스트랩 기반으로 연동하는 걸 테스트 하는 중이다.

jQuery 기반 동작 소스를 부트스트랩 기반으로 완벽하게 처리할 때까지 시도해볼 생각이다.

블로그 이미지

Link2Me

,
728x90

부트스트랩 기반으로 멀터레벨 드랍다운 메뉴를 만드는 걸 목표로 구글링해서 찾은 소스를 분석해가면서 만들어보려고 한다.


http://bootsnipp.com/snippets/featured/multi-level-dropdown-menu-bs3

에 나온 예제 소스를 가지고 분석해보자.


사이트 HTML 소스만으로 실행하면 아래 화면과 같은 결과가 나온다.

소스 보기


이 소스에서 bootstrap 관련 CSS와 JS를 연결하면, 아래와 같이 바뀐다.


소스보기


서브메뉴가 제대로 나오지 않는다는 걸 확인할 수 있다.

이제 topmenu.css 라는 이름으로 css 파일을 추가해보자. 

서브메뉴까지 다 나온 걸 확인할 수 있다.

여기까지 시도하려고 작성한 것은 아니다.

분석을 더 해보자.

<div class="container">
    <div class="row">
        <h2>Multi level dropdown menu in Bootstrap 3</h2>
        <hr>
        <div class="dropdown">
            <a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-primary" data-target="#" href="/page.html">
                Dropdown <span class="caret"></span>
            </a>
            <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
              <li><a href="#">Some action</a></li>
              <li><a href="#">Some other action</a></li>
              <li class="divider"></li>
              <li class="dropdown-submenu">
                <a tabindex="-1" href="#">Hover me for more options</a>
                <ul class="dropdown-menu">
                  <li><a tabindex="-1" href="#">Second level</a></li>
                  <li class="dropdown-submenu">
                    <a href="#">Even More..</a>
                    <ul class="dropdown-menu">
                        <li><a href="#">3rd level</a></li>
                        <li><a href="#">3rd level</a></li>
                    </ul>
                  </li>
                  <li><a href="#">Second level</a></li>
                  <li><a href="#">Second level</a></li>
                </ul>
              </li>
            </ul>
        </div>
    </div>
</div>



<ul class="dropdown-menu"> 로 표기되고 있고,
<li class="dropdown-submenu"> 로 표기되고 있다.


=== topmenu.css ===

.dropdown-submenu { position: relative;}

.dropdown-submenu>.dropdown-menu {
    top: 0;
    left: 100%;
    margin-top: -6px;
    margin-left: -1px;
    -webkit-border-radius: 0 6px 6px 6px;
    -moz-border-radius: 0 6px 6px;
    border-radius: 0 6px 6px 6px;
}

.dropdown-submenu:hover>.dropdown-menu { display: block;}

.dropdown-submenu>a:after {
    display: block;
    content: " ";
    float: right;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
    border-width: 5px 0 5px 5px;
    border-left-color: #ccc;
    margin-top: 5px;
    margin-right: -10px;
}

.dropdown-submenu:hover>a:after { border-left-color: #fff;}

.dropdown-submenu.pull-left { float: none;}

.dropdown-submenu.pull-left>.dropdown-menu {
    left: -100%;
    margin-left: 10px;
    -webkit-border-radius: 6px 0 6px 6px;
    -moz-border-radius: 6px 0 6px 6px;
    border-radius: 6px 0 6px 6px;
}


메뉴를 수동으로 직접 작성하는 것은 별로 어려울 것이 없을 거 같다.

목적은 메뉴를 PHP와 연동하여 자동으로 생성하는 걸 구현하고 싶다.

다음에는 PHP 와 연동하여 메뉴를 자동으로 생성하는 걸 해보자.

블로그 이미지

Link2Me

,
728x90

아직 bootstrap 내용을 완벽하게 숙지하지 못한 상태에서 기능 익히느라고 Copy & Paste 하면서 형태를 변경해보면서 하다보니 원하지 않은 결과로 좀 고생하고 있다.


<nav class="navbar navbar-default navbar-fixed-top">

를 설정했는데 모달(modal)창이 계속 비활성화되어 왜 그런지 원인 찾으려고 무진장 고생을 했다.


navbar-fixed-top 때문에 생긴 현상이다.

이거 없앴더니 바로 정상 모드로 돌아온다.


if(tabName == '#modal-login'){
    //alert(tabName);
    $('#modal-login').on('shown.bs.modal', function () {
                $(this).find('input[type=text]:visible:first').focus();
    });
}


그리고 Path 설정을 하면서 고생 좀 하고 있는 중이다.

Web root 에 설정하면 문제가 없는데 실행되는 파일이 서브디렉토리에 있으면 문제가 되는거 같다.

현재 디렉토리 경로를 파악하여 어떤 경로에 있던 완벽하게 할 수 있는 코드를 만들어 볼 생각이다.


<?php
$cur_root = '../';  // 실행경로가 root 가 아니라서 root는 부모 디렉토리
$g = array(
    'path_root'   => $cur_root,
    'path_core'   => $cur_root.'_core/',
    'path_var'    => $cur_root.'_var/',
    'path_tmp'    => $cur_root.'_tmp/',
    'path_layout' => $cur_root.'layout/',
    'path_module' => $cur_root.'modules/',
    'path_plugin' => $cur_root.'plugin/',
    'path_bootstrap' => $cur_root.'plugin/bootstrap/',
    'path_page'   => $cur_root.'pages/',
    'path_file'   => $cur_root.'files/'
);

?>








블로그 이미지

Link2Me

,
728x90

부트스트랩을 적용하여 상단 메뉴에서 로그인, 로그아웃 처리하는 걸 구현중이다.

메뉴 Layout 이 완벽하게 마음에 들지 않는다. 좀 더 기능을 찾아보고 테스트해야 한다.

아직 미완성 부분도 있지만 현재까지 구현에 성공한 걸 적어둔다.


=== topmenu.php ===

<?php
if(!isset($_SESSION)) {
    session_start();
}
session_save_path('./_tmp/session');


// 단말 종류 검사 및 단말 구분에 따라 보여주는 화면 처리
require_once "deviceChk.php";


$titleName = "테스트";
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="robots" content="noindex,nofollow"/>
    <?php if($device_type != 3):?>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
    <meta http-equiv="pragma" content="no-cache" />
    <meta name="apple-mobile-web-app-capable" content="no" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <?php endif?>
    <title><?=$titleName;?></title>
    <link rel="stylesheet" href="css/topmenu.css" />
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />
    <script src="http://code.jquery.com/jquery.min.js" ></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <!--[if lt IE 9]> <!-- 5. 인터넷익스플로러 9버전 이하일 경우 html5가 인식될 수 있게 해주는 스크립트 -->
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <script src="bootstrap/js/respond.min.js"></script>
    <script src="js/login.js"></script>
    <script type="text/javascript">
        var currentName = null;
        $(document).ready(function(){
            tabSetting(); // 탭 초기화 및 설정
        });

        function tabSetting() {
            $('.tabPage').hide();
            $('#navbar-collapse-2 a').on('click', function() {
                var tabName = $(this).attr('href');
                if(currentName != tabName){
                    $('.tabPage').hide();
                    currentName = tabName;
                }
                if($(tabName).is(":visible")){
                    //$(tabName).slideUp();
                    $(tabName).toggle();
                }else{                   
                    $(tabName).slideDown();
                }

                if(tabName != '#nav-loginForm'){ // 로그인 창이 아니면
                    // 반응형으로 메뉴 동작시 메뉴 클릭후 자동 숨김
                    $('#navbar-collapse-2').collapse('hide');
                }
            });
           
            $('.side-menu-container a').on('click', function() {
                var tabName = $(this).attr('href');
                if(currentName != tabName){
                    $('.tabPage').hide();
                    currentName = tabName;
                }
                if($(tabName).is(":visible")){
                    //$(tabName).slideUp();
                    $(tabName).toggle();
                }else{                   
                    $(tabName).slideDown();
                }
            });
        }

    </script>
</head>
<body>

<nav class="navbar navbar-default">
     <div class="container-fluid"><!-- 전체 화면을 사용 / container 클래스 선택자는 최대 넓이가 1170px -->
        <div class="navbar-header">
            <!--모바일 시 메뉴 숨기기 시작 -->
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-2">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <!--모바일 시 메뉴 숨기기 끝  -->
            <a class="navbar-brand" href="#"><?=$titleName;?></a>
        </div>
        <div class="collapse navbar-collapse" id="navbar-collapse-2">
            <ul class="nav navbar-nav navbar-left">
                <li><a href="#home">Home</a></li>
                <li><a href="#tab01">News</a></li>
                <li><a href="#tab02">Contact</a></li>
                <li><a href="#tab03">About</a></li>
                <li><a href="#tab04">Support</a></li>
                <li><a href="#tab05">Blog</a></li>
                <li><a href="#tab06">게시판</a></li>
                <li><a href="#base">Base</a></li>
                <li><a href="#custom">Custom</a></li>
                <li><a href="#more">More</a></li>
                <li><a href="#logo">Logo</a></li>
                <?php if(isset($_SESSION['userid']) && !empty($_SESSION['userid'])):?>
                    <li><a href="#" onclick="document.getElementById('logout-form').submit();">로그아웃</a></li>
                <?php else:?>
                    <li><a href="#nav-loginForm" data-toggle="modal" >로그인</a></li>
                <?php endif;?>
            </ul>

            <div class="modal fade" id="nav-loginForm" role="dialog">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal">&times;</button>
                            <h4 class="modal-title"><span class="glyphicon glyphicon-lock"></span>로그인 폼</h4>
                        </div>
                        <div class="modal-body">
                            <form role="form" id="login-form">
                                <div class="form-group">
                                    <label for="userid"><span class="glyphicon glyphicon-user"></span>userID</label>
                                    <input type="text" class="form-control" id="userid" placeholder="아이디를 입력하세요" autofocus required />
                                </div>
                                <div class="form-group">
                                    <label for="password"><span class="glyphicon glyphicon-eye-open"></span>비밀번호</label>
                                    <input type="password" class="form-control" id="password" placeholder="비밀번호를 입력하세요" required />
                                </div>
                                <div class="checkbox">
                                    <label><input type="checkbox" value="" checked>로그인 유지</label>
                                </div>
                                <button type="submit" id="login-submit" class="btn btn-success btn-block"><span class="glyphicon glyphicon-off"></span>로그인</button>
                            </form>
                        </div>
                        <div class="modal-footer">
                            <button id="login_lost_btn" type="button" class="btn btn-link">비밀번호 찾기</button>
                            <button id="login_register_btn" type="button" class="btn btn-link">회원가입</button>
                            <!--<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>-->
                        </div>
                        <!-- End # Login Form -->

                        <form id="logout-form" style="display:none" action="oauth/logout.php" method="POST"></form>

                        <!-- Begin | Lost Password Form --><!-- 좀 더 테스트 해봐야 할 영역 -->
                        <form id="lost-form" style="display:none;">
                            <div class="modal-body">
                                <div id="div-lost-msg">
                                    <div id="icon-lost-msg" class="glyphicon glyphicon-chevron-right"></div>
                                    <span id="text-lost-msg">Type your e-mail.</span>
                                </div>
                                <input id="lost_email" class="form-control" type="text" placeholder="E-Mail (type ERROR for error effect)" required>
                            </div>
                            <div class="modal-footer">
                                <div>
                                    <button type="submit" class="btn btn-primary btn-lg btn-block">Send</button>
                                </div>
                                <div>
                                    <button id="lost_login_btn" type="button" class="btn btn-link">Log In</button>
                                    <button id="lost_register_btn" type="button" class="btn btn-link">Register</button>
                                </div>
                            </div>
                        </form>
                        <!-- End | Lost Password Form -->

                        <!-- Begin | Register Form -->
                        <form id="register-form" style="display:none;">
                            <div class="modal-body">
                                <div id="div-register-msg">
                                    <div id="icon-register-msg" class="glyphicon glyphicon-chevron-right"></div>
                                    <span id="text-register-msg">Register an account.</span>
                                </div>
                                <input id="register_username" class="form-control" type="text" placeholder="Username (type ERROR for error effect)" required>
                                <input id="register_email" class="form-control" type="text" placeholder="E-Mail" required>
                                <input id="register_password" class="form-control" type="password" placeholder="Password" required>
                            </div>
                            <div class="modal-footer">
                                <div>
                                    <button type="submit" class="btn btn-primary btn-lg btn-block">Register</button>
                                </div>
                                <div>
                                    <button id="register_login_btn" type="button" class="btn btn-link">Log In</button>
                                    <button id="register_lost_btn" type="button" class="btn btn-link">Lost Password?</button>
                                </div>
                            </div>
                        </form>
                        <!-- End | Register Form -->

                    </div>

                </div>
            </div>
        </div><!-- .navbar-collapse -->
     </div><!-- .container-fluid -->
</nav>

<main class="container-fluid">
     <div class="container main-container">
         <div class="col-md-2 sidebar">
             <div class="row">
                 <div class="absolute-wrapper"> </div>
                 <!-- Menu -->
                 <div class="side-menu">
                     <nav class="navbar navbar-default" role="navigation">
                         <!-- Main Menu -->
                         <div class="side-menu-container">
                             <ul class="nav navbar-nav">
                                 <li><a href="#tab01"><span class="glyphicon glyphicon-cloud"></span> Link</a></li>
                             </ul>
                         </div>
                     </nav>
                 </div>
             </div>
            
         </div>
        
         <!-- Main 화면 -->            
         <div class="col-md-10 content">
             <div class="panel panel-default">
                 <div class="panel-body">
                    메인 본문 표시 영역
                    <div id="tab01" class="tabPage">
                    <img class="img-responsive" src="./images/img_01.jpg">
                    </div>
                    <div id="tab02" class="tabPage">
                        <img class="img-responsive" src="./images/img_02.jpg">
                    </div>
                    <div id="tab03" class="tabPage">
                        <img class="img-responsive" src="./images/img_03.jpg">
                    </div>
                    <div id="tab04" class="tabPage">
                        <img class="img-responsive" src="./images/img_04.jpg">
                    </div>
                    <div id="tab05" class="tabPage">
                        <img class="img-responsive" src="./images/img_05.jpg">
                    </div>
                 </div> 
            </div>   
         </div>    
    </div>
</main>

<footer class="pull-left footer">
    <p class="col-md-12">
        <hr class="divider">
        &copy; Linke2ME 2016
    </p>
</footer>

</body>
</html>


=== login.js ===

$(function(){
    $('#login-submit').click(function(){
        $('#login-form').submit(function(e){
            e.preventDefault();
            $.ajax({
                url: 'oauth/loginChk.php',
                type: 'POST',
                data: {userid:$('#userid').val(), password:$('#password').val()},
                dataType: "json",
                success: function (response) {
                if(response.result == 1){
                    //alert('로그인 성공');                       
                    $('#nav-loginForm').modal('hide');
                    location.reload(); // 화면 갱신                      
                } else {
                    alert('로그인 실패');
                }                   
                },
                error: function(){
                    alert('ajax form 전송에 문제가 있습니다');
                }
            });           
        });
    });

});


=== loginChk.php ===

<?php
if(!isset($_SESSION)) {
    session_start();
}

@extract($_POST);
if(isset($userid) && !empty($userid) && isset($password) && !empty($password)) {
    require_once 'dbconnect.php'; // db접속 성공
    require_once '../phpclass/loginClass.php';
   
    $salt = "&
c4f96fa549b58356d638%#!s29e5dce852e5d1";
    $password = hash('sha384', $password.$salt);

    $c=new LoginClass();
    $rs = $c->WebUserAuthCheck($userid,$password);
    if($rs == '1') {
        $_SESSION['userid'] = $userid;
        echo '{"result":"1"}';
    } else {
        echo '{"result":"0"}';
    }
}
?>


=== dbconnect.php ===

<?php
include_once 'dbinfo.php';
$dbconn = isConnectDb($db);

function isConnectDb($db)
{
    $conn = mysqli_connect($db['host'],$db['user'],$db['pass'],$db['name'],$db['port']);
    mysqli_set_charset($conn, "utf8");  // DB설정이 잘못되어 euc-kr 로 되어 있으면 문제가 됨
    if (mysqli_connect_errno()) {
        echo "Failed to connect to MySQL: " . mysqli_connect_error();
        exit;
    } else {
        return $conn;
    }
}
?>


=== logout.php ===

<?php
if(!isset($_SESSION)) {
    session_start();
}
unset($_SESSION['userid']);
if(session_destroy()){
    echo '{"result":"1"}';
    header("Location: ../topmenu.php");
}
?>


=== topmenu.css ===

@charset "utf-8";
@import url(http://fonts.googleapis.com/earlyaccess/nanumgothic.css);

body {padding-top: 0px;}

/* 로그인 폼 */
.modal-header {
      color:black !important;
      text-align: center;
      font-size: 30px;
}
.modal-footer {
      background-color: #f9f9f9;
      padding: 5px 5px 5px 5px;
      border-top: 0px;
}
/* 로그인 폼 End */ 

.sidebar { padding-left: 0;}
.main-container { background: #FFF; padding-top: 15px; margin-top: -20px;}
.footer { width: 100%;}   
:focus { outline: none;}
.side-menu {
    position: relative;
    width: 100%;
    height: 100%;
    background-color: #f8f8f8;
    border-right: 1px solid #e7e7e7;
}
.side-menu .navbar {
    border: none;
}
.side-menu .navbar-header {
    width: 100%;
    border-bottom: 1px solid #e7e7e7;
}
.side-menu .navbar-nav .active a {
    background-color: transparent;
    margin-right: -1px;
    border-right: 5px solid #e7e7e7;
}
.side-menu .navbar-nav li {
    display: block;
    width: 100%;
    border-bottom: 1px solid #e7e7e7;
}
.side-menu .navbar-nav li a {
    padding: 15px;
}
.side-menu .navbar-nav li a .glyphicon {
    padding-right: 10px;
}
.side-menu #dropdown {
    border: 0;
    margin-bottom: 0;
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
}
.side-menu #dropdown .caret {
    float: right;
    margin: 9px 5px 0;
}
.side-menu #dropdown .indicator {
    float: right;
}
.side-menu #dropdown > a {
    border-bottom: 1px solid #e7e7e7;
}
.side-menu #dropdown .panel-body {
    padding: 0;
    background-color: #f3f3f3;
}
.side-menu #dropdown .panel-body .navbar-nav {
    width: 100%;
}
.side-menu #dropdown .panel-body .navbar-nav li {
    padding-left: 15px;
    border-bottom: 1px solid #e7e7e7;
}
.side-menu #dropdown .panel-body .navbar-nav li:last-child {
    border-bottom: none;
}
.side-menu #dropdown .panel-body .panel > a {
    margin-left: -20px;
    padding-left: 35px;
}
.side-menu #dropdown .panel-body .panel-body {
    margin-left: -15px;
}
.side-menu #dropdown .panel-body .panel-body li {
    padding-left: 30px;
}
.side-menu #dropdown .panel-body .panel-body li:last-child {
    border-bottom: 1px solid #e7e7e7;
}
.side-menu #search-trigger {
    background-color: #f3f3f3;
    border: 0;
    border-radius: 0;
    position: absolute;
    top: 0;
    right: 0;
    padding: 15px 18px;
}
.side-menu .brand-name-wrapper {
    min-height: 50px;
}
.side-menu .brand-name-wrapper .navbar-brand {
    display: block;
}
.side-menu #search {
    position: relative;
    z-index: 1000;
}
.side-menu #search .panel-body {
    padding: 0;
}
.side-menu #search .panel-body .navbar-form {
    padding: 0;
    padding-right: 50px;
    width: 100%;
    margin: 0;
    position: relative;
    border-top: 1px solid #e7e7e7;
}
.side-menu #search .panel-body .navbar-form .form-group {
    width: 100%;
    position: relative;
}
.side-menu #search .panel-body .navbar-form input {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    width: 100%;
    height: 50px;
}
.side-menu #search .panel-body .navbar-form .btn {
    position: absolute;
    right: 0;
    top: 0;
    border: 0;
    border-radius: 0;
    background-color: #f3f3f3;
    padding: 15px 18px;
}
/* Main body section */
.side-body {
    margin-left: 310px;
}

.navbar-brand { position: relative; z-index: 2; }

.navbar-nav.navbar-right .btn { position: relative; z-index: 2; padding: 4px 20px; margin: 10px auto; }

.navbar .navbar-collapse { position: relative; }
.navbar .navbar-collapse .navbar-right > li:last-child { padding-left: 22px; }

.navbar .nav-collapse { position: absolute; z-index: 1; top: 0; left: 0; right: 0; bottom: 0; margin: 0; padding-right: 120px; padding-left: 80px; width: 100%; }
.navbar.navbar-default .nav-collapse { background-color: #f8f8f8; }
.navbar.navbar-inverse .nav-collapse { background-color: #222; }
.navbar .nav-collapse .navbar-form { border-width: 0; box-shadow: none; }
.nav-collapse>li { float: right; }

.btn.btn-circle { border-radius: 50px; }
.btn.btn-outline { background-color: transparent; }

/* 화면 해상도에 따른 글자 크기 변경 */
@media only screen and (max-width: 768px) {
    .navbar .navbar-collapse .navbar-right > li:last-child { padding-left: 15px; padding-right: 15px; }
   
    .navbar .nav-collapse { margin: 7.5px auto; padding: 0; }
    .navbar .nav-collapse .navbar-form { margin: 0; }
    .nav-collapse>li { float: none; }
       
    .side-menu {
        position: relative;
        width: 100%;
        height: 0;
        border-right: 0;
    }

    .side-menu .navbar {
        z-index: 999;
        position: relative;
        height: 0;
        min-height: 0;
        background-color:none !important;
        border-color: none !important;
    }
    .side-menu .brand-name-wrapper .navbar-brand {
        display: inline-block;
    }
    /* Slide in animation */
    @-moz-keyframes slidein {
        0% {
            left: -300px;
        }
        100% {
            left: 10px;
        }
    }
    @-webkit-keyframes slidein {
        0% {
            left: -300px;
        }
        100% {
            left: 10px;
        }
    }
    @keyframes slidein {
        0% {
            left: -300px;
        }
        100% {
            left: 10px;
        }
    }
    @-moz-keyframes slideout {
        0% {
            left: 0;
        }
        100% {
            left: -300px;
        }
    }
    @-webkit-keyframes slideout {
        0% {
            left: 0;
        }
        100% {
            left: -300px;
        }
    }
    @keyframes slideout {
        0% {
            left: 0;
        }
        100% {
            left: -300px;
        }
    }
    /* Slide side menu*/
    /* Add .absolute-wrapper.slide-in for scrollable menu -> see top comment */
    .side-menu-container > .navbar-nav.slide-in {
        -moz-animation: slidein 300ms forwards;
        -o-animation: slidein 300ms forwards;
        -webkit-animation: slidein 300ms forwards;
        animation: slidein 300ms forwards;
        -webkit-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    .side-menu-container > .navbar-nav {
        /* Add position:absolute for scrollable menu -> see top comment */
        position: fixed;
        left: -300px;
        width: 300px;
        top: 43px;
        height: 100%;
        border-right: 1px solid #e7e7e7;
        background-color: #f8f8f8;
        overflow: auto;
        -moz-animation: slideout 300ms forwards;
        -o-animation: slideout 300ms forwards;
        -webkit-animation: slideout 300ms forwards;
        animation: slideout 300ms forwards;
        -webkit-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    @-moz-keyframes bodyslidein {
        0% {
            left: 0;
        }
        100% {
            left: 300px;
        }
    }
    @-webkit-keyframes bodyslidein {
        0% {
            left: 0;
        }
        100% {
            left: 300px;
        }
    }
    @keyframes bodyslidein {
        0% {
            left: 0;
        }
        100% {
            left: 300px;
        }
    }
    @-moz-keyframes bodyslideout {
        0% {
            left: 300px;
        }
        100% {
            left: 0;
        }
    }
    @-webkit-keyframes bodyslideout {
        0% {
            left: 300px;
        }
        100% {
            left: 0;
        }
    }
    @keyframes bodyslideout {
        0% {
            left: 300px;
        }
        100% {
            left: 0;
        }
    }
    /* Slide side body*/
    .side-body {
        margin-left: 5px;
        margin-top: 70px;
        position: relative;
        -moz-animation: bodyslideout 300ms forwards;
        -o-animation: bodyslideout 300ms forwards;
        -webkit-animation: bodyslideout 300ms forwards;
        animation: bodyslideout 300ms forwards;
        -webkit-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    .body-slide-in {
        -moz-animation: bodyslidein 300ms forwards;
        -o-animation: bodyslidein 300ms forwards;
        -webkit-animation: bodyslidein 300ms forwards;
        animation: bodyslidein 300ms forwards;
        -webkit-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    /* Hamburger */
    .navbar-toggle-sidebar {
        border: 0;
        float: left;
        padding: 18px;
        margin: 0;
        border-radius: 0;
        background-color: #f3f3f3;
    }
    /* Search */
    #search .panel-body .navbar-form {
        border-bottom: 0;
    }
    #search .panel-body .navbar-form .form-group {
        margin: 0;
    }
    .side-menu .navbar-header {
        /* this is probably redundant */
        position: fixed;
        z-index: 3;
        background-color: #f8f8f8;
    }
    /* Dropdown tweek */
    #dropdown .panel-body .navbar-nav {
        margin: 0;
    }    
}

블로그 이미지

Link2Me

,
728x90

자바스크립트로 하면 여러줄을 적어줘야 하는데 jQuery 로 하면 심플해진다.

// Assumes element with id='button'
var button = document.getElementById('button');

button.onclick = function() {
    var mydiv = document.getElementById('tabName');
    if (mydiv.style.display === 'block' || mydiv.style.display === '') {
        mydiv.style.display = 'none';
    }
    else {
        mydiv.style.display = 'block';
    }
};

$("#button").click(function() {
    // assumes element with id='button'
    $("#tabName").toggle();
});


메뉴만들기

열심히 이 자료 저자료 테스트해보면서 이해하고 내것으로 만들어가고 있는 중이다.

아래 코드를 연습한 소스코드 파일 첨부한다.

이미지 파일은 http://blog.naver.com/hyoyeol/70177051041 블로그에 올려진 파일 이미지 파일을 활용했다.

하지만 코드 내용은 완전 다르다.


topmenu-01.zip

=== index.php ===

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="robots" content="noindex,nofollow"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>메뉴만들기</title>
    <link rel="stylesheet" href="css/bootstyle.css" />
    <link rel="stylesheet" href="css/topmenu.css" />
    <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <script src="http://code.jquery.com/jquery.min.js" ></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <script type="text/javascript">
        var currentName = null;
        $(document).ready(function(){
            tabSetting(); // 탭 초기화 및 설정
        });
       
        function tabSetting() {
            $('.tabPage').hide();
            $('.topmenu a').on('click', function() {
                var tabName = $(this).attr('href');
                if(currentName != tabName){
                    $('.tabPage').hide();
                    currentName = tabName;
                }
                $(tabName).toggle();
            });
        }
    </script>
</head>
<body>
<header>
     <nav class="navbar navbar-fixed-top navbar-full navbar-light">
        <div class="topmenu">
            <a href="#home">Home</a>
            <a href="#tab01">News</a>
            <a href="#tab02">Contact</a>
            <a href="#tab03">About</a>
            <a href="#tab04">Support</a>
            <a href="#tab05">Blog</a>
            <a href="#tools">Tools</a>
            <a href="#base">Base</a>
            <a href="#custom">Custom</a>
            <a href="#more">More</a>
            <a href="#logo">Logo</a>
            <a href="#friends">Friends</a>
            <a href="#partners">Partners</a>
            <a href="#people">People</a>
            <a href="#work">Work</a>
        </div>
     </nav>
</header>
<main class="container-fluid">
     <div id="contents">
        <div id="tab01" class="tabPage">
            <img src="./images/img_01.jpg">
        </div>
        <div id="tab02" class="tabPage">
            <img src="./images/img_02.jpg">
        </div>
        <div id="tab03" class="tabPage">
            <img src="./images/img_03.jpg">
        </div>
        <div id="tab04" class="tabPage">
            <img src="./images/img_04.jpg">
        </div>
        <div id="tab05" class="tabPage">
            <img src="./images/img_05.jpg">
        </div>
    </div>

</main>

</body>
</html>


/// nav 설명

<nav class="navbar navbar-fixed-top navbar-full navbar-light">

.navbar-fixed-top : 상단에 고정

.navbar-fixed-bottom : 하단에 고정


/// 설명 : 화면 부드럽게 나오고 사라지게 하기

$(tabName).toggle(); 는 화면이 부드럽게 나오고 부드럽게 사라지지 않는다.

화면을 부드럽게 나오고 부드럽게 사라지게 하고 싶으면

$(element).is(":visible"); // 화면이 보이는 상태인지 체크

를 사용해서 코드를 변경해주면 된다.


if($(tabName).is(":visible")){
    $(tabName).slideUp();
}else{
    $(tabName).slideDown();
}



=== topmenu.css ===

charset "utf-8";
@import url(http://fonts.googleapis.com/earlyaccess/nanumgothic.css);

body, div, ul, li, table, tr, td, th{margin:0px; padding:0px;}

ul, li{list-style:none;}

body {
    font-family: NanumGothic, '나눔고딕', NanumGothicWeb, "Malgun Gothic",Gulim,sans-serif;
    background: #ddd;
    font-size:10px;
}

div.topmenu {
    border: 1px solid #ccc;
    background-color: #f1f1f1;
    margin:auto;
    overflow: auto;
    white-space: nowrap;
}

div.topmenu a {
    display: inline-block; /* 자동으로 줄바꿈되지 않고 크기를 지정할 수 있음 */
    color: black;
    text-align: center;
    padding: 14px;
    text-decoration: none;
    transition: 0.1s;
}

div.topmenu a:hover {
    background-color: #ddd;
    color:#0000ff;
    cursor:pointer;
    font-weight:bold;
}

/*컨텐츠*/
#contents{
    width:900px;
    margin:auto;
}

#contents div{
    margin:0 0px;
}

/* 화면 해상도에 따른 글자 크기 변경 */
@media only screen and (max-width: 768px) {
    div.topmenu a {
        padding: 12px;
    }
}
@media only screen and (min-width: 768px) and (max-width: 1024px) {
    div.topmenu a {
        padding: 13px;
    }
}
@media only screen and (min-width: 1025px) {
        body { background-color: blue; }
        h1 { color: white; }
}

블로그 이미지

Link2Me

,
728x90

Tree 형태의 JSON 을 만드는 방법으로 easyUI jQuery 를 사용하는 방법을 테스트 했다.

 

id: "1",
name: "loreim ipsum",
data: {},
children: [{
    id: "2",
    name: "lorem ipsum1",
    data: {},
    children: [{
        id: "3",
        name: "lorem ipsum2",
        data: {},
        children: [{


tree 형태의 JSON을 만드는 방법은

http://stackoverflow.com/questions/4328515/convert-php-array-to-json-tree

에 나온 걸 참조하면 된다.



Convert PHP array to JSON tree

=== treeSQLtoJSON.php ===

<?php
include_once "connect.php";
$sql = "SELECT * FROM treeview_items";
$res = mysqli_query($db, $sql);
while($row = mysqli_fetch_assoc($res)){
    $data[] = $row;
}

$node = array();
// Build array of item references:
foreach($data as $key => &$item) {
   $node[$item['id']] = &$item;
   // Children array:
   $node[$item['id']]['children'] = array();
   // Empty data class (so that json_encode adds "data: {}" )
   $node[$item['id']]['data'] = new StdClass();
}

// Set items as children of the relevant parent item.
foreach($data as $key => &$item)
   if($item['parent_id'] && isset($node[$item['parent_id']]))
      $node [$item['parent_id']]['children'][] = &$item;

// Remove items that were added to parents elsewhere:
foreach($data as $key => &$item) {
   if($item['parent_id'] && isset($node[$item['parent_id']]))
      unset($data[$key]);
}

$json = json_encode($data);
echo $json;
?>

=== treeview.php ===

<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Basic Tree - jQuery EasyUI Demo</title>
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<meta http-equiv="X-UA Compatible"/>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<link rel="stylesheet" href="js/easyui/themes/default/easyui.css">
<link rel="stylesheet" href="js/easyui/themes/icon.css">
<link rel="stylesheet" href="js/easyui/demo.css">

<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/easyui/jquery.easyui.min.js"></script>
<script type="text/javascript">
$(function(){
    $('#tt').tree({
        url: 'treeSQLtoJSON.php',
        onClick: function(node){
            //alert(node.link);
            $('.content').html(node.link);
        }
    });
});
</script>

</head>
<body>
<div style="margin:20px 0;"></div>
<div class="container-fluid"><!--container-fluid 클래스 선택자는 전체 화면을 사용할 때 사용 -->
  <div class="container"><!--container 클래스 선택자는 최대 넓이가 1170px -->
    <div class="col-md-2 sidenav">
      <!--사이드바 내용-->
        <div class="easyui-panel" style="padding:5px">
            <ul id="tt"></ul>
        </div>
    </div>
    <div class="col-md-10">
        <div class="content">
          <!--본문 내용-->
          본문내용
        </div>
    </div>
  </div>
</div>
</body>
</html>


코드가 훨씬 심플해졌다.


이제 http://www.jeasyui.com/demo/main/index.php 사이트 데모를 가지고 만들어보기가 훨씬 수월해졌다.


블로그 이미지

Link2Me

,
728x90

Treeview 를 만들기 위해서 이것 저것 테스트 해보느라고 고생 좀 하고 있다.

easytree.js 는 node.id 얻는 방법을 몰라서 포기를 했다.

그래서 검색해서 easyUI tree 를 찾아냈다.

http://www.jeasyui.com/documentation/index.php# 에 설명이 잘 나와 있다.

easyUI jQuery 는 잘 활용하면 홈페이지가 확 달라질 거 같다.


중요 포인트는 MySQL DB 자료를 JSON Data 로 만드는 방법을 알아야 하더라.

좀 복잡한 것을 만들 줄 알아야 하는데 아직 그 부분까지는 이해를 못했다.


=== treeSQLtoJSON.php ===

<?php
include_once "connect.php";
$sql = "SELECT * FROM treeview_items";
$res = mysqli_query($db, $sql);
while($row = mysqli_fetch_assoc($res)){
    $menu[] = $row;
}

// while 하나로 처리해야 하는데 Class 처리 목적 분리 코딩
$result = array();
foreach ($menu as $row){
    array_push($result,
    array('id'=>$row['id'],
          'parentId'=>$row['parent_id'],
          'name'=>$row['text'],
          'link'=>$row['link']
    ));
}

echo json_encode($result);
?>


JSON Data 만드는 법을 알고 나면 http://www.jeasyui.com/tutorial/tree/tree6.php 에서 내용을 읽어보고 데모 파일을 받아서 수정해서 사용하면 된다.

블로그 이미지

Link2Me

,
728x90

jsTree 는 MIT 에서 공개한 jquery plugin 으로 HTML 또는 JSON 데이터를 Tree 형식으로 화면에 출력해주는 라이브러리이다.

https://www.jstree.com/ 에서 jquery plugin 설명을 참조한다.

여기서 다루는 jstree.js 는 include 해보니 jstree.min.js 와 약간 다른지 tree 아이콘 모양이 달라서 jstree.min.js 를 사용했다.


본 자료는 구글링을 통해서 얻은 지식으로 기존 자료에 부족한 사항을 추가했다.

기본적인 설명은 http://phpflow.com/php/dynamic-tree-with-jstree-php-and-mysql/ 사이트에 잘 나와있다.

관리자가 메뉴를 추가/수정/삭제하는 기능도 이 사이트에 잘 나와 있다.

다만 아쉬웠던 것은 Treeview 에서 아이템을 클릭하면 해당 ITEM에 연결된 link 를 다른 <div>에 뿌려주는 것이 되어야 Treeview 의 의미가 있으므로 이 부분 처리를 하려고 열심히 검색하고 찾았는데 ....

포기하고 생각을 변경하여 시도를 한 끝에 원하는 결과를 얻었다.

이 과정에서 고수의 도움을 받았는데 알고 보면 생각의 전환만 했어도 쉽게 해결할 수 있었던 사항이다.


=== 테이블 구조 ===

CREATE TABLE IF NOT EXISTS `treeview_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` varchar(11) DEFAULT NULL,
  `name` varchar(200) NOT NULL,
  `text` varchar(200) NOT NULL,
  `link` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=15 ;


INSERT INTO `treeview_items` (`id`, `parent_id`, `name`, `text`, `link`) VALUES
(1, '0', 'MySQL', 'MySQL', '#'),
(2, '0', 'Java', 'Java', '#'),
(3, '0', 'PHP', 'PHP', '#'),
(4, '3', '투토리얼', '투토리얼', 'http://link2me.tistory.com'),
(5, '3', 'PHP Script', 'Script', '#'),
(6, '5', '메일', '메일', '#'),
(7, '2', 'Java Tutorial', 'Tutorial', '#'),
(8, '2', 'Java Resources', 'Resources', '#'),
(9, '1', 'MySQL Tutorial', 'Tutorial', '#'),
(10, '5', '로그인', '로그인', 'http://www.naver.com'),
(11, '3', 'PHP Resources', 'Resources', '#'),
(12, '10', 'Login1', 'Login1', ''),
(13, '10', 'Login2', 'Login2', ''),
(14, '3', '추가노드', '추가노드', '');


=== tree.php ===

<!DOCTYPE html>
<head>
<meta charset=UTF-8" />
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<meta http-equiv="X-UA Compatible" control="IE=edge,chrome=1" />
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<link rel="stylesheet" href="js/jstree/style.min.css">
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="js/jstree/jstree.min.js"></script>

<script type="text/javascript">
$(document).ready(function(){
    $('#tree-container').jstree({
        'plugins': ["wholerow"],
        'core' : {
            'data' : {
                "url" : "tree_getdb.php",
                "dataType" : "json"
            }
        }
    }).on("changed.jstree", function (e, data) {
        if(data.selected.length) {
            var id = data.instance.get_node(data.selected[0]).id;
            $.post('tree_link_result.php', {id: id}, function(data){
                //alert(data);
                $('.content').html(data);
            });
        }
    });

});
</script>
</head>
<body>
<div class="container-fluid"><!--container-fluid 클래스 선택자는 전체 화면을 사용할 때 사용 -->
  <div class="container"><!--container 클래스 선택자는 최대 넓이가 1170px -->
    <div class="col-md-2">
      <!--사이드바 내용-->
        <div id="tree-container"></div>
    </div>
    <div class="col-md-10">
        <div class="content">
          <!--본문 내용-->
          본문내용
        </div>
    </div>
  </div>
</div>

</body>
</html>


=== tree_link_result.php ===

<?php
$id=$_POST['id'];
if(isset($id) && !empty($id)){
    include_once "connect.php";
    $sql = "SELECT * FROM treeview_items where id='{$id}'";
    $result = mysqli_query($db, $sql);
    if($row=mysqli_fetch_array($result)){
        echo $row['link'];
    }
}
?>


=== on("changed.jstree", function (e, data) { 부분을 아래와 같이 수정해도 된다.

    }).bind("select_node.jstree", function (e, data) {
        var id = data.node.id;
        $.post('tree_link_result.php', {id: id}, function(data){
            //alert(data);
            if(data == '#') return '';
            $('.content').html(data);
        });


나머지 자료는 phpflow.com 과 인터넷에서 구해서 위에 나온 부분만 수정해서 사용하면 문제없이 처리될 것이다.


구글링해서 구해 테스트한 jstree 소스만 첨부한다.

jstree.zip


블로그 이미지

Link2Me

,