CodeIgniterの学習 18 - HTMLテーブルクラスを使ってテーブルタグを自動生成してみる
これまでいろいろ試していたけど、CodeIgniterの標準機能のものをあんまり使って学習していないので、
基本に立ち返って、タスクリストを作りながら学習していくことにする。
設計とかはせずに行き当たりばったりで、いろんな機能を試してみるつもりなので、
途中の過程では相当中途半端だと思う。
でも完成したら使い物になるかも(希望)。
開発方針としては、
- 設計はしない。思いつきでおもしろそうな機能を試す。
- モデルにロジックを寄せるのは後回しにする。(全部コントローラ内で完結させる)
- 必要な項目は必要になった時にalter文で列追加する。
- xssの対策は後でやる。
理由は、書き方を学習する時に、いちいち設計してたら面倒でやる気が出ないから。
日々の進み具合は非常にゆっくりになると思う。練習アプリはのんびり作っていくことにする。
まずはタスク一覧でも作ってみる
タスクリストといえばまずは、タスク一覧。
前回のエントリで作ったデータを一覧表示してみる。
データの一覧表示には、HTMLテーブルクラスを使ってみたいと思う。
コントローラ内で、
<?php //上略 $this -> load -> library( 'table' ); // データ取得 $q = $this -> db -> get( 'tasklist', 20 ); $data['tblList'] = $this -> table -> generate($q); //下略 ?>
でテーブルクラスを有効にして、
tasklistテーブルのデータを20件まで取得し、
$this -> table -> generate($q);
でテーブルを自動生成している。
以下全ソース
これまでのエントリでいろいろやったソースを流用している。(ビューとかcssとか)作ったテーブルのddl文はソースの末尾にあるが、おそらく後のエントリで相当変わるはず。
1)コントローラ:application/controllers/tasklist.php
クエリを発行して、テーブルタグを作ってテンプレートに流し込んでいる。
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); // タスクリストというかいろいろ実験 class Tasklist extends Controller { // コンストラクタ function Tasklist() { parent :: Controller(); // ログイン認証、ログインしてなければログイン画面に飛ばされる // $this -> freakauth_light -> check(); // 開発中はscaffoldingを有効に //if ( config_item( 'my_debugger' ) ) { // $this -> load -> scaffolding( 'tasklist' ); // テーブル名とクラス名は同じでなくてもいい //} // urlヘルパ $this -> load -> helper( 'url' ); //フォームヘルパ $this->load->helper('form'); // モデルの読み込み todo:後でモデルに寄せる // $this -> load -> model( 'tasklist_mdl' ); } // デフォルトインデックス function index() { $data = array(); //HTML テーブルクラスを使ってみる $this -> load -> library( 'table' ); // データ取得 $q = $this -> db -> get( 'tasklist', 20 ); $data['tblList'] = $this -> table -> generate($q); // ビューの生成 $this -> _setTpl( "tasklist_index" , $data ); } // ビューの生成 一カ所にまとめた function _setTpl( $viewName, $data = array() ) { // 大枠のテンプレート側の変数(ヘッダ部分のタイトルと、xajax用javascriptタグ) $tpl["page_title"] = "タスクリストにようこそ"; // タスクリスト(実験ソース)のテンプレートにデータをセット $tpl["main_content"] = $this -> load -> view( $viewName, $data , true ); // 大枠のテンプレートに、タスクリストのビューをはめ込む $this -> load -> view( 'base_view', $tpl ); } } //Endofclass /** * タスクリストのテーブル、適当なので後で、完了日時とかユーザーidとか項目を追加 * CREATE TABLE tasklist ( * id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, * user_name VARCHAR(128) NULL, * title VARCHAR(255) NULL, * note TEXT NULL, * target_date DATETIME NULL, * limit_date DATETIME NULL, * del_flg INTEGER NOT NULL DEFAULT '0', * created timestamp NULL DEFAULT CURRENT_TIMESTAMP, * modified timestamp NULL DEFAULT '0000-00-00 00:00:00', * PRIMARY KEY(id), * INDEX idx_tasklist_id(id), * INDEX idx_tasklist_tdate(target_date), * INDEX idx_tasklist_ldate(limit_date) * ); */ /** * End of file tasklist.php */ /** * Location: ./application/controllers/tasklist.php */ ?>
2)ビュー(中身):application/views/tasklist_index.php
中身のビューはコントローラ側で生成したテーブルを展開しているのみ。
<h2>タスクリスト</h2> <?= $tblList ?>
3)ビュー(外側):application/views/base_view.php
以前のエントリで作ったもの。特に変えていない。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <meta name="keywords" content="ここがキーワード" /> <meta name="description" content="ここに説明が入る" /> <title><?php if(isset($page_title)){echo $page_title ;}?></title> <?php if(isset($xajax_js)){echo $xajax_js ;}?> <link href="/css/style.css" rel="stylesheet" type="text/css"/> </head> <body> <!-- container //--> <div id="container"> <!-- header //--> <div id="header"> <div id="top"> <!-- タイトル --> <h1><span id="title">CodeIgniterの学習</span><span id="subtitle"> - タスクリスト</span></h1> <!-- スローガン --> <h2>dix3の練習サンドボックス 適当に作ったけどベースにつかえるかもね。</h2> </div> <!-- メインメニュー --> <!-- todo:後で --> <div id="menu"> <ul> <li><a href="/" class="current">ホーム</a></li><li><a href="/flickr">Flickrのテスト</a></li><li><a href="#">ヘルプ</a></li><li><a href="/auth/logout.html">ログアウト</a></li> </ul> </div> </div> <!--// header --> <!-- leftblock //--> <div id="leftblock"> <div> <p>ようこそ!<?php echo ""; //getUserName();//freakauth用 ?>ちゃん</p> <p class="yellow">締切り前のタスクが1件あります</p> <p class="red">期限切れのタスクが2件あります</p> </div> <div> <!-- サブメニュー --> <ul id="submenu"> <li><a href="#">セッションの動作テスト</a></li> <li><a href="#">キャプチャの動作テスト</a></li> <li><a href="#">グラフの動作テスト</a></li> <li><a href="#">なんとかかんとかの動作テスト</a></li> </ul> </div> <?php if(isset($calendar)){ ?> <!-- calendar //--> <div class="calendar"><?=$calendar?></div> <!--// calendar --> <?php } ?> </div> <!--// leftblock --> <!-- rightblock //--> <div id="rightblock"> <!-- breadcrumb //--> <div id="breadcrumb"> <a href="#">ホーム</a> > <a href="#">CodeIgniterの学習</a> > <a href="#">ここはブレッドクラム</a> </div> <!--// breadcrumb --> <!-- content //--> <div id="content"> <!-- main_content //--> <?=$main_content?> <!--// main_content --> </div> <!--// content --> </div> <!--// rightblock --> <!-- footer //--> <div id="footer"> © 2008 dix3 ヌル日記 <a href="http://d.hatena.ne.jp/dix3/">http://d.hatena.ne.jp/dix3/</a> </div> <!--// footer --> </div> <!--// container --> </body> </html>
5)css : ドキュメントルート/css/style.css
以前のエントリで作ったもの。特に変えていない。
/* ボディ */ body{ background:#fff; font-family: 'メイリオ','Meiryo','Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3','Osaka','MS Pゴシック',Arial,Verdana,sans-serif; font-size:14px; line-height:1.4em; margin: 0 auto; } h1, h2{ color: #555; font-size:1.6em; border-bottom:1px solid #ddd; padding: 20px 0 1px 2px; width:50%; } h3, h4{ color: #555; font-size:1.2em; padding: 0 0 4px 2px; } hr{ border:0; border-bottom: 1px solid #ddd; height: 1px; } a{ text-decoration:none; } a:link, a:visited{ color: #4169e1; } a:hover{ color: #ff6600; } li{ line-height: 1.6em; } /* 作成途中のメモ用 */ .memo{ color:#ff0000; font-size:16px; } #content{ /* 赤枠は後で消す */ /*border:dotted 1px #ff0000;*/ } /* フォーム */ #content form{ padding:8px; width:80%; background:#f2f2f2; } /* フォーム内のラベル */ form label{ margin:3px 0 2px 0; display:block; font-weight:bold; } #content input{ padding:2px 3px; } #content div{ padding:4px; } /* テーブル */ #content table{ border-collapse: collapse; background:#ddd; border:1px solid #ccc; } #content th{ border:1px solid #ccc; text-align:center; padding:5px; } #content td{ border:1px solid #ccc; background:#f9f9f9; padding:5px; } /* ヘッダ */ #header{ padding: 0 0 4px 0; border-bottom: 1px solid #ddd; background : transparent; } /* フッタ */ #footer{ clear : both; text-align:right; margin : 0; padding : 10px; color : #777; border-top : 1px solid #ddd; } /* トップ */ #top { padding:10px; background : transparent; height:32px; } /* タイトル */ #top h1 { font-size: 1.7em; font-weight: bold; margin : 0 10px; padding : 18px 0 0 0; letter-spacing : 1px; color : #a87b7b; border:0; } /* サブタイトル */ #subtitle{ color: #666; } /* スローガン */ #top h2 { font-size : 0.9em; margin : 1px 30px; padding : 0; letter-spacing : 0; color : #868686; border : 0; } /* 大外の枠 */ #container{ margin : 2px auto; width : 97%; color: #4F5155; border:1px solid #ccc; } /* メニュー */ #menu { text-align:right; margin : 0; padding : 0; height : 34px; } #menu li { list-style : none; display : inline; line-height : 34px; } #menu li a { text-decoration : none; margin : 0; padding : 9px 15px 10px 15px; font-weight : bold; color : #fff; background:#bc8f8f; border-left:1px solid #fff; } #menu li a:hover { color : #222; background : #f8cbcb; margin : 0; } #menu li a.current{ color : #fff; background : #eec1c1; margin : 0; } /* 左ブロック */ #leftblock{ float: left; margin: 0; padding: 4px ; width: 20%; height: auto; } #leftblock p{ width: 100%; padding: 3px 4px; } /* 右ブロック */ #rightblock{ float: right; width:75%; min-width: 400px; padding: 12px; border-left: 1px solid #ddd; line-height: 145%; } /* サブメニュー */ #submenu{ width:96%; margin:0; padding:2px 0 0 18px; font-size:0.875em; border:1px solid #ffffcc; background:#ffffdd; } #submenu li{ padding:0; margin:0; line-height:100%; } #submenu a:link, #submenu a:visited{ margin: 3px 0; padding: 4px 3px 3px 8px; text-decoration: underline; display: block; } /* ブレッドクラム */ #breadcrumb { padding: 8px 0 14px 0; } #breadcrumb a:link, #breadcrumb a:visited{ text-decoration: underline; color: #777; } #breadcrumb a:hover{ color: #ff6600; } /* ラベルの色 */ .info{ padding: 10px; margin:4px 0; width:70%; } .box{ padding:4px; width:80%; } .red{ background: #ffbbcc; border:1px solid #ffbbcc; } .green{ background: #b8e08f; border:1px solid #bfdb58; } .yellow{ background: #f6e080; border:1px solid #ffd77d; } .blue{ background: #c1ecfa; border:1px solid #b7e2f0; } .gray{ background-color: #f9f9f9; border:1px solid #f1f1f1; } .txt_red{ color:#ff0000; } /* カレンダー */ .calendar { margin-top:8px; font-size:1.1em; } .calendar table{ border-collapse: collapse; background:#bc8f8f; border:1px solid #ccc; } .calendar th{ border:1px solid #ccc; text-align:center; color:#fff; padding:5px; } .calendar th a{ color:#fff; } .calendar th a:hover{ color:#ff6600; } .calendar td{ border:1px solid #ccc; background:#fcfcfc; padding:6px; text-align:center; } /* カレンダーの週 */ .cal_weekrow td{ background:#a69090; color:#fff; } .cal_today{ text-decoration:underline; color:#ff6600; }
画面
こんなかんじ。この状態だと全カラムが表示されるので、実用的ではない。テーブル生成部分を改良してみる
クエリで取得する列を絞り込めばいいのだが、まだ何を表示するか決めていないので、テーブル生成の呼び方を変えてみた。
// テーブルのヘッダ $this -> table -> set_heading( 'id','済', 'タスク名', '内容', '完了予定日', '期限' );
で、テーブルのヘッダを作り、
// テーブルの生成 foreach ( $q -> result() as $row ) { $this -> table -> add_row($row -> id ,… }
で、クエリ結果をぐるぐる回して一行毎にタグを生成している。
ついでにフォームヘルパの form_checkbox(名前, 値) を使って、チェックボックスも生成してみた。
1改)コントローラ:application/controllers/tasklist.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); // タスクリストというかいろいろ実験 class Tasklist extends Controller { // コンストラクタ function Tasklist() { parent :: Controller(); // ログイン認証、ログインしてなければログイン画面に飛ばされる // $this -> freakauth_light -> check(); // 開発中はscaffoldingを有効に //if ( config_item( 'my_debugger' ) ) { // $this -> load -> scaffolding( 'tasklist' ); // テーブル名とクラス名は同じでなくてもいい //} // urlヘルパ $this -> load -> helper( 'url' ); //フォームヘルパ $this->load->helper('form'); // モデルの読み込み todo:後でモデルに寄せる // $this -> load -> model( 'tasklist_mdl' ); } // デフォルトインデックス function index() { $data = array(); //HTML テーブルクラスを使ってみる $this -> load -> library( 'table' ); // データ取得 $q = $this -> db -> get( 'tasklist', 20 ); // テーブルのヘッダ $this -> table -> set_heading( 'id','済', 'タスク名', '内容', '完了予定日', '期限' ); // テーブルの生成 foreach ( $q -> result() as $row ) { $this -> table -> add_row( $row -> id , form_checkbox('done', 'true'),// $row -> title , $row -> note , $row -> target_date , $row -> limit_date ) ; } // テーブルの生成 $data['tblList'] = $this -> table -> generate(); // ビューの生成 $this -> _setTpl( "tasklist_index" , $data ); } // ビューの生成 一カ所にまとめた function _setTpl( $viewName, $data = array() ) { // 大枠のテンプレート側の変数(ヘッダ部分のタイトルと、xajax用javascriptタグ) $tpl["page_title"] = "タスクリストにようこそ"; // タスクリスト(実験ソース)のテンプレートにデータをセット $tpl["main_content"] = $this -> load -> view( $viewName, $data , true ); // 大枠のテンプレートに、タスクリストのビューをはめ込む $this -> load -> view( 'base_view', $tpl ); } } //Endofclass /** * タスクリストのテーブル、適当なので後で、完了日時とかユーザーidとか項目を追加 * CREATE TABLE tasklist ( * id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, * user_name VARCHAR(128) NULL, * title VARCHAR(255) NULL, * note TEXT NULL, * target_date DATETIME NULL, * limit_date DATETIME NULL, * del_flg INTEGER NOT NULL DEFAULT '0', * created timestamp NULL DEFAULT CURRENT_TIMESTAMP, * modified timestamp NULL DEFAULT '0000-00-00 00:00:00', * PRIMARY KEY(id), * INDEX idx_tasklist_id(id), * INDEX idx_tasklist_tdate(target_date), * INDEX idx_tasklist_ldate(limit_date) * ); */ /** * End of file tasklist.php */ /** * Location: ./application/controllers/tasklist.php */ ?>
画面(改良版)
こんなかんじ。少しずつイメージがわいてきた。この画面上でステータスとか、予定日とかを一覧画面上で編集できるといいね。
あとタスクの追加も。
今日はここまで。
一覧画面で、完了ロジックとかも入れたいけど、明日は先に個別編集画面の枠を作る。