이렇게 긴 텍스트를 쓸 때, 가로스크롤이 생겨서 우측 끝 텍스트를 확인하려면 가로스크롤을 제일 우측까지 당겨야 한다.

 

 

 

 

하지만 화면에 맞춰서 자동으로 다음줄로 넘어가게끔 하는 기능이 있다.

상단 메뉴 보기 > 자동 줄바꿈을 선택해주자.

 

 

선택하면 아래와 같이 보기편하게 변한다.

 

 

1
<tr onclick='메서드명()'/>
 

또는

1
2
3
 $("#테이블ID").on("click""tr"function () {
    alert("클릭");
 });
 
 

을 하면 table 의 tr (행단위)로 클릭 이벤트를 줄 수 있다. 하지만 특정 td 에는 클릭 이벤트를 걸고 싶지 않을 때에는

 

td에 다음과 같이 적어주면 된다.

1
<td onclick='event.cancelBubble=true;'>
 

이렇게 해주게 되면, 설정한 td 는 클릭 이벤트를 먹지 않는다.

카카오톡 알림톡 보낼때 템플릿에 #{이름} 이런식으로 변수를 설정할 수 있는데,

텍스트박스에 입력할때마다 #{이름} 이 홍길동 이런식으로 바뀌는것을 하고자 한다.

 

#{이름} 님 안녕하세요~ #{판매자} 입니다.

 

라고 되어있고 텍스트박스에 입력을 해서 내용을 바꾸려고 하는데,

홍길동의 ㅎ 을 누르자마자 ㅎ 님 안녕하세요~ 라고 바로 바뀌어버려서 원하는대로 되지않았다. (키보드의 keyup이벤트)

 

우선 변수형태인 #{이름} 과 #{판매자} 를 뽑아오기 위해 다음과 같이 선언한다.

변수형태가 2개 이상이기 때문에 matchAll 을 사용했다.

 

templateContent = 템플릿 내용 = #{이름} 님 안녕하세요~ #{판매자} 입니다.

1
2
var regex = new RegExp("#{(.*?)}""g");//변수찾기 ex.#{이름}
var matches = templateContent.matchAll(regex);//모든 변수 찾기
 

#{(.*?)} 는 #{   } 의 형식으로 되어있으면서 { } 안에 아무 내용이 들어가있는 것을 모두 찾겠다는 뜻이다.

g 는 모든 문자열 전체를 찾겠다는 뜻이다.

 

matchAll 을 하면 템플릿 내용 중 위의 정규표현식에 해당하는 모든 문자를 찾겠다는것이다.

위의 템플릿 내용으로 예시를 들면 matches 변수에는 #{이름} , #{판매자} 가 들어가게 된다.

 

이제 변수명의 갯수만큼 텍스트박스를 그려주도록 하자.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (let m of matches) {
        var cnt = 0;
        rules.find((element, index, array) => {
            if (element['key'== m[1])//변수가 이미 배열에 담겨있으면 화면에 그려주지 않기
                cnt++;
        });
        if (cnt == 0) {
            html = "<tr>";
            html += "<th>" + m[1+ "</th>";
            html += "<td>" + "<input type='text' class='input-large' id='" + "txt" + m[1+ "'></td>";
            html += "</tr>";
            $("#variableList").append(html);
            var rule = {};
            rule['key'= m[1];
            rules.push(rule);
        }
    }
 
 

for문을 처음 들어왔을 때 m은 이름에 대한 정보이고 m[1] 로 할시에 "이름" 이라는 텍스트를 얻을 수 있다.

ruels 는 변수들이 담겨있는 배열이며, 이미 텍스트박스가 그려진 변수라면 더이상 추가되지 않도록 하는것이다.

 

ruels.find((element, index, array) => 배열을 돌면서 = for문과 같이 동작하는것같다.

 

 

 

이제 키보드에서 손을 뗄때마다 템플릿 내용이 바뀌도록 해보자.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function insert(matches) {
    for (let m of matches) {
        var doc = document.getElementById("txt" + m);
        doc.addEventListener('keyup'function (e) {
            var changeContent = tempMsg;//원본 
            for (var i = 0; i < rules.length; i++) {
                var regex = new RegExp("#{" + rules[i]['key']+ "}""g");
                var value = $("#txt" + rules[i]['key']).val();
                if (value != '') {
                    changeContent = changeContent.replace(regex, value);
                }
            }
            $("#sms_field").val(changeContent);
        });
    }
 
}
 

matches 에는 이름, 판매자가 들어있다. (m[1] 들을 저장했다.)

var doc = document 노드에서 id 가 "txt이름" 인 텍스박스를 찾는다.

doc.addEventListener keyup => 키보드에서 손을 뗄때 이벤트를 추가한다.

tempMsg 에는 템플릿의 내용 원본을 저장해놓는다. (#{이름} 님 안녕하세요~ #{판매자} 입니다.)

그리고 changeContent 에 원본내용을 담는 변수를 선언한다.

그러면 키보드에서 손을땔때마다 원본 내용을 다시 읽어들여서 내용을 바꾸기 때문에,

홍길동이라는 글자를 입력해도 ㅎ 만 입력해서 #{이름} 이 리플레이스 되는것이 아니라

#{이름} 이 계속해서 ㅎ, 호, 홍 홍길동 이렇게 리플레이스 될수가 있게된다.

CTE

CTE 란 Common Table Expression 이다.

CTE는 기존의 뷰, 파생 테이블, 임시 테이블 등으로 사용되던 것을 대신할 수 있으며 간결하게 보여질 수 있다.

 

CTE는 비재귀적 CTE와 재귀적 CTE 두 가지가 있다.

 

비재귀적 CTE

1
2
3
4
5
6
7
WITH CTE_테이블이름(열 이름)
AS
(
    <쿼리문>
)
 
SELECT 열1, 열2 FROM CTE_테이블이름 ;
cs

쿼리문에 대한 것을 CTE_테이블로 정의해놓고, SELECT 문에서 CTE_테이블을 활용한다.

 

 

 

 

1
2
3
SELECT userid AS '사용자', SUM(price*amount) AS '총구매액'
  FROM buyTBL 
  GROYP BY userid;
 
cs

이 쿼리의 조회 결과가 아래와 같고,

 

 

 

총구매액을 내림차순으로 정렬하고 싶을 때, 쿼리 뒤에 ORDER BY 를 붙이는 방법 대신, CTE 방법을 이용하면 다음과 같다.

 

1
2
3
4
5
6
7
WITH abc(userid , total)
AS
(
    SELECT userid, SUM(price*amount)
    FROM buytbl GROUP BY userid
)
SELECT * FROM abc ORDER BY total desc;
cs

AS () 안에서 조회 한 buytbl 의 userid, SUM(price*amount) 가 각각

abc 테이블의 userid, total 열로 설정이 된다.

 

이때 주의할 점은 WITH ( 1, 2, 3... ) 의 열 개수와 AS ( SELECT 1, 2, 3... ) 의 열 개수가 같아야 한다.

이 쿼리의 조회 결과는 아래와 같다.

buytbl 을 ORDER BY 한 결과와 같다!

 

 

>>여러 개의 CTE 를 사용한 예제

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WITH cte_userTBL(addr, maxHeight)
AS
(
    SELECT addr, MAX(height)
    FROM usertbl
    GROUP BY addr
),
cte_addr(addr, height)
AS
(
    SELECT addr, height
    FROM usertbl
    GROUP BY addr
)
SELECT AVG(A.maxHeight*1.0) AS '각 지역별 최고키의 평균' , B.addr FROM cte_userTBL A, cte_addr B;
cs

 

+ Recent posts