CodeIgniter と Ajax に jQuery を使用する
効果的で使い易い Web 2.0 インターフェースを作成する方法
CodeIgniter は、PHP で作成された人気の高い軽量のオープンソース・フレームワークで、MVC (Model-View-Controller) アーキテクチャー・パターンをベースにしています。jQuery は、高速かつ軽量のオープンソース JavaScript ライブラリーであり、HTML ページの操作と Ajax によるやりとりを単純化することを目的として設計されています。この 2 つを組み合わせて使用することで、使い易い Web サイトおよびアプリケーションを迅速に開発するための強力な基盤が実現します。
この記事では、この 2 つのシステムを 1 つのフレームワークに統合する方法、そして jQuery を使用して既存の Web アプリケーションの UI を改善する方法を説明します。記事で前提とするのは、CodeIgniter のバージョン 1.7.2 以降と MySQL のバージョン 4.1 以降が両方ともインストールされていること、そしてこの 2 つを使用する上で十分な実用上の知識を持っていることです。さらに、jQuery ライブラリーのバージョン 1.4.2 以降も必要です。CodeIgniter を初めて使用する場合、またはざっと復習する必要がある場合には、「参考文献」に記載したリンクを利用して詳細を調べてください。
Web 2.0: jQuery を使用した Ajax
最も重要な Web 2.0 の側面の 1 つは、ユーザー・エクスペリエンスが Web サイトよりもデスクトップ・アプリケーションのユーザー・エクスペリエンスに近いことです。具体的に言うと、Web ページとの対話では、ユーザーには Web サーバーとやりとりしていることがわかりません。例えば送信ボタンをクリックした後、送信された情報を Web サーバーが処理し、それによって更新されたコンテンツで Web ページ全体の表示が更新されるのを待つ必要はないということです。Web 2.0 では、変更の必要があるコンテンツだけが更新されて、ページの残りはそのままの状態で維持されます。
この「送信なし」のプロセスは、Ajax を利用して行われます。Web 開発者は Ajax を使うことにより、ページを更新することなく、Web クライアント (ブラウザー) と Web サーバーとの間で情報を送信することができます。その上この情報転送は、直接ユーザーが介入しなくてもトリガーすることが可能です。
Web ページが Ajax を使用すると、そのページは Web サーバーとの間で非同期にデータ送受信を行っている状態となります。送受信されるデータは平文なので、XML や HTML、そして JSON などの異なるフォーマットにすることも、あるいは平文のまま使用することもできます。
実際のデータ送信は、JavaScript と XMLHttpRequest
という API を使用して行われます。ここで登場するのが、jQuery です。jQuery ライブラリーは、Ajax を使用するプロセスを極めて単純なものにします。Ajax を容易に使えるようになるだけではありません。jQuery ライブラリーによって、更新されたデータを表示するのも容易になります (JavaScript で HTML DOM をトラバースしようとした経験があるなら、どれほど容易になったか、その違いを実感できるはずです)。
既存の CodeIgniter アプリケーション
CodeIgniter で使用する jQuery の威力と簡単さを実証するため、この記事では既存の Web アプリケーションの UI を改善する具体的な手順を説明します。このアプリケーションは、教師がクラスの行事と、それぞれの行事への保護者の参加を管理できるように設計されたものです。アプリケーションでは教師がまず、委員会が承認した行事のリストのなかからクラスで行う行事を選択し、それぞれの行事の日程を計画します。次に、生徒の保護者がサイトに登録し、その子供に関する連絡先情報を入力します。この情報を入力した後、保護者はクラスの行事リストを表示して、自分の参加レベル (物資の購入、準備手伝い、補佐、または行事のリーダーとしての参加) を選択することができます。
注: このシステムは、子供たちのスポーツ・チームや YMCA グループなどをにも簡単に適用することができます。
この記事のために、アプリケーションのデータベースにはすでに 100 件のイベント、5 人の保護者、そして 1 人の教師がロードされています。保護者には parent1、parent2 というように、parent5 までのユーザー名が設定されています。教師のユーザー名は teacher で、パスワードは全員共通して ibm です。記事の手順に従うには、この Web アプリケーションとデータベースをダウンロードして、Web サーバーにセットアップしてください。このアプリケーションの要件として、CodeIgniter フレームワークはサーバーのルートに置かれている必要があります。
jQuery のセットアップ
jQuery を使用するための最初のステップは、このライブラリーをダウンロードすることです (リンクについては「参考文献」を参照)。バージョン・リリースごとに、圧縮されていないファイルと「縮小」ファイル (この高度に圧縮されたバージョンは短時間でロードできますが、トレースしたいと思っても、それは不可能です) の 2 つが用意されています。開発には圧縮されていないバージョンを使用し、本番には縮小バージョンを使用することをお勧めします。
次に、jQuery ライブラリー・ファイルを Web サーバーのルートにある .assets/js フォルダーに配置します。同じフォルダーに、global.js という名前の新規ファイルを作成してください (リスト 1 を参照)。このファイルが、アプリケーション全体の JavaScript コードを配置する場所となります。
リスト 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 ロードが完了した時点でのみ、自動的にトリガーされます。
アプリケーションが jQuery ライブラリー・ファイルと新規に作成したファイルの両方をロードするように、./system/application/views/template.php ファイルをリスト 2 のように編集します。
リスト 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>
ここで、Web サイトの index ページにナビゲートしてみてください。ページがロードされると、「Hello World」という JavaScript アラートが表示されるはずです。
CodeIgniter で使用する jQuery と Ajax
jQuery ライブラリーと global.js ファイルが準備できたところで、ここからはアプリケーションのインターフェースを改善する作業に取り掛かります。まだ実際にこのシステムにログインしていないのであれば、ここで少し時間を割いて保護者として、そして教師としてログインして、このシステムでの行事の操作に慣れてください。
ユーザー名の自動検証
UI を改善する最初の場所は、「Registration (登録)」ページです。現在のところ、ユーザー名が使用済みであるかどうかの検証は、ユーザーがページを送信した後に行われます。けれども Ajax を使用すれば、ページを送信しなくても、サーバー・サイドの検証を実行して結果を返すことができます。
そのためのコードをユーザー名フィールドの onblur()
イベントにバインドします。このイベントは、ユーザーのカーソルがフィールドを離れるとトリガーされます。更新後の global.js ファイルは、リスト 3 のとおりです。
リスト 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>'); } } ); }); });
上記のコードは、ID を username
に設定した DOM 要素を使って jQuery オブジェクトを作成した後、jQuery の blur()
メソッドを呼び出して、ユーザー名フィールドの onblur()
イベントに関数をバインドします。バインドされる関数は Ajax を使用して、ユーザー名フィールドの値を ajax
という名前の CodeIgniter コントローラーとそのメソッド、username_taken
に POST します。続いて既存のエラー・メッセージをクリアし、Ajax の POST リクエストの結果に応じて、エラー・メッセージを表示するか、表示しないかを決定します。
今度は ./system/application/controllers に、ajax.php という名前のファイルを作成します。これは、jQuery の Ajax .post()
メソッドが参照するファイルです。リスト 4 に、このコントローラーのソース・コードを記載します (このコントローラーには ajax
という名前を付けてありますが、この名前に特別な理由はありません。.post()
メソッド内の URL が適切なコントローラーを参照する限り、どのような名前にでもすることができます)。
リスト 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 POST リクエストはデータを Web ページに送信し、その結果更新されたページのデータを使用します。つまり、プログラムによってこのメソッド自体に作用することはしません。
これで、最初の Ajax 関数が完成しました。「Registration (登録)」ページにナビゲートし、すでに使われている任意のユーザー名で登録しようとすると、該当するエラー・メッセージが表示されることを確認してください。
興味深いことに、この jQuery コードは、作成時には意図していなかった結果になっています。Ajax 関数がバインドされるのは username
という ID を持つフィールドですが、「Login (ログイン)」ページのユーザー名フィールドもこれに該当します。リスト 5 に、registration_form
フォーム内のユーザー名フィールドにだけバインドされるように jQuery オブジェクトを変更する方法を示します。
リスト 5. 正しいユーザー名フィールドに制限するためのコード
/* 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 です。保護者が特定の行事に参加することを示すには、その行事に対応するラジオ・ボタンをクリックしてから、保存のためのリンクをクリックしてページを送信するという操作が必要です。この UI を改善し、保存のためのリンクをクリックする操作をなくします。つまり、ページを送信する必要を一切失くすということです。
まずは、以降に記載するコードを global.js ファイルに追加します。プロセスを説明しやすくするために、このコードはリスト 6、リスト 7、リスト 8 に分けてあります。
リスト 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; } });
v
この関数がバインドされるのは、participation_type_id というラジオ・ボタンの onclick()
イベントです。関数はクリックされたラジオ・ボタンの値を取得した後、一連のメソッドを使用してフォームの隠し要素を返します。map()
メソッドはその関数を介して隠し要素のそれぞれを渡し、class_activity_id
と user_id
の値を取得します。
保護者の参加を設定するために必要な値が認識されると、コードはこの情報を保存するため、Ajax リクエストを実行します (リスト 7 を参照)。このリクエストに対するサーバーのレスポンスはデータをエコー出力しないので、jQuery レスポンス関数は空となります (実際には削除されている可能性もあります)。
リスト 7. CodeIgniter への Ajax リクエストの送信
// 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()
メソッドによって該当する色に変更します。このコードは、リスト 8 のとおりです。
リスト 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 コードは完成したので、今度は ajax
コントローラーに update_user_participation()
メソッドを作成する必要があります (リスト 9 を参照)。
リスト 9. CodeIgniter でユーザーの参加を処理するコード
public function update_user_participation() { $this->load->model('MActivity', '', TRUE); $this->MActivity->set_user_participation($_POST); }
上記のメソッドは、MActivity モデルの既存の set_user_participation()
メソッドを使用します。この set_user_participation() メソッドは、Ajax リクエストが POST した変数を引数に取ります。
最後に、./system/application/controller/activity.php の保存リンクをコメント・アウトします (リスト 10 を参照)。
リスト 10. 不要な保存リンクの削除
'<span style="style="white-space: nowrap;">'. $participation_type_buttons.' '. /* the save link is no longer needed '<a href="" onclick="document.forms[\'form_'.$activity->id.'\'].submit(); return false;">save</a>'. */ '</span>'. '</form>';
これで、保護者の参加を変更すれば、ページを更新することなく自動的に変更内容が保存されることになります。
オートサジェスト入力フィールド
最も効果的で、最も広く普及している Ajax の機能の 1 つとして挙げられるのは、オートサジェスト、あるいは自動補完とも呼ばれる機能です。教師としてログインして、「Manage Class Activities (クラスの行事の管理)」をクリックしてください。行事を追加するには、選択可能な行事の長々と続くリストをスクロール・ダウンしなければなりません。この UI を改善し、autosuggest
関数にバインドした入力フィールドを ./system/application/views/activity_master_listing.php ファイルの先頭に追加します (リスト 11 を参照)。こうすることで、教師は計画されていないすべての行事のなかから簡単に項目を選択できるようになります。
リスト 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> 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()
イベントにバインドされた 2 つの jQuery オブジェクトとメソッドに注目してください。jQuery は単なる JavaScript ライブラリーなので、$(document).ready()
関数の中だけでなく、アプリケーション全体にわたって JavaScript とシームレスにやりとりできるという点を覚えておいてください。
次に、global.js ファイルの $(document).ready()
関数の外側に以下の JavaScript 関数を実装します。この関数をバインドするのは、class_activity 入力フィールドの onkeyup()
イベントです。リスト 12 に、ソース・コードを記載します。
リスト 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()
メソッドは、オートサジェストの結果の順不同リストをエコー出力します。このコードは、リスト 13 のとおりです。
リスト 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()
メソッドを追加します。リスト 14 に、./system/application/models/mactivity.php から抜粋したコードを記載します。
リスト 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 を簡潔にして、リストの要素をクリックできるようにするためには、autosuggest <div>
とリストにスタイルを設定する必要もあります。そこで、./assets/css/screen.css にリスト 15 のスタイルを追加します。
リスト 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 ファイルに、行事名のフィールドを設定するための関数、そして行事の情報を提供する行を表示するための関数を追加します。リスト 16 に、この 2 つの関数のソース・コードを記載します。
リスト 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 は、リスト 17 のコードで生成します。
リスト 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(' Add this Activity'); $this->table->set_empty(" "); $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; } }
上記のコードは、行事コントローラーのコードに多少の変更 (最終的な表を返す代わりに、表をエコー出力するなど) を加えただけです。リスト 18 に、./system/application/models/mactivity.php から抜粋した、このコードに必要な SQL クエリーを記載します。
リスト 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'); }
最後に、新しい行事を追加できるだけでなく、計画されていない行事を削除して、リストを昇順で再度ソートできるようにします。リスト 19 に、そのように更新した MActivity モデルの SQL コードを記載します。
リスト 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 ライブラリーのオープソース拡張) のプラグインである、jQuery UI Datepicker です。まずは、./system/application/views/template.php ファイルをリスト 20 のように更新してください。
リスト 20. jQuery UI Datepicker のインクルード
<!-- including the jQuery UI Datepicker and styles --> <script src="//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 UI をはじめとする多くのライブラリーの無料リポジトリー、http://ajax.googleapis.com を参照しています。また、CSS ファイルとイメージは必要なスタイル (http://jqueryui.com/download) だけが含まれるように構成されています。そして最後の注意点として、jQuery UI ライブラリーは本文のフォント・サイズを 62.5% に設定していることを前提として作成されているので、必要に応じてこのデフォルトのサイズを変更してください。
Datepicker は、HTML 内の CSS クラスまたは ID にバインドされることで動作します。行事を編集する関数の場合には、date-picker
という名前のクラスを、./system/application/controllers/activity.php の 210 行目あたりにある日付入力フィールドに割り当てます。このコードをリスト 21 に記載します。
リスト 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/>'.
行事を追加する関数の場合には、同じクラスを、./system/application/controllers/ajax.php の 83 行目あたりにある日付入力フィールドに割り当てます。このコードをリスト 22 に記載します。
リスト 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/>'.
最後に Datepicker をバインドして、クラスの行事を編集または追加するときに、このカレンダーが表示されるようにします。リスト 23 に、global.js ファイルの $(document).ready()
関数内部に配置するコードを記載します。
リスト 23. Datepicker とクラスのバインド
/* jQUERY UI CALENDAR PLUGIN */ // bind the Datepicker to the date-picker class $(".date-picker").datepicker();
早速、クラスの行事を編集してみてください。カーソルを日付入力フィールドに置くとカレンダーが表示され、行事の日付を選択できるようになっているはずです。ただし、行事を追加するときにはカレンダーは表示されません。その理由は、行事を追加するための HTML は (Ajax を使って) 文書がロードされた後に作成されているため、Datepicker がその日付入力フィールドにバインドされていないからです。この問題を修正するには、Ajax 関数が HTML を作成した後に、Datepicker を日付入力フィールドにバインドするようにします。そのために global.js ファイルの display_activity_details()
に加えた変更は、リスト 24 のとおりです。
リスト 24. Datepicker と日付追加フィールドのバインド
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(); }
これで、Datepicker カレンダーを使ってクラスの行事を追加できるようになります。
まとめ
よく出来ました! jQuery オブジェクトを使用して DOM 操作を組み合わせ、Ajax を使ったシームレスなやりとりを実現することによって、このアプリケーションの UI は大幅に改善されています。しかも多くの場合に、ごくわずかなコードでこのような改善を加えられることがわかった今、このアプリケーションをさらに強化するという課題に取り組んでみるのも一考です。例えば Ajax を使ってクラスの行事をインラインで編集できるようにしたり、あるいはこの記事を読んでいる間に思い付いた他のあらゆる UI を実装したりするなど、さまざまな可能性が考えられます。
ダウンロード可能なリソース
- このコンテンツのPDF
- SQL file to create classroom database (classroom_database.zip | 15KB)
- Full initial code base including CodeIgniter files (source_w_codeigniter.zip | 411KB)
- The initial MVC files for this article (source_only.zip | 23KB)
- The jQuery library v1.4.2 (jquery_library.zip | 45KB)
- CSS files needed for jQuery UI Datepicker (jquery_datepicker.zip | 53KB)
- Full final code base including CodeIgniter files (final_source_w_codeigniter.zip | 515KB)
- The final MVC files from this article (final_source_only.zip | 124KB)
関連トピック
- 「CodeIgniter 入門」(developerWorks、2008年8月): CodeIgniter フレームワークの優れた入門記事を読んでください。
- 「Developing dynamic Web sites with CodeIgniter」(developerWorks、2010年1月): CodeIgniter の詳細と MVC アーキテクチャーについて学んでください。
- CodeIgniter User Guide: CodeIgniter のオンライン・マニュアルを読んでください。
- developerWorks Web architecture ゾーン: Web 2.0 開発のツールと情報が満載の Web development ゾーンにアクセスしてください。
- CodeIgniter: CodeIgniter の最新バージョンをダウンロードしてください。
- MySQL: MySQL の最新バージョンをダウンロードしてください。
- jQuery: jQuery ライブラリーの詳細を学んで、このライブラリーの最新バージョンをダウンロードしてください。
- jQuery UI: jQuery UI の Web サイトで、追加ウィジェットの詳細を学んでダウンロードしてください。