728x90

Javascript 코드를 구현할 때 재귀호출을 하면서 Identifier 'marker' has already been declared 라는 메시지가 나온다.

뭐가 문제일까?

 

아래코드를 새로운 창에서 매번 실행한다면 문제될 것이 전혀 없다.

그리고 var 변수로 선언된 변수는 다시 선언해도 되므로 문제가 되지 않는다.

즉, 특정 div 영역에 재로딩을 해도 var 변수가 덮어쓰기 되므로 문제될 것이 없다.

하지만 변수를 let, const  로 변경하면 문제가 될 수 있다.

<body>
<div id="map" style="width:100%;height:350px;"></div>
 
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 사용하세요"></script>
<script>
var mapContainer = document.getElementById('map'), // 지도를 표시할 div 
    mapOption = { 
        center: new kakao.maps.LatLng(33.450701126.570667), // 지도의 중심좌표
        level: 3 // 지도의 확대 레벨
    };
 
var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다
 
// 마커가 표시될 위치입니다 
var markerPosition  = new kakao.maps.LatLng(33.450701126.570667); 
 
// 마커를 생성합니다
var marker = new kakao.maps.Marker({
    position: markerPosition
});
 
// 마커가 지도 위에 표시되도록 설정합니다
marker.setMap(map);
 
// 아래 코드는 지도 위의 마커를 제거하는 코드입니다
// marker.setMap(null);    
</script>
</body>

 

 

아래와 같이 코드를 구현했을 경우에는 어떤 문제가 생기는지 살펴보자.

id가 panel_content 라는 DIV 영역에 필요한 파일을 계속 Load하여 화면을 새로 그리는 구조로 코드를 구현해서 사용하고 있다.

<main>
    <div class="container-fluid text-center">
        <div class="row">
            <div class="col-md-12">
                <div class="content" id="panel_content">
                </div>
                <div class="card">
                </div>
            </div>
        </div>
    </div>
</main>
 
<script>
function MListTable(where,keyword,curPage,uri,bidx,sort,cat1,cat2,idx) {
 
    if (keyword.length > 20) {
        calluri = uri + '?p='+curPage+'&idx='+idx+'&cat1='+cat1+'&cat2='+cat2+'&where='+where+'&keyword='+encodeURIComponent(keyword)+'&sortby='+sort;
        console.log('bCode : ' + calluri);
    }
    else
        calluri = uri + '?p='+curPage+'&idx='+idx+'&cat1='+cat1+'&cat2='+cat2+'&where='+where+'&keyword='+encodeURIComponent(keyword)+'&bidx='+bidx+'&sortby='+sort;
 
    $('#panel_content').load(calluri, function() {
        var curPage = $('#paging .act a').text();
 
 
        $('#MNListTable tbody tr').mouseover(function() {
            $(this).children().css({
                'backgroundColor' : '#DCDCDC''cursor' : 'pointer'
            });
        }).mouseout(function() {
            $(this).children().css({
                'backgroundColor' : '#FFFFFF''cursor' : 'default'
            });
        });
 
        $('#MNListTable tbody tr').click(function() {
            var idx = $(this).attr('id');
            MNView(idx,curPage,where,keyword,cat1,cat2,bidx,sort);
        });
        $('#MNHome').click(function(e) {
            e.preventDefault();
            var uri = $('#urlPath').attr('url-path');
           MListTable('','',1,uri,'','','','','');
        });
 
    });
}
 
</script>

 

 

테이블에서 특정 TR 를 누르면 해당 값을 읽어서 MNView 로 넘기는 형태이다.

<script>
function MNView(idx,curPage,where,keyword,cat1,cat2,bidx,sort){
    var uri = 'View.php';
   MListTable(where,keyword,curPage,uri,bidx,sort,cat1,cat2,idx);
}
</script>

 

 

id 가 panel_content 의 DIV 영역에 View.php?idx=1 파일의 내용을 로딩하게 된다.

아래 파일이 View.php?idx=3 으로 다시 로딩하게 되면 let marker 가 이미 선언되어 있기 때문에 중복 선언되는 문제가 발생하는 것이다.

<div class="card">
<div class="mt-1 mb-2 mx-2">
    <div id="map" style="width:100%;height:450px;"></div>
</div>
</div>
 
<script>
var latitude = '<?php echo $lat;?>';
var longitude = '<?php echo $lng;?>';
 
// 마커를 담을 배열입니다
let marker = [];
 
const mapContainer = document.getElementById('map'), // 지도를 표시할 div 
    mapOption = { 
        center: new kakao.maps.LatLng(latitude, longitude), // 지도의 중심좌표
        level: 6 // 지도의 확대 레벨
    };
 
const map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다
 
// 마커가 표시될 위치입니다 
const markerPosition  = new kakao.maps.LatLng(latitude, longitude); 
 
// 마커를 생성합니다
marker = new kakao.maps.Marker({
    position: markerPosition
});
 
// 마커가 지도 위에 표시되도록 설정합니다
marker.setMap(map);
 
// 아래 코드는 지도 위의 마커를 제거하는 코드입니다
// marker.setMap(null); 
</script>

 

 

이 문제를 방지하려면 함수를 만들어서 구현하면 해결된다.

index.php 파일 하단에 DrawMap 함수를 추가한다.

<script>
function DrawMap(latitude,longitude){
    // 마커를 담을 배열입니다
    let marker = [];
 
    const mapContainer = document.getElementById('map'), // 지도를 표시할 div 
        mapOption = { 
            center: new kakao.maps.LatLng(latitude, longitude), // 지도의 중심좌표
            level: 6 // 지도의 확대 레벨
        };
 
    const map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다
 
    // 마커가 표시될 위치입니다 
    const markerPosition  = new kakao.maps.LatLng(latitude, longitude); 
 
    // 마커를 생성합니다
    marker = new kakao.maps.Marker({
        position: markerPosition
    });
 
    // 마커가 지도 위에 표시되도록 설정합니다
    marker.setMap(map);
 
    // 아래 코드는 지도 위의 마커를 제거하는 코드입니다
    // marker.setMap(null); 
    
</script>

 

그리고 View.php 파일은 아래와 같이 수정한다.

그러면 let 과 const 로 선언한 변수가 재선언되지 않기 때문에 문제가 해결된다.

<div class="card">
<div class="mt-1 mb-2 mx-2">
    <div id="map" style="width:100%;height:450px;"></div>
</div>
</div>
 
<script>
var latitude = '<?php echo $lat;?>';
var longitude = '<?php echo $lng;?>';
 
DrawMap(latitude,longitude);
</script>

 

블로그 이미지

Link2Me

,
728x90

자바스크립트 코드로 동적으로 태그를 추가하는 예제이다.

 

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script defer src="./main.js"></script>
</head>
<body>
<h1>Hello world!</h1>
<ul></ul>
</body>
</html>

 

main.js

<script>
// for(시작조건;종료조건;변화조건) {}
 
const ulEl = document.querySelector('ul')
 
for(let i =0 ; i < 3; i++){
    const li = document.createElement('li')
    li.textContent = `list-${i+1}`
    li.addEventListener('click'function () {
        console.log(li.textContent)
    })
    ulEl.appendChild(li)
}
</script>

 

블로그 이미지

Link2Me

,
728x90

It is important to remember that create must be triggered on the parent container and not on the individual element that needs to be enhanced.

 

$('selector').trigger('선택할 이벤트');

// 트리거를 create로 변경해주면 된다.
$("타겟").append("추가할 html").trigger("create");

 

아래 예제는 http://jsbin.com/umatel/1/edit?html,js,output 를 참조하여 일부 헤더 정보 추가하고 테스트했다.

 

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Trigger Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <link href="https://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.css" rel="stylesheet" type="text/css" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  <script src="https://code.jquery.com/jquery-1.3.2.min.js"></script>
  <style>
    body {
      margin-top: 10px;
      margin-left: 10px;
    }
  </style>
</head>
<body>
  <div data-role="page" id="first">
    <button>Button element</button>  
  </div>
 
<script>
$("button").click(function() {
  $('<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive table-stroke"><thead><tr><th data-priority="1">Rank</th><th data-priority="persist">Movie Title</th><th data-priority="2">Year</th><th data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th><th data-priority="4">Reviews</th></tr></thead><tbody><tr><th>1</th><td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external">Citizen Kane</a></td><td>1941</td><td>100%</td><td>74</td></tr><tr><th>2</th><td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external">Casablanca</a></td><td>1942</td><td>97%</td><td>64</td></tr><tr><th>3</th><td><a href="http://en.wikipedia.org/wiki/The_Godfather" data-rel="external">The Godfather</a></td><td>1972</td><td>97%</td><td>87</td></tr><tr><th>4</th><td><a href="http://en.wikipedia.org/wiki/Gone_with_the_Wind_(film)" data-rel="external">Gone with the Wind</a></td><td>1939</td><td>96%</td><td>87</td></tr><tr><th>5</th><td><a href="http://en.wikipedia.org/wiki/Lawrence_of_Arabia_(film)" data-rel="external">Lawrence of Arabia</a></td><td>1962</td><td>94%</td><td>87</td></tr></tbody></table>').appendTo("#first");
 
  $("#first").trigger("create");
});
</script>
</body>
</html>

 

$('<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive table-stroke"><thead><tr><th data-priority="1">Rank</th><th data-priority="persist">Movie Title</th><th data-priority="2">Year</th><th data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th><th data-priority="4">Reviews</th></tr></thead><tbody><tr><th>1</th><td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external">Citizen Kane</a></td><td>1941</td><td>100%</td><td>74</td></tr><tr><th>2</th><td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external">Casablanca</a></td><td>1942</td><td>97%</td><td>64</td></tr><tr><th>3</th><td><a href="http://en.wikipedia.org/wiki/The_Godfather" data-rel="external">The Godfather</a></td><td>1972</td><td>97%</td><td>87</td></tr><tr><th>4</th><td><a href="http://en.wikipedia.org/wiki/Gone_with_the_Wind_(film)" data-rel="external">Gone with the Wind</a></td><td>1939</td><td>96%</td><td>87</td></tr><tr><th>5</th><td><a href="http://en.wikipedia.org/wiki/Lawrence_of_Arabia_(film)" data-rel="external">Lawrence of Arabia</a></td><td>1962</td><td>94%</td><td>87</td></tr></tbody></table>').appendTo("#first");

 

실행결과

 

클릭전

 

클릭후

블로그 이미지

Link2Me

,
728x90

// jQuery prototype
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$.fn.changeColor = function(){
    $(this).css('color', "red");

    return this; // 생략 가능
};

</script>

<script>
$('#abc').changeColor();
</script>

 

jQuery Selector를 이용하는 메소드를 추가하려면 $.fn.메소드명 을 통해 추가한다.

this 키워드는 $("selector") 를 통해 들어온 jQuery Object를 의미한다.

chaining을 지원하기 위해 this를 return한다.

 

https://learn.jquery.com/plugins/basic-plugin-creation/ 를 참고하면 더 많은 내용을 확인할 수 있다.

 

 

<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
 <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
 <!-- jQuery prototype -->
 <script>
$.fn.changeColor = function(){
    $(this).css('color'"red");
};
 
$.fn.blueBorder = function(){
    this.each(function(){
        $(this).css("border","solid blue 1px");
    });
    return this;
};
$.fn.redText = function(){
    this.each(function(){
        $(this).css("color","red");
    });
    return this;
};
 
</script>
 
</head>
<body>
<div id="abc">
    글자색 변환
</div>
<br>
<input id="b" type="button" value="Apply" /><br />
<div class="blue">1</div>
<div class="blue">2</div>
<div class="blue">3</div>
 
<script>
$('#abc').changeColor();
 
$("#b").click(function(){
    $('.blue').blueBorder().redText();
});
</script>
 
</body>
</html>

 

 

VSCode 에서 HTML, Javascript 개발 환경 구축하여 테스트 해보는 방법

Code Runner 를 설치하고 나서 VSCode 우측 상단의 ▷ 를 누르면 하단 콘솔창에 실행결과가 나온다.

 

open in browser 를 설치하여 Web 브라우저 상에서 확인해보자.

VSCode 를 종료한 다음 다시 실행한 다음 VSCode 왼쪽 하단에 있는 설정 아이콘을 클릭한다.

검색창에서 open-in-browser.default 를 입력하고 chrome 이라고 입력해 준다.

 

아래와 같이 VSCode 창에서 ALT + B 를 누르면 크롬브라우저가 팝업되면서 결과가 화면에 출력된다.

블로그 이미지

Link2Me

,
728x90

PHP 와 Query를 이용하여 테이블의 칼럼을 누루면 해당 칼럼 순으로 정렬하는 기능을 구현하고 싶을 때가 있다.

핵심 기능에 필요한 것만 발췌하여 적어둔다.

<?php
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
 
$link_url = "MemberList.php"// 현재 실행중인 파일명 가져오기
 
$sort = isset($_GET['sortby']) ? $a->XSSFilter($_GET['sortby']): '';
$bidx = isset($_GET['bidx']) ? $a->XSSFilter($_GET['bidx']) :'';
switch($bidx){
    case 1:
        $xorderby"userNM ";
        $sortby = ($sort == "userNMDESC") ? "ASC" : "DESC";
        $xorderby.= $sortby;
        break;
    case 2:
        $xorderby"userID ";
        $sortby = ($sort == "userIDDESC") ? "ASC" : "DESC";
        $xorderby.= $sortby;
        break;
    default:
        $xorderby"idx DESC";
        $sortby = "DESC";
        break;
}
?>
 
<th scope="col" class="bldSort" data-bidx="1" style="cursor:pointer">성명</th>
<th scope="col" class="bldSort" data-bidx="2" style="cursor:pointer">아이디</th>
 
<div class='form-group'>
    <form name="ListForm" class="form-inline" action="<?php echo $link_url;?>">
        <input type="hidden" name="m" value="<?php echo $m;?>" />
        <input type="hidden" name="orderby" id="xorderby" value="<?php echo $xorderby;?>" />
        <!-- 일부 코드 생략 -->
</div>
<div id="urlPath" url-path="<?php echo $link_url;?>"></div>
 
<script>
$('.bldSort').click(function(e) {
    e.preventDefault();
    var bidx = $(this).attr('data-bidx');
    var uri = $('#urlPath').attr('url-path');
    var sort = document.getElementById('xorderby').value.replace(/(\s*)/g,"");
    MemberListTable(where,keyword,curPage,uri,bidx,sort);
});
</script>

 

 

블로그 이미지

Link2Me

,
728x90

논리 연산자를 효율적으로 사용하는 방법이라고 보면 된다.

 

console.log(true && "hello"); // 'hello'
console.log(null && undefined); // null
console.log(undefined && "hello"); // undefined
console.log("hello" && null); // null
console.log("hello" && "bye"); // bye
console.log(null && "hello"); // null
console.log(undefined && "hello"); // undefined
console.log('' && 'hello'); // ''
console.log(0 && 'hello'); // 0
console.log(1 && 'hello'); // hello
console.log(1 && 1); // 1

&& 연산자는 첫번째가 true 이면 뒤에 있는 hello 를 반환한다.

첫번째가 false 이면 첫번째를 반환한다.

 

&& 연산자로 코드 단축시키기

const seaFood = {
  name"쭈꾸미"
}
 
function getName(fish) {
  // && 논리 연산자가 truly 하면 fish.name 을 반환한다.
  return fish && fish.name
}
 
const name = getName(seaFood);
console.log(name); // '쭈꾸미'

fish 도 Truthy 하고 fish.name 또한 Truthy 하다면 오른쪽의 값을 return 한다.

 

|| 연산자로 코드 단축시키기

A || B 는 만약 A 가 Truthy 할경우 결과는 A 가 됩니다. 반면, A 가 Falsy 하다면 결과는 B 가 된다.

const seaFood = {
  name"박달대게"
};
 
function getName(fish) {
  // fish 가 Truthy 하면 왼쪽 값인 fish 를 return 
  // fish 가 Falsy 하면 오른쪽 값인 '이름없음' 을 return
  return fish || '이름없음'
}
 
const name = getName(seaFood)
console.log(name// {name : 박달대게}
 
const name2 = getName()
console.log(name2) // '이름없음'
 

 

 

블로그 이미지

Link2Me

,
728x90

프로그래밍 학습이나 교육에 활용하면 좋은 온라인 코드 에디터 CodeSnadbox 를 이용하는 방법이다.

 

https://codesandbox.io/ 에 접속한다.

JS를 선택한다.

 

 

 

 

 

 

 

 

 

로그인을 한 다음에 사용하면 된다.

 

https://learnjs.vlpt.us/basics/01-hello-javascript.html 에 좋은 강좌 내용이 있으니 참고하면 좋다.

 

function biggerThanThree(numbers) {
  /* 구현해보세요 */
  const arr = [];
  for (let i = 0; i < numbers.length; i++) {
    if (i < 3continue;
    arr.push(numbers[i]);
  }
  return arr;
}
 
const numbers = [1234567];
console.log(biggerThanThree(numbers)); // [4, 5, 6, 7]
 
export default biggerThanThree;
 
 

 

블로그 이미지

Link2Me

,
728x90
// 사업자 번호 체크
function BizNOChk(b1,b2,b3){
    // 사업자 등록번호는 000-00-00000 의 구조
    // 123 : 국세청과 세무서별 코드
    // 45 : 개인, 법인 구분
    // 6789 : 과세사업자나 면세사업자 또는 법인사업자별로 등록 또는 지정일자를 일련번호로 나타낸 것
    // 0 : 맨끝 자리 수는 전산시스템으로 오류를 검증하기 위해 부여되는 검증번호
    // bizID는 숫자만 10자리로 해서 문자열로 넘긴다. 
    var checkID = new Array(1371371351); 
    var tmpBizID, i, chkSum=0, c2, remander; 
    var bizID = b1+b2+b3; 
 
    if (trim(bizID)==""return false;
    for (i=0; i<=7; i++) chkSum += checkID[i] * bizID.charAt(i); 
    c2 = "0" + (checkID[8* bizID.charAt(8)); 
    c2 = c2.substring(c2.length - 2, c2.length); 
    chkSum += Math.floor(c2.charAt(0)) + Math.floor(c2.charAt(1)); 
    remander = (10 - (chkSum % 10)) % 10 ; 
 
    if (Math.floor(bizID.charAt(9)) == remander) 
        return true ; // OK! 
    else
        return false
}
 
 
// 법인번호 검사
function isRegNo(sRegNo) {
    var re = /-/g;
    sRegNo = sRegNo.replace('-','');
 
    if (sRegNo.length != 13){
        return false;
    }
 
    var arr_regno  = sRegNo.split("");
    var arr_wt   = new Array(1,2,1,2,1,2,1,2,1,2,1,2);
    var iSum_regno  = 0;
    var iCheck_digit = 0;
 
    for (i = 0; i < 12; i++){
        iSum_regno +=  eval(arr_regno[i]) * eval(arr_wt[i]);
    }
 
    iCheck_digit = 10 - (iSum_regno % 10);
 
    iCheck_digit = iCheck_digit % 10;
 
    if (iCheck_digit != arr_regno[12]){
        return false;
    }
    return true;
}
 
 
//주민등록번호 체크
//111111-1111118
function chkJumin(jumin) {
    if(jumin.match(/^\d{2}[0-1]\d[0-3]\d-[1-4]\d{6}$/== null) {
        return false;
    }
 
    var chk = 0;
    var i;
    var last_num = jumin.substring(1314);
    var chk_num = '234567-892345';
 
    for(i = 0; i < 13; i++) {
        if(jumin.charAt(i) != '-')
            chk += ( parseInt(chk_num.charAt(i)) * parseInt(jumin.charAt(i)) );
    }
 
    chk = (11 - (chk % 11)) % 10;
 
    if (chk != last_num) return false;
    return true;
}
 
 
// 숫자만 입력 체크
// 사용법 : <input type=text name=id onKeyPress="return IsNumChk()">
function IsNumChk(objWord) {
    var InputValue = objWord.value;
    for(var i=0; i<InputValue.length; i++) {
        if(isNaN(InputValue.charAt(i))) {
            window.alert("숫자만 입력하세요!");
            objWord.vlaue = "";
            for(var j=0; j < i; j++) {
                objWord.vale += InputValue.charAt(j);
            }
            return;
        }
    }
}
 
// 숫자만 입력
$(document).on("keyup""input:text[numberOnly]"function() {
    $(this).val($(this).val().replace(/[^0-9]/gi,"") );
});
 

 

 

블로그 이미지

Link2Me

,
728x90

맥북에서 node.js 설치하는 방법을 적어둔다.

 

https://nodejs.org/en/download/ 에서 pkg 버전을 열면 바로 설치 화면창이 나오고 계속 진행하면 설치된다.

 

설치하고 나서 터미널 창을 연다.

sudo npm install -g n

sudo npm cache clean -f

sudo n stable

 

javascript 실행 코드를 node.js 에서 실행하면 동작한다.

 

실행 화면

 

결과가 codesandbox 에서 만큼 정확하지 않아서 사용을 계속할지는 의문이 든다.

블로그 이미지

Link2Me

,
728x90

테이블을 JQuery 로 다루는 걸 간략하게 작성해둔다.

보통은 row 단위로 테이블의 마우스 포인트를 처리하고, row 의 값만 추출한다.

만약, 특정한 셀을 눌렀을 때의 값을 추출하거나, 함수 처리를 하고 싶을 때가 있다.

이때에는 기준점이 td 이므로 td 에 클래스명을 부여시 서로 다르게 부여한다.

 

 

위와 같은 테이블의 PHP 소스코드가 아래와 같다고 가정하자.

 

<tr id="<?php echo $R['uid']; ?>">
    <td class="BoardView"><?php echo $no;?></td>
    <td class="BoardView"><?php echo $R['subject'];?></td>
    <td class="BoardView"><?php echo $R['writer'];?></td>
    <td class="Excelpdf"><?php echo $R['regdate'];?></td>
    <td class="BoardView"><?php echo $R['hit'];?></td>
</tr>

 

 

 

관련 jQuery 코드가 아래와 같이 처리한다.

테이블에서 계속 변경되는 테이블의 row 는 클래스로 부여하고, 현재 셀은 $(this) 이고, 상위의 값은 $(this).parent().attr('id') 로 부여한 요소값을 추출한다.

인접한 셀의 값을 가져오기 위해서 $(this).parent().find("td:eq(3)").text() 로 처리한다.

 

$('.BoardView').click(function() {
    var idx = $(this).parent().attr('id');
    var date = $(this).parent().find("td:eq(3)").text();
    uri = "excelpdf.php?do="+idx+"&date="+date;
    window.location.href = uri;
});

 

 

parents() 메소드 : 자신부터 document root 까지 검색을 하기 때문에 검색 결과가 1개 이상일 수 있다는 점
  문서의 root 요소부터 DOM Tree를 탐색하여 각 부모요소들로 임시 집합을 구성하고
  제공된 선택자에 의해 임시 집합에서 추출

closest() 메소드 : 선택된 요소의 최초의 부모 요소를 얻을 수 있다.
  현 시점의 요소에서 시작하여 DOM 트리의 마지막 부분까지 조회한다.
  없거나 하나의 요소를 포함한 jQuery 객체를 반환
  자기 자신부터 찾기 시작하여 부모 요소 탐색을 하다가 해당 아이템에서 탐색을 멈춤

 

var age = $(this).find('[name=age]').val();
// name으로 접근시 $("tag_name[name=name]") 
$("input[name=search_value]")

아래 3개는 모두 동일한 결과를 보여준다.

var idx = $('#FloorForm').find('[name=bidx]').val();
var idx = $('input[name=bidx]',document.FloorForm).val();
var idx = $(document.FloorForm).find('[name=bidx]').val();

<div class='form-group'>
	<form name="FloorForm" id="FloorForm" class="form-inline" action="<?php echo $link_url;?>">
		<input type="hidden" name="bidx" value="<?php echo $bidx;?>" />

		<div class="input-group mb-3">
			<select name="where" class="browser-default custom-select">
				<option value="floor">층</option>
				<option value="all">전체</option>
			</select>
		</div>
		<div class="input-group mb-3">
		  <input type="text" name="keyword" class="form-control" id="FloorSearchKeyword">
		  <div class="input-group-append">
			<button class="btn btn-outline-default" type="button" id="FloorSearch">검색</button>
			<button class="btn btn-outline-default" type="button" id="FloorHome">Home</button>
		  </div>
		</div>
	</form>
</div>

$('#FloorSearchKeyword').on('keypress', function(event){
	var agent = navigator.userAgent.toLowerCase();
	var keycode = (event.keyCode ? event.keyCode : event.which);
	if(keycode == 13){ // 엔터키가 입력될 때까지는 어떤 것도 하지 않는다.
		event.preventDefault(); // 엔터키가 입력되면 현재 이벤트의 기본 동작을 중단한다.
		//event.stopPropagation(); // 현재 이벤트가 상위로 전파되지 않도록 중단한다.
		var where = $('#FloorForm').find('[name=where]').val();
		var keyword = $('#FloorForm').find('[name=keyword]').val();
		FloorSearch(where,keyword);
	}
});

$('#FloorSearch').click(function(e){
	var where = $('#FloorForm').find('[name=where]').val();
	var keyword = $('#FloorForm').find('[name=keyword]').val();
	FloorSearch(where,keyword);
});

function FloorSearch(where,keyword){
	var uri = $('#urlPath').attr('url-path');
	var idx = $('#FloorForm').find('[name=bidx]').val();

	keyword= keyword.replace(/\s/g,""); // 문자열내의 모든 공백 제거
	var regExp = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%&\\\=\(\'\"]/gi; // 특수문자 제거
	keyword = keyword.replace(regExp,"");
	if(keyword.length == 0){
		alert('검색어를 입력하세요');
		$('input[name=keyword]').focus();
		return false;
	}
	MemberListTable(where,keyword,1,uri,idx);
}

라디오버튼의 value 가져오기
$("#FloorForm").find("[name=chk_confirm]:checked").val();

 

select박스
* 선택된값 가져오기 : $("#FloorForm>[name=cate]>option:selected").val() );
* 값 선택하기 :  $("#FloorForm").find("[name=cate]>option@[value=BLOG]").attr('selected','true');

 

<form id="frm" name="frm">
   <input type="text" name="price" value="100" />
   <input type="text" name="price" value="200" />
   <input type="text" name="price" value="300" />
   <input type="text" name="price" value="400" />
</form>

var Price = $("#frm input[name='price']").eq(2).val();
블로그 이미지

Link2Me

,
728x90

사용자가 직접 클릭하지 않고 자동으로 클릭이 되는 기능을 동작시키고 싶을 때가 있다.

왼쪽 메뉴를 클릭하거나 로그인 버튼을 눌렀을 때 팝업 모달이 자동으로 실행되게 하고 싶은데 처음에는 좀 해맸다.


로직에 대한 기본 이해 부족이었다.

동작 순서를 고려하여 순차적으로 실행되게 해야 한다.


1. 왼쪽 메뉴를 누르면

2. a href 링크의 고유 기능은 이벤트 실행 금지 시킨다. e.preventDefault();

3. 우측 content 에 원하는 걸 load 시킨다.

    $('.memberModify').on('click',function(e){
        var uri = $(this).attr('href');
        if(uri != '#'){
            $('#panel_content').load(uri);
        }
    });

4. load 되는 곳에 특정 키워드가 포함되어 있고 또 클릭을 해야 하는 불편이 있다면...

    $('.memberModify').on('click',function(e){
        e.preventDefault(); // a 링크 실행 방지
        var uri = $(this).attr('href');
        if(uri != '#'){
            $('#panel_content').load(uri,function(){
                if($('#modalLoginClick:contains("눌러주세요")')){
                    $('#modalLoginClick').trigger('click'); // 자동 클릭
                }
            });
        }
    });


trigger 메소드를 사용하면 자동 클릭이 되는 걸 확인할 수 있다.

load 시킨 다음에 자동 클릭이 되어야 정확하게 원하는 결과가 나왔다.


ㅇ trigger(eventType)
  eventType는 이벤트의 타입을 지정하는 문자열로써 click, dblclick, focus, blur 등등 해당 이벤트를 구동한다.




블로그 이미지

Link2Me

,
728x90

jQuery 에서 검색어를 입력하고 엔터키를 누르면 검색이 실행되도록 하는 코드를 테스트하는데 자꾸 오동작이 발생한다.

한마디로 개념 부족에서 오는 현상이었다.

프로그램은 절대 거짓말 하지 않는다는 지인의 말이 생각난다.

구현하려는 로직과 내가 코딩하는 것의 사이에서 놓치는 점이 무엇인가 다시 고민해보자.


처리하려는 로직을 순서대로 적어본다.

1. 엔터키를 입력할 때까지는 어떠한 것도 하지 않는다.

2. 엔터키가 입력되면 event.preventDefault(); 를 실행하여 자동으로 서밋되는 걸 방지한다.

3. 원하는 결과를 실행한다.


if(parseInt(device_type) === 3){ // PC에서 입력한 코드인지 확인
    // 27 is the ESC key (익스플로어나 크롬에서는 27로 나오고 파이어폭스는 0)
    $('#BBSSearchKeyword').on('keypress', function(event){
        var keycode = (event.keyCode ? event.keyCode : event.which);
        if(keycode == 13){ // 엔터키가 입력될 때까지는 어떤 것도 하지 않는다.
            event.preventDefault(); // 엔터키가 입력되면 이벤트의 기본 동작을 중단한다.
            //event.stopPropagation(); // 현재 이벤트가 상위로 전파되지 않도록 중단한다.
            BBSSearch(uri,where,keyword);
        }
    });
}

크롬브라우저 정상 동작, Firefox 브라우저 정상 동작
익스플로러에서 실행하니까 한글 입력 결과의 텍스트가 깨지면서 정확한 결과를 반환하지 않는다.
코드에서 UTF-8 을 기본으로 인식하는 코드를 추가해줘야 하나보다.

encodeURIComponent : URI로 데이터를 전달하기 위해서 문자열을 UTF-8 인코딩, IE8 이상의 브라우저에서 모두 지원한다.


블로그 이미지

Link2Me

,
728x90

jQuery 에서 값 입력 여부를 체크하는 걸 반복적으로 하니까 좀 귀찮은 거 같아서 간단하게 처리하는 걸 시도했다.


함수 만들기 이전 입력값 체크

if($('select[name=cat1]').val().length == 0){
    alert('카테고리1 선택을 안했습니다.');
    $('select[name=cat1]').focus();
    return false;
}
if($('select[name=cat2]').val().length == 0){
    alert('카테고리2 선택을 안했습니다.');
    $('select[name=cat2]').focus();
    return false;
}
if($('input[name=userID]').val().length == 0){
    alert('아이디를 입력하세요');
    $('input[name=userID]').focus();
    return false;
}
if($('input[name=userNM]').val().length == 0){
    alert('성명을 입력하세요');
    $('input[name=userNM]').focus();
    return false;
}


함수를 만들고 나서 입력값 체크

function CheckErr(vsel,msg){
    var count = vsel.val().length;
    if(count < 1){
        alert(msg);
        vsel.focus();
        return false;
    }
    return true;
}


if(CheckErr($('select[name=cat1]'),'카테고리1 선택을 안했습니다.') == false) return false;
if(CheckErr($('select[name=cat2]'),'카테고리2 선택을 안했습니다.') == false) return false;
if(CheckErr($('input[name=userID]'),'아이디를 입력하세요.') == false) return false;
if(CheckErr($('input[name=userNM]'),'성명을 입력하세요.') == false) return false;


블로그 이미지

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

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

<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

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

,