knockoutのデータバインディングは formの入力要素と連携できます。今回はいくつかのサンプルでフォームに関連するバインディングを使ってみました。

動作確認は KnockoutJS 3.3 で行っています。

1. 簡単なサンプル textInput, value, enable バインディングを使ってみます

フォームの input で使用するバインディングは value バインディングだと思います。下記サンプルではvalueとtextInputバインディングを使用して入力数をカウントしています。また、checkedとenableバインディングを使用してチェックボックスにチェックしたら送信ボタンを押せるようにしています。 value は onChangeイベントで値が評価されますが、 textInput バインディングの場合はキーを入力したら即時に値が再評価されるという違いがあります。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <form>
        <h1>テキスト入力カウント:キー入力時即時に反映</h1>
        <textarea data-bind="textinput: text1"></textarea><br/>
        残りの文字 <span data-bind="text: leftoverCharacters1"></span>
        <h1>テキスト入力カウント:フォーカスが外れたタイミングで繁栄(onChange)</h1>
        <textarea data-bind="value: text2"></textarea><br />
        残りの文字 <span data-bind="text: leftoverCharacters2"></span><br/>
        <input type="checkbox" data-bind="checked: isAcceptConditions"  /><label>同意する</label>
        <input type="submit" data-bind="enable: isAcceptConditions" value="送信" />
    </form>
    <script type="text/javascript" src="/Scripts/knockout-3.3.0.js"></script>
    <script type="text/javascript">
        function viewModel(maxlength) {
            var self = this;

            self.maxlength = maxlength;

            self.text1 = ko.observable('');
            self.leftoverCharacters1 = ko.pureComputed(function () {
                return self.maxlength - self.text1().length;
            })

            self.text2 = ko.observable('');
            self.leftoverCharacters2 = ko.pureComputed(function () {
                return self.maxlength - self.text2().length;
            })

            self.isAcceptConditions = ko.observable(false);
        }
        var vm = new viewModel(200);    
        ko.applyBindings(vm);   
    </script>
</body>
</html>

2.checked バインディングと配列を組み合わせて使用する

checkedバインディングは bool のプロパティにバインドできるだけでなく、配列のコレクション(ObservableArray)にバインドすることでチェックされた項目の値を配列に追加できるようになります。下記サンプルでは、チェックボックスにチェックした項目をドロップダウンリストの選択しに追加するようにしています。また、クリアボタンで選択をクリアしています。checkedやoptions, click バインディングを使用しています。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <form>
        <h1>配列とcheckedをバインド</h1>
        <div>
            <input type="checkbox" data-bind="checked: prefectures" value="Tokyo" />
            <input type="checkbox" data-bind="checked: prefectures" value="Aichi" />
            <input type="checkbox" data-bind="checked: prefectures" value="Hokkaido" />
        </div>
        <select data-bind="options:prefectures, optionsCaption:'都道府県を選択'"></select><br/>
        <input type="button" data-bind="click: clear" value="リストをクリア" />
    </form>
    <script type="text/javascript" src="/Scripts/knockout-3.3.0.js"></script>
    <script type="text/javascript">
        function viewModel() {
            var self = this;

            self.prefectures = ko.observableArray([]);
            self.clear = function () {
                self.prefectures([]);
            }
        }
        var vm = new viewModel();    
        ko.applyBindings(vm);   
    </script>
</body>
</html>

 

3. subscribe を使用してカスケーディングドロップダウンを使用してみる

サンプルや公式ドキュメントを使用すると結構簡単にバインディングの機能を利用できることが分かると思います。今回の記事の最後に subscribe メソッドを使用して observableなオブジェクトの変更をサブスクライブしてカスケーディングドロップダウンを作成するサンプルを記載します。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <form>
        <h1>subscribe を使用してカスケーディングドロップダウンを実装する</h1>
        <div>
            <select data-bind="options:destination, optionsCaption:'都道府県を選択', optionsText:'prefecture', optionsValue: 'id', value: selectedPrefecture"></select>
            <select data-bind="options:airport, optionsCaption:'空港を選択',  value: selectedAirport"></select>
        </div>
    </form>
    <script type="text/javascript" src="/Scripts/knockout-3.3.0.js"></script>
    <script type="text/javascript">
        function viewModel() {
            var self = this;

            self.destination = ko.observableArray([
                {
                    id: 1, prefecture: '東京',
                    airport : ['羽田', '成田']
                }, {
                    id: 2, prefecture: '北海道',
                    airport: ['千歳', '函館']
                }, {
                    id: 2, prefecture: '大阪',
                    airport: ['関空', '伊丹']
                }
            ]);
            self.airport = ko.observableArray([]);

            self.selectedPrefecture = ko.observable();
            self.selectedAirport = ko.observable();

            // 値の変更をサブスクライブするイベントリスナーを実装
            self.selectedPrefecture.subscribe(function () {
                self.airport([]); // クリア
                // 実際は Webサービスなどを呼び出すかもしれませんが、今回は静的なデータを使用
                for (var i = 0; i < self.destination().length; ++i){
                    if(self.destination()[i].id == self.selectedPrefecture()){
                        self.airport(self.destination()[i].airport);
                        break;
                    }
                }
            });
        };
        var vm = new viewModel();    
        ko.applyBindings(vm);   
    </script>
</body>
</html>

subscribe 関数を使用して 値が変更したタイミングで 子ドロップダウンにバインドしている observableArray の内容を変更しています。

4.まとめ

サンプルコードのご紹介は以上です。

今回取り上げませんでしたが、そのほか disable ,submit, hasFocus, selectedOptions, event 等のバインディングもあります。詳細は KnockoutJS の ドキュメントhttp://knockoutjs.com/documentation/introduction.htmlを参照してください。