메인 컨텐츠로 가기

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

jQuery를 사용하는 Ajax와 CodeIgniter

효과적이고 사용이 편리한 Web 2.0 인터페이스 작성

Kevin Howard Goldberg, CTO, imagistic
Kevin Howard Goldbeg
With 20 years of experience in the high-tech industry, Kevin Howard Goldberg is a technology executive, author, and consultant residing in Westlake Village, Calif. He currently serves as CTO at imagistic, an award-winning digital marketing and technology company, which he co-founded in 1997. An expert on Web development and technology, he serves on the Santa Monica College Computer Science Advisory Board and held senior positions at Film Roman, Lionsgate, and Philips Interactive Media. He is the author of XML: Visual QuickStart Guide (2nd Edition), (PeachPit Press, 2008). You can reach him at http://kehogo.com/contact.

요약:  jQuery를 사용하여 CodeIgniter 애플리케이션의 유용성을 쉽게 개선하는 방법을 살펴봅니다. CodeIgniter의 MVC 기반 프레임워크와 jQuery의 Ajax(Asynchronous JavaScript and XML) 상호 작용 지원 기능을 활용하여 더욱 효과적인 UI를 신속하고 효율적으로 작성하는 방법을 학습합니다.

원문 게재일:  2010 년 5 월 11 일 번역 게재일:   2010 년 8 월 20 일
난이도:  중급 영어로:  보기 PDF:  A4 and Letter (65KB | 18 pages)Get Adobe® Reader®
페이지뷰:  7433 회
의견:  


CodeIgniter는 널리 사용되는 경량 오프 소스 프레임워크로 PHP로 작성되었으며 MVC(Model-View-Controller) 아키텍처 패턴을 기반으로 한다. jQuery는 신속한 경량 오픈소스 Javascript 라이브러리로 HTML 페이지와 Ajax 상호 작용을 처리하는 과정을 단순하게 하기 위해 디자인되었다. 이 두 가지 도구를 함께 사용하면 유용한 웹 사이트와 애플리케이션을 신속하게 개발할 수 있는 강력한 기반을 구축할 수 있다.

DB2 Express 9 데이터베이스 서버 무료 버전을 사용해 보도록 하자.

DB2 Express-C는 신속하게 실행할 수 있도록 설계되어 있으며 사용이 쉽고 임베드하기가 용이하며 자체적인 관리 기능이 있다. 또한, pureXML™과 같은 DB2 for Linux, UNIX, and Windows의 핵심 기능을 모두 갖추고 있다. DB2 Express-C는 다른 DB2 Express 에디션과 동일한 핵심 데이터 서버 기반을 제공하며 또한, C/C++, Java™, .NET®, PHP, Ruby on Rails, Python과 같은 프로그래밍 언어를 사용하여 개발된 애플리케이션을 빌드하여 전개할 수 있는 완전한 기반을 제공한다.

이 기사에서는 이러한 두 시스템을 하나의 프레임워크에 통합하는 방법과 jQuery를 사용하여 기존 웹 애플리케이션의 UI를 개선하는 방법을 살펴본다. 독자가 CodeIgniter 버전 1.7.2 이상, MySQL 버전 4.1 이상을 설치했으며 이 두 가지 도구를 사용하는 데 익숙하다고 가정한다. 또한, jQuery 라이브러리 버전 1.4.2 이상이 필요하다. CodeIgniter를 처음 사용하거나 이와 관련된 내용을 신속하게 다시 살펴보고자 하는 경우에는 참고자료에 있는 링크를 통해 자세한 정보를 확인하도록 한다.

Web 2.0: jQuery를 이용한 Ajax 사용

Web 2.0의 가장 중요한 특성 중 하나는 사용자 경험이 웹 사이트보다는 데스크탑 애플리케이션에 가깝다는 점이다. 특히, 웹 페이지와 상호 작용하기 위해 웹 서버와 "시각적인 통신"(예를 들면, 제출 단추를 클릭하고 웹 서버가 제출된 정보를 처리하기를 기다리면 전체 웹 페이지가 업데이트된 내용으로 새로 고쳐짐)을 할 필요가 없다. 그 대신 변경해야 하는 내용만 업데이트되고 나머지 페이지는 그대로 유지된다.

이러한 "제출 과정이 적은(submission-less)" 프로세스는 Ajax를 사용하여 처리하며 이렇게 함으로써 웹 페이지를 새로 고치지 않고도 웹 개발자는 웹 클라이언트(브라우저)와 웹 서버 간에 정보를 전송할 수 있게 된다. 더 좋은 점은 사용자가 직접 개입하지 않고도 이러한 정보 전달을 트리거할 수 있다는 점이다.

웹 페이지에서 Ajax를 사용하는 경우에는 웹 서버와 웹 페이지 간의 데이터 통신(송신 및 수신)이 비동기적으로 수행된다. 이러한 전송 데이터는 일반 텍스트이기 때문에 XML, HTML, JSON 또는 일반 텍스트와 같은 다양한 형식이 될 수 있다.

데이터는 실제로 XMLHttpRequest라고 하는 API 호출과 Javascript를 사용하여 전송되며 이 과정에서 jQuery가 중요해진다. jQuery 라이브러리에는 Ajax 사용과 관련된 매우 단순화된 프로세스가 있다. 그리고 이 라이브러리를 이용하면 Ajax를 더욱 쉽게 사용할 수 있을 뿐만 아니라 업데이트된 데이터를 표시하기도 훨씬 더 수월하다. (Javascript를 사용하여 HTML DOM을 처리한 적이 있다면 이렇게 하는 것이 얼마나 수월한지 진정으로 알 수 있을 것이다.)


기존 CodeIgniter 애플리케이션

이 기사에서는 기존 웹 애플리케이션의 UI를 개선하는 과정을 통해 CodeIgniter와 jQuery를 함께 사용하는 것이 얼마나 단순하고 강력한지 살펴보기로 한다. 이 애플리케이션은 교사가 학급 활동과 이 활동에 참여하는 각 부모를 관리할 수 있게 설계되었다. 교사는 먼저 위원회에서 승인된 옵션 목록에서 학급 활동을 선택하여 각 활동에 맞는 날짜를 스케줄한다. 그러면 부모가 해당 사이트에 등록하여 자신의 아이의 연락처 정보를 입력한다. 부모는 학급 활동 목록을 보고 자신의 참여 레벨(소모품 구입, 준비 과정 참여, 조력, 활동 리더로 봉사)을 선택할 수 있다.

참고: 이 시스템은 어린이 스포츠 팀, YMCA 그룹 등에 쉽게 적용할 수 있다.

이 기사의 내용을 수행하기 위해 이 애플리케이션의 데이터베이스에 이벤트 100개, 부모 5명, 교사 1명을 로드하였다. 부모의 사용자 이름은 parent1, parent2, . . . parent5이다. 교사의 사용자 이름은 teacher이며 모든 암호는 ibm이다. 웹 애플리케이션과 데이터베이스를 다운로드하고 웹 서버에 설정하여 이 과정을 함께 수행하도록 하자. 이 애플리케이션을 수행하려면 CodeIgniter 프레임워크가 서버의 루트에 있어야 한다.


jQuery 설정

jQuery를 사용하려면 먼저 jQuery 라이브러리를 다운로드해야 한다. (관련 링크는 참고자료를 확인한다.) 릴리스된 각 버전에 해당하는 두 개의 파일이 제공된다. 하나는 압축이 해제된 파일이며 다른 하나는 "축소된" 파일(이 파일은 강력하게 압축된 버전이며 로드 속도가 빠르지만 원하더라도 추적할 수 없음)이다. 개발 과정에서는 압축 해제된 버전을 사용하고 프로덕션 상태에서는 축소된 버전을 사용하기를 권장한다.

다음은 jQuery 라이브러리 파일을 웹 서버의 루트에 있는 .assets/js 폴더에 저장한다. 그런 다음, 같은 폴더에 Listing 1에 표시된 것과 같이 새로운 파일 global.js를 작성한다. 이 폴더에 전체 애플리케이션의 Javascript 코드를 저장하게 된다.


Listing 1. jQuery를 사용하여 "Hello World" 표시하기
	
/* Global JavaScript File for working with jQuery library */

// execute when the HTML file's (document object model: DOM) has loaded
$(document).ready(function() {

  alert ('Hello World');
	
});

이 기사에 있는 대부분의 애플리케이션에서는 jQuery 코드의 대부분이 $(document).ready() 함수 안에 존재한다. 이 함수는 HTML 파일의 DOM이 모두 로드된 직후에 자동으로 트리거된다.

애플리케이션이 이러한 두 가지 파일을 모두 로드하도록 Listing 2에서와 같이 ./system/application/views/template.php 파일을 편집한다.


Listing 2. jQuery와 글로벌 Javascript 파일 로드하기
	
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

<link href="/assets/css/screen.css" rel="stylesheet" type="text/css" />

<!--  the following two lines load the jQuery library and JavaScript files -->
<script src="/assets/js/jquery-1.4.2.js" type="text/javascript"></script>
<script src="/assets/js/global.js" type="text/javascript"></script>

<title><?php echo $title;?></title>
</head>

이제, 웹 사이트의 색인 페이지를 탐색한다. 웹 페이지가 로드되면 Javascript 경보를 통해 "Hello World"가 표시된다.


CodeIgniter 프레임워크에서 jQuery와 Ajax 사용하기

jQuery 라이브러리와 global.js 파일이 해당 위치에 저장되어 있으면 애플리케이션 인터페이스를 개선할 준비가 된 것이다. 아직 준비되지 않았으면 잠시 기다렸다가 부모와 교사로 로그인하여 시스템에서 활동이 어떻게 수행되는지 익숙해지도록 한다.

사용자 이름 유효성 검증 자동화하기

먼저 등록 페이지의 UI를 개선하도록 하자. 현재는 사용자 이름이 이미 사용되었는지 여부가 등록 페이지를 제출한 이후에 확인된다. 그러나 Ajax를 사용하면 페이지를 제출하지 않고도 서버측에서 유효성을 검증하여 그 결과를 리턴할 수 있다.

그렇게 하려면 username 필드의 onblur() 이벤트에 코드를 바인드해야 하며 이 이벤트는 사용자의 커서가 필드를 벗어날 때 트리거된다. Listing 3에는 업데이트된 global.js 파일이 표시되어 있다.


Listing 3. 사용자 이름이 이미 등록되었는지 확인하기
	
/* Global JavaScript File for working with jQuery library */

// execute when the HTML file's (document object model: DOM) has loaded
$(document).ready(function() {

  /* USERNAME VALIDATION */
  // use element id=username 
  // bind our function to the element's onblur event
  $('#username').blur(function() {

    // get the value from the username field                              
    var username = $('#username').val();
    
    // Ajax request sent to the CodeIgniter controller "ajax" method "username_taken"
    // post the username field's value
    $.post('/index.php/ajax/username_taken',
      { 'username':username },

      // when the Web server responds to the request
      function(result) {
        // clear any message that may have already been written
        $('#bad_username').replaceWith('');
        
        // if the result is TRUE write a message to the page
        if (result) {
          $('#username').after('<div id="bad_username" style="color:red;">' +
            '<p>(That Username is already taken. Please choose another.)</p></div>');
        }
      }
    );
  });  

});

jQuery의 $

jQuery에서 달러 부호($)는 실제로는 새로운 jQuery 오브젝트를 작성하는 데 사용되는 별명이다. 그러므로 Javascript 변수 this는 Javascript 변수로부터 작성되는 jQuery 오브젝트 $(this)와는 다르다. $를 사용하면 앞에 $를 사용한 변수에 익숙한 PHP 개발자에게 특히 혼동을 줄 수 있다. 코드에 문제가 발생하면 $를 사용했는지 확인하도록 한다.

이 코드에서는 ID가 username인 DOM 요소를 사용하여 jQuery 오브젝트를 작성한다. 그런 다음, jQuery blur() 메소드를 호출하며 이 메소드는 username 필드의 onblur() 이벤트에 함수를 바인드한다. 이 함수는 Ajax를 사용하여 username 필드의 값을 CodeIgniter 제어기(ajax)와 메소드 username_taken에 전송한다. 그러면 기존의 오류 메시지는 모두 지워지며 Ajax 포스트 결과에 따라 오류 메시지가 표시되거나 그렇지 않게 된다.

다음은 ./system/application/controllers에서 ajax.php 파일을 작성한다. 이 파일은 jQuery Ajax .post() 메소드에서 참조한다. Listing 4에는 이 제어기의 소스 코드가 표시되어 있다. (이 제어기의 이름을 ajax로 지정한 데는 특별한 이유가 없다. .post() 메소드에 있는 URL이 올바른 제어기를 참조하는 한, 이름은 어떻게 지정하든 관계가 없다.)


Listing 4. Ajax 요청을 처리하는 CodeIgniter 제어기
	
<?php

class Ajax extends Controller {

  public function Ajax() {
  
    parent::Controller(); 
  }

  public function username_taken()
  {
    $this->load->model('MUser', '', TRUE);
    $username = trim($_POST['username']);
    // if the username exists return a 1 indicating true
    if ($this->MUser->username_exists($username)) {
      echo '1';
    }
  }

}

/* End of file ajax.php */
/* Location: ./system/application/controllers/ajax.php */

username_taken() 메소드는 값을 리턴하지 않는다. 이 메소드는 오히려 응답을 반향하는데 이점이 중요하다고 할 수 있다. jQuery Ajax 요청은 웹 페이지에 데이터를 포스트하고 그 결과로 생성된 페이지 데이터를 사용하지 프로그램을 통해 메소드 자체에 접근하지는 않는다.

이제 첫 번째 Ajax 함수가 완료되었다. 등록 페이지를 탐색하고 이미 입력된 사용자 이름으로 등록하여 해당 오류 메시지를 확인한다.

흥미롭게도 jQuery 코드의 결과는 작성할 때 의도했던 것과는 다른 결과가 나온다. Ajax 함수는 ID가 username인 필드에 바인드되어 Login 페이지에 username 필드를 삽입한다. Listing 5에는 jQuery 오브젝트를 수정하여 registration_form 양식 내에 있는 username 필드에만 바인드되도록 하는 방법이 표시되어 있다.


Listing 5. username 필드의 유효성 검증
	
  /* USERNAME VALIDATION */
  // use element id=username within the element id=registration_form
  // bind our function to the element's onblur event
  $('#registration_form').find('#username').blur(function() {

원활한 상태 업데이트 및 저장

다음에는 Class Activity Listing 페이지의 UI를 개선한다. 특정 활동에 참여를 표시할 부모는 해당 단일 선택 단추를 클릭한 후, save 링크를 클릭하여 학급 활동 목록 페이지를 제출한다. UI를 개선하려면 save 링크를 클릭한 다음, 페이지를 제출해야 하는 과정을 제거해야 한다.

먼저 global.js 파일에 다음 코드를 추가한다. 프로세스를 보다 쉽게 설명하기 위해 코드를 Listing 6, Listing 7 및 Listing 8에 나누어 놓았다.


Listing 6. jQuery를 사용하여 관련된 요소 값 가져오기
	
  /* AUTOSAVE PARTICIPATION */
  // use input element name=participation_type_id and type=radio
  // bind our function to the element's onclick event
  $('input[name=participation_type_id]:radio').click(function() {
    
    var participation_type_id = this.value;

    // create global variables for use below
    var class_activity_id, user_id;
    
    // get the form's two hidden input elements 
    // each is a sibling of the parent of the clicked radio button
    // store their values in the global variables
    var hidden_elements = $(this).parent().siblings('input:hidden');
    $(hidden_elements).map(function() {
      if (this.name == 'class_activity_id') {
        class_activity_id = this.value;
      }
      if (this.name == 'user_id') {
        user_id = this.value;
      }
    });

jQuery와 DOM의 계층 구조

jQuery를 사용하면 DOM을 탐색하는 복잡한 과정이 대부분 숨겨지지만 이렇게 한다고 해서 모든 것이 해결되는 것은 아니다. 특히, jQuery를 효과적으로 사용하기 위해서는 문서에 있는 요소의 계층 구조적 관계를 기본적으로 이해해야 한다.

함수는 이름인 participation_type_id인 모든 단일 선택 단추의 onclick() 이벤트에 바인드된다. 이 함수는 클릭한 단일 선택 단추의 값을 가져온다. 그런 다음, 일련의 체인 메소드를 사용하여 숨겨진 양식 요소를 리턴한다. map() 메소드는 자신의 함수를 통해 각 요소를 전달하고 class_activity_iduser_id 값을 검색한다.

부모의 참여를 설정하는 데 필요한 값이 식별되면 코드에서 Listing 7에 표시된 바와 같이 Ajax 요청이 실행되어 이러한 정보가 저장된다. 이 요청에 대한 서버의 응답은 데이터를 반향하지 않으므로 jQuery 응답 함수는 빈 상태가 되며 실제로는 제거된다.


Listing 7. Ajax 요청을 CodeIgniter에 포스트하기
	
    // Ajax request to CodeIgniter controller "ajax" method "update_user_participation"
    // post the user_id, class_activity_id and participation_type_id fields' values
    $.post('/index.php/ajax/update_user_participation',
      { 'user_id':user_id, 
        'class_activity_id':class_activity_id, 
        'participation_type_id':participation_type_id },
      // when the Web server responds to the request
      function(result) { }
    );

마지막으로 jQuery next() 메소드를 사용하여 단일 선택 단추 옆에 있는 텍스트의 색상을 각 문자열을 대상으로 적절하게 변경한다. 이 코드는 Listing 8에 있다.


Listing 8. 동적으로 변경되는 단일 선택 단추 텍스트 색상
	
    // set the text next to the clicked radio button to red
    $(this).next().css("color", "red");

    // set the text next to the remaining radio buttons to black
    var other_r_buttons = $(this).siblings('input[name=participation_type_id]:radio');
    $(other_r_buttons).map(function() {
      $(this).next().css("color", "black");
    });

  });

이제까지 jQuery 코드를 작성했으므로 이제는 Listing 9에서와 같이 ajax 제어기의 update_user_participation() 메소드를 작성해야 한다.


Listing 9. CodeIgniter에서 사용자 참여 처리하기
	
  public function update_user_participation()
  {
    $this->load->model('MActivity', '', TRUE);
    $this->MActivity->set_user_participation($_POST);
  }

이 메소드는 MActivity 모델에서 이미 확인한 set_user_participation() 메소드를 사용하며 이 메소드는 Ajax 요청을 통해 포스트된 변수를 취한다.

마지막으로 Listing 10에 표시된 바와 같이 ./system/application/controller/activity.php에 있는 save 링크를 주석 처리한다.


Listing 10. 불필요한 save 링크 제거하기
	
          '<span style="style="white-space: nowrap;">'.
          $participation_type_buttons.'&nbsp;&nbsp;'.
          /* the save link is no longer needed
            '<a href="" onclick="document.forms[\'form_'.$activity->id.'\'].submit();
return false;">save</a>'. */
          '</span>'.
          '</form>';

이제 부모의 참여를 변경할 수 있으며 페이지를 새로 고치지 않아도 변경된 내용이 자동으로 저장된다.

자동 제안 입력 필드

Ajax의 기능 중에서 가장 효과적이고 널리 사용되는 것은 자동 제안이나 자동 완료 기능이다. 교사로 로그인하여 Manage Class Activities를 클릭한다. 활동을 추가하려면 길게 표시되는 가능한 활동 목록을 사용자가 스크롤 다운해야 한다. UI를 개선하기 위해 Listing 11과 같이 autosuggest 함수에 바인드된 입력 필드를 ./system/application/views/activity_master_listing.php 파일의 맨 위에 추가한다. 이렇게 하면 교사가 스케줄되지 않은 모든 활동을 이용하여 활동을 보다 쉽게 선택할 수 있게 된다.


Listing 11. 자동 제안 입력 필드 추가
	
<div id="select_anchor">
  <a href="" onclick="$('#select_anchor').hide(100); 
    $('#select_activity').show(100);
    return false;">
    Select an unscheduled Activity to add >></a>
  <br /><br />
</div>
<div id="select_activity" class="requested_activity" style="display:none;">
  <table>
    <caption>&nbsp;Select an unscheduled Activity</caption>
    <tr class="odd_row_add">
      <td>
        Begin by typing a few letters of an activity name<br />
        then select from the resulting list<br />
        <br />
        <input type="text" value="" id="class_activity" 
          onkeyup="autosuggest(this.value);" class="autosuggest_input" />
        <div class="autosuggest" id="autosuggest_list"></div>
      </td>
    </tr>
  </table>
</div>

Javascript onclick() 이벤트에 바운드된 메소드와 두 개의 jQuery 오브젝트를 주목하자. jQuery는 Javascript 라이브러리이며 $(document).ready() 함수 내에서 뿐만 아니라 애플리케이션 전체에서 Javascript와 원활하게 상호 작용할 수 있다는 점을 기억한다.

다음은 global.js 파일에 있는 $(document).ready() 함수 외부에서 다음과 같은 Javascript 함수를 구현한다. 이 함수는 class_activity 입력 필드의 onkeyup() 이벤트에 바인드된다. 소스 코드는 Listing 12에 표시되어 있다.


Listing 12. jQuery를 사용하여 자동 제안 구현하기
	
/* AUTOSUGGEST SEARCH */
// triggered by input field onkeyup
function autosuggest(str){
  // if there's no text to search, hide the list div
  if (str.length == 0) {
    $('#autosuggest_list').fadeOut(500);
  } else {
    // first show the loading animation
    $('#class_activity').addClass('loading');
    
    // Ajax request to CodeIgniter controller "ajax" method "autosuggest"
    // post the str parameter value
    $.post('/index.php/ajax/autosuggest',
      { 'str':str },
      function(result) {
        // if there is a result, fill the list div, fade it in 
        // then remove the loading animation
        if(result) {
          $('#autosuggest_list').html(result);
          $('#autosuggest_list').fadeIn(500);
          $('#class_activity').removeClass('loading');
      }
    });
  }
}

이 함수가 $(document).ready() 함수 내에 있지 않다고 해도 이 함수는 여전히 jQuery 오브젝트와 메소드를 사용한다. 이 함수의 jQuery .post() 메소드는 Ajax 제어기의 autosuggest() 메소드를 호출하여 정렬되지 않은 자동 제안 결과 목록을 반향한다. Listing 13에는 이 코드가 표시되어 있다.


Listing 13. 자동 제안 결과의 검색 및 반향
	
  public function autosuggest()
  {
    // escapes single and double quotes
    $str = addslashes($_POST['str']);
    
    $this->load->model('MActivity', '', TRUE);
    $unscheduled_activities_qry = $this->MActivity->find_unscheduled_activities($str);
    
    // echo a list where each li has a set_activity function bound to its onclick() event
    echo '<ul>';
    foreach ($unscheduled_activities_qry->result() as $activity) {
      echo '<li onclick="set_activity(\''.addslashes($activity->name).'\'';
      echo ', '.$activity->id.');">'.$activity->name.'</li>'; 
    }
    echo '</ul>';
  }  

다음은 데이터베이스에서 자동 제안 결과를 리턴하도록 find_unscheduled_activities() 메소드를 추가한다. Listing 14에는 ./system/application/models/mactivity.php의 코드가 있다.


Listing 14. 데이터베이스에서 스케줄되지 않은 활동 쿼리하기
	
  // Finds all unscheduled activities that match the passed string
  function find_unscheduled_activities($str)
  {
    $this->db->select('id, name
        FROM master_activity 
        WHERE name LIKE \''.$str.'%\'
          AND id NOT IN 
            (SELECT master_activity_id FROM class_activity)
          ORDER BY name', FALSE);
    return $this->db->get();
  }

또한, UI가 보다 명료하고 list 요소가 클릭 가능하도록 autosuggest <div>와 list에 스타일을 지정한다. ./assets/css/screen.css에 추가된 스타일은 Listing 15에 표시되어 있다.


Listing 15. 자동 제안 목록을 명료하고 클릭 가능하게 하기
	
/***************/
/* Autosuggest */

.autosuggest {
  border:1px solid #000000;
  display:none;
  overflow:hidden;
  padding:0px;
  position:absolute;
  width:200px;
  z-index:1;
}

.autosuggest ul li {
  background-color:#FFFFFF;
  cursor:pointer;
  display:block;
  list-style:none;
  padding:5px;
  white-space:nowrap;
}

.autosuggest ul li:hover {
  background-color:#316AC5;
  color:#FFFFFF;
}

.loading{
  background-image:url('../img/indicator.gif');
  background-position:right;
  background-repeat:no-repeat;
}

.autosuggest_input {
  width:200px;
}

.table_header_add {
  background-color:#FFCC66;
}

.odd_row_add {
  background-color:#FFCC66;
}

이제 어느 정도 완성이 되었다. 필드에 문자를 입력하여 일련의 일치하는 활동을 검색할 수 있다. 이제 학급 활동을 선택하고 표시, 저장할 코드를 구현하도록 하자. 먼저, global.js 파일에 함수 두 개를 추가하여 활동 이름 필드를 설정하고 활동 정보가 있는 행을 표시한다. Listing 16에는 이러한 두 가지 기능을 하는 코드가 표시되어 있다.


Listing 16. 선택된 활동을 가져와서 표시하기
	
/* AUTOSUGGEST SET ACTIVITY */
// triggered by an onclick from any of the li's in the autosuggest list
// set the class_acitity field, wait and fade the autosuggest list
// then display the activity details
function set_activity(activity_name, master_activity_id) {
  $('#class_activity').val(activity_name);
  setTimeout("$('#autosuggest_list').fadeOut(500);", 250);
  display_activity_details(master_activity_id);
}

/* AUTOSUGGEST DISPLAY ACTIVITY DETAILS */
// called by set_activity()
// get the HTML to display and display it
function display_activity_details(master_activity_id) {
  
  // Ajax request to CodeIgniter controller "ajax" method "get_activity_html"
  // post the master_class_activity parameter values
  $.post('/index.php/ajax/get_activity_html',
    { 'master_activity_id':master_activity_id },
    // when the Web server responds to the request
    // replace the innerHTML of the select_activity element
    function(result) { 
      $('#select_activity').html(result);
    }
  );
}

또한, 이 코드도 Ajax를 사용하여 선택된 활동을 표시하는 테이블 행을 가져온다. 해당 HTML은 Listing 17에 있는 코드에서 생성된다.


Listing 17. 활동을 표시하는 HTML 테이블 반향하기
	
  public function get_activity_html()
  {
    $this->load->model('MActivity', '', TRUE);
    $this->load->library('table');

    $requested_activity_id = $_POST['master_activity_id'];
    $requested_activity_qry = 
      $this->MActivity->get_requested_master_activity($requested_activity_id);

    // code leveraged from /controllers/activity.php manage_class_listing() method
    // generate HTML table from query results
    $tmpl = array (
      'table_open' => '<table>',
      'heading_row_start' => '<tr class="table_header_add">',
      'row_start' => '<tr class="odd_row_add">' 
    );
    $this->table->set_template($tmpl); 
    
    $this->table->set_caption('&nbsp;Add this Activity'); 

    $this->table->set_empty("&nbsp;"); 
    
    $this->table->set_heading('<span class="date_column">Date</span>',
                  '<span class="activity_name_column">Activity Name</span>',
                  '<span class="address_column">Address</span>',
                  'City', 'Details');
    
    $table_row = array();

    foreach ($requested_activity_qry->result() as $activity)
    {
      $m_id = $activity->master_activity_id;

      $table_row = NULL;

      $table_row[] = ''.
        '<form action="" name="form_'.$m_id.'" method="post">'.
        '<input type="hidden" name="master_activity_id" value="'.$m_id.'"/> '.
        '<input type="text" name="activity_date" size="12" /> '.
        '<input type="hidden" name="action" value="save" /> '.
        '</form>'.
        '<span class="help-text">format: MM-DD-YYYY</span><br/>'.
        '<a href="" onclick="document.forms[\'form_'.$m_id.'\'].submit();'.
        'return false;">save</a>';


      $table_row[] = '<input type="text" value="'.$activity->name.
        '" id="class_activity" onkeyup="autosuggest(this.value);"'.
        'class="autosuggest_input" />'.
        '<div class="autosuggest" id="autosuggest_list"></div>';
      $table_row[] = htmlspecialchars($activity->address);
      $table_row[] = htmlspecialchars($activity->city);
      $table_row[] = htmlspecialchars($activity->details);

      $this->table->add_row($table_row);
    }    
      
    $requested_activities_table = $this->table->generate();

    echo $requested_activities_table;
  }

}

이 코드는 최종 테이블을 리턴하지 않고 반향하도록 약간 수정하여 활동 제어기에 활용되었다. 또한, Listing 18에 표시된 것과 같은 SQL 쿼리가 필요하며 이 쿼리 코드는 ./system/application/models/mactivity.php에 있다.


Listing 18. 요청된 마스터 활동 리턴하기
	
  // Returns a single master activity record
  public function get_requested_master_activity($id)
  {
    $this->db->select('id as master_activity_id, name, address, city, details');
    $this->db->where('id', $id);
    return $this->db->get('master_activity');
  }

마지막으로 새 활동을 이미 추가할 수 있다고 하더라도 스케줄되지 않은 활동을 제거하고 활동 목록을 오름 차순으로 다시 정렬한다. MActivity 모델에서 업데이트된 SQL 코드는 Listing 19에 표시되어 있다.


Listing 19. 스케줄되지 않은 활동만 리턴하기
	
  // Retrieve all master activity records
  function list_class_activities($activity_id)
  {
    // get all records
    if (!$activity_id) {
      $this->db->select('ma.id as master_activity_id, ma.name, 
                ma.address, ma.city, 
                ma.details, ca.id as class_activity_id, ca.date
            FROM master_activity ma
            /*LEFT*/ JOIN class_activity ca ON ca.master_activity_id = ma.id
            ORDER BY ca.date /*DESC*/, ma.name', FALSE);
      return $this->db->get();
    // get all records except the one being requested
    } else {
      $this->db->select('ma.id as master_activity_id, ma.name, 
                ma.address, ma.city, 
                ma.details, ca.id as class_activity_id, ca.date
            FROM (SELECT * FROM master_activity 
              WHERE master_activity.id != '.$activity_id.') ma
            /*LEFT*/ JOIN class_activity ca ON ca.master_activity_id = ma.id
            ORDER BY ca.date /*DESC*/, ma.name', FALSE);
      return $this->db->get();
    }
  }

날짜를 선택할 수 있는 시각적 캘린더

UI에서 마지막으로 개선해야 할 사항은 시각적 캘린더를 사용하여 날짜를 입력하는 데 필요한 텍스트 입력 필드를 바꾸는 일이다. 이렇게 하려면 jQuery UI 날짜 선택기를 사용해야 하며 이 선택기는 널리 사용되는 jQuery UI 라이브러리 플러그인(jQuery 라이브러리의 오픈 소스 확장)이다. Listing 20와 같이 ./system/application/views/template.php 파일을 업데이트한다.


Listing 20. jQuery UI 날짜 선택기 삽입하기
	
<!-- including the jQuery UI Datepicker and styles -->
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"
  type="text/javascript"></script>
<link href="/assets/css/jquery-ui-1.7.2.custom.css" rel="stylesheet" type="text/css" />
<style type="text/css">
  /* jQuery UI sizing override */
  .ui-widget {font-size:1em;}
</style>

<script> 태그에서는 다운로드된 jQuery 라이브러리를 사용하는 대신 jQuery UI와 같은 다양한 라이브러리를 위한 무료 저장소인 http://ajax.googleapis.com을 참조한다. CSS 파일과 이미지는 필수 스타일만 포함되도록 구성되었다(http://jqueryui.com/download). 마지막으로 jQuery UI 라이브러리는 본문 글꼴 크기가 62.5%라고 가정하여 빌드되므로 기본 글꼴 크기를 대체하여 글꼴 크기를 적절하게 조정한다.

날짜 선택기는 HTML 내에서 ID나 CSS 클래스에 바인드되어 작동한다. 활동 편집 기능을 처리하기 위해 ./system/application/controllers/activity.php 210 행에 있는 날짜 입력 필드에 date-picker 클래스를 지정한다. 이 코드는 Listing 21에 표시되어 있다.


Listing 21. 활동 편집용 date-picker 클래스 지정
	
          // add the date-picker class to the date input field
          '<input type="text" name="activity_date" size="12" value="'.
            date('m/d/Y', strtotime($activity->date)).'" class="date-picker" /> '.
          '<input type="hidden" name="action" value="update" /> '.
          '</form>'.
          '<span class="help-text">format: MM/DD/YYYY</span><br/>'.

활동 추가 기능을 처리하기 위해 Listing 22에 표시된 바와 같이 ./system/application/controllers/ajax.php 83 행에 있는 날짜 입력 필드에 동일한 클래스를 지정한다.


Listing 22. 활동 추가용 date-picker 클래스 지정
	
        // add the date-picker class to the date input field
        '<input type="text" name="activity_date" size="12" class="date-picker" /> '.
        '<input type="hidden" name="action" value="save" /> '.
        '</form>'.
        '<span class="help-text">format: MM/DD/YYYY</span><br/>'.

마지막으로 학급 활동을 편집하거나 추가할 때 표시되도록 날짜 선택기를 바인드한다. global.js 파일에 있는 $(document).ready() 함수 안에 삽입할 코드는 Listing 23에 표시되어 있다.


Listing 23. 날짜 선택기를 클래스에 바인드하기
	
  /* jQUERY UI CALENDAR PLUGIN */
  // bind the Datepicker to the date-picker class
  $(".date-picker").datepicker();

이제 학급 활동을 편집하도록 하자. 날짜 입력 필드에 커서를 놓으면 캘린더가 표시되며 이 캘린더를 통해 학급 활동 날짜를 선택할 수 있다. 그러나 활동을 추가하려고 하면 이 캘린더가 작동하지 않는다. 그 이유는 문서가 이미 로드된(Ajax의 사용으로) 이후에 활동을 추가하는 HTML이 작성되어 날짜 선택기가 날짜 입력 필드에 바인드되지 않았기 때문이다. 이러한 문제점을 수정하려면 Ajax 함수가 HTML을 작성한 후에 날짜 선택기를 날짜 입력 필드에 바인드해야 한다. global.js 파일에 있는 display_activity_details() 함수를 대상으로 이와 같이 변경한 내용이 Listing 24에 표시되어 있다.


Listing 24. 날짜 선택기를 날짜 추가 필드에 바인드하기
	
    function(result) { 
      $('#select_activity').html(result);

      // because the add datepicker is not loaded with the DOM
      // manually add it after the date input field is written
      $(".date-picker").datepicker();
    }

이제는 날짜 선택기 캘린더를 사용하여 클래스 활동을 추가할 수 있다.


결론

My developerWorks에 있는 웹 개발 그룹에 참여하자.

My developerWorks 웹 개발 그룹에서 다른 개발자들과 웹 개발과 관련된 주제를 토론하고 관련 자료를 공유하자.

My developerWorks 회원이 아니라면, 지금 가입하자!

이제 작업이 모두 완료되었다. jQuery 오브젝트를 통해 DOM 처리를 결합하고 Ajax를 통해 원활하게 통신하여 이러한 애플리케이션의 UI를 대폭 개선하는 방법을 살펴보았다. 그리고 이러한 기능을 수행하는 코드는 대부분 매우 간단했다. 이제는 Ajax를 사용하여 학급 활동의 편집 과정이 인라인으로 처리되게 하거나 이 기사를 읽는 동안 경험했을 수 있는 기타 UI 개념을 구현함으로써 애플리케이션을 더욱 개선해야 하는 과제를 수행할 수 있다.



다운로드 하십시오

설명이름크기다운로드 방식
SQL file to create classroom databaseclassroom_database.zip15KBHTTP
Full initial code base including CodeIgniter filessource_w_codeigniter.zip411KBHTTP
The initial MVC files for this articlesource_only.zip23KBHTTP
The jQuery library v1.4.2jquery_library.zip45KBHTTP
CSS files needed for jQuery UI Datepickerjquery_datepicker.zip53KBHTTP
Full final code base including CodeIgniter filesfinal_source_w_codeigniter.zip515KBHTTP
The final MVC files from this articlefinal_source_only.zip124KBHTTP

다운로드 방식에 대한 정보


참고자료

교육

제품 및 기술 얻기

  • CodeIgniter: CodeIgniter 최신 버전을 다운로드할 수 있다.

  • MySQL: MySQL 최신 버전을 다운로드할 수 있다.

  • jQuery: jQuery 라이브러리 최신 버전을 다운로드하여 자세히 배워보자.

  • jQuery UI: jQuery UI 웹 사이트에서 추가 위젯을 다운로드하여 자세히 배워보자.

  • IBM 제품 평가판: 이러한 평가판을 다운로드하거나 DB2®, Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및 미들웨어 제품을 사용해 볼 수 있다.

토론

필자소개

Kevin Howard Goldbeg

With 20 years of experience in the high-tech industry, Kevin Howard Goldberg is a technology executive, author, and consultant residing in Westlake Village, Calif. He currently serves as CTO at imagistic, an award-winning digital marketing and technology company, which he co-founded in 1997. An expert on Web development and technology, he serves on the Santa Monica College Computer Science Advisory Board and held senior positions at Film Roman, Lionsgate, and Philips Interactive Media. He is the author of XML: Visual QuickStart Guide (2nd Edition), (PeachPit Press, 2008). You can reach him at http://kehogo.com/contact.

잘못된 도움말 신고

부정사용 신고

감사합니다. 이 항목은 운영자가 관심을 표시했습니다.


잘못된 도움말 신고

부정사용 신고

제출실패 신고. 나중에 다시 실행해주세요.


디벨로퍼웍스 로그인


IBM ID가 필요하세요?
IBM ID를 잊으셨습니까?


비밀번호를 잊으셨습니까?
비밀번호 변경

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

화면상에 보여지는 닉네임을 정하세요.

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

3개의 &이나 대쉬를 포함해주시고 31글자내로 제한해주세요.


developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


아티클 순위

의견

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=20
Zone=웹 개발
ArticleID=512444
ArticleTitle=jQuery를 사용하는 Ajax와 CodeIgniter
publish-date=05112010
author1-email=kgoldberg@imagistic.com
author1-email-cc=

태그

Help
검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오.

태그를 더 많이 보거나 적게 보기 위해 슬라이더 막대를 사용하십시오.

인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다.

내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.

검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오. 인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다. 내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.