Knockout Bootstrap 3 TypeAhead

by Dejan Vasic

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="container">
  <div class="form-group">
    <label class="control-label">Seat (jQuery only)</label>
    <input type="text" class="form-control" autocomplete="off" />
  </div>

  <div class="form-group">
    <label class="control-label">Seat (knockout binding)</label>
    <input type="text" class="form-control" autocomplete="off" data-bind="typeahead: seats, value: seatNumber" />
    <p class="help-text">
      Selected Seat: <span data-bind="text: seatNumber"></span>
    </p>
  </div>
</div>

JavaScript

var seats = ['A1', 'A2', 'A3'];

// Simple jQuery 
$('input').typeahead({
  source: seats
});

ko.bindingHandlers.typeahead = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    var $element = $(element);
    var allBindings = allBindingsAccessor();
    var source = ko.utils.unwrapObservable(valueAccessor());
    var items = ko.utils.unwrapObservable(allBindings.items) || 4;

    var valueChange = function(item) {
      return item;
    };

    var options = {
      source: source,
      items: items,
      updater: valueChange
    };

    $element
      .attr('autocomplete', 'off')
      .typeahead(options);
  }
};


// Model
var model = {
  seatNumber: ko.observable(),
  seats: ko.observableArray(seats)
};

ko.applyBindings(model);