반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함


두개의 select 메뉴가 있는 상황에서 두번째의 select menu 내용이 첫번째 select menu 에 따라 동적으로 종속되는 기능이 있는 샘플 소스를 분석해 보겠습니다.

잘 알아 두면 실무에서 유용하게 사용할 수 있을 것 같네요.

우선 소스 부터 보겠습니다.


<!DOCTYPE html>
<html>
  <head>
    <title>Cascading Selects</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
   
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0rc1/jquery.mobile-1.0rc1.min.css" />
    <script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.0rc1/jquery.mobile-1.0rc1.min.js"></script>
    <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
    <script id="childrenTemplate" type="text/x-jquery-tmpl">
      <option value="${k}">${v}</option>
    </script>

    <script>
      var childrenHash = {};
      childrenHash['1'] = [{k: 1, v: "1st child of parent 1"},
                           {k: 2, v: "2nd child of parent 1"}];
      childrenHash['2'] = [{k: 3, v: "1st child of parent 2"},
                           {k: 4, v: "2nd child of parent 2"},
                           {k: 5, v: "3rd child of parent 2"}];
   
      var refreshChildrenSelect = function(parentKey) {
        var children = $('#children');
        children.empty();
       
        $('#childrenTemplate')
          .tmpl(childrenHash[parentKey])
          .appendTo(children);
       
        children.selectmenu('refresh');
      };

      $('#mypage').live('pageinit',function(event) {
        refreshChildrenSelect($('#parent').val());
       
        $('#parent').bind('change', function(event) {
          refreshChildrenSelect($('#parent').val());
        });
      });

    </script>   
  </head>
  <body>
    <div id="mypage" data-role="page">
      <div data-role="header">
        <h1>
          Cascading Selects
        </h1>
      </div>
      <div data-role="content">
        <form>
          <div data-role="fieldcontain">
            <label for="parent">Parent</label>
            <select id="parent" name="parent" data-native-menu="false">
              <option value="1">parent 1</option>
              <option value="2">parent 2</option>
            </select>
          </div>
         
         <div data-role="fieldcontain">
            <label for="children">Children</label>
            <select id="children" name="children" data-native-menu="false">
            </select>
          </div>
        </form>
      </div>
    </div>
  </body>
</html>





이번엔 우선 body 부터 볼까요?

data-role="page" 가 하나 있는 걸로 봐서 이 페이지는 하나짜리 페이지 입니다. 이 파일 내에서의 화면 이동이 없겠네요.

그 다음에 data-role="hearder" 로 페이지 제목을 정해 줬구요.
다음에 data-role="content" 가 왔습니다. 헤더 아래 부분 즉 이 페이지에서 표시될 주요 내용들이죠.


form은 html 태그이구요. 그 다음에 data-role="fieldcontain" 이 선언 됐네요.
실제 예제에서는 이 fieldcontain이 자주 나오는 군요. 시간 내서 숙지해 둬야겠어요.
그 다음에는 첫번째 select form 이 나오는데 제목이 Parent 이고 안의 옵션들은 parent 1, parent 2 이렇게 두가지가 있습니다.

그 다음에 두번째 fieldcontain 이 나오구요. 또 select 메뉴가 나오네요.

이 body 안에는 id 가 첫번째 select 메뉴에 parent로 주어졌고 두번째 select menu에 children으로 주어 졌습니다. 이 두 id 가지고 위의 자바스크립트에서 지지고 볶고 할 거예요.

이제 자바스크립트 쪽을 보겠습니다.

여기서는 $(document).ready(function() {} 같은거 안 썼네요.
뭐 그거 안써도 함수 안에 집어 넣지 않으면 페이지가 로딩될 때 다 실행 될테니까 이 경우에는 상관 없습니다.

childrenHash 라는 배열을 선언했습니다. 지난 글의 myArray 처럼 [] 가 아니라 {} 입니다. 자바스크립트에서는 이중 배열을 쓸 때는 {}를 쓰나요? 둘의 차이를 정확히는 모르겠습니다.
아시는 분 알려 주세요.

이 배열의 첫번째에는 두개의 인자가 들어갔고 두번째 배열에는 세개의 인자들이 들어갔습니다.

그 다음은 refreshChildrenSelect() 라는 함수가 선언됐는데요.

이렇게 함수가 선언되면 자동적으로 실행되는게 아니라 어디에선거 이 함수를 call 해줘야 실행 됩니다.


그 내용을 볼까요?

children 이라는 변수에 아래 두번째 select 메뉴의 아이디인 #children을 넣었습니다.
이 두번째 select에 뭔가를 넣을 건가 봅니다.
그리고 나서 children 변수를 비웠네요. 이 empty() 메소드도 jQuery 메소드이네요.

이건 간단한 거니까 이 글 끝에 예제 복사해 넣어서 나중에 참조해야겠습니다.
아주 간단한 기능이네요.

그 다음은 #childrenTemplate 가 나옵니다. 이것은 지난 번 봤던 jQuery 템플렛입니다.

<option> 태그를 만들어 주는 탬플릿이네요.
childrenHash[] 에 전달받은 매개변수 parentKey를 가지고 아까 childrenHash에서 정해 놨던 1이나 2 를 가져와서 children에 집어 넣는 겁니다.
이 children은 아까 #children을 대입하고 나서 empty() 시켰던 변수죠.
여기에 childrenHash[1] 아니면 childrenHash[2] 가 들어가 있겠네요.

그 다음에 children.selectmenu('refresh'); 로 children select 메뉴를 refresh 했습니다.

여기까지가 parentKey를 받아서 거기에 맞는 childrenHash를 가져와서 body 내에 있는 children select menu에 넣고 refresh 하는 refreshChildrenSelect 함수 내용입니다.


그 다음엔 여러번 봤던 .live 함수가 나오네요.
자세히 분석하지는 않았지만 자주 보니까 웬지 잘 아는 함수 같네요.
여기서는 click event가 아니라 pageinit event 일 경우 이 함수를 실행합니다.
처음에 .ready() 함수를 안 썼는데 여기서는 pageinit 이벤트에서 이 함수를 실행하도록 하면서 처리 했나봅니다.

그렇게 되면 refreshChildrenSelect 메뉴에 현재의 parent value를 매개변수로 전달하면서 call 하게 됩니다. .val() 메소드가 나오네요. 못 보던거니까 일 단 샘플 복사해 넣고 간단하게 분석하고 넘어가겠습니다.


이 소스에서는 이 .val() 부분이 없으면 최초 페이지 로딩할 때 children select menu 에 아무런 value가 없게 됩니다. 그러니까 최초 페이지 로딩이 일어 났을 때 children select menu를 채워주는 일을 하는 곳입니다.

그 다음엔 bind를 사용해서 뭔가 변화가 일어 났을 때 그러니까 parent select menu에 변화가 일어 났을 때 동적으로 child select menu 의 value 값들을 변화시켜 주는 부분 입니다.

처음 보는 메소드들이 몇개 있어서 한번에 해석하지 못하고 약간 멈칫했습니다.

첫번째 것은 .empty() 인데 이건 사실 이름만 보면 알수 있는 거라서 멈칫까지도 안했던 거네요.


<!DOCTYPE html>
<html>
<head>
 
<style>
  p
{ background:yellow; }
</style>
 
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
 
<p>
  Hello,
<span>Person</span> <a href="javascript:;">and person</a>
</p>

<button>Call empty() on above paragraph</button>
<script>
  $
("button").click(function () {
    $
("p").empty();
 
});
</script>

</body>
</html>


예제도 간단해서 이해하기 쉽습니다. 해당 내용을 지워주는 거죠?

두번째 .val() 부분이 좀 멈칫거리게 만들었어요.


<!DOCTYPE html>
<html>
<head>
 
<style>

  p
{ color:blue; margin:8px; }
 
</style>
 
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
 
<input type="text" value="some text"/>
 
<p></p>
<script>
    $
("input").keyup(function () {
     
var value = $(this).val();
      $
("p").text(value);
   
}).keyup();
</script>

</body>
</html>


이건 해당 값을 넣는 거군요.

.html() 이랑 .text() 랑 비슷한거 아닌가 모르겠네요.

.html()은 태그까지 들어가고 .text()는 문자만 들어가는데. .val() 는 select 메뉴의 실제 value 값을 받아오는 것 같습니다.

오늘도 새로운거 몇개 배웠습니다.

have a nice weekend!


반응형

Comment