https://stackoverflow.com/questions/44167547/using-bootstrap-modals-in-knockoutjs

by jlspake

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<table>
  <tr data-bind="foreach: items">
    <td data-bind="css: { highlighted: $root.highlightedRowIndex() == $index() }">
      <input type="text" data-bind="value: itemNo, insertPress: $index, deletePress: $index, selected: invalidItemNum, hasFocus: isSelected, event: { blur: $parent.onBlur }" class="form-control" />
    </td>
  </tr>
</table>

CSS

highlighted {
  border: 1px solid orange;
}

JavaScript

var viewModel = function() {
  var self = this;
  
  self.highlightedRowIndex = function(){
  	return 0;
  }
  
  self.onBlur = function(data, e){ 
  	e.preventDefault();
  	var index = self.items.indexOf(data);
    console.log(data.itemNo() + ': ' + index);
    self.checkItemNo(data, index);
  }

  self.checkItemNo = function(data, index) {
    var itemNo = $.trim(data.itemNo());
    if (confirm("Verify?")) {
    	//Focus moves to next input
      //data.isSelected(false); //happens automatically with hasFocus bind
      if(index < self.items().length - 1){
      	self.items()[index+1].isSelected(true);    	
      }
    } else {
      //Focus restored to previous input
      data.isSelected(true); //reselect it since hasFocus unselected it.
    }
  };
  
  self.items = ko.observableArray([
    {
      value: ko.observable(0),
      invalidItemNum: ko.observable(false),
      itemNo: ko.observable(0),
      isSelected: ko.observable(false)
    },
    {
      value: ko.observable(1),
      invalidItemNum: ko.observable(false),
      itemNo: ko.observable(1),
      isSelected: ko.observable(false)
    }
  ]);
}

ko.applyBindings(new viewModel());

$('#reportItem').click(function() {
  $('#invalidItemModal').modal('hide');
  // ??? - go to next knockout input from previous input that was blurred
});