Do You PHP はてな このページをアンテナに追加 RSSフィード Twitter

2015-05-21

[]Motorola Moto 360を買った

すでに1ヶ月前になりますが、MotorolaMoto 360を購入しました。

f:id:shimooka:20150521122355j:image

注文から届くまで

購入先はネットのコンビニAmazon.comです。「.co.jp」ではなく「.com」ですが、日本への発送も対応しています。

Motorola Moto 360 - Light Metal, 23mm, Smart Watch

f:id:shimooka:20150508120845j:image

値段は本体+送料+税で256.29USD(31,983円)。

バンドは23mmのメタルバンド(Light Metal)を選択。レザーバンドは昔夏場にひどく肌が荒れたことがあって、それ以来敬遠しています。また、18mmバンドではなくなぜ23mmにしたか?なんですが、18mmバンドと比較して注文時点で60USDも値段に差があるとさすがに厳しいです(汗)

http://f.hatena.ne.jp/shimooka/20150521122407

注文から到着までの流れですが、

  • 注文:2015/04/14
  • 発送:2015/04/15
  • 到着:2015/04/18

と言った具合で、思ったよりも全然早く到着しました。ただし、発送先の氏名が何故かメールアドレスになってしまっていたため、入管で1〜2日ほど止まっていたっぽいです(泣)

で、荷物はこんな感じ。Amazon.comのダンボールに入って到着。

f:id:shimooka:20150418102122j:image

化粧箱はこんな感じです。

f:id:shimooka:20150418102814j:image

到着が揃うよう、保護フィルムとQi充電パッドも別途注文しておきました。

f:id:shimooka:20150418102841j:image

開封の儀

開封の儀は。。。写真を撮ってあったんですが見つからないのでこちらを参照してください;-)

Moto360日本購入レビュー。初期設定方法やバッテリーの持ちなどの使用感。 - Android(アンドロイド)おすすめアプリ・カスタムニュース|AndroidLover.net

保護フィルムの貼り付け

ディスプレイ面が割れるとどうしようもないので、とりあえず高硬度のガラスフィルムを選択しました。

0.3mmとは言うものの、思ったよりも厚みがありました。まあ、Moto 360自体が思ったより厚みがあるので誤差範囲でしょう。貼り付けはスマートフォンと同様ですが、フィルムが円形なので位置合わせはそこまで難しくなかったです。

Moto 360のセットアップ

セットアップについても先ほどのサイトに詳しく書いてありますが、ハマる点としては

  • Android端末側にAndroidWearアプリインストールする必要がある
  • ペアリング完了後の処理に結構時間がかかるので、充電してからセットアップした方が良いかも(20〜30%ぐらいしか電池残量がなかった)

の2点です。

OSアップデート

セットアップが終わったら、OSを最新版に更新。つい先日Android Wear 5.1.1へのアップデートが始まりましたが購入当時では5.0.2がリリースされていました。

アップデートは、Moto 360側のメニューの

設定→端末情報→システムアップデート

から行います。アップデート後のソフトウェアバージョンが更新されていれば成功です。

f:id:shimooka:20150521130759p:image

で、通常はあまりないとは思いますが、Adblock Plus for Android等の広告フィルタAndroid FirewallなどのiptablesアプリををAndroid端末にインストールしている場合、アップデートファイルをダウンロードできない場合があります(というか、ハマった)ので、ダウンロードできない場合は

$ adb logcat

などでAndroid端末のログを確認してみてください。

開発者向けオプションメニューの有効化

Android端末をそれなりに使ってる人にはピンと来ると思いますが、Android Wearにも開発者向けオプションメニューがあり、有効にするとBluetooth経由でのadbデバッグなどが可能になります。

有効化する手順もAndroid端末と同様、端末情報メニューにある「ビルド番号」を連続タップするというものです。

f:id:shimooka:20150521130757p:image

メタルバンドの長さ調整

メタルバンドの長さですが、個人的には若干長めだったので、ヨドバシアキバの3Fにある時計修理コーナーでやってもらいました。所要時間は約10分で500円程度でした。一瞬、工具を買って自分でやろうかと思ったんですが、頻繁に調整するものでもないし素直に時計屋さんでやってもらった方が良いと思います。

インストールしているWearアプリ

あちこちで紹介されているものから個人的な好みまで、有料・無料問わずいくつか入れてあります。

  • Wear Mini Launcher
    • スワイプするとアプリドロワーを表示するアプリ。何でこの機能が標準でないのか不明なぐらい必須アプリAndroid Wear 5.1.1から機能的に追加されるらしい。また、Androidのクイック設定パネルのようにWi-FiテザリングのON/OFF、ボリューム調整などのメニューもある。
  • Slumber for Android Wear
    • 必須アプリ。充電中にスクリーンをオフにするアプリMoto 360は充電中にスクリーンオフにならず、これによるディスプレイの焼き付きが問題となっている(いた?)模様。対策としてScreen Off Wearがよく紹介されているが、現時点でGooglePlayでは公開されていないためこちらで代用。機能的には必要十分。
  • Feel The Wear
  • Wear Battery Stats
    • Android Wearのバッテリー残量を表示するアプリAndroid端末側だけではなく、Android Wear側でもグラフを表示できる。確認したところ、だいたい1時間あたり3〜6%ぐらいのバッテリー消費ペースなので、通常なら朝から夜まではバッテリーが保つ計算。ただし、Moto 360側で設定変更などをガシガシやっているとあっという間にバッテリーがなくなるので、予備のQi充電器を職場に用意するなどの対策は必要。

f:id:shimooka:20150521133958p:image

今のWatch Face

Watch Face - Minimal & Elegantを使ってます。

f:id:shimooka:20150521122416j:image

時間ごとに背景のグラデーションを変更できるのと、Little Worldsというちょっとした画像を表示できディスプレイ下のデッドスペースをうまく目立たなくさせられるのがポイント。アナログ時計じゃないので視認性はあまり良くないですが、かなりシンプルで個人的には好みです。

f:id:shimooka:20150521130758p:image

1ヶ月使ってみてどうだったか?

主に平日に朝から晩まで付けてみた感想です。

  • メタルバンドはいい感じのズッシリ感。今では、これぐらい太めのメタルバンドでも意外と良いんじゃないか?という感じ。
  • セットアップ後に操作チュートリアルがあるんだけど、あれだけで操作を覚えられる人いるのかな?最初は結構「あれ?あれれ?」な感じで操作してましたが、だいたいがタップ/ロングタップ/上下左右へのスワイプのどれかなので「あとは身体で覚えろ」的な感じがする。
  • 携帯を見なくても、手元で通知が判る&内容を確認できるのは非常に良い
  • 音声による操作は意外と認識精度が高くて便利。ただし、「腕時計に向かっていきなり話しかける」というシチュエーションは日本人にとってはハードルが高い(と思う)。
  • 手元でAndroid端末の操作(テザリングとか)ができるアプリインストールしておくと良い
  • Watch Faceを自分好みに変更できるが、種類がホントに多すぎて迷う
  • アプリによっては通知が鬱陶しいほど来るので、通知ブロックをうまく使う必要がある
  • Bluetoothの接続距離が思ったより狭いので、Android端末との接続が意外と切れる
  • Fitness機能はあまり意識してません。たまに心拍数を計るぐらいかなぁ。。。

まとめ

Androidガジェット」ということで遅ればせながら飛びついてみた感満載なわけですが、個人的には買って損はなかったかな?と思います。

ガジェットっぽくないデザインも良いし、当初予想していた通り通知機能に関しては非常に便利です。ただ、単なる「通知専用ガジェット」ならコストパフォーマンスが見合わないですかね。また、今のところAndroid端末との連携がほぼ前提になっているので、Android Wear側からAndroid側を操作できるといろいろと助かる場面が増える感じはしますが、これらもキラーアプリ/コンテンツにはなり得ないような気がします。

まあ、ここでウダウダ書かなくても皆さん何か別の「圧倒的に便利なこと」を模索してるんだろうし、これからどうなっていくかを焦らず見て行きましょうかね。何かアイデアを思いついたらWearアプリも作ってみたいし:-)

あ、あとAndroid Wear 5.1.1には期待してますよ!(が、まだ降って来てない)

2015-05-13

[]PHPからInfluxDBに繋いでみた

最近PHPからいろいろなデータベース(RDBMS以外も)に繋ぐことが多くなっていた中で、InfluxDBにも繋ぐ必要が出てきたのでざっくりまとめてみました。

間違ってる所があれば、指摘をお願いします;-)

基本的な環境

  • CentOS 6.4(x86_64, ClouderaのQuickStartVM)
  • PHP 5.6.8
  • InfluxDB 0.8.8(rpm)

InfluxDBとは

InfluxDBは時系列データを格納するためのオープンソースなデータストアで、Goで書かれています。

InfluxDB - Open Source Time Series, Metrics, and Analytics Database

とりあえず、以下のページをざっと読むと良いかと。

2015/05/12現在、最新版は0.8.8で0.9をそろそろリリースするとアナウンスされています(が、なかなか出てきません。。。)。

特徴としては、以下の様なものがあります。

  • クラスタ環境も構築可能
  • SQLに似た問い合わせ言語が用意されており、基本的な集約関数やJOINも利用可能。
  • HTTP(S) APIJSONが強力で、データ登録や問い合わせだけでなくデータベース作成などいろいろ操作できる
  • 管理画面が組み込みで用意されている

インストール

RedHatCentOS向けにrpmが用意されているので、それをインストールするのが楽チンです:-)

$ sudo rpm -ivh http://s3.amazonaws.com/influxdb/influxdb-latest-1.x86_64.rpm

InfluxDB関連のファイルは、/opt/influxdbに配置されます。設定ファイルは/opt/influxdb/shared/config.tomlです。設定オプションは、以下を参照してください。

InfluxDBを起動・停止してみる

起動・停止は、serviceコマンドで行います。

$  sudo service influxdb start
Setting ulimit -n 65536
Starting the process influxdb [ OK ]
influxdb process was started [ OK ]
$ 

起動後、8083、8086、8090、8099の4ポートでLISTENしていることを確認して下さい。

$ sudo netstat -tnlp | grep -P "80(83|86|90|99)"
tcp        0      0 0.0.0.0:8083                0.0.0.0:*                   LISTEN      12943/influxdb
tcp        0      0 0.0.0.0:8086                0.0.0.0:*                   LISTEN      12943/influxdb
tcp        0      0 0.0.0.0:8090                0.0.0.0:*                   LISTEN      12943/influxdb
tcp        0      0 0.0.0.0:8099                0.0.0.0:*                   LISTEN      12943/influxdb
$ 

LISTENできていない場合は、/opt/influxdb/shared/log.txtを確認してみてください。

管理画面を使ってデータベース作成〜データ登録する

まずはデータベースの作成を行います。HTTP(S) APIでもデータベースを作成できますが、とりあえず用意されている管理画面からデータベースを作成してみます。

1. ログインする

ブラウザから、http://[ホスト名]:8083/ にアクセスするとログイン画面が表示されます。

f:id:shimooka:20150512140857p:image

デフォルトのusernameとpasswordは"root"ですので、入力し"connect"ボタンを押下します。

2. データベースの作成

ログインすると、以下の様なデータベース一覧画面が表示されます。

f:id:shimooka:20150512143930p:image

とりあえず、"test"というデータベースを作ってみました。ここでは、データベース名に"test"と入力し、右下の"Create Database"ボタンを押下します。ここでは割愛しますが、Shard Specsではデータの保存期間やクラスタ構成時の分割数を指定します。詳細は、以下を参照してください。

データベース作成が成功すると、一覧に作成済みのデータベースが表示されます。

f:id:shimooka:20150512143931p:image

3.データベース接続用のユーザーを登録する

データベースを作成したら、データベース接続用のユーザーを追加しましょう。

先ほどの画面に表示されているデータベース一覧からデータベース名"test"をクリックすると、ユーザーの登録画面になります。

f:id:shimooka:20150513115011p:image

接続用ユーザーのユーザー名とパスワードを入力し、"Create"ボタンを押下します。

4.データを登録する

ここまでできたら、データを登録してみましょう。

画面上部のメニューの"Databases"をクリックすると先ほどのデータベース一覧画面になりますので、"Explore Data"リンクをクリックします。すると、データの参照・登録画面になりますので、下にある"Write Point"からデータを登録します。

f:id:shimooka:20150512143932p:image

InfluxDBには、RDBMSのテーブルのように"シリーズ(Series)"と呼ばれるテーブル的なものがあります。データはオブジェクトJSON形式で1レコードに相当します。この時、キーがRDBMSでいうカラム名に相当します。フォーマットの詳細は、以下を参照してください。

まずは、

  • Time Series Name:series01
  • Values:{"event": "test", "value": "123"}

と入力し、"Write Point"ボタンを押下します。

f:id:shimooka:20150512143933p:image

これでボタンの右に"200 OK"と表示されればデータ登録完了です。続けて何件かデータを登録します。

5.問い合わせを実行してみる

データをある程度登録したら、先ほどの画面の上にある"Read Points"から問い合わせを実行してみます。

"Query"に

SELECT * FROM series01

と入力し、登録済みのデータが全件出力されればOKです。

f:id:shimooka:20150512183920p:image

この時、データとしては登録していないはずの

  • time
  • sequence_number

というカラムも出力されていると思いますが、データ登録した日時のタイムスタンプ(ms単位)とシーケンス番号になります。これはInfluxDBが付与したもので、これら2カラムでユニークになります。

その他集約関数やデータ削除、シリーズの削除については、以下を参照してください。

InfluxDB-CLI

「管理画面もいいけど、やっぱ黒い画面よね」という方向けにInfluxDB-CLIというものもあります。

今のところ、Go/Ruby/Node.js製のものがあるようですが、今回はNode.js製のものをインストールしてみました。

$ sudo yum install -y nodejs npm --enablerepo=epel
$ sudo npm install influxdb-cli -g
$ 

コマンドは"influxdb-cli"です。

$ influxdb-cli --help
InfluxDB SQL CLI
Usage: influxdb-cli

Options:
  -h, --hostname  Host [%s]                             [default: "localhost"]
  --port          Port [%s]                             [default: 8086]
  -s, --secure    Use HTTPS if flag is present          [default: false]
  -u, --user      User [%s]                             [default: "root"]
  -a, --auth      HTTP basic auth [%s]                  [default: ""]
  -p, --password  Password [%s]                         [default: "root"]
  -d, --database  Database [%s]                         [default: "db"]
  --pretty        Display time in a human readable way  [default: false]

$ influxdb-cli --database=test
test> Connecting to http://localhost:8086/db/test ...
test> ✔ ready
test> select * from series01;
┌────────┬────────┬────┬───┐
│ time          │ sequence_number │ value │ event │
├────────┼────────┼────┼───┤
│ 1431424603006276961510001789test  │
│ 14314090029592769614900013     │ baz   │
│ 14314089986662769614800012     │ bar   │
│ 14314089836682769614700011     │ foo   │
│ 1431408976749276961460001456test  │
│ 1431408770502276961450001123test  │
└────────┴────────┴────┴───┘
Query took  9 ms
test>

やっぱこっちの方が扱いやすいですね:-)

PHP+InfluxDB

ようやくPHPからInfluxDBに繋げてみます(汗)

InfluxDBには各言語向けのクライアントライブラリが公開されていますので、それを使います。

2015/05/12現在、InfluxDB 0.9用と0.8.x用が公開されていますが、今回は後者を利用します。インストールはcomposerで。

$ vi composer.json
$ cat composer.json
{
    "require": {
        "crodas/influx-php": "0.1.*"
    }
}
$ ./composer.phar install
$ 

続いて、以下の様なテスト用スクリプト(test.php)を作成します。接続先のポート番号は8086です。

<?php
require_once __DIR__ . '/vendor/autoload.php';

define('INFLUXDB_HOST', 'localhost');
define('INFLUXDB_PORT', 8086);
define('INFLUXDB_NAME', 'test');
define('INFLUXDB_USER', [接続用ユーザーのユーザー名]);
define('INFLUXDB_PASS', [接続用ユーザーのパスワード]);

$client = new crodas\InfluxPHP\Client(INFLUXDB_HOST, INFLUXDB_PORT, INFLUXDB_USER, INFLUXDB_PASS);
$db = new crodas\InfluxPHP\DB($client, INFLUXDB_NAME);
$query = "SELECT * FROM series01";
try {
    var_dump($db->query($query));
} catch (Exception $e) {
    var_dump($e->getMessage());
}

で、実行。管理画面から確認したデータが取得できていればOKです。

$ php -v
PHP 5.6.8 (cli) (built: May  8 2015 14:17:31)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.2.7, Copyright (c) 2002-2015, by Derick Rethans
$ php test.php
class crodas\InfluxPHP\Cursor#4 (1) {
  private $storage =>
  array(6) {
    [0] =>
    class stdClass#5 (4) {
      public $time =>
      int(1431424603)
      public $sequence_number =>
      int(276961510001)
      public $event =>
      string(4) "test"
      public $value =>
      string(3) "789"
    }
    [1] =>
    class stdClass#6 (4) {
      public $time =>
      int(1431409002)
      public $sequence_number =>
      int(276961490001)
      public $event =>
      string(3) "baz"
      public $value =>
      string(1) "3"
    }}
$ 

データのバックアップと移行

開発用環境など「とりあえずそれなりの量のデータが入っていれば良い」という状態にしたい場合、opt/influxdb/shared/data以下のファイルをコールドバックアップ&リストアすることで、データを移行することができます。

ただし、データベースのRetensionの設定によってはデータ保持期限切れでデータが消えてしまうので、移行後にHTTP(S) APIを使ってデータベースの設定を変更する必要があるかもしれません。

$ sudo service influxdb stop
$ sudo \rm -rf /opt/influxdb/shared/data
$ sudo tar zxf data.tgz -C /opt/influxdb/shared/
$ curl -X POST "http://localhost:8086/cluster/shard_spaces/test/test?u=root&p=root" -d '{ "retentionPolicy": "inf" }'
$ sudo service influxdb start
$ 

あとは、バックアップ/リストアツールもいくつかと公開されているようなので、それを使ってみるのも手かもしれません。

まとめ

またもや「ちゃんと繋げられましたよー」で終わっちゃいますが。。。(汗)

InfluxDBへの接続自体はライブラリのお陰でほとんど苦労することなくできると思います。

あと、SQLっぽい問い合わせ言語が使えるのはメリットが大きいんですが、結構クセがあるので「えっ?」ということが多いことに注意です。

2015-05-12

[]JsViewsチュートリアル - データが更新された時に独自のイベントハンドラを実行する

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsRender入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでデータリンクしたデータの更新を監視し、独自のイベントハンドラを実行する。

コード

<html>
<body>
<div id="list"></div>
<hr/>
<button id="code">update code</button>
<button id="name">update name</button>
<button id="color">update color</button>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="js/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// リンクされたデータの更新を監視し、イベントハンドラを実行する
$(function() {
    // データのオブジェクト
    var application = {
            log: [],
            fruits: {
                code: "01",
                name: "りんご",
                color: '赤'
            }
        };

    // テンプレートに名前をつけて登録する
    $.templates({
        pathTemplate: "#template"
    });

    // テンプレートlinkTemplate(#template)と変数applicationをリンクさせ、
    // レンダリング結果をid="list"に表示
    $.link.pathTemplate("#list", application);

    $(document)
        .on('click', '#code', function(ev) {
            $.observable(application.fruits).setProperty('code', application.fruits.code + '9');
        })
        .on('click', '#name', function(ev) {
            $.observable(application.fruits).setProperty('name', application.fruits.name + '!');
        })
        .on('click', '#color', function(ev) {
            $.observable(application.fruits).setProperty('color', application.fruits.color + '色');
        })

    // application.fruitsのnameプロパティもしくはcolorプロパティが
    // 更新された場合にハンドラが実行される
    $.observe(application, 'fruits.name', 'fruits.color', function(ev, args) {
        $.observable(application.log).insert([args.path + 'が' + args.value + 'に更新されました']);
    });
});
</script>

<script id="template" type="text/x-jsrender">
    <div>
        <p><span data-link="fruits.code"></span>:<span data-link="fruits.name"></span>(<span data-link="fruits.color"></span>)</p>
    </div>
    <div>
        {^{for log tmpl="#template_log"/}}
    </div>
</script>
<script id="template_log" type="text/x-jsrender">
    <li><span data-link="#data"></span></li>
</script>
</body>
</html>

説明

データリンクしたデータが更新されたタイミングで、ログ出力や視覚的なエフェクトをかけるなど何らかのハンドラを実行したい場合があるかと思います。JsViewsではこのための仕組みも用意されています。

$.observe([対象の変数], [プロパティへのパス1], [プロパティへのパス2], ... , [イベントハンドラ])

プロパティへのパスは1つ以上指定可能で、「対象の変数」が基準となります。先ほどのコード例では、application.fruitsオブジェクト直下にあるnameプロパティもしくはcolorプロパティが更新された場合にログ出力するイベントハンドラが実行されます。

プロパティへのパスですが、ワイルドカードが使えます。例えば、application.fruitsオブジェクト直下にあるすべてのプロパティが対象であれば、

$.observe(application, 'fruits.*', function(ev, args) {});

といった具合になります。

また、イベントハンドラ引数を2つ取ります。1つ目はjQueryのイベントオブジェクト、2つ目はJsViewsのイベントオブジェクトで更新前後の値やどういう更新を行ったのか?という情報が含まれます。

また、対象の変数に存在するすべてのプロパティに対してイベントハンドラを割り当てたい場合は、次の書式が利用できます。

$.observable([対象の変数]).observeAll([イベントハンドラ])

JSFiddleで動作を見る

参照

2015-04-10

[]JsViewsチュートリアル - データリンクしたオブジェクトメソッドを呼び出す

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsRender入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでデータリンクしたオブジェクトメソッドを呼び出す。この際、データリンクした値が変更された場合にメソッド戻り値を再評価させてみる。

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// リンクされたオブジェクトのメソッドを呼び出す
$(function() {
    var data = {
        a: 'foo',
        b: 'bar',
        unlinkedFunction: function() {
            return 'hoge';
        },
        linkedFunction: function(a, b) {
            return a === b;
        },
        notLinkedFunction: function() {
            return this.a === this.b;
        },
        notLinkedFunctionWithDepends: function() {
            return this.a === this.b;
        }
    };

    // notLinkedFunctionWithDependsの戻り値はデータリンクした値に
    // 依存しているので、依存関係を定義する
    //
    //   [対象のメソッド].depends = [対象の変数, 依存するプロパティへのパス, ...]
    //
    // "*"は、dataオブジェクト直下のすべてのプロパティについて変化した
    // かどうかを監視する
    data.notLinkedFunctionWithDepends.depends = [data, '*'];

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数dataをリンク
    $.link.linkTemplate("#result", data);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
<p>テキストボックスが同じ値の場合、boolの値が変化します</p>
<div>
    <p data-link="a"></p>
    <input type="text" data-link="a trigger=true"/>
</div>
<div>
    <p data-link="b"></p>
    <input type="text" data-link="b trigger=true"/>
</div>
<p>固定値:<span data-link="unlinkedFunction()"></span></p>
<p>linkedFunction(a, b):<span data-link="linkedFunction(a, b)"></span></p>
<p>notLinkedFunction():<span data-link="notLinkedFunction()"></span></p>
<p>notLinkedFunctionWithDespanends():<span data-link="notLinkedFunctionWithDepends()"></span></p>
</script>
</body>
</html>

説明

JsRenderチュートリアル - テンプレートに渡したオブジェクトのメソッドを呼び出す - Do You PHP はてなテンプレートに渡されたオブジェクトメソッドを呼び出してみましたが、JsViewsの場合も基本的にはそのまま記述すればOKです。ただし、データリンクした値が変更された場合にメソッド戻り値を再評価したいかどうかJavaScript側のコードが変わってきます。

1. 戻り値を再評価しなくて良い場合

JsRenderと同様の記述方法でOKです。unlinkedFunctionメソッドはデータリンクした値と関連がありません。

<span data-link="unlinkedFunction()"></span>
2. 戻り値を再評価するが、引数でデータリンクした値を受け取っている場合

これもJsRenderと同様の記述方法でOKです。linkedFunctionメソッドはデータリンクした値を受け取っているので、「データリンクした値が変更された場合にメソッドを呼び出す」といった依存関係が自動的に定義されるためです。

<span data-link="linkedFunction(a, b)"></span>
3. 戻り値を再評価するが、引数でデータリンクした値を受け取っていない場合

たとえば

var variable = {
    a: {
        b: {
            c: 'foo'
            d: 'bar'
        },
        e: 'bar'
    },
    func: function() {
        return this.a.b.c > this.a.b.d && this.a.e !== 'hoge';
    }
};

という階層を持ったオブジェクトをデータリンクしても、JsViews(実際はJsObservable)にとってはfuncメソッドがどういう依存関係を持っているのか分からないため、戻り値が再評価されません。この場合は先ほど説明した依存関係を定義する必要があります

依存関係の定義方法ですが、定義したいオブジェクトメソッドのdependsプロパティとして、

配列もしくは文字列として記述します。

[対象のメソッド].depends = [対象の変数, 依存するプロパティへのパス, ...]

後者のプロパティへのパスですが、先ほど出てきたオブジェクトの場合、プロパティcへのパスは

a.b.c

また、プロパティeへのパスは

a.e

といった具合になります。また、直下のすべてのプロパティを表す"*"(アスタリスク)を指定することもできます。

ここまで踏まえた依存関係の定義例は以下のとおりになります。それぞれ、いずれの書き方でもOKです。

// variableオブジェクトのプロパティ"e"が変更された場合にのみ
// variable.funcを再評価する
variable.func.depends = [variable, 'a.e'];
variable.func.depends = [variable.a, 'e'];
variable.func.depends = 'a.e';

// variableオブジェクトのプロパティ"c"または"d"が変更された場合に
// variable.funcを再評価する
variable.func.depends = [variable, 'a.b.c', 'a.b.d'];
variable.func.depends = [variable, 'a.b.*'];
variable.func.depends = [variable.a, 'b.c', 'b.d'];
variable.func.depends = [variable.a, 'b.*'];
variable.func.depends = [variable.a.b, 'c', 'd'];
variable.func.depends = [variable.a.b, '*'];
variable.func.depends = ['a.b.c', 'a.b.d'];
variable.func.depends = ['a.b.*'];

// variableオブジェクトのすべてのプロパティについて、変更があった
// 場合にvariable.funcを再評価する
variable.func.depends = [variable, 'a.e', 'a.b.c', 'a.b.e'];
variable.func.depends = [variable, 'a.*', 'a.b.*'];
variable.func.depends = ['a.e', 'a.b.c', 'a.b.e'];
variable.func.depends = ['a.*', 'a.b.*'];

JSFiddleで動作を見る

参照

2015-04-02

[]JsRenderチュートリアル - 存在しないプロパティを参照した時のエラーを回避する

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsRender入門 - Do You PHP はてなも参照してください。

今回やること

JsRenderやJsViewsで存在しないプロパティを参照した時のエラーを回避する

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
    // データの配列(もしくはオブジェクト)
    var fruits = {
            code: "01",
            name: "りんご",
            color: {
                name: "赤"
            },
            err: function() {
                return "エラーです";
            }
        };

    $.views.helpers({
        onerror: function(message) {
            return message + "です";
        }
    });

    // テンプレートに名前をつけて登録する
    $.templates({
        fruitsTemplate: "#template"
    });

    // テンプレート"fruitsTemplate"に変数fruitsを渡し、
    // レンダリング結果をid="result"に表示
    $("#result").html($.render.fruitsTemplate(fruits));
});
</script>

<script id="template" type="text/x-jsrender">
    <div>
        <li>{{>color.name}}</li>

        {{!--
            存在するオブジェクトのundefinedなプロパティを参照しても
            エラーにならず、空文字が表示される
        --}}
        <li>{{>color.foo}}</li>

        {{!--
            #data直下のundefinedなプロパティを参照してもエラーにならず、
            空文字が表示される
        --}}
        <li>{{>foo}}</li>

        {{!--
            undefinedのプロパティを参照すると

              {Error: TypeError: data.color.foo is undefined}

            というエラーになるが、onerrorを使うとエラー時に表示する
            メッセージを指定できる
        --}}
        <li>{{>color.foo.bar onerror="barがありません"}}</li>

        {{!-- リテラルだけではなくリンクした変数やヘルパーも使える --}}
        <li>{{>color.foo.bar onerror=color.name + "です"}}</li>
        <li>{{>color.foo.bar onerror=err()}}</li>
        <li>{{>color.foo.bar onerror=~onerror("ヘルパー")}}</li>
    </div>
</script>
</body>
</html>

説明

JsRenderやJsViewsで存在しないプロパティを参照した場合、

{Error: TypeError: data.foo.bar is undefined}

のようなメッセージが表示されることがありますが、このデフォルトのメッセージではなく任意のメッセージを表示させることができます。

JsRenderでの書式は次のとおりで、変数や式に続けて"onerror="と表示するメッセージを記述します。

{{>[変数や式] onerror=[表示するメッセージ]}}

表示するメッセージには、文字列のほか、テンプレートに渡された変数の値やヘルパーも使用できます。

JsViewsの場合、データリンクしたタグ({^{...}})のほかにdata-link属性にも記述可能です。

<li data-link="color.foo.bar onerror='エラーです'"></li>

JSFiddleで動作を見る

参照

2015-04-01

[]JsViewsチュートリアル - スタイルをリンクさせる

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでスタイルと変数をリンクさせる

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<style type="text/css">
<!--
.box {
    border: 1px solid;
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
-->
</style>
<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// スタイルのリンク
$(function() {
    // 表示するデータ
    var data = {
        text: 'Hello !',
        width: 150,
        height: 100,
        bgcolor: 'lightgray'
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数dataをリンク
    $.link.linkTemplate('#result', data);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <div class="box" data-link="
        {:text}
        css-color{:bgcolor != '' ? 'white' : ''}
        css-background-color{:bgcolor}
        css-width{:width}
        css-height{:height}"
    >
    </div>
    <div>
        <p>表示するテキスト</p>
        <input type="text" data-link="text trigger=true"/>
    </div>
    <div>
        <p>幅</p>
        <select data-link="width">
        <option value="100">100</option>
        <option value="150">150</option>
        <option value="200">200</option>
        </select>
    </div>
    <div>
        <p>高さ</p>
        <select data-link="height">
        <option value="100">100</option>
        <option value="150">150</option>
        <option value="200">200</option>
        </select>
    </div>
    <div>
        <p>背景色</p>
        <select data-link="bgcolor">
        <option value="">なし</option>
        <option value="lightgray">lightgray</option>
        <option value="blue">blue</option>
        <option value="red">red</option>
        <option value="green">green</option>
        </select>
    </div>
</script>
</body>
</html>

説明

JsViewsチュートリアル - HTML要素の属性をデータリンクする - Do You PHP はてなでは属性と変数をリンクさせましたが、スタイルと直接リンクさせる事もできます。

書式ですが、属性名の代わりにプロパティ名に"css-"を付けたものになります。

data-link="css-[プロパティ名]{:[変数もしくは式]}

たとえば、colorプロパティであれば"css-color"、background-colorプロパティであれば"css-background-color"になります。

コード例では、

  • width
  • height
  • background-color

の3つを変数と直接リンクさせ、colorプロパティについてはbackground-colorプロパティの値が指定された場合に"white"となるように記述しています。

JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - HTML要素の属性値のトグル

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでHTML要素の属性値をデータリンクさせた変数の値を使ってトグルさせる

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<style type="text/css">
<!--
.label { font-weight: bold; }
.red { color: #e03fac; }
-->
</style>
<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// 属性のトグル
$(function() {
    // 表示するデータ
    var data = {
        mode: '1'
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数dataをリンク
    $.link.linkTemplate('#result', data);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <div>
        <p>現在のmode:<span data-link="mode"></span></p>
        <label for="mode1">
            <input type="radio" id="mode1" name="radio" value="1" data-link="mode"/>
            <span class="label" data-link="class{merge:mode == '1' toggle='red'}">ラジオ1</span>
        </label>
        <label for="mode2">
            <input type="radio" id="mode2" name="radio" value="2" data-link="mode"/>
            <span class="label" data-link="class{merge:mode == '2' toggle='red'}">ラジオ2</span>
        </label>
        <label for="mode3">
            <input type="radio" id="mode3" name="radio" value="3" data-link="mode"/>
            <span class="label" data-link="class{merge:mode == '3' toggle='red'}">ラジオ3</span>
        </label>
    </div>
</script>
</body>
</html>

説明

JsViewsチュートリアル - HTML要素の属性をデータリンクする - Do You PHP はてなでは属性値そのものををデータリンクした変数とリンクさせましたが、「変数が○○○の時だけ特定の属性を追加する」といった属性の値の一部をトグルさせる事もできます。

書式ですが、mergeコンバータを使って次のようになります。

data-link="[属性名]{merge:[変数もしくは式] toggle='[トグルさせる値]'}

変数もしくは式がtrueと判定された場合に限り、指定した属性名に"トグルさせる値"が追加されます。それ以外の場合は追加されません。

たとえば、「特定の場合だけclass属性に"active"というクラスを追加する」といった感じです。コード例では、ラジオボタンが選択された場合のみラベルに色を付けています。

なお、最初から指定されていた属性値はtoggleによる影響を受けません。コード例の場合だと、"label"クラスは上書きされずに残ります。

JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - データリンクの方向性

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsのデータリンクが一方向・双方向の2種類あることを確認する

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// データリンクの方向性
$(function() {
    // 表示するデータ
    var message = {
        greet: 'Hello !'
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <div>
        <p><span data-link="greet"></span></p>

        {{!-- 変数名(triggerを含む)の前にのみ":"を付けた場合は一方向リンク --}}
        <p>一方向:data-link="{:greet trigger=true}"</p>
        <div><input data-link="{:greet trigger=true}"/></div>

        {{!-- 変数名(triggerを含む)の前後に":"を付けた場合は双方向リンク --}}
        <p>双方向:data-link="{:greet trigger=true:}"</p>
        <div><input data-link="{:greet trigger=true:}"/></div>

        {{!-- 変数名(triggerを含む)だけの場合は1番目の記述方法の省略形(双方向リンク) --}}
        <p>双方向:data-link="greet trigger=true"</p>
        <div><input data-link="greet trigger=true"/></div>
    </div>
</script>
</body>
</html>

説明

JsViewsチュートリアル - フォーム要素とデータリンク(チェックボックス+コンバータ) - Do You PHP はてなでも軽く触れましたが、JsViewsのdata-link属性に変数を記述する際、記述方法によって変更した値をリンクした変数に反映するかどうかが決まります。

JsViewsでのデータの流れは、先のエントリでも若干説明しましたが、大まかに以下のようになります。

変数 → [値] → [コンバータによる変換] → data-link属性を付けたHTML要素 → [変更された値] → [コンバータによる変換] → 変数

一方、data-link属性の値は、正しくは先のエントリにある

data-link="{[変数を取得する際のコンバータ]:[変数名]:[変数を書込む際のコンバータ]}"

という記述方法になります。各コンバータは省略可能です。先ほどのデータの流れに対応してるのが分かりますかね?

また、変数とコンバータの区切りに":"(コロン)を付けていますが、これが"どの方向に対してデータをリンクするか"を表しています。たとえば、上のように変数名の前後に":"を付けると、データの流れが

  • 変数→HTML要素
  • 変数←HTML要素

という双方向になります。これは双方向(two-way)データリンクと呼ばれます。

一方、後ろの":"以降を省略すると

data-link="{[コンバータA]:[変数名]}"

となりますが、データの流れは

変数 → [値] → [コンバータAによる変換] → data-link属性を付けたHTML要素

という具合に

  • 変数→HTML要素

という流れのみになるので、一方向(one-way)データリンクと呼ばれます。結果として、変更した値は変数に反映されません

また、

data-link="{:[変数名]:}"

とすれば

変数 → [値] → data-link属性を付けたHTML要素 → [変更された値] → 変数

になりますが、これは今までの説明で出てきた

data-link="[変数名]"

と等価になります。

なお、変数名の前の":"のみ省略する、ということはできません。

ちなみに、フォーム要素以外のHTML要素の場合、リンクされた値を直接変更する手段がありませんので、一方向・双方向のいずれの記述方法でも結果的に一方向となります。


JSFiddleで動作を見る

参照

2015-03-31

[]JsViewsチュートリアル - HTML要素の属性をデータリンクする

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでHTML要素の属性をデータリンクさせる

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<p>テキストボックスに入力すると表示されたデータが更新される</p>
<div id="result"></div>

<style type="text/css">
<!--
.green { color: #3fe0ac; }
-->
</style>
<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// 属性をリンクさせる
$(function() {
    // 表示するデータ
    var message = {
        greet: 'Hello !',
        color: 'green',
        type: 'password',
        id: 'message',
        multiple: true
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <div>
        <p><span data-link="{:greet} class{:color}"></span></p>
        <div><input data-link="{:greet trigger=true} type{:type} id{:id}"/></div>

        <select id="select" data-link="multiple{:multiple}">
        <option value="1">セレクト1</option>
        <option value="2">セレクト2</option>
        <option value="3">セレクト3</option>
        </select>
    </div>
</script>
</body>
</html>

説明

1つ前のエントリと同様、JsViewsではフォーム要素のvalue値や可視性(visibility)だけではなく、classやtype、idなど他のHTML属性ともリンクさせることができます。

書式は次のようになります。1つ前のエントリの一般形ですね。

<[HTML要素名] ... data-link="[属性名]{:[変数もしくは式]} ..." />

また、以下のように複数同時に設定することも可能です。1つ前のエントリにあるvisibleも同様です。

<div data-link="id{:id} class{:color} visible{:visibility}">...</div>

ただし、"input要素のvalue属性の値と、他の属性値を同時に指定したい"といった場合、前者の書き方を以下のようにする必要があります。

{:[変数名]:}

これを

{:[変数名]}

としてしまうと、フォーム要素で変更した値がリンクした変数に反映されません。一方、span要素やdiv要素など、値を変更することができない要素の場合はいずれの記述でも問題ありません。

JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - visibilityをリンクする

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsで変数の値と可視性(visibility)をリンクさせる

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<p>テキストボックスに入力すると表示されたデータが更新される</p>
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// visibilityをリンクさせる
$(function() {
    // 表示するデータ
    var message = {
        greet: 'Hello !'
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <div>
        <p><span class="red" data-link="visible{:greet == 'Hello'}">"Hello"以外を入力してください</span></p>
        <div><input type="text" data-link="greet trigger=true"/></div>
    </div></script>
</body>
</html>

説明

JsViewsではフォーム要素のvalue値だけではなく、可視性(visibility)とリンクさせることができます。

書式は次のようになります。

<[HTML要素名] ... data-link="visibile{:[変数もしくは式]}" />

JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - フォーム要素とデータリンク(チェックボックス+コンバータでvalue属性の値を使う)

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでチェックボックスをデータリンクさせ、コンバータで変数に格納する値をvalue属性の値に変更する

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// フォーム要素とデータリンク
$(function() {
    $.views.converters({
        preCheckboxWithValue: function (value) {
//            console.log(this);
            var v = this.linkCtx.elem.value ? this.linkCtx.elem.value : null;
            return value === v ? true : false;
        },
        postCheckboxWithValue: function (value) {
//            console.log(this);
            var v = this.linkCtx.elem.value ? this.linkCtx.elem.value : null;
            return value == true ? v : null;
        }
    });

    // 表示するデータ
    var message = {
        check_as_value: null
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <p>check_as_value=<span data-link="check_as_value"></span></p>

    <div>
        <label for="check_as_value"><input id="check_as_value" type="checkbox" value="bar" data-link="{preCheckboxWithValue:check_as_value:postCheckboxWithValue}"/>チェックボックス</label>
    </div>
</script>
</body>
</html>

説明

1つ前のエントリではコンバータを使ってチェックボックスとデータリンクさせた場合の値を"0"と"1"に変換する例を見てきましたが、どうせならチェックボックスのvalue属性の値にしたいですよね?

コンバータとして定義した関数内では、自身を表す"this"を使って現在対象となっている要素やViewオブジェクトなどの"コンテキスト情報"を取得することができます。

たとえば、現在のコンバータが対象としている変数はtagCtx(タグコンテキスト)を使って

this.tagCtx.params.args

その値は

this.tagCtx.args

また、リンクされた変数の値は

this.linkCtx._val

といった具合です。実際にコンバータ関数の中でconsole.log()等で値を確認してみると良いです。

で、この中に、現在コンバータが対象としているHTML要素も

this.linkCtx.elem

で取得でき、そのvalue属性の値を

this.linkCtx.elem.value

で参照できます。これを使うことでvalue属性の値を結果の値とすることができます。

JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - フォーム要素とデータリンク(チェックボックス+コンバータ)

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでチェックボックスをデータリンクさせ、コンバータで変数に格納する値を変更する

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// フォーム要素とデータリンク
$(function() {
    $.views.converters({
        preCheckbox: function (value) {
            return value == '1' ? true : false;
        },
        postCheckbox: function (value) {
            return value == true ? '1' : '0';
        }
    });

    // 表示するデータ
    var message = {
        check_as_value: '0'
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <p>check=<span data-link="check"></span></p>

    <div>
        <label for="check_as_value"><input id="check_as_value" type="checkbox" data-link="{preCheckbox:check_as_value:postCheckbox}"/>チェックボックス</label>
    </div>
</script>
</body>
</html>

説明

1つ前のエントリではチェックボックスとデータリンクさせた場合、値がbool型(true・false)になることを見てきましたが、"0"と"1"で表したほうが良い場合が多々あると思います。この場合、コンバータを使うことで解決できます。

これまでは、表示形式を変更するためにコンバータを使ってきましたが、リンクした値を変更する場合にも使えます。また、

  • リンクした変数から値を取得する
  • リンクした変数に値を格納する

という2つのタイミングでコンバータを使用できます。イメージ的には次のようなフローになります。

変数 → [値を取得] → input要素 → [値を格納] → 変数

2つコンバータを使用する場合のテンプレート側の書き方は以下のようになります。

{[コンバータ(前)]:[変数]:[コンバータ(後)]}

先ほどのフローを書き換えると次のようになります。

変数 → [コンバータ(前)] → input要素 → [コンバータ(後)] → 変数

たとえば、今回のチェックボックスの場合、input要素ではtrue・falseでチェックボックスのオン・オフを切り替えますが、最終的な値は1か0としたいので、

  • コンバータ(前)では、1・0をそれぞれtrue・falseに変換する
  • コンバータ(後)では、true・falseをそれぞれ1・0に変換する

とすれば良い、ということになります。

変数 → [1・0をtrue・falseに変換] → input要素 → [true・falseを1・0に変換] → 変数

コンバータの書式はJsRenderチュートリアル - 独自のコンバータを作る - Do You PHP はてなと同じです。以下のpreCheckbox、postCheckboxというコンバータが、それぞれコンバータ(前)、コンバータ(後)に相当します。

$.views.converters({
    preCheckbox: function (value) {
        return value == '1' ? true : false;
    },
    postCheckbox: function (value) {
        return value == true ? '1' : '0';
    }
});

また、テンプレート側は次のように変数check_as_valueがpreCheckboxとpostCheckboxに挟まれた形になります。

<input id="check_as_value" type="checkbox" data-link="{preCheckbox:check_as_value:postCheckbox}"/>

JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - フォーム要素とデータリンク(チェックボックス)

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでチェックボックスをデータリンクさせる

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// フォーム要素とデータリンク
$(function() {
    // 表示するデータ
    var message = {
        check: false
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <p>check=<span data-link="check"></span></p>

    <div>
        <label for="check"><input id="check" type="checkbox" data-link="check"/>チェックボックス</label>
    </div>
</script>
</body>
</html>

説明

フォーム要素と変数の値をデータリンクさせたい場合、基本的には、JsViewsチュートリアル - まずはHello World - Do You PHP はてなで出てきたdata-link属性を使ってリンクしたい変数を指定します。今回はチェックボックス(input要素のtype属性が"checkbox")の例です。

基本的にはselect要素やラジオボタンと同様、チェックボックスにdata-link属性を付けてリンクさせる変数を指定します。

<input id="check" type="checkbox" data-link="check"/>

ブラウザ上から選択された項目が変更されたタイミングで変数の値が変化します。ただし、値がvalue属性の値ではなくbool型(true/false)になることに注意してください。


JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - フォーム要素とデータリンク(ラジオボタン)

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでラジオボタンをデータリンクさせる

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
// フォーム要素とデータリンク
$(function() {
    // 表示するデータ
    var message = {
        radio: '1'
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <p>radio=<span data-link="radio"></span></p>

    <div>
        <label for="radio1"><input id="radio1" type="radio" name="radio" value="1" data-link="radio"/>ラジオ1</label>
        <label for="radio2"><input id="radio2" type="radio" name="radio" value="2" data-link="radio"/>ラジオ2</label>
        <label for="radio3"><input id="radio3" type="radio" name="radio" value="3" data-link="radio"/>ラジオ3</label>
    </div>
</script>
</body>
</html>

説明

フォーム要素と変数の値をデータリンクさせたい場合、基本的には、JsViewsチュートリアル - まずはHello World - Do You PHP はてなで出てきたdata-link属性を使ってリンクしたい変数を指定します。今回はラジオボタン(input要素のtype属性が"radio")の例です。

基本的にはselect要素と同様、ラジオボタンにdata-link属性を付けてリンクさせる変数を指定します。通常、複数のラジオボタンを用意すると思いますが、そのいずれにもdata-link属性と同じ変数を指定します。

<input type="radio" name="radio" value="1" data-link="radio"/>
<input type="radio" name="radio" value="2" data-link="radio"/>
<input type="radio" name="radio" value="3" data-link="radio"/>

ブラウザ上から選択された項目が変更されたタイミングで変数の値が変化し、値はvalue属性の値になります。


JSFiddleで動作を見る

参照

[]JsViewsチュートリアル - フォーム要素とデータリンク(select要素)

JavaScript製でjQuery非依存なテンプレートエンジンであるJsRender/JsViewsを使ったチュートリアルを書いてみようと思います。

以前に書いたエントリJsViews入門 - Do You PHP はてなも参照してください。

今回やること

JsViewsでselect要素をデータリンクさせる

コード

<html>
<body>

<!-- レンダリング結果を表示するスペース -->
<div id="result"></div>

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="http://www.jsviews.com/download/jsviews.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
    // 表示するデータ
    var message = {
        select: '2',
        multiple: [1, 3]
    };

    // テンプレートに名前(ここでは"linkTemplate")をつけて登録する
    $.templates({
        linkTemplate: "#template"
    });

    // テンプレート"linkTemplate"と変数messageをリンク
    $.link.linkTemplate('#result', message);
});
</script>

<!-- テンプレート -->
<script id="template" type="text/x-jsrender">
    <p>select=<span data-link="select"></span></p>
    <p>multiple=<span data-link="multiple"></span></p>

    <div>
        <select id="select" data-link="select">
            <option value="1">セレクト1</option>
            <option value="2">セレクト2</option>
            <option value="3">セレクト3</option>
        </select>
    </div>
    <div>
        <select id="multiple" multiple data-link="multiple">
            <option value="1">マルチプル1</option>
            <option value="2">マルチプル2</option>
            <option value="3">マルチプル3</option>
        </select>
    </div>
</script>
</body>
</html>

説明

フォーム要素と変数の値をデータリンクさせたい場合、基本的には、JsViewsチュートリアル - まずはHello World - Do You PHP はてなで出てきたdata-link属性を使ってリンクしたい変数を指定します。今回はselect要素(プルダウン)の例で、単一選択と複数選択の2種類の動作が確認できるサンプルです。

select要素にdata-link属性を付け、リンクさせる変数を指定します。

<select id="select" data-link="select"></select>

ブラウザ上から選択された項目が変更されたタイミングで変数の値が変化し、値はoption要素のvalue属性の値(文字列)になります。また、multiple属性を付けた場合も同様ですが、変数の値は文字列配列、非選択時はnullになります。


JSFiddleで動作を見る

参照