기본 콘텐츠로 건너뛰기

tutorial - radio button을 이용한 tree 구조 만들기

http://jsbin.com/cikuga/edit?html,css,output

IE 호환을 위해 jQuery를 사용했다. 안해도 되지만 이 편이 그래도 좀 읽기 쉽지 않나 싶다.
접히고 펼쳐지는 트리구조를 만드는 데 있어 핵심 아이디어는 같은 깊이에 인접한(sibling ) 요소들끼리는 radio button을 사용하면 된다는 것이다.

가령

<input type="radio" name="group1">
<input type="radio" name="group1">
<input type="radio" name="group1">

이렇게 했을 경우 같은 이름(name)을 가지고 있으므로 셋 중 하나만 radio 버튼이 들어오고

<input type="radio" name="group1">
<input type="radio" name="group2">
<input type="radio" name="group2">
<input type="radio" name="group2">

<input type="radio" name="group1">
<input type="radio" name="group1">

이와 같이 구성하면 group2는 group2끼리 group1은 group1끼리 각각 구성할 수 있다.
따라서 각각의 radio button에 대한 id가

1
  1-1
  1-2
2
  2-1
    2-1-1
    2-1-2
3

일 경우엔 1,2,3을 top
1-1, 1-2는 1
2-1은 2
2-1-1, 2-1-2는 2-1 같이 name을 지정해주면 된다.

여기서 label의 for와 input의 id를 맞춰주면 label을 클릭해도 radio가 켜지니 같이 묶어주자.
    <input type="radio" name="top" id="r1">
    <label for="r1">Title of Tab 1</label>
이런 식이면 충분.
전체적으로 구성을 해보자. 하위 아이템도 있고 그게 링크인 경우도 있을 수 있다.

<ol class="acc">
  <li>
    <input type="radio" name="top" id="r1">
    <label for="r1">Title of Tab 1</label>
    <ol class="tab-content">
      <li>
        <input type="radio" name="t-1" id="r1-1">
        <label for="r1-1">Title of Tab 1</label>
        <div class="tab-content">
          cascaded!
        </div>
      </li>
      <li>
        <input type="radio" name="t-1" id="r1-2">
        <label for="r1-2">Title of Tab 1</label>
        <div class="tab-content">
          cascaded!
        </div>
      </li>
    </ol>
  </li>
  <li>
    <input type="radio" name="top" id="r2">
    <label for="r2">Title of Tab 1</label>
    <ol class="tab-content">
      <li>
        <a href="#">link</a>
      </li>
      <li>
        <a href="#">link</a>
      </li>
    </ol>
  </li>
  <li>
    <input type="radio" name="top" id="r3">
    <label for="r3">Title of Tab 1</label>
    <div class="tab-content">
      Some content....
    </div>
  </li>
</ol>

이와 같이 구성해보았다.

실제 렌더링은 아마도 이럴 것이다.
Label을 눌러도 radio가 잘 작동하는지 꼭 보자.

이제 CSS로 스타일링을 할 시간이다.
Label을 눌러도 되니 radio 버튼은 안봐도 된다.
input[type=radio] {
  display: none;
}
숨기자.
그리고 대신 + 표시를 달아주자.
label:before {
  content: "+";
  position: relative;
  left: -2em;
}
label 위치보다 2글자 왼쪽에 content를 사용해서 "+"를 넣어줬다.
상대좌표니까 position을 relative로 하자.
이미지를 넣으려면 content: url(xxx.png) 식으로 지정하면 된다.

닫혀 있을 때 상태는 .tab-content 아래에 넣어서 숨기도록 한다.
.tab-content {
  display: none;
}
이걸로 닫힌 상태는 완성.

다음은 펼친 상태를 구현할 차례인데
"라디오 버튼이 checked 일때 인접한 .tab-content가 보이도록"
하면 된다.
그리고 label:before 에 있던 + 도 - 로 바꿔주면 좋겠다.
input:checked + label:before {
  content: "-";
}
input이 checked일때 + (바로 뒤에 인접한) label:before 의 content를 - 로 지정한다.
마찬가지로,
input이 checked일때 ~ (sibling이면서 뒤쪽 어딘가에 있는) display: none이던 .tab-content도 보이게 하자.
input:checked ~ .tab-content {
  display: block;
}
간단?
이것만으로도 OK.

label:before 를 선택할 때 +대신 ~로 써도 되는거 아녀요? 라고 물어보면
그렇다! 라고 말할 수 있다. ~는 +를 포함하니 상관없다.

여기까지만이면 좋겠는데 선택해서 펼쳐진 상태에서 label을 또 클릭하면 닫게 하고 싶을 수 있다.
이건 CSS만으론 어렵고 약간 코드가 필요하다.
  var selectedItemId = undefined;
  $('input', handler).click(function(e) {
    var t=e.target;
    if (t.id === selectedItemId) {
      t.checked = undefined;
      selectedItemId = undefined;
    } else {
      selectedItemId = t.id;
    }
  });
radio는 한번 선택을 하면 같은 그룹에서 undefined로 지정하기 전까진 항상 어딘가가 checked인 상태이다.
따라서, 이전에 선택한 radio와 같은 걸 클릭하면 checked를 undefined로 지정한다.
약간 hacky 한 구현이라고 볼 수 있다.

마지막으로 radio 대신 checkbox 로도 바꿔도 보고 어떻게 다른지 관찰하면 더욱 좋겠다.

이 블로그의 인기 게시물

ESP32 DevBoard 개봉기

오늘 드디어 손에 넣었다. ESP32 DevBoard!
Adafruit 에서 15개 한정 재입고 트윗을 보고 광속 결제.
그리고 1주일의 기다림. 사랑해요 USPS <3
알리를 이용하다보니 1주일 정도는 광속 배송임.
물론 배송비도 무자비함 -_ㅜ
15개 한정판 adafruit 발 dev board
그놈이 틀림없으렸다.
오오 강려크한 포스
ESP32_Core_board_V2라고 적혀있군요.
ESP32 맞구요. 네네. ESP32-D0WDQ6 라고 써있는데 D → Dual-core 0 → No internal flash W → Wi-Fi D → Dual-mode Bluetooth Q → Quad Flat No-leads (QFN) package 6 → 6 mm × 6 mm package body size 라고 함.
길이는 이정도
모듈크기는 이정도
코어는 6mm밖에 안해! 여기에 전기만 넣으면 BLE+WIFI!
밑에 크고 발 8개 달린 놈은 FM25Q32라고 32Mbit 플래시메모리
ESP8266 DevBoard 동생이랑 비교 크고 아름다운 레귤레이터랑 CP2102 USB Driver가 붙어있음.
ESP8266 DevBoard엔 CH340G 인데 확 작아졌네.
머리를 맞대어 보았음.
모듈크기는 아주 약간 ESP32가 더 큰데 워낙에 핀이 많고 촘촘함. ESP8266인 ESP12는 핀 간격이 2.00mm인데 비해
ESP32는 1.27mm 밖에 안함.
딱봐도 비교가 될 정도.
https://www.sparkfun.com/news/2017 크고 아름다운 Pinouts

ESP8266 보드랑 별로 안달라보인다.
http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx#mac
에서 CP2102 드라이버를 설치하고
screen 으로 연결해보자.
내 경우엔 tty.SLAB_USBtoUART 로 잡혔다.
어디서 기본 속도가 115200bps 라고 들은 적이 있어서
screen /dev/tty.SLAB_USBtoUART …

Rinkeby Test Network에 접근하는 간단한 방법.

dApp 개발 시 실제 계정으로 트랜젝션을 보내면 너무나 비싸므로
Rinkeby나 Ropsten 같은 테스트 네트워크에 연결하여 마이닝 없이 faucet을 통해 ether를 받고
그걸로 트랜젝션 테스트를 하면 편리하다.

보통 https://github.com/ethereum/wiki/wiki/Dapp-using-Meteor#create-your-%C3%90app 문서를 보고 시작하는데
geth --rpc --rpccorsdomain "http://localhost:3000" 이렇게 하면 마이닝부터 해야하니 귀찮다.
https://infura.io/#how-to 를 보고 계정을 신청하자. 이런 것도 호스팅이 되다니 좋은 세상이네.
간단한 개인 정보 몇가지를 입력하고 나면 Access Token이 나온다.

가입 후  https://infura.io/register.html 화면

Access Token이 있는 네트워크 주소로 geth를 연결한다.
geth --rpc --rpccorsdomain "https://rinkeby.infura.io/<YOUR_ACCESS_TOKEN>" 이러면 오케이.

meteor project를 만들고
meteor add ethereum:web3 추가한 다음 console에서
web3.eth.getBalance(web3.eth.coinbase, (error,result)=>console.log(
  error, result.toFormat()
)); 자신의 coinbase의 잔액을 구해보자.
6eth가 최소단위인 wei로 보면 6,000,000,000,000,000,000 정도.
https://faucet.rinkeby.io/ 여기에서 받아온 (무료로/마이닝없이) ether가 잘 나온다.
여기서부터 시작하는게 좋아보인다.

meteor로 nw.js 개발하기.

실제로 nw.js 어플리케이션을 개발하다보면 UI구현하기 막막하고 수동으로 리프레쉬 하는 것도 귀찮아서 Meteor 연동을 하려고 했더니 생각보다 간단했다.

디렉토리 구조는 먼저 이렇게 잡았다.
`- app
  `-client
  `-public
`- dist
  `- 배포용 html,css,js
  `- package.json
`- package.json 아이디어는 이렇다. nw.js의 시작페이지를 http://localhost:3000으로 두고 배포시엔 meteor client 배포툴인 meteor-build-client를 사용하여 html,css,js 로 분리하는 계획이다.

가장 중요한 nw.js 용 package.json 파일은 아래와 같이 구성한다.
{
  "main": "http://localhost:3000",
  "node-remote": "http://localhost:3000",
  "name": "<앱이름>"
} 이게 전부. 어떻게 보면 Web과 nw.js를 동시에 개발할 수도 있는 환경이기도 한 것이다.
meteor create app 을 해서 meteor용 앱을 만들고 meteor 를 시작한다.
그리고, 위의 package.json이 있는 경로로 돌아가서 nw . 으로 nwjs를 실행한다.

한번 번쩍하더니 잘 된다.
cordova 등에서 index.html 대신 http://localhost:3000을 하는 것도 비슷한 느낌이다.

즐겁게 개발을 일단 마구 하고 실제로 배포하기 위해서는 개발환경이 아니라 html,css,js로 구성된 배포본을 만들어야한다.
npm install -g 해도 되지만 어짜피 Meteor에서만 쓸거
meteor npm install -g meteor-build-client 해버릴거다.

개발은 문제 없어 보이고 배포판을 한번 만들어보자. meteor app 이 있는 경로(meteor run으로 …