May 29, 2013

KnockoutJS - radio button與textbox混搭應用

有一組表單控制項佈置如下

我們希望可以達到以下需求,如何以KnockoutJS來實作?
  1. 選擇Other時,textbox才可以輸入資料
  2. 選擇Other時,textbox要自動取得focus
  3. 選擇Other輸入資料後,再選擇其它項目時,將textbox內的資料清空

建立View
<h3>What's your favorite fruit?</h5>
<label>
    <input name="fruit" type="radio" value="Apple" />Apple</label>
<label>
    <input name="fruit" type="radio" value="Banana" />Banana</label>
<label>
    <input name="fruit" type="radio" value="Other" />Other:</label>
<input type="text" />


建立ViewModel
function ViewModel() {
    var self = this;
    self.fruit = ko.observable("");
    self.hasOther = ko.computed(function () {
        return self.fruit() == "Other";
    });

    self.hasOther.subscribe(function (newValue) {
        if (!newValue) {
            self.other('');
        }
    });

    self.other = ko.observable("");
}

ko.applyBindings(new ViewModel());
  • fruit屬性表示所選擇的水果種類
  • hasOther屬性表示是否選擇Other自行輸入水果名稱。hasOther為一個computed屬性,如果使用者選擇的是Other則hasOther為true
  • other屬性表示使用者於textbox裡輸入的值
  • hasOther屬性使用subscribe函式,當使用者選擇的不是Other時就將屬性other清空。

建立Data Bindings
<h3>What's your favorite fruit?</h5>
<label>
    <input name="fruit" type="radio" value="Apple" data-bind="checked: fruit" />Apple</label>
<label>
    <input name="fruit" type="radio" value="Banana" data-bind="checked: fruit" />Banana</label>
<label>
    <input name="fruit" type="radio" value="Other" data-bind="checked: fruit" />Other:</label>
<input type="text" data-bind="value: other, enable: hasOther(), hasfocus: hasOther()" />
  • radio button設定checked binding來記錄fruit屬性值
  • textbox設定value binding記錄使用者輸入的水果名稱
  • textbox設定enable bindng,當hasOther屬性為true(使用者撰擇Other)時,textbox方能編輯
  • textbox設定hasfocus binding,當hasOther屬性為true(使用者撰擇Other)時,textbox就能取得focus
執行結果請參考http://jsfiddle.net/petekcchen/NZTD4/

No comments: