專案裡的介面需求: 網站需開放使用者由候選清單挑選多個項目放入組成清單,組成清單的項目要能調整順序。

實作範例如下,就想像從三國武將中挑選精英組團打副本吧!(裡面有個黑大是什麼東西?) 並可調整出場順序。

搬出Knockout,運用下拉選單的options、selectedOptions多選繫結加上JavaScript陣列基本操作,就能讓選取項目在兩個<select>間搬移;至於選取項目在陣列上下移動,以前我只會傻傻用for跑迴圈搬動,學會splice()後,就能用兩行指令優雅地完成。

就這樣,不到90行,搞定收工~ 線上展示

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>KO範例30 - 可排序的多重選擇器</title>
    <style>
      select { width: 100px; height: 120px;}
    </style>
</head>
<body>
<table>
  <tr>
    <td>
      <select multiple data-bind="options: candidates, selectedOptions: selCandidates"></select>
    </td>
    <td>
      <input type='button' value='&gt;' data-bind="click: pick" />
      <br />
      <input type='button' value='&lt;' data-bind="click: unpick" />
    </td>
    <td>
      <select multiple data-bind="options: members, selectedOptions: selMembers"></select>
    </td>
    <td>
      <input type='button' value='▲' data-bind="click: moveUp" />
      <br />
      <input type='button' value='▼' data-bind="click: moveDown" />
    </td>
  </tr>
  </table>
 
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
    <script>
        function myViewModel() {
          var self = this;
          self.candidates = ko.observableArray(
            ["關羽", "張飛", "孔明", "呂布", "典韋", "許褚", "黑大"]);
          self.selCandidates = ko.observableArray();
          self.members = ko.observableArray();
          self.selMembers = ko.observableArray();
          self.pick = function() {
            $.each(self.selCandidates(), function(i, m) {
              self.candidates.remove(m);
              self.members.push(m);
            });
            self.selCandidates([]);           
          };
          self.unpick = function() {
            $.each(self.selMembers(), function(i, m) {
              self.members.remove(m);
              self.candidates.push(m);
            });
            self.selMembers([]);
          };
          function get1stSelMem() {
            var ary = self.selMembers();
            if (ary.length) {
              var mem = ary[0];
              ary = self.members();
              return { array: ary, index: $.inArray(mem, ary), value: mem };
            }
            return null;
          }
          self.moveUp = function() {
            var res = get1stSelMem();
            if (res && res.index) {
              res.array.splice(res.index, 1);
              res.array.splice(res.index - 1, 0, res.value);
              self.members(res.array);
            }
          };
          self.moveDown = function() {
            var res = get1stSelMem();
            if (res && res.index < res.array.length - 1) {
              res.array.splice(res.index, 1);
              res.array.splice(res.index + 1, 0, res.value);
              self.members(res.array);
            }
          };
        }
        var vm = new myViewModel();
        ko.applyBindings(vm);
    </script>
</body>
</html>

[KO系列]

http://www.darkthread.net/kolab/labs/default.aspx?m=post

Comments

# by hsiao

黑大 線上展示我如果選了左欄的關羽再點二下搬移『>』 右邊就會出現2個關羽~反之亦然

# by Jeffrey

to hsiao, 感謝指正,原寫法有Bug。搬移完成後加入self.selCandidates([])及self.selMembers([])清空已選取項目,問題已修正,再次感謝。

# by hsiao

黑大,小弟才要感謝您阿。常常看黑大的文章受良多,小弟功力淺薄真的是連黑大的車尾燈都看不到XD

Post a comment