/assets/js/app/search.js

https://github.com/meirish/backbone-intro · JavaScript · 148 lines · 113 code · 30 blank · 5 comment · 12 complexity · 5e80a7cc20e6ec415d33bc8946846189 MD5 · raw file

  1. Lstn.Views.SearchView = Backbone.View.extend({
  2. el: '#search',
  3. // the view that will hold the results
  4. results: null,
  5. events:{
  6. 'keyup':'checkForEnter',
  7. 'focus':'bindToReset',
  8. 'blur':'unbindReset'
  9. },
  10. initialize: function(options){
  11. _.bindAll(this, 'suggestSearch');
  12. var throttleSugg = _.throttle( this.suggestSearch, 700 );
  13. $(this.el).keyup( throttleSugg );
  14. },
  15. checkForEnter: function(e){
  16. // if enter is pressed, submit the `val()`
  17. // to the search URL to get the results and hide a results panel if it's there
  18. if (e.keyCode === 13){
  19. var query = $(this.el).val();
  20. Lstn.router.navigate('search/'+ query, true);
  21. if ( this.results ){
  22. this.results.trigger('hide');
  23. }
  24. }
  25. },
  26. suggestSearch: function(e){
  27. var self = this,
  28. query = $(this.el).val();
  29. if (query.length > 2){
  30. Lstn.searchresult.fetch({data: {q:query}});
  31. }
  32. if(query.length === 0 && this.results){
  33. this.results.trigger('hide');
  34. }
  35. },
  36. refreshResults: function(){
  37. if (this.results){
  38. this.results.trigger('reset');
  39. if( $(this.results.el).is(':hidden') ){
  40. this.results.trigger('show');
  41. }
  42. } else {
  43. this.results = new Lstn.Views.SearchSuggestView;
  44. this.results.trigger('render');
  45. }
  46. },
  47. bindToReset: function(){
  48. Lstn.searchresult.bind('reset', this.refreshResults, this);
  49. },
  50. unbindReset: function(){
  51. Lstn.searchresult.unbind('reset');
  52. }
  53. });
  54. Lstn.Views.SearchSuggestView = Backbone.View.extend({
  55. className:'search-suggest',
  56. template: $('#search-suggest').html(),
  57. events: {
  58. 'click .go-to-search':'goToSearch',
  59. 'click a.close':'stopBubble',
  60. 'click a':'hide'
  61. },
  62. initialize: function(options){
  63. this.bind('reset', this.reset, this);
  64. this.bind('render', this.reset, this);
  65. this.bind('hide', this.hide, this);
  66. this.bind('show', this.show, this);
  67. this.render();
  68. },
  69. render: function(){
  70. $(this.el).html( this.template ).appendTo('body');
  71. return this;
  72. },
  73. reset: function(){
  74. var container = $(this.el).detach().empty();
  75. container.append($('<a href="#" class="close">Close</a><a href="#" class="go-to-search">See all search results</a>'));
  76. Lstn.searchresult.each(function(model){
  77. var view = new Lstn.Views.RdioObjView({ model: model, template:'#search-result' });
  78. container.append( $(view.el) );
  79. });
  80. container.appendTo('body');
  81. },
  82. goToSearch: function(e){
  83. e.preventDefault();
  84. var query = $('#search').val();
  85. Lstn.router.navigate('search/'+ query, true);
  86. },
  87. stopBubble: function(e){
  88. e.preventDefault();
  89. this.hide();
  90. },
  91. hide: function(e){
  92. $(this.el).fadeOut('fast', function(){ $(this).empty(); });
  93. },
  94. show: function(){
  95. $(this.el).fadeIn('fast');
  96. }
  97. });
  98. Lstn.Collections.SearchCollection = Backbone.Collection.extend({
  99. model: Lstn.Models.RdioObj,
  100. url: function(){
  101. if (this.type === 'suggest'){
  102. return '/suggest'
  103. } else {
  104. return '/find'
  105. }
  106. },
  107. initialize: function(){
  108. this.type = 'suggest'
  109. },
  110. setType: function( type ){
  111. //can be 'suggest' or 'search'
  112. if ( type && _.indexOf(['suggest','search'], type) !== -1 ){
  113. this.type = type;
  114. }
  115. }
  116. });
  117. // only going to use one
  118. Lstn.searchresult = new Lstn.Collections.SearchCollection;