Skip to content

Instantly share code, notes, and snippets.

@maggiben
Created January 25, 2016 08:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maggiben/678fa214a207d0e50107 to your computer and use it in GitHub Desktop.
Save maggiben/678fa214a207d0e50107 to your computer and use it in GitHub Desktop.
Aurelia typeahead
<template>
<require from="/styles/type-ahead.css"></require>
<div class="ui icon input">
<input type="text" class="form-control" placeholder.bind="options.placeholder" value.bind="value">
<i class="search link icon"></i>
</div>
</template>
import {ViewCompiler, ViewResources, inject, customElement, Container, bindable} from 'aurelia-framework';
import {TemplateRegistryEntry, Loader} from 'aurelia-loader';
import {HttpClient} from 'aurelia-http-client';
import typeahead from 'typeahead';
import Rx from 'rx';
@inject(Element, HttpClient, Loader, ViewResources, ViewCompiler, Container)
@bindable('value')
@bindable('options')
@customElement('type-ahead')
export class TypeAhead {
constructor(element, http, loader, viewResources, viewCompiler, container) {
this.element = element;
this.http = http;
this.loader = loader;
this.viewResources = viewResources;
this.viewCompiler = viewCompiler;
this.container = container;
}
searchTerm(term) {
return new HttpClient()
.createRequest('api/v2/Lookup/jsonp')
.asJsonp()
.withBaseUrl('http://dev.markitondemand.com')
.withParams({
input: term
})
.withCallbackParameterName('callback')
.send()
.then(function(result) {
return result.response.map(function(item, index){
return {
symbol: item.Symbol,
name: item.Name,
exchange: item.Exchange
};
});
});
}
getSuggestions() {
//var keyup = Rx.Observable.fromEvent($(this.element).find('input'), 'keyup')
var keyup = Rx.Observable.fromEvent($(this.element), 'typeahead:asyncrequest')
.map(function (e) {
return e.target.value; // Project the text from the input
})
.filter(function (text) {
var regex = new RegExp('^[a-zA-Z0-9_ ]*$'); // Match only alphanumric underscore and space
return regex.test(text);
})
.debounce(750)
.distinctUntilChanged(); // Only if the value has changed
var searcher = keyup.flatMapLatest(this.searchTerm);
this.searcher = searcher;
return (query, syncResults, asyncResults) => {
var subscription = this.searcher.first().subscribe(
(data) => {
return asyncResults(data);
},
function (error) {
return asyncResults([]);
}
);
};
}
attached() {
var options = {
hint: true,
async: true,
highlight: true,
minLength: 2,
display: 'symbol'
};
var datasets = [{
name: 'tickers',
//valueKey: this.options.valueKey,
limit: 4,
displayKey: 'symbol',
source: this.getSuggestions()
}]
this.loader.loadTemplate('components/styles/type-ahead-templates.html')
.then((templateRegistryEntry) => {
let viewFactory = this.viewCompiler.compile(templateRegistryEntry.template, this.viewResources);
datasets.forEach(dataset => {
dataset.templates = {
suggestion: (data) => {
// Bind the view and it's children
let view = viewFactory.create(this.container, data);
view.bind(data);
var serializer = new XMLSerializer()
return serializer.serializeToString(view.fragment.querySelector('div'));
}
};
});
options = Object.assign(options, this.options.options);
this.typeAhead = $(this.element).find('input').typeahead(options, datasets);
this.typeAhead.bind('typeahead:selected', (event, datum, name) => {
event = new CustomEvent('selected', {
detail: {
value: datum
},
bubbles: true
});
this.element.dispatchEvent(event);
});
this.typeAhead.bind('typeahead:autocomplete', (event, datum, name) => {
event = new CustomEvent('autocomplete', {
detail: {
value: datum
},
bubbles: true
});
this.element.dispatchEvent(event);
});
// Typeahead will trigger an 'open' if input gains focus to display suggestions
// This in turn triggers antoher async call
this.typeAhead.bind('typeahead:asyncrequest', (event, query, name) => {
this.isSearching = true;
});
this.typeAhead.bind('typeahead:asyncreceive', (event, query, name) => {
this.isSearching = false;
});
this.typeAhead.bind('typeahead:asynccancel', (event, query, name) => {
this.isSearching = false;
});
});
}
valueChanged(newValue, oldValue) {
console.log('valueChanged', newValue)
}
optionsChanged(newValue, oldValue) {
console.log('optionsChanged', newValue)
}
detached() {
$(this.element).typeahead('destroy');
}
}
@aluanhaddad
Copy link

@maggiben May I use this code in a project? I just wanted to check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment