This repository has been archived by the owner on Sep 23, 2019. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Backbone Autocomplete View test</title> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
<script type="text/javascript"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
var Backbone = require('backbone'); | ||
var _ = require('backbone/node_modules/underscore'); | ||
var ResultsView = require('./results-view'); | ||
|
||
// Captured by the keyfilter to control search results | ||
var keys = { | ||
9: 'enter', | ||
13: 'enter', | ||
38: 'up', | ||
40: 'down', | ||
27: 'escape' | ||
}; | ||
|
||
var noop = function(){}; | ||
|
||
var MIN_INPUT_LENGTH = 3; | ||
|
||
var AutocompleteView = Backbone.View.extend({ | ||
tagName: 'div', | ||
className: 'bb-autocomplete', | ||
events: { | ||
'keyup .ac-user-input':'onKeyup', | ||
'blur .ac-user-input':'onBlur', | ||
'change .ac-user-input': 'onChange' | ||
}, | ||
template: _.template('<input class="ac-user-input" type="text" /><div class="ac-results"></div>'), | ||
initialize: function initialize(options) { | ||
options = options || {}; | ||
|
||
this.MIN_INPUT_LENGTH = options.minimumInputLength || MIN_INPUT_LENGTH; | ||
|
||
this.collection = options.collection; // data to search against | ||
this.resultsCollection = new Backbone.Collection(); // where to put results of search | ||
// method on data collection which gives us results | ||
// should return an array of JS objects representing the data | ||
this.shouldFetch = options.shouldFetch || false; | ||
|
||
|
||
this.resultsView = new ResultsView({ | ||
parentView: this, | ||
collection: this.resultsCollection | ||
}); | ||
|
||
}, | ||
setupEvents: function setupEvents(){ | ||
|
||
}, | ||
onKeyup: function onKeydown(evt){ | ||
var input = evt.target; | ||
// see if the user has pressed a key we are explicitly wanting to control | ||
// the behaviour for | ||
if (keys[evt.keyCode]) { | ||
evt.preventDefault(); | ||
switch (keys[evt.keyCode]){ | ||
case 'enter': | ||
break; | ||
case 'escape': | ||
input.blur(); | ||
break; | ||
default: | ||
this.resultsView.trigger(keys[evt.keyCode]); | ||
break; | ||
} | ||
return false; | ||
} | ||
}, | ||
onBlur: function onBlur(evt) { | ||
this.resultsView.trigger('hide'); | ||
}, | ||
onChange: function(evt){ | ||
this.searchValue = evt.target.value; | ||
}, | ||
|
||
doSearch: function(){ | ||
var filteredResults = this.collection.filter(this.searchMethod); | ||
this.resultsCollection.reset(filteredResults); | ||
}, | ||
render: function render (){ | ||
this.$el.html(this.template()); | ||
return this; | ||
}, | ||
// overwritten when subclassing | ||
onSelect: noop // callback that receives the model that was chosen | ||
searchMethod: function searchMethod(item) { | ||
var label = item.get('label'); | ||
if (label.indexOf(this.searchValue) !== -1) { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
}); | ||
|
||
|
||
module.exports = AutocompleteView; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "backbone-autocomplete", | ||
"version": "0.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"backbone": "~1.1.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Backbone Autocomplete View | ||
|
||
Made with browserify or similar in mind. | ||
|
||
MIT License (c) Dan Peddle 2014 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
var Backbone = require('backbone'); | ||
var _ = require('backbone/node_modules/underscore'); | ||
|
||
var ItemView = Backbone.View.extend({ | ||
tagName: 'span', | ||
className: 'ac-result', | ||
template: _.template('<%= label %>'), | ||
events: { | ||
'click':'onSelect', | ||
'mouseenter':'onHover' | ||
}, | ||
initialize: function(options){ | ||
this.parentView = options.parentView; | ||
}, | ||
onHover: function(){ | ||
this.parentView.trigger('highlight', this.model); | ||
}, | ||
onSelect: function(){ | ||
this.parentView.trigger('chosen', this.model); | ||
} | ||
}); | ||
|
||
var ResultsView = Backbone.View.extend({ | ||
tagName: 'div', | ||
className: 'bb-autocomplete-results', | ||
initialize: function initialize(options) { | ||
this.collection = options.collection; | ||
this.parentView = options.parentView; | ||
this.noResultsText = options.noResultsText || 'No results'; | ||
this.on('show', this.show, this); | ||
this.on('hide', this.hide, this); | ||
|
||
var moveUp = _.bind(this.moveHighlight, this, -1); | ||
var moveDown = _.bind(this.moveHighlight, this, 1); | ||
this.on('up', moveUp); | ||
this.on('down', moveDown); | ||
this.on('highlight', this.highlight, this); | ||
this.on('chosen', function(model) { | ||
this.parentView.trigger('chosen', model); | ||
}, this); | ||
}, | ||
show: function show() { | ||
this.$el.removeClass('hidden'); | ||
}, | ||
hide: function hide() { | ||
this.$el.addClass('hidden'); | ||
} | ||
resetHighlightIndex: function resetHighlightIndex() { | ||
this.removeHighlights(); | ||
this.highlightIndex = false; | ||
if (this.collection.length === 0) { | ||
var localisedWarning = this.noResultsText; | ||
this.$el.html('<span class="bb-autocomplete-no-results">' + localisedWarning + '</span>'); | ||
} | ||
}, | ||
removeHighlights: function removeHighlights() { | ||
this.$el.find('.highlight').removeClass('highlight'); | ||
}, | ||
highlight: function(model) { | ||
this.removeHighlights(); | ||
model = model || this.collection.at(this.highlightIndex); | ||
var viewToHighlight = this._getViewByModel(model); | ||
if (viewToHighlight) { | ||
viewToHighlight.$el.addClass('highlight'); | ||
this.highlightIndex = this.collection.indexOf(model); | ||
} | ||
}, | ||
moveHighlight: function(direction) { | ||
if (this.collection.length === 0) { | ||
// do nothing as we have no results | ||
return; | ||
} | ||
|
||
if (this.highlightIndex === false) { | ||
if (direction < 0) { | ||
this.highlightIndex = this.collection.length - 1; | ||
} else if (direction > 0) { | ||
this.highlightIndex = 0; | ||
} | ||
} else { | ||
|
||
this.highlightIndex += direction; | ||
|
||
if (this.highlightIndex < 0) { | ||
this.highlightIndex = this.collection.length - 1; | ||
} else if (this.highlightIndex >= this.collection.length) { | ||
this.highlightIndex = 0; | ||
} | ||
|
||
} | ||
|
||
this.highlight(); | ||
}, | ||
render: function render() { | ||
|
||
} | ||
}); | ||
|
||
module.exports = ResultsView; |