2011/04/21

JQueryMobileでらくらくアプリ開発をはじめよう(2)

前回JQueryMobileのサンプルプログラムとしてToDo管理アプリのUIを作るところまで説明しました。
今回は、JavaScript(JQuery)とHTML5のWebStorageを使って実際にToDoを入力し、保存できるところまで
つくりアプリを完成させます。

まずサンプルコードを書く前に、WebStorageについて少し説明します。

HTML5のWebStorageについて

WebStorageはHTML5から新たに搭載された規格で、
Cookieのような働きをします。ローカルストレージという端末ごとの
データ保存領域に(キー、バリュー)の組み合わせを保存できます。

しかし、Cookieと違う点としては、
・CookieはHTTPリクエストを使ってサーバに値を送信するのに対して、
 WebStorageはサーバ通信は必要とせず、ローカルで完結している。
・サイズ制限が無い
・有効期限が無い
・JavaScriptのオブジェクトをそのまま保存できる
などの便利な点があります。

詳しくは第14回HTML5とか勉強会資料:Web Storageが参考になります。

サンプルアプリの作成(データ処理編)
ここから本題のサンプルアプリの作成の話に戻ります。

前回の記事ではUIだけを
作りました。このUIだけ記述したHTMLファイルに今回はJavaScriptのコードを記述して、ToDoデータの画面間での受け渡しと登録されたToDo情報の保存の2つの機能を追加します。

機能追加した時のサンプルアプリのイメージはこんな感じです。


ローカルストレージ領域には次の2種類のデータを保存します。
・list_acountという名前で現在ToDoリストが何個あるかを記憶します。
・text(本文)、date(日付)という変数をToDoが新規登録される度に作成し、これにToDoの情報を記憶していきます。
WebStorageは単純な(キー、バリュー)のペアでしか保存できないので、text1,text2...date1,date2...という
名前で保存していくことで擬似的に配列を表現しています。 
(※ほんとはWeb SQL Storageを使った方がスマートですが、今回は説明簡略化のため、Web Storageで行います)

そして、画面遷移の際に発生する処理は以下の2つです。
・set関数
- 新規ToDo入力画面で入力されたテキストと日付をローカルストレージに保存します。
・load関数 
- ローカルストレージに保存されているテキストと日付を取り出し、リストに反映させます。

ソースコードは以下になります。javascriptの部分(<script>タグに囲まれた部分)以外は基本的に前回と同じです。

<!DOCTYPE html> 
<html lang="ja"> 
    <head>
        <meta charset="utf-8">
            <title>ToDoアプリ</title>
            <meta name="viewport" content="width=320,user-scalable=no" />
            <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.css" />
            <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.min.js"></script>
            <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.js"></script>    
            </head> 
    <body onload="load()">
        
        <div data-role="page" data-theme="b"> 
            
                <div  data-role="header"> 
                    <h1>TODOリスト</h1>
                    <a rel="external" href="add_todo.html" data-role="button" data-icon="plus" data-transition="slide" >追加</a>
                </div> 
                
                <div data-role="content">
            
                    <ul data-role="listview" id="todo_list">
                    </ul>
                    
                </div>
                        
                <div data-role="footer"> 
        
                </div>
        
                <script>
        
                function load(){
                    
                    jQuery.noConflict();
                    
                    //リストの反映
                    var text;
                    var date;
                    
                    //現在の登録件数をlocalStorageから取得
                    var list_acount = localStorage['list_acount'];

                    if(list_acount == null){
                        list_acount = 0;
                    }
                    
                    for(var i=list_acount-1; i>=0; i--){

                        text = localStorage['text' + i];
                        date = localStorage['date' + i];
                        
                        jQuery('#todo_list').append('<li><h2>' + text + '</h2><p>' + date + '</p></li>');
                        
                    }
                    
                    jQuery('#todo_list').listview('refresh');
                    
                }
        
                </script>
                
            </div>

    </body> 
</html>
リスト1:TODO一覧を表示する画面のソースコード(index.html)

<!DOCTYPE html> 
<html lang="ja"> 
    <head>
        <meta charset="utf-8">
            <title>ToDoアプリ</title>
            <meta name="viewport" content="width=320,user-scalable=no" />
            <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.css" />
            <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.min.js"></script>
            <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.js"></script>
            <link href="displaytest4.css" rel="stylesheet" type="text/css" />
            
    </head> 
    <body onload="load()"> 
        
        <div data-role="page" data-theme="b"> 
            
                <div data-role="header"> 
     <h2>ToDoの追加</h2>
                    <a rel="external" href="index.html" data-role="button" data-icon="back" data-transition="slide">戻る</a>
                </div>
                
                <div data-role="content">
            
      <div id="label">TODOを入力してください</div>
                        <div data-role="fieldcontain">
                            <input type="text" id="text" value=""  />
                        </div>

                        <a rel="external" href="index.html" data-role="button" data-icon="check" data-transition="slide" onclick="set()">追加</a>

    </div>
                           
    <div data-role="footer"> 
        
    </div>
    
    <script>
        
    function set(){
            
                    jQuery.noConflict();
            
                    //現在の登録件数をlocalStorageから取得
                    var list_acount = localStorage['list_acount'];
                    
                    if(list_acount == null){
                        list_acount = 0;
                    }

                    var set_text = jQuery('#text').val();
                    var set_date = new Date();

                    //send_textに何か書いてあればlocalStorageに追加する。
                    if(set_text.length > 0){
                        
                        localStorage['text' + list_acount] = set_text;
                        localStorage['date' + list_acount] = set_date;
                        
                        list_acount++;
                                                                                                                                                                                                        
                    }
                    
                    localStorage['list_acount'] = list_acount;
                 
    }
                        
    </script>
        
  </div>
        
    </body> 
</html>
リスト2:新規TODOを追加する画面のソースコード(add_todo.html)

両方のソースに共通する前回との相違点は、8行目でJQueryのライブラリを読み込みのところです。
JavaScriptのライブラリであるJQueryを使う事でDOM操作のコードが非常にシンプルで分かりやすくなります。

具体的なソースコードの説明はまず、リスト2のset関数からしたいと思います。
set関数は新規ToDoのテキストを入力して「追加」ボタンを押したときに呼び出されます。

ここでの処理は以下の4ステップです。

ステップ1(42行目〜47行目):
ローカルストレージのlist_acountから現在登録されているリスト数を取得します。
初回起動時はlist_acountが存在しない(値を取得するとNullが返ってくる)ので0を設定します。

ステップ2(51,52行目):
テキストエリアに入力された値と現在の日時をset_text,set_date変数にそれぞれ代入します。

ステップ3(55行目〜62行目):
set_text,set_dateの値をローカルストレージに保存します。この処理で新たなToDoが1つ
追加されました。このときに保存する変数名は現在のリスト数+1のインデックスを変数名の後ろに付加した形の
名前にすることでリストの追加を実現しています。
(例えば、現在2行ToDoが登録されている場合に新規に追加するとtext3とdata3に保存します)
また、1行追加されたのでlist_acountを+1します。

ステップ4(64行目)
:+1したlist_acountの値をローカルストレージに保存します。

以上の4ステップで新たなToDoを追加することができました。

次にリスト1のload関数の説明をします。
ここでは、ローカルストレージに保存されているすべてのToDoを取り出して、表示する処理をしています。
このload関数はページ(index.html)が読み込まれたときに呼び出されます。
以下の3ステップです。

ステップ1(42行目〜47行目):
ローカルストレージのlist_acountから現在登録されているリスト数を取得します。
さっきのset関数でやったのと同じですね。

ステップ2(49行目〜56行目):
ローカルストレージに保存されているすべてのToDoを取得し、リスト表示させます。54行目で
実際のリストへの追加が行われており、23行目のulタグの子要素として追加されていきます。

ステップ3(58行目):
ステップ2でDOM操作を行ったため、これを反映させる為に最後にリフレッシュをします。

このようにJavaScriptとHTML5のWebStorageを使うことでUIに実際の処理を追加する事ができます。

これでサンプルアプリは完成です。この2つのhtmlを同一階層のフォルダに置いてSafariで読み込むだけで
動作を確認する事もできます。前回も書きましたが、PhoneGapを使ってアプリ化することで、iPhoneやAndroid端末
で動作させる事もできるようになります。

Objective-CやJavaでアプリを作るよりも、かなりシンプルで保守性も高いコードになっていると思います。
このようにJQueryMobileなどのWeb技術をベースとしてアプリをつくるメリットの一つに、
コードがとてもシンプルになり可読性があがることが挙げられると思います。
UIの記述はデザイナーに、実際の処理はプログラマが実装という分業や、複数人でコードを書くとかが
非常に楽になるのではという感じがしています。

今回はこのくらいで次回以降はサンプルを作りながら分かってきたJQueryMobileの癖なんかをちょっとづつ
書いていこうかと思っています。

2 件のコメント:

  1. 役に立ちました。ありがとうございました。

    返信削除
  2. webstorageを用いたままここにさらにチェックボックスを付けたりすることは可能ですか?

    返信削除