728x90

상대경로 상에서 게시판(board)에서 게시글을 클릭하면 해당 게시글을 수정할 수 있는 write.php 파일로 이동하는 기능을 작성하다보니 경로 추출이 쉽지 않다.


성공한 결과값부터 적어둔다.

$('.tr1').click(function() {
    var idx=$(this).attr('data-uid');
    var modulepath =$("#ajax_loginpath").attr('data-module');
    var page = urlParam('p') ? urlParam('p') : 1;
    var moveURL = modulepath + 'bbs/board.php?m=write&idx='+idx+'&p='+page;
    $(location).attr('href', moveURL);

}).mouseover(function() {
    $(this).children('.td2').css({'backgroundColor':'#DCDCDC','cursor':'pointer'});
}).mouseout(function() {
    $(this).children('.td2').css({'backgroundColor':'#FFFFFF','cursor':'default'});
});


과정 설명

테이블에서 해당 게시글을 눌렀을때 별도의 팝업창을 띄우거나 해당 게시글을 수정할 수 있는 창을 만들기 위해서는 해당 게시글의 uid 번호를 알아야 한다.

이것은 테이블 작성시에

<tr class="tr1" data-uid="'.$row['uid'].'">

로 해당 uid 를 추출할 수 있게 해준다.


modulepath 는

<div id="ajax_loginpath" data-path="<?php echo $g['path_page'];?>" data-module="<?php echo $g['path_module'];?>"></div>

에서 추출할 수 있도록 작성한다.


해당 페이지 번호도 넘겨줘야 게시글 수정후 list.php 파일로 돌아올 때 화면이 변경되지 않는다.

그러기 위해서는 URL parameter 값을 받아서 넘겨줘야 한다.

이 URL parameter 값을 넘겨주는 함수는

http://handam.tistory.com/41 분이 작성한 함수가 있어서 편하게 해결할 수 있었다. 꾸뻑^^


function urlParam(name){
    var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
    if (results==null){
       return null;
    }
    else{
       return results[1] || 0;
    }
}


변수에서 추출을 못할 경우에는 null 을 반환하는데

페이지가 없으면 1을 반환하도록 삼항연산자를 사용했다.

var page = urlParam('p') ? urlParam('p') : 1;


이제 이동하고 싶은 URL을 설정하면 된다.

var moveURL = modulepath + 'bbs/board.php?m=write&idx='+idx+'&p='+page;

$(location).attr('href', moveURL); // 해당 URL 로 이동

블로그 이미지

Link2Me

,
728x90

loginChk.php 파일의 경로가 /abc/pages/loginChk.php 로 되어 있다.


로그인 모달창에서 로그인 처리를 하는데 경로설정에 대한 문제로 골치가 아팠다.

유연한 상대경로 설정하는 방법을 몰라서 겪은 증상이다.


아래와 같이 경로에 PHP의 상대경로를 직접 입력하면 문제가 될까? 안될까?

이렇게 입력하면 ajax 에서는 경로를 인식하지 못한다.


자동 상대경로 설정법은 http://link2me.tistory.com/1197 를 참조하면 된다.


// 로그인 처리
$('#login-submit').click(function(e){
    e.preventDefault();
    //alert(window.location.pathname); // 현재 경로 확인
    $.ajax({
        url:
<?php echo $g['path_page'];?>"+'loginChk.php',
        type: 'POST',
        data: {userid:$('#userid').val(), password:$('#password').val()},
        dataType: "json",
        success: function (response) {
           if(response.result == 1){
               //alert('로그인 성공');
               $('#modal-login').modal('hide');
               location.reload(); // 화면 갱신
           } else {
               alert('로그인 실패');
           }
        },
        error: function(jqXHR, textStatus, errorThrown){
           alert("arjax error : " + textStatus + "\n" + errorThrown);
        }
    });
});


해결방법

PHP의 변수를 ajax 등 javascript 로 넘기기 위해서는 HTML 로 일단 저장해야 한다.

<body></body> 사이에 아래 코드를 추가한다.

내용은 전혀 보이지 않게 처리한다.

<div id="ajax_loginpath" data-path="<?php echo $g['path_page'];?>" ></div>


그런 다음에 아래와 같이 코드를 구현하면 해결된다.

// 로그인 처리
$('#login-submit').click(function(e){
    e.preventDefault();
    //alert(window.location.pathname); // 현재 경로 확인
    var loginpath =$("#ajax_loginpath").attr('data-path');
    $.ajax({
        url: loginpath+'loginChk.php',
        type: 'POST',
        data: {userid:$('#userid').val(), password:$('#password').val()},
        dataType: "json",
        success: function (response) {
           if(response.result == 1){
               //alert('로그인 성공');
               $('#modal-login').modal('hide');
               location.reload(); // 화면 갱신
           } else {
               alert('로그인 실패');
           }
        },
        error: function(jqXHR, textStatus, errorThrown){
           alert("arjax error : " + textStatus + "\n" + errorThrown);
        }
    });
});


결론 정리

상대경로의 개념은 현재 실행되는 파일을 기준으로 경로(path)를 상대적으로 설정한다.

따라서 실행되는 파일의 위치가 달라지면 그 위치를 기준으로 경로를 상대적으로 설정하기 때문에

../../loginChk.php 처럼 적어주면 문제가 생긴다.

실행되는 파일의 위치가 어디든지 간에 상대경로 문제가 아무런 문제없이 해결되기 위해서는 코드를 잘 짜야 한다.

이런 문제때문에 계속 문제에 부딪치면서 완벽한 해결책을 구현해보겠다는 일념으로 드디어 해결을 했다.

자동 상대경로 설정법은 http://link2me.tistory.com/1197 과 이 게시글을 활용하면 누구든지 경로설정 문제로 골치아픈 일은 없을 것이다.

블로그 이미지

Link2Me

,
728x90

window.location.href; // URL 포함한 전체 경로


window.location.href = 'index.php';

location.replace('index.php'); // 이전 페이지로 돌아가기 할 수 없음


window.location.pathname; // 현재 경로 확인


window.location.pathname.split('/').pop(); // 현재 실행 파일명


location.reload() and location.reload(true) works like F5 on browser. (페이지를 재실행)

window.location.reload() : 컴퓨터에 이미 받아놓은 캐쉬파일을 뒤지고 없으면 서버에서 파일을 받아온다.
window.location.reload(true) : true 가 들어가게 되면 캐쉬파일은 무시하고 무조건 서버에서 받아온다.


// 회원가입 처리를 위한 화면 이동
$('#member-join').click(function(){
    $('#modal-login').modal('hide'); // 모달 창 닫기
    //alert(window.location.pathname); // 현재 경로 확인
    if(window.location.pathname.split('/').pop() != 'member_join.php'){ // 현재 실행 파일명
        location.replace('member_join.php');
    }
});



// 부모창의 form안에 자동으로 값을 채워넣고 그 값을 submit
window.opener.document.getElementById("parent_hidden_field_something").value = "somethingSpecial";
window.opener.document.getElementById("parent_form_something").submit();




블로그 이미지

Link2Me

,
728x90

책을 다시 보면서 기본 지식을 다시 정리해보고 있다.

하다가 막히면 다시 원점에서 흘려버린 걸 다시 되짚어 가면서 시작하는 것이 도움이 될 수도 있기 때문이다.


모든 언어의 기본은 데이터 타입을 파악하는 것부터 시작한다.

자바스크립트에서는 기본 타입을 제외한 모든 값은 객체다.


자바스크립트는 변수를 선언할 때 var 라는 한가지 키워드를 사용한다.

 - 선언부에 Data Type을 기재하지 않는다.

 - var 선언문이 위치한 영역에 따라 전역/지역변수 결정

 - var 를 사용하지 않으면 전역(global)변수로 선언

var 로 변수를 선언하기 때문에 데이터 타입이 무엇인지 몰라서 헤매는 경우도 생기더라.

+ 는 숫자연산과 문자열 연결에 사용되므로 잘못된 결과가 나올 수 있으니 주의해서 봐야 한다.


숫자

 다른 언어와 달리 하나의 숫자형만 존재한다.

 모든 숫자를 64비트 부동 소수점 형태로 저장한다.

 모든 숫자를 실수로 처리하므로, 나눗셈 연산을 할 때는 주의해야 한다.

  ex) 1/2 = 0.5

 정수만 구하고 싶다면 Math.floor() 메서드를 사용한다.

 + 연산자는 숫자일 경우에는 더하기 연산이 수행된다.

 Number 형 변환 실패 결과는 NaN  

  ex) "abc" - 0 = NaN

 문자열

 작은 따옴표나 큰 따옴표로 생성한다.

 문자열은 문자 배열처럼 인덱스를 이용해서 접근할 수 있다.

 + 연산자는 문자열 연결 연산을 수행한다.

 boolean

 자바스크립트는 true 와 false를 나타내는 boolean 타입을 가진다.

 undefined

 자바스크립트에서 '값이 비어있음'을 나타낸다.

 typeof 연산자 결과는 undefined 이다. 즉, Data Type 이 정해지지 않은 타입

 null

 자바스크립트에서 '값이 비어있음'을 나타낸다.

 typeof 연산자 결과는 object 이다. null 이 아니다. 아무것도 참조하지 않는 값이다.

 객체

 자바스크립트 객체는 key:value 형태의 property들은 저장하는 컨테이너다.

  - 객체 내에서 변수는 속성(property)이라 부른다.

  - 객체 내에서 함수는 메서드(method)라 부른다.

  - 이름은 key라고 불린다.

 객체는 여러 개의 property들을 포함할 수 있다.

 객체 생성

   - 생성자 문법을 이용하여 객체 생성 :
     new 연산자 사용 var hotel = new Object(); // 객체를 위한 공간 생성

     this 키워드 -> window 객체를 나타냄

   - 객체 생성자 표기법을 이용하여 객체를 생성

 객체 property 삭제는 delete 연산자를 이용해서 삭제할 수 있지만 객체 자체는 삭제 못한다.

 상속이란 기존의 생성자 함수나 객체를 기반으로 새로운 생성자 함수나 객체를 쉽게 만드는 것

 비교

 기본 타입은 동등 연산자(==)를 이용해서 비교할 때 값을 비교한다.

 동등 연산자(==)는 피연산자의 타입이 다를 경우 타입 변환을 거친 다음 비교한다.
 참조 타입인 객체 비교는 참조값이 같아야 true 가 된다.

 일치 연산자(===)는 피연산자의 타입이 다를 경우 타입을 변경하지 않고 비교한다.

 배열

 자바스크립트에서 배열은 크기를 지정하지 않아도 된다.
 배열 리터럴은 []를 사용한다.
 동적으로 배열 원소를 추가할 수 있다.
 length 프로퍼티는 배열 내에서 가장 큰 인덱스에 1을 더한 값이다.

 실제 메모리는 length 크기처럼 할당되지 않는다.

 push() 메서드는 인수로 넘어온 항목을 배열의 끝에 추가한다.

 arr.length = 5;

 arr.push('english');

 생성자 함수로 배열을 생성할 때 new 연산자를 사용한다.

 delete arr[3]; // 배열 요소 삭제하라는 의미지만 실제는 해당 요소값을 undefined로 설정한다.


 배열도 객체이므로

  for(var i in arr) {

    console.log(i, arr[i]);

  }

  문을 사용해서 배열 내의 모든 프로퍼티를 열거할 수 있다. --> 불필요한 프로퍼티가 출력될 수 있다.

  for(var i=0; i<arr.length; i++) {

   console.log(i, arr[i]);

  }

  문을 사용하면 불필요한 프로퍼티가 출력되지 않는다.

 함수

 function 키워드로 함수를 선언한다.

 선언부에 Return Type 을 기재하지 않는다.

 자바스크립트에서는 함수도 하나의 값처럼 취급한다.

 함수도 숫자나 문자열처럼 변수에 할당하는 것이 가능하다.

 매개변수로 넘기는 값에 변수 타입을 기술하지 않는다.

 자바스크립트 함수 표현식에서 함수 이름은 꼭 붙이지 않아도 된다. (익명함수)

 함수 내부에서 정의된 매개변수는 var를 사용하여 정의한다.

 함수에 정의된 인자가 3개라고 가정하자.

   - 2개는 정의하나 나머지 하나를 정의하지 않으면 undefined 값이 할당된다.

   - 정의된 개수보다 많게 4개를 정의하면, 초과된 인수는 무시된다.


블로그 이미지

Link2Me

,
728x90

Form 데이터를 jQuery submit 하면서 기초가 부족해서 삽질을 많이 한다.

http://hayageek.com/jquery-submit-form/ 사이트 예제, http://www.sqler.com/387921 를 보면 도움된다.


Form 전송시 필드(input box) 를 동적으로 추가해야 할 경우가 있다.

http://www.codexworld.com/add-remove-input-fields-dynamically-using-jquery/ 에서 소스를 받아서 코드를 보강하면서 테스트를 했다.


수정/추가한 부분 및 내역

- javascript:void(0); 대신에 #으로 수정하고 jQuery 코드 부분 수정(e.preventDefault() 추가)

- 용어 내 스타일로 변경

- form submit 부분 추가하고 ajax 형태로 처리하는 코드 추가

- 입력값이 없을 때 체크하는 코드 추가

※ DB에 저장하고 나서 다시 수정/삭제/추가할 경우까지 고려되어 있지는 않다.


=== index.php ===

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Add more fields using jQuery</title>
<style type="text/css">
input[type="text"]{height:18px;width:220px;vertical-align:top;}
.field_wrapper div{ margin-bottom:10px;}
.add_button{ margin-top:10px; margin-left:10px;vertical-align: text-bottom;}
.removeBtn{ margin-top:10px; margin-left:10px;vertical-align: text-bottom;}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    var maxCount = 5;
    var addButton = $('.add_button');
    var wrapper = $('.field_wrapper');
    var AddBox = '<div><input type="text" name="kordiv[]" value=""/><a href="#" class="removeBtn" title="제거"><img src="remove-icon.png"/></a></div>';
    var x = 1;
    $(addButton).click(function(e){
        e.preventDefault();
        if(x < maxCount){
            x++;
            $(wrapper).append(AddBox);
        }else{
            alert('최대 '+maxCount+'개까지 허용합니다');
            return false;
        }
    });
    $(wrapper).on('click', '.removeBtn', function(e){
        e.preventDefault();
        $(this).parent('div').remove();
        x--;
    });

    $("#submit1").click(function(){
        // 폼 요소 내부의 입력값만을 찾기 위해서 폼 요소에서 find()를 호출
        var xyz = $("#myform").find('[name=xyz]').val();
        if(xyz =='') {
            alert('xyz 값이 입력되지 않았습니다.');
            return false;
        }

        // 배열로 된 값이 제대로 입력되었는지 체크
        var cnt = 0;
        $('input[name^="kordiv"]').each(function() {
            //alert($(this).val());
            if($(this).val() === '') {
                cnt++;
            }
        });
        if(cnt > 0){
            alert('kordiv 에 입력되지 않는 필드가 '+cnt+'개 있습니다');
            return false;
        }

        var formData = $("#myform").serialize();
        var URL = $("#myform").attr("action");
        $.post(URL, formData, function(data, textStatus, jqXHR){
            alert(data);
            var data = jQuery.parseJSON(data);
            $.each(data, function(index, value) {
                alert(value);
            });

        }).fail(function(jqXHR, textStatus, errorThrown) {
            console(errorThrown);
        });

    });

});
</script>
</head>
<body>
<form name="frm" id="myform" action="frm_result.php" method="POST">
<input type="hidden" name="xyz" value="123" />
<div class="field_wrapper">
    <div>
        <input type="text" name="kordiv[]" value=""/>
        <a href="#" class="add_button" title="추가"><img src="add-icon.png"/></a>
    </div>
</div>
<input type="hidden" name="submit" value="true" />
</form>
<br/>
<input type="button" id="submit1" value="전송" />
</body>
</html>


=== frm_result.php ===

<?php
if(isset($_POST['submit'])){
    $kordiv_array = $_POST['kordiv']; // 배열

    /*
    print '<pre>';
    print_r($kordiv_array);
    print_r($_POST['xyz']);
    print '</pre>';
    // */

    $R = array();
    foreach($kordiv_array as $value){ // 배열로 받은 걸 분리 처리
        //echo $value;
        array_push($R,$value);
    }
    $Content = 'Hello world';
    echo json_encode(array('rs'=>$R,'Content' => $Content));
}
?>


블로그 이미지

Link2Me

,
728x90

<th><a href="#" onfocus=blur()  onClick="window.open('Stats.php','','width=1600, height=680,top=200,left=50,location=no, directories=no,resizable=no,status=no,toolbar=no,menubar=no,titlebar=no,scrollbars=no, resizable=no,copyhistory=no');return false;">일별통계</a></th>



location=no 를 설정해도 보안 문제 때문에 무조건 보이게 한단다.

그래서 윈도우 창을 새로 띄운 경우에는 URL 정보가 노출된다.


jQuery popup 하는 걸 테스트해보면

<div></div> 가 있는 상태에서 화면에 보이지 않게 하다가 새로운 창으로 정보를 보이게 해주는 역할이다.

그러다보니 기존 파일의 jQuery 정보와의 충돌문제가 있을 수도 있어서 원하지 않은 결과가 나오기도 한다.


팝업창 띄우는 걸 검색해서 하나 찾았다.

http://inspirationalpixels.com/tutorials/custom-popup-modal


이것만으로 쉽게 해결될 수도 있지만 해결이 잘 안될때가 있다.

그걸 극복하기 위해서 편법을 구상했다. 바로 <iframe> 이다.

iframe 에 대한 사항은 http://www.homejjang.com/05/iframe.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" />
<link href="http://www.jqueryscript.net/css/jquerysctipttop.css" rel="stylesheet" type="text/css">
<link href="popup_layer.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
    // 팝업 OPEN
    $('#popup-open-1').on('click', function(e)  {
        var targeted_popup_class = jQuery(this).attr('data-popup-open');
        $('[data-popup="' + targeted_popup_class + '"]').fadeIn(350);
        e.preventDefault();
    });
 
    // 팝업 CLOSE
    $('#popup-colse-1').on('click', function(e)  {
        var targeted_popup_class = jQuery(this).attr('data-popup-close');
        $('[data-popup="' + targeted_popup_class + '"]').fadeOut(350);
        e.preventDefault();
    });
});
</script>
</head>
<body>
<a href="#" id="popup-open-1" class="btn" data-popup-open="popup-1">Open Popup #1</a>
<div class="popup" data-popup="popup-1">
    <div class="popup-inner">
        <iframe src="http://www.daum.net" frameborder="0" width="1200" height="500" marginwidth="0" marginheight="0"></iframe>
        <a href="#" id="popup-colse-1" class="popup-close" data-popup-close="popup-1">x</a>
    </div>
</div>

</body>
</html>




블로그 이미지

Link2Me

,
728x90

PHP 배열로 넘겨주는 함수에 따라서 처리를 다르게 해야 동작된다는 걸 확인하고 코드를 다시 적어둔다.


http://link2me.tistory.com/1134 게시글에서 가져오는 함수에서 넘겨주는 값이

문자열로 넘겨줄 경우와 배열로 넘겨줄 경우 각각 상황에 맞게 구현해야 한다.


<?php
require_once 'connect.php'; // db접속 성공
require_once 'statsClass.php'; // 통계 클래스
$b = new statsClass();
$R = $b->extract_YM();
date_default_timezone_set('Asia/Seoul');
if(isset($_GET['ym'])){
    $ym = $_GET['ym'];
} else {
    $ym = date("Ym");
}
$ticks = json_encode($b->maxdate_YM($ym));
$line1 = json_encode($b->dailyCnt_value($ym));
$line2 = json_encode($b->userCnt_value($ym));
?>
<!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" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- http://www.jqplot.com 제공 자바스크립트 include -->
<script type="text/javascript" src="../js/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="../js/jqplot/plugins/jqplot.barRenderer.js"></script>
<script type="text/javascript" src="../js/jqplot/plugins/jqplot.pointLabels.js"></script>
<script type="text/javascript" src="../js/plugins/jqplot.categoryAxisRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="../js/jqplot/jquery.jqplot.css" />
<script type="text/javascript">
$(document).ready(function(){
    var plot1;

    var obj1 = <?php echo $line1; ?>;
    var line1 = $.map(obj1, function(el) { return el });
    var obj2 = <?php echo $line2; ?>;
    var line2 = $.map(obj2, function(el) { return el });
    var ticks = JSON.parse('<?php echo $ticks; ?>');

    renderChart(line1,line2,ticks);

    $('#selectmonth').on('change',function(){
        if(this.value !== ""){
            var optVal=$(this).find(":selected").val();
            //var pageURL = "<?php echo $_SERVER['PHP_SELF'];?>?ym=" + optVal;
            //$(location).attr('href', pageURL);

            var year = optVal.substr(0,4); // 년
            var month = optVal.substr(4,2); // 월
            $.post('stats_db.php',{optVal:optVal},function(msg){
                //alert(msg); // 배열 형태로 넘어오는지 확인 목적
                var jsonObj = $.parseJSON(msg); // JSON 문자열을 JavaScript object 로 반환
                //alert(typeof jsonObj.ticks);
                //alert(jsonObj.data1);
// string 인지 object 인지 확인 목적
                var data1 = $.map(jsonObj.data1, function(el) { return el });
                var data2 = $.map(jsonObj.data2, function(el) { return el });
                //alert(jsonObj.ticks);
                var xAxis = jsonObj.ticks;
                updatePlot(data1,data2,xAxis);
            });
        }
    });

});


function renderChart(line1,line2,xAxis){
    plot1 = $.jqplot('chartDiv', [line1,line2], CreateBarChartOptions(xAxis));
}

function updatePlot(line1,line2,xAxis){
    plot1.destroy();
    plot1 = $.jqplot('chartDiv', [line1,line2], CreateBarChartOptions(xAxis));
}

function CreateBarChartOptions(xAxis) {
    var optionsObj = {
        title: '일자별 접속 통계',
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer, // 막대 그래프
            rendererOptions: { barWidth: 10 }, // bar의 너비 수동으로 설정
            pointLabels: { show: true } // 레이블 값
        },
        axes: {
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: xAxis,
                tickOptions: {
                    formatString: '%d' // 정수형으로 표시
                }
                //label:'일자'
            },
            yaxis:{
                //renderer:$.jqplot.DateAxisRenderer,
                min:0,
                //max:80
            }
        },
        highlighter: { show: false }
    };
    return optionsObj;
}
</script>

</head>
<body>
<div id="chartDiv" style="height:400px;width:1500px; "></div>
<div style="height:300px;width:1490px;margin-top:10px;text-align:right;">
<select name="month" id="selectmonth">
<option value="">년월 선택</option>
<?php
    while ($row = mysql_fetch_array($R)){
        echo "<option value='".$row[0]."' ";
        if($row[0] === $ym) echo "selected='selected'";
        echo ">".$row[0]."</option>\n";
    }
?>
</select>
</div>
</body>
</html>


=== stats_db.php ===

<?php
if(isset($_POST['optVal'])){
    require_once 'connect.php'; // db접속 성공
    require_once 'statsClass.php'; // 통계 클래스
    $b = new statsClass;
    $ym = $_POST['optVal'];
    $data1 = $b->dailyCnt_value($ym); // 배열로 받은 결과
    $data2 = $b->userCnt_value($ym); // 배열로 받은 결과
    $ticks = $b->maxdate_YM($ym);  // 배열로 받은 결과
    $R = array('data1'=>$data1,'data2'=>$data2, 'ticks'=>$ticks);
    echo json_encode($R);
}
?>

블로그 이미지

Link2Me

,
728x90

Array 변수 처리에 대한 이해가 부족하여 기능 구현보다 변환하는데 시간이 휠씬 더 걸리고 있다.

다 기초가 부족한 탓이다. 테스트한 결과를 무조건 기록해둔다.


PHP 함수에서 return json_encode($R); 배열로 반환 결과가

{"1":"36","2":"23","3":"14","4":"7","5":"12","6":"6","7":"5","8":"9","9":"17","10":"7"}

일 경우


자바스크립트에서 배열 변수로 받기 위해서는

var obj1 = JSON.parse('<?php echo $line1; ?>');

var line1 = new Array();

for(var i in obj1){

    line1.push(obj1[i]);

}

로 하면 값만 추출된 배열변수가 만들어진다.

또다른 방법으로 테스트를 했다.

var obj1 = <?php echo $line1; ?>;

var line1 = $.map(obj1, function(el) { return el });

로 해도 동일한 결과가 나온다.



배열 변환 결과가

[0,1,2,3,4,5,6,7,8,9,10]

로 화면 출력될 경우에는

var ticks = JSON.parse('<?php echo json_encode($ticks); ?>');

또는

var ticks = <?php echo '["' . implode('","', $ticks) . '"]' ?>;

둘 중에 하나를 사용하면 배열 변수가 된다.


PHP 배열로 반환된 결과를

<?php

$Line2 = array();
foreach($line2 as $key => $value){
    array_push($Line2,$value);
}

?>

로 값만 다시 배열로 만든다음에

var line2 = <?php echo '["' . implode('","', $Line2) . '"]' ?>;

로 자바스크립트 배열 변수를 만들 수 있다.


테스트한 파일을 그대로 적어둔다.

<?php
require_once 'connect.php'; // db접속 성공
require_once 'statsClass.php'; // 통계 클래스
$b = new statsClass();
$R = $b->extract_YM();
date_default_timezone_set('Asia/Seoul');
if(isset($_GET['ym'])){
    $ym = $_GET['ym'];
} else {
    $ym = date("Ym");
}
$ticks = $b->maxdate_YM($ym);
$line1 = $b->dailyCnt_value($ym);
$line2 = $b->userCnt_value($ym);
//echo $line1.'<br />';
//echo json_encode($line2).'<br />';
//echo json_encode($ticks).'<br />';
$Line2 = array();
foreach($line2 as $key => $value){
    array_push($Line2,$value);
}
?>
<!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" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- http://www.jqplot.com 제공 자바스크립트 include -->
<script type="text/javascript" src="../js/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="../js/jqplot/plugins/jqplot.barRenderer.js"></script>
<script type="text/javascript" src="../js/jqplot/plugins/jqplot.pointLabels.js"></script>
<script type="text/javascript" src="../js/plugins/jqplot.categoryAxisRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="../js/jqplot/jquery.jqplot.css" />
<script type="text/javascript">
$(document).ready(function(){
    var plot1;
    /*
    var obj1 = JSON.parse('<?php echo $line1; ?>');
    var line1 = new Array();
    for(var i in obj1){
        line1.push(obj1[i]);
    }
    */
    var obj1 = <?php echo $line1; ?>;
    var line1 = $.map(obj1, function(el) { return el });

    //var obj2 = JSON.parse('<?php echo json_encode($line2); ?>');
    /*
    var line2 = new Array();
    for(var i in obj2){
        line2.push(obj2[i]);
    }
    */
    var line2 = <?php echo '["' . implode('","', $Line2) . '"]' ?>;

    //var ticks = JSON.parse('<?php echo json_encode($ticks); ?>');
    var ticks = <?php echo '["' . implode('","', $ticks) . '"]' ?>;

    renderChart(line1,line2,ticks);

    $('#selectmonth').on('change',function(){
        if(this.value !== ""){
            var optVal=$(this).find(":selected").val();
            var pageURL = "<?php echo $_SERVER['PHP_SELF'];?>?ym=" + optVal;
            $(location).attr('href', pageURL);
        }
    });

});


function renderChart(line1,line2,xAxis){
    plot1 = $.jqplot('chartDiv', [line1,line2], CreateBarChartOptions(xAxis));
}

function updatePlot(line1,line2,xAxis){
    plot1.destroy();
    plot1 = $.jqplot('chartDiv', [line1,line2], CreateBarChartOptions(xAxis));
}

function CreateBarChartOptions(xAxis) {
    var optionsObj = {
        title: '일자별 접속 통계',
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer, // 막대 그래프
            rendererOptions: { barWidth: 10 }, // bar의 너비 수동으로 설정
            pointLabels: { show: true } // 레이블 값
        },
        axes: {
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: xAxis,
                tickOptions: {
                    formatString: '%d' // 정수형으로 표시
                }
                //label:'일자'
            },
            yaxis:{
                //renderer:$.jqplot.DateAxisRenderer,
                min:0,
                //max:80
            }
        },
        highlighter: { show: false }
    };
    return optionsObj;
}
</script>

</head>
<body>
<div id="chartDiv" style="height:400px;width:1500px; "></div>
<div style="height:300px;width:1490px;margin-top:10px;text-align:right;">
<select name="month" id="selectmonth">
<option value="">년월 선택</option>
<?php
    while ($row = mysql_fetch_array($R)){
        echo "<option value='".$row[0]."' ";
        if($row[0] === $ym) echo "selected='selected'";
        echo ">".$row[0]."</option>\n";
    }
?>
</select>
</div>
</body>
</html>


블로그 이미지

Link2Me

,
728x90

어제 고객사 사이트에 autocomplete 기능을 적용 테스트를 했다.

내가 사용하는 환경인 윈도우10 Explorer 11 에서는 autocomplete 동작이 잘 된다.

하지만 고객사 키맨으로부터 전혀 검색을 할 수가 없어 기존 사용하던 것도 안된다는 민원이 발생해서 환경을 확인해보니 윈도우 7 에 Explorer 버전이라고 나온다. Explorer 세부 버전정보까지는 확인 불가

그래서 결국에

$('#searchValue').autocomplete({
    source: "path/autosearch.php",
    minLength: 1
});

는 주석처리 할 수 밖에 없었다.


// === autosearch.php ====
<?php
require_once "connect.php";

if (isset($_GET['term'])){
    $return_arr = array();

    $keyword = $_GET['term'];
    $sql = "SELECT distinct(name) FROM member WHERE name LIKE '%".$keyword."%'";
    $result = mysql_query($sql);
    while($row = mysql_fetch_assoc($result)){
        array_push($return_arr,$row['name']);
    }

    echo json_encode($return_arr);
}
?>


중복없이 이름 검색이 되도록 하기 위해서 distinct 처리를 했다.

원하는 결과가 잘 나옴에도 불구하고 적용은 할 수가 없었다.


http://jqueryui.com/autocomplete/ 에서 샘플로 나온 것이 아래 스크립트를 포함하고 있어서 이걸로 테스트를 했는데 윈도우 10 Firefox 브라우저에서는 잘 되는걸 확인했다.

<link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" type="text/css" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>


일단 접속하는 브라우저의 정확한 정보부터 수집하는 코드를 구현해야 할 거 같다.

지금은 Chrome,Firefox, Explorer 여부만 수집되는데 버전 정보까지 수집되도록 코드를 세분화해야 할 거 같다.

그래야 새로운 코드 적용시 발생하는 민원을 정확하게 감지할 수 있을 거 같다.


http://www.computerhope.com/issues/ch000604.htm 사이트 자료에 Explorer 세팅 정보를 수정하면 동작되는 것 처럼 되어 있기는 하다.


멀티부팅되는 환경을 만들어서 다양한 접속을 해야만 하나보다.

블로그 이미지

Link2Me

,
728x90

현재 실행중인 파일에서 일부 값이 변경되어 그 값을 가지고 변경되어야 할 경우가 있다.


PHP 에서 echo $_SERVER['PHP_SELF']; 로 확인해보면 http://domain/path/filename.php 까지를 추출한다.


jQuery 에서 alert($(location).attr('href')); 로 확인해보면 $(location).attr('href'); 는 뒤에 GET 변수까지를 추출한다.


그래서

var pageURL = $(location).attr('href')+"?ym=" + optVal;

$(location).attr('href', pageURL);

로 하면 잘못된 결과가 나온다.

즉 GET 변수까지를 $(location).attr('href') 로 인식하므로 뒤에 또 덧붙여져 ?ym=201611?ym=201612 이런 식이 되어 버린다.


그래서 PHP 를 같이 활용하여

var pageURL = "<?php echo $_SERVER['PHP_SELF'];?>?ym=" + optVal;

$(location).attr('href', pageURL);

로 코드 구현해서 원하는 결과를 얻었다.


$('#selectmonth').on('change',function(){
    if(this.value !== ""){
        var optVal=$(this).find(":selected").val();
        var pageURL = "<?php echo $_SERVER['PHP_SELF'];?>?ym=" + optVal;
        $(location).attr('href', pageURL);
    }
});


참고사항

$(location).attr('host');        // returns host
$(location).attr('hostname');    // returns hostname
$(location).attr('path');        // returns path
$(location).attr('href');        // returns href
$(location).attr('port');        // returns port
$(location).attr('protocol');    // returns protocol


블로그 이미지

Link2Me

,
728x90


JQuery 기반 Autocompete 구현을 해보기로 하고 검색해서 개념을 잡고 테스트했다.

jQuery 를 모를 때는 엄두도 낼 수 없었는데 jQuery 에 대한 기본 개념을 조금 이해하고 다양한 플러그인(plugin)들을 테스트 해보고 있다.


http://www.bewebdeveloper.com/tutorial-about-autocomplete-using-php-mysql-and-jquery 에서 제공한 소스코드를 받아서 윈도우 AutoSet9 에서 설치하였다.

ajax_refresh.php 코드는 내가 사용하는 방식의 코드가 아니라서 수정했다.

나머지 파일은 약간 수정했다.



=== ajax_refresh.php ===

<?php
include_once 'connect.php';

$keyword = $_POST['keyword'];
$sql = "SELECT * FROM country WHERE country_name LIKE '%".$keyword."%' ORDER BY uid ASC LIMIT 0, 10";
$result = mysqli_query($db, $sql);
while($row = mysqli_fetch_assoc($result)){
    $list[] = $row;
}

foreach ($list as $rs) {
    // put in bold the written text
    $country_name = str_replace($_POST['keyword'], '<b>'.$_POST['keyword'].'</b>', $rs['country_name']);
    // add new option
    echo '<li onclick="set_item(\''.str_replace("'", "\'", $rs['country_name']).'\')">'.$country_name.'</li>';
}
?>


=== autocomplete.js ===

function autocomplet() {
    var min_length = 0; // min caracters to display the autocomplete
    var keyword = $('#uid').val();
    if (keyword.length >= min_length) {
        $.ajax({
            url: 'ajax_refresh.php',
            type: 'POST',
            data: {keyword:keyword},
            success:function(data){
                $('#country_list_id').show();
                $('#country_list_id').html(data);
            }
        });
    } else {
        $('#country_list_id').hide();
    }
}

// set_item : this function will be executed when we select an item
function set_item(item) {
    // change input value
    $('#uid').val(item);  // 실제 DB와 연동하여 값을 넘겨줘서 검색해야 하는 부분
    // hide proposition list
    $('#country_list_id').hide();
}


파일은 원 사이트에서 받아도 되고 첨부한 파일을 받아서 DB 관련 부분을 수정해서 테스트 해봐도 된다.

본 첨부파일에는 dbconnect.php 파일도 같이 포함되어 있고, DB 스키마를 내가 사용하는 uid로 수정한 것도 포함되어 있다. 즉 받아서 DB에 테이블 생성하고 경로만 지정해주면 바로 동작이 가능하다.

mysqli 기반으로 테스트 한 것이므로 mysql 를 사용하는 환경이라면 약간 수정해야 한다.


autocomplete_for_php.zip


이 정도로도 개념 이해는 도움은 많이 되는데 다른 것도 검색해서 테스트해보고 기록해 두려고 한다.

문제점 : 한글 자동완성 검색 안됨


한글검색되는 코드 (추천)

구글링을 해보니 코드가 유사하게 몇개의 사이트에서 검색된다. 이용하기는 이 코드가 훨씬 편할 거 같기는 하다.

원  소스 사이트는 https://jqueryui.com/autocomplete/ 다. 여기서 데모 실행부터 해보면 된다.

이 사이트에 가면 유용한 기능이 많다. 기능 적용이 매우 단순하다.

아래 코드 연결된 버전 정보로 해도 되지만 jqueryui.com 사이트에 적용된 최신버전으로 적용해도 된다.


사용법

1. jquery-ui.min.css, jquery-ui.min.js 링크 추가 또는 파일 다운로드 받아서 폴더 경로 추가

2. <input type='text' name='country' value='' id='auto'> input 에 ID 추가하거나 Class 추가

3. jQuery 코드

$('#auto').autocomplete({ 

source: "autosearch.php", // 타이핑시 보여질 내용

minLength: 1

});

4. PHP 코드 구현(autosearch.php)

<?php
require_once 'sessionChk.php'; // 세션 체크
require_once 'dbconnect.php';

if (isset($_GET['term'])){
    $return_arr = array();

    $keyword = $_GET['term'];
    $sql = "SELECT distinct(userNM) FROM members WHERE userNM LIKE '%".$keyword."%'";
    $result = mysqli_query($db,$sql);
    while($row = mysqli_fetch_assoc($result)){
        array_push($return_arr,$row['userNM']);
    }
    echo json_encode($return_arr);
}
?>



autocomplete-master.zip


<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo</title>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/themes/base/minified/jquery-ui.min.css" type="text/css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script><!-- 최신버전으로 구해서-->
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.1/jquery-ui.min.js"></script>   
<script type="text/javascript">
$(function() {
    //autocomplete
    $(".auto").autocomplete({
        source: "autosearch.php",
        minLength: 1
    });               
});
</script></head>
<body>
    <form action='' method='post'>
        <p><label>Country:</label><input type='text' name='country' value='' class='auto'></p>
    </form>
</body>
</html>


=== autosearch.php ===

이 부분 코드는 내가 사용하는 방식으로 수정했다.

<?php
include_once 'connect.php';

if (isset($_GET['term'])){
    $return_arr = array();

    $keyword = $_GET['term'];
    $sql = "SELECT country_name FROM country WHERE country_name LIKE '%".$keyword."%'";
    $result = mysqli_query($db, $sql);
    while($row = mysqli_fetch_assoc($result)){
        $return_arr[] =  $row['country_name'];
    }
   
    echo json_encode($return_arr);
}
?>


여기서 검색어 결과가 너무 많이 나오는 것이 싫다면 LIMIT 를 사용해서 제한하면 된다.

$sql = "SELECT distinct(country_name) FROM country WHERE country_name LIKE '%".$keyword."%' LIMIT 10";

검색할 내용이 너무 많다면 별도로 검색한 결과를 별도 테이블로 작성해서 그 검색결과를 자동완성 검색어로 불러들려도 된다. 이 경우에는 별도로 코딩이 좀 필요하다.

블로그 이미지

Link2Me

,
728x90

jQuery 팝업창에서 부모창으로 값을 전달해야 할 때 사용하는 방법이다.


=== 부모창 ===

<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script language='javascript'>
$(document).ready(function() {
    $('#pay').submit(function() {
        window.open('', 'payviewer', 'width=400,height=400,resizeable,scrollbars');
        this.action = 'popup.php';
        this.method = 'POST';
        this.target = 'payviewer';
    });
});
</script>

<form id="pay" >
    <input type="hidden" name="var" value="POST DATA SENT">
    <input type="text" name="name" id="name" value="홍길동">
    <input type="submit" value="결제하기">
</form>


=== 자식창 : popup.php ===

<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script language='javascript'>
$(document).ready(function() {
    $('#payreturn').submit(function() {
        var name = $("input[name='name']").val(); // 현재 폼의 입력값
        $("input[name='name']",opener.document).val(name); // 값 전달 방식 1
        //$(opener.document).find("#name").val(name); // 값 전달 방식 2

        //$("#name",opener.document).val(name); // 값 전달방식 3
        window.self.close(); // 현재 팝업 닫기
    });
});
</script>

<p><?php echo($_POST['var']); ?></p>
<form id="payreturn" >
    <input type="text" name="name" value="<?php echo($_POST['name']); ?>">
    <input type="submit" value="확인">
</form>


위 샘플코드의 파일

popup.zip



$("input[name='name']",opener.document).val(name);는 부모창의 id를 지정하지 않았어도 값을 변경할 수 있다.

$(opener.document).find("#name").val(name); 는 부모창의 id를 직접 찾아서 값을 변경한다.


jQuery 자식 팝업 창에서 부모창 컨트롤
$(opener.document).find("#Form").attr("action","index.do").submit();

// 팝업창에서 부모창 함수 호출

opener.location.href="javascript:fun();"; //일반적인 방법

$(opener.location).attr("href","javascript:부모스크립트함수명();"); //jQuery 이용
$(opener.location).attr("href","javascript:fun();"); //jQuery 이용


// 부모창의 필드값 가져오기

1. 일반적인 방법
var parentValue = opener.document.getElementById("parentId").value;
2. jQuery를 이용한 방법
$("#parentId", opener.document).val();
3. find를 이용한 방법
$(opener.document).find("#parentId").val();


//팝업창에서 부모창 새로고침(새로고침 의사 표현을 묻는 창이 뜸)
window.opener.parent.location.reload();
window.opener.document.location.reload();


// 작은 윈도우 창을 열어서(window.open) 특정 작업을 처리한 후 부모창(opener)을 refresh하는 방법

// window.opener.location.reload(); 에서 window는 생략 가능

<script>
opener.location.reload();
window.close();
</script>


//팝업창 자신 페이지 새로고침
document.location.reload();

//팝업창 닫기
window.self.close();


// 부모창의 URL을 대체시킨다.

opener.location.replace("URL정보");


// 전체 창에서 새 페이지 열기

top.location.href="abc.php";


// 연 창의 URL 이동

opener.location.href="abc.php";


<script type="text/javascript">
  alert("회원가입을 하시겠습니까?")
  location.href= "member.php"
</script>


블로그 이미지

Link2Me

,
728x90

form 데이터를 window 팝업창으로 값을 전달하여 open 해야 할 필요가 있을 때 사용하는 방법이다.


<form action="popup.php" method="post" target="payviewer" onsubmit="window.open('popup.php', 'payviewer', 'width=200, height=200,resizeable,scrollbars');">
    <input type="hidden" name="var" value="POST DATA SENT">
    <input type="submit" value="결제하기" >
</form>


=== popup.php ===

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Receiver popup</title>
</head>
<body>
<p><?php echo($_POST['var']); ?></p>
</body>
</html>


위와 같은 방법을 jQuery 로 전달하는 방법이다.

<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<script language='javascript'>
$(document).ready(function() {
    $('#pay').submit(function() {
        window.open('', 'payviewer', 'width=200,height=200,resizeable,scrollbars');
        this.target = 'payviewer';
    });
});
</script>

<form id="pay" action="popup.php" method="post" >
    <input type="hidden" name="var" value="POST DATA SENT">
    <input type="submit" value="결제하기">
</form>


이걸 더 수정해보자.

바로 위 코드와 아래 코드가 어떻게 다른지 확인이 될 것이다.

정보를 어떻게 전달하는지를 알 수 있다.


<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<script language='javascript'>
$(document).ready(function() {
    $('#pay').submit(function() {
        window.open('', 'payviewer', 'width=200,height=200,resizeable,scrollbars');
        this.action = 'popup.php';
        this.method = 'POST';
        this.target = 'payviewer';
    });
});
</script>

<form id="pay" >
    <input type="hidden" name="var" value="POST DATA SENT">
    <input type="submit" value="결제하기">
</form>




블로그 이미지

Link2Me

,
728x90

화면(page)을 주기적으로 자동 갱신해야 하는 경우가 있다.

아래 코드는 real time update 보다는 일정한 주기로 업데이트 처리하도록 했다.

갱신 주기를 짧게 하면 실시간 업데이트가 된다.

서버에서 데이터를 가져와야 하는 경우에 너무 빠른 갱신 주기는 부하를 야기할 수 있으므로 주의가 필요할 수도 있다.

구글링을 해서 실제 데이타가 맞는지 확인하면 맞지 않은 경우도 있다.

그래서 반드시 샘플 데이터를 만들고 직접 테스트를 해보고 동작 여부를 확인하고 코드를 적어둔다.


<!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" type="text/css" href="css/table.css" />
<script type="text/javascript" src="//code.jquery.com/jquery.min.js"></script>
<!-- 자동 갱신 스크립트 include -->
<script>
var timerID;

$(document).ready(function () {
    $('#execute').on('click',function(e){
        e.preventDefault();
        updateData();
    });
    $('#stop').on('click',function(e){
        e.preventDefault();
        clearTimeout(timerID); // 타이머 중지
        $('#showtime').html('');
    });   

});

function updateData(){
    $.ajax({
      url: "getserver.php",
      type:"post",
      cache : false,
      success: function(data){ // getserver.php 파일에서 echo 결과값이 data 임
       $('#showtime').html(data);
      }
    });
    timerID = setTimeout("updateData()", 2000); // 2초 단위로 갱신 처리
}
</script>

</head>

<body>
<p>time : <span id="
showtime"></span></p>
<input type="button" id="execute" value="실행" />
<input type="button" id="stop" value="중지" />
</body>
</html>


==== getserver.php ===
<?php
$time = date("H:m:s");
echo $time;
?>


ajax 는 비동기 Javascript 와 XML를 말한다.

ajax 를 사용하면 페이지 이동 없이 전체 HTML 이 아닌, XML 이나 JSON형식으로 구성된 새로운 데이터를 XMLHttpRequest 객체를 통해 받아온다.

블로그 이미지

Link2Me

,
728x90

MySQL DB와의 연동하여 통계 그래프를 작성하는 샘플이다.

100% PHP 코드함수까지 오픈하지 않는다. 하지만 핵심적으로 알아야 할 내용은 모두 작성했다.

var line1 = [<?php echo $data;?>];  PHP 문자열을 이렇게 대입해주면 자바스크립트에서 배열 변수로 인식하기 때문에 ajax response 메시지 값도 [jsonObj.data] 로 해주면 되는줄 알고 alert 창으로 확인하면서 시간낭비를 많이 했다. alert 창 메시지를 육안으로 확인하면 PHP 변수를 배열화한 것과 다를바가 없었다. typeof 를 찍어보고 나서 문제가 뭔지 찾아내고 바로 해결했다. 기초가 약해서 발생한 문제였다.


<?php
require_once 'connect.php'; // db접속 성공
require_once 'phpclass/statsClass.php'; // 통계 클래스
$b = new statsClass;
$R = $b->extract_YM(); // DB에서 년월 추출

$ym = date("Ym"); // 현재 년월

$ticks = $b->maxday_YM($ym);  // X축 좌표 값
$data = $b->dailyCnt_value($ym);  // 막대그래프 값
?>
<!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" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- http://www.jqplot.com 제공 자바스크립트 include -->
<script type="text/javascript" src="./plugin/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.barRenderer.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.pointLabels.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="./plugin/jqplot/jquery.jqplot.css" />
<script type="text/javascript">
$(document).ready(function(){
    var plot1;
    var line1 = [<?php echo $data;?>];
    //var line2 = [10, 8, 22, 15, 10];  // 막대그래프를 2개 그리고자 할 경우
    var xAxis = [<?php echo $ticks;?>];

    renderChart(line1,xAxis);

    $('#selectmonth').on('change',function(){
        if(this.value !== ""){
            var optVal=$(this).find(":selected").val();
            //var year = optVal.substr(0,4); // 년
            //var month = optVal.substr(4,2); // 월
            $.post('ajaxdb.php',{optVal:optVal},function(msg){
                //alert(msg); // 배열 형태로 넘어오는지 확인 목적
                var jsonObj = $.parseJSON(msg); // JSON 문자열을 JavaScript object 로 반환
                //alert(typeof jsonObj.data); // string
                data = jsonObj.data.split(','); // 문자열을 배열로 변환
                xAxis = jsonObj.ticks.split(',');
                //alert(typeof data);
                updatePlot(data,xAxis);
            });
        }
    });

});

function renderChart(data,xAxis){
    plot1 = $.jqplot('chartDiv', [data], CreateBarChartOptions(xAxis));
}

function updatePlot(data,xAxis){
    plot1.destroy();
    plot1 = $.jqplot('chartDiv', [data], CreateBarChartOptions(xAxis));
}

function CreateBarChartOptions(xAxis) {
    var optionsObj = {
        title: '일자별 접속 통계',
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer, // 막대 그래프
            rendererOptions: { barWidth: 15 }, // bar의 너비 수동으로 설정
            pointLabels: { show: true } // 레이블 값
        },
        axes: {
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: xAxis,
                tickOptions: {
                    formatString: '%d' // 정수형으로 표시
                }
                //label:'일자'
            }
        },
        highlighter: { show: false }
    };
    return optionsObj;
}

</script>

</head>
<body>
<div id="chartDiv" style="height:300px;width:900px;"></div>
<div style="height:300px;width:890px;margin-top:10px;text-align:right;">
<select name="month" id="selectmonth">
<option value="">년월 선택</option>
<?php
    while ($row = mysqli_fetch_array($R)){
        echo "<option value='".$row[0]."' ";
        echo ">".$row[0]."</option>\n";
    }
?>
</select>
</div>
</body>
</html>


==== ajaxdb.php ====

<?php
if(isset($_POST['optVal'])){
    require_once 'connect.php'; // db접속 성공
    require_once 'phpclass/statsClass.php'; // 통계 클래스
    $b = new statsClass;
    $ym = $_POST['optVal'];
    $data = $b->dailyCnt_value($ym); // 문자열로 받음
    $ticks = $b->maxday_YM($ym); // 문자열로 받음
    $R = array('data'=>$data, 'ticks'=>$ticks); // X축 좌표값과 일별 통계 값을 DB에서 추출하여 배열화 처리
    echo json_encode($R);
}
?>


alert(typeof jsonObj.data); 으로 type 을 확인해서 object 인지 string 인지 확인하여 상황에 맞게 변환해서 사용하는케 키포인트다.


json_encode 를 사용하면 배열로 결과를 반환하는 걸 자유자재로 할 수 있다.

어떻게 하는지는 바로 위의 코드를 보면 알 수 있으므로 이걸 본 방문객은 쉽게 해결이 가능하리라 본다.

구글 검색과 jqplot 검색을 하면 그래프 그려주는 js 파일 구조에 대해 파악이 될 것이다.

블로그 이미지

Link2Me

,
728x90

MySQL DB와의 연동하여 통계 그래프를 작성하는 방법이다.

바로 앞 게시물(http://link2me.tistory.com/1132)과 비교해서 달라진 부분이 어떤 것인지만 비교해보면 된다.

색깔을 표시한 부분을 주의깊게 살펴보면 답은 의외로 간단하다.


<?php
//require_once 'connect.php'; // db접속 성공
//require_once 'phpclass/boardClass.php'; // 게시판 클래스
$line1 ="4,6,2,5";  // DB와 연동한 결과로 문자열을 생성했다고 가정한다.
?>
<!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" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- http://www.jqplot.com 제공 자바스크립트 include -->
<script type="text/javascript" src="./plugin/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.barRenderer.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.pointLabels.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="./plugin/jqplot/jquery.jqplot.css" />
<script type="text/javascript">
$(document).ready(function(){
    var line1 = [<?php echo $line1;?>];
    var line2 = [10, 8, 22, 15, 10];
    var ticks = ['닛산', '포르쉐', 'KIA', '현대', '벤츠'];
 
    $('#chart1').jqplot([line1,line2], {
        title:'막대그래프 예제',
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer, // 막대 그래프
            rendererOptions: { barWidth: 25 }, // bar의 너비 수동으로 설정
            pointLabels: { show: true, formatString: '%d' } // 레이블 값
        },
        axes:{
            xaxis:{
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks // X축 값
            }
        }
    });
});
</script>

</head>
<body>
<div id="chart1" style="height:300px;width:600px; "></div>
</body>
</html>


다음 기회에 월을 선택하면 일별 막대그래프를 자동으로 그려주는 통계에 대한 PHP코드를 작성해볼 생각이다.

로직은 년월에 대한 값을 DB에서 자동으로 선택해서 selectbox에 표시하고 선택한 년월 정보로 통계그래프가 표시되도록 하면 된다.

- DB에서 년월에 대한 값을 중복없이 뽑아낸다.

- 년월을 선택하면 마지막 일자의 값을 자동으로 추출해서 문자열을 생성한다.

- jQuery change 로 해당 값이 변동되면 그래프를 그리도록 한다.

블로그 이미지

Link2Me

,
728x90

시각적으로 통계 결과를 화면에 보여주는 걸 구현할 때 jqplot 플러그인을 이용하면 쉽게 챠트를 그릴 수 있다.


위와 같은 막대 그래프로 통계 결과를 보여주고자 한다면 어떻게 해야 할까?


1. http://www.jqplot.com 사이트에서 플러그인 파일을 다운로드하여 서버에 설치한다.

   현재 기준 최신버전은 jquery.jqplot.1.0.9.d96a669.zip 이다.

   이 사이트를 알게 된 것은 2년전에 전문 개발자를 통해 알았는데 jQuery를 배우니 쉽게 활용이 가능하다.


2. 다운로드한 파일에 usage.txt 파일에 사용법이 나온다.

    그리고 웹사이트 Examples 에도 다양한 형태의 예제 파일이 있다.

    하지만 설명이 잘 이해되지 않을 수도 있다.


3. 간략하게 예제를 살펴보자.

    예제는 DB와의 연동까지는 고려하지 않은 1단계라고 보면 된다.

    필요한 플러그인 js 파일이 있는 경로명을 제대로 표시해주어야 그래프가 그려진다.

    - 변수 line1 과 line2 두개를 표시하고자 할 경우이며, 1개만 표시하고 싶으면 line1 만 적어준다.

    - 변수 ticks 는 X 좌표에 해당되는 값을 표시

    - title : 상단 제목


<!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" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- http://www.jqplot.com 제공 자바스크립트 include -->
<script type="text/javascript" src="./plugin/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.barRenderer.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.pointLabels.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="./plugin/jqplot/jquery.jqplot.css" />
<script type="text/javascript">
$(document).ready(function(){
    var line1 = [4, 6, 2, 5];
    var line2 = [10, 8, 22, 15, 10];
    var ticks = ['닛산', '포르쉐', 'KIA', '현대', '벤츠'];
 
    $('#chart1').jqplot([line1,line2], {
        title:'막대그래프 예제',
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer,
            rendererOptions: { barWidth: 25 },
            pointLabels: { show: true, formatString: '%d' }
        },
        axes:{
            xaxis:{
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            }
        }
    });
});
</script>

</head>
<body>
<div id="chart1" style="height:300px;width:600px; "></div>
</body>
</html>


보는 바와 같이 코드는 정말 심플하다.


변수 값을 PHP 와 연동하여 처리하는 것은 다음에 기술할 예정이다.

통계 그래프에 직접 변수를 지정해주는 경우는 거의 없을 것이고, DB와 연동하여 실시간처리가 되도록 해야 의미가 있을 것이다.


설명이 잘된 사이트가 있어서 링크를 걸어둔다.

http://wickedmagic.tistory.com/525


jqplot.com 사이트에서 영문으로 된 자료를 가지고 약간만 테스트를 하면서 본인이 원하는 스타일로 구현하면 된다. 그리고 좀 더 세부적인 내용을 알고자 한다면 구글에서 jqplot bar width example 와 같은 검색어를 입력하면 원하는 자료를 쉽게 찾을 수 있다.

http://www.jqplot.com/docs/files/plugins/jqplot-barRenderer-js.html 에도 옵션에 대한 설명이 나온다.

블로그 이미지

Link2Me

,
728x90

MP3 Player jQuery 화면 만들기 예제를 적어둔다.

실제 사용은 안하고 있으나, 화면 생성에 대한 사항을 사용할 일이 있을때 참고하려고 적어둔다.

좋은 MP3 플레이어 jQuery 는 http://www.wimpyplayer.com/ 다.


<div id="mp3playerdiv"></div>
<!--플레이어-->
<div class="player">
<div class="player_bg"><!--tmp--></div>
<div class="player_area" id="tubeplayer"></div>
</div>
<!--플레이어-->

<script type="text/javascript">
//<![CDATA[
   //플레이어
   $('.simbol a').click(function(e) {
   e.preventDefault();
   $(".player").fadeIn();
  
     $("#tubeplayer").append('<iframe width="400" height="80" src="<?php echo $g['dir_module_skin']?>movie/demo/movie.php?file='+this.id+'" frameborder="0" scrolling="no" allowfullscreen></iframe>');
  
      var temp = $('.player_area');
   
       if (temp.outerHeight() < $(document).height() ) temp.css('margin-top', '-'+temp.outerHeight()/2+'px');
       else temp.css('top', '0px');
       if (temp.outerWidth() < $(document).width() ) temp.css('margin-left', '-'+temp.outerWidth()/2+'px');
       else temp.css('left', '0px');

      $(".player .player_bg").on("click", function() {
      $(".player").fadeOut();
      $("#tubeplayer iframe").remove();
    });
           
      //키보드 esc
      $(document).bind('keydown', function(e) {
        if (e.which == 27) {
        $(".player").fadeOut();
        $("#tubeplayer iframe").remove();
        }
      });

    });
    //플레이어

//]]>
</script>

블로그 이미지

Link2Me

,
728x90

자바스크립트의 변수를 PHP 에서 읽을 수 있는 방법

"<script>document.write(p1);</script>"; 를 사용하면 된다.

자바스크립트는 별다른 표시가 없으면 윗줄에서 아래줄로 순차적으로 해석한다.


<script>
var p1 = "success";
</script>

<?php
echo "<script>document.write(p1);</script>";
?>

배열도 1차원으로 나열하더라.

   육안(화면)으로 보이는 것과 웹브라우저 소스보기로 보는 거랑은 결과가 다를 수 있음을 확인해야 한다.


PHP 변수 값을 자바스크립트/jQuery 로 전달하는 방법

전제조건 : 자바스크립트는 순차적으로 읽어들이므로 PHP 코드가 자바스크립트보다 위에 나와야 한다.

<script>
var str = '<?php echo $str;?>';
</script>


※ 자바스크립트에서 PHP 로 변수 넘기기 알아야 할 사항

    - 위에서부터 순차적으로 실행되는 구조하에서 javascript 변수를 PHP에서 읽어내는 것은 가능하다.
      하지만 자바스크립트 함수내에서 PHP 변수로 넘기는 것은 안된다.

    - 자바스크립트에서 결과값으로 얻은 변수를 PHP 다른 파일로 넘기는 것은 ajax를 사용하면 된다.

      하지만, ajax 결과를 다시 PHP 변수로 넘긴다?? 안된다는 걸 명심하자.

      ajax 결과를 가지고 클라이언트 HTML 파일을 업데이트할 수는 있다.

   

내가 제대로 이해 못할 수도 있으니 https://opentutorials.org/module/532/6508 게시글 참조하면 도움 될 수도....



PHP 배열 변수를 자바스크립트 배열로 전달하는 방법

JSON(JavaScript Object Notation)은 인터넷에서 자료를 주고 받을 때 그 자료를 표현하는 방법이다.

자료의 종류에 큰 제한은 없으며, 특히 컴퓨터 프로그램의 변수값을 표현하는 데 가장 적합하다.
왜냐하면 JSON은 문자열 뿐만 아니라 배열(Array), 오브젝트(Object) 등 컴퓨터의 모든 변수 형태를 문자열로 표현할 수 있기 때문이다.
JSON에서 표현할 수 있는 데이터 형식으로는 다음과 같은 것들이 있다.
- String (문자열): 큰 따옴표로 묶어 표현, ex) "link2me"
- Number (숫자): 숫자 표현, ex) 1234
- Array (배열): 대괄호로 묶어 표현, ex) [ 'a', 'b', 'c' ]
- Object (객체): 중괄호로 묶어 표현, ex) { key:'value',key2:'value2' }
- Boolean (참/거짓): TRUE 또는 FALSE, ex) true, false
- Null

json_encode 함수를 사용하면 1차원 배열이든 2차원 배열이든 간단하게 자바스크립트 배열로 만들어 준다.
json 은 UTF-8 로 인코딩되어야 인식된다는 걸 명심하자.

파일 Encoding 이 ANSI 로 되어 있으면 결과값이 출력되지 않는다.


<?php

$_POST = array('1','2','3');

echo json_encode($_POST, JSON_FORCE_OBJECT);

?>

<SCRIPT type="text/javascript">

var aa = <?php echo json_encode($_POST);?>;
alert(aa.subject);
// 연관배열에서 key로 값을 찾아준다. 한글도 잘 인식되더라.
</SCRIPT>


<script type='text/javascript'>
<?php
$php_array = array('aaa','bbb','ccc');
$js_array = json_encode($php_array);
echo "var javascript_array = ". $js_array . ";\n";
?>
</script>


다른 방법은 PHP 배열(1차원)을 문자열로 변환한 다음에 new Array()에 넣으면 1차원 배열은 해결된다.

단순한 값들의 나열이라면 배열 타입으로도 충분하다.

<?php

$_POST = array('1','2','3');

?>

<SCRIPT type="text/javascript">
var aa = new Array("<?=implode("\",\"" , $_POST);?>"); // 배열의 값만 문자열로 저장
</SCRIPT>



String to Array

string(문자열)을 구분자로 구분하여 배열로 저장하여 값을 출력
<?php

$flddata ="uid,ItemName,Price,Quantity";
$data = array();
$data = explode(",", $flddata); // 문자열을 배열로 저장

for($i=0; $i < count($data); $i++) {
      echo $data[$i].'<br />';
}
?>


Array to String

배열(array)을 구분자로 구분하여 문자열(string)로 저장

<?php
$arr = array('Hello','World!','Beautiful','Day!');
echo implode(" ",$arr); // 배열을 문자열로 저장
?>



Array 출력

checkbox 에서 선택한 값을 배열로 담아서 ajax 로 넘길 경우 코드와 PHP 파일을 값을 받아서 처리하는 과정이다.

배열을 분리하여 값을 추출하고자 할 경우에 foreach 문을 사용하면 된다.

$('.chkbox:checked').each(function()  // chkbox 라는 클래스명을 준 경우

$('input:checkbox[name="uid[]"]:checked').each(function()  // inputbox name 을 직접 준 경우


$('.btnbox1').click(function(){
    var chkdata = new Array();
    $("input:checked").each(function() {
        chkdata.push($(this).val());
    });
    if(chkdata.length != 0){
        alert(chkdata);
        $.post('ajax.php',{data:chkdata}, function(response) {
            //alert(response);
        });
    } else {
        alert('선택한 항목이 없습니다.');
    }
});


<?php
if(isset($_POST['data'])){
    foreach($_POST['data'] as $column => $value) {
        echo $value;

        // $value 를 가지고 MySQL DB Delete 수행하는 로직 처리

    }
}
?>



블로그 이미지

Link2Me

,
728x90

년도와 월을 선택하면 해당월의 마지막 날짜가 자동으로 변경되는 jQuery 를 작성했다.


PHP 와 jQuery 값을 전달하는 방법을 잘 몰라 고생 좀 했다.


jQuery Ajax 를 이용해서 파일 A 에서 전달한 값을 가지고 파일 B(get_LastDay.php)에서 결과를 계산하고 그 결과를 받아서 다시 파일 A에 PHP 변수로는 전달할 수가 없더라. (방법이 있는데 못찾은 것인지는 모름)


년도는 선택하지 않고 월만 선택하는 것도 고려하다보니, 자바스크립트 함수를 사용하지 않고 Ajax 로 전달해서 PHP 함수식을 이용하여 계산된 결과를 받도록 처리했다.


function getLastDay(year, month){
    if(month==4 || month==6 || month==9 || month==11)
        return 30;
    else if(month==2){ //2월
        if(year%4 == 0) // 2월, 윤년일 때
            return 29;
        else    // 2월, 윤년이 아닐 때
            return 28
    } else {
        return 31;
    }
}


Ajax 로 전달받은 결과는 HTML 을 갱신할 수는 있다.

이 방법을 이용해서 코드를 작성했다.


참고로, 년도와 월을 모두 선택한다면 Ajax 사용하지 않고 위 함수를 이용하여 처리해도 된다.

var year = $("#year option:selected").val();
var month = $("#month option:selected").val();
var lastDate = getLastDay(year, month);

$("#day > option").remove(); // remove all items from list
for(i=1; i<=lastDate; i++){
    $("#day").append("<option value='"+ i +"'>"+ i +"</option>");
}


=== 파일 A ===

<?php
date_default_timezone_set('Asia/Seoul');
$YEAR_LAST = date("Y");
$cur_year = $YEAR_LAST;
$cur_month = date("m");
// 현재 월의 마지막 날짜를 일단 선택하도록 처리하고, 년/월을 선택하면 자동으로 변경
$last_day = date("t", mktime(0, 0, 1, $cur_month, 1, $cur_year));
?>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){ // html 문서를 다 읽어들인 후
    var year;
    var month;
    $('#year').on('change', function(){
        if($("#year option:selected").val() !== ""){
            year = $(this).find(":selected").val();
            month = $("#month option:selected").val();
            if($("#month option:selected").val() !== ""){
                $.post('get_LastDay.php',{year:year,month:month}, function(data) {
                    //alert(data);
                    $("#day > option").remove(); // remove all items from list
                    for(i=1; i<=data; i++){
                        $("#day").append("<option value='"+ i +"'>"+ i +"</option>");
                    }
                });
            }
        }
    });


    $('#month').on('change', function(){
        if($("#month option:selected").val() !== ""){
            year = $("#year option:selected").val();
            month = $(this).find(":selected").val();
            $.post('get_LastDay.php',{year:year,month:month}, function(data) {
                $("#day > option").remove(); // remove all items from list
                for(i=1; i<=data; i++){
                    $("#day").append("<option value='"+ i +"'>"+ i +"</option>");
                }
            });
        }
    });

});
</script>
<body>
<label>년도: </label>
<select id="year">
    <option value=''>년도</option>
    <?php for($i=2010; $i <= $YEAR_LAST; $i++){
        echo("<option value='$i'>$i 년</option>");
        } ?>
</select>

<select id="month">
<option value=''> 월 </option>
<?php for($i=1; $i <= 12; $i++){
    echo("<option value='$i'>$i</option>");
    } ?>
</select>

<select id="day">
<option value=''> 일 </option>
<?php for($i=1; $i <= $last_day; $i++){
    echo("<option value='$i'>$i</option>");
    } ?>
</select>

</body>
</html>


=== 파일 B : get_LastDay.php ===

<?php
$select_year = $_POST['year'];
$select_month = $_POST['month'];

$month_day = Array(31,29,31,30,31,30,31,31,30,31,30,31);

if(isset($select_year) && !empty($select_year) && isset($select_month) && !empty($select_month) ){
    // "t"는 두 번째 인자로 넘어온 해당 연,월에 대한 총 일수를 구하기 위한 파라미터
    $last_day = date("t", mktime(0, 0, 1, $select_month, 1, $select_year));
} else if(isset($select_month) && !empty($select_month)) {
    // 월만 선택한 경우에는 2월의 최대값이 28일지, 29일지 알 수 없으므로 최대 29를 선택하도록 처리
    $last_day = $month_day[$select_month-1];
}
echo $last_day;
?>



블로그 이미지

Link2Me

,