使用select / deselect all复选框敲出js图像样式复选框组

时间:2017-07-04 21:56:49

标签: knockout.js

我是淘汰赛的新手,我需要帮助! 我有一个书籍列表(例如),我希望标记几个或选择/取消全选。我需要用图像设置复选框的样式。当我这样做的一切都破裂了。我在这里上传了我的大部分代码。谢谢你的时间!



  // Main JS - Step`s Wizard
  // defines a single step in the wizard
  function Step(id, type, template) {
      var self = this;
      // step id
      self.id = id;
      // indicates wether this is a common or a specific type
      self.templateType = type;
      // the template name
      self.template = template;
      // just a helper to check whether this is a common or not
      self.common = (type == 0);
  }

  // this is our ko view model
  var createCustomer = function() {
      var self = this;

      // create a new customer object
      self.CustomerType = ko.observable();
      self.Registration = ko.observable();
      self.Tax = ko.observable();
      self.Name = ko.observable();
      self.Contact = ko.observable();
      self.Address = ko.observable();
      self.searchForMarketingListFolder = ko.observable("");

      self.navSteps = ko.observableArray([{
          "name": "Marketing Lists",
          "step": 1
      }, {
          "name": "Map Fields",
          "step": 2
      }, {
          "name": "Confirm and import",
          "step": 3
      }]);
      // a simple validation method
      self.IsValid = function() {
          return true //!!self.CustomerType();
      };
      // define the customer types (ideally get them from the server)
      self.MarketingList = ko.observableArray([
          new MarketingList("cbML1", "Summer Events Invitees"),
          new MarketingList("cbML2", "Monthly Newsletter"),
          new MarketingList("cbML3", "Interests - Dynamics Solution")
      ]);
      self.filteredMarketingList = ko.computed(function() {
          var filter = self.searchForMarketingListFolder().toLowerCase();

          if (!filter) {
              return self.MarketingList();
          } else {
              return ko.utils.arrayFilter(self.MarketingList(), function(item) {
                  return item.Name.toLowerCase().indexOf(filter) !== -1;
              });
          }
      });

      self.sendFieldsForMapping = ko.observableArray([{
          SendID: 1,
          SendFieldName: "First Name",
          CRMID: ko.observable()
      }, {
          SendID: 2,
          SendFieldName: "Last Name",
          CRMID: ko.observable()
      }, {
          SendID: 3,
          SendFieldName: "Email",
          CRMID: ko.observable()
      }]);
      self.fieldMapListDropDown = ko.observableArray([
          new fieldMapListDropDown(111111, "First Name"),
          new fieldMapListDropDown(222222, "Last Name"),
          new fieldMapListDropDown(333333, "Email")
      ]);

      // define the steps
      self.stepModels = ko.observableArray([
          new Step(1, 0, "step1Tmpl"),
          new Step(2, 1, "step2Tmpl"), 
          new Step(3, 1, "step3Tmpl"), 
      ]);



      // set the current step to the 1st initially
      self.currentStep = ko.observable(self.stepModels()[0]);
      // get the current step index (0 based)
      self.currentIndex = ko.computed(function() {
          return self.stepModels.indexOf(self.currentStep());
      });
      // get current step template
      self.getTemplate = function(data) {
          return self.currentStep().template;
      };
      // check whether theres another step we can goto
      self.canGoNext = ko.computed(function() {
          return self.currentIndex() < self.stepModels().length - 1;
      });
      // check whether theres another step we can go back to
      self.canGoPrevious = ko.computed(function() {
          return self.currentIndex() > 0;
      });
      self.checkCurrentStep = function(step) {
          return self.currentIndex() === step - 1;
      };
      self.showImportBtn = function() {
          return self.currentIndex() === self.stepModels().length - 1;
      };
      // go back one step
      // here we need to take the customer type into account
      self.GoBack = function() {
          var d = ko.toJS(self); // convenience  

          // proceed only if we can go back
          if (self.canGoPrevious()) {
              var prev;
              if (d.CustomerType == 2) { // residential
                  // use underscore.js filter method
                  prev = _.filter(self.stepModels(), function(m) {
                      // get the common ones and skip the business ones
                      return (m.id <= self.currentIndex() + 1) && (m.templateType == 0 || m.common);
                  });
              } else {
                  prev = _.filter(self.stepModels(), function(m) {
                      // get the common ones AND business ones.
                      return (m.id <= self.currentIndex() + 1) && (m.templateType == 1 || m.common);
                  });
              }

              // filtering will give us every step we have to take in this
              // route upto where we are already
              // so the last in the list will be the current step
              // so, reverse it, get the 1st one (0th is current)
              self.currentStep(prev.reverse()[1]);
          }
      };
      self.GoNext = function() {
          // run validations:
          if (!self.IsValid()) {
              alert("Select customer type");
              return;
          }
          // same logic as in GoBack()
          // except we check for larger than current ids.
          var d = ko.toJS(self);

          if (self.canGoNext()) {
              var nxt;
              if (d.CustomerType == 2) {
                  nxt = _.find(self.stepModels(), function(m) {
                      return (m.id > self.currentIndex() + 1) && (m.templateType == 0 || m.common);
                  });
              } else {
                  nxt = _.find(self.stepModels(), function(m) {
                      return (m.id > self.currentIndex() + 1) && (m.templateType == 1 || m.common);
                  });
              }
              self.currentStep(nxt);
          }
      };
      self.SelectAll = ko.observable({
          'Selected': ko.observable(false)
      });
      //   self.SelectAll = ko.computed({
      //       read: function() {
      //           var tmpElement = document.getElementById('cbML0');
      //           var item = ko.utils.arrayFirst(self.MarketingList(), function(item) {
      //               if (tmpElement != null) {
      //                   if (item.Selected()) {
      //                       tmpElement.classList.remove('unchecked');
      //                       tmpElement.classList.add('tdCheckbox');
      //                   } else {
      //                       tmpElement.classList.remove('tdCheckbox');
      //                       tmpElement.classList.add('unchecked');
      //                   }
      //               }
      //               return !item.Selected();
      //           });
      //           return item == null;
      //       },
      //       write: function(value) {
      //           ko.utils.arrayForEach(self.MarketingList(), function(list) {
      //               list.Selected(value);
      //           });
      //       }
      //   });

      self.ImportData = function() {
          var tmpMarketingList = ko.toJS(self.MarketingList());
          var tmpSelectedFieldMaps = ko.toJS(self.sendFieldsForMapping());
          var tmpFieldMapListDropDown = ko.toJS(self.fieldMapListDropDown());

          self.confirmAndImport = new confirmAndImport(tmpMarketingList, tmpSelectedFieldMaps, tmpFieldMapListDropDown);
          console.log('self.confirmAndImport');
          console.log(self.confirmAndImport);
          console.log("******* 2 ***********");
          new ImportDataFromInterAction(self.confirmAndImport);


      };
  };

  var MarketingList = function(id, name) {
      this.id = id;
      this.Name = name;
      this.Selected = ko.observable(true);
  };
  var fieldMapListDropDown = function(id, name) {
      this.CRMID = id;
      this.CRMName = name;
      this.CRMSelected = ko.observable();
  };

  var ImportDataFromInterAction = function(data) {
      console.log(data);
  }
  var viewModel = new createCustomer();
  ko.applyBindings(viewModel, $("#IA-Main-Container")[0]);

  function confirmAndImport(MarketingList, tmpSelectedFieldMaps, tmpFieldMapListDropDown) {

      var showConfirmAndImportData = new Object;
      showConfirmAndImportData.MarketingList = [];
      showConfirmAndImportData.MapFields = [];

      Object.keys(MarketingList).map(function(objectKey, index) {
          if (MarketingList[index].Selected) {
              showConfirmAndImportData.MarketingList.push(MarketingList[index]);
          }
      });
      Object.keys(tmpSelectedFieldMaps).map(function(objectKey, index) {
          var match = ko.utils.arrayFirst(tmpFieldMapListDropDown, function(item) {
              return item.CRMID == tmpSelectedFieldMaps[index].CRMID;
          });
          showConfirmAndImportData.MapFields.push({
              'fieldName': tmpSelectedFieldMaps[index].SendFieldName,
              'connectedToCRMID': match.CRMID,
              'connectedToCRMName': match.CRMName,
          });
      });

      return showConfirmAndImportData;
  }

  function toggleClassesOnMarketingListCheckBoxes(pressedId) {


      var tmpData = viewModel.MarketingList()
      tmpData.forEach(function(objectKey, index) {
          if (pressedId != 'cbML0') {
              if (objectKey.id == pressedId) {
                  viewModel.MarketingList()[index].Selected(!objectKey.Selected());
                  toggleClassesOnMarketingListCheckBoxesInnerFunction(viewModel.MarketingList()[index].Selected(), pressedId);
              }
          } else {
              viewModel.MarketingList()[index].Selected(viewModel.SelectAll().Selected());
              toggleClassesOnMarketingListCheckBoxesInnerFunction(!viewModel.SelectAll().Selected(), viewModel.MarketingList()[index].id);
          }
      });

      if (pressedId == 'cbML0') {
          //viewModel.SelectAll.Selected() && tmpElement.classList.contains('unchecked')
          var tmp = viewModel.SelectAll();
          toggleClassesOnMarketingListCheckBoxesInnerFunction(tmp.Selected(), pressedId);
          viewModel.SelectAll().Selected(!viewModel.SelectAll().Selected());
      }
  };

  function toggleClassesOnMarketingListCheckBoxesInnerFunction(bool, pressedId) {
      var tmpElement = document.getElementById(pressedId);
      if (tmpElement != null) {
          if (bool) {
              tmpElement.classList.remove('unchecked');
              tmpElement.classList.add('tdCheckbox');
          } else {
              tmpElement.classList.remove('tdCheckbox');
              tmpElement.classList.add('unchecked');
          }
      }
  }
&#13;
#IA-Main-Container {
  width: 800px;
  height: 500px;
  background: lightgoldenrodyellow;
  margin: auto;
  padding: 5px;
  border: 3px solid silver;
  border-style: solid;
  border-color: #d7d9db;
  color: #3c4650;
  font-family: Arial, Verdana, Sans-Serif;
}

#IA-Main-Container .searchForm#marketingListSearchForm {
  height: 23px;
  line-height: 23px;
  padding: 5px;
  border: 1px solid;
  margin-bottom: 10px;
  background-color: #d7d9db;
  border-color: #d7d9db;
  text-align: right;
}

#IA-Main-Container input[type=checkbox] {
  /*display: none;*/
}

#IA-Main-Container input[type=checkbox].unchecked+label {
  width: 14px;
  height: 14px;
  background-image: url('https://c.contentsvr.com/skins/common/images/icons/common.png');
  background-position: 0px -14px;
  background-repeat: no-repeat;
  background-color: transparent;
  cursor: pointer;
  display: inline-block;
  font-size: 14px;
  height: 14px;
  line-height: 14px;
  padding: 0;
  text-align: left;
  text-decoration: none;
  text-indent: -9999px;
  width: 14px;
}

#IA-Main-Container input[type=checkbox].tdCheckbox:checked+label {
  width: 14px;
  height: 14px;
  background-image: url('https://c.contentsvr.com/skins/common/images/icons/common.png');
  background-position: -14px -14px;
  background-repeat: no-repeat;
  background-color: transparent;
  cursor: pointer;
  display: inline-block;
  font-size: 14px;
  height: 14px;
  line-height: 14px;
  padding: 0;
  text-align: left;
  text-decoration: none;
  text-indent: -9999px;
  width: 14px;
}

#IA-Main-Container .searchForm#marketingListSearchForm input {
  border: 1px solid #7F8084;
  margin: 3px 0 0;
  padding: 1px;
}

#IA-Main-Container .searchForm#marketingListSearchForm input::-webkit-input-placeholder {
  color: #999;
  padding-left: 3px;
}

#IA-Main-Container header {
  height: 34px;
  background-color: #FFF;
  border-color: #FFF;
  color: #00aae6;
  font-size: 1.2em;
  display: block;
  clear: both;
  margin-bottom: 10px;
  padding: 5px;
}

#IA-Main-Container header .title {
  width: 80%;
  float: left;
  line-height: 34px;
  font-weight: 700;
  margin: 0 5px 0 0;
}

#IA-Main-Container tbody {
  overflow-y: auto;
  overflow-x: hidden;
}

#IA-Main-Container .nav-stepContainer {
  margin-top: 10px;
  margin-bottom: 16px;
  height: 27px;
}

#IA-Main-Container .nav-stepContainer nav ul {
  font-size: 1em;
  float: left;
  list-style: none;
  width: auto;
  display: block;
  padding: 0px;
  margin: 0px;
}

#IA-Main-Container .nav-stepContainer nav ul li {
  font-size: 1em;
  float: left;
  list-style: none;
  width: auto;
}

#IA-Main-Container .nav-stepContainer nav ul li a {
  border-bottom: 5px solid;
  border-color: #DDD;
  color: #999;
  text-decoration: none;
  padding-bottom: 4px;
}


/*#IA-Main-Container .nav-stepContainer nav ul li .selected_navigationBar {*/

.selected_navigationBar {
  border-color: #00aae6 !important;
  color: black !important;
}

#IA-Main-Container .nav-stepContainer nav ul li:not(:first-child)
/*:not(:last-of-type)*/

{
  background-image: url('https://d3dcudlcyz9qvm.cloudfront.net/skins/_common/5/images/brand.png');
  background-position: 5px -232px;
  padding-left: 15px;
}

.innerScreen {
  height: 325px;
  padding: 2px;
  border: 2px solid #9FADAC;
}

.innerScreen table tbody tr {
  border-bottom: 1px solid #9FADAC;
}

.footer {
  text-align: right
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="IA-Main-Container">
        <header>
            <label class="title"> Import InterAction List </label>
        </header>
        <div class="nav-stepContainer">
            <nav>
                <ul data-bind="foreach: navSteps">
                    <li>
                        <a data-bind="text: name, css:{selected_navigationBar: $parent.checkCurrentStep(step) }, attr: {'id': step}"> </a>
                    </li>
                </ul>
            </nav>
        </div>
        <div>
            <div data-bind="template: { name: getTemplate }"></div>
        </div>
        <div class="footer">
            <label>Cancel</label>
            <button id="updateContactBtn" class="btn btn-primary" data-bind="click: GoBack, visible: currentIndex() > 0">&#171; Previous Step</button>
            <button id="updateContactBtn" class="btn btn-primary" data-bind="click: GoNext, visible: canGoNext() ">Next Step &#187;</button>
            <button id="updateContactBtn" class="btn btn-primary" data-bind="click: ImportData, visible: showImportBtn() ">Import</button>
        </div>
    </section>


    <script type="text/html" id="step1Tmpl">
        <div class="form-group">
            <form class="searchForm" id="marketingListSearchForm">
                <input type="text" name="search" placeholder="Search for" data-bind="textInput: searchForMarketingListFolder" autocomplete="off">
            </form>
            <div class="innerScreen">
                <table>
                    <thead>
                        <tr>
                            <th><input type="checkbox" name='thing' value='valuable' data-bind="checked: SelectAll, css: {'unchecked': !SelectAll(), 'tdCheckbox' : SelectAll() }" id="cbML0" />
                                <label for="thing"></label>
                            </th>
                            <th>Name</th>
                        </tr>
                    </thead>
                    <tbody data-bind="foreach: filteredMarketingList">
                        <tr>
                            <td><input type="checkbox" name='thing' value='valuable' class="MarketingListChecboxGroup" data-bind=", css: {'unchecked': !Selected(), 'tdCheckbox' : Selected() }, checked: Selected, attr: {'id': id}" />
                                <label for="thing"></label>
                            </td>
                            <td data-bind="text: Name"></td>
                        </tr>
                    </tbody>
                </table>
            </div>
    </script>






    <script type="text/html" id="step2Tmpl">
        <div class="form-group " style=" border: 3px solid silver; margin: 10px; padding: 25px;">
            <p>
                <label style="width:100%" class="col-md-4 control-label">Determine how the fields in your list should be stored.</label>
            </p>
            <table style="width:100%">
                <thead>
                    <tr style="text-align: left;">
                        <th style="width:50%">Field in Your List</th>
                        <th style="width:50%">Store As</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>
                            <label>First Name</label>
                        </td>
                        <td>
                            <label>First Name</label>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <label>Last Name</label>
                        </td>
                        <td>
                            <label>Last Name</label>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <label>Email</label>
                        </td>
                        <td>
                            <label>Email</label>
                        </td>
                    </tr>
                </tbody>
                <tbody data-bind="foreach: sendFieldsForMapping">
                    <tr>
                        <td data-bind="text: SendFieldName"></td>
                        <td>
                            <div class="col-md-8">
                                <select id="CustomerType" name="CustomerType3" class="col-md-6 form-control" data-bind="value: CRMID, options: $parent.fieldMapListDropDown, optionsText: 'CRMName', optionsValue: 'CRMID', optionsCaption: 'Select...'"></select>
                            </div>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

    </script>






    <script type="text/html" id="step3Tmpl">


    </script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

我还没有通过所有代码阅读,但这可能有所帮助:

要设置一个可以切换“全选”的复选框,您可以使用具有computedread功能的write可观察对象。

  • 读取功能会检查所有项目是否为Selected并返回true(如果有),如果不是则false
  • 写入值会在传递Selected时标记所有项目true,并在传递false时取消选择所有项目。

即:

this.SelectAll = ko.computed({
  read: function() {
    return this.MarketingList().every(function(item) {
      return item.Selected();
    });
  },
  write: function(val) {
    this.MarketingList().forEach(function(item) {
      item.Selected(val);
    });
  }
}, this);

在一个工作示例中:

function Item(name) {
  this.name = name;
  this.selected = ko.observable(false);
};

function App() {

  this.items = ko.observableArray([
    new Item(1),
    new Item(2),
    new Item(3)
  ]);
    
  this.allSelected = ko.computed({
    read: function() {
      return this.items().every(function(item) {
        return item.selected();
      });
    },
    write: function(val) {
      this.items().forEach(function(item) {
        item.selected(val);
      });
    }
  }, this);
}

ko.applyBindings(new App());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>


<label>
  <input type="checkbox" data-bind="checked: allSelected">
  <span>select all</span>
</label>

<ul data-bind="foreach: items">
  <li>
    <label>
      <input type="checkbox" data-bind="checked: selected">
      <span data-bind="text: name"></span>
    </label>
  </li>
</ul>

P.S。如果我是你,我会将我的属性重命名为以小写字符开头,这样它们就不会与构造函数方法混淆。