我是淘汰赛的新手,我需要帮助! 我有一个书籍列表(例如),我希望标记几个或选择/取消全选。我需要用图像设置复选框的样式。当我这样做的一切都破裂了。我在这里上传了我的大部分代码。谢谢你的时间!
// 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">« Previous Step</button>
<button id="updateContactBtn" class="btn btn-primary" data-bind="click: GoNext, visible: canGoNext() ">Next Step »</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;
答案 0 :(得分:1)
我还没有通过所有代码阅读,但这可能有所帮助:
要设置一个可以切换“全选”的复选框,您可以使用具有computed
和read
功能的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。如果我是你,我会将我的属性重命名为以小写字符开头,这样它们就不会与构造函数方法混淆。