Move search box to header. Add search results to breadcrumbs when you search

This commit is contained in:
Brian Jacobel
2016-08-02 16:07:13 -04:00
parent 4c4476a720
commit 1f2c843f23
16 changed files with 190 additions and 130 deletions

View File

@@ -7,9 +7,10 @@
'backbone',
'discussion/js/discussion_router',
'discussion/js/views/discussion_fake_breadcrumbs',
'discussion/js/views/discussion_search_view',
'common/js/discussion/views/new_post_view'
],
function($, Backbone, DiscussionRouter, DiscussionFakeBreadcrumbs, NewPostView) {
function($, Backbone, DiscussionRouter, DiscussionFakeBreadcrumbs, DiscussionSearchView, NewPostView) {
return function(options) {
var userInfo = options.user_info,
sortPreference = options.sort_preference,
@@ -22,7 +23,9 @@
newPostView,
router,
breadcrumbs,
BreadcrumbsModel;
BreadcrumbsModel,
searchBox,
routerEvents;
// TODO: Perhaps eliminate usage of global variables when possible
window.DiscussionUtil.loadRoles(options.roles);
@@ -53,6 +56,13 @@
});
router.start();
// Initialize and render search box
searchBox = new DiscussionSearchView({
el: $('.forum-search'),
threadListView: router.nav
}).render();
// Initialize and render breadcrumbs
BreadcrumbsModel = Backbone.Model.extend({
defaults: {
contents: []
@@ -65,6 +75,7 @@
events: {
'click .all-topics': function(event) {
event.preventDefault();
searchBox.clearSearch();
this.model.set('contents', []);
router.navigate('', {trigger: true});
router.nav.selectTopic($('.forum-nav-browse-menu-all'));
@@ -72,9 +83,23 @@
}
}).render();
// Add new breadcrumbs when the user selects topics
router.nav.on('topic:selected', function(topic) {
breadcrumbs.model.set('contents', topic);
routerEvents = {
// Add new breadcrumbs and clear search box when the user selects topics
'topic:selected': function(topic) {
breadcrumbs.model.set('contents', topic);
},
// Clear search box when a thread is selected
'thread:selected': function() {
searchBox.clearSearch();
},
// Add 'Search Results' to breadcrumbs when user searches
'search:initiated': function() {
breadcrumbs.model.set('contents', ['Search Results']);
}
};
Object.keys(routerEvents).forEach(function(key) {
router.nav.on(key, routerEvents[key]);
});
};
});

View File

@@ -0,0 +1,36 @@
define([
'jquery',
'edx-ui-toolkit/js/utils/constants',
'discussion/js/views/discussion_search_view'
],
function($, constants, DiscussionSearchView) {
'use strict';
describe('DiscussionSearchView', function() {
var view;
beforeEach(function() {
setFixtures('<div class="search-container"></div>');
view = new DiscussionSearchView({
el: $('.search-container'),
threadListView: {
performSearch: jasmine.createSpy()
}
}).render();
});
describe('Search events', function() {
it('perform search when enter pressed inside search textfield', function() {
view.$el.find('.search-input').trigger($.Event('keydown', {
which: constants.keyCodes.enter
}));
expect(view.threadListView.performSearch).toHaveBeenCalled();
});
it('perform search when search icon is clicked', function() {
view.$el.find('.search-btn').click();
expect(view.threadListView.performSearch).toHaveBeenCalled();
});
});
});
}
);

View File

@@ -0,0 +1,50 @@
(function(define) {
'use strict';
define([
'underscore',
'backbone',
'edx-ui-toolkit/js/utils/html-utils',
'edx-ui-toolkit/js/utils/constants',
'text!discussion/templates/search.underscore'
],
function(_, Backbone, HtmlUtils, constants, searchTemplate) {
/*
* TODO: Much of the actual search functionality still takes place in discussion_thread_list_view.js
* Because of how it's structured there, extracting it is a massive task. Significant refactoring is needed
* in order to clean up that file and make it possible to break its logic into files like this one.
*/
var searchView = Backbone.View.extend({
events: {
'keydown .search-input': 'performSearch',
'click .search-btn': 'performSearch',
'topic:selected': 'clearSearch'
},
initialize: function(options) {
_.extend(this, _.pick(options, 'threadListView'));
this.template = HtmlUtils.template(searchTemplate);
this.threadListView = options.threadListView;
this.listenTo(this.model, 'change', this.render);
this.render();
},
render: function() {
HtmlUtils.setHtml(this.$el, this.template());
return this;
},
performSearch: function(event) {
if (event.which === constants.keyCodes.enter || event.type === 'click') {
event.preventDefault();
this.threadListView.performSearch($('.search-input', this.$el));
}
},
clearSearch: function() {
this.$('.search-input').val('');
this.threadListView.clearSearchAlerts();
}
});
return searchView;
});
}).call(this, define || RequireJS.define);

View File

@@ -0,0 +1,9 @@
<label class="field-label sr-only" for="search" id="search-hint"><%- gettext("Search all posts") %></label>
<input
class="field-input input-text search-input"
type="search"
name="search"
id="search"
placeholder="<%- gettext("Search all posts") %>"
/>
<button class="btn-brand btn-small search-btn" type="button"><%- gettext("Search") %></button>