読者です 読者をやめる 読者になる 読者になる

牌語備忘録 -pygo

あくまでもメモです。なるべくオフィシャルの情報を参照してください。

牌語備忘録 -pygo

続『iPhoneアプリケーション開発ガイド――HTML+CSS+JavaScriptによる開発手法』5章 クライアントサイドのストレージ を jQuery Mobile に書き換えてみた。

HTML Javascript CSS

main.js若干修正

4章 アニメーション効果 を jQuery Mobile に書き換えてみた。』の続き
サンプルが jQTouch だったので jQuery Mobil でやってみた。


ファイル構成

  • img/button.png
    • jQTouch の /themes/jqt/img/button.png をコピーして preview.appで色変えてみた。


HTML

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Kilo</title>
    <link rel="stylesheet" href="jq/jquery.mobile-1.0b3.min.css" />
    <link rel="stylesheet" href="kilo.css" />
    <script type="text/javascript" src="jq/jquery-1.6.4.min.js"></script>
    <script type="text/javascript" src="jq/jquery.mobile-1.0b3.min.js"></script>
    <script type="text/javascript" src="phonegap-1.0.0.js"></script>
    <script type="text/javascript" src="main.js"></script>
  </head>


  <body>
    <div data-role="page" id="home">
      <div data-role="header" data-theme="c">
        <h1>Kilo</h1>
        <a href="#settings" data-transition="flip" data-role="button" data-icon="gear" class="ui-btn-right settingsButton">設定</a>
      </div>
      <div data-role="content">
        <ul data-role="listview" data-theme="c">
          <li><a href="#dates">日付一覧</a></li>
          <li><a href="#about">Kiloについて</a></li>
        </ul>
      </div>
    </div>


    <div data-role="page" id="dates">
      <div data-role="header" data-theme="c">
        <h1>日付一覧</h1>
        <a href="#home" data-transition="slide" data-direction="reverse" data-role="button" data-icon="arrow-l">戻る</a>
      </div>
      <div data-role="content">
        <ul data-role="listview" data-theme="c">
          <li><a id="0" href="#date">今日</a></li>
          <li><a id="1" href="#date">昨日</a></li>
          <li><a id="2" href="#date">2日前</a></li>
          <li><a id="3" href="#date">3日前</a></li>
          <li><a id="4" href="#date">4日前</a></li>
          <li><a id="5" href="#date">5日前</a></li>
        </ul>
      </div>
    </div>


    <div data-role="page" id="about">
      <div data-role="header" data-theme="c">
        <a href="#home" data-transition="slide" data-direction="reverse" data-role="button" data-icon="arrow-l">戻る</a>
        <h1>Kiloについて</h1>
      </div>
      <div data-role="content">
        <p>Kiloを使うと、毎日の食事を簡単に記録できます。</p>
      </div>
    </div>


    <div data-role="page" id="date">
      <div data-role="header" data-theme="c">
        <a href="#dates" data-transition="slide" data-direction="reverse" data-role="button" data-icon="arrow-l">戻る</a>
        <h1>その日の食べ物</h1>
        <a href="#createEntry" data-transition="slideup" data-role="button" data-icon="plus">追加</a>
      </div>
      <ul data-role="listview">
        <li id="entryTemplate" class="entry" style="display:none">
          <span class="label">ラベル</span>
          <span class="calories">000</span>
          <span class="delete">削除</span>
        </li>
      </ul>
    </div>


    <div data-role="page" id="settings">
      <div data-role="header" data-theme="c">
        <a href="#home" data-transition="flip" data-direction="reverse" data-rel="back">キャンセル</a>
        <h1>設定</h1>
      </div>
      <div data-role="content">
        <form method="post">
          <div data-role="fieldcontain">
            <p><input placeholder="年齢" type="number" name="age" id="age" /></p>
            <p><input placeholder="体重" type="number" name="weight" id="weight" /></p>
            <p><input placeholder="上限カロリー" type="number" name="budget" id="budget" /></p>
            <br />
            <!-- <input type="submit" class="submit" name="action" value="変更を保存" />  -->
            <a href="#home" class="aButton" data-transition="flip" data-direction="reverse" data-role="button">変更を保存</a>
          </div>
        </form>
      </div>
    </div>

    

    <div data-role="page" id="createEntry">
      <div data-role="header" data-theme="c">
        <a href="#date" data-transition="slidedown">キャンセル</a>
        <h1>新規エントリ</h1>
      </div>
      <div data-role="content">
        <form method="post">
          <div data-role="fieldcontain">
            <p><input placeholder="食べ物" type="text" name="food" id="food" autocapitalize="off" autocorrect="off" autocomplete="off" /></p>
            <p><input type="number" placeholder="カロリー" name="calories" id="calories" autocapitalize="off" autocorrect="off" autocomplete="off" /></p>
            <br />
            <!-- <input type="submit" class="submit" name="action" value="変更を保存" data-rel="back" /> -->
            <a href="#hame" class="aButton" data-transition="slidedown" data-role="button" data-rel="back">エントリを保存</a>
          </div>
        </form>
      </div>
    </div>
  </body>
</html>

Javascript

main.js

var db;
$(document).ready(function() {
    $('#createEntry form .aButton').click(createEntry);
    // $('#settings form').submit(saveSettings);
    $('#settings form .aButton').click(saveSettings);
    $('#home .settingsButton').bind('click', loadSettings);
    // $('#settings').ready(loadSettings);
    $('#settings').live('pagebeforeshow', function(e, ui) {
        loadSettings();
    });    $('#dates li a').click(function() {
        var dayOffset = this.id;
        var date = new Date();
        date.setDate(date.getDate() - dayOffset);
        sessionStorage.currentDate =
            date.getMonth() + 1 + '/' +
            date.getDate() + '/' +
            date.getFullYear();
        refreshEntries();
    });
    var shortName = 'kilo';
    var version = '1.0';
    var displayName = 'Kilo';
    var maxzSize = 65536;
    db = openDatabase(shortName, version, displayName, maxzSize);
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'CREATE TABLE IF NOT EXISTS entries ' +
                    ' (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
                    ' date DATE NOT NULL, food TEXT NOT NULL,  ' +
                    ' calories INTEGER NOT NULL );'
            );
        }
    );
});

function saveSettings() {
    localStorage.age = $('#age').val();
    localStorage.budget = $('#budget').val();
    localStorage.weight = $('#weight').val();
}

function loadSettings() {
    $('#age').val(localStorage.age);
    $('#budget').val(localStorage.budget);
    $('#weight').val(localStorage.weight);
}

function refreshEntries() {
    var currentDate = sessionStorage.currentDate;
    $('#date h1').text(currentDate);
    $('#date ul li:gt(0)').remove();
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'SELECT * FROM entries WHERE date = ? ORDER BY food;',
                [currentDate],
                function(transaction, result) {
                    for (var i = 0; i < result.rows.length; i++) {
                        var row = result.rows.item(i);
                        var newEntryRow = $('#entryTemplate').clone();
                        newEntryRow.removeAttr('id');
                        newEntryRow.removeAttr('style');
                        newEntryRow.data('entryId', row.id);
                        newEntryRow.appendTo('#date ul');
                        newEntryRow.find('.label').text(row.food);
                        newEntryRow.find('.calories').text(row.calories);
                        newEntryRow.find('.delete').click(function() {
                            var clickedEntry = $(this).parent();
                            var clickedEntryId = clickedEntry.data('entryId');
                            deleteEntryById(clickedEntryId);
                            clickedEntry.slideUp();
                        });
                    }
                },
                errorHandler
            );
        }
    );
}

function createEntry() {
    var date = sessionStorage.currentDate;
    var calories = $('#calories').val();
    var food = $('#food').val();
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'INSERT INTO entries (date, calories, food) VALUES (?, ?, ?);',
                [date, calories, food],
                function() {
                    refreshEntries();
                },
                errorHandler
            );
        }
    );
    // return false; // use jQTouch
}

function errorHandler(transaction, error) {
    alert('「'+error.message+'」のエラー(コード:'+error.code+')が発生したようです');
    return true;
}


function deleteEntryById(id) {
    db.transaction(
        function(transaction) {
            transaction.executeSql('DELETE FROM entries WHERE id=?;',
                                   [id], null, errorHandler);
        }
    );
}

CSS

kilo.css

#date ul li {
  position: relative;
  
}

/* #date ul li span { */
/*   color: #FFFFFF; */
  
/* } */

#date ul li .delete {
  position: absolute;
  top: 5px;
  right: 6px;
  font-size: 12px;
  line-height: 30px;
  padding: 0 3px;
  border-width: 0 5px;
    -webkit-border-image: url(img/button.png) 0 5 0 5;
}

#date ul li .delete:hover  {
  opacity:0.6;
  /* IE7 */
  filter:alpha(opacity=60);
  /* IE8 */
  ms-filter:"alpha(opacity=60)";
}