728x90

PHP 에서 배열 데이터를 json_encode 로 생각없이 넘겨주면 jQuery JSON 에서 처리를 쉽게 해결될 줄 알고 구글링하면서 이것 저것 찾아서 해결하면 금방 잊어버리고 그랬다.

분명히 예전에 했던 것인데 다시 할려고 하니까 시간을 또 허비하고 있다.

뭔가 대충해서 문제가 있는 거 같아서 집중적으로 테스트를 해봤다.


먼저 PHP에서 넘겨주는 데이터 파일을 보자.

 <?php
require_once 'path.php';
require_once $g['path_center'].'config/config.php';
require_once $g['path_class'].'connect.php';
require_once $g['path_class'].'dbDataClass.php';
$c = new DBDataClass;
$sql ="select idx,userNM,telNO,mobileNO,codeID FROM member ";
$sql.="where userID='".$_REQUEST['userID']."'";
$result = mysqli_query($db,$sql);
$R = array();
if($row = mysqli_fetch_assoc($result)):
    array_push($R,$row);
endif;

//echo '<pre>';print_r($R);echo '</pre>';
echo json_encode($R);
//echo json_encode(array('rs' => $R));
?>


보다시피 배열로 만들어진 결과를 json_encode 한 다음에 echo 문으로 출력을 한 것이다.


이제 클라이언트 JSON 처리 파일을 살펴보자.

결과 그림부터 보고 아래 코드를 살펴보면 뭐가 다른지 보인다.

문자열은 중괄호({})로 둘러쌓여 있는데, PHP에서 넘겨온 데이터는 대괄호([])가 있고 중괄호({})가 있는 형태다.

이렇게 데이터 형태가 다른데 이걸 JSON.parse 만 하면 원하는 object 로 되는 줄 알고 처리를 시도했더니 결과가 나오지 않았던 것이다.

이걸 stringify 하여 문자열로 변환한 다음에 split 으로 대괄호 부분을 제거하고 다시 JSON.parse 를 하면 원하는 결과가 나온다.

var obj = JSON.stringify(msg); // 문자열로 변경된다.
var objsplit1 = obj.split(']');
var objsplit2 = objsplit1[0].split('[');
var rs = JSON.parse(objsplit2[1]);
console.log('idx = '+rs.idx);


이렇게 처리하거나 배열로 뽑아내서 원하는 결과를 얻어서 처리하는 방법이 최선이다.

var arr= new Array();
$.each(msg, function(key, obj){
    $.each(obj,function(k,value){
        arr.push(value)
    });
});


<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<h2>JSON Object, String</h2>
<p id="txt"></p>
<p id="obj_parse"></p>
<p id="obj"></p>
<p id="post_msg"></p>
<p id="ajax_msg"></p>
<p id="json2string"></p>
<p id="stringify"></p>
<script>
var txt = '{"name":"홍길동", "age":30, "city":"서울"}';
$('#txt').html('문자열 : '+txt);

var obj = JSON.parse(txt);
$("#obj_parse").html(obj.name + ", " + obj.age);

document.getElementById("obj").innerHTML = obj;
// $("#obj").html(obj); // 출력 결과물이 화면에 표시하지 못한다.

$.post('json.php',{userID:72771381},function(msg){
    console.log(msg); // 결과가 문자열로 넘어온다.
    //document.getElementById("post_msg").innerHTML = msg;
    $('#post_msg').html(msg);
});

$.ajax({
    url: "json.php",
    type: "POST",
    data: {userID:72771381},
    dataType: "JSON",
    success: function (msg) {
        console.log(msg);
        document.getElementById("ajax_msg").innerHTML = msg;
        var obj = JSON.stringify(msg); // 문자열로 변경된다.
        $('#json2string').html(obj);
        var objsplit1 = obj.split(']');
        var objsplit2 = objsplit1[0].split('[');
        console.log(objsplit2[1]);
        var rs = JSON.parse(objsplit2[1]);
        console.log('idx = '+rs.idx);

        var arr= new Array();
        $.each(msg, function(key, obj){
            $.each(obj,function(k,value){
                arr.push(value)
            });
        });
        console.log(arr);
    }
});


var myObject = new Object();
myObject.name = "왈패";
myObject.age = 12;
myObject.pets = ["cat", "dog"];
var myString = JSON.stringify(myObject);
$("#stringify").html(myString);

</script>
</body>
</html>
 


마지막 myObject 를 JSON.stringify 를 하면 맨 처음과 똑같은 형태의 중괄호({})로 둘러쌓인 문자열이 만들어진다는 걸 확인할 수 있다.


결론 PHP 에서 넘어온 JSON 형태는 jQuery 가 처리하려는 형태와 약간 다르므로 이걸 고려해서 파싱처리해야 한다는 것이다.

블로그 이미지

Link2Me

,
728x90

PHP에서 json_encode 로 데이터를 만들어서 jQuery 에서 ajax를 이용하여 원하는 데이터를 처리하는 방법이다.


$sql ="select userNM,telNO,mobileNO,codeID FROM member ";
$sql.="where userID='".$_REQUEST['userID']."'";
$result = mysqli_query($db,$sql);
$R = array();
if($row = mysqli_fetch_assoc($result)):
    array_push($R,$row);
endif;
echo json_encode($R);
 



jQuery ajax 로 결과를 받은 데이터는 JSON object 인데 그냥은 원하는 결과를 파싱할 수가 없다.

실력이 부족해서인지 개념부족인지 여기서 막힌다.

( 참조하면 왜 그런지 알 수 있다 : https://link2me.tistory.com/1595 )

그래서 Array로 변환하여 데이터를 처리했다.


 $('#getStaffData').on('click',function(){
    var userID = $('input[name=userID]').val();
    if(userID.length == 0){
        alert('입력값이 없습니다.');
        $('input[name=userID]').focus();
        return false;
    }

    $.ajax({
        url: "StaffFetchData.php",
        type: "POST",
        data: {userID:userID},
        dataType: "JSON",
        success: function (data) {
            //console.log(data);
            var arr= new Array();
            $.each(data, function(key, obj){
                $.each(obj,function(k,value){
                    arr.push(value)
                });
            });
            console.log(arr);
            $('input[name=userNM]').val(arr[0]);
            $('input[name=telNO]').val(arr[1]);
            $('input[name=mobileNO]').val(arr[2]);
            $('#codeID').val(arr[3]);
        }
    });

});


로컬에서 만든 임의의 데이터와 PHP를 통해 가져온 데이터의 차이점이 있다는 걸 알아야 한다.

Android 에서 JSON 데이터를 파싱처리하고자 한다면 파싱 처리하는 코드를 알아야 처리할 수 있다.

블로그 이미지

Link2Me

,
728x90

정해진 클래스가 아니면 동작이 안된다. bootstrap 3에서 잘 동작하던 걸 MDBootstrap 기반에서 동작되도록 하려면 Class 속성을 정확하게 알아야만 가능한 거 같다.


select 일반 속성을 적용하고자 할 때


<select name="where" class="browser-default custom-select" >
    <option value="unify">통합</option>
    <option value="userNM">성명</option>
    <option value="mNO">휴대폰</option>
</select>


자료 입력을 편하기 위해서 엔터키를 치면 자동으로 검사하는 코드를 추가했더니 먹통이 되는 증상이 보였다.

스마트폰에서는 엔터키를 입력하는 걸 추가하면 안되더라.

그래서 PC에서만 동작하는 코드를 검사하여 추가하는 걸로 코드를 변경했다.

구글링으로 검색해서 찾은 코드로 테스트했더니 잘 안되어서 PHP 코드에서 Device를 검사한 다음에 코드화를 통해서 해당 코드값을 인식하고 자바스크립트 코드는 코드의 하단에 추가하여 순차적으로 읽을 때 PHP 값을 읽을 수 있도록 했다.


<?php require_once 'deviceChk.php';?>

<script>

var device_type = "<?php echo $mtype;?>";

//alert(typeof device_type); // string 으로 인식하는 걸 확인할 수 있다.


if(parseInt(device_type) > 2){ // 정확한 검사를 위해 정수형으로 변환하여 부등 비교를 했음
    $('#BBSSearchKeyword').keypress(function(e){
        e.preventDefault();
        if(e.keyCode == 13 || e.which==13){ // 검색어 입력하고 엔터키를 누르면
            BBSSearch(uri,where,keyword);
        }
    });
}






블로그 이미지

Link2Me

,
728x90

jQuery UI 팝업창이 최상단 정중앙에 오지 않고 이상하게 보이는 증상 때문에 삽질을 엄청했다.


https://jqueryui.com/download/all/ 에서 가장 최신버전을 받아서 홈페이지에 필요한 파일을 옮긴다.

가장 최신버전이 2016.9월에 올라온 버전이다.


<div id="dialog" title="회원 현황"></div>


HTML 파일 하단에 팝업창을 띄울 dialog DIV를 적어준다.


헤더에 다음과 같이 경로에 맞게 두줄을 추가한다.

<link href="css/jquery-ui.css" rel="stylesheet">
<script type="text/javascript" src="js/jquery-ui.js"></script>


테이블에 id를 추가하고 tr 에 uid 값이 기록되도록 코드에 추가한다.

<table id="BBSListTable" class="table table-striped table-bordered table-hover">
<tbody>
<tr id="<?php echo $R['uid']; ?>">


제어를 위한 jQuery 코드를 아래와 같이 작성한다.

$('#BBSListTable tbody tr').click(function() {
    var idx = $(this).attr('id');
    BBSView(idx);
}).mouseover(function() {
    $(this).children().css({
        'backgroundColor' : '#DCDCDC',
        'cursor' : 'pointer'
    });
}).mouseout(function() {
    $(this).children().css({
        'backgroundColor' : '#FFFFFF',
        'cursor' : 'default'
    });
});

function BBSView(idx){
    $('#dialog').load('BBSView.php?idx=' + idx, function() {
        $(this).dialog({
            autoOpen : true,
            title : '회원정보',
            width: 450,
            height: 300,
            draggable: true,
            position: { my: "center", at: "center", of: window },
            buttons : {
                "수정" : function() {
                    gocStaffModifyView(idx);
                },
                "삭제" : function() {
                    gocStaffDelete(idx);
                },
                "닫기" : function() {
                    $(this).dialog("close");
                }
            }
        });
    });
}
 


position: { my: "center", at: "center", of: window } 이 한줄의 옵션을 몰라서 엄청 해멨다.

이 한줄로 고민은 싹 해결되었다.







블로그 이미지

Link2Me

,
728x90

jQuery Paging 처리를 완벽하게 한 것은 아니지만 PHP 와 연동하여 기본적인 처리를 하도록 만들어봤다.

함수는 재귀호출이 가능하다는 점을 활용했다.


https://www.w3schools.com/bootstrap4/bootstrap_pagination.asp 에 Bootstrap 4 Pagination 에 대한 기본 설명이 잘 나왔다. Pagination 은 HTML 코드의 <ul>태그와 <li>태그를 활용하여 모양이 예쁜 Pagination 이 만들어진다.

보통 jQuery 와 연동되는 Pagination 처리에서는 href="#" 으로 해서 해당 URL로 연결되지 않고 jQuery 코드상에서 처리한다.

PHP 코드와 잘 연계하여 Paging 이 처리되는 함수를 만든 다음에 jQuery 와 연동하면 코드를 크게 고려하지 않고도 잘 만들 수 있을 거 같다.


function BBSListTable(where,keyword,curPage){
    $('#panel_content').load('BBSList.php?where='+where+'&keyword='+keyword+'&p='+curPage, function() {
        var curPage = $('#paging .act a').text();
        $('#paging li').click(function(e) {
            e.preventDefault();
            switch($(this).text()){
                case '◁':
                    curPage=parseInt($(this).next().text()) - 1;
                    break;
                case '▷':
                    curPage=parseInt($(this).prev().text()) + 1;
                    break;
                default:
                    curPage = $(this).text();
                    break;
            }
            BBSListTable(where,keyword,curPage); // 재귀호출 가능
        });

        $('#BBSHome').click(function(e){
            e.preventDefault();
            BBSListTable('','','',1);
        });

        $('#BBSSearch').click(function(e){
            var where = $('[name=where]').val();
            var keyword = $('[name=keyword]').val();
            if(keyword =='' || keyword == 'undefined'){
                alert('검색어를 입력하세요');
                $('input[name=keyword]').focus();
                return false;
            }
            BBSListTable(where,keyword,1);
        });

        // 검색어 초기화
        $('#BBSKeywordReset').click(function(){
            $('input[name=keyword]').val('');
        });

    });
}
 





블로그 이미지

Link2Me

,
728x90

JSON.parse() : JSON 문자열을 JSON object로 변환시켜준다.

$.parseJSON(data); // JSON 문자열을 JSON 객체(JavaScript object) 로 변환시켜 준다

JSON.stringify : JSON object를 JSON 문자열로 변환시켜 준다.



다음 예제를 직접 실행해보면 내용을 이해할 수 있다.

 <!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
    <div>
        <div id="result"></div>
    </div>
</form>

<script>
$(function () {
    // json 객체 정의
    var employee = { "name": "홍길동", "address": "용인시 죽전동", "phone": "555-4567" };

    // JSON.stringify를 사용하여 String으로 변환한다.
    var jsonstring = JSON.stringify(employee);
    $("#result").append('<p>json string: ' + jsonstring + '</p>');

    // JSON.parse function을 사용하여 JSON string을 JSON 객체(object)로 변환
    var jsonobject = JSON.parse(jsonstring); // $.parseJSON(jsonstring) 사용해도 된다.
    var info = '<ul><li>Name:' + jsonobject.name + '</li><li>Street:' + jsonobject.address + '</li><li>Phone:' + jsonobject.phone + '</li></ul>';

    $("#result").append('<p>json object:</p>');
    $("#result").append(info);
});
</script>
</body>
</html>


블로그 이미지

Link2Me

,
728x90

DB에서 구한 URL 를 가지고 PHP 를 이용하여 JSON 파일로 만드는 코드 예제다.


<?php
if(isset($_POST['id']) && !empty($_POST['id'])){
    $id=$_POST['id'];
    require_once 'path.php';// root 폴더를 기준으로 상대경로 자동 구하기
    require_once $g['path_class'].'connect.php';
    $sql = "SELECT * FROM menu_items where id='{$id}'";
    $result = mysqli_query($db, $sql);
    if($row=mysqli_fetch_array($result)){
        //echo $row['url'];
        $url = $row['url'];
    }

    if($url !== '#'){
        $data = file_get_contents($url);
        $R = json_decode($data,TRUE); // JSON to Array
        echo json_encode($R); // JSON
    }
}
?>
 


블로그 이미지

Link2Me

,
728x90

jQuery 로 select 박스가 2개인 것의 값을 제어하는 걸 테스트하고 적어둔다.

 

여기서 알아둘 사항은 Javascript/jQuery 로 현재 URL, 경로 가져오는 방법이다.

//window.location is an object in javascript.
window.location.host             #returns host
window.location.hostname     #returns hostname
window.location.path             #return path
window.location.href             #returns full current url
window.location.port             #returns the port
window.location.protocol       #returns the protocol

// in jquery you can use
$(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



// To get the URL of the parent window from within an iframe
$(window.parent.location).attr('href');


http://www.abc.com:8082/index.php#tab2?foo=789

Property                                Result
----------------------------------------------------
$(location).attr('host')            www.abc.com:8082
$(location).attr('hostname')    www.abc.com
$(location).attr('port')            8082
$(location).attr('protocol')      http:
$(location).attr('pathname')   index.php
$(location).attr('href')           http://www.abc.com:8082/index.php#tab2
$(location).attr('hash')         #tab2
$(location).attr('search')       ?foo=789

 

 

기본적인 HTML 문법과 PHP를 혼용하여 사용하고 있다.

PHP는 대체문법을 사용하여 깔끔하게 보기좋게 정렬을 하고 있고, 함수화를 통해서 코드를 심플하게 보이도록 구현되어 있다.

 

<?php
include_once "connect.php";
include_once "dbDataClass.php";
$d = new DBDataClass();
$cat1 = isset($_GET['cat1'])? $_GET['cat1'] : 0;
$cat2 = isset($_GET['cat2'])? $_GET['cat2'] : 0;
?>
구분1 <select name="cat1" id="cat1">
    <option value="">+ 구분</option>
    <?php $_CAT1 = $d->getDbArray('menu_items''parent_id=0''*'''01);?>
    <?php while($_CA1 = mysqli_fetch_array($_CAT1)):?>
    <option value="<?php echo $_CA1['id']?>"<?php if($_CA1['id']==$cat1):?> selected<?php endif ?>><?php echo $_CA1['name']?></option>
    <?php endwhile ?>
    </select>
 
    &nbsp;&nbsp;&nbsp;구분2
    <select name="cat2" id="cat2">
    <option value="">+ 구분</option>
    <?php if($cat1):?>
    <?php $_CAT2 = $d->getDbArray('menu_items''parent_id='.$cat1, '*'''01); ?>
    <?php while($_CA2 = mysqli_fetch_array($_CAT2)):?>
    <option value="<?php echo $_CA2['id']?>"<?php if($_CA2['id']==$cat2):?> selected<?php endif ?>><?php echo $_CA2['name']?></option>
    <?php endwhile ?>
    <?php endif ?>
    </select>&nbsp;&nbsp;&nbsp;
    <!--구분 -->
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$('#cat1').on('change',function(){
    var cat1 = $("#cat1 option:selected").val(); // this.value
    location.href = $(location).attr('pathname'+ '?cat1='+cat1;
});
$('#cat2').on('change',function(){
    var cat1 = $("#cat1 option:selected").val();
    var cat2 = $("#cat2 option:selected").val();
    location.href = window.location.pathname + '?cat1='+cat1+'&cat2='+cat2;
});
</script>

 

 아래 코드 예시는 Secure Coding을 고려하여 작성한 코드 중에서 필요한 부분만 발췌하여 적은 것이다.

MDB(Material Design Bootsrap4) 코드를 적용한 select 가 포함되어 있다.

<?php
$link_url = "MemberList.php"// 현재 실행중인 파일명 가져오기
$rowsPage = 10// 한 화면에 표시되는 게시글 수
$curPage = isset($_GET['p']) ? $a->NoFilter($_GET['p']) : 1;
$m = isset($_GET['m']) ? $a->XSSFilter($_GET['m']) :'list';
$cat1 = isset($_GET['cat1']) ? $a->XSSFilter($_GET['cat1']) :'';
 
$g['url_link']=($m?'m='.$m.'&amp;':'').($cat1?'&amp;cat1='.$cat1.'&amp;':'').($where?'where='.$where.'&amp;':'').($keyword?'keyword='.urlencode(stripslashes($keyword)).'&amp;':'');
$g['bbs_reset'= $link_url.'?'.($m?'m='.$m.'&amp;':'');
 
?>
 
<div class="table-responsive text-nowrap">
<p class="h4 mb-4">회원 현황</p>
<div class="float-left info">
    <?php if$keyword ):?><strong>"<?php echo $keyword?>"</strong> 검색결과 : <?php endif?>
    <?php echo number_format($NUM)?>개 (<?php echo $curPage;?>/<?php echo $TPG;?>페이지)
</div>
 
<?php if($_SESSION['authID'== 2):?>
<div class="float-right info">
<select id="cat1" class="browser-default custom-select">
<?php $cats = $a->getDbArray('orgTree''parent_id=0''*'''01);?>
    <option value="">-본부-</option>
    <?php foreach($cats as $C): ?>
        <option value="<?php echo $C['id'];?>"<?php if($C['id']==$cat1):?> selected<?php endif;?>><?php echo $C['name'];?></option>
    <?php endforeach;?>
</select>
</div>
<?php endif;?>
 
<script>
$('#cat1').on('change',function(e){
    e.preventDefault();
    var cat1 = $("#cat1 option:selected").val(); // this.value
    var uri = $('#urlPath').attr('url-path');
    MemberListTable(where,keyword,curPage,uri,cat1);
});
</script>
 

 

 

블로그 이미지

Link2Me

,
728x90

JSON 데이터 포멧으로 Web URL 데이터를 받아서 PHP 배열로 변환하여 파싱하는 방법이다.


<?php
$url = "http://100.10.10.10/chart/data.json";
$data = file_get_contents_curl($url);

//echo $data.'<br />';

$R = json_decode($data,TRUE);// JSON 데이터를 배열로 변환

foreach($R['content'] as $val) {
    echo $val['sysdate'] . ' | ' . $val['mcount'] . "<br />";
}

function file_get_contents_curl($url) {
    $ch = curl_init();// curl 리소스를 초기화
    curl_setopt($ch, CURLOPT_URL, $url); // url을 설정
    // 헤더는 제외하고 content 만 받음
    curl_setopt($ch, CURLOPT_HEADER, 0);
    // 응답 값을 브라우저에 표시하지 말고 값을 리턴
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($ch);
    curl_close($ch);// 리소스 해제를 위해 세션 연결 닫음
    return $data;
}

?>
 


블로그 이미지

Link2Me

,
728x90

Bootstrap 그래프 샘플을 가지고 테스트한 걸 적어둔다.


var loadJSON = './test.json';
$.getJSON(loadJSON, function(data){
    $each(data, function(i, item){
        console.log(item.name);
    });
});


사이트에 나온 실제 그래프 그려주는 예제에 위 코드를 적용하여 만들면 아래와 같다.

<script>
var ctx = document.getElementById("myChart").getContext('2d');
var loadJSON = './graph.json'; // 서버에서 제공하는 데이터
$.getJSON(loadJSON, function(data){
    var names = new Array();
    var datas = new Array();
    $.each(data, function(i,item){
        names.push(item.name);
        datas.push(item.data);
    });
    console.log(names);
    console.log(datas);

    var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: names, // JSON 파일을 읽어서 배열로 저장하여 처리
      datasets: [{
        label: '가입자수',
        data: datas, // JSON 파일을 읽어서 배열로 저장하여 처리
        backgroundColor: [
          'rgba(255, 99, 132, 0.2)',
          'rgba(54, 162, 235, 0.2)',
          'rgba(255, 206, 86, 0.2)',
          'rgba(75, 192, 192, 0.2)',
          'rgba(153, 102, 255, 0.2)',
          'rgba(153, 102, 255, 0.2)',
          'rgba(255, 159, 64, 0.2)'
        ],
        borderColor: [
          'rgba(255,99,132,1)',
          'rgba(54, 162, 235, 1)',
          'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)',
          'rgba(153, 102, 255, 1)',
          'rgba(153, 102, 255, 1)',
          'rgba(255, 159, 64, 1)'
        ],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        yAxes: [{
          ticks: {
            beginAtZero: true
          }
        }]
      }
    }
    });
});
</script>
 


'Web 프로그램 > js, jQuery' 카테고리의 다른 글

jQuery Paging 처리 (진행중....)  (0) 2019.01.20
JSON.parse(), JSON.stringify()  (0) 2019.01.13
jQuery parent, children, find 차이  (0) 2018.12.14
jQuery on 이벤트  (0) 2018.12.10
[Javascript] 화면 크기  (0) 2018.12.07
블로그 이미지

Link2Me

,
728x90

jQuery 기능을 익히고자 파싱 테스트를 해봤다.

크롬브라우저에서 시도하면 https://brunch.co.kr/@adrenalinee31/1 에서 2. 외부요청을 가능하게 해주는 플러그인 설치를 하면 파싱이 잘 된다.

원하는 조건의 selector 를 찾느라고 좀 삽질을 했다.

$(html).find('.wiki-heading').find("a:contains('3.2.')").parent().next().find(".wiki-link-internal")



<!DOCTYPE html>

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>

<script>
var weburl ='https://namu.wiki/w/KBO%20%EB%A6%AC%EA%B7%B8/2018%EB%85%84/%EC%8B%A0%EC%9D%
B8%EB%93%9C%EB%9E%98%ED%94%84%ED%8A%B8'

$.get(weburl, function( html ) {
    var data = new Array();
    // 찾으려는 className 을 반복적으로 찾는다.
    var heading = $(html).find('.wiki-heading').find("a:contains('3.2.')").text();
    //console.log(heading);
    var nextclass = $(html).find('.wiki-heading').find("a:contains('3.2.')").parent().next().find(".wiki-link-internal");
    $(html).find('.wiki-heading').find("a:contains('3.2.')").parent().next().find(".wiki-link-internal").each( function(){
        var text = $(this).parent().text();
        if(text !== 'kt' && text !== '삼성' && text !== '롯데' && text !== '한화' && text !== 'SK' && text !== 'KIA' && text !== 'LG' && text !== 'NC' && text !== '넥센' && text !== '두산') {
            //console.log(text);
            data.push(text);
        }
    });

    for(var i=0;i<data.length;i++){
        console.log(data[i]);
    }
});
</script>

</body>
</html>



파싱 결과


크롬 브라우저 콘솔상에서 연습해보던 Javascript 코드

var data = document.querySelectorAll('.wiki-table-wrap .wiki-table .wiki-link-internal');
for(var i=0;i<data.length;i++){
    var t = data[i];
    t = t.innerText;
    console.log(t);
}


블로그 이미지

Link2Me

,
728x90

<div class="box">
   <div class="something1"></div>
   <div class="something2">
      <a class="mylink">My link</a>
   </div>
</div>


$(".mylink").click(function() { // 아래 4개는 모두 동일한 결과 반환
    $(this).parent().siblings(".something1");
    $(this).parent().prev(); // if you always want the parent's previous sibling
    $(this).parents(".box").children(".something1");

    $(this).closest('.box').children('.something1');

});


- closest()는 모든 부모 요소를 대상으로하여 원하는 요소만 선택자로 가져올 수 있다.
- 하나가 아닌 모든 부모 요소를 반환할 필요가 있다면 parents() 메소드를 사용한다.
- parent()는 해당 요소의 바로 위의 부모 요소를 반환한다.

- children()은 해당 요소의 바로 아래 자식 요소들만을 반환한다.

- find()는 해당 노드 아래의 전체 DOM을 탐색하여 반환한다.

- prev() - 이전 요소를 선택하도록 반환한다.
- next() - 다음 요소를 선택하도록 반환한다.




'Web 프로그램 > js, jQuery' 카테고리의 다른 글

JSON.parse(), JSON.stringify()  (0) 2019.01.13
JSON 데이터 읽어서 그래프 그리기  (0) 2018.12.18
jQuery on 이벤트  (0) 2018.12.10
[Javascript] 화면 크기  (0) 2018.12.07
Javascript 객체 배열  (0) 2018.11.17
블로그 이미지

Link2Me

,
728x90

jQuery on 함수는 1.7버전부터 추가 되었다.
.on( events [, selector ] [, data ], handler(eventObject) )
 - event : 등록하고자 하는 이벤트 타입을 지정한다. (예: "click") s가 붙었으니 여러개도 사용가능하다.
 - selector : 이벤트가 설치된 엘리먼트의 하위 엘리먼트를 이벤트 대상으로 필터링한다.
 - data : 이벤트가 실행될 때 핸들러로 전달될 데이터를 설정한다.
 - handler : 이벤트 핸들러 함수

$(elem).on("click focus keydown", function(e) { ... });

on 함수의 종료는 off 함수가 있다.

'Web 프로그램 > js, jQuery' 카테고리의 다른 글

JSON 데이터 읽어서 그래프 그리기  (0) 2018.12.18
jQuery parent, children, find 차이  (0) 2018.12.14
[Javascript] 화면 크기  (0) 2018.12.07
Javascript 객체 배열  (0) 2018.11.17
[jQuery] HTML 속성의 제어  (0) 2018.11.15
블로그 이미지

Link2Me

,
728x90

윈도우/맥북에서 동시에 사용할 수 있는 Editor를 찾다보니 Brackets 이 괜찮은 거 같아서 이용을 해보고 있다.


새로운 파일을 생성하고 Shift + Tab 키를 누르니까 HTML5 기본 포멧이 바로 생성된다.

들여쓰기는 보통은 Shift + Tab 키인데, brackets 에서는 Ctrl + [ 키를 누르면 된다.

내어쓰기는 보통은 Tab 인데, brackets 에서는 Ctrl + ] 키를 누르면 된다.

블로그 이미지

Link2Me

,
728x90

viewport : 뷰포트는 문서의 내용 중 사용자에게 보여주는 영역을 의미
window.inner*은 뷰포트의 크기를 나타내고, screen.*은 스크린의 크기를 나타낸다.

// 가로 길이(너비)
window.innerWidth // 브라우저 창(window) 두께를 제외한 실질적 가로 길이
window.outerWidth // 브라우저 창(window) 두께를 포함한 브라우저 전체 가로 길이


//세로길이(높이)
window.innerHeight // 브라우저 창(window) 두께를 제외한 실질적 세로 길이
window.outerHeight // 브라우저 창(window) 두께를 포함한 브라우저 전체 세로 길이

$(window).width();   // returns width of browser viewport
$(window).height();   // returns height of browser viewport

document.body.scrollWidth // (문서 전체의 너비)
document.body.scrollHeight //(문서 전체의 높이)

$(document).height(); // returns height of HTML document (same as pageHeight in screenshot)
$(document).width(); // returns width of HTML document (same as pageWidth in screenshot)

window.screen.width, window.screen.height
모니터 스크린의 너비와 높이

window.scrollTo(x,y);

<script>
    document.getElementById('scrollBtn').addEventListener('click', function(){
        window.scrollTo(0, 1000);
    })
</script>

블로그 이미지

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

객체 배열의 특징
내장객체 Array 객체를의미한다.
배열이름[인덱스] : 인덱스는0부터시작한다.
배열이름= new Array(개수); // 생성하는 방법
Arr_Name = new Array(10);

- join(): 배열을 하나의 문자열로 만들어 준다.
- sort(): 배열의 값들을 순서대로 정렬한다.
- reverse(): 배열안에 값들을 순서대로 재정렬시킨다.
- concat(): 두개 배열을 하나의 배열로 만든다.
- slice(): 배열의 일부분의 값을 추출한다.

<SCRIPT LANGUAGE="JAVASCRIPT">
array1 = new Array("사과", "배", "바나나")
document.write("<h4>" + array1.join() + "<br>")
document.write(array1.join("와") + "<br>")
document.write(array1.join("&") + "</h4>")
</SCRIPT>

<SCRIPT LANGUAGE="JAVASCRIPT">
array1 = new Array("오징어", "낙지", "문어","꼴뜨기");
array2 = array1.slice(1,3);
document.write(array2);
</SCRIPT>

블로그 이미지

Link2Me

,
728x90

자바스크립트에서 속성 읽기, 설정, 제거하는 방법이다.

<a id="target" href="http://abc.com">tutorials</a>

<script>

var t = document.getElementById('target');

t.getAttribute('href'); // href 속성의 값을 가져온다.

t.setAttribute('title', 'abcdef'); // title 속성의 값을 설정한다.

t.removeAttribute('title'); // title 속성을 제거한다.

</script>


jQuery는 HTML 요소에 대해 객체를 통하여 속성 값을 제어할 수 있는 attr()함수를 제공한다.


var 변수 = $("요소").attr("속성이름"); // 속성 값 읽기

var 변수 = $("요소").attr("속성이름","값"); // 속성 값 변경/추가


예제1

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


var loginpath =$("#ajaxPath").attr('data-path');
$.ajax({
    url: loginpath+'updateUser.php',
    type: 'POST',
    data: {
        idx:$("#memberidx").val(),
        userNM:$("#memberName").val(),
        mobileNO:$("#memberMobile").val()
    },
    dataType: "json",
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
    success: function (response) {
        if(response.result == 1){
            alert('수정 완료');
            location.replace('index.php'); // 화면 갱신
        } else if(response.result == 0){
            alert('수정 실패');
        }
    },
    error: function(jqXHR, textStatus, errorThrown){
        alert("ajax error : " + textStatus + "\n" + errorThrown);
    }
});


예제2

<span class="button" id="errorChk" data-uid="<?=$R['uid']?>">오류</span>


$("#errorChk").click(function(){
    uid=$(this).attr("data-uid");
    ErrorDisplay(uid);
});

function ErrorDisplay(_uid){
    $.get("ErrorChk.php", {uid:_uid}, function(data){
        $("#dialog").dialog("open").html(data);
    });
}

function ErrorChk(_uid,_mod){
    $.get("ErrorChk.php", {uid:_uid, mod:_mod}, function(data){
        $("#dialog").dialog("open").html(data);
    });
}


prop() 함수 : 선택한 요소에 속성을 반환/생성/변환한다.

주의할 점은 HTML 입장에서의 속성(attribute)이 아닌 Javascript 입장에서의 속성(property)이다.

jQuery 1.6 부터 prop()함수가 추가되어 attr()함수의 역할을 나누게 되었다.


다음 예제를 통해 결과가 어떻게 다른지 확인해보자.

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    var prop_id = $(":text").prop("id");
    var attr_id = $(":text").attr("id");

    alert("prop id값  : " + prop_id + " , attr id값 : " +  attr_id);


    var prop_class = $(":text").prop("class");
    var attr_class = $(":text").attr("class");

    alert("prop class값 : " + prop_class + " , attr class값 : " +  attr_class);


    var prop_readonly = $(":text").prop("readonly");
    var attr_readonly = $(":text").attr("readonly");

    alert("prop readonly값 : " + prop_readonly + " , attr readonly값 : " +  attr_readonly);


    var prop_disabled = $(":text").prop("disabled");
    var attr_disabled = $(":text").attr("disabled");
    alert("prop disabled값 : " + prop_disabled + " , attr disabled값 : " +  attr_disabled);
})
</script>
</head>
<body>
<input type="text" id="text_field" class="text_class" readonly="readonly" disabled="disabled" />
</body>
</html>


prop id값  : text_field , attr id값 : text_field

prop class값 : text_class , attr class값 : text_class


prop readonly값 : true , attr readonly값 : readonly

prop disabled값 : true , attr disabled값 : disabled


<input id="chk" type="checkbox" checked="checked" />
먼저 attr 함수로 checked 속성 값을 가져오면 그 결과 값은 checked(HTML이 가지고 있는 속성의 text 값)로 나온다.
하지만, prop 함수로 checked 속성 값을 가져오면 그 결과 값은 true(속성이 실제 의미하는 값)가 된다.

먼저 attr 함수로 checked 속성 값을 가져오면 그 결과 값은 checked(HTML이 가지고 있는 속성의 text 값)로 나온다.

하지만, prop 함수로 checked 속성 값을 가져오면 그 결과 값은 true(속성이 실제 의미하는 값)가 된다.



출처: http://ggmouse.tistory.com/92 [초보개발자꽁쥐]

true / false체크 같은 것을 사용할 때 아주 유용하다.
prop가 나온후로는
$("요소").prop("checked",true);
$("요소").prop("checked",false);
로 변경을 해주어야 체크박스 핸들링이 가능하다.

블로그 이미지

Link2Me

,
728x90

음력 달력 예제를 가지고 수정해서 만들어본 코드다.


달력의 모양은 위와 같다.

ㅇ bootstrap 코드로 수정 보완

    - 해상도에 따라 일부 좀 수정해야 할 부분이 있음.

ㅇ jQuery 일정 등록 기능 추가

   - 해당 셀에서 마우스 클릭하면 일정 등록 추가 화면 팝업

   - 등록된 일정에 마우스를 클릭하면 삭제 여부 문의 및 삭제 처리

   - 코드를 좀 더 보완해야 할 듯....

ㅇ 음력 및 간지 지원 (음력 지원 DB 활용)

ㅇ 대체공휴일 코드 추가

    - 어린이날, 설날, 추석 대체공유일 코드

ㅇ 기념일 등록

    - 기념일을 등록하는 코드 파일은 미 구현(DB에 직접 기록하는 방법으로 테스트)

    - 태어난 연도 이전에는 표시되지 않도록 하는 코드는 미구현


음력은 함수 lun2sol.php 파일은 만세력 달력을 찾아보니 데이터가 불일치한다.

그래서 MySQL DB 데이터 기준으로 동작되도록 코드를 수정했다.

검색해보니 고영창 만세력 코드가 있는데 이것으로 테스트는 해봤지만 이 코드에 맞춰서 테스트는 아직 안해봤다.

MySQL DB파일 사이즈가 좀 되다보니 용량이 조금 크다고 볼 수도 있다.


테이블 구조

 CREATE TABLE IF NOT EXISTS `memorials` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category` int(4) NOT NULL,
  `subject` text NOT NULL,
  `start_year` char(4) DEFAULT NULL,
  `memorial_date` varchar(4) NOT NULL,
  `dateType` tinyint(2) NOT NULL DEFAULT '0',
  `writing_date` date NOT NULL DEFAULT '0000-00-00',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

--
-- 테이블의 덤프 데이터 `memorials`
--

INSERT INTO `memorials` (`id`, `category`, `subject`, `start_year`, `memorial_date`, `dateType`, `writing_date`) VALUES
(1, 1, '홍길동 생일', '1978', '0827', 1, '2018-10-30'),
(2, 1, '이정민 생일', '1979', '1215', 1, '2018-10-30'),
(3, 1, '홍진경 생일', '1992', '0614', 0, '2018-10-30');

-- --------------------------------------------------------

--
-- 테이블 구조 `memorial_data`
--

CREATE TABLE IF NOT EXISTS `memorial_data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `relatedid` int(11) NOT NULL,
  `solar_date` date NOT NULL DEFAULT '0000-00-00',
  `lunar_date` date NOT NULL DEFAULT '0000-00-00',
  `yun` tinyint(1) NOT NULL DEFAULT '0',
  `subject` text NOT NULL,
  `category` int(4) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `relatedid` (`relatedid`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- 테이블 구조 `tbl_events`
--

CREATE TABLE IF NOT EXISTS `tbl_events` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `start` date NOT NULL,
  `end` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;



<?php
define("PHP_SELF", $_SERVER['PHP_SELF']);
error_reporting(error_reporting() & ~E_NOTICE);
if (!isset($cellh))
    $cellh = 70; // date cell height
if (!isset($tablew))
    $tablew = 650; //table width
$cellw = 130;
//---- 오늘 날짜
$thisyear = date('Y'); // 4자리 연도
$thismonth = date('n'); // 0을 포함하지 않는 월
$today = date('j'); // 0을 포함하지 않는 일

// $year, $month 값이 없으면 현재 날짜
$year = isset($_GET['year']) ? $_GET['year'] : $thisyear;
$month = isset($_GET['month']) ? $_GET['month'] : $thismonth;
$day = isset($_GET['day']) ? $_GET['day'] : $today;

//------ 날짜의 범위 체크
if (($year > 2038) or ($year < 1900))
    ErrorMsg("연도는 1900 ~ 2038년만 가능합니다.");

$last_day = date('t', mktime(0, 0, 0, $month, 1, $year)); // 해당월의 총일수 구하기

$prevmonth = $month - 1;
$nextmonth = $month + 1;
$prevyear = $nextyear = $year;
if ($month == 1) {
    $prevmonth = 12;
    $prevyear = $year - 1;
} elseif ($month == 12) {
    $nextmonth = 1;
    $nextyear = $year + 1;
}
$pre_year = $year - 1;
$next_year = $year + 1;


include_once 'dbconnect.php'; // DB 연결
include_once 'lun2sol.php';  //양력.음력 변환 인클루드

/****************** lunar_date ************************/
$predate = date("Y-m-d", mktime(0, 0, 0, $month - 1, 1, $year));
$nextdate = date("Y-m-d", mktime(0, 0, 0, $month + 1, 1, $year));

$sql = "SELECT solar_date,ganji,lunar_date,yun FROM lunar_data where solar_date between '$predate' and '$nextdate' ";
$result = mysqli_query($dbconn, $sql) or die(mysqli_error($dbconn));
while ($R = mysqli_fetch_array($result)) {
    $lunarData[] = array(0 => date("n-j", strtotime($R['solar_date'])), 1 => $R['ganji'], 2 => date("n.j", strtotime($R['lunar_date'])), 3 => date("j", strtotime($R['lunar_date'])), 4 => $R['yun']);
}
//echo '<pre>';print_r($lunarData);echo '</pre>';
/****************** lunar_date ************************/

/****************** 기념일 데이터 ************************/
// 음력 기념일을 생성하면 시작년도부터 해당 양력일자를 자동으로 생성 처리??
$sql = "SELECT category,subject,memorial_date,dateType FROM memorials";
$result = mysqli_query($dbconn, $sql);
while ($R = mysqli_fetch_array($result)) {
    if($R['dateType'] == 1){ // 음력
        //$tmp = lun2sol($year . $R['memorial_date']); // 정확도가 맞는지 확인 필요
        $lunar_temp = $year ."-".substr($R['memorial_date'],0,2)."-".substr($R['memorial_date'],2,2);
        $rsql = "SELECT solar_date,num,yun,lunar_date FROM lunar_data where lunar_date='".$lunar_temp."'";
        $rs = mysqli_query($dbconn, $rsql);
        $RS = mysqli_fetch_array($rs);
        $tmp = strtotime($RS[0]);
        if(substr($RS[0],0,4) !== $year){ // 음력 기념일이 같은 해가 아니면
            $sql = "SELECT count(relatedid) FROM memorial_data where relatedid=".$RS[1]." and solar_date='".$RS[0]."' and yun=".$RS[2]." and subject='".$R['subject']."' ";
            $rt = mysqli_query($dbconn, $sql);
            $RT = mysqli_fetch_array($rt);
            if($RT[0] == 0){ // 일치하는 데이터가 없으면
                $sql ="INSERT INTO memorial_data (relatedid,solar_date,lunar_date,yun,subject,category) ";
                $sql.="VALUES (".$RS[1].",'".$RS[0]."','".$RS[3]."','".$RS[2]."','".$R['subject']."','".$R['category']."')";
                mysqli_query($dbconn, $sql);
            }
        }
    } else { // 양력
        $tmp = strtotime($year ."-".substr($R['memorial_date'],0,2)."-".substr($R['memorial_date'],2,2));
    }
    $memorialData[] = array(0 => date("n-j",$tmp), 1 => $R['category'], 2 => $R['subject']);
}

// 음력 기념일이 같은 해에 없는 경우 테이블에 생성된 데이터를 조회 및 추가
$sql = "SELECT solar_date,subject,category FROM memorial_data where solar_date between '$predate' and '$nextdate' ";
$result = mysqli_query($dbconn, $sql);
while ($R = mysqli_fetch_array($result)) {
    $tmp = strtotime($R[0]);
    $memorialData[] = array(0 => date("n-j",$tmp), 1 => $R['category'], 2 => $R['subject']);
}

/****************** 휴일 정의 ************************/
$Holidays = Array();
$Holidays[] = array(0 => '1-1', 1 => '신정');
$Holidays[] = array(0 => '3-1', 1 => '삼일절');
$Holidays[] = array(0 => '5-5', 1 => '어린이날');
$Holidays[] = array(0 => '6-6', 1 => '현충일');
$Holidays[] = array(0 => '7-17', 1 => '제헌절');
$Holidays[] = array(0 => '8-15', 1 => '광복절');
$Holidays[] = array(0 => '10-3', 1 => '개천절');
$Holidays[] = array(0 => '10-9', 1 => '한글날');
$Holidays[] = array(0 => '12-25', 1 => '성탄절');

//$tmp = lun2sol($year . "0101");  //설날
$tmp = strtotime(Lun2SolDate($year."-01-01"));
$Holidays[] = array(0 => date("n-j", ($tmp - (3600 * 24))), 1 => '');
$Holidays[] = array(0 => date("n-j", $tmp), 1 => '설날');
$Holidays[] = array(0 => date("n-j", ($tmp + (3600 * 24))), 1 => '');

//$tmp = lun2sol($year . "0408");  //석가탄신일
$tmp = strtotime(Lun2SolDate($year."-04-08"));
$Holidays[] = array(0 => date("n-j", $tmp), 1 => '석탄일');

//$tmp = lun2sol($year . "0815"); //추석
$tmp = strtotime(Lun2SolDate($year."-08-15"));
$Holidays[] = array(0 => date("n-j", ($tmp - (3600 * 24))), 1 => '');
$Holidays[] = array(0 => date("n-j", $tmp), 1 => '추석');
$Holidays[] = array(0 => date("n-j", ($tmp + (3600 * 24))), 1 => '');

// 어린이날 대체공휴일 검사 : 어린이날은 토요일, 일요일인 경우 그 다음 평일을 대체공유일로 지정
$childdayChk = isWeekend($year."-05-05");
if($childdayChk == 0) $Holidays[] = array(0 => date("n-j", strtotime($year."-05-06")), 1 => '대체공휴일');
if($childdayChk == 6) $Holidays[] = array(0 => date("n-j", strtotime($year."-05-07")), 1 => '대체공휴일');

// 설날 대체공휴일 검사
if(isWeekend(Lun2SolDate($year."-01-01")) == 0)
    $Holidays[] = array(0 => date("n-j", strtotime(Lun2SolDate($year."-01-03"))), 1 => '');
if(isWeekend(Lun2SolDate($year."-01-01")) == 1)
    $Holidays[] = array(0 => date("n-j", strtotime(Lun2SolDate($year."-01-03"))), 1 => '');
if(isWeekend(Lun2SolDate($year."-01-02")) == 0)
    $Holidays[] = array(0 => date("n-j", strtotime(Lun2SolDate($year."-01-03"))), 1 => '');


// 추석 대체공휴일 검사
if(isWeekend(Lun2SolDate($year."-08-14")) == 0)
    $Holidays[] = array(0 => date("n-j", strtotime(Lun2SolDate($year."-08-17"))), 1 => '');
if(isWeekend(Lun2SolDate($year."-08-15")) == 0)
    $Holidays[] = array(0 => date("n-j", strtotime(Lun2SolDate($year."-08-17"))), 1 => '');
if(isWeekend(Lun2SolDate($year."-08-16")) ==0)
    $Holidays[] = array(0 => date("n-j", strtotime(Lun2SolDate($year."-08-17"))), 1 => '');

/****************** 휴일 정의 ************************/

/****************** schedule ************************/
$sql = "SELECT * FROM tbl_events where start between '$predate' and '$nextdate' ";
$result = mysqli_query($dbconn, $sql);
while ($R = mysqli_fetch_array($result)) {
    $schedule[] = array(0 => date("n-j", strtotime($R['start'])), 1 =>date("n-j", strtotime($R['end'])) ,2 => $R['title'],3 => $R['id']);
}
//echo '<pre>';print_r($schedule);echo '</pre>';
/****************** schedule ************************/

?>

<!DOCTYPE html>
<html lang="ko">
<head>
<title>PHP Calendar</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<style>
    body{margin-top: 20px; }
    .all {border-width: 1;border-color: #cccccc;border-style: solid;}
    font {font-family: 굴림체;font-size: 12px;color: #505050;    }
    font.title {font-family: 굴림체;font-size: 12px;font-weight: bold;color: #2579CF;    }
    font.week {font-family: 돋움,돋움체;color: #ffffff;font-size: 8pt;    letter-spacing: -1;}
    font.holy {font-family: tahoma;font-size: 22px;color: #FF6C21;}
    font.blue {font-family: tahoma;font-size: 22px;color: #0000FF;}
    font.black {font-family: tahoma;font-size: 22px;color: #000000;}
    font.lunar {font-family: tahoma;font-size: 14px;color: #0000bb;}
    font.gangi {font-family: tahoma;font-size: 14px;color: #424242;}
    font.sblue {font-family: tahoma;font-size: 14px;color: blue;    }
    font.green {font-family: tahoma;font-size: 14px;color: green;    }
    font.red {font-family: tahoma;font-size: 14px;color: red;}
    font.num {font-family: tahoma;font-size: 14px;background-color: #DBA901;}
    font.gray {font-family: tahoma;font-size: 14px;color: #bbbbbb;}
    .main {float: left;width: 70%;border: 5px solid #ccc;background-color: #fff;m }
    .right {float: right;width: 20%;background-color: #fff;border: 5px solid #eee;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script>
$(document).ready(function() {
    $(".calcell").click(function(){
        var val=$(this).attr("id");
        var date = val.split('-');
        var year = date[0];
        var month = date[1];
        var day = date[2];
        var title = prompt('Event Title:');
        $.ajax({
            url : 'add-event.php',
            type : 'POST',
            data :{year:date[0],month:date[1],day:date[2],title:title},
            success : function(data){
                if(data == 1){
                    location.reload();
                } else if(data == 0) {
                    alert('등록에 실패했습니다.');
                }
            },
            error: function(jqXHR, textStatus, errorThrown){
                alert("arjax error : " + textStatus + "\n" + errorThrown);
            }
        });
    });

    $(".num").click(function(e){
        var val=$(this).attr("uid");
        var deleteMsg = confirm("정말 삭제하시겠습니까?");
        if(deleteMsg){
            $.ajax({
                url : 'delete-event.php',
                type : 'POST',
                data :{id:val},
                success: function (data) {
                    if(data == 1){
                        location.reload();
                    } else if(data == 0) {
                        alert('삭제에 실패했습니다.');
                    }
                }
            });
        }
    });
});
</script>
</head>
<body>
<div class="container">
<table class="table table-bordered table-responsive">
  <tr align="center" >
    <td>
        <a href=<?php echo 'calendar.php?year='.$pre_year.'&month='.$month . '&day=1'; ?>>◀◀</a>
    </td>
    <td>
        <a href=<?php echo 'calendar.php?year='.$prevyear.'&month='.$prevmonth . '&day=1'; ?>>◀</a>
    </td>
    <td height="50" bgcolor="#FFFFFF" colspan="3">
        <a href=<?php echo 'calendar.php?year=' . $thisyear . '&month=' . $thismonth . '&day=1'; ?>>
        <?php echo "&nbsp;&nbsp;" . $year . '년 ' . $month . '월 ' . "&nbsp;&nbsp;"; ?></a>
    </td>
    <td>
        <a href=<?php echo 'calendar.php?year='.$nextyear.'&month='.$nextmonth.'&day=1'; ?>>▶</a>
    </td>
    <td>
        <a href=<?php echo 'calendar.php?year='.$next_year.'&month='.$month.'&day=1'; ?>>▶▶</a>
    </td>
  </tr>
  <tr class="info">
    <th style="width:14%;text-align:center;">일</td>
    <th style="width:14%;text-align:center;">월</th>
    <th style="width:14%;text-align:center;">화</th>
    <th style="width:14%;text-align:center;">수</th>
    <th style="width:14%;text-align:center;">목</th>
    <th style="width:14%;text-align:center;">금</th>
    <th style="width:14%;text-align:center;">토</th>
  </tr>
  <tr height=<?php echo $cellh;?>>

<?php
    $date = 1;
    $offset = 0;
    $ck_row = 0;
    //프레임 사이즈 조절을 위한 체크인자
    $R = array();

    while ($date <= $last_day) {
        $mday = $date;

        if ($date == '1') {
            // 시작 요일 구하기 : date("w", strtotime($year."-".$month."-01"));
            $offset = date('w', mktime(0, 0, 0, $month, $date, $year)); // 0: 일요일, 6: 토요일
            SkipOffset($offset, mktime(0, 0, 0, $month, $date, $year));
        }
        if ($offset == 0)
            $style = "holy"; // 일요일 빨간색으로 표기
        else if($offset == 6)
            $style = "holy"; // 토요일 빨간색 또는 파란색
        else
            $style = "black";

        // 법정 공휴일
        for ($i = 0; $i < count($Holidays); $i++) {
            if ($Holidays[$i][0] == "$month-$date") {
                $style = "holy";
                $mday = "$date";
                $holidata = $Holidays[$i][1];
                break;
            }
        }

        // 음력 일자 및 간지 데이터
        for ($i = 0; $i < count($lunarData); $i++) {
            if ($lunarData[$i][0] == "$month-$date") {
                if($lunarData[$i][4] == 1){ // 윤달이면
                    $lunarday = '(閏)'.$lunarData[$i][2];
                } else {
                    $lunarday = $lunarData[$i][2];
                }
                $gaingi_text = $lunarData[$i][1];
            }
        }

        // 기념일 : 결혼, 생일, 제사, 기타 등
        for ($i = 0; $i < count($memorialData); $i++) {
            if ($memorialData[$i][0] == "$month-$date") {
                $memorialdata = $memorialData[$i][2];
                break;
            }
        }

        // 사용자 일정 데이터
        $dType1 = array();
        for ($i = 0; $i < count($schedule); $i++) {
            if ($schedule[$i][0] == "$month-$date") {
                $dType1[] = array(0=>$schedule[$i][2],1=>$schedule[$i][3]);
            }
        }
      
        if ($date == $today && $year == $thisyear && $month == $thismonth) { // 오늘 날짜
            echo "<td valign=top bgcolor=#99FFFF class='calcell' id='".$year."-".$month."-".$mday."'>";
        } else {
            echo "<td valign=top class='calcell' id='".$year."-".$month."-".$mday."'>";
        }
            CalendarPrint($style,$mday,$lunarday,$gaingi_text,$holidata,$memorialdata,$dType1);
            echo "</td>\n";

        // 출력후 값 초기화
        $holidata = "";
        $memorialdata ="";

        $date++; // 날짜 증가
        $offset++;
        if ($offset == 7) {
            echo "</tr>";
            if ($date <= $last_day) {
                echo "<tr height=$cellh>";
                $ck_row++;
            }
            $offset = 0;
        }

    }// end of while

    if ($offset != 0) {
        SkipOffset((7 - $offset), '', mktime(0, 0, 0, $month + 1, 1, $year));
        echo "</tr>\n";
    }
    echo("</td>\n");

    function ErrorMsg($msg) {
        echo " <script>window.alert('$msg');history.go(-1);</script>";
        exit;
    }

    function CalendarPrint($style,$mday,$lunarday,$gaingi,$holidata='',$memorialdata='',$dType1=''){
        echo "<font class=".$style.">$mday</font><br/>";
        echo "<font class=lunar>$lunarday</font><br/>";
        echo "<font class=gangi>$gaingi</font><br/>";
        if(strlen($holidata)>0) echo "<font class=red>$holidata</font><br/>";
        if(strlen($memorialdata)>0) echo "<font class=sblue>$memorialdata</font><br/>";
        if(count($dType1)>0) { // 배열 출력
            for ($i = 0; $i < count($dType1); $i++) {
                echo "<font class=num uid=".$dType1[$i][1].">".$dType1[$i][0]."</font><br/>";
            }
        }
    }

    function SkipOffset($no, $sdate = '', $edate = '') {
        for ($i = 1; $i <= $no; $i++) {
            $ck = $no - $i + 1;
            if ($sdate)
                $num = date('n.j', $sdate - (3600 * 24) * $ck);
            if ($edate)
                $num = date('n.j', $edate + (3600 * 24) * ($i - 1));

            echo "<td valign=top><font class=gray>$num</font></td>";
        }
    }

    function Lun2SolDate($date){
        global $dbconn;
        $sql = "SELECT solar_date FROM lunar_data where lunar_date='".$date."'";
        $result = mysqli_query($dbconn, $sql);
        $R = mysqli_fetch_array($result);
        return $R[0];
    }

    function isWeekend($date){
        // 앙력 날짜의 요일을 리턴
        // 일요일 0 토요일 6
        return date("w", strtotime($date));
    }

?>
    </tr>
</table>
</div>
</body>
</html>



코드 구현 파일

calendar.zip

lunar_data.zip


참조한 사이트

- 참조한 URL을 찾게되면 추가할 예정



본 자료가 도움되었다면 000 해주세요. 좋은 글 작성에 큰 힘이 됩니다.


'Web 프로그램 > PHP 응용 및 활용' 카테고리의 다른 글

PHP 날짜와 시간 차이  (0) 2019.03.26
jQuery Select Box 선택값 제어  (0) 2019.01.05
법정공휴일  (0) 2018.11.03
PHP 달력 만들기 소스  (0) 2018.10.30
날짜 선택  (0) 2018.10.26
블로그 이미지

Link2Me

,