JavaScript(ECMAScript5)ではクラスを作成することができません。ECMAScript2015になって、ようやくクラスを使えるようになりました。しかしレガシーなブラウザでは実装されていないため、Babelのようなライブラリを使ってコードを変換するのが一般的です。
JavaScriptではprototypeやdefinePropertyなどを使ってクラス(的なもの)を実装しますが、hifiveではそういった面倒な仕組みを意識することなくクラスを実装できるモジュールを開発しました。この機能は1.3.1以降で利用できます。
今回はクラスのフィールド、アクセサについて紹介します
フィールドについて
フィールドはインスタンスで用いる変数になります。基本的に外部から直接変更することはありません。defaultValueを使って規定値を設定できます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var HelloClass = h5.cls.RootClass.extend(function (super_) { | |
| return { | |
| // クラス名(完全修飾名) | |
| name: 'HelloClass', | |
| // クラスのフィールド定義 | |
| field: { | |
| _name: null, | |
| _scale: { | |
| defaultValue: 0 | |
| }, | |
| _read: { | |
| defaultValue: "This is read only" | |
| } | |
| }, | |
| } |
アクセサについて
フィールドにアクセスするためのget/setメソッドを提供するのがアクセサです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var HelloClass = h5.cls.RootClass.extend(function (super_) { | |
| return { | |
| // クラス名(完全修飾名) | |
| name: 'HelloClass', | |
| // クラスのフィールド定義 | |
| field: { | |
| _name: null, | |
| _scale: { | |
| defaultValue: 0 | |
| }, | |
| _read: { | |
| defaultValue: "This is read only" | |
| } | |
| }, | |
| accessor: { | |
| accessible: null, | |
| scale: { | |
| get: function() { | |
| return this._scale; | |
| }, | |
| set: function(val) { | |
| this._scale = val * 100; | |
| } | |
| }, | |
| read: { | |
| get: function() { | |
| return this._read; | |
| } | |
| } | |
| }, | |
| } | |
| } |
アクセサ名をnullで定義した場合、自動的に _p_アクセサ名 でget/setが定義されます。また、getだけを定義した場合は読み取り専用のアクセサになります。
アクセサはフィールドにそのまま値を入れるだけでなく、計算した上で入力/出力できます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| scale: { | |
| get: function() { | |
| return this._scale; | |
| }, | |
| set: function(val) { | |
| this._scale = val * 100; | |
| } | |
| }, | |
| hello.scale = 200; | |
| hello.scale // -> 20000 |
読み取り専用にするために
JavaScriptの 'use strict'; を使うことで読み取り専用のアクセサに書き込みを行おうとしたり、存在しないアクセサへのアクセスをエラーにできます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // これはエラーになります | |
| try{ | |
| hello.read = "Update string"; | |
| }catch(e) { | |
| result.val(result.val() + "\n" + e); | |
| } | |
| result.val(result.val() + "\n" + hello.read); | |
| // これはエラーになります | |
| try{ | |
| hello.unknown = "Update!"; | |
| }catch(e) { | |
| result.val(result.val() + "\n" + e); | |
| } |
適切に開発していくためにも 'use strict'; を使っていくべきでしょう。
今回のコードは JSFiddle にアップロードしてあります。実装時の参考にしてください。
サーバサイドの開発に慣れている方にとってはクラスや継承は当たり前のものでしょう。これによって実装がとても簡単に、生産性高いものになるはずです。ぜひhifiveのクラス機能を使いこなしてください。
JavaScript(ECMAScript5)ではクラスを作成することができません。ECMAScript2015になって、ようやくクラスを使えるようになりました。しかしレガシーなブラウザでは実装されていないため、Babelのようなライブラリを使ってコードを変換するのが一般的です。
JavaScriptではprototypeやdefinePropertyなどを使ってクラス(的なもの)を実装しますが、hifiveではそういった面倒な仕組みを意識することなくクラスを実装できるモジュールを開発しました。この機能は1.3.1以降で利用できます。
今回はクラスの基本機能でもある継承について紹介します。
ベースになるクラスについて
まずベースになるクラス、AnimalClassについて紹介します。名前と鳴き声を紹介するメソッドがあります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var AnimalClass = h5.cls.RootClass.extend(function (super_) { | |
| return { | |
| // クラス名(完全修飾名) | |
| name: 'AnimalClass', | |
| // クラスのフィールド定義 | |
| field: { | |
| _name: null, | |
| _voice: null | |
| }, | |
| // クラスのメソッド定義 | |
| method: { | |
| constructor: function (params) { | |
| // 親クラスのコンストラクタ呼び出し | |
| super_.constructor.call(this); | |
| this._name = params; | |
| }, | |
| hello: function() { | |
| return this._name; | |
| }, | |
| cry: function(name, voice) { | |
| return name + "'s crying voice is " + voice; | |
| } | |
| } | |
| }; | |
| }); | |
継承する
このAnimalClassを継承するクラスとして、DogClassとCatClassを作成します。この時、 AnimalClass.extend を使います。コンストラクタは必須のメソッドになります。また、この時点で親のフィールド(voice)にアクセスできます。親のコンストラクタを呼び出す際には
`super.constructor.call(this, params);` を使います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var DogClass = AnimalClass.extend(function (super_) { | |
| return { | |
| name: 'DogClass', | |
| method: { | |
| constructor: function (params) { | |
| super_.constructor.call(this, params); | |
| this._voice = 'bow wow'; | |
| }, | |
| cry: function() { | |
| return super_.cry(this._name, this._voice); | |
| } | |
| } | |
| } | |
| }); |
CatClassも殆ど同じ実装になります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var CatClass = AnimalClass.extend(function (super_) { | |
| return { | |
| name: 'CatClass', | |
| method: { | |
| constructor: function (params) { | |
| super_.constructor.call(this, params); | |
| this._voice = 'mew'; | |
| }, | |
| cry: function() { | |
| return super_.cry(this._name, this._voice); | |
| } | |
| } | |
| } | |
| }); | |
このように共通化される機能は親クラスに入れられるようになります。
使い方
継承したクラスは通常のクラスと同じように実装できます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var dog = Animal.DogClass.create('Hachi'); | |
| $("#dog").val(dog.cry()); | |
| // -> Hachi's crying voice is bow wow | |
| var cat = Animal.CatClass.create('Tama'); | |
| $("#cat").val(cat.cry()); | |
| // -> Tama's crying voice is mew |
サーバサイドの開発に慣れている方にとってはクラスや継承は当たり前のものでしょう。これによって実装がとても簡単に、生産性高いものになるはずです。ぜひhifiveのクラス機能を使いこなしてください。
大きなシステムが機能やサービスごとに分割して開発されるように、フロントエンドにおいても一つのコントローラですべてを管理するのではなく、複数のコントローラに分けて実装する方が効率的です。
今回はhifiveで複数のコントローラを分ける実装方法について紹介します。
実装例はJSFiddleにあります。参考にしてください。

概要
まず大事なのは全体を統括するコントローラの存在です。その中に個々の機能を実装するコントローラが複数存在します。つまり全体を統括するコントローラは機能実装はせず、コントローラ同士をつなぐ役割に徹するのが良いでしょう。
HTMLについて
HTMLは次のようになります。全体として #container があり、その中に子コントローラ用の #container1 、 #container2 があります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div id="container"> | |
| <div id="container1"> | |
| <input type="text" id="text" /> | |
| </div> | |
| <div id="container2"> | |
| <p class="message">ここにメッセージがきます | |
| </p> | |
| </div> | |
| </div> |
JavaScriptについて
JavaScriptの実装ですが、まず子コントローラを定義します。まずテキストが入力されたタイミングでイベントハンドリングを行うコントローラです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(function() { | |
| var controller = { | |
| __name: 'aController', | |
| '#text keyup': function(cotnext, $el) { | |
| let text = this.$find("#text").val(); | |
| this.trigger('sendMessage', { | |
| text: text | |
| }) | |
| } | |
| } | |
| h5.core.expose(controller); | |
| }); |
次に親コントローラから送られてきたメッセージを表示するコントローラです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(function() { | |
| var controller = { | |
| __name: 'bController', | |
| getMessage: function(message) { | |
| this.$find(".message").text(message); | |
| } | |
| } | |
| h5.core.expose(controller); | |
| }); | |
最後にこの2つのコントローラをつなぐ親コントローラです。大事なのは __meta の中で子コントローラごとにrootElementとして監視するDOMを指定しておくことです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(function() { | |
| var controller = { | |
| __name: 'parrentController', | |
| _sendController: aController, | |
| _buttonController: bController, | |
| __meta: { | |
| _sendController: { | |
| rootElement: '#container1' | |
| }, | |
| _buttonController: { | |
| rootElement: '#container2' | |
| } | |
| }, | |
| __ready: function() { | |
| }, | |
| '{rootElement} sendMessage': function(context) { | |
| let text = context.evArg.text; | |
| this._buttonController.getMessage(text); | |
| } | |
| } | |
| h5.core.controller('#container', controller); | |
| }); |
実際の処理のハンドリングについては以下のように、まず子コントローラからトリガーを使って親コントローラへ通知します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| this.trigger('sendMessage', { | |
| text: text | |
| }) |
親コントローラでは {rootElement} という定義を使って受け取ります。こちらでは子コントローラのメソッドを直接呼び出します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| '{rootElement} sendMessage': function(context) { | |
| let text = context.evArg.text; | |
| this._buttonController.getMessage(text); | |
| } |
そして子コントローラで表示処理を行います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| getMessage: function(message) { | |
| this.$find(".message").text(message); | |
| } |
このように実装することでDOMごとにコントローラを分けて権限を管理しつつ、相互にメッセージのやり取りができるようになります。ごく小さなWebアプリケーションであれば一つのコントローラで良いですが、ある程度大きくなるのが予想される場合はあらかじめコントローラ連携を念頭に作るのが良いでしょう。
詳細は13.コントローラの連携 – hifiveを参照してください。
JavaScript(ECMAScript5)ではクラスを作成することができません。ECMAScript2015になって、ようやくクラスを使えるようになりました。しかしレガシーなブラウザでは実装されていないため、Babelのようなライブラリを使ってコードを変換するのが一般的です。
JavaScriptではprototypeやdefinePropertyなどを使ってクラス(的なもの)を実装しますが、hifiveではそういった面倒な仕組みを意識することなくクラスを実装できるモジュールを開発しました。この機能は1.3.1以降で利用できます。
今回はまず基本的な構造を紹介します。次のように書きます。重要なのは h5.cls.RootClass.extend になります。そして、 _super (親クラス)を引数として、オブジェクトを返却します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var SampleClass = h5.cls.RootClass.extend(function (super_) { | |
| return { | |
| // クラス名(完全修飾名) | |
| name: 'SampleClass', | |
| // クラスのフィールド定義 | |
| field: { | |
| }, | |
| // クラスのプロパティ(アクセサ)定義 | |
| accessor: { | |
| }, | |
| // クラスのメソッド定義 | |
| method: { | |
| constructor: function (initialValue) { | |
| }, | |
| } | |
| }; | |
| }); |
オブジェクトには基本的なキーとして name/field/accessor/method があります。それぞれクラス名、フィールド名、プロパティ、メソッドの4つになります。
フィールドの利用
例えばフィールドは次のようになります。_ではじめるのがルールです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| field: { | |
| _count: null | |
| }, |
プロパティの利用
プロパティは次のようになります。こちらは_を使いません。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| accessor: { | |
| scale: null | |
| }, |
メソッドの利用
メソッドは初期で読み込まれるconstructor以外は自由に定義できます。クラスのインスタンスを作成する際に値を送ることもできます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| method: { | |
| constructor: function (initialValue) { | |
| // 親クラスのコンストラクタ呼び出し | |
| super_.constructor.call(this); | |
| // 初期値を設定(インスタンス生成時に指定) | |
| this._count = initialValue; | |
| // 初期値を設定(直接指定) | |
| this.scale = 1; | |
| }, | |
| increment: function () { | |
| ++this._count; | |
| return; | |
| }, | |
| getValue: function () { | |
| return this._count * this.scale; | |
| } | |
| } |
インスタンス生成
そしてクラスのcreateメソッドを使ってインスタンスを生成します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var sample = SampleClass.create(1); |
後はこのインスタンスを使って自由にメソッドを呼び出せます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| sample.getValue(); |
外部に公開する
最後に外部(グローバル)に公開する場合です。これは h5.u.obj.expose を使います。例えば以下の例では hoge.fuga.SampleClass でアクセスできます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| h5.u.obj.expose('hoge.fuga', { | |
| SampleClass: SampleClass | |
| }); |
クラスを使ったサンプルをJSFiddleにアップしてあります。ごく基本的な機能だけですが、実装時の参考にしてください。
これから何回かに分けてクラスの使い方を紹介します。JavaやC#相当まではいきませんが、クラスを使うことでより生産性の高いコードが書けるようになるはずです。
hifiveは業務システム開発に特化しているのでjQuery UIやBootstrapと組み合わせて使われることが多くなっています。そこで今回はよく使われるライブラリについて、その組み合わせ方を紹介します。
今回はモーダルウィンドウです。
デモコードについて
実際に動作するデモはJSFiddleにアップロードしてあります。ボタンを押すとモーダルウィンドウが表示されて、情報を入力すると一覧が更新されます。

HTMLについて
HTMLは主に3つの分かれて構成されます。まずモーダルとして表示する部分があります。これは最初表示されません。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div id="dialog-form" title="Create new user" style="display: none;"> | |
| <form> | |
| <fieldset> | |
| <label for="name">ID</label> <input type="text" name="id" id="id" | |
| class="text ui-widget-content ui-corner-all" /> <label | |
| for="email">名前</label> <input type="text" name="userName" | |
| id="userName" value="" | |
| class="text ui-widget-content ui-corner-all" /> <label | |
| for="password">パスワード</label> <input type="password" | |
| name="password" id="password" value="" | |
| class="text ui-widget-content ui-corner-all" /> | |
| </fieldset> | |
| </form> | |
| </div> |
次にデータの一覧を表示するテーブルがあります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <table id="result" class="ui-widget ui-widget-content" | |
| style="margin: 1em 0; border-collapse: collapse;"> | |
| <tr class="ui-widget-header"> | |
| <th>ID</th> | |
| <th>名前</th> | |
| <th>パスワード</th> | |
| </tr> | |
| <tr> | |
| <td>test_id</td> | |
| <td>test_name</td> | |
| <td>test_password</td> | |
| </tr> | |
| </table> | |
| <input type="button" id="register" value="register" /> |
そして一覧部分のテンプレートがあります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script type="text/ejs" id="row"> | |
| <tr> | |
| <td>[%= id %]</td> | |
| <td>[%= userName %]</td> | |
| <td>[%= password %]</td> | |
| </tr> | |
| </script> |
JavaScriptについて
JavaScriptの実装ですが、今回はコントローラとロジックに分かれています。それぞれ目的は次のようになります。
- コントローラ
UI側のクリックなどをハンドリング - ロジック
ユーザ作成処理などを担当(今回はモック)
まずロジックから紹介します。
ロジックの実装
今回のロジックは DialogLogic としています。今回はモックですが、本来であればAjaxを使ってデータを保存したりします。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var dialogLogic = { | |
| __name: 'DialogLogic', | |
| createUser: function() { | |
| this._private(); | |
| }, | |
| _private: function() { | |
| alert('create user!'); | |
| } | |
| }; |
コントローラの実装
コントローラは次のような実装になります。まず全体像を紹介します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var controller = { | |
| // コントローラ名の定義 | |
| __name: 'DialogController', | |
| // ロジックの定義 | |
| dialogLogic: dialogLogic, | |
| // コントローラが作成された際のイベント | |
| __ready: function() { | |
| }, | |
| // 登録ボタンを押した時のイベント | |
| '#register click': function() { | |
| }, | |
| // ダイアログの"Create User"ボタンがクリックされた時のコールバック | |
| createUser: function(originalThis, event) { | |
| }, | |
| // ダイアログを閉じる際のイベント | |
| cancel: function(target, event) { | |
| }, | |
| // ダイアログ内のフォームをクリアする | |
| clearForm: function() { | |
| } | |
| }; | |
| // コントローラの作成と要素へのバインド | |
| h5.core.controller('#container', controller); |
コントローラが作成された際のイベント
__ready イベントでは次のように実装します。ポイントとしてはボタンを押した際のコールバック先をhifiveのコントローラとしていることです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| __ready: function() { | |
| // registerボタンの装飾 | |
| $('#register').button(); | |
| var that = this; | |
| // dialogの設定 | |
| // ボタンを押した時のコールバックはhifive化したコントローラのメソッドを設定している。 | |
| $('#dialog-form').dialog({ | |
| autoOpen: false, | |
| height: 320, | |
| width: 350, | |
| modal: true, | |
| buttons: { | |
| 'Create User': that.ownWithOrg(that.createUser), | |
| Cancel: that.ownWithOrg(that.cancel) | |
| }, | |
| close: that.own(that.clearForm) | |
| }); | |
| }, |
登録ボタンを押した時のイベント
登録ボタンを押した時には単にモーダルを開くだけです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| '#register click': function() { | |
| $('#dialog-form').dialog('open'); | |
| }, |
ダイアログの”Create User”ボタンがクリックされた時のコールバック
モーダルでユーザ作成のボタンが押された際にはロジック側の createUser を呼び出し、その後HTMLに入力された内容を反映します。そして最後にモーダルを閉じて完了です。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| createUser: function(originalThis, event) { | |
| // DialogLogicのcreateUserメソッドを呼ぶ | |
| this.dialogLogic.createUser(); | |
| // 画面に追加する文字列を取得 | |
| var row = this.view.get('row', { | |
| id: $('#id').val(), | |
| userName: $('#userName').val(), | |
| password: $('#password').val() | |
| }); | |
| $('#result tbody').append(row); | |
| $('#dialog-form').dialog('close'); | |
| }, |
ダイアログを閉じる際のイベント
モーダルを閉じるのはjQuery UIのdialogの機能をそのまま使います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cancel: function(target, event) { | |
| $('#dialog-form').dialog('close'); | |
| }, |
ダイアログ内のフォームをクリアする
最後にフォームの内容をクリアする処理です。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| clearForm: function() { | |
| $('#id').val(''); | |
| $('#userName').val(''); | |
| $('#password').val(''); | |
| } |
このように実装することでhifiveとjQuery UIのdialogをシームレスに連携させられるようになります。モーダルウィンドウの表示はよくある機能なので、実装時の参考にしてください。
実際に動作するデモはJSFiddleにアップロードしてあります。こちらも合わせてご覧ください。
hifiveは業務システム開発に特化しているのでjQuery UIやBootstrapと組み合わせて使われることが多くなっています。そこで今回はよく使われるライブラリについて、その組み合わせ方を紹介します。
今回はバリデーションです。
デモコードについて
実際に動作するデモはJSFiddleにアップロードしてあります。入力して送信ボタンを押すとバリデーションが実行されます。
HTMLについて
HTMLは次のようになります。通常のHTMLと変わりません。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <form method="get" action="#" id="form1"> | |
| <fieldset> | |
| <legend>アンケート</legend> | |
| <div> | |
| <div>好きな食べ物を選択して下さい</div> | |
| <input type="checkbox" value="1" name="food">和食 <input | |
| type="checkbox" value="2" name="food">中華 <input | |
| type="checkbox" value="3" name="food">イタリアン <input | |
| type="checkbox" value="4" name="food">フレンチ <span | |
| class="errorMsg"></span> | |
| </div> | |
| <br> | |
| <div> | |
| <div>タバコを吸っていますか?</div> | |
| <div> | |
| <input type="radio" value="yes" name="conf_tobacco">はい <input | |
| type="radio" value="no" name="conf_tobacco">いいえ <span | |
| class="errorMsg"></span> | |
| </div> | |
| <br> | |
| <div>1日の喫煙本数</div> | |
| <div> | |
| <input type="text" name="count">本 <span class="errorMsg"></span> | |
| </div> | |
| </div> | |
| </fieldset> | |
| <p> | |
| <fieldset> | |
| <legend>ユーザ情報登録</legend> | |
| <div> | |
| <div>URL(任意)</div> | |
| <input type="text" name="url"> <span class="errorMsg"></span> | |
| </div> | |
| <p> | |
| <div> | |
| <div>ユーザID ("hifive"以外を入力すると「入力されたユーザ名は既に使用されています」がエラーメッセージに表示されます)</div> | |
| <input type="text" name="userid"> <span class="errorMsg"></span> | |
| </div> | |
| <div> | |
| <div>パスワードを入力(8~12文字)</div> | |
| <input type="password" name="pass"> <span class="errorMsg"></span> | |
| </div> | |
| <div> | |
| <div>パスワードを再入力</div> | |
| <input type="password" name="conf_pass"> <span | |
| class="errorMsg"></span> | |
| </div> | |
| <br> | |
| </fieldset> | |
| <br /> | |
| <input type="submit" value="送信" /> | |
| </p> | |
| </form> |
CSSについて
CSSはエラー時の色をつけるクラスなどを追加しています。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @charset "utf-8"; | |
| #form1 { | |
| border: 1px solid black; | |
| padding: 15px; | |
| } | |
| .errorMsg { | |
| color: red; | |
| } | |
| .strong { | |
| font-weight: bold; | |
| } | |
| .rules { | |
| border-collapse: collapse; | |
| } | |
| .rules td { | |
| border: 1px solid black; | |
| } |
JavaScriptについて
JavaScriptは長いので、幾つかに分けて紹介します。まず、hifiveのコントローラ化が完了した際の__readyイベントにてバリデーションの設定を行います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| this.$find('#form1').validate({ | |
| // Submitイベントが実行された場合に、自動でバリデーションを実行 | |
| onsubmit: true, | |
| // フォーカスが当たった場合に現在のエラー内容を一旦クリア | |
| focusCleanup: true, | |
| // バリデーションルール | |
| rules: { | |
| food: { | |
| required: true | |
| }, | |
| conf_tobacco: { | |
| required: true | |
| }, | |
| count: { | |
| required: { | |
| depends: '[name="conf_tobacco"][value="male"]:checked' | |
| }, | |
| number: { | |
| depends: '[name="conf_tobacco"][value="male"]:checked' | |
| }, | |
| min: { | |
| param: 1, | |
| depends: '[name="conf_tobacco"][value="male"]:checked' | |
| }, | |
| max: { | |
| param: 999, | |
| depends: '[name="conf_tobacco"][value="male"]:checked' | |
| } | |
| }, | |
| lastname: { | |
| required: true | |
| }, | |
| firstname: { | |
| required: true | |
| }, | |
| email: { | |
| required: true, | |
| email: true | |
| }, | |
| url: { | |
| url: true | |
| }, | |
| userid: { | |
| required: true, | |
| minlength: 6, | |
| remote: '/exists' // useridをパラメータのキーにして、/existsに結果を問い合わせる (サーバは"true"または"false"の文字列を返す必要がある) | |
| }, | |
| pass: { | |
| required: true, | |
| rangelength: [8, 12] | |
| }, | |
| conf_pass: { | |
| equalTo: '[name="pass"]' | |
| }, | |
| policy: { | |
| required: true | |
| } | |
| }, | |
| messages: { // エラー時に表示するメッセージ | |
| food: { | |
| required: '1つ以上選択して下さい。' | |
| }, | |
| conf_tobacco: { | |
| required: '「はい」または「いいえ」のいずれかを選択して下さい' | |
| }, | |
| count: { | |
| required: '「はい」を選択した場合は、喫煙本数を入力して下さい', | |
| number: '本数は数字で入力して下さい', | |
| min: '{0}以上の値を入力して下さい', | |
| max: '{0}以下の値で入力して下さい' | |
| }, | |
| lastname: { | |
| required: '姓を入力して下さい' | |
| }, | |
| firstname: { | |
| required: '名を入力して下さい' | |
| }, | |
| email: { | |
| required: 'メールアドレスを入力して下さい', | |
| email: '正しいメールアドレスを入力して下さい' | |
| }, | |
| url: { | |
| url: '正しいURLを入力して下さい' | |
| }, | |
| userid: { | |
| required: 'ユーザIDを入力して下さい。', | |
| minlength: '{0}以上で入力して下さい。', | |
| remote: '入力されたユーザ名は既に使用されています' | |
| }, | |
| pass: { | |
| required: 'パスワードを入力して下さい', | |
| rangelength: '{0}以上{1}文字以下で入力して下さい' | |
| }, | |
| conf_pass: { | |
| equalTo: 'パスワードが一致しません' | |
| }, | |
| policy: { | |
| required: '同意される場合はチェックを入れて下さい' | |
| } | |
| }, | |
| // エラーメッセージの表示先を指定する | |
| errorPlacement: function(error, el) { | |
| el.parent().children('.errorMsg').append(error); | |
| }, | |
| // エラーがある要素毎に実行するコールバック | |
| showErrors: function(errorMap, errorList) { | |
| this.defaultShowErrors(); | |
| }, | |
| // 入力項目でエラーがあったときに実行されるハンドラ | |
| highlight: this.ownWithOrg(this.highLightArea), | |
| // エラーが解消されたときに実行されるハンドラ, | |
| unhighlight: this.ownWithOrg(this.unHighLightArea), | |
| // validateのチェックが通り、submitが行われるときに実行するハンドラ | |
| submitHandler: this.ownWithOrg(this.submitHandler), | |
| // validateでエラーが1つでもあると実行されるハンドラ | |
| invalidHandler: this.ownWithOrg(this.invalidHandler), | |
| // 入力項目でエラーが解消されるたびに実行されるハンドラ | |
| success: this.ownWithOrg(this.successHandler) | |
| }); |
この際、入力チェックを行う際などのイベントハンドラも設定もします。this.ownWithOrgを使うことでhifiveのコントローラ自身を渡せるようになります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // エラーがある要素毎に実行するコールバック | |
| showErrors: function(errorMap, errorList) { | |
| this.defaultShowErrors(); | |
| }, | |
| // 入力項目でエラーがあったときに実行されるハンドラ | |
| highlight: this.ownWithOrg(this.highLightArea), | |
| // エラーが解消されたときに実行されるハンドラ, | |
| unhighlight: this.ownWithOrg(this.unHighLightArea), | |
| // validateのチェックが通り、submitが行われるときに実行するハンドラ | |
| submitHandler: this.ownWithOrg(this.submitHandler), | |
| // validateでエラーが1つでもあると実行されるハンドラ | |
| invalidHandler: this.ownWithOrg(this.invalidHandler), | |
| // 入力項目でエラーが解消されるたびに実行されるハンドラ | |
| success: this.ownWithOrg(this.successHandler) |
後は各イベントハンドラの実装になります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 入力項目でエラーがあったときに実行されるハンドラ | |
| highLightArea: function(orgThis, el, error, errorClass) { | |
| $(el).css('background-color', 'red'); | |
| }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // エラーが解消されたときに実行されるハンドラ, | |
| unHighLightArea: function(orgThis, el, error, errorClass) { | |
| var $el = $(el); | |
| $el.css('background-color', ''); | |
| // 操作した要素が「1日の喫煙本数」テキストボックスでかつ、「たばこを吸っていますか」チェックボックスが「いいえ」の場合は、 | |
| // 「1日の喫煙本数」テキストボックスのハイライトを除去する | |
| if ($el.is('[name="conf_tobacco"]') && this.$find('[name="conf_tobacco"]:checked').val() === 'female') { | |
| this.$find('[name="count"]').css('background-color', ''); | |
| } | |
| }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // validateのチェックが通り、submitが行われるときに実行するハンドラ | |
| submitHandler: function(orgThis, form, ev) { | |
| alert('FORMの内容をサーバに送信します。'); | |
| form.submit(); | |
| }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // validateでエラーが1つでもあると実行されるハンドラ | |
| invalidHandler: function(orgThis, ev, validator) { | |
| alert('入力内容に誤りがあります。'); | |
| }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 入力項目でエラーが解消されるたびに実行されるハンドラ | |
| successHandler: function(orgThis, errMsgElement, inputElement) { | |
| if (window.console) { | |
| console.log('入力OK: '+ inputElement.name); | |
| } | |
| }, |
最後にチェックボックス、ラジオボタンのバリデーションについて別途実装します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //「好きな食べ物を選択して下さい」のバリデーション | |
| '[name="food"] click': function(context, $ct) { | |
| // input[name="food"]の要素に対してバリデーションを実行する | |
| $ct.valid(); | |
| }, | |
| //「1日の喫煙本数」テキストボックスのバリデーション | |
| '[name="count"] focusout': function(context, $ct) { | |
| // input[name="count"]の要素に対してバリデーションを実行する | |
| $ct.valid(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(function() { | |
| h5.core.controller('body', { | |
| __name: 'sample.plugin.validationSampleController', | |
| __ready:function() { | |
| // バリデーターにルールやメッセージ等を設定 | |
| this.$find('#form1').validate({ | |
| // Submitイベントが実行された場合に、自動でバリデーションを実行 | |
| onsubmit: true, | |
| // フォーカスが当たった場合に現在のエラー内容を一旦クリア | |
| focusCleanup: true, | |
| // バリデーションルール | |
| rules: { | |
| food: { | |
| required: true | |
| }, | |
| conf_tobacco: { | |
| required: true | |
| }, | |
| count: { | |
| required: { | |
| depends: '[name="conf_tobacco"][value="yes"]:checked' | |
| }, | |
| number: { | |
| depends: '[name="conf_tobacco"][value="yes"]:checked' | |
| }, | |
| min: { | |
| param: 1, | |
| depends: '[name="conf_tobacco"][value="yes"]:checked' | |
| }, | |
| max: { | |
| param: 999, | |
| depends: '[name="conf_tobacco"][value="yes"]:checked' | |
| } | |
| }, | |
| url: { | |
| url: true | |
| }, | |
| // useridをパラメータのキーにして、/existsに結果を問い合わせる | |
| // サーバは"true"または"false"の文字列を返す必要がある | |
| userid: { | |
| required: true, | |
| minlength: 6, | |
| remote: '/exists' | |
| }, | |
| pass: { | |
| required: true, | |
| rangelength: [8, 12] | |
| }, | |
| conf_pass: { | |
| equalTo: '[name="pass"]' | |
| }, | |
| policy: { | |
| required: true | |
| } | |
| }, | |
| messages: { // エラー時に表示するメッセージ | |
| food: { | |
| required: '1つ以上選択して下さい。' | |
| }, | |
| conf_tobacco: { | |
| required: 'はい、またはいいえを選択して下さい' | |
| }, | |
| count: { | |
| required: '「はい」を選択した場合は、喫煙本数を入力して下さい', | |
| number: '本数は数字で入力して下さい', | |
| min: '{0}以上の値を入力して下さい', | |
| max: '{0}以下の値で入力して下さい' | |
| }, | |
| url: { | |
| url: '正しいURLを入力して下さい' | |
| }, | |
| userid: { | |
| required: 'ユーザIDを入力して下さい。', | |
| minlength: '{0}以上で入力して下さい。', | |
| remote: '入力されたユーザ名は既に使用されています' | |
| }, | |
| pass: { | |
| required: 'パスワードを入力して下さい', | |
| rangelength: '{0}以上{1}文字以下で入力して下さい' | |
| }, | |
| conf_pass: { | |
| equalTo: 'パスワードが一致しません' | |
| } | |
| }, | |
| // エラーメッセージの表示先を指定する | |
| errorPlacement: function(error, el) { | |
| el.parent().children('.errorMsg').append(error); | |
| }, | |
| // エラーがある要素毎に実行するコールバック | |
| showErrors: function(errorMap, errorList) { | |
| this.defaultShowErrors(); | |
| }, | |
| // 入力項目でエラーがあったときに実行されるハンドラ | |
| highlight: this.ownWithOrg(this.highLightArea), | |
| // エラーが解消されたときに実行されるハンドラ, | |
| unhighlight: this.ownWithOrg(this.unHighLightArea), | |
| // validateのチェックが通り、submitが行われるときに実行するハンドラ | |
| submitHandler: this.ownWithOrg(this.submitHandler), | |
| // validateでエラーが1つでもあると実行されるハンドラ | |
| invalidHandler: this.ownWithOrg(this.invalidHandler), | |
| // 入力項目でエラーが解消されるたびに実行されるハンドラ | |
| success: this.ownWithOrg(this.successHandler) | |
| }); | |
| }, | |
| highLightArea: function(orgThis, el, error, errorClass) { | |
| $(el).css('background-color', 'red'); | |
| }, | |
| unHighLightArea: function(orgThis, el, error, errorClass) { | |
| var $el = $(el); | |
| $el.css('background-color', ''); | |
| // 操作した要素が「1日の喫煙本数」テキストボックスでかつ、「たばこを吸っていますか」チェックボックスが「いいえ」の場合は、 | |
| // 「1日の喫煙本数」テキストボックスのハイライトを除去する | |
| if ($el.is('[name="conf_tobacco"]') && this.$find('[name="conf_tobacco"]:checked').val() === 'no') { | |
| this.$find('[name="count"]').css('background-color', ''); | |
| } | |
| }, | |
| submitHandler: function(orgThis, form, ev) { | |
| alert('FORMの内容をサーバに送信します。'); | |
| form.submit(); | |
| }, | |
| invalidHandler: function(orgThis, ev, validator) { | |
| alert('入力内容に誤りがあります。'); | |
| }, | |
| successHandler: function(orgThis, errMsgElement, inputElement) { | |
| if (window.console) { | |
| console.log('入力OK: '+ inputElement.name); | |
| } | |
| }, | |
| //「好きな食べ物を選択して下さい」のバリデーション | |
| '[name="food"] click': function(context, $ct) { | |
| // input[name="food"]の要素に対してバリデーションを実行する | |
| $ct.valid(); | |
| }, | |
| //「1日の喫煙本数」テキストボックスのバリデーション | |
| '[name="count"] focusout': function(context, $ct) { | |
| // input[name="count"]の要素に対してバリデーションを実行する | |
| $ct.valid(); | |
| } | |
| }); | |
| }); |
hifiveでもvalidation機能を提供していますが、使い慣れた方を採用するケースもあるでしょう。そうした時にはコールバックの管理などはhifiveで行うことで、よりメンテナンスしやすいバリデーション実装ができるようになります。
実際に動作するデモはJSFiddleにアップロードしてあります。お試しください。
JavaScriptは非同期で処理を行う言語です。そして、オブジェクト自身を意味する this が頻繁に使われます。しかし、非同期処理の後はthisが思ったものではなくなっていたりして、困った経験があるのではないでしょうか。
例えば次のような処理です。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var Hello = { | |
| name: "hifive", | |
| message: function() { | |
| return "Hello, " + this.name; | |
| } | |
| } | |
| Hello.message(); // "Hello, hifive" |
これは普通ですが、非同期処理に変更します。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var Hello = { | |
| name: "hifive", | |
| message: function() { | |
| setTimeout(function() { | |
| return "Hello, " + this.name; | |
| }, 1000); | |
| } | |
| } | |
| Hello.message(); |
この時の this は Windowオブジェクトになるので、nameはありません。このようにスコープが変わってしまうと this の値も変化します。
その解決策として、次のように実行してみます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var Hello = { | |
| name: "hifive", | |
| message: function() { | |
| setTimeout(function() { | |
| alert("Hello, " + this.name); | |
| }.call(this), 1000); | |
| } | |
| } | |
| console.log(Hello.message()); |
setTimeoutを使っているのは変わりませんが、関数をそのまま渡すのではなく、 .call(this) を追加します。そうすると、this.nameはhifiveという値が取れるようになります。callの引数に渡す値が、その関数内でのthisとして使えるようになります。
via Function.prototype.call() – JavaScript | MDN
このようにして、thisのスコープを変えることでプログラミングしやすくなります。
own/ownWithOrgの使い方
hifiveではcall(this)ではなく、ownメソッドを提供しています。例えばコントローラの中で、次のように使います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $.ajax({ | |
| : | |
| }) | |
| .then(this.own(function(response) { | |
| this // hifiveのコントローラ | |
| })); |
さらにhifiveのコントローラだけでなく、本来のthisを使いたい場合にはownWithOrgがあります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $.ajax({ | |
| : | |
| }) | |
| .then(this.ownWithOrg(function(original, response) { | |
| this // hifiveのコントローラ | |
| original // 元々のthis | |
| })); |
このようにして this による混乱を抑えられるようになります。
サンプルコードをJSFiddleにアップロードしています。各処理における this の値の違いについて確認してみてください。
hifiveは業務システム開発に特化しているのでjQuery UIやBootstrapと組み合わせて使われることが多くなっています。そこで今回はよく使われるライブラリについて、その組み合わせ方を紹介します。
今回はDOMのソートです。
デモコードについて
実際に動作するデモはJSFiddleにアップロードしてあります。各要素をドラッグして上下に移動したり、別なカラムにドロップできます。

HTMLについて
少し長いですがHTMLは次のようになります。portlet クラスごとに移動できます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div id="container" style="padding: 30px;"> | |
| <div class="column"> | |
| <div class="portlet"> | |
| <div class="portlet-header">Feeds</div> | |
| <div class="portlet-content" style="height: 320px;">Lorem | |
| ipsum dolor sit amet, consectetuer adipiscing elit</div> | |
| </div> | |
| <div class="portlet"> | |
| <div class="portlet-header">News</div> | |
| <div class="portlet-content">Lorem ipsum dolor sit amet, | |
| consectetuer adipiscing elit</div> | |
| </div> | |
| </div> | |
| <div class="column"> | |
| <div class="portlet"> | |
| <div class="portlet-header">Shopping</div> | |
| <div class="portlet-content">Lorem ipsum dolor sit amet, | |
| consectetuer adipiscing elit</div> | |
| </div> | |
| </div> | |
| <div class="column"> | |
| <div class="portlet"> | |
| <div class="portlet-header">Links</div> | |
| <div class="portlet-content">Lorem ipsum dolor sit amet, | |
| consectetuer adipiscing elit</div> | |
| </div> | |
| <div class="portlet"> | |
| <div class="portlet-header">Images</div> | |
| <div class="portlet-content">Lorem ipsum dolor sit amet, | |
| consectetuer adipiscing elit</div> | |
| </div> | |
| </div> | |
| <ul id="list" style="list-style: none;"></ul> | |
| </div> |
スタイルシートについて
スタイルシートはカラム部分の設定などになります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .column { | |
| width: 220px; | |
| float: left; | |
| padding-bottom: 100px; | |
| } | |
| .portlet { | |
| margin: 0 1em 1em 0; | |
| } | |
| .portlet-header { | |
| margin: 0.3em; | |
| padding-bottom: 4px; | |
| padding-left: 0.2em; | |
| } | |
| .portlet-header .ui-icon { | |
| float: right; | |
| } | |
| .portlet-content { | |
| padding: 0.4em; | |
| } | |
| .ui-sortable-placeholder { | |
| border: 1px dotted black; | |
| visibility: visible !important; | |
| height: 50px !important; | |
| } | |
| .ui-sortable-placeholder * { | |
| visibility: hidden; | |
| } |
JavaScriptについて
JavaScriptは次のようになります。まずは概要です。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(function() { | |
| var controller = { | |
| __name: 'SortableController', | |
| // 初期化処理 | |
| __ready: function() { | |
| }, | |
| // ドロップ時のコールバック | |
| stop: function(event, ui) { | |
| } | |
| }; | |
| // コントローラの作成と要素へのバインド. | |
| h5.core.controller('#container', controller); | |
| }); |
初期化処理
hifiveのコントローラが初期化された段階でソートの設定を行います。ここではドロップした時のイベント(stop)だけ指定しています。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| __ready: function() { | |
| var that = this; | |
| $('.column').sortable({ | |
| connectWith: '.column', | |
| stop: that.own(that.stop) | |
| }); | |
| $('.portlet').addClass('ui-widget ui-widget-content ui-helper-clearfix ui-corner-all') | |
| .find('.portlet-header').addClass('ui-widget-header ui-corner-all').prepend( | |
| '<span class="ui-icon ui-icon-minusthick"></span>').end().find( | |
| '.portlet-content'); | |
| $('.portlet-header .ui-icon').click(function() { | |
| $(this).toggleClass('ui-icon-minusthick').toggleClass('ui-icon-plusthick'); | |
| $(this).parents('.portlet:first').find('.portlet-content').toggle(); | |
| }); | |
| $('.column').disableSelection(); | |
| }, |
ドロップ時のコールバック
次にドロップを止めた時のイベントです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| stop: function(event, ui) { | |
| var target = $(ui.item); | |
| $('#list').append('<li>' + target.find('.portlet-header').text() + 'が移動しました。</li>'); | |
| } |
このように実装することでhifiveとjQuery UIのソート機能をシームレスに連携させられるようになります。ダッシュボードであったり、ユーザが自分でコンテンツを自由に設定できるページを作るのに使えるのでぜひ参考にしてください。
実際に動作するデモはJSFiddleにアップロードしてあります。こちらも合わせてご覧ください。
HTML5でWebの表現力は一気に拡大しています。もちろんJavaScriptでも多数のAPIが追加されており、リッチなWebシステムを構築するのに必須機能が揃ってきています。今回は多数あるHTML5 APIの中で、業務システム周りで使えるものをピックアップして紹介します。
## File API
従来のJavaScriptではローカルファイルへアクセスできませんでした。HTML5で追加されたFile APIによって、ファイル選択ダイアログであったり、ドラッグ&ドロップされたファイルを読み込めるようになりました。
CSVファイルを読み込んだり、画像を読み込んで加工すると言った処理もできるようになっています。また、読み込んだ内容をAjaxでサーバに送ることで、ファイルのドラッグ&ドロップでアップロード処理を行うと言った処理も可能になります。
[File – Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/File)
## Geolocation API
位置情報を取得するAPIです。一般的なPCにはGPSモジュールは入っていませんので、IPアドレス、WiFi、Bluetoothなど様々な情報を使って位置情報を特定します。一度だけ取得することも、継続的に取得し続けることもできます。精度はそこそこといったところなので、あまり厳密性を求めるような運用は難しいでしょう。
位置情報を使えば付近の情報を取得したり、駅名や住所の入力を省けるようになります。スマートフォンなど文字入力が面倒な場合において特に有効です。
[Geolocation の利用 – Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/Geolocation/Using_geolocation)
## クリップボードAPI
いわゆるクリップボードの操作が可能になるAPIです。文字列をコピーするだけでなく、HTMLやリンクなども対象になります。さらにファイルをコピーすることでアクセスできるようにもなります。
ユーザに任意の文字列をコピーしてもらうのに使ったり、画像やHTMLなどを含んだコンテンツをコピーしてもらうのに使えます。
[ClipboardEvent – Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/ClipboardEvent)
## localStorage
キーバリュー型でデータの保存、取り出しができるストレージです。Cookieに似ていますが、もっと容量は大きな仕組みです。KVSなので、検索などの機能はありません。恒久的なデータ保存場所として使うのが便利です。
[Window.localStorage – Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage)
## History API
JavaScriptで画面を書き換えるようなWebアプリケーションの場合、History APIを使うことでブラウザの履歴として管理できるようになります。ハッシュまたはパーマネントURLを書き換える形になります。
History APIでパーマネントURLを使う場合、そのURLに対してダイレクトにアクセスしたとしてもきちんと表示されるようになっている必要があります。
[ブラウザの履歴を操作する – ウェブデベロッパーガイド | MDN](https://developer.mozilla.org/ja/docs/Web/Guide/DOM/Manipulating_the_browser_history)
## WebSocket API
サーバとクライアントで同期的にメッセージを送受信できる仕組みがWebSocketです。特定のチャンネルを購読したり、逆にブロードバンドにメッセージを流すこともできます。ソケットとついている通り、HTTPとは異なるプロトコルを使います。
そのためWebSocket用のサーバを別途用意したりする必要があります。その際セッションデータなどを連携させるなど実装には工夫が必要になるでしょう。
[WebSockets – Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/WebSockets_API)
—-
APIは他にもたくさんあります。WebGLであったり、Web NotificationといったAPIもあります。Webシステムをより便利にするためにHTML5 APIを活用してください。
hifiveは業務システム開発に特化しているのでjQuery UIやBootstrapと組み合わせて使われることが多くなっています。そこで今回はよく使われるライブラリについて、その組み合わせ方を紹介します。
今回はタブ表示です。
デモコードについて
実際に動作するデモはJSFiddleにアップロードしてあります。各タブをクリックするとその下にあるコンテンツが切り替わるのが確認できます。

HTMLについて
HTMLですが、各タブ(リスト)のリンク先にタブのIDを指定しています。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div id="tabs"> | |
| <ul> | |
| <li><a href="#tabs-1">tab1</a></li> | |
| <li><a href="#tabs-2">tab2</a></li> | |
| <li><a href="#tabs-3">tab3</a></li> | |
| </ul> | |
| <div id="tabs-1">tab1</div> | |
| <div id="tabs-2">tab2</div> | |
| <div id="tabs-3">tab3</div> | |
| </div> |
JavaScriptについて
JavaScriptの実装は次のようになります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(function() { | |
| var controller = { | |
| __name: 'TabsController', | |
| // 初期化処理 | |
| // タブが選択された時のコールバック | |
| }; | |
| // コントローラの作成と要素へのバインド. | |
| h5.core.controller('#tabs', controller); | |
| }); |
初期化処理について
初期化処理ではタブの表示処理を行います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 初期化処理 | |
| __ready: function() { | |
| var that = this; | |
| // jQuery UI Tabsを設定 | |
| $(this.rootElement).tabs({ | |
| // タブが選択された時のコールバックを設定 | |
| // ownメソッドでラップしてイベントコンテキストやロジックを使えるようにしている。 | |
| select: that.own(that.selectTab) | |
| }); | |
| }, |
タブがクリックされた時の処理
タブがクリックされた際にコールバックが受け取れます。Ajax処理などを行ったりするのに使えます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // タブが選択された時のコールバック | |
| selectTab: function(event, ui) { | |
| $(ui.panel).html('tab' + (ui.index + 1) + 'が選択されました。'); | |
| } |
このように実装することでhifiveとjQuery UIのdialogをシームレスに連携させられるようになります。多くの情報を表示する際にタブは便利な機能なので、実装時の参考にしてください。
実際に動作するデモはJSFiddleにアップロードしてあります。こちらも合わせてご覧ください。