HTML 에서 테이블을 쓰다가, 테이블의 제목은 가운데 정렬을 해주고 번호나 날짜는 가운데정렬을 하지만 제목이나 내용은 왼쪽 정렬로 출력하고 싶고.... 원하는 데로 테이블을 꾸미고 싶을 때가 있습니다.

이때 여러가지 방법으로 꾸며줄 수 있습니다.

이번 포스트에서는 표를 가운데 정렬하는 방법을 알아보려 합니다.


01. 표(table) 예제

표 예제를 살펴보면 다음과 같습니다.

<html lang="ko">
  <head>
    <meta charset="utf-8">
    <title>Table 정렬</title>
    <style>
      table, th, td {
        border: 1px solid #bcbcbc;
      }
      table {
        width: 1000px;
        height: 200px;
      }
    </style>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <th>번호</th>
          <th>제목</th>
          <th>날짜</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>번호1</td>
          <td>제목1</td>
          <td>날짜1</td>
        </tr>
        <tr>
          <td>번호2</td>
          <td>제목2</td>
          <td>날짜2</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>


위의 코드를 실행하면 크게 꾸며준 것이 없는 테이블을 볼 수 있습니다.


Table 정렬
번호 제목 날짜
번호1 제목1 날짜1
번호2 제목2 날짜2

이제 이 기본 소스에서 추가적인 작업을 수행하면서 어떻게 정렬을 바꾸고 수정할지 방법을 알아보겠습니다.





02. 표 가운데 정렬

CSS 수정하는 방법

아래의 소스는 표 예제 소스에서 CSS 부분을 수정한 것입니다.

<html lang="ko">
  <head>
    <meta charset="utf-8">
    <title>Table 정렬</title>
    <style>
      table, th, td {
        border: 1px solid #bcbcbc;
      }
      table {
        width: 1000px;
        height: 200px;
      }
      td {
        text-align: center;
      }
    </style>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <th>번호</th>
          <th>제목</th>
          <th>날짜</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>번호1</td>
          <td>제목1</td>
          <td>날짜1</td>
        </tr>
        <tr>
          <td>번호2</td>
          <td>제목2</td>
          <td>날짜2</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>


td 태그에 text-align: center;를 추가해줌으로써 모든 td를 가운데정렬을 해주었습니다.

Table 정렬
번호 제목 날짜
번호1 제목1 날짜1
번호2 제목2 날짜2



<center>태그를 이용하는 방법

CSS 속성을 변경해주는 것보다 번거로운 점이 있지만 특정 td 태그만 가운데정렬을 간편하게 할 수 있습니다.

물론 CSS 속성을 보다 견고하게 세분화하여 적용해준다면 center를 사용하는 번거로움도 없어지겠지만, 저는 아래와 같은 방법을 사용하였습니다.

<html lang="ko">
  <head>
    <meta charset="utf-8">
    <title>Table 정렬</title>
    <style>
      table, th, td {
        border: 1px solid #bcbcbc;
      }
      table {
        width: 1000px;
        height: 200px;
      }
    </style>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <th>번호</th>
          <th>제목</th>
          <th>날짜</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>번호1</td>
          <td><center>제목1</center></td>
          <td>날짜1</td>
        </tr>
        <tr>
          <td>번호2</td>
          <td><center>제목2</center></td>
          <td>날짜2</td>
        </tr>
      </tbody>
    </table>
  </body>
</html



Table 정렬
번호 제목 날짜
번호1
제목1
날짜1
번호2
제목2
날짜2




Jinja2를 사용할 때 원래는 break문을 기본적으로 사용할 수 있을 것 같지만, 전혀 그렇지 않습니다... 허허...

보통은 break는 기본으로 제공하지만 jinja2는 예외더랍니다.


따라서 추가적인 작업이 필요합니다.


01. jinja2.ext.loopcontrols 적용

Jinja2에서 'jinja2.ext.loopcontrols'를 적용해주면 추가적인 작업 없이 {% break %}를 사용할 수 있습니다.

# ==============================
# flask_folder/run.py (실행파일)
# ==============================
import sys
from app import app

app.run(host='0.0.0.0', port=80, threaded=True)


위와 같이 run.py가 작성되어 있다고 가정합니다.

그러면 이제 jinja2.ext.loopcontrols를 적용해주어야 하는데, 이는 다음과 같이 적용해줄 수 있습니다.


# ==============================
# flask_folder/app/__init__.py
# ==============================
from flask import Flask, request, session, g, redirect, url_for, abort, render_template

# Configurations
app.config.from_object('config')

# Jinja2 environment add extension
app.jinja_env.add_extension('jinja2.ext.loopcontrols')


반드시 위와 같은 방법으로 추가해주지 않아도 되지만, 저는 이 방법으로 작업을 수행했습니다.




02. {% break %} 사용 예제

아래는 {% break %}문을 사용하는 예제 입니다.


{% for m in menu %}
    {% if m.case in cases %}
       <li class="on">
            {{ m.data }}
       </li>
    {% else %}
       {% break %}
    {% endif %}
{% endfor %}




자바스크립트의 반복문은 while, do while, for, for in문으로 총 네 가지가 있습니다.

특성은 C 언어와 python과 비슷합니다.


while문

var value = 0;
while(value < 5) {
    alert('No.' + value);
    value++;
}


while문은 C언어와 거의 같다고 보시면 될 것 같습니다.


do while문

var value = 0;
do {
    alert('No.' + value);
    value++;
} while(value < 5);


do while문도 마찬가지로 C언어와 거의 같은 형태를 보이고 있습니다.


for문

var array = ['1', '2', '3', '4'];

for(var i=0; i<array.length; i++) {
    alert(array[i]);
}


여기서 특이한 점이 array의 길이를 .length를 통해 표현하고 있습니다.

리스트(배열)의 길이는 .length를 통해 설정할 수 있습니다.


for in문

var array = ['1', '2', '3', '4'];
 
for(var i in array) {
    alert(array[i]);
}


자바스크립트는 배열이나 객체를 좀 더 쉽게 다룰 수 있도록 for in문을 제공합니다. 이는 마치 python의 형태와 유사한데, 완전히 같다고는 할 수 없습니다. 하하... 위의 예제에서 in 앞의 var i는 index를 나타내는 것이며 배열 내의 값을 나타내진 않습니다.






자바스크립트의 조건문은 if문과 switch문이 있습니다.

특성은 C언어나 다른 일반적인 언어와 비슷합니다.


if문

var date = new Date();
var hour = date.getHours();
 
if(hour < 11) {
    alert("It is Breakfast");
}
else if(hour >= 11 && hour < 15) {
    alert("It is Lunch");
}
else {
    alert("It is Dinner");
}


switch문

var input = Number(prompt('Input Your Number.', 'Number'));
 
switch(input % 2) {
    case 0:
        alert("Even!!!");
        break;
    case 1:
        alert("Odd!!");
        break;
    default:
        alert("It is not number..!");
        break;
}


삼항 연산자

var input = prompt('Input Your Number.', 'Number');
var number = Number(input);
 
(number > 0) ? alert('Natural Number') : alert('Not Natural Number');


이외에도 javascript에서는 보다 짧게 조건문을 작성해볼 수 있습니다.

다음과 같은 예제와 같습니다.


짧은 조건문

true || alert('Answer A');
false || alert('Answer B');
// || 연산 첫 번째 줄에서 Answer A는 실행되지 않고 Answer B는 실행됩니다.
 
true && alert('Answer C');
false && alert('Answer D');
// && 연산 첫 번째 줄에서 Answer C는 실행되고 Answer D는 실행되지 않습니다.


설명을 더하면, 다음과 같습니다.

1. true || alert(); 에서는 왼쪽이 이미 참이기 때문에 오른쪽 값을 확인하지 않고 넘어가버립니다.

2. false || alert(); 에서는 왼쪽이 거짓이기 때문에 오른쪽 값을 확인합니다. 따라서 alert() 함수가 실행됩니다.

3. true && alert(); 에서는 왼쪽이 참이기 때문에 오른쪽을 확인합니다.(and 연산은 둘 다 참이어야 실행됩니다.) 따라서 alert() 함수가 실행됩니다.

4. false && alert(); 에서는 왼쪽이 이미 거짓이기 때문에 오른쪽을 볼 것도 없이 이미 이 연산은 거짓이 되어 실행되지 않습니다.






01. remove 함수

문법

.remove( [ selector ] )


remove 함수는 선택한 요소를 제거할 때 사용하거나, 요소 내의 태그들을 삭제할 때 사용합니다.


예제 소스

<html lang="ko">
  <head>
    <title>kkamikoon javascript</title>
    <script>
      $( document ).ready( function() {
        $( 'ul' ).remove( '.rm' );
      } );
    </script>
  </head>
  <body>
    <ul class='rm'>
      <li>Test1</li>
      <li>Test2</li>
    </ul>
  </body>
</html>


결과

<body>
</body>


위와 같이 class 이름이 rm인 ul이 사라진 것을 볼 수 있습니다.




02. remove 함수 응용

이를 특정 id 값을 지정해주어 해당 요소 내부에 있는 값들만을 제거하고 싶을 때가 있을 것입니다.

이때의 예제는 다음과 같습니다.


예제 소스

<script>
	function TestList()
	{
		//$("test_list").remove(); // div 자체를 삭제하기 때문에 사용하지 않음
		$("test_list *").remove(); // div 아래에 있는 태그들만 삭제함
	}
</script>

<div id="test_list">
    <li> It is Test </li>
    <li> It is Test </li>
    <li> It is Test </li>
</div>


위의 예제 소스에서 TestList 함수를 실행시키면 다음과 같은 결과값으로 HTML이 변경됩니다.


결과

<div id="test_list"></div>






01. append 함수

문법

.append( content [, content ] )


append 함수는 선택한 요소의 내용의 끝에 새로운 콘텐츠를 추가할 수 있습니다.


예제 소스

<html lang="ko">
  <head>
    <title>kkamikoon javascript</title>
    <script>
      $( document ).ready( function() {
        $( 'ul' ).append( '<li>Test3</li>' );
      } );
    </script>
  </head>
  <body>
    <ul>
      <li>Test1</li>
      <li>Test2</li>
    </ul>
  </body>
</html>


결과

  <body>
    <ul>
      <li>Test1</li>
      <li>Test2</li>
      <li>Test3</li>
    </ul>
  </body>


위와 같이 Test3의 태그가 하나 추가되는 것을 볼 수 있습니다.




02. append 함수 응용

이를 특정 id 값을 지정해주어 해당 요소에 값을 추가해줄 수 있습니다.

예제는 다음과 같습니다.


예제 소스

<script>
	function TestList()
	{
		var tmp = "";
		tmp = tmp + "<li> It is Test </li>"
		
		$("test_list").append(tmp);
	}
</script>

<div id="test_list"></div>


위의 예제 소스에서 TestList 함수를 실행시키면 다음과 같은 결과값으로 HTML이 변경됩니다.


결과

<!--한 번 수행됐을 때-->
<div id="test_list"><li> It is Test </li></div>
<!--여러 번 수행됐을 때-->
<div id="test_list"><li> It is Test </li><li> It is Test </li><li> It is Test </li></div>






Python Flask 혹은 Django를 사용하게 되면 HTML에 Jinja2 문법을 사용하여 추가적인 작업을 수행할 수 있습니다.

여기서 Jinja2의 리스트, 그러니까 배열을 사용하는 방법을 알아보도록 하겠습니다.


Jinja2를 사용할 때 HTML 소스코드 내부에 다음과 같은 for문을 작성했다고 합시다.


배열은 ['1', '2', '3']이라고 가정합시다.


예제 소스

{% for item in mylist %}
   <p> your item is : {{ item }} </p>
{% endfor %}


위와 같이 코드를 작성했을 때 <p>로 작성된 배열 목록들이 쭈루룩 출력될 것입니다.


결과

your item is : 1
your item is : 2
your item is : 3


이는 다음과 같은 예제도 똑같이 나타나게 됩니다.


예제 소스

<p> your item is : {{ mylist[0] }} </p>
<p> your item is : {{ mylist[1] }} </p>
<p> your item is : {{ mylist[2] }} </p>


결과

your item is 1
your item is 2
your item is 3


이처럼 배열의 index 값을 설정해서 사용해줄 수 있습니다.


만약 세 번째 아이템만 출력하고 싶다면 다음과 같은 예제처럼 하면 됩니다.


예제 소스

{% for item in mylist %}
   {% if loop.index == 2 %}
   <p> your item is : {{ item }} </p>
   {% endif %}
{% endfor %}


결과

your item is 3

jinja2에서 for문의 인덱스 값은 다른 선언 없이 loop.index라고 작성하면 됩니다.




'WEB PROGRAMMING > Jinja2' 카테고리의 다른 글

[Jinja2] For 문 사용하는 방법  (0) 2019.02.19
[Jinja2] break문 사용하는 방법  (0) 2019.02.12

Javascript를 이용하여 선택한 요소(element)의 속성(attribute) 값을 설정할 수 있습니다.

먼저 문법 먼저 알아보도록 하겠습니다.(절대 다음과 같이 똑같이 코드를 작성한다고 동작하지는 않습니다.)


01. setAttribute 함수

문법

element.setAttribute('attribute_name', 'attribute_value');


element를 선택하여 setAttribute 함수를 실행할 때 우리가 설정하고자 하는 attribute_name(속성 이름)과 attribute_value(속성 값)을 넣어줘야 합니다.


예제 소스코드

document.getElementById('id_value').setAttribute('title', 'It is kkamikoon Title');


위의 예제 소스코드를 살펴보시면 getElementById() 함수를 통해 'id_value'를 가지고 있는 요소를 가져옵니다.

그리고 setAttribute() 함수를 통해 'title' 이라는 이름에 'It is kkamikoon Title'이라는 값을 넣어줍니다.


보다 자세한 예시로 살펴보도록 합시다.



02. setAttribute 함수 응용 예제

만약 id 값이 test인 요소에 href 속성 값을 변경하는 소스코드는 다음과 같습니다.

<html lang="ko">
  <head>
    <title>JavaScript - kkamikoon | .setAttribute()</title>
  </head>
  <body>
    <p><a id="test" target="_blank">kkamikoon main page</a></p>
    <script>
      document.getElementById( 'test' ).setAttribute( 'href', 'https://kkamikoon.tistory.com' );
    </script>
  </body>
</html>

 

결과

kkamikoon main page





자바스크립트에서 변수를 선언할 때 var, let, const 형태로 선언할 수 있습니다.


varfunction-scoped라고 함

let, constblock-scoped라고 함


여기서 function-scoped와 block-scoped가 무엇일까 알아보니 다음과 같은 내용을 볼 수 있었습니다.


01. var (function-scoped)

// var는 function-scope이기 때문에 for문이 끝난다음에 i를 호출하면 값이 출력이 잘 됨
// 이건 var가 hoisting이 되었기 때문이다.
for(var j=0; j<10; j++) {
  console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10


// 아래의 경우에는 에러가 발생한다.
function counter () {
  for(var i=0; i<10; i++) {
    console.log('i', i)
  }
}
counter()
console.log('after loop i is', i) // ReferenceError: i is not defined


여기서 hoisting이라는 말이 나오는데.. (처음에 hosting이라고 착각함 ㅎㅎ....)

이건 또 무슨 말이고 하니.. 요약하자면 "후선언된 변수나, 함수들이 해당 Scope에서 최상위에 위치하는 걸 뜻함"이라고 합니다.

대충 선언 부분이 잘못되도 자바스크립트에서는 이를 올바르게 코딩된 것처럼 인식한다는 뜻인데, 이는 다음 포스트에서 다루도록 하겠습니다.


위에서 나타난 에러처럼 ReferenceError 즉, 선언이 안 되었다는 에러가 나타납니다.

간단히 이해하기 위해 다음과 같이 코드를 바꿀 수 있습니다.


// var는 function-scope이기 때문에 for문이 끝난다음에 i를 호출하면 값이 출력이 잘 됨
// 이건 var가 hoisting이 되었기 때문이다.
var j=0;
for(j=0; j<10; j++) {
  console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10


// 아래의 경우에는 에러가 발생한다.
function counter () {
  var i=0;
  for(i=0; i<10; i++) {
    console.log('i', i)
  }
}
counter()
console.log('after loop i is', i) // ReferenceError: i is not defined
//--> i는 counter 함수의 지역변수이기 때문임


위와 같이 지역변수의 느낌으로 이해하면 쉽게 와닿을 수 있습니다.


자바스크립트에서는 immediately-invoked function expression( or IIFE, pronounced "iffy")라는 것이 있다고 합니다..

무슨 말인지 알아먹기 힘든 영어로 되어있지만 예시를 통해 알아보도록 합시다.


다음은 IIFE로 function-scope처럼 만들 수 있는 예시입니다.


IIFE function-scope 예시(1)

// IIFE를 사용하면
// i is not defined가 뜬다.
(function() {
  // var 변수는 여기까지 hoisting이 된다.
  for(var i=0; i<10; i++) {
    console.log('i', i)
  }
})()
console.log('after loop i is', i) // ReferenceError: i is not defined


위의 소스코드를 보면 소괄호로 묶어 마치 하나의 함수처럼 만들어준 것처럼 보입니다.

hoisting이 되는 위치도 웃긴 게, function 내부에 되어버리게 되어, 결국 function 밖에서 실행할 때 사용되는 i의 값은 undefined 변수가 되어버리게 됩니다.

에러가 나지 않도록 작성한 코드는 다음과 같습니다.


IIFE function-scope 예시(2) - hoisting

// 이 코드를 실행하면 에러없이 after loop i is 10이 호출된다.
(function() {
  for(i=0; i<10; i++) {
    console.log('i', i)
  }
})()
console.log('after loop i is', i) // after loop i is 10


위의 소스코드가 에러가 나지 않는 이뉴는 i를 function 내에서 다시 재정의하지 않아서 hoisting이 이루어졌다는 의미입니다.

즉, i 함수는 function 밖에서 선언된 전역(global) 변수라는 것입니다.


이러한 hoisting을 방지하기 위해서는 use strict라는 것을 사용할 수 있습니다.

밖에서 사용한 전역변수가 함수 내에서 hoisting 되지 않도록 방지하는 것입니다.


IIFE function-scope 예시(2) - use strict

// 아까랑 다르게 실행하면 i is not defined라는 에러가 발생한다.
var i;
(function() {
  'use strict'
  for(i=0; i<10; i++) {
    console.log('i', i)
  }
})()
console.log('after loop i is', i) // ReferenceError: i is not defined


위의 소스코드는 밖에서 선언된 var i의 값이 hoisting되지 않았기 때문에, i의 값에는 아무런 값이 들어가 있지 않습니다.

따라서 정상적으로 에러를 출력하는 걸 볼 수 있습니다.


변수 하나에 너무나 많은 고민이 들어가게 됩니다. 허허...

이러한 수고를 덜어주기 위해 등장한 것이 바로 let과 const라고 할 수 있습니다.


02. let, const (block-scoped)

자바스크립트에는 var만 존재했을 때 다음과 같은 문제가 있었다고 합니다.

// 이미 만들어진 변수이름으로 재선언했는데 아무런 문제가 발생하지 않는다.
var a = 'test'
var a = 'test2'

// hoisting으로 인해 ReferenceError에러가 안난다.
c = 'test'
var c


위와 같은 문제점으로 인해 자바스크립트를 욕하는 사람이 많았다고 합니다.. ㅎㅎ

하지만 let과 const를 사용하면 var를 사용할 때보다 훨씬 편리하게 코드를 작성할 수 있게 되었다고 합니다.


이 두 가지 형태는 변수의 재선언이 불가능하다는 공통점이 있습니다.(마치 C언어의 #define과 const의 느낌이 아닐까 싶습니다.)


let은 변수에 재할당이 가능하지만, const는 재선언, 재할당이 모두 불가능합니다.


// let
let a = 'test'
let a = 'test2' // Uncaught SyntaxError: Identifier 'a' has already been declared
a = 'test3'     // 가능

// const
const b = 'test'
const b = 'test2' // Uncaught SyntaxError: Identifier 'a' has already been declared
b = 'test3'    // 불가능 Uncaught TypeError:Assignment to constant variable.


이때 let과 const에 hoisting이 발생하지 않는 건 아닙니다.

만약 var가 function-scoped로 hoisting 되었다면 let과 const는 block-scoped로 hoisting이 일어나게 됩니다.


d = "test"
var d; // hoisting이 되어 에러가 나지 않음

/* javascript가 인식할 때 다음과 같이 인식됨
var d;
d = "test";
자기 알아서 순서가 바뀐 채로 인식됨 ㄷㄷ*/

c = 'test' // ReferenceError: c is not defined
let c;


c가 에러가 나는 이유는 let의 특징인 tdz(temporal dead zone) 때문입니다.

이는 let으로 선언된 변수는 값을 할당하기 전에 변수가 먼저 선언되어 있어야 합니다.(위의 4 ~ 6번째 라인과 같은 hoisting이 일어나지 않음)


이는 const도 예외가 아닙니다. 단지 let보다 좀 더 업격할 뿐...


// let은 선언하고 나중에 값을 할당이 가능하지만
let dd
dd = 'test'

// const 선언과 동시에 값을 할당 해야한다.
const aa // Missing initializer in const declaration


자바스크립트에 tdz와 같은 기능이 필요한 이유는 동적언어이다보니 runtime type check가 필요해서라고 합니다.




+ Recent posts