2 var Backbone = require('backbone');
3 var Marionette = require('backbone.marionette');
4 const debug = require('debug-proxy')('app:typeahead');
5 var Dropdown = require('./dropdown');
6 var liveSearch = require('./live-search');
8 var TypeaheadView = Marionette.ItemView.extend({
14 initialize: function(options) {
15 this.disableListenToChange = options.disableListenToChange;
16 this.longDebounce = options.longDebounce;
17 this.shortDebounce = options.shortDebounce;
19 if (!this.collection) {
20 this.collection = new Backbone.Collection();
23 if (!options.disableShowOnAdd) {
24 // fix for first typeahead suggestion not triggering
25 // the dropdown to show
27 // if dropdown.show() is called on every add, then you
28 // get weird duplicates in the collectionView (!)
30 // tbh, dropdown's support for live typeaheads and static menus
32 this.listenToOnce(this.collection, 'add', function() {
38 this.autoSelector = options.autoSelector;
45 onRender: function() {
50 * clear() clears the input element's value
72 if (this.dropdown) return;
73 liveSearch(this, this.$el, 'searchTextChanged', {
74 immediate: 'autoSelect',
75 disableListenToChange: this.disableListenToChange,
76 longDebounce: this.longDebounce,
77 shortDebounce: this.shortDebounce
80 this.dropdown = new Dropdown({
81 collection: this.collection,
82 itemTemplate: this.options.itemTemplate,
83 itemSerializeData: this.options.itemSerializeData,
84 targetElement: this.el,
85 dropdownClass: this.options.dropdownClass,
86 backdropClass: this.options.backdropClass
89 this.listenTo(this.dropdown, 'selected', this.selected);
92 onDestroy: function() {
94 this.dropdown.destroy();
99 selected: function(m) {
101 this.trigger('selected', m);
105 return this.dropdown.active();
108 autoSelect: function() {
109 var input = this.el.value;
111 if (!this.autoSelector) return;
114 var model = this.dropdown.getActive();
116 var predicate = this.autoSelector(input);
117 if (model && predicate(model)) return; // Existing model matches
119 var matches = this.collection.filter(predicate);
120 if (matches.length === 0) return;
122 this.dropdown.setActive(matches[0]);
124 searchTextChanged: function(input) {
127 function fetchSuccess() {
130 if (this.options.fetch) {
131 this.options.fetch(input, this.collection, fetchSuccess);
133 this.collection.fetch(
134 { data: { q: input } },
135 { add: true, remove: true, merge: true, success: fetchSuccess }
142 keydown: function(e) {
145 this.dropdown.selectActive();
149 this.dropdown.selectPrev();
153 if (this.dropdown.active()) {
154 this.dropdown.selectNext();
161 if (!this.dropdown.active()) {
178 module.exports = TypeaheadView;