AngularUI使い方メモ（UI.Utils）

#基本
##ダウンロード
[ここ](http://angular-ui.github.io/ui-utils/#/include) から zip をダウンロードする。

##HTML で読み込む
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
```

- AngularJS と `ui-utils.min.js` を読み込む。

##モジュールをロードする
```js:
angular
.module('mine', ['ui.utils'])
（以下略）
```

- `ui.utils` モジュールをロードする。

#Event Binder
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
    
    <style>
      div {
        width: 300px;
        height: 200px;
        border: 1px solid black;
        overflow: auto;
      }
    </style>
  </head>
  <body>
    <div ui-event="{scroll: 'onscroll($event)'}">
      <ul>
        <li ng-repeat="value in array">{{value}}</li>
      </ul>
    </div>
    <p>scrollTop : {{scrollTop}} px</p>
  </body>
</html>
```

```js:script.js
angular
.module('mine', ['ui.utils'])
.run(function($rootScope) {
    var array = [],
        i;
    
    for (i=0; i<1000; i++) {
        array.push(i);
    }
  
    $rootScope.array = array;
    $rootScope.scrollTop = 0;
  
    $rootScope.onscroll = function(event) {
        $rootScope.scrollTop = event.target.scrollTop;
    };
});
```

[Plunker サンプル](http://plnkr.co/edit/0d88dDyONXseYldkX9eJ?p=preview)

- AngularJS が標準ではサポートしていないイベントでもバインドできるようにするためのディレクティブ。
- 内部では jQuery の `bind()` 関数を使っているので、イベント名はそれの仕様に合わせて指定することになる。

#Format
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <p>{{ 'name = $0' | format:'Hoge' }}</p>
    
    <p>{{ 'name = $0, $1' | format:['Hoge', 'Fuga'] }}</p>
    
    <p>{{ 'name = :hoge, :fuga' | format:{hoge: 'Hoge', fuga: 'Fuga'} }}</p>
  </body>
</html>
```

```js:script.js
angular
.module('mine', ['ui.utils']);
```

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/601db6b8-cc0e-569e-1cb6-37bf4e4df917.jpeg)

- 文字の埋め込みができるフィルター。
- `$0, $1` のように順番で指定する方法と、 `:hoge, :fuga` のように名前で指定する方法がある。

#Highlight
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-sanitize.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
    
    <style>
      .ui-match {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <p ng-bind-html="'One Two Three' | highlight:'o'"></p>
    
    <p ng-bind-html="'One Two Three' | highlight:'o':true"></p>
  </body>
</html>
``` 

```js:script.js
angular
.module('mine', ['ui.utils', 'ngSanitize']);
```

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/dbed440e-b629-a370-18a0-e3b39e5f93c9.jpeg)

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/4f06c24a-1f6b-cf5f-3e38-96ce02a9ae5c.jpeg)

- 文字のハイライト用フィルター。
- フィルターの引数で指定した文字列にマッチする部分を `span` タグで括った HTML を出力する。
- フィルターの第二引数に true を指定すると、大文字小文字を区別するようになる。
- `span` タグには `.ui-match` クラスが設定されているので、 css でこのクラスのスタイルを指定すれば、ハイライト表現が実現できる。
- 出力がサニタイズされないように、 `ng-bind-html` を使って出力する。
- `ng-bind-html` を使用するには、 `ngSanitize` モジュールをロードする必要がある（`angular-sanitize.min.js`）

#Include Fragment
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <ui-include src="'other.html'" fragment="'#hoge'"></ui-include>
    <div ui-include="'other.html'" fragment="'#fuga'"></div>
  </body>
</html>
```

```js:script.js
angular
.module('mine', ['ui.utils']);
```

```html:other.html
<h1 id="hoge">HOGE</h1>
<h1 id="fuga">FUGA</h1>
```

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/c63b2872-d464-23b2-259c-950c2faa6d23.jpeg)

- ページの一部に他の HTML を読み込むためのディレクティブ。
- `ng-include` ディレクティブは HTML をまるごと埋め込むが、この `ui-include` は `fragment` 属性でさらに読み込む部分を限定できる。
- `fragment` 属性には jQuery のセレクタを指定する。
- jQuery のセレクタを全て使用できるようにするためには、 jQuery 本体を読み込む必要がある。
- その場合、<ins>jQuery は AngularJS より先に読み込むようにしなければならない。</ins>
- `src` 及び `fragment` に渡す値は Angular 式なので、文字列を指定する場合はシングルクォーテーション `'` で括ることを忘れないように注意。

#Indeterminate checkbox
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <table border="1" style="text-align: center;">
      <tr>
        <th></th>
        <th>ng-model</th>
        <th>ui-indeterminate</th>
      </tr>
      <tr>
        <td><input type="checkbox" ui-indeterminate="true" /></td>
        <td>-</td>
        <td>true</td>
      </tr>
      <tr>
        <td><input type="checkbox" ng-model="checked" ui-indeterminate="true" /></td>
        <td>true</td>
        <td>true</td>
      </tr>
      <tr>
        <td><input type="checkbox" ng-model="checked" ui-indeterminate="false" /></td>
        <td>true</td>
        <td>false</td>
      </tr>
      <tr>
        <td><input type="checkbox" ng-model="unchecked" ui-indeterminate="true" /></td>
        <td>false</td>
        <td>true</td>
      </tr>
      <tr>
        <td><input type="checkbox" ng-model="unchecked" ui-indeterminate="false" /></td>
        <td>false</td>
        <td>false</td>
      </tr>
    </table>
  </body>
</html>
```

```js:script.js
angular
.module('mine', ['ui.utils'])
.run(function($rootScope) {
    $rootScope.checked = true;
    $rootScope.unchecked = false;
});
```

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/71be728b-9c50-997f-491c-be1e7afe1075.jpeg)

- `checkbox` に `indeterminate` （不確定）の状態を設定するためのディレクティブ。
- `indeterminate` が使用できるのは HTML5 から。
- 本来 `indeterminate` は JavaScript から DOM のプロパティに直接アクセスしないと設定できないが、 `ui-indeterminate` ディレクティブを使えば HTML 上で指定ができるようになる。

#Inflector
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <p>{{'Here Is my_phoneNumber' | inflector:'humanize'}}</p>
    <p>{{'Here Is my_phoneNumber' | inflector:'underscore'}}</p>
    <p>{{'Here Is my_phoneNumber' | inflector:'variable'}}</p>
  </body>
</html>
```

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/05568633-726b-4667-6268-0b343d4e6f3e.jpeg)

- 指定した文字のフォーマットを変更する。
- 正直使い道が分からない（公式サイトに `Why?` がない）。

#jQuery Passthrough
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
    
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
  </head>
  <body>
    <input type="text" ui-jq="datepicker" />
    <input type="text" ui-jq="datepicker" ui-options="{changeYear: true}" />
  </body>
</html>
```

```js:
angular
.module('mine', ['ui.utils'])
.value('uiJqConfig', {
    datepicker: {
        changeMonth: true
    }
});
```

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/c3c672c5-5bba-78d3-6384-3322c29c5882.jpeg)

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/6e8bc4b5-6247-bcc9-d09e-84b15e3fa9de.jpeg)

- JavaScript を記述することなく、 jQuery のメソッドを実行できる。
- `ui-jq` ディレクティブで指定した jQuery のメソッドが、そのタグに対して実行される。
- 実行するメソッドに渡すオプションは、 `ui-options` で指定する（Angular 式）。
- デフォルトで指定したいオプションがある場合は、 `uiJqConfig` という名前の `value` をモジュールに定義する。
- `uiJqConfig` は次のフォーマットで指定する。


```text:
module.value('uiJqConfig', {
    <jQueryのメソッド名>: <デフォルトのオプション>
});
```

#Keypress

コードが長いので [Plunker サンプル](http://plnkr.co/edit/tMNbe26ajOWtNggnXSS7?p=preview) を参照。

- 具体的なキーを指定してキーイベントを設定する。
- `ui-keypress`, `ui-keyup`, `ui-keydown` の３つがある。
- 半角スペース区切りで複数のキーを設定できる。
- 半角ハイフン `-` 区切りで `Ctrl + Shift + Enter` のような複合キーを設定できる。
- `enter` や `esc` のように、一部のキーは名前で指定できる。
- `shift`, `ctrl`, `alt` は複合キーのときだけ名前で指定できる。

#Mask
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <h1>placeholder なし</h1>
    <div>
      Number : <input ng-model="a" ui-mask="9999 - 9999 - 9999" />
    </div>
    <div>
      Alphabet : <input ng-model="b" ui-mask="AAAA - AAAA - AAAA" />
    </div>
    <div>
      Any : <input ng-model="c" ui-mask="**** - **** - ****" />
    </div>
  </body>
</html>
```

[Plunker サンプル](http://plnkr.co/edit/nYAFu34RxXF7o2VJhlm5?p=preview)

- 入力にマスクを指定できる。
- `ng-model` と `ui-mask` の両方を指定する必要がある。
- マスクのフォーマットは、以下のとおり。
    - `A`：任意のアルファベット。
    - `9`：任意の数値。
    - `*`：任意のアルファベットまたは数値。
    - それ以外の文字・記号：非入力。固定文字。

#Reset

__解読不能__

#Route Checking
##基本

[Plunker サンプル](http://plnkr.co/edit/lt2jdN7vVh7SBx1suK4s?p=preview)

- `ui-route` で指定したパスが現在表示されているかどうかを `$uiRoute` 変数を通じて boolean 値で取得できる。

##正規表現で指定する

[Plunker サンプル](http://plnkr.co/edit/5q5zuYpSNQ69Q1fIHsv5?p=preview)

- `ui-route` は正規表現が使える。

##ui-route と href を合わせて設定する

[Plunker サンプル](http://plnkr.co/edit/SwGMaDtfM9eR1IcfD8tm?p=preview)

- `ui-route` と `href` or `ng-href` を合わせて設定した場合、 `ui-route` は値の指定を省略できる。

##$uiRoute の代わりに任意の変数を指定する

[Plunker サンプル](http://plnkr.co/edit/f7ZUAi57EZgBF9IQ9U9q?p=preview)

- `ui-route` と `ng-model` を一緒に設定すれば、任意の変数に `$uiRoute` と同じ値を設定できる。

#Scroll till you drop
##基本
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-scroll="value in datasource">{{value}}</div>
  </body>
</html>
```

```js:
angular
.module('mine', ['ui.utils'])
.service('datasource', function() {
    this.get = function(index, count, success) {
        var data = [],
            i,
            from = index,
            to = index + (count - 1);
        
        for (i=from; i<to; i++) {
            if (1 <= i && i <= 300) {
                data.push(i);
            }
        }
        
        success(data);
    };
});
```

[Plunker サンプル](http://plnkr.co/edit/2LvHKr5QulgUFmA0E5Js?p=preview)

- 仮想スクロール（見えているところだけ DOM を実際に生成して、見えない部分はスクロールして見えるようになる時に動的に生成する仕組み）を実現できる。
- 非表示になった部分の DOM は順次削除されるので、表示したいデータ量が大量でもリソースを圧迫しない。
- 2014/06/01 現在 [ここ](http://angular-ui.github.io/ui-utils/) からダウンロードできる ver0.1.1 は、 `ng-scroll` で指定する（`ui-scroll` じゃない）。
    - ただし、[2014/05/20 のコミット](https://github.com/angular-ui/ui-utils/commit/ec4b7a133659f721f50d92d52ac399fb0abe2cd6#diff-451bf2958cca496c9f27d19144d3c284) で、名前が `ui-scroll` に変更になっている。
    - なので、たぶん以後のバージョンでは `ui-scroll` で指定する。
- 読み込むデータの取得元（上記例の `datasource`）は、 AngularJS の Service として定義する。
    - Service には `get` という名前のメソッドを定義する。
    - `get` には、 `index`, `count`, `success` の３つの値が渡される。
    - `index` は、次に読み込むデータの先頭を示すインデックス値。
    - `count` は、次に読み込むデータの数。
    - `success` は、読み込みが完了したときに実行しなければならない関数。引数に、読み込み結果を配列で渡す。１件も読み込むデータがない場合は、空の配列を渡す。

##ビューポートを指定する
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div style="height: 300px; border: 1px solid black;" ng-scroll-viewport>
      <div ng-scroll="value in datasource">{{value}}</div>
    </div>
  </body>
</html>
```

JavaScript は同じ。

[Plunker サンプル](http://plnkr.co/edit/5g7gkP6ltqtgbA07a8XP?p=preview)

- 標準では、ブラウザの Window 全体がスクロールされる。
- スクロール領域を限定したい場合は、 `ng-scroll-viewport` を指定したブロック要素で `ng-scroll` を括る。

#Scrollfix

- スクロールしたら `.ui-scrollfix` クラスを設定する。
- 使い道はよくわからない。

#Show, Hide and Toggle Alternatives
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
    
    <style>
      .show {
        opacity: 1.0;
      }
      
      .hide {
        opacity: 0.0;
      }
      
      .ui-show {
        transition: all 0.5s linear 0s;
        opacity: 1.0;
      }
      
      .ui-hide {
        transition: all 0.5s linear 0s;
        opacity: 0.0;
      }
    </style>
  </head>
  <body>
    <label>
      <input type="checkbox" ng-model="flag" /> flag
    </label>
    
    <div ui-show="flag" class="hide">ui-show</div>
    <div ui-hide="flag" class="show">ui-hide</div>
    <div ui-toggle="flag">ui-toggle</div>
  </body>
</html>
```

[Plunker サンプル](http://plnkr.co/edit/qQrVcaUCP0ZL5JVaEuGD?p=preview)

- `ui-show` に指定している値が true の場合は `.ui-show` クラスが、
- `ui-hide` に指定している値が true の場合は `.ui-hide` クラスが、
- `ui-toggle` に指定している値が true の場合は `.ui-show` クラスが、 false の場合は `.ui-hide` クラスが設定される。
- `ng-show` だと単純な表示・非表示の切り替えになるが、このディレクティブなら CSS3 の transition を利用してアニメーションを定義できたりする。
- `ng-class="{'hoge': flag}"` みたいなことをしたい場合の簡易表現として利用できる。

#Unique
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <pre>{{array | unique:'age' | json}}</pre>
  </body>
</html>
```

```js:script.js
angular
.module('mine', ['ui.utils'])
.run(function($rootScope) {
    $rootScope.array = [
        {
            name: 'Takeshi',
            age: 17
        },
        {
            name: 'Koji',
            age: 18
        },
        {
            name: 'Yuji',
            age: 17
        },
        {
            name: 'Hiroshi',
            age: 19
        },
        {
            name: 'Yamato',
            age: 18
        },
        {
            name: 'Akira',
            age: 17
        }
    ];
});
```

![angularui.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/5eae083c-5e85-a25b-f3e6-20ce75f75487.jpeg)

- オブジェクトの配列から、指定したプロパティの値が重複する要素を取り除く。

#Validate
##基本
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <form name="myForm">
      <input type="text" name="hoge" ng-model="hoge" ui-validate=" '$value.length == 5' "/>
      <p>myForm.hoge.$error.validator = {{myForm.hoge.$error.validator}}</p>
      
      <input type="text" name="fuga" ng-model="fuga" ui-validate=" 'validateFuga($value)' "/>
      <p>myForm.fuga.$error.validator = {{myForm.fuga.$error.validator}}</p>
    </form>
  </body>
</html>
```

```js:script.js
angular
.module('mine', ['ui.utils'])
.run(function($rootScope) {
    $rootScope.validateFuga = function(value) {
        return 18 <= value;
    };
});
```

[Plunker サンプル](http://plnkr.co/edit/A9GSGE1o89vf7RIKjG0Q?p=preview)

- 任意のチェックルールを追加できる。
- 文字列で式または関数の実行を記述する。
- 評価結果が true の場合は非エラー、 false の場合はエラー扱いになる。
- エラー状態を参照するときは、 `validator` というルール名で参照できる（`myForm.fuga.$error.validator`） 。

##ルール名を指定する
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
    </style>
  </head>
  <body>
    <form name="myForm">
      <input type="text" name="hoge" ng-model="hoge" ui-validate=" {hogeError: 'validateHoge($value)'} "/>
      <p>myForm.hoge.$error.hogeError = {{myForm.hoge.$error.hogeError}}</p>
    </form>
  </body>
</html>
```

```js:script.js
angular
.module('mine', ['ui.utils'])
.run(function($rootScope) {
    $rootScope.validateHoge = function(value) {
        return angular.isString(value) ? value.match(/^[a-g]+$/) : false;
    };
});
```

[Plunker サンプル](http://plnkr.co/edit/ERf3zkrrP58DaM3IGvgD?p=preview)

- `ui-validate` にオブジェクトを渡せば、プロパティの名前がルール名になり、値がチェックロジックになる。
- 複数のチェック（プロパティ）を指定することも可能。

##他のモデルの変更を監視する
```html:
<!DOCTYPE html>
<html ng-app="mine">
  <head>
    <meta charset="UTF-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script src="ui-utils.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <form name="myForm">
      <input type="text" name="hoge" ng-model="x" />
      <input type="text" name="fuga" ng-model="y" ui-validate=" 'validateFuga(x, $value)' " ui-validate-watch=" 'x' " />
      
      <p>myForm.fuga.$error.validator = {{myForm.fuga.$error.validator}}</p>
    </form>
  </body>
</html>
```

```js:
angular
.module('mine', ['ui.utils'])
.run(function($rootScope) {
    $rootScope.validateFuga = function(x, y) {
        return x === y;
    };
});
```

[Plunker サンプル](http://plnkr.co/edit/4VAU2JgJE2o1L6Onuv4S?p=preview)

- `ui-validate-watch` にモデルの名前を文字列で指定すると、そのモデルの変更も監視するようになる。


#参考
##AngularUI UI.Utils について
- [Angular UI ~ UI.Utils Doc](http://angular-ui.github.io/ui-utils/)

##checkbox の indeterminate について
- [3状態チェックボックス（HTML5だけど古いIEでも動く） - Qiita](http://qiita.com/mk_summer/items/305f72fd725989a14ecc)

##キーコードについて
- [各ブラウザのキーコード表[JavaScript]](http://www.programming-magic.com/file/20080205232140/keycode_table.html)