Crumblenautjs Crumblenautjs - 1 year ago 109
TypeScript Question

Knockout Checkboxes using Typescript

Context: I have a table with a list of checks. Each check has a checkbox and the table itself has a "select all" check box at the top. The purpose for the check boxes is to print the checks.

I currently have the select all check box working - it adds all of the checks to a chosenChecks ko.observable array as well as the checkIDs to a CheckIDs array. The server's print function uses a list of checkIDs.

The issue I am having is with the adding and removing of individual checks/checkIDs.. I'm not sure how to determine if the check/checkID is already in the array, and if so, how to remove it. Here's the code, with the views etc.

Disclaimer: I might be over thinking this in how I've setup all of my arrays.

Thanks for all your help.

The View:

<table class="details_table" data-bind="visible: vendorChecks().length">
<th>Check ID
<th>Check Date
<th>Vendor Name
<th>Check Amount
<th>Approve Status
<input type="checkbox" data-bind="checked: selectAllChecks" title="Select all/none"/>

<tbody class="nohighlight" data-bind="foreach: $root.vendorChecks">
<td><span data-bind="text: $data.CheckID"></span></td>
<td><span data-bind="text: CheckDate"></span></td>
<td><span data-bind="text: VendorName"></span></td>
<td><span data-bind="text: FormatCurrency(CheckAmount())"></span></td>
<td><span data-bind="text: Globalize.formatCheckRunApproveStatus(ApprovalStatusID())"></span></td>
<input type="checkbox" class="print_line_checkbox" data-bind="checkedValue: $data, checked: $root.chosenChecks(), click: $root.addCheck"/>

The Typescript:

class SearchPrintedChecksModel {
public checkRuns = ko.observableArray<CheckRunModel>(null);
public bankDrafts = ko.observableArray<BankDraftInfoModel>(null);
public vendorChecks = ko.observableArray<BankDraftInfo>(null);
public isSelectedCheck = ko.observable(false);
public chosenChecks = ko.observableArray<BankDraftInfo>(null);
public checkIDs = ko.observableArray();

public addCheck(checkIDs) {
var checks = printModel.chosenChecks();
const CheckIDs = checkIDs;
for (var i in checks) {
public selectAllChecks = ko.pureComputed({
read: function () {
return this.chosenChecks().length === this.vendorChecks().length;
write: function(value) {
this.chosenChecks(value ? this.vendorChecks.slice(0) : []);
const checks = printModel.chosenChecks();
const checkIDs = printModel.checkIDs();
for (let i in checks) {
if (checks.hasOwnProperty(i)) {
owner: this


$(document).ready(() => {

Answer Source

Rather than finding the error in your logic, I'd suggest looking in to a slightly different structure:

  • Put a checked observable in each of the items. Use this observable in the checked data-bind.
  • Create a computed with a read and write method in the parent view model.
    • The read function checks if all items are checked
    • The write function passes the written value to each item

Here's what the code would look like:

function ViewModel() {
  this.items = [
    { id: 1, checked: ko.observable(false) },
    { id: 2, checked: ko.observable(false) },
    { id: 3, checked: ko.observable(false) },
    { id: 4, checked: ko.observable(false) },
   this.allChecked = ko.computed({
     read: function() {
       return this.items.every(function(item) {
         return item.checked();
     write: function(value) {
        this.items.forEach(function(item) {
   }, this);
ko.applyBindings(new ViewModel());
<script src=""></script>

  <input type="checkbox" data-bind="checked: allChecked">
<ul data-bind="foreach: items">
      <input type="checkbox" data-bind="checked: checked"/>
      <span data-bind="text: 'Item ' + id"></span>