How to construct a google like search interface to a Solr service using Ember
I'm new to Ember, and trying to implement a Google-like search interface
to a Solr API. i.e. I would like for the results to update automatically
on the page as you type.
My first thought was to create a reusable TextSearch CollectionView, with
two child views SearchInput, and SearchResults.
Typing into the SearchInput would trigger an event, the event would be
caught by the TextSearch CollectionView, which would update the
SearchResult child element.
I got the events generated ok, but the TextSearch ContainerView is not
able to intercept the event using either actions, functions, or event
manager. I can, however, intercept the event in the IndexController for
some reason, but I need to have it handled in a reusable TextSearch
CollectionView instead (I think).
Finally, I am not able to update the view in the SearchResults (when I try
handling the event in the IndexController), and the SearchResult model is
not firing on page load.
I'm quite new at Ember, so I'm sure I'm doing something silly here. It's
been a bit of a long road to get to this point.
Any advice would be greatly appreciated!
Pastebin: http://jsbin.com/ezomOkO/3/edit
HTML:
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
{{view App.TextSearchView }}
</script>
<script type="text/x-handlebars" data-template-name="textSearch">
{{view App.SearchInputView }}
{{view App.SearchResultsView }}
</script>
<script type="text/x-handlebars" data-template-name="searchInput">
{{input type="text" value=query size="50"}}
</script>
<script type="text/x-handlebars" data-template-name="searchResults" >
<ul>
<li>
Sorry, nobody is here.
{{/each}}
</ul>
Javascript:
App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend({
appName: 'Snomed Search'
});
App.Router.map(function() {
this.route("index", {path: "/"});
});
// INDEX
App.IndexRoute = Ember.Route.extend({
});
App.IndexController = Ember.Controller.extend({
});
//TEXT SEARCH
App.TextSearchView = Ember.View.extend({
actions:{
search: function(search) {
this.get('controllers.searchResults').set('model',
App.TextSearch.find(search));
return false;
}
},
needs: "searchResults",
templateName: 'textSearch'
});
// SEARCH INPUT
App.SearchInputController = Ember.Controller.extend({
query: 'Family'
});
App.SearchInputView = Ember.View.extend({
templateName: 'searchInput',
keyUp: function(evt) {
this.get('controller').send('search', this.get('controller.query'));
}
});
// SEARCH RESULTS
App.SearchResultsController = Ember.Controller.extend({
model: function(){
return App.TextSearch.find('Family');
},
afterModel: function(posts, transitions){
alert('model');
},
isPublic: true
});
App.SearchResultsView = Ember.View.extend({
templateName: 'searchResults'
});
App.SearchResults = Ember.Object.extend({
total: 0,
start: 0,
concepts: Ember.A()
});
App.Concept = Ember.Object.extend({
id: null,
title: null,
active: null,
effectiveTime: null
});
App.TextSearch = Ember.Object.extend({});
App.TextSearch.reopenClass({
find: function(searchString){
return Ember.Deferred.promise(function(p) {
p.resolve($.getJSON("http://solr.sparklingideas.co.uk/solr/concept/select?q=title:"
+ searchString + "&wt=json&indent=true")
.then(function(solr) {
var returned = App.SearchResults.create();
returned.total = solr.response.numFound;
returned.start = solr.response.start;
solr.response.docs.forEach(function (doc) {
var concept = App.Concept.create();
concept.id = doc.id;
concept.title = doc.title;
concept.active = doc.active;
concept.effectiveTime= doc.effectiveTime;
returned.concepts.push(concept);
});
return returned;
}) //then
);//resolve
});//deferred promise
}//find
});//reopen
No comments:
Post a Comment