기본 콘텐츠로 건너뛰기

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 로도 바꿔도 보고 어떻게 다른지 관찰하면 더욱 좋겠다.

이 블로그의 인기 게시물

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가 잘 나온다.
여기서부터 시작하는게 좋아보인다.

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 …

MQTT 접속해제 - LWT(Last will and testament)

통신에서 중요하지만 구현이 까다로운 문제로 "상대방이 예상치 못한 상황으로 인하여 접속이 끊어졌을때"의 처리가 있다.

이것이 까다로운 이유는 상대방이 의도적으로 접속을 종료한 경우는 접속 종료 직전에 자신의 종료 여부를 알리고 나갈 수 있지만 프로그램 오류/네트웍 연결 강제 종료와 같은 의도치 않은 상황에선 자신의 종료를 알릴 수 있는 방법 자체가 없기 때문이다.
그래서 전통적 방식으로는 자신의 생존 여부를 계속 ping을 통해 서버가 물어보고 timeout 시간안에 pong이 안올 경우 서버에서 접속 종료를 인식하는 번거로운 방식을 취하는데

MQTT의 경우 subscribe 시점에서 자신이 접속 종료가 되었을 때 특정 topic으로 지정한 메시지를 보내도록 미리 설정할 수 있다.
이를 LWT(Last will and testament) 라고 한다. 선언을 먼저하고 브로커가 처리하게 하는 방식인 것이다.

Last Will And Testament 라는 말 자체도 흥미롭다.
법률용어인데 http://www.investopedia.com/terms/l/last-will-and-testament.asp
대략 내가 죽으면 뒷산 xx평은 작은 아들에게 물려주고 어쩌고 하는 상속 문서 같은 내용이다.

즉, 내가 죽었을(연결이 끊어졌을) 때에 변호사(MQTT Broker - ex. mosquitto/mosca/rabbitMQ등)로 하여금 나의 유언(메시지)를 상속자(해당 토픽에 가입한 subscriber)에게 전달한다라는 의미가 된다.

MQTT Client 가 있다면 한번 실습해보자.
여러가지가 있겠지만 다른 글에서처럼 https://www.npmjs.com/package/mqtt 을 사용하도록 한다.

npm install mqtt --save 로 설치해도 되고 내 경우는 자주 사용하는 편이어서 npm install -g mqtt 로 전역설치를 했다.

호스트는 무료 제공하고 있는 test.mosquitto.org 를 사용한다.
실 사용시엔 -h 옵션을 …